def xyzfieldt(k, m, n, knots, gcoefs, thetav, phiv, t): lpmv = scipy.special.lpmv x = numpy.zeros_like(thetav) y = x.copy() z = x.copy() schmidt = schmidt_real(m, n, grid=False) #1. calcular los splines #base = bspline.deboor_base(knots, t, 3).T[:-4] base = bspline.condition_array(knots, t).T #3. for q... for q, spline in enumerate(base): for ki, mi, ni, g, sch in zip(k, m, n, gcoefs[q,:], schmidt): m_abs = abs(mi) cossin = numpy.cos(m_abs*phiv) if mi >= 0 else numpy.sin(m_abs*phiv) sinmcos = numpy.sin(m_abs*phiv) if mi >= 0 else -numpy.cos(m_abs*phiv) leg = lpmv(m_abs, ni, numpy.cos(thetav))*sch dleg = dlpmv(m_abs, ni, numpy.cos(thetav))*(-numpy.sin(thetav))*sch x += g*cossin*dleg*spline y += g*sinmcos*m_abs*leg/numpy.sin(thetav)*spline z -= (ni+1)*(g*cossin)*leg*spline return x, y, z
def invert_dift(thetav, phiv, t, D, I, F, degrees, knots, g0=None, reg_coef_spatial = 0, reg_coef_time = 0, theta_0 = None, steps=5): k, m, n = degrees #n_knots, n_degrees = len(knots)-4, len(k) #knots = bspline.fix_knots(kn, 3) n_knots, n_degrees = len(knots), len(k) n_coefs = n_knots*n_degrees #base = bspline.deboor_base(knots, t, 3)[:, :-4] Ax, Ay, Az = condition_matrix_xyz(thetav, phiv, degrees) D_0, I_0, F_0 = D, I, F base = numpy.concatenate((bspline.condition_array(knots, t[~numpy.isnan(D)]), bspline.condition_array(knots, t[~numpy.isnan(I)]), bspline.condition_array(knots, t[~numpy.isnan(F)])), axis=0) D_0 = D_0[~numpy.isnan(D)] I_0 = I_0[~numpy.isnan(I)] F_0 = F_0[~numpy.isnan(F)] if g0 is None: g0 = numpy.zeros((n_knots, n_degrees)) can_get_z = ((~numpy.isnan(I)) & (~numpy.isnan(F))) avg_z = numpy.average(F[can_get_z] * sin(I[can_get_z])) g0[:, 0] = -avg_z g = g0.copy() di_0 = numpy.concatenate((D_0, I_0)) if (reg_coef_spatial != 0) or (reg_coef_time != 0): reg_matrix = full_reg(spatial_reg(k, m, n, theta_0), time_reg(knots), coef_L=reg_coef_spatial, coef_S=reg_coef_time) else: reg_matrix = 0.0 for iteration in range(steps): #como poner la dependencia del tiempo aquí? #con magia Bx, By, Bz = xyzfieldt(k, m, n, knots, g, thetav, phiv, t) D_model, I_model, F_model, H_model = xyz.xyz2difh(Bx, By, Bz) Ad, Ai, Af = condition_matrix_dif(Bx, By, Bz, F_model, H_model, Ax, Ay, Az) Af = Af / F_model[:, numpy.newaxis] Adif = numpy.concatenate((Ad[~numpy.isnan(D), :], Ai[~numpy.isnan(I), :], Af[~numpy.isnan(F), :]), axis=0) Adif = numpy.concatenate([Adif*spline[:, numpy.newaxis] for spline in base.T], axis=1) D_model = D_model[~numpy.isnan(D)] I_model = I_model[~numpy.isnan(I)] F_model = F_model[~numpy.isnan(F)] di = numpy.concatenate((D_model, I_model), axis=0) di_delta = numpy.arctan2(numpy.sin(di-di_0), numpy.cos(di-di_0)) f_delta = (F_model - F_0)/F_model delta = numpy.concatenate((di_delta, f_delta), axis=0) #solution = numpy.linalg.lstsq(Adif, delta) #g = g - solution[0].reshape((n_knots, n_degrees)) g = g - ((numpy.linalg.pinv(Adif.T @ Adif + reg_matrix) @ Adif.T) @ delta).reshape((n_knots, n_degrees)) sys.stdout.write("\r") sys.stdout.write("[{: <20}] ".format("#"*int((iteration/steps)*20+1))) sys.stdout.write("iteration {0} : rms = ".format(iteration+1)) sys.stdout.write(str(numpy.sqrt(sum(delta**2)/len(delta)))) #debuge #ax.scatter(t, di_delta[:len(di_delta)//2], color="green") #ax.scatter(t, di_delta[len(di_delta)//2:], color="red") #ax.scatter(t, f_delta, color="blue") #ax.scatter(t, D_model - D_0, color="green") #ax.scatter(t, I_model - I_0, color="red") #ax.scatter(t, F_model - F_0, color="blue") #pyplot.show(fig) if (sum(abs(delta**2)) > 10000): warnings.warn("a bad thing is happening ヽ( `д´*)ノ") return g