def ex11_4(fname):
    """
    Plot eigenvectors of the null space and the orthogonal representers
    """
    measurement_depths, measurement_data, measurement_errors = read_data(fname)
    inversion_depths = get_inversion_depth_steps(measurement_depths, num_steps=200)
    V, Lambda, U_transposed, _ = do_SVD_from_file(fname, full_matrices=True, num_steps=200)
    S_inverted = matrix_S_inverted_helper(inversion_depths)
    U = np.transpose(U_transposed)
    representants = S_inverted @ U
    # representants now holds the representants in its columns, but it is set up so that indexing it accesses its rows
    # transpose it to access the representants by index
    representants = np.transpose(representants)

    # create enough subplots to plot all representes
    f, ax_arr = plt.subplots(len(measurement_data), sharex=True)
    plt.suptitle("Representants")
    for i, repr in enumerate(representants[0:len(measurement_data)]):
        # show singular value belonging to representer in legend
        ax_arr[i].plot(inversion_depths, repr, label=f"$\lambda_{{{i+1}}}$: {Lambda[i]:4.1f}")
        ax_arr[i].legend()
    plt.xlabel(r"Depth $z$ in m")
    plt.figure()
    for nullspace_vector in representants[len(measurement_data):]:
        plt.plot(inversion_depths, nullspace_vector)
    plt.xlabel(r"Depth $z$ in m")
    plt.title("Eigenvectors null space")
    plt.show()
def resolution_matrix(fname, nu=None, depth_num_steps=10000):
    """
    Calculate the resolution matrix R. Every column of the matrix is the inversion result for a test model containing
    one spike at a certain depth.
    :param fname: Filepath to measurement file which contains three values per line
    depth (m) measurement data (mGal, not corrected for free air gradient), measurement error (mgal)
    :param nu: Lagrange parameter
    :param depth_num_steps: Number of steps for the resulting discrete density Model
    :return: matrix R
    """
    measurement_depths, measurement_data, measurement_errors = read_data(fname)
    inversion_depths = get_inversion_depth_steps(measurement_depths,
                                                 num_steps=depth_num_steps)
    S_inverted = matrix_S_inverted_helper(inversion_depths)
    V, Lambda, U_transposed, _ = do_SVD_from_file(fname,
                                                  num_steps=depth_num_steps)
    # calculate new data
    d_double_prime = new_data(measurement_data, np.transpose(V),
                              measurement_errors)
    # calculate desired misfit using bisection
    desired_misfit = len(measurement_depths)
    optimal_nu, misfit = optimal_nu_bysection(desired_misfit, d_double_prime,
                                              Lambda)
    D_nu = matrix_D_nu(optimal_nu, Lambda)
    D_nu_inverted = np.linalg.inv(D_nu)
    R = matrix_R(S_inverted, U_transposed.T, D_nu_inverted, Lambda)
    return R
def invert_errors(fname, nu=None, depth_num_steps=10000):
    """
    Do an inversion using the borehole gravity measurements with errors given in fname
    :param fname: Filepath to measurement file which contains three values per line
    depth (m) measurement data (mGal, not corrected for free air gradient), measurement error (mgal)
    Every line represents one measurement point. Measurement points in the file are ordered with increasing depth.
    :param nu: Lagrange parameter
    :param depth_num_steps: Number of steps for the resulting discrete density Model
    :return: InversionModel which holds the depth, density values of the resulting model
    """
    measurement_depths, measurement_data, measurement_errors = read_data(fname)
    inversion_depths = get_inversion_depth_steps(measurement_depths,
                                                 num_steps=depth_num_steps)
    V, Lambda, U_transposed, _ = do_SVD_from_file(fname,
                                                  num_steps=depth_num_steps)
    # calculate new data
    d_double_prime = new_data(measurement_data, np.transpose(V),
                              measurement_errors)
    # calculate desired misfit using bisection
    desired_misfit = len(measurement_depths)
    optimal_nu, misfit = optimal_nu_bysection(desired_misfit, d_double_prime,
                                              Lambda)
    # calculate new coefficients
    alpha_double_prime = calculate_coeffs(d_double_prime, optimal_nu, Lambda)
    S_inverted = matrix_S_inverted_helper(inversion_depths)
    dens_model = calculate_model(S_inverted,
                                 np.transpose(U_transposed),
                                 new_coefficients=alpha_double_prime)
    return InversionModel(inversion_depths, dens_model, optimal_nu, misfit)
Пример #4
0
def ex_1(fname):
    NUMBER_OF_DEPTH_STEPS = 200
    measurement_depth, *_ = read_data(fname)
    inversion_depths = get_inversion_depth_steps(
        measurement_depth, num_steps=NUMBER_OF_DEPTH_STEPS)
    R = resolution_matrix(fname, depth_num_steps=NUMBER_OF_DEPTH_STEPS)
    extent = (inversion_depths[0], inversion_depths[-1], inversion_depths[-1],
              inversion_depths[0])
    plt.imshow(R, interpolation="none", extent=extent)
    cbar = plt.colorbar()
    cbar.set_label("Density (g/cm³)")
    plt.xlabel("Tiefe der dünnen Schicht (m)")
    plt.ylabel("Tiefe (m)")
    plt.title("Resolutionsmatrix")
    plt.show()
def ex11_2(fname):
    """
    Calculate new data d'' and misfit chi² and plot chi²(nu)
    """
    measurement_depths, measurement_data, measurement_errors = read_data(fname)
    V, Lambda, U_transposed, _ = do_SVD_from_file(fname)
    # calculate new data
    d_double_prime = new_data(measurement_data, np.transpose(V),  measurement_errors)
    # calculate misfit for multiple values of nu
    range_of_nus = np.logspace(-2, 2, 1000)
    range_of_chis = np.array([misfit_squared(d_double_prime, nu, Lambda) for nu in range_of_nus])
    plt.plot(range_of_nus, range_of_chis, ".")
    plt.title(r"$\nu/\chi^2$")
    plt.xlabel(r"Lagrangeparameter $\nu$")
    plt.ylabel(r"Misfit $\chi^2$")
    plt.xscale("log")
    plt.yscale("log")
    plt.show()