def test_frozen_param(): # ====================================================================== "Check that linear and nonlinear parameters can be frozen during the optimization" r = np.linspace(0, 6, 300) def Amodel(p): mean1, mean2, width1, width2 = p return np.atleast_2d([ dd_gauss.nonlinmodel(r, mean1, width1), dd_gauss.nonlinmodel(r, mean2, width2) ]).T x = np.array([0.5, 0.6]) y = Amodel([3, 5, 0.2, 0.3]) @ x nonlin_frozen = [None, 5, None, None] lin_frozen = [0.5, None] fit = snlls(y, Amodel, par0=[3.2, 5.2, 0.2, 0.3], lb=[0, 0, 0.01, 0.01], ub=[10, 10, 5, 5], lbl=[0, 0]) fit_frozen = snlls(y, Amodel, par0=[3.2, 5.2, 0.2, 0.3], lb=[0, 0, 0.01, 0.01], ub=[10, 10, 5, 5], lbl=[0, 0], nonlin_frozen=nonlin_frozen, lin_frozen=lin_frozen) assert np.allclose(fit_frozen.model, y, atol=1e-2) and np.allclose( fit_frozen.model, fit.model, atol=1e-2)
def test_extrapenalty(): # ====================================================================== "Check that custom penalties can be passed and act on the solution" t = np.linspace(0, 3, 300) r = np.linspace(2, 5, 200) P = dd_gauss2(r, 3.5, 0.5, 0.5, 4, 0.1, 0.5) K = dipolarkernel(t, r) V = K @ P + whitegaussnoise(t, 0.15, seed=1) par0 = [2.5, 0.01, 0.1, 4.5, 0.01, 0.6] lb = [1, 0.01, 0, 1, 0.01, 0] ub = [20, 1, 1, 20, 1, 1] # Fit case it fails, stuck at "spicky" Gaussians model = lambda p: K @ dd_gauss2(r, *p) fit = snlls(V, model, par0, lb, ub) # Fit with Tikhonov penalty on the Gaussians model L = regoperator(r, 2) alpha = 1e-4 tikhonov = lambda p, _: alpha * L @ dd_gauss2(r, *p) fit_tikh = snlls(V, model, par0, lb, ub, extrapenalty=tikhonov) Pfit = dd_gauss2(r, *fit.nonlin) Pfit_tikh = dd_gauss2(r, *fit_tikh.nonlin) assert ovl(P, Pfit) < ovl(P, Pfit_tikh)
def test_multiple_penalties(): # ====================================================================== "Check that multiple additional penaltyies can be passed correctly" t = np.linspace(0, 5, 300) r = np.linspace(2, 6, 90) P = dd_gauss(r, 4.5, 0.25) param = 0.2 K = dipolarkernel(t, r, mod=param) V = K @ P + whitegaussnoise(t, 0.001, seed=1) dr = np.mean(np.diff(r)) beta = 0.05 R = 0.5 compactness_penalty = lambda pnonlin, plin: beta * np.sqrt(plin * ( r - np.trapz(plin * r, r))**2 * dr) radial_penalty = lambda pnonlin, plin: 1 / R**2 * (np.linalg.norm( (pnonlin - param) / param - R))**2 Kmodel = lambda lam: dipolarkernel(t, r, mod=lam) fit0 = snlls(V, Kmodel, par0=0.2, lb=0, ub=1, lbl=np.zeros_like(r), extrapenalty=[compactness_penalty]) fitmoved = snlls(V, Kmodel, par0=0.2, lb=0, ub=1, lbl=np.zeros_like(r), extrapenalty=[compactness_penalty, radial_penalty]) assert ovl(P, fit0.lin) > ovl(P, fitmoved.lin)
def test_frozen_Nparam(): # ====================================================================== "Check that the correct number of linear and nonlinear parameters are return even when freezing" r = np.linspace(0, 6, 90) def Amodel(p): mean1, mean2, width1, width2 = p return np.atleast_2d([ dd_gauss.nonlinmodel(r, mean1, width1), dd_gauss.nonlinmodel(r, mean2, width2) ]).T x = np.array([0.5, 0.6]) y = Amodel([3, 5, 0.2, 0.3]) @ x nonlin_frozen = [None, 5, None, None] lin_frozen = [0.5, None] fit = snlls(y, Amodel, par0=[2, 4, 0.2, 0.2], lb=[0, 0, 0.01, 0.01], ub=[10, 10, 5, 5], lbl=[0, 0], nonlin_frozen=nonlin_frozen, lin_frozen=lin_frozen) fit_frozen = snlls(y, Amodel, par0=[2, 4, 0.2, 0.2], lb=[0, 0, 0.01, 0.01], ub=[10, 10, 5, 5], lbl=[0, 0]) assert len(fit.nonlin) == 4 and len(fit.lin) == 2 and len( fit_frozen.nonlin) == 4 and len(fit_frozen.lin) == 2
def test_masking(): # ====================================================================== "Check that datapoints can be masked out" x = np.linspace(0, 7, 100) def model(p): center, width = p y = dd_gauss(x, center, width) return y mask = np.ones_like(x).astype(bool) mask[(x > 2.5) & (x < 3.5)] = False y = model([3, 0.5]) yref = y.copy() y[~mask] = 0 fitmasked = snlls(y, model, par0=[4, 0.2], lb=[1, 0.05], ub=[6, 5], mask=mask) fit = snlls(y, model, par0=[4, 0.2], lb=[1, 0.05], ub=[6, 5]) assert np.allclose(fitmasked.model, yref) and not np.allclose(fit.model, yref)
def test_confinter_scaling(): #============================================================ "Check that the confidence intervals are agnostic w.r.t. scaling" # Prepare test data r = np.linspace(1, 8, 80) t = np.linspace(0, 4, 50) lam = 0.25 K = dipolarkernel(t, r, mod=lam) parin = [3.5, 0.4, 0.6, 4.5, 0.5, 0.4] P = dd_gauss2(r, *parin) V = K @ P + whitegaussnoise(t, 0.01, seed=1) # Non-linear parameters nlpar0 = 0.2 lb = 0 ub = 1 # Linear parameters: non-negativity lbl = np.zeros(len(r)) V0_1 = 1 V0_2 = 1e8 # Separable LSQ fit fit1 = snlls(V * V0_1, lambda lam: dipolarkernel(t, r, mod=lam), nlpar0, lb, ub, lbl, nonlin_tol=1e-3) fit2 = snlls(V * V0_2, lambda lam: dipolarkernel(t, r, mod=lam), nlpar0, lb, ub, lbl, nonlin_tol=1e-3) # Assess linear parameter uncertainties ci1 = fit1.linUncert.ci(95) ci2 = fit2.linUncert.ci(95) ci1[ci1 == 0] = 1e-16 ci2[ci2 == 0] = 1e-16 assert np.max(abs(ci2 / V0_2 - ci1)) < 1e-6 # Assess nonlinear parameter uncertainties ci1 = fit1.nonlinUncert.ci(95) ci2 = fit2.nonlinUncert.ci(95) ci1[ci1 == 0] = 1e-16 ci2[ci2 == 0] = 1e-16 assert np.max(abs(ci2 - ci1)) < 1e-6
def test_globalfit(): # ====================================================================== "Check that global fitting yields correct results" r = np.linspace(2, 5, 200) par = np.array([3, 0.2]) P = dd_gauss(r, *par) t1 = np.linspace(0, 3, 300) K1 = dipolarkernel(t1, r) V1 = K1 @ P t2 = np.linspace(-0.5, 4, 200) K2 = dipolarkernel(t2, r) V2 = K2 @ P def Vmodel(par): Pfit = dd_gauss(r, *par) V1 = K1 @ Pfit V2 = K2 @ Pfit return [V1, V2] par0 = [5, 0.5] lb = [1, 0.1] ub = [20, 1] fit = snlls([V1, V2], Vmodel, par0, lb, ub) assert all(abs(par - fit.nonlin) < 1e-2)
def test_confinter_values(): # ====================================================================== "Check that the values of the confidence intervals are correct" np.random.seed(0) A = np.random.rand(300, 2) p = np.array([0.5, 3]) y = A @ p + 0.2 * np.random.randn(300) # Reference confidence intervals (calculated using lmfit package, see #116) cov = [99.73, 95.45, 68.27] a_ci_ref = [[0.41918705096124576, 0.6052333453428683], [0.4504549830560608, 0.5739654132472912], [0.48140740318342196, 0.5430129931207299]] b_ci_ref = [[2.8472129716943995, 3.0317740823087562], [2.878254646104185, 3.00073387702068], [2.9089331341860465, 2.9700584546043713]] fit = snlls(y, A, reg=False) a_ci = [fit.paramUncert.ci(cov[i])[0, :] for i in range(3)] b_ci = [fit.paramUncert.ci(cov[i])[1, :] for i in range(3)] ci_match = lambda ci, ci_ref, truth: np.max( abs(np.array(ci) - np.array(ci_ref))) / truth < 0.05 assert ci_match(a_ci, a_ci_ref, p[0]) & ci_match(b_ci, b_ci_ref, p[1])
def test_globalfit_scales(): #============================================================ "Check that the global fit with arbitrary amplitudes works." t1 = np.linspace(0, 5, 300) t2 = np.linspace(0, 2, 300) r = np.linspace(3, 5, 100) P = dd_gauss(r, 4, 0.25) K1 = dipolarkernel(t1, r) K2 = dipolarkernel(t2, r) scales = [1e3, 1e9] V1 = scales[0] * K1 @ P V2 = scales[1] * K2 @ P def Vmodel(par): Pfit = dd_gauss(r, *par) V1 = K1 @ Pfit V2 = K2 @ Pfit return block_diag(V1, V2).T par0 = [5, 0.5] lb = [1, 0.1] ub = [20, 1] fit = snlls(np.concatenate([V1, V2]), Vmodel, par0, lb, ub) assert max(abs(np.asarray(scales) / fit.lin - 1)) < 1e-2
def test_confinter_model(): #======================================================================= "Check that the confidence intervals of the fitted model are correct" # Prepare test data r = np.linspace(1, 8, 150) t = np.linspace(0, 4, 200) lam = 0.25 K = dipolarkernel(t, r, mod=lam) parin = [3.5, 0.4, 0.6, 4.5, 0.5, 0.4] P = dd_gauss2(r, *parin) V = K @ P + whitegaussnoise(t, 0.05, seed=1) nlpar0 = 0.2 lb = 0 ub = 1 lbl = np.full(len(r), 0) # Separable LSQ fit fit = snlls(V, lambda lam: dipolarkernel(t, r, mod=lam), nlpar0, lb, ub, lbl) Vfit = fit.model Vuq = fit.modelUncert Vci50 = Vuq.ci(50) Vci95 = Vuq.ci(95) Vlb = np.full(len(t), -np.inf) Vub = np.full(len(t), np.inf) assert_confidence_intervals(Vci50, Vci95, Vfit, Vlb, Vub)
def test_multiple_datasets(): # ====================================================================== "Check bootstrapping when using multiple input datasets" t1 = np.linspace(0, 5, 200) t2 = np.linspace(-0.5, 3, 300) r = np.linspace(2, 6, 300) P = dd_gauss(r, 4, 0.8) K1 = dipolarkernel(t1, r) K2 = dipolarkernel(t2, r) Vexp1 = K1 @ P + whitegaussnoise(t1, 0.01, seed=1) Vexp2 = K2 @ P + whitegaussnoise(t2, 0.02, seed=2) def Vmodel(par): V1 = K1 @ dd_gauss(r, *par) V2 = K2 @ dd_gauss(r, *par) return [V1, V2] par0 = [3, 0.5] fit = snlls([Vexp1, Vexp2], Vmodel, par0) Vfit1, Vfit2 = fit.model def bootfcn(V): fit = snlls(V, Vmodel, par0) return fit.nonlin paruq = bootstrap_analysis(bootfcn, [Vexp1, Vexp2], [Vfit1, Vfit2], 5) assert all(abs(paruq.mean - fit.nonlin) < 1.5e-2)
def test_reg_tikhonov(): #============================================================ "Check that Tikhonov regularization of linear problem works" # Prepare test data r = np.linspace(1, 8, 80) t = np.linspace(0, 4, 100) lam = 0.25 K = dipolarkernel(t, r, mod=lam) parin = [3.5, 0.4, 0.6, 4.5, 0.5, 0.4] P = dd_gauss2(r, *parin) V = K @ P # Non-linear parameters # nlpar = [lam] nlpar0 = 0.2 lb = 0 ub = 1 # Linear parameters: non-negativity lbl = np.zeros(len(r)) # Separable LSQ fit fit = snlls(V, lambda lam: dipolarkernel(t, r, mod=lam), nlpar0, lb, ub, lbl, uq=False) Pfit = fit.lin assert ovl(P, Pfit) > 0.95
def test_plot(): # ====================================================================== "Check that the plot method works" # Prepare test data r = np.linspace(1, 8, 80) t = np.linspace(0, 4, 200) lam = 0.25 K = dipolarkernel(t, r, mod=lam) parin = [3.5, 0.4, 0.6, 4.5, 0.5, 0.4] P = dd_gauss2(r, *parin) V = K @ P # Linear parameters: non-negativity lbl = np.zeros(len(r)) # Separable LSQ fit fit = snlls(V, lambda lam: dipolarkernel(t, r, mod=lam), par0=0.2, lb=0, ub=1, lbl=lbl, uq=False) fig = fit.plot(show=False) assert str(fig.__class__) == "<class 'matplotlib.figure.Figure'>"
def assert_solver(solver): # Prepare test data r = np.linspace(1, 8, 80) t = np.linspace(0, 4, 200) lam = 0.25 K = dipolarkernel(t, r, mod=lam) parin = [3.5, 0.4, 0.6, 4.5, 0.5, 0.4] P = dd_gauss2(r, *parin) V = K @ P # Non-linear parameters # nlpar = [lam] nlpar0 = 0.2 lb = 0 ub = 1 # Linear parameters: non-negativity lbl = np.zeros(len(r)) ubl = [] # Separable LSQ fit fit = snlls(V, lambda lam: dipolarkernel(t, r, mod=lam), nlpar0, lb, ub, lbl, ubl, nnlsSolver=solver, uq=False) Pfit = fit.lin assert ovl(P, Pfit) > 0.95
def test_goodness_of_fit(): #============================================================ "Check the goodness-of-fit statistics are correct" # Prepare test data r = np.linspace(2, 5, 150) t = np.linspace(-0.2, 4, 100) lam = 0.25 K = dipolarkernel(t, r, mod=lam) parin = [3.5, 0.15, 0.6, 4.5, 0.2, 0.4] P = dd_gauss2(r, *parin) sigma = 0.03 V = K @ P + whitegaussnoise(t, sigma, seed=2, rescale=True) # Non-linear parameters # nlpar = [lam] nlpar0 = 0.2 lb = 0 ub = 1 # Linear parameters: non-negativity lbl = np.zeros(len(r)) ubl = [] # Separable LSQ fit fit = snlls(V, lambda lam: dipolarkernel(t, r, mod=lam), nlpar0, lb, ub, lbl, ubl, noiselvl=sigma, uq=False) stats = fit.stats assert abs(stats['chi2red'] - 1) < 0.05
def test_complex_model_uncertainty(): # ====================================================================== "Check the fit of a real-valued model to complex-valued data" x = np.linspace(0, 7, 100) def model(p): phase, center, width = p y = dd_gauss(x, center, width) y = y * np.exp(-1j * phase) return y y = model([np.pi / 5, 3, 0.5]) y = y + whitegaussnoise(x, 0.01) y = y + 1j * whitegaussnoise(x, 0.05) fitResult = snlls(y, model, par0=[2 * np.pi / 5, 4, 0.2], lb=[-np.pi, 1, 0.05], ub=[np.pi, 6, 5]) ciwidth = np.sum( fitResult.modelUncert.ci(95)[:, 1] - fitResult.modelUncert.ci(95)[:, 0]) assert (ciwidth.real < ciwidth.imag).all()
def test_confinter_nonlinear(): #======================================================================= "Check that the confidence intervals of the non-linear parameters are correct" # Prepare test data r = np.linspace(1, 8, 80) t = np.linspace(0, 4, 200) lam = 0.25 K = dipolarkernel(t, r, mod=lam) parin = [3.5, 0.4, 0.6, 4.5, 0.5, 0.4] P = dd_gauss2(r, *parin) V = K @ P # Non-linear parameters # nlpar = [lam] nlpar0 = 0.2 lb = 0 ub = 1 # Linear parameters: non-negativity lbl = np.zeros(len(r)) ubl = np.full(len(r), np.inf) # Separable LSQ fit fit = snlls(V, lambda lam: dipolarkernel(t, r, mod=lam), nlpar0, lb, ub, lbl, ubl) parfit = fit.nonlin uq = fit.nonlinUncert parci50 = np.atleast_2d(uq.ci(50)) parci95 = np.atleast_2d(uq.ci(95)) assert_confidence_intervals(parci50, parci95, parfit, lb, ub)
def test_confinter_linear(): #======================================================================= "Check that the confidence intervals of the linear parameters are correct" # Prepare test data r = np.linspace(1, 8, 150) t = np.linspace(0, 4, 200) lam = 0.25 K = dipolarkernel(t, r, mod=lam) parin = [3.5, 0.4, 0.6, 4.5, 0.5, 0.4] P = dd_gauss2(r, *parin) V = K @ P + whitegaussnoise(t, 0.05, seed=1) # Non-linear parameters # nlpar = [lam] nlpar0 = 0.2 lb = 0 ub = 1 # Linear parameters: non-negativity lbl = np.zeros(len(r)) ubl = np.full(len(r), np.inf) # Separable LSQ fit fit = snlls(V, lambda lam: dipolarkernel(t, r, mod=lam), nlpar0, lb, ub, lbl) Pfit = np.round(fit.lin, 6) uq = fit.linUncert Pci50 = np.round(uq.ci(50), 6) Pci95 = np.round(uq.ci(95), 6) assert_confidence_intervals(Pci50, Pci95, Pfit, lbl, ubl)
def test_confinter_values(): # ====================================================================== "Check that the values of the confidence intervals are correct" np.random.seed(0) A0 = np.random.rand(300, 2) A = lambda p: 1 - p[0] + A0**p[1] pnonlin = np.array([0.5, 2]) plin = np.array([0.75, 5.5]) y = A(pnonlin) @ plin + 0.3 * np.random.randn(300) # Reference confidence intervals (calculated using lmfit package, see #116) cov = [99.73, 95.45, 68.27] a_ci_ref = [[0.4636991758611843, 0.5411943256617782], [0.47730341575508245, 0.5286896152296477], [0.4905189733270308, 0.5161245529171482]] b_ci_ref = [[1.7876921926935445, 2.1089296764536907], [1.8384482433779732, 2.0515346381926847], [1.8899306688797555, 1.9961521871803736]] fit = snlls(y, A, [0.5, 0.2], reg=False) a_ci = [fit.nonlinUncert.ci(cov[i])[0, :] for i in range(3)] b_ci = [fit.nonlinUncert.ci(cov[i])[1, :] for i in range(3)] ci_match = lambda ci, ci_ref, truth: np.max( abs(np.array(ci) - np.array(ci_ref))) / truth < 0.01 assert ci_match(a_ci, a_ci_ref, pnonlin[0]) & ci_match( b_ci, b_ci_ref, pnonlin[1])
def test_cost_value(): #============================================================ "Check that the cost value is properly returned" # Prepare test data r = np.linspace(1, 8, 80) t = np.linspace(0, 4, 200) lam = 0.25 K = dipolarkernel(t, r, mod=lam) parin = [3.5, 0.4, 0.6, 4.5, 0.5, 0.4] P = dd_gauss2(r, *parin) V = K @ P # Non-linear parameters nlpar0 = 0.2 lb = 0 ub = 1 # Linear parameters: non-negativity lbl = np.zeros(len(r)) ubl = np.full(len(r), np.inf) # Separable LSQ fit fit = snlls(V, lambda lam: dipolarkernel(t, r, mod=lam), nlpar0, lb, ub, lbl, ubl) assert isinstance(fit.cost, float) and np.round( fit.cost / np.sum(fit.residuals**2), 5) == 1
def assert_multigauss_SNLLS_problem(nonlinearconstr=True, linearconstr=True): # Prepare test data r = np.linspace(1, 8, 80) t = np.linspace(0, 4, 200) K = dipolarkernel(t, r) parin = [3.5, 0.4, 0.6, 4.5, 0.5, 0.4] P = dd_gauss2(r, *parin) V = K @ P def Kmodel(p, t, r): # Unpack parameters r1, w1, r2, w2 = p # Generate basic kernel K0 = dipolarkernel(t, r) # Get Gauss basis functions P1 = dd_gauss(r, r1, w1) P2 = dd_gauss(r, r2, w2) # Combine all non-linear functions into one K = np.zeros((len(t), 2)) K[:, 0] = K0 @ P1 K[:, 1] = K0 @ P2 return K # Non-linear parameters # nlpar = [r1 w1 r2 w2] nlpar0 = [3.2, 0.2, 4.2, 0.3] if nonlinearconstr: lb = [1, 0.1, 1, 0.1] ub = [20, 5, 20, 5] else: lb = [] ub = [] # Linear parameters if linearconstr: lbl = [0, 0] ubl = [1, 1] else: lbl = [] ubl = [] # Separable LSQ fit fit = snlls(V, lambda p: Kmodel(p, t, r), nlpar0, lb, ub, lbl, ubl, reg=False, uq=False) nonlinfit = fit.nonlin linfit = fit.lin parout = [ nonlinfit[0], nonlinfit[1], linfit[0], nonlinfit[2], nonlinfit[3], linfit[1] ] parout = np.asarray(parout) parin = np.asarray(parin) assert np.max(abs(parout - parin) < 1e-1)
def test_confinter_global(): #============================================================ "Check that the confidence intervals are correctly computed even with multiple datasets" r, _, V1, V2, K1, K2 = generate_global_dataset() fit = snlls([V1, V2], [K1, K2], lbl=np.zeros_like(r)) assert_confidence_intervals(fit.paramUncert, fit.param)
def test_global_weights(): # ====================================================================== "Check that the global weights properly work when specified" t = np.linspace(0, 5, 300) r = np.linspace(2, 8, 150) K = dipolarkernel(t, r) param1 = [3, 0.2] param2 = [5, 0.2] P1 = dd_gauss(r, *param1) P2 = dd_gauss(r, *param2) V1 = K @ P1 + whitegaussnoise(t, 0.01, seed=1) V2 = K @ P2 + whitegaussnoise(t, 0.01, seed=1) fit1 = snlls([V1, V2], [K, K], lbl=np.zeros_like(r), weights=[1, 1e-10]) fit2 = snlls([V1, V2], [K, K], lbl=np.zeros_like(r), weights=[1e-10, 1]) assert ovl(P1, fit1.param) > 0.95 and ovl(P2, fit2.param) > 0.95
def test_frozen_Nparam(): # ====================================================================== "Check that the correct number of parameters are returned even with frozen parameters" x = np.linspace(0, 6, 100) def gauss(mean, width): return np.exp(-(x - mean)**2 / width**2 / 2) A = np.squeeze(np.atleast_2d([gauss(3, 0.4), gauss(4, 0.2)]).T) y = A @ np.array([0.5, 0.6]) xfrozen = [0.5, None] fit = snlls(y, A, lbl=np.zeros(2)) fit_frozen = snlls(y, A, lbl=np.zeros(2), lin_frozen=xfrozen) assert len(fit.param) == 2 and len(fit_frozen.param) == 2 # ======================================================================
def assert_solver(solver): #============================================================ np.random.seed(1) t = np.linspace(-2, 4, 300) r = np.linspace(2, 6, 100) P = dd_gauss(r, 3, 0.2) K = dipolarkernel(t, r) V = K @ P + whitegaussnoise(t, 0.01) fit = snlls(V, K, lbl=np.zeros_like(r), nnlsSolver=solver, uq=False) assert ovl(P, fit.param) > 0.95 # more than 95% overlap
def test_frozen_param(): # ====================================================================== "Check that parameters can be frozen during the optimization" r = np.linspace(0, 6, 300) def model(param): mean1, mean2, width1, width2, amp1, amp2 = param return amp1 * dd_gauss(r, mean1, width1) + amp2 * dd_gauss( r, mean2, width2) y = model([3, 4, 0.2, 0.3, 0.5, 0.6]) par0 = [3.1, 4.2, 0.2, 0.3, 0.5, 0.6] lb = [0, 0, 0.01, 0.01, 0, 0] ub = [10, 10, 5, 5, 1, 1] frozenpars = [None, 4, None, 0.3, None, None] fit = snlls(y, model, par0, lb, ub) fit_frozen = snlls(y, model, par0, lb, ub, nonlin_frozen=frozenpars) assert np.allclose(fit_frozen.model, fit.model) and np.allclose( fit_frozen.model, y)
def test_goodness_of_fit_global(): #============================================================ "Check the goodness-of-fit statistics are correct with multiple signals" r, _, V1, V2, K1, K2 = generate_global_dataset() fit = snlls([V1, V2], [K1, K2], lbl=np.zeros_like(r), noiselvl=[0.01, 0.01]) stats = fit.stats assert (abs(stats[0]['chi2red'] - 1) < 5e-2) and (abs(stats[1]['chi2red'] - 1) < 5e-2)
def test_nonuniform_r(): #============================================================ "Check that fit works correctly with non-uniform distance vectors" t = np.linspace(0, 4, 300) r = np.sqrt(np.linspace(1, 7**2, 200)) P = dd_gauss(r, 3, 0.2) K = dipolarkernel(t, r) V = K @ P fit = snlls(V, K, lbl=np.zeros_like(r)) Vfit = K @ fit.param assert abs(Vfit[0] - 1) < 1e-6
def test_plot(): #============================================================ "Check the plotting method" t = np.linspace(0, 3, 200) r = np.linspace(1, 5, 100) P = dd_gauss(r, 3, 0.08) K = dipolarkernel(t, r) V = K @ P fit = snlls(V, K, lbl=np.zeros_like(r)) fig = fit.plot(show=False) assert str(fig.__class__) == "<class 'matplotlib.figure.Figure'>"
def test_convergence_criteria(): #============================================================ "Check that convergence criteria can be specified without crashing" t = np.linspace(0, 3, 200) r = np.linspace(1, 5, 100) P = dd_gauss(r, 3, 0.08) K = dipolarkernel(t, r) V = K @ P fit = snlls(V, K, lin_tol=1e-9, lin_maxiter=2e3, lbl=np.zeros_like(r)) assert ovl(P, fit.param) > 0.90 # more than 80% overlap