Example #1
0
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'>"
Example #2
0
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
Example #3
0
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
Example #4
0
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
Example #5
0
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
Example #6
0
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)
Example #7
0
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)
Example #8
0
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)
Example #9
0
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)
Example #10
0
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
Example #11
0
def test_regularized_global():
    #=======================================================================
    "Check global SNLLS of a nonlinear-constrained + linear-regularized problem"

    t1 = np.linspace(0, 3, 150)
    t2 = np.linspace(0, 4, 200)
    r = np.linspace(2.5, 5, 80)
    P = dd_gauss2(r, 3.7, 0.5, 0.5, 4.3, 0.3, 0.5)
    kappa = 0.50
    lam1 = 0.25
    lam2 = 0.35
    K1 = dipolarkernel(t1, r, mod=lam1, bg=bg_exp(t1, kappa))
    K2 = dipolarkernel(t2, r, mod=lam2, bg=bg_exp(t2, kappa))
    V1 = K1 @ P
    V2 = K2 @ P

    # Global non-linear model
    def globalKmodel(par):
        # Unpack parameters
        kappa, lam1, lam2 = par
        K1 = dipolarkernel(t1, r, mod=lam1, bg=bg_exp(t1, kappa))
        K2 = dipolarkernel(t2, r, mod=lam2, bg=bg_exp(t2, kappa))
        return K1, K2

    # Non-linear parameters
    # [kappa lambda1 lambda2]
    par0 = [0.5, 0.5, 0.5]
    lb = [0, 0, 0]
    ub = [1, 1, 1]
    # Linear parameters: non-negativity
    lbl = np.zeros(len(r))
    ubl = []

    # Separable LSQ fit
    fit = snlls([V1, V2], globalKmodel, par0, lb, ub, lbl, ubl, uq=False)
    Pfit = fit.lin

    assert ovl(P, Pfit) > 0.9