Пример #1
0
def calc_stiefel():
    # Y is a matrix point
    eta = matrices('eta')
    Y = stiefels('Y')
    a = sm.sym_symb('a')
    al0, al1 = scalars('al0 al1')
    # scalars are symmetric
    sm.g_symms.update((al0, al1))
    
    def J(Y, eta):
        return mat_spfy(t(Y) * eta + t(eta) * Y).doit()

    def J_adj(Y, a):
        dY = symbols('dY', commutative=False)
        return xtrace(trace(mat_spfy(J(Y, dY) * a)), dY)

    def g(Y, eta):
        return al0*eta+(al1-al0)*Y*t(Y)*eta

    def g_inv(Y, eta):
        return mat_spfy(1/al0*eta + (1/al1-1/al0)*Y*t(Y)*eta)
    
    J_giv_J_adj = J(Y, g_inv(Y, J_adj(Y, a)))
    print(J_giv_J_adj)
        
    def proj(Y, omg):
        jo = mat_spfy(J(Y, omg))
        ifactor = al1/Integer(4)
        return omg - mat_spfy(
            g_inv(Y, mat_spfy(J_adj(Y, ifactor*jo))))
    
    def r_gradient(Y, omg):
        return mat_spfy(
            proj(Y, mat_spfy(g_inv(Y, omg))))
        
    print(r_gradient(Y, eta))
    
    xi, phi = matrices('xi phi')
    trilinear = mat_spfy(trace(DDR(g(Y, eta), Y, phi) * t(xi)))
    xcross = xtrace(trilinear, phi)
    K = (Integer(1)/Integer(2))*(DDR(g(Y, eta), Y, xi) +
                                 DDR(g(Y, xi), Y, eta) - xcross)
    
    def d_proj(Y, xi, omg):
        e = matrices('e')
        r = mat_spfy(proj(Y, e))
        expr = DDR(r, Y, xi)
        return expr.xreplace({e: omg})

    dp_xi_eta = d_proj(Y, xi, eta)
    prK = simplify_stiefel_tangent(proj(Y, g_inv(Y, K)), Y, (xi, eta))
    Gamma = mat_spfy(
        simplify_stiefel_tangent(prK - dp_xi_eta, Y, (xi, eta)))
    print("This is the Christoffel function:")
    pprint(Gamma)
    fY, fYY = matrices('fY fYY')
    rhess02 = trace(mat_spfy(t(eta)*fYY*xi-Gamma * t(fY)))
    rhess11_bf_gr = xtrace(rhess02, eta)
    print("This is the Riemannian Hessian Vector Product:")
    pprint(rhess11_bf_gr)
Пример #2
0
 def NT(Y, P, omg_Y, omg_P):
     nB, nD = matrices('nB nD')
     ipt = mat_spfy(base_ambient_inner(*N(Y, P, nB, nD), omg_Y, omg_P))
     ntB = mat_spfy(xtrace(ipt, nB))
     ntD1 = mat_spfy(xtrace(ipt, nD))
     ntD = mat_spfy(Integer(1) / Integer(2) * (ntD1 + t(ntD1)))
     return ntB, ntD
Пример #3
0
def calc_psd_range():
    # in this method, the ambient is still
    # R(n times p) + Symmetric(p)
    # Horizontal is still
    # al1*t(Y)*omg_Y + bt*omg_P*inv(R*R) - bt*inv(R*R)*omg_P)
    # manifold is on pair (Y, P)
    # Use pair B, D. B size n*(n-p), D size p(p+1)/2
    # Use the embedding
    # omg_Y = bt(Y*(inv(P)*D - D*inv(P))
    # omg_P = al1*D
    # so need to set up a new variable Y_0 and relation YY_0=0

    Y, Y0 = stiefels('Y Y0')
    sm.g_cstiefels[Y] = Y0
    sm.g_cstiefels[Y0] = Y

    B, eta_Y, eta_P = matrices('B eta_Y eta_P')
    P, D = sym_symb('P D')
    al0, al1, bt = scalars('al0 al1 bt')

    def g(Y, P, omg_Y, omg_P):
        return al0 * omg_Y + (al1 - al0) * Y * t(Y) * omg_Y, bt * inv(
            P) * omg_P * inv(P)

    def ginv(Y, P, omg_Y, omg_P):
        return 1 / al0 * omg_Y + (
            1 / al1 - 1 / al0) * Y * t(Y) * omg_Y, 1 / bt * P * omg_P * P

    # check that ginv \circ g is id
    e1, e2 = ginv(Y, P, *(g(Y, P, eta_Y, eta_P)))
    e1 = mat_spfy(e1)
    e2 = mat_spfy(e2)
    print(e1, e2)

    def base_ambient_inner(omg_Y, omg_P, xi_Y, xi_P):
        return mat_spfy(
            trace(mat_spfy(omg_Y * t(xi_Y))) +
            trace(mat_spfy(omg_P * t(xi_P))))

    def ambient_inner(Y, P, omg_Y, omg_P, xi_Y, xi_P):
        return mat_spfy(
            trace(
                mat_spfy((al0 * omg_Y +
                          (al1 - al0) * Y * t(Y) * omg_Y) * t(xi_Y))) +
            trace(mat_spfy(bt * inv(P) * omg_P * inv(P) * t(xi_P))))

    def EN_inner(Y, P, Ba, Da, Bb, Db):
        return trace(mat_spfy(Da * Db) + mat_spfy(Ba * t(Bb)))

    qat = asym_symb('qat')

    ipr = ambient_inner(Y, P, eta_Y, eta_P, Y * qat, P * qat - qat * P)
    dqat = mat_spfy(xtrace(ipr, qat))
    print(dqat)

    def N(Y, P, B, D):
        N_Y = mat_spfy(bt * Y * (inv(P) * D - D * inv(P))) + Y0 * B
        N_P = mat_spfy(al1 * D)

        return N_Y, N_P

    def NT(Y, P, omg_Y, omg_P):
        nB, nD = matrices('nB nD')
        ipt = mat_spfy(base_ambient_inner(*N(Y, P, nB, nD), omg_Y, omg_P))
        ntB = mat_spfy(xtrace(ipt, nB))
        ntD1 = mat_spfy(xtrace(ipt, nD))
        ntD = mat_spfy(Integer(1) / Integer(2) * (ntD1 + t(ntD1)))
        return ntB, ntD

    # check that image of N is horizontal:
    print(
        mat_spfy(
            xtrace(
                mat_spfy(
                    ambient_inner(Y, P, *N(Y, P, B, D), Y * qat,
                                  P * qat - qat * P)), qat)))
    NTe_B, NTe_D = NT(Y, P, eta_Y, eta_P)
    mdict = {'bt': r'\beta', 'al': r'\alpha'}
    print(latex_map(mat_latex(NTe_B), mdict))
    print(latex_map(mat_latex(NTe_D), mdict))

    gN = g(Y, P, *N(Y, P, B, D))
    gN_B = mat_spfy(gN[0])
    gN_D = mat_spfy(gN[1])
    print(latex_map(mat_latex(gN_B), mdict))
    print(latex_map(mat_latex(gN_D), mdict))

    NTgN_B, NTgN_D = NT(Y, P, *gN)

    print(latex_map(mat_latex(NTgN_B), mdict))
    print(latex_map(mat_latex(NTgN_D), mdict))

    NTg_B, NTg_D = NT(Y, P, *g(Y, P, eta_Y, eta_P))
    print(latex_map(mat_latex(NTg_B), mdict))
    # print(latex_map(sp.latex(NTgN_P), mdict))
    print(latex_map(mat_latex(NTg_D), mdict))

    def sym(x):
        return mat_spfy(Integer(1) / Integer(2) * (x + t(x)))

    xi_Y, xi_P, phi_Y, phi_P = matrices('xi_Y xi_P phi_Y phi_P')
    gYPeta = g(Y, P, eta_Y, eta_P)
    Dgxieta_Y = DDR(gYPeta[0], Y, xi_Y)
    Dgxieta_P = DDR(gYPeta[1], P, xi_P)

    gYPxi = g(Y, P, xi_Y, xi_P)
    Dgetaxi_Y = DDR(gYPxi[0], Y, eta_Y)
    Dgetaxi_P = DDR(gYPxi[1], P, eta_P)

    Dgxiphi_Y = DDR(gYPxi[0], Y, phi_Y)
    Dgxiphi_P = DDR(gYPxi[1], P, phi_P)

    tr3 = mat_spfy(base_ambient_inner(Y, P, Dgxiphi_Y, Dgxiphi_P, eta_Y,
                                      eta_P))
    xcross_Y = xtrace(tr3, phi_Y)
    xcross_P = xtrace(tr3, phi_P)

    K_Y = (Integer(1) / Integer(2)) * (Dgxieta_Y + Dgetaxi_Y - xcross_Y)
    K_P = (Integer(1) / Integer(2)) * (Dgxieta_P + Dgetaxi_P - xcross_P)

    pprint(K_Y)
    pprint(K_P)
Пример #4
0
 def JT(Y, P, a_P, a_YP):
     dY, dP = matrices('dY dP')
     ipt = mat_spfy(EJ_inner(Y, P, *J(Y, P, dY, dP), a_P, a_YP))
     jty = mat_spfy(xtrace(ipt, dY))
     jtp = mat_spfy(xtrace(ipt, dP))
     return jty, jtp
Пример #5
0
def calc_psd():
    # manifold is on pair (Y, P)
    Y = stiefels('Y')
    P = sym_symb('P')
    a_P = asym_symb('a_P')
    a_YP, eta_Y, eta_P = matrices('a_YP eta_Y eta_P')

    al0, al1, bt = scalars('al0 al1 bt')

    def g(Y, P, omg_Y, omg_P):
        return al0 * omg_Y + (al1 - al0) * Y * t(Y) * omg_Y, bt * inv(
            P) * omg_P * inv(P)

    def ginv(Y, P, omg_Y, omg_P):
        return 1 / al0 * omg_Y + (
            1 / al1 - 1 / al0) * Y * t(Y) * omg_Y, 1 / bt * P * omg_P * P

    # check that ginv \circ g is id
    e1, e2 = ginv(Y, P, *(g(Y, P, eta_Y, eta_P)))
    e1 = mat_spfy(e1)
    e2 = mat_spfy(e2)
    print(e1, e2)

    def ambient_inner(Y, P, omg_Y, omg_P, xi_Y, xi_P):
        return mat_spfy(
            trace(
                mat_spfy((al0 * omg_Y +
                          (al1 - al0) * Y * t(Y) * omg_Y) * t(xi_Y))) +
            trace(mat_spfy(bt * inv(P) * omg_P * inv(P) * t(xi_P))))

    def base_ambient_inner(Y, P, omg_Y, omg_P, xi_Y, xi_P):
        return mat_spfy(
            trace(mat_spfy(omg_Y * t(xi_Y))) +
            trace(mat_spfy(omg_P * t(xi_P))))

    def EJ_inner(Y, P, a_P, a_YP, b_P, b_YP):
        return trace(mat_spfy(-a_P * b_P) + mat_spfy(a_YP * t(b_YP)))

    qat = matrices('qat')
    ipr = ambient_inner(Y, P, eta_Y, eta_P, Y * qat, P * qat - qat * P)
    dqat = mat_spfy(xtrace(ipr, qat))
    print(dqat)

    def J(Y, P, omg_Y, omg_P):
        J_P = mat_spfy(omg_P - t(omg_P))
        J_YP = mat_spfy(al1 * t(Y) * omg_Y + bt * omg_P * inv(P) -
                        bt * inv(P) * omg_P)

        return J_P, J_YP

    def JT(Y, P, a_P, a_YP):
        dY, dP = matrices('dY dP')
        ipt = mat_spfy(EJ_inner(Y, P, *J(Y, P, dY, dP), a_P, a_YP))
        jty = mat_spfy(xtrace(ipt, dY))
        jtp = mat_spfy(xtrace(ipt, dP))
        return jty, jtp

    JTa_Y, JTa_P = JT(Y, P, a_P, a_YP)

    ginvJT = ginv(Y, P, JTa_Y, JTa_P)
    ginvJT_Y = mat_spfy(ginvJT[0])
    ginvJT_P = mat_spfy(ginvJT[1])
    pprint(ginvJT_Y)
    pprint(ginvJT_P)

    Jginv_P, Jginv_YP = J(Y, P, *ginv(Y, P, eta_Y, eta_P))
    pprint(Jginv_P)
    pprint(Jginv_YP)

    b_P, b_YP = J(Y, P, *ginvJT)
    pprint(b_P)
    pprint(b_YP)

    # even part of a_YP
    aYPev = sym(a_YP)

    exp1 = bt * (Integer(1) / Integer(2) * b_P - P * aYPev + aYPev * P)
    exp1 = mat_spfy(exp1)
    pprint(exp1)
    print('check the formula for even part of a_YP recover b_YP')
    exp1 = al1 * aYPev + bt / 2 * (b_P * inv(P) - inv(P) * b_P) - sym(b_YP)
    pprint(mat_spfy(exp1))

    aYPodd = mat_spfy(a_YP - aYPev)
    exp2 = (al1-2*bt)*aYPodd + bt*P*aYPodd*inv(P) + bt*inv(P)*aYPodd*P -\
        Integer(1)/Integer(2)*(b_YP-t(b_YP))
    # this is the equation to solve a_YPodd
    print('this is the equation to solve a_YPodd')
    pprint(exp2)

    def even_solve(Y, P, b_P, b_YP):
        return Integer(1)/al1*sym(b_YP) +\
            bt/(Integer(2)*al1)*(inv(P)*b_P - b_P*inv(P))

    print(mat_spfy(even_solve(Y, P, b_P, b_YP)))
    xi_Y, xi_P, phi_Y, phi_P = matrices('xi_Y xi_P phi_Y phi_P')
    gYPeta = g(Y, P, eta_Y, eta_P)
    Dgxieta_Y = DDR(gYPeta[0], Y, xi_Y)
    Dgxieta_P = DDR(gYPeta[1], P, xi_P)

    gYPxi = g(Y, P, xi_Y, xi_P)
    Dgetaxi_Y = DDR(gYPxi[0], Y, eta_Y)
    Dgetaxi_P = DDR(gYPxi[1], P, eta_P)

    Dgxiphi_Y = DDR(gYPeta[0], Y, phi_Y)
    Dgxiphi_P = DDR(gYPeta[1], P, phi_P)

    tr3 = mat_spfy(base_ambient_inner(Y, P, Dgxiphi_Y, Dgxiphi_P, xi_Y, xi_P))
    xcross_Y = xtrace(tr3, phi_Y)
    xcross_P = xtrace(tr3, phi_P)

    K_Y = (Integer(1) / Integer(2)) * (Dgxieta_Y + Dgetaxi_Y - xcross_Y)
    K_P = (Integer(1) / Integer(2)) * (Dgxieta_P + Dgetaxi_P - xcross_P)

    K_Y = simplify_stiefel_tangent(K_Y, Y, (eta_Y, xi_Y))
    K_P = simplify_pd_tangent(K_P, P, (eta_P, xi_P))
    pprint(K_Y)
    pprint(K_P)

    giKY, giKP = ginv(Y, P, K_Y, K_P)

    giKY1 = simplify_stiefel_tangent(giKY, Y, (eta_Y, xi_Y))
    giKP1 = simplify_pd_tangent(giKP, P, (eta_P, xi_P))
    jK1 = J(Y, P, giKY1, giKP1)
    jKP = simplify_pd_tangent(jK1[0], P, (eta_P, xi_P))
    jKY = simplify_stiefel_tangent(jK1[1], Y, (eta_Y, xi_Y))
    jKY1 = simplify_pd_tangent(jKY, P, (eta_P, xi_P))
    pprint(jKP)
    pprint(jKY1)

    def DJ(Y, P, xi_Y, xi_P, eta_Y, eta_P):
        expr_P, expr_YP = J(Y, P, eta_Y, eta_P)
        der_P = DDR(expr_P, Y, xi_Y) + DDR(expr_P, P, xi_P)
        der_YP = DDR(expr_YP, Y, xi_Y) + DDR(expr_YP, P, xi_P)
        return mat_spfy(der_P), mat_spfy(der_YP)

    pprint(DJ(Y, P, xi_Y, xi_P, eta_Y, eta_P))
Пример #6
0
 def J_adj(Y, a):
     dY = symbols('dY', commutative=False)
     return xtrace(trace(mat_spfy(J(Y, dY) * a)), dY)
Пример #7
0
def calc_pd():
    """ For positive definite matrices
    Y is a matrix point, a positive definite matrix
    eta is an ambient point, same size with Y not necessarily
    symmetric or invertible
    b is a point in E_J. b is antisymmetric
    """
    # eta is an ambient
    Y = sm.sym_symb('Y')
    eta = matrices('eta')
    b = sm.asym_symb('b')
    
    def J(Y, eta):
        return eta - t(eta)
    
    def J_adj(Y, a):
        dY = symbols('dY', commutative=False)
        return xtrace(trace(mat_spfy(J(Y, dY) * a)), dY)

    def g(Y, eta):
        return inv(Y)*eta*inv(Y)

    def g_inv(Y, eta):
        return Y*eta*Y
    
    J_g_inv_J_adj = J(Y, g_inv(Y, J_adj(Y, b)))
    pprint(J_g_inv_J_adj)

    def solve_JginvJadj(Y, a):
        return Integer(-1)/Integer(4)*inv(Y)*a*inv(Y)

    def proj(Y, omg):
        jo = mat_spfy(J(Y, omg))
        cJinvjo = solve_JginvJadj(Y, jo)
        return mat_spfy(omg - mat_spfy(
            g_inv(Y, mat_spfy(J_adj(Y, cJinvjo)))))

    def r_gradient(Y, omg):
        return mat_spfy(
            proj(Y, mat_spfy(g_inv(Y, omg))))

    print(proj(Y, eta))
    print(r_gradient(Y, eta))

    xi, phi = matrices('xi phi')
    xcross = xtrace(mat_spfy(trace(DDR(g(Y, eta), Y, phi) * t(xi))), phi)
    K = (Integer(1)/Integer(2))*(
        DDR(g(Y, eta), Y, xi) + DDR(g(Y, xi), Y, eta) - xcross)

    def d_proj(Y, xi, omg):
        e = matrices('e')
        r = mat_spfy(proj(Y, e))
        expr = DDR(r, Y, xi)
        return expr.xreplace({e: omg})

    dp_xi_eta = d_proj(Y, xi, eta)
    prK = simplify_pd_tangent(proj(Y, mat_spfy(g_inv(Y, K))), Y, (xi, eta))
    Gamma = mat_spfy(
        simplify_pd_tangent(-dp_xi_eta+prK, Y, (xi, eta)))
    print("This is the Christoffel function:")
    pprint(Gamma)
    fY, fYY = matrices('fY fYY')
    rhess02 = trace(mat_spfy(t(eta)*fYY*xi-Gamma * t(fY)))
    rhess11_bf_gr = xtrace(rhess02, eta)
    print("This is the Riemannian Hessian Vector Product:")
    pprint(r_gradient(Y, rhess11_bf_gr))