Beispiel #1
0
def new_solver_with_p(derivatives, sizes, max_order=2):

    if max_order == 1:
        [f_0, f_1] = derivatives
    elif max_order == 2:
        [f_0, f_1, f_2] = derivatives
    elif max_order == 3:
        [f_0, f_1, f_2, f_3] = derivatives
    diff = derivatives

    f = diff
    #n = f[0].shape[0] # number of variables
    #s = f[1].shape[1] - 3*n
    [n_v, n_s, n_p] = sizes

    n = n_v

    f1_A = f[1][:, :n]
    f1_B = f[1][:, n:(2 * n)]
    f1_C = f[1][:, (2 * n):(3 * n)]
    f1_D = f[1][:, (3 * n):((3 * n) + n_s)]
    f1_E = f[1][:, ((3 * n) + n_s):]

    ## first order
    [ev, g_x] = second_order_solver(f1_A, f1_B, f1_C)

    mm = np.dot(f1_A, g_x) + f1_B

    g_u = -np.linalg.solve(mm, f1_D)
    g_p = -np.linalg.solve(mm, f1_E)

    d = {'ev': ev, 'g_a': g_x, 'g_e': g_u, 'g_p': g_p}

    if max_order == 1:
        return d

    # we need it for higher order

    V_x = np.concatenate([
        np.dot(g_x, g_x), g_x,
        np.eye(n_v),
        np.zeros((n_s, n_v)),
        np.zeros((n_p, n_v))
    ])
    V_u = np.concatenate([
        np.dot(g_x, g_u), g_u,
        np.zeros((n_v, n_s)),
        np.eye(n_s),
        np.zeros((n_p, n_s))
    ])
    V_p = np.concatenate([
        np.dot(g_x, g_p), g_p,
        np.zeros((n_v, n_p)),
        np.zeros((n_s, n_p)),
        np.eye(n_p)
    ])
    V = [None, [V_x, V_u]]

    # Translation
    n_a = n_v
    n_e = n_s
    n_p = g_p.shape[1]

    f_1 = f[1]
    f_2 = f[2]
    f_d = f1_A
    f_a = f1_B
    f_h = f1_C
    f_u = f1_D
    V_a = V_x
    V_e = V_u
    g_a = g_x
    g_e = g_u

    # Once for all !
    A = f_a + sdot(f_d, g_a)
    B = f_d
    C = g_a
    A_inv = np.linalg.inv(A)

    #----------Computing order 2

    order = 2

    #--- Computing derivatives ('a', 'a')

    K_aa = +mdot(f_2, [V_a, V_a])
    L_aa = np.zeros((n_v, n_a, n_a))

    #We need to solve the infamous sylvester equation
    #A = f_a + sdot(f_d,g_a)
    #B = f_d
    #C = g_a
    D = K_aa + sdot(f_d, L_aa)
    g_aa = solve_sylvester(A, B, C, D)

    if order < max_order:
        Y = L_aa + mdot(g_a, [g_aa]) + mdot(g_aa, [g_a, g_a])
        Z = g_aa
        V_aa = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('a', 'e')

    K_ae = +mdot(f_2, [V_a, V_e])
    L_ae = +mdot(g_aa, [g_a, g_e])

    #We solve A*X + const = 0
    const = sdot(f_d, L_ae) + K_ae
    g_ae = -sdot(A_inv, const)

    if order < max_order:
        Y = L_ae + mdot(g_a, [g_ae])
        Z = g_ae
        V_ae = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('a', 'p')

    K_ap = +mdot(f_2, [V_a, V_p])
    L_ap = +mdot(g_aa, [g_a, g_p])

    #We solve A*X + const = 0
    const = sdot(f_d, L_ap) + K_ap
    g_ap = -sdot(A_inv, const)

    if order < max_order:
        Y = L_ap + mdot(g_a, [g_ap])
        Z = g_ap
        V_ap = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('e', 'e')

    K_ee = +mdot(f_2, [V_e, V_e])
    L_ee = +mdot(g_aa, [g_e, g_e])

    #We solve A*X + const = 0
    const = sdot(f_d, L_ee) + K_ee
    g_ee = -sdot(A_inv, const)

    if order < max_order:
        Y = L_ee + mdot(g_a, [g_ee])
        Z = g_ee
        V_ee = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('e', 'p')

    K_ep = +mdot(f_2, [V_e, V_p])
    L_ep = +mdot(g_aa, [g_e, g_p])

    #We solve A*X + const = 0
    const = sdot(f_d, L_ep) + K_ep
    g_ep = -sdot(A_inv, const)

    if order < max_order:
        Y = L_ep + mdot(g_a, [g_ep])
        Z = g_ep
        V_ep = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('p', 'p')

    K_pp = +mdot(f_2, [V_p, V_p])
    L_pp = +mdot(g_aa, [g_p, g_p])

    #We solve A*X + const = 0
    const = sdot(f_d, L_pp) + K_pp
    g_pp = -sdot(A_inv, const)

    if order < max_order:
        Y = L_pp + mdot(g_a, [g_pp])
        Z = g_pp
        V_pp = build_V(Y, Z, (n_a, n_e, n_p))

    d.update({
        'g_aa': g_aa,
        'g_ae': g_ae,
        'g_ee': g_ee,
        'g_ap': g_ap,
        'g_ep': g_ep,
        'g_pp': g_pp
    })
    if max_order == 2:
        return d

    #----------Computing order 3

    order = 3

    #--- Computing derivatives ('a', 'a', 'a')

    K_aaa = +3 * mdot(f_2, [V_a, V_aa]) + mdot(f_3, [V_a, V_a, V_a])
    L_aaa = +3 * mdot(g_aa, [g_a, g_aa])

    #We need to solve the infamous sylvester equation
    #A = f_a + sdot(f_d,g_a)
    #B = f_d
    #C = g_a
    D = K_aaa + sdot(f_d, L_aaa)
    g_aaa = solve_sylvester(A, B, C, D)

    if order < max_order:
        Y = L_aaa + mdot(g_a, [g_aaa]) + mdot(g_aaa, [g_a, g_a, g_a])
        Z = g_aaa
        V_aaa = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('a', 'a', 'e')

    K_aae = +mdot(f_2, [V_aa, V_e]) + 2 * mdot(f_2, [V_a, V_ae]) + mdot(
        f_3, [V_a, V_a, V_e])
    L_aae = +mdot(g_aa, [g_aa, g_e]) + 2 * mdot(g_aa, [g_a, g_ae]) + mdot(
        g_aaa, [g_a, g_a, g_e])

    #We solve A*X + const = 0
    const = sdot(f_d, L_aae) + K_aae
    g_aae = -sdot(A_inv, const)

    if order < max_order:
        Y = L_aae + mdot(g_a, [g_aae])
        Z = g_aae
        V_aae = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('a', 'a', 'p')

    K_aap = +mdot(f_2, [V_aa, V_p]) + 2 * mdot(f_2, [V_a, V_ap]) + mdot(
        f_3, [V_a, V_a, V_p])
    L_aap = +mdot(g_aa, [g_aa, g_p]) + 2 * mdot(g_aa, [g_a, g_ap]) + mdot(
        g_aaa, [g_a, g_a, g_p])

    #We solve A*X + const = 0
    const = sdot(f_d, L_aap) + K_aap
    g_aap = -sdot(A_inv, const)

    if order < max_order:
        Y = L_aap + mdot(g_a, [g_aap])
        Z = g_aap
        V_aap = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('a', 'e', 'e')

    K_aee = +2 * mdot(f_2, [V_ae, V_e]) + mdot(f_2, [V_a, V_ee]) + mdot(
        f_3, [V_a, V_e, V_e])
    L_aee = +2 * mdot(g_aa, [g_ae, g_e]) + mdot(g_aa, [g_a, g_ee]) + mdot(
        g_aaa, [g_a, g_e, g_e])

    #We solve A*X + const = 0
    const = sdot(f_d, L_aee) + K_aee
    g_aee = -sdot(A_inv, const)

    if order < max_order:
        Y = L_aee + mdot(g_a, [g_aee])
        Z = g_aee
        V_aee = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('a', 'e', 'p')
    ll = [
        mdot(f_2, [V_ae, V_p]),
        mdot(f_2, [V_ap, V_e]),
        mdot(f_2, [V_a, V_ep]),
        mdot(f_3, [V_a, V_e, V_p])
    ]
    l = [
        mdot(f_2, [V_ae, V_p]),
        mdot(f_2, [V_ap, V_e]).swapaxes(2, 3),
        mdot(f_2, [V_a, V_ep]),
        mdot(f_3, [V_a, V_e, V_p])
    ]

    K_aep = +mdot(f_2, [V_ae, V_p]) + mdot(f_2, [V_ap, V_e]).swapaxes(
        2, 3) + mdot(f_2, [V_a, V_ep]) + mdot(f_3, [V_a, V_e, V_p])
    L_aep = +mdot(g_aa, [g_ae, g_p]) + mdot(g_aa, [g_ap, g_e]).swapaxes(
        2, 3) + mdot(g_aa, [g_a, g_ep]) + mdot(g_aaa, [g_a, g_e, g_p])

    #We solve A*X + const = 0
    const = sdot(f_d, L_aep) + K_aep
    g_aep = -sdot(A_inv, const)

    if order < max_order:
        Y = L_aep + mdot(g_a, [g_aep])
        Z = g_aep
        V_aep = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('a', 'p', 'p')

    K_app = +2 * mdot(f_2, [V_ap, V_p]) + mdot(f_2, [V_a, V_pp]) + mdot(
        f_3, [V_a, V_p, V_p])
    L_app = +2 * mdot(g_aa, [g_ap, g_p]) + mdot(g_aa, [g_a, g_pp]) + mdot(
        g_aaa, [g_a, g_p, g_p])

    #We solve A*X + const = 0
    const = sdot(f_d, L_app) + K_app
    g_app = -sdot(A_inv, const)

    if order < max_order:
        Y = L_app + mdot(g_a, [g_app])
        Z = g_app
        V_app = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('e', 'e', 'e')

    K_eee = +3 * mdot(f_2, [V_e, V_ee]) + mdot(f_3, [V_e, V_e, V_e])
    L_eee = +3 * mdot(g_aa, [g_e, g_ee]) + mdot(g_aaa, [g_e, g_e, g_e])

    #We solve A*X + const = 0
    const = sdot(f_d, L_eee) + K_eee
    g_eee = -sdot(A_inv, const)

    if order < max_order:
        Y = L_eee + mdot(g_a, [g_eee])
        Z = g_eee
        V_eee = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('e', 'e', 'p')

    K_eep = +mdot(f_2, [V_ee, V_p]) + 2 * mdot(f_2, [V_e, V_ep]) + mdot(
        f_3, [V_e, V_e, V_p])
    L_eep = +mdot(g_aa, [g_ee, g_p]) + 2 * mdot(g_aa, [g_e, g_ep]) + mdot(
        g_aaa, [g_e, g_e, g_p])

    #We solve A*X + const = 0
    const = sdot(f_d, L_eep) + K_eep
    g_eep = -sdot(A_inv, const)

    if order < max_order:
        Y = L_eep + mdot(g_a, [g_eep])
        Z = g_eep
        V_eep = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('e', 'p', 'p')

    K_epp = +2 * mdot(f_2, [V_ep, V_p]) + mdot(f_2, [V_e, V_pp]) + mdot(
        f_3, [V_e, V_p, V_p])
    L_epp = +2 * mdot(g_aa, [g_ep, g_p]) + mdot(g_aa, [g_e, g_pp]) + mdot(
        g_aaa, [g_e, g_p, g_p])

    #We solve A*X + const = 0
    const = sdot(f_d, L_epp) + K_epp
    g_epp = -sdot(A_inv, const)

    if order < max_order:
        Y = L_epp + mdot(g_a, [g_epp])
        Z = g_epp
        V_epp = build_V(Y, Z, (n_a, n_e, n_p))

    #--- Computing derivatives ('p', 'p', 'p')

    K_ppp = +3 * mdot(f_2, [V_p, V_pp]) + mdot(f_3, [V_p, V_p, V_p])
    L_ppp = +3 * mdot(g_aa, [g_p, g_pp]) + mdot(g_aaa, [g_p, g_p, g_p])

    #We solve A*X + const = 0
    const = sdot(f_d, L_ppp) + K_ppp
    g_ppp = -sdot(A_inv, const)

    if order < max_order:
        Y = L_ppp + mdot(g_a, [g_ppp])
        Z = g_ppp
        V_ppp = build_V(Y, Z, (n_a, n_e, n_p))

    d.update({
        'g_aaa': g_aaa,
        'g_aae': g_aae,
        'g_aee': g_aee,
        'g_eee': g_eee,
        'g_aap': g_aap,
        'g_aep': g_aep,
        'g_eep': g_eep,
        'g_app': g_app,
        'g_epp': g_epp,
        'g_ppp': g_ppp
    })

    return d
Beispiel #2
0
def new_solver_with_p(derivatives, sizes, max_order=2):

    if max_order == 1:
        [f_0,f_1] = derivatives
    elif max_order == 2:
        [f_0,f_1,f_2] = derivatives
    elif max_order == 3:
        [f_0,f_1,f_2,f_3] = derivatives
    derivs = derivatives

    f = derivs
    #n = f[0].shape[0] # number of variables
    #s = f[1].shape[1] - 3*n
    [n_v,n_s,n_p] = sizes

    n = n_v

    f1_A = f[1][:,:n]
    f1_B = f[1][:,n:(2*n)]
    f1_C = f[1][:,(2*n):(3*n)]
    f1_D = f[1][:,(3*n):((3*n)+n_s)]
    f1_E = f[1][:,((3*n)+n_s):]

    ## first order
    [ev,g_x] = second_order_solver(f1_A,f1_B,f1_C)

    mm = np.dot(f1_A, g_x) + f1_B

    g_u = - np.linalg.solve( mm , f1_D )
    g_p = - np.linalg.solve( mm , f1_E )

    d = {
        'ev':ev,
        'g_a':g_x,
        'g_e':g_u,
        'g_p':g_p
    }

    if max_order == 1:
        return d

    # we need it for higher order

    V_x = np.concatenate( [np.dot(g_x,g_x),g_x,np.eye(n_v),np.zeros((n_s,n_v)), np.zeros((n_p,n_v))] )
    V_u = np.concatenate( [np.dot(g_x,g_u),g_u,np.zeros((n_v,n_s)),np.eye(n_s), np.zeros((n_p,n_s))] )
    V_p = np.concatenate( [np.dot(g_x,g_p),g_p,np.zeros((n_v,n_p)),np.zeros((n_s,n_p)), np.eye(n_p)] )
    V = [None, [V_x,V_u]]

    # Translation
    n_a = n_v
    n_e = n_s
    n_p = g_p.shape[1]

    f_1 = f[1]
    f_2 = f[2]
    f_d = f1_A
    f_a = f1_B
    f_h = f1_C
    f_u = f1_D
    V_a = V_x
    V_e = V_u
    g_a = g_x
    g_e = g_u

    # Once for all !
    A = f_a + sdot(f_d,g_a)
    B = f_d
    C = g_a
    A_inv = np.linalg.inv(A)

    #----------Computing order 2

    order = 2

    #--- Computing derivatives ('a', 'a')

    K_aa =  + mdot(f_2,[V_a,V_a])
    L_aa = np.zeros((n_v, n_a, n_a))

    #We need to solve the infamous sylvester equation
    #A = f_a + sdot(f_d,g_a)
    #B = f_d
    #C = g_a
    D =  K_aa + sdot(f_d,L_aa)
    g_aa = solve_sylvester(A,B,C,D)

    if order < max_order:
        Y = L_aa + mdot(g_a,[g_aa]) + mdot(g_aa,[g_a,g_a])
        Z = g_aa
        V_aa = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('a', 'e')

    K_ae =  + mdot(f_2,[V_a,V_e])
    L_ae =  + mdot(g_aa,[g_a,g_e])

    #We solve A*X + const = 0
    const = sdot(f_d,L_ae) + K_ae
    g_ae = - sdot(A_inv, const)

    if order < max_order:
        Y = L_ae + mdot(g_a,[g_ae])
        Z = g_ae
        V_ae = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('a', 'p')

    K_ap =  + mdot(f_2,[V_a,V_p])
    L_ap =  + mdot(g_aa,[g_a,g_p])

    #We solve A*X + const = 0
    const = sdot(f_d,L_ap) + K_ap
    g_ap = - sdot(A_inv, const)

    if order < max_order:
        Y = L_ap + mdot(g_a,[g_ap])
        Z = g_ap
        V_ap = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('e', 'e')

    K_ee =  + mdot(f_2,[V_e,V_e])
    L_ee =  + mdot(g_aa,[g_e,g_e])

    #We solve A*X + const = 0
    const = sdot(f_d,L_ee) + K_ee
    g_ee = - sdot(A_inv, const)

    if order < max_order:
        Y = L_ee + mdot(g_a,[g_ee])
        Z = g_ee
        V_ee = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('e', 'p')

    K_ep =  + mdot(f_2,[V_e,V_p])
    L_ep =  + mdot(g_aa,[g_e,g_p])

    #We solve A*X + const = 0
    const = sdot(f_d,L_ep) + K_ep
    g_ep = - sdot(A_inv, const)

    if order < max_order:
        Y = L_ep + mdot(g_a,[g_ep])
        Z = g_ep
        V_ep = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('p', 'p')

    K_pp =  + mdot(f_2,[V_p,V_p])
    L_pp =  + mdot(g_aa,[g_p,g_p])

    #We solve A*X + const = 0
    const = sdot(f_d,L_pp) + K_pp
    g_pp = - sdot(A_inv, const)

    if order < max_order:
        Y = L_pp + mdot(g_a,[g_pp])
        Z = g_pp
        V_pp = build_V(Y,Z,(n_a,n_e,n_p))


    d.update({
        'g_aa':g_aa,
        'g_ae':g_ae,
        'g_ee':g_ee,
        'g_ap':g_ap,
        'g_ep':g_ep,
        'g_pp':g_pp
     })
    if max_order == 2:
        return d

    #----------Computing order 3

    order = 3

    #--- Computing derivatives ('a', 'a', 'a')

    K_aaa =  + 3*mdot(f_2,[V_a,V_aa]) + mdot(f_3,[V_a,V_a,V_a])
    L_aaa =  + 3*mdot(g_aa,[g_a,g_aa])

    #We need to solve the infamous sylvester equation
    #A = f_a + sdot(f_d,g_a)
    #B = f_d
    #C = g_a
    D = K_aaa + sdot(f_d,L_aaa)
    g_aaa = solve_sylvester(A,B,C,D)

    if order < max_order:
        Y = L_aaa + mdot(g_a,[g_aaa]) + mdot(g_aaa,[g_a,g_a,g_a])
        Z = g_aaa
        V_aaa = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('a', 'a', 'e')

    K_aae =  + mdot(f_2,[V_aa,V_e]) + 2*mdot(f_2,[V_a,V_ae]) + mdot(f_3,[V_a,V_a,V_e])
    L_aae =  + mdot(g_aa,[g_aa,g_e]) + 2*mdot(g_aa,[g_a,g_ae]) + mdot(g_aaa,[g_a,g_a,g_e])

    #We solve A*X + const = 0
    const = sdot(f_d,L_aae) + K_aae
    g_aae = - sdot(A_inv, const)

    if order < max_order:
        Y = L_aae + mdot(g_a,[g_aae])
        Z = g_aae
        V_aae = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('a', 'a', 'p')

    K_aap =  + mdot(f_2,[V_aa,V_p]) + 2*mdot(f_2,[V_a,V_ap]) + mdot(f_3,[V_a,V_a,V_p])
    L_aap =  + mdot(g_aa,[g_aa,g_p]) + 2*mdot(g_aa,[g_a,g_ap]) + mdot(g_aaa,[g_a,g_a,g_p])

    #We solve A*X + const = 0
    const = sdot(f_d,L_aap) + K_aap
    g_aap = - sdot(A_inv, const)

    if order < max_order:
        Y = L_aap + mdot(g_a,[g_aap])
        Z = g_aap
        V_aap = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('a', 'e', 'e')

    K_aee =  + 2*mdot(f_2,[V_ae,V_e]) + mdot(f_2,[V_a,V_ee]) + mdot(f_3,[V_a,V_e,V_e])
    L_aee =  + 2*mdot(g_aa,[g_ae,g_e]) + mdot(g_aa,[g_a,g_ee]) + mdot(g_aaa,[g_a,g_e,g_e])

    #We solve A*X + const = 0
    const = sdot(f_d,L_aee) + K_aee
    g_aee = - sdot(A_inv, const)

    if order < max_order:
        Y = L_aee + mdot(g_a,[g_aee])
        Z = g_aee
        V_aee = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('a', 'e', 'p')
    ll = [ mdot(f_2,[V_ae,V_p]) , mdot(f_2,[V_ap,V_e]), mdot(f_2,[V_a,V_ep]) , mdot(f_3,[V_a,V_e,V_p])     ]
    l = [ mdot(f_2,[V_ae,V_p]) , mdot(f_2,[V_ap,V_e]).swapaxes(2,3) , mdot(f_2,[V_a,V_ep]) , mdot(f_3,[V_a,V_e,V_p])     ]

    K_aep =  + mdot(f_2,[V_ae,V_p]) + mdot(f_2,[V_ap,V_e]).swapaxes(2,3) + mdot(f_2,[V_a,V_ep]) + mdot(f_3,[V_a,V_e,V_p])
    L_aep =  + mdot(g_aa,[g_ae,g_p]) + mdot(g_aa,[g_ap,g_e]).swapaxes(2,3) + mdot(g_aa,[g_a,g_ep]) + mdot(g_aaa,[g_a,g_e,g_p])

    #We solve A*X + const = 0
    const = sdot(f_d,L_aep) + K_aep
    g_aep = - sdot(A_inv, const)

    if order < max_order:
        Y = L_aep + mdot(g_a,[g_aep])
        Z = g_aep
        V_aep = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('a', 'p', 'p')

    K_app =  + 2*mdot(f_2,[V_ap,V_p]) + mdot(f_2,[V_a,V_pp]) + mdot(f_3,[V_a,V_p,V_p])
    L_app =  + 2*mdot(g_aa,[g_ap,g_p]) + mdot(g_aa,[g_a,g_pp]) + mdot(g_aaa,[g_a,g_p,g_p])

    #We solve A*X + const = 0
    const = sdot(f_d,L_app) + K_app
    g_app = - sdot(A_inv, const)

    if order < max_order:
        Y = L_app + mdot(g_a,[g_app])
        Z = g_app
        V_app = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('e', 'e', 'e')

    K_eee =  + 3*mdot(f_2,[V_e,V_ee]) + mdot(f_3,[V_e,V_e,V_e])
    L_eee =  + 3*mdot(g_aa,[g_e,g_ee]) + mdot(g_aaa,[g_e,g_e,g_e])

    #We solve A*X + const = 0
    const = sdot(f_d,L_eee) + K_eee
    g_eee = - sdot(A_inv, const)

    if order < max_order:
        Y = L_eee + mdot(g_a,[g_eee])
        Z = g_eee
        V_eee = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('e', 'e', 'p')

    K_eep =  + mdot(f_2,[V_ee,V_p]) + 2*mdot(f_2,[V_e,V_ep]) + mdot(f_3,[V_e,V_e,V_p])
    L_eep =  + mdot(g_aa,[g_ee,g_p]) + 2*mdot(g_aa,[g_e,g_ep]) + mdot(g_aaa,[g_e,g_e,g_p])

    #We solve A*X + const = 0
    const = sdot(f_d,L_eep) + K_eep
    g_eep = - sdot(A_inv, const)

    if order < max_order:
        Y = L_eep + mdot(g_a,[g_eep])
        Z = g_eep
        V_eep = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('e', 'p', 'p')

    K_epp =  + 2*mdot(f_2,[V_ep,V_p]) + mdot(f_2,[V_e,V_pp]) + mdot(f_3,[V_e,V_p,V_p])
    L_epp =  + 2*mdot(g_aa,[g_ep,g_p]) + mdot(g_aa,[g_e,g_pp]) + mdot(g_aaa,[g_e,g_p,g_p])

    #We solve A*X + const = 0
    const = sdot(f_d,L_epp) + K_epp
    g_epp = - sdot(A_inv, const)

    if order < max_order:
        Y = L_epp + mdot(g_a,[g_epp])
        Z = g_epp
        V_epp = build_V(Y,Z,(n_a,n_e,n_p))

    #--- Computing derivatives ('p', 'p', 'p')

    K_ppp =  + 3*mdot(f_2,[V_p,V_pp]) + mdot(f_3,[V_p,V_p,V_p])
    L_ppp =  + 3*mdot(g_aa,[g_p,g_pp]) + mdot(g_aaa,[g_p,g_p,g_p])

    #We solve A*X + const = 0
    const = sdot(f_d,L_ppp) + K_ppp
    g_ppp = - sdot(A_inv, const)

    if order < max_order:
        Y = L_ppp + mdot(g_a,[g_ppp])
        Z = g_ppp
        V_ppp = build_V(Y,Z,(n_a,n_e,n_p))


    d.update({
        'g_aaa':g_aaa,
        'g_aae':g_aae,
        'g_aee':g_aee,
        'g_eee':g_eee,
        'g_aap':g_aap,
        'g_aep':g_aep,
        'g_eep':g_eep,
        'g_app':g_app,
        'g_epp':g_epp,
        'g_ppp':g_ppp
    })

    return d
Beispiel #3
0
def perturb_solver(derivatives,
                   Sigma,
                   max_order=2,
                   derivatives_ss=None,
                   mlab=None):

    if max_order == 1:
        [f_0, f_1] = derivatives
    elif max_order == 2:
        [f_0, f_1, f_2] = derivatives
    elif max_order == 3:
        [f_0, f_1, f_2, f_3] = derivatives
    else:
        raise Exception(
            'Perturbations not implemented at order {0}'.format(max_order))
    diff = derivatives

    f = diff
    n = f[0].shape[0]  # number of variables
    s = f[1].shape[1] - 3 * n
    [n_v, n_s] = [n, s]

    f1_A = f[1][:, :n]
    f1_B = f[1][:, n:(2 * n)]
    f1_C = f[1][:, (2 * n):(3 * n)]
    f1_D = f[1][:, (3 * n):]

    ## first order
    [ev, g_x] = second_order_solver(f1_A, f1_B, f1_C)

    res = np.dot(f1_A, np.dot(g_x, g_x)) + np.dot(f1_B, g_x) + f1_C

    mm = np.dot(f1_A, g_x) + f1_B

    g_u = -np.linalg.solve(mm, f1_D)

    if max_order == 1:
        d = {'ev': ev, 'g_a': g_x, 'g_e': g_u}
        return d

    # we need it for higher order
    V_a = np.concatenate(
        [np.dot(g_x, g_x), g_x,
         np.eye(n_v), np.zeros((s, n))])
    V_e = np.concatenate(
        [np.dot(g_x, g_u), g_u,
         np.zeros((n_v, n_s)),
         np.eye(n_s)])

    # Translation

    f_1 = f[1]
    f_2 = f[2]
    f_d = f1_A
    f_a = f1_B
    g_a = g_x
    g_e = g_u
    n_a = n_v
    n_e = n_s

    # Once for all !
    A = f_a + sdot(f_d, g_a)
    B = f_d
    C = g_a
    A_inv = np.linalg.inv(A)

    ##################
    # Automatic code #
    ##################

    #----------Computing order 2

    order = 2

    #--- Computing derivatives ('a', 'a')

    K_aa = +mdot(f_2, [V_a, V_a])
    L_aa = np.zeros((n_v, n_v, n_v))

    #We need to solve the infamous sylvester equation
    #A = f_a + sdot(f_d,g_a)
    #B = f_d
    #C = g_a
    D = K_aa + sdot(f_d, L_aa)
    if mlab == None:
        g_aa = solve_sylvester(A, B, C, D)
    else:
        n_d = D.ndim - 1
        n_v = C.shape[1]
        CC = np.kron(C, C)
        DD = D.reshape(n_v, n_v**n_d)
        [err, E] = mlab.gensylv(2, A, B, C, DD, nout=2)
        g_aa = -E.reshape((n_v, n_v, n_v))  # check that - is correct

    if order < max_order:
        Y = L_aa + mdot(g_a, [g_aa]) + mdot(g_aa, [g_a, g_a])
        assert (abs(mdot(g_a, [g_aa]) - sdot(g_a, g_aa)).max() == 0)
        Z = g_aa
        V_aa = build_V(Y, Z, (n_a, n_e))

    #--- Computing derivatives ('a', 'e')

    K_ae = +mdot(f_2, [V_a, V_e])
    L_ae = +mdot(g_aa, [g_a, g_e])

    #We solve A*X + const = 0
    const = sdot(f_d, L_ae) + K_ae
    g_ae = -sdot(A_inv, const)

    if order < max_order:
        Y = L_ae + mdot(g_a, [g_ae])
        Z = g_ae
        V_ae = build_V(Y, Z, (n_a, n_e))

    #--- Computing derivatives ('e', 'e')

    K_ee = +mdot(f_2, [V_e, V_e])
    L_ee = +mdot(g_aa, [g_e, g_e])

    #We solve A*X + const = 0
    const = sdot(f_d, L_ee) + K_ee
    g_ee = -sdot(A_inv, const)

    if order < max_order:
        Y = L_ee + mdot(g_a, [g_ee])
        Z = g_ee
        V_ee = build_V(Y, Z, (n_a, n_e))

    # manual
    I = np.eye(n_v, n_v)
    M_inv = np.linalg.inv(sdot(f1_A, g_a + I) + f1_B)
    K_ss = mdot(f_2[:, :n_v, :n_v], [g_e, g_e]) + sdot(f1_A, g_ee)
    rhs = -np.tensordot(K_ss, Sigma, axes=((1, 2),
                                           (0, 1)))  #- mdot(h_2,[V_s,V_s])
    if derivatives_ss:
        f_ss = derivatives_ss[0]
        rhs -= f_ss
    g_ss = sdot(M_inv, rhs)
    ghs2 = g_ss / 2

    if max_order == 2:
        d = {
            'ev': ev,
            'g_a': g_a,
            'g_e': g_e,
            'g_aa': g_aa,
            'g_ae': g_ae,
            'g_ee': g_ee,
            'g_ss': g_ss
        }
        return d
    # /manual

    #----------Computing order 3

    order = 3

    #--- Computing derivatives ('a', 'a', 'a')
    K_aaa = +3 * mdot(f_2, [V_a, V_aa]) + mdot(f_3, [V_a, V_a, V_a])
    L_aaa = +3 * mdot(g_aa, [g_a, g_aa])

    #K_aaa =  2*( mdot(f_2,[V_aa,V_a]) ) + mdot(f_2,[V_a,V_aa]) + mdot(f_3,[V_a,V_a,V_a])
    #L_aaa =  2*( mdot(g_aa,[g_aa,g_a]) ) + mdot(g_aa,[g_a,g_aa])
    #K_aaa =  ( mdot(f_2,[V_aa,V_a]) + mdot(f_2,[V_a,V_aa]) )*3.0/2.0 + mdot(f_3,[V_a,V_a,V_a])
    #L_aaa =  ( mdot(g_aa,[g_aa,g_a]) + mdot(g_aa,[g_a,g_aa]) )*3.0/2.0

    #K_aaa = (K_aaa + K_aaa.swapaxes(3,2) + K_aaa.swapaxes(1,2) + K_aaa.swapaxes(1,2).swapaxes(2,3) + K_aaa.swapaxes(1,3) + K_aaa.swapaxes(1,3).swapaxes(2,3) )/6
    #L_aaa = (L_aaa + L_aaa.swapaxes(3,2) + L_aaa.swapaxes(1,2) + L_aaa.swapaxes(1,2).swapaxes(2,3) + L_aaa.swapaxes(1,3) + L_aaa.swapaxes(1,3).swapaxes(2,3) )/6

    #We need to solve the infamous sylvester equation
    #A = f_a + sdot(f_d,g_a)
    #B = f_d
    #C = g_a
    D = K_aaa + sdot(f_d, L_aaa)

    if mlab == None:
        g_aaa = solve_sylvester(A, B, C, D)
    # this is much much faster
    else:
        n_d = D.ndim - 1
        n_v = C.shape[1]
        CC = np.kron(np.kron(C, C), C)
        DD = D.reshape(n_v, n_v**n_d)
        [err, E] = mlab.gensylv(3, A, B, C, DD, nout=2)
        g_aaa = E.reshape((n_v, n_v, n_v, n_v))

    #res = sdot(A,g_aaa) + sdot(B, mdot(g_aaa,[C,C,C])) - D
    #print 'res : ' + str( abs(res).max() )

    if order < max_order:
        Y = L_aaa + mdot(g_a, [g_aaa]) + mdot(g_aaa, [g_a, g_a, g_a])
        Z = g_aaa
        V_aaa = build_V(Y, Z, (n_a, n_e))

    # we transform g_aaa into a symmetric multilinear form
    g_aaa = (g_aaa + g_aaa.swapaxes(3, 2) + g_aaa.swapaxes(1, 2) +
             g_aaa.swapaxes(1, 2).swapaxes(2, 3) + g_aaa.swapaxes(1, 3) +
             g_aaa.swapaxes(1, 3).swapaxes(2, 3)) / 6

    #--- Computing derivatives ('a', 'a', 'e')

    K_aae = +mdot(f_2, [V_aa, V_e]) + 2 * mdot(f_2, [V_a, V_ae]) + mdot(
        f_3, [V_a, V_a, V_e])
    L_aae = +mdot(g_aa, [g_aa, g_e]) + 2 * mdot(g_aa, [g_a, g_ae]) + mdot(
        g_aaa, [g_a, g_a, g_e])

    #We solve A*X + const = 0
    const = sdot(f_d, L_aae) + K_aae
    g_aae = -sdot(A_inv, const)

    if order < max_order:
        Y = L_aae + mdot(g_a, [g_aae])
        Z = g_aae
        V_aae = build_V(Y, Z, (n_a, n_e))

    #--- Computing derivatives ('a', 'e', 'e')

    K_aee = +2 * mdot(f_2, [V_ae, V_e]) + mdot(f_2, [V_a, V_ee]) + mdot(
        f_3, [V_a, V_e, V_e])
    L_aee = +2 * mdot(g_aa, [g_ae, g_e]) + mdot(g_aa, [g_a, g_ee]) + mdot(
        g_aaa, [g_a, g_e, g_e])

    #We solve A*X + const = 0
    const = sdot(f_d, L_aee) + K_aee
    g_aee = -sdot(A_inv, const)

    if order < max_order:
        Y = L_aee + mdot(g_a, [g_aee])
        Z = g_aee
        V_aee = build_V(Y, Z, (n_a, n_e))

    #--- Computing derivatives ('e', 'e', 'e')

    K_eee = +3 * mdot(f_2, [V_e, V_ee]) + mdot(f_3, [V_e, V_e, V_e])
    L_eee = +3 * mdot(g_aa, [g_e, g_ee]) + mdot(g_aaa, [g_e, g_e, g_e])

    #We solve A*X + const = 0
    const = sdot(f_d, L_eee) + K_eee
    g_eee = -sdot(A_inv, const)

    if order < max_order:
        Y = L_eee + mdot(g_a, [g_eee])
        Z = g_eee
        V_eee = build_V(Y, Z, (n_a, n_e))

    ####################################
    ## Compute sigma^2 correction term #
    ####################################

    # ( a s s )

    A = f_a + sdot(f_d, g_a)
    I_e = np.eye(n_e)

    Y = g_e
    Z = np.zeros((n_a, n_e))
    V_s = build_V(Y, Z, (n_a, n_e))

    Y = mdot(g_ae, [g_a, I_e])
    Z = np.zeros((n_a, n_a, n_e))
    V_as = build_V(Y, Z, (n_a, n_e))

    Y = sdot(g_a, g_ss) + g_ss + np.tensordot(g_ee, Sigma)
    Z = g_ss
    V_ss = build_V(Y, Z, (n_a, n_e))

    K_ass_1 = 2 * mdot(f_2, [V_as, V_s]) + mdot(f_3, [V_a, V_s, V_s])
    K_ass_1 = np.tensordot(K_ass_1, Sigma)

    K_ass_2 = mdot(f_2, [V_a, V_ss])

    K_ass = K_ass_1 + K_ass_2

    L_ass = mdot(g_aa, [g_a, g_ss]) + np.tensordot(
        mdot(g_aee, [g_a, I_e, I_e]), Sigma)

    D = K_ass + sdot(f_d, L_ass)

    if derivatives_ss:
        f_1ss = derivatives_ss[1]
        D += mdot(f_1ss, [V_a]) + sdot(f1_A, mdot(g_aa, [g_a, g_ss]))

    g_ass = solve_sylvester(A, B, C, D)

    # ( e s s )

    A = f_a + sdot(f_d, g_a)
    A_inv = np.linalg.inv(A)
    I_e = np.eye(n_e)

    Y = g_e
    Z = np.zeros((n_a, n_e))
    V_s = build_V(Y, Z, (n_a, n_e))

    Y = mdot(g_ae, [g_e, I_e])
    Z = np.zeros((n_a, n_e, n_e))
    V_es = build_V(Y, Z, (n_a, n_e))

    Y = sdot(g_a, g_ss) + g_ss + np.tensordot(g_ee, Sigma)
    Z = g_ss
    V_ss = build_V(Y, Z, (n_a, n_e))

    K_ess_1 = 2 * mdot(f_2, [V_es, V_s]) + mdot(f_3, [V_e, V_s, V_s])
    K_ess_1 = np.tensordot(K_ess_1, Sigma)

    K_ess_2 = mdot(f_2, [V_e, V_ss])

    K_ess = K_ess_1 + K_ess_2

    L_ess = mdot(g_aa, [g_e, g_ss]) + np.tensordot(
        mdot(g_aee, [g_e, I_e, I_e]), Sigma)
    L_ess += mdot(g_ass, [g_e])

    D = K_ess + sdot(f_d, L_ess)

    g_ess = sdot(A_inv, -D)

    if max_order == 3:
        d = {
            'ev': ev,
            'g_a': g_a,
            'g_e': g_e,
            'g_aa': g_aa,
            'g_ae': g_ae,
            'g_ee': g_ee,
            'g_aaa': g_aaa,
            'g_aae': g_aae,
            'g_aee': g_aee,
            'g_eee': g_eee,
            'g_ss': g_ss,
            'g_ass': g_ass,
            'g_ess': g_ess
        }
        return d
Beispiel #4
0
def perturb_solver(derivatives, Sigma, max_order=2, derivatives_ss=None, mlab=None):


    if max_order == 1:
        [f_0,f_1] = derivatives
    elif max_order == 2:
        [f_0,f_1,f_2] = derivatives
    elif max_order == 3:
        [f_0,f_1,f_2,f_3] = derivatives
    else:
        raise Exception('Perturbations not implemented at order {0}'.format(max_order))
    derivs = derivatives

    f = derivs
    n = f[0].shape[0] # number of variables
    s = f[1].shape[1] - 3*n
    [n_v,n_s] = [n,s]


    f1_A = f[1][:,:n]
    f1_B = f[1][:,n:(2*n)]
    f1_C = f[1][:,(2*n):(3*n)]
    f1_D = f[1][:,(3*n):]

    ## first order
    [ev,g_x] = second_order_solver(f1_A,f1_B,f1_C)

    res = np.dot(f1_A,np.dot(g_x,g_x)) + np.dot(f1_B,g_x) + f1_C

    mm = np.dot(f1_A, g_x) + f1_B

    g_u = - np.linalg.solve( mm , f1_D )

    if max_order == 1:
        d = {'ev':ev, 'g_a': g_x, 'g_e': g_u}
        return d

    # we need it for higher order
    V_a = np.concatenate( [np.dot(g_x,g_x),g_x,np.eye(n_v),np.zeros((s,n))] )
    V_e = np.concatenate( [np.dot(g_x,g_u),g_u,np.zeros((n_v,n_s)),np.eye(n_s)] )

    # Translation

    f_1 = f[1]
    f_2 = f[2]
    f_d = f1_A
    f_a = f1_B
    g_a = g_x
    g_e = g_u
    n_a = n_v
    n_e = n_s

    # Once for all !
    A = f_a + sdot(f_d,g_a)
    B = f_d
    C = g_a
    A_inv = np.linalg.inv(A)


    ##################
    # Automatic code #
    ##################

    #----------Computing order 2

    order = 2

    #--- Computing derivatives ('a', 'a')

    K_aa =  + mdot(f_2,[V_a,V_a])
    L_aa = np.zeros( (n_v, n_v, n_v) )

    #We need to solve the infamous sylvester equation
    #A = f_a + sdot(f_d,g_a)
    #B = f_d
    #C = g_a
    D = K_aa + sdot(f_d,L_aa)
    if mlab==None:
        g_aa = solve_sylvester(A,B,C,D)
    else:
        n_d = D.ndim - 1
        n_v = C.shape[1]
        CC = np.kron(C,C)
        DD = D.reshape( n_v, n_v**n_d )
        [err,E] = mlab.gensylv(2,A,B,C,DD,nout=2)
        g_aa = - E.reshape((n_v,n_v,n_v)) # check that - is correct


    if order < max_order:
        Y = L_aa + mdot(g_a,[g_aa]) + mdot(g_aa,[g_a,g_a])
        assert( abs(mdot(g_a,[g_aa]) - sdot(g_a,g_aa)).max() == 0)
        Z = g_aa
        V_aa = build_V(Y,Z,(n_a,n_e))

    #--- Computing derivatives ('a', 'e')

    K_ae =  + mdot(f_2,[V_a,V_e])
    L_ae =  + mdot(g_aa,[g_a,g_e])

    #We solve A*X + const = 0
    const = sdot(f_d,L_ae) + K_ae
    g_ae = - sdot(A_inv, const)

    if order < max_order:
        Y = L_ae + mdot(g_a,[g_ae])
        Z = g_ae
        V_ae = build_V(Y,Z,(n_a,n_e))

    #--- Computing derivatives ('e', 'e')

    K_ee =  + mdot(f_2,[V_e,V_e])
    L_ee =  + mdot(g_aa,[g_e,g_e])

    #We solve A*X + const = 0
    const = sdot(f_d,L_ee) + K_ee
    g_ee = - sdot(A_inv, const)

    if order < max_order:
        Y = L_ee + mdot(g_a,[g_ee])
        Z = g_ee
        V_ee = build_V(Y,Z,(n_a,n_e))

    # manual
    I = np.eye(n_v,n_v)
    M_inv = np.linalg.inv( sdot(f1_A,g_a+I) + f1_B )
    K_ss = mdot(f_2[:,:n_v,:n_v],[g_e,g_e]) + sdot( f1_A, g_ee )
    rhs =  - np.tensordot( K_ss, Sigma, axes=((1,2),(0,1)) ) #- mdot(h_2,[V_s,V_s])
    if derivatives_ss:
        f_ss = derivatives_ss[0]
        rhs -= f_ss
    g_ss = sdot(M_inv,rhs)
    ghs2 = g_ss/2



    if max_order == 2:
        d = {
            'ev': ev,
            'g_a': g_a,
            'g_e': g_e,
            'g_aa': g_aa,
            'g_ae': g_ae,
            'g_ee': g_ee,
            'g_ss': g_ss
        }
        return d
    # /manual

    #----------Computing order 3

    order = 3

    #--- Computing derivatives ('a', 'a', 'a')
    K_aaa =  + 3*mdot(f_2,[V_a,V_aa]) + mdot(f_3,[V_a,V_a,V_a])
    L_aaa =  + 3*mdot(g_aa,[g_a,g_aa])

    #K_aaa =  2*( mdot(f_2,[V_aa,V_a]) ) + mdot(f_2,[V_a,V_aa]) + mdot(f_3,[V_a,V_a,V_a])
    #L_aaa =  2*( mdot(g_aa,[g_aa,g_a]) ) + mdot(g_aa,[g_a,g_aa])
    #K_aaa =  ( mdot(f_2,[V_aa,V_a]) + mdot(f_2,[V_a,V_aa]) )*3.0/2.0 + mdot(f_3,[V_a,V_a,V_a])
    #L_aaa =  ( mdot(g_aa,[g_aa,g_a]) + mdot(g_aa,[g_a,g_aa]) )*3.0/2.0


    #K_aaa = (K_aaa + K_aaa.swapaxes(3,2) + K_aaa.swapaxes(1,2) + K_aaa.swapaxes(1,2).swapaxes(2,3) + K_aaa.swapaxes(1,3) + K_aaa.swapaxes(1,3).swapaxes(2,3) )/6
    #L_aaa = (L_aaa + L_aaa.swapaxes(3,2) + L_aaa.swapaxes(1,2) + L_aaa.swapaxes(1,2).swapaxes(2,3) + L_aaa.swapaxes(1,3) + L_aaa.swapaxes(1,3).swapaxes(2,3) )/6


    #We need to solve the infamous sylvester equation
    #A = f_a + sdot(f_d,g_a)
    #B = f_d
    #C = g_a
    D = K_aaa + sdot(f_d,L_aaa)



    if mlab == None:
        g_aaa = solve_sylvester(A,B,C,D)
    # this is much much faster
    else:
        n_d = D.ndim - 1
        n_v = C.shape[1]
        CC = np.kron(np.kron(C,C),C)
        DD = D.reshape( n_v, n_v**n_d )
        [err,E] = mlab.gensylv(3,A,B,C,DD,nout=2)
        g_aaa = E.reshape((n_v,n_v,n_v,n_v))

    #res = sdot(A,g_aaa) + sdot(B, mdot(g_aaa,[C,C,C])) - D
    #print 'res : ' + str( abs(res).max() )


    if order < max_order:
        Y = L_aaa + mdot(g_a,[g_aaa]) + mdot(g_aaa,[g_a,g_a,g_a])
        Z = g_aaa
        V_aaa = build_V(Y,Z,(n_a,n_e))

    # we transform g_aaa into a symmetric multilinear form
    g_aaa = (g_aaa + g_aaa.swapaxes(3,2) + g_aaa.swapaxes(1,2) + g_aaa.swapaxes(1,2).swapaxes(2,3) + g_aaa.swapaxes(1,3) + g_aaa.swapaxes(1,3).swapaxes(2,3) )/6

    #--- Computing derivatives ('a', 'a', 'e')

    K_aae =  + mdot(f_2,[V_aa,V_e]) + 2*mdot(f_2,[V_a,V_ae]) + mdot(f_3,[V_a,V_a,V_e])
    L_aae =  + mdot(g_aa,[g_aa,g_e]) + 2*mdot(g_aa,[g_a,g_ae]) + mdot(g_aaa,[g_a,g_a,g_e])

    #We solve A*X + const = 0
    const = sdot(f_d,L_aae) + K_aae
    g_aae = - sdot(A_inv, const)

    if order < max_order:
        Y = L_aae + mdot(g_a,[g_aae])
        Z = g_aae
        V_aae = build_V(Y,Z,(n_a,n_e))

    #--- Computing derivatives ('a', 'e', 'e')

    K_aee =  + 2*mdot(f_2,[V_ae,V_e]) + mdot(f_2,[V_a,V_ee]) + mdot(f_3,[V_a,V_e,V_e])
    L_aee =  + 2*mdot(g_aa,[g_ae,g_e]) + mdot(g_aa,[g_a,g_ee]) + mdot(g_aaa,[g_a,g_e,g_e])

    #We solve A*X + const = 0
    const = sdot(f_d,L_aee) + K_aee
    g_aee = - sdot(A_inv, const)

    if order < max_order:
        Y = L_aee + mdot(g_a,[g_aee])
        Z = g_aee
        V_aee = build_V(Y,Z,(n_a,n_e))

    #--- Computing derivatives ('e', 'e', 'e')

    K_eee =  + 3*mdot(f_2,[V_e,V_ee]) + mdot(f_3,[V_e,V_e,V_e])
    L_eee =  + 3*mdot(g_aa,[g_e,g_ee]) + mdot(g_aaa,[g_e,g_e,g_e])

    #We solve A*X + const = 0
    const = sdot(f_d,L_eee) + K_eee
    g_eee = - sdot(A_inv, const)

    if order < max_order:
        Y = L_eee + mdot(g_a,[g_eee])
        Z = g_eee
        V_eee = build_V(Y,Z,(n_a,n_e))


    ####################################
    ## Compute sigma^2 correction term #
    ####################################

    # ( a s s )

    A = f_a + sdot(f_d,g_a)
    I_e = np.eye(n_e)

    Y = g_e
    Z = np.zeros((n_a,n_e))
    V_s = build_V(Y,Z,(n_a,n_e))

    Y = mdot( g_ae, [g_a, I_e] )
    Z = np.zeros((n_a,n_a,n_e))
    V_as = build_V(Y,Z,(n_a,n_e))

    Y = sdot(g_a,g_ss) + g_ss + np.tensordot(g_ee,Sigma)
    Z = g_ss
    V_ss = build_V(Y,Z,(n_a,n_e))

    K_ass_1 =  2*mdot(f_2,[V_as,V_s] ) + mdot(f_3,[V_a,V_s,V_s])
    K_ass_1 = np.tensordot(K_ass_1,Sigma)

    K_ass_2 = mdot( f_2, [V_a,V_ss] )

    K_ass = K_ass_1 + K_ass_2

    L_ass = mdot( g_aa, [g_a, g_ss]) + np.tensordot( mdot(g_aee,[g_a, I_e, I_e]), Sigma)

    D = K_ass + sdot(f_d,L_ass)

    if derivatives_ss:
        f_1ss = derivatives_ss[1]
        D += mdot( f_1ss, [V_a]) + sdot( f1_A, mdot( g_aa, [ g_a , g_ss ])  )

    g_ass = solve_sylvester( A, B, C, D)


    # ( e s s )

    A = f_a + sdot(f_d,g_a)
    A_inv = np.linalg.inv(A)
    I_e = np.eye(n_e)

    Y = g_e
    Z = np.zeros((n_a,n_e))
    V_s = build_V(Y,Z,(n_a,n_e))

    Y = mdot( g_ae, [g_e, I_e] )
    Z = np.zeros((n_a,n_e,n_e))
    V_es = build_V(Y,Z,(n_a,n_e))

    Y = sdot(g_a,g_ss) + g_ss + np.tensordot(g_ee,Sigma)
    Z = g_ss
    V_ss = build_V(Y,Z,(n_a,n_e))

    K_ess_1 =  2*mdot(f_2,[V_es,V_s] ) + mdot(f_3,[V_e,V_s,V_s])
    K_ess_1 = np.tensordot(K_ess_1,Sigma)

    K_ess_2 = mdot( f_2, [V_e,V_ss] )

    K_ess = K_ess_1 + K_ess_2

    L_ess = mdot( g_aa, [g_e, g_ss]) + np.tensordot( mdot(g_aee,[g_e, I_e, I_e]), Sigma)
    L_ess += mdot( g_ass, [g_e])

    D = K_ess + sdot(f_d,L_ess)

    g_ess = sdot( A_inv, -D)

    if max_order == 3:
        d = {'ev':ev,'g_a':g_a,'g_e':g_e, 'g_aa':g_aa, 'g_ae':g_ae, 'g_ee':g_ee,
    'g_aaa':g_aaa, 'g_aae':g_aae, 'g_aee':g_aee, 'g_eee':g_eee, 'g_ss':g_ss, 'g_ass':g_ass,'g_ess':g_ess}
        return  d