def test_projection(man, Y):
    print("test projection")
    N = 10
    ret = np.zeros(N)

    for i in range(N):
        U = man._rand_ambient()
        Upr = man.proj(Y, U)
        ret[i] = check_zero(man._vec_range_J(man.J(Y, Upr)))
    # print(ret)

    if check_zero(ret) > 1e-9:
        print("not all works")
    else:
        print("All good")
    print("test randvec")
    ret_pr = np.zeros(N)
    for i in range(N):
        XX = man.rand()
        H = man.randvec(XX)
        U = man._rand_ambient()
        Upr = man.proj(XX, U)
        ret_pr[i] = man.inner(XX, U, H) - man.inner(XX, Upr, H)
        ret[i] = (check_zero(XX.T.conjugate() @ H + H.T.conjugate() @ XX))
    print(ret)
    if check_zero(ret) > 1e-9:
        print("not all works")
    else:
        print("All good")
    print("check inner of projection = inner of original")
    print(ret_pr)
    if check_zero(ret_pr) > 1e-9:
        print("not all works")
    else:
        print("All good")
Example #2
0
def test_N_proj():
    alpha = randint(1, 10, 2) * .1
    beta = randint(1, 10, 1)[0] * .02
    n = 10
    d = 6
    man = ComplexPositiveSemidefinite(n, d, alpha=alpha, beta=beta)
    S = man.rand()
    """
    def proj_range_alt(man, S, U):
        # projection. U is in ambient
        # return one in tangent
        al1 = man.alpha[1]
        beta = man.beta
        YTU = [email protected]
        D0 = sym(U.tP + [email protected] - S.P@YTU)
        D = _extended_lyapunov(al1, beta, S.P, D0, S.evl, S.evec)
        return psd_ambient(
            beta*S.Y@(S.Pinv@[email protected]) + U.tY - S.Y@([email protected]), al1*D)
    """
    U = man.randvec(S)
    Upr1 = super(ComplexPositiveSemidefinite, man).proj(S, U)
    Upr2 = man.proj(S, U)
    Upr3 = man.proj_range_alt(S, U)
    print(check_zero(Upr1.tP - Upr2.tP))
    print(check_zero(Upr1.tY - Upr2.tY))
    print(check_zero(Upr1.tY - Upr3.tY))
    print(check_zero(Upr1.tP - Upr3.tP))
Example #3
0
def test_vectorize():
    from ManNullRange.manifolds.tools import cvech, cunvech, cvecah, cunvecah
    p = 10
    mat = crandn(p, p)
    mat += mat.T.conjugate()
    v = cvech(mat)
    mat2 = cunvech(v)
    print(check_zero(mat - mat2))

    # check inner product:
    for i in range(p * p):
        v = zeros(p * p)
        v[i] = 1
        h = cunvech(v)
        assert (np.abs(trace(h @ h.T.conjugate()).real - 1) < 1e-10)

    # now do skew
    mat = crandn(p, p)
    mat -= mat.T.conjugate()
    v = cvecah(mat)
    mat2 = cunvecah(v)
    print(check_zero(mat - mat2))

    for i in range(p * p):
        v = zeros(p * p)
        v[i] = 1
        h = cunvecah(v)
        assert (np.abs(trace(h @ h.T.conjugate()).real - 1) < 1e-10)
def test_covariance_deriv():
    # now test full:
    # do covariant derivatives
    # check that it works, preseving everything
    dvec = np.array([10, 3, 2, 3])
    p = dvec.shape[0] - 1
    alpha = randint(1, 10, (p, p + 1)) * .1
    man = ComplexFlag(dvec, alpha=alpha)
    n = man.n
    d = man.d
    Y = man.rand()

    slp = np.random.randn(n * d)
    aa = np.random.randn(n * d, n * d)

    def omg_func(Y):
        return (aa @ Y.reshape(-1) + slp).reshape(n, d)

    xi = man.randvec(Y)

    egrad = omg_func(Y)
    ehess = (aa @ xi.reshape(-1)).reshape(n, d)

    val1 = man.ehess2rhess(Y, egrad, ehess, xi)

    def rgrad_func(W):
        return man.proj_g_inv(W, omg_func(W))

    if False:
        d_xi_rgrad = num_deriv(man, Y, xi, rgrad_func)
        rgrad = man.proj_g_inv(Y, egrad)
        fourth = man.christoffel_form(Y, xi, rgrad)
        val1c = man.proj(Y, d_xi_rgrad) + man.proj_g_inv(Y, fourth)

    if False:
        first = ehess
        a = man.J(Y, man.g_inv(Y, egrad))
        rgrad = man.proj_g_inv(Y, egrad)
        second = -man.D_g(Y, xi, man.g_inv(Y, egrad))
        aout = man.solve_J_g_inv_Jst(Y, a)
        third = -man.proj(Y, man.D_g_inv_Jst(Y, xi, aout))
        fourth = man.christoffel_form(Y, xi, rgrad)
        val1a = man.proj_g_inv(Y, first + second + fourth) + third

    d_xi_rgrad = num_deriv(man, Y, xi, rgrad_func)
    rgrad = man.proj_g_inv(Y, egrad)
    fourth = man.christoffel_form(Y, xi, rgrad)
    val1b = man.proj(Y, d_xi_rgrad) + man.proj_g_inv(Y, fourth)
    print(check_zero(val1 - val1b))
    # nabla_v_xi, dxi, cxxi
    # val2a, _, _ = calc_covar_numeric(man, Y, xi, omg_func)
    val2, _, _ = calc_covar_numeric(man, Y, xi, rgrad_func)
    # val2_p = project(prj, val2)
    val2_p = man.proj(Y, val2)
    # print(val1)
    # print(val2_p)
    print(check_zero(val1 - val2_p))
def test_covariance_deriv():
    # now test full:
    # do covariant derivatives
    # check that it works, preseving everything
    n, d = (5, 3)
    A = make_sym_pos(n)
    B = make_sym_pos(d)

    man = RealStiefelWoodbury(n, d, A=A, B=B)
    Y = man.rand()

    slp = np.random.randn(n * d)
    aa = np.random.randn(n * d, n * d)

    def omg_func(Y):
        return (aa @ Y.reshape(-1) + slp).reshape(n, d)

    xi = man.randvec(Y)

    egrad = omg_func(Y)
    ehess = (aa @ xi.reshape(-1)).reshape(n, d)

    val1 = man.ehess2rhess(Y, egrad, ehess, xi)
    if False:
        val1a = man.ehess2rhess_alt(Y, egrad, ehess, xi)
        print(check_zero(val1 - val1a))

    def rgrad_func(W):
        return man.proj_g_inv(W, omg_func(W))

    if False:
        first = ehess
        a = man.J(Y, man.g_inv(Y, egrad))
        rgrad = man.proj_g_inv(Y, egrad)
        second = -man.D_g(Y, xi, man.g_inv(Y, egrad))
        aout = man.solve_J_g_inv_Jst(Y, a)
        third = -man.proj(Y, man.D_g_inv_Jst(Y, xi, aout))
        fourth = man.christoffel_form(Y, xi, rgrad)
        val1a = man.proj_g_inv(Y, first + second + fourth) + third

    d_xi_rgrad = num_deriv(man, Y, xi, rgrad_func)
    rgrad = man.proj_g_inv(Y, egrad)
    fourth = man.christoffel_form(Y, xi, rgrad)
    val1b = man.proj(Y, d_xi_rgrad) + man.proj_g_inv(Y, fourth)
    print(check_zero(val1 - val1b))
    # nabla_v_xi, dxi, cxxi
    val2a, _, _ = calc_covar_numeric(man, Y, xi, omg_func)
    val2, _, _ = calc_covar_numeric(man, Y, xi, rgrad_func)
    # val2_p = project(prj, val2)
    val2_p = man.proj(Y, val2)
    # print(val1)
    # print(val2_p)
    print(val1 - val2_p)
def testN(man, X):
    m, n, p = (man.m, man.n, man.p)
    B = crandn(m-p, p)
    C = crandn(n-p, p)
    D = crandn(p, p)
    ee = N(man, X, B, C, D)
    print(check_zero(stU(X, ee)))
    print(check_zero(stV(X, ee)))
    print(check_zero(symP(X, ee)))
    print(check_zero(Hz(man, X, ee)))
    nmat = make_N_mat(man, X)
    ee2 = man._unvec(nmat @ np.concatenate(
        [cvec(B), cvec(C), cvec(D)]))
    print(check_zero(man._vec(ee - ee2)))
def testN(man, X):
    m, n, p = (man.m, man.n, man.p)
    B = randn(m - p, p)
    C = randn(n - p, p)
    D = randn(p, p)
    ee = N(man, X, B, C, D)
    print(check_zero(stU(X, ee)))
    print(check_zero(stV(X, ee)))
    print(check_zero(symP(X, ee)))
    print(check_zero(Hz(man, X, ee)))
    nmat = make_N_mat(man, X)
    ee2 = man._unvec(nmat @ np.concatenate(
        [B.reshape(-1), C.reshape(-1),
         D.reshape(-1)]))
    print(check_zero(man._vec(ee - ee2)))
 def testNTgN(man, X):
     m, n, p = (man.m, man.n, man.p)
     B0 = crandn(m-p, p)
     C0 = crandn(n-p, p)
     D0 = crandn(p, p)
     out1 = NTgN @ np.concatenate(
         [cvec(B0), cvec(C0), cvec(D0)])
     out2a = NTgN_opt(X, B0, C0, D0)
     out2 = np.concatenate(
         [cvec(out2a[0]), cvec(out2a[1]), cvec(out2a[2])])
     print(check_zero(out1-out2))
     out2b = solveNTgN(X, *out2a)
     print(check_zero(out2b[2]-D0))
     print(check_zero(out2b[1]-C0))
     print(check_zero(out2b[0]-B0))
 def testNTgN(man, X):
     m, n, p = (man.m, man.n, man.p)
     B0 = randn(m - p, p)
     C0 = randn(n - p, p)
     D0 = randn(p, p)
     out1 = NTgN @ np.concatenate(
         [B0.reshape(-1), C0.reshape(-1),
          D0.reshape(-1)])
     out2a = NTgN_opt(X, B0, C0, D0)
     out2 = np.concatenate(
         [out2a[0].reshape(-1), out2a[1].reshape(-1), out2a[2].reshape(-1)])
     print(check_zero(out1 - out2))
     out2b = solveNTgN(X, *out2a)
     print(check_zero(out2b[2] - D0))
     print(check_zero(out2b[1] - C0))
     print(check_zero(out2b[0] - B0))
def test_christ_flat():
    """now test that christofel preserve metrics:
    on the flat space
    d_xi <v M v> = 2 <v M nabla_xi v>
     v = proj(W) @ (aa W + b)
    """
    alpha = randint(1, 10, 2) * .1
    gamma = randint(1, 10, 2) * .1
    beta = randint(1, 10, 2)[0] * .1

    m = 4
    n = 5
    p = 3
    man = ComplexFixedRank(m, n, p, alpha=alpha, beta=beta, gamma=gamma)
    
    S = man.rand()
    
    xi = man.randvec(S)
    aaU = crandn(m*p, m*p)
    bbU = crandn(m*p)

    aaV = crandn(n*p, n*p)
    bbV = crandn(n*p)
    
    cc = crandn(p*p, p*p)
    dd = hsym(crandn(p, p))
        
    def v_func_flat(S):
        # a function from the manifold
        # to ambient
        csp = hsym((cc @ S.P.reshape(-1)).reshape(p, p))
        
        return fr_ambient(
            (aaU @ S.U.reshape(-1) + bbU).reshape(m, p),
            (aaV @ S.V.reshape(-1) + bbV).reshape(n, p),
            csp + dd)

    vv = v_func_flat(S)  # vv is not horizontal
    dlt = 1e-7
    Snew = fr_point(
        S.U + dlt * xi.tU,
        S.V + dlt * xi.tV,
        S.P + dlt * xi.tP)
    vnew = v_func_flat(Snew)

    val = man.inner(S, vv)
    valnew = man.inner(Snew, vnew)
    d1 = (valnew - val)/dlt
    dv = (vnew - vv).scalar_mul(1/dlt)
    nabla_xi_v = dv + man.g_inv(
        S, man.christoffel_form(S, xi, vv))
    # not equal bc vv is not horizontal:
    nabla_xi_va = dv + man.g_inv(
        S, super(ComplexFixedRank, man).christoffel_form(S, xi, vv))
    print(check_zero(man._vec(nabla_xi_v) - man._vec(nabla_xi_va)))
    d2 = man.inner(S, vv, nabla_xi_v)

    print(d1)
    print(2*d2)
 def diff_i_j(i, j):
     U = zeros_like(Y)
     U[ii, jj] = 1
     ju = man.J(Y, U)
     asum = 0
     gdc = man._g_idx
     for r, s in ju:
         br, er = gdc[r]
         if r == s:
             asum += check_zero(ju[r, r] - alpha[r - 1, r] *
                                Y[:, br:er].T.conjugate() @ U[:, br:er])
         else:
             bs, es = gdc[s]
             asum += check_zero(ju[r, s] -
                                Y[:, br:er].T.conjugate() @ U[:, bs:es] -
                                U[:, br:er].T.conjugate() @ Y[:, bs:es])
     return asum / len(ju)
Example #12
0
def solve_dist_with_man(man, A, X0, maxiter, check_deriv=False):
    import pymanopt
    from pymanopt import Problem
    from pymanopt.solvers import TrustRegions

    @pymanopt.function.Callable
    def cost(S):
        """
        if not(S.P.dtype == np.float):
            raise(ValueError("Non real"))
        """
        diff = (A - S.Y @ S.P @ S.Y.T.conjugate())
        val = trace(diff @ diff.T.conjugate()).real
        # print('val=%f' % val)
        return val

    @pymanopt.function.Callable
    def egrad(S):
        return psd_ambient(-4 * A @ S.Y @ S.P,
                           2 * (S.P - S.Y.T.conjugate() @ A @ S.Y))

    @pymanopt.function.Callable
    def ehess(S, xi):
        return psd_ambient(
            -4 * A @ (xi.tY @ S.P + S.Y @ xi.tP),
            2 * (xi.tP - xi.tY.T.conjugate() @ A @ S.Y -
                 S.Y.T.conjugate() @ A @ xi.tY))

    if check_deriv:
        xi = man.randvec(X0)
        dlt = 1e-7
        S1 = psd_point(X0.Y + dlt * xi.tY, X0.P + dlt * xi.tP)
        print((cost(S1) - cost(X0)) / dlt)
        print(man.base_inner_ambient(egrad(X0), xi))
        h1 = egrad(S1) - egrad(X0)
        h1 = psd_ambient(h1.tY / dlt, h1.tP / dlt)
        h2 = ehess(X0, xi)
        print(check_zero(h1.tY - h2.tY) + check_zero(h1.tP - h2.tP))
        return

    prob = Problem(man, cost, egrad=egrad, ehess=ehess)

    solver = TrustRegions(maxtime=100000, maxiter=maxiter, use_rand=False)
    opt = solver.solve(prob, x=X0, Delta_bar=250)
    return opt
Example #13
0
def test_Jst(man, S, jmat):
    print("test JST")
    for ii in range(10):
        a = man._rand_range_J()
        avec = man._vec_range_J(a)
        jtout = jmat.T @ avec
        jtout2 = man._vec(man.Jst(S, a))
        # print(np.where(np.abs(jtout - jtout2) > 1e-9))
        diff = check_zero(jtout - jtout2)
        print(diff)
def test_Jst(man, Y, jmat):
    print("test JST")
    for ii in range(10):
        a = man._rand_range_J()
        avec = man._vec_range_J(a)
        jtout = man._unvec(jmat.T.conjugate() @ avec)
        jtout2 = man.Jst(Y, a)
        # print(np.where(np.abs(jtout - jtout2) > 1e-9))
        diff = check_zero(jtout - jtout2)
        print(diff)
Example #15
0
def test_chris_vectorfields():
    # now test that it works on embedded metrics
    # we test that D_xi (eta g eta) = 2(eta g nabla_xi eta)
    n, d = (20, 3)
    alpha = randint(1, 10, 2) * .1
    beta = randint(1, 10, 1)[0] * .1
    man = ComplexPositiveSemidefinite(n, d, alpha=alpha, beta=beta)

    S0 = man.rand()
    aa = crandn(n * d, n * d)
    intc = crandn(n * d)
    cc = crandn(d * d, d * d)
    p_intc = hsym(crandn(d, d))

    inct_xi = man._rand_ambient()
    aa_xi = crandn(n * d, n * d)
    cc_xi = crandn(d * d, d * d)

    def v_func(S):
        # a function from the manifold
        # to ambient
        csp = hsym((cc @ (S.P - S0.P).reshape(-1)).reshape(d, d))

        return man.proj(
            S,
            psd_ambient((aa @ (S.Y - S0.Y).reshape(-1) + intc).reshape(n, d),
                        csp + p_intc))

    SS = psd_point(S0.Y, S0.P)
    xi = man.proj(SS, inct_xi)

    nabla_xi_v, dv, cxv = calc_covar_numeric(man, SS, xi, v_func)

    def xi_func(S):
        csp_xi = hsym((cc_xi @ (S.P - S0.P).reshape(-1)).reshape(d, d))
        xi_amb = psd_ambient((aa_xi @ (S.Y - S0.Y).reshape(-1) +
                              inct_xi.tY.reshape(-1)).reshape(n, d),
                             csp_xi + inct_xi.tP)
        return man.proj(S, xi_amb)

    vv = v_func(SS)

    nabla_v_xi, dxi, cxxi = calc_covar_numeric(man, SS, vv, xi_func)
    diff = nabla_xi_v - nabla_v_xi
    print(diff.tY, diff.tP)
    # now do Lie bracket:
    dlt = 1e-7
    SnewXi = psd_point(SS.Y + dlt * xi.tY, SS.P + dlt * xi.tP)
    Snewvv = psd_point(SS.Y + dlt * vv.tY, SS.P + dlt * vv.tP)
    vnewxi = v_func(SnewXi)
    xnewv = xi_func(Snewvv)
    dxiv = (vnewxi - vv).scalar_mul(1 / dlt)
    dvxi = (xnewv - xi).scalar_mul(1 / dlt)
    diff2 = man.proj(SS, dxiv - dvxi)
    print(check_zero(man._vec(diff) - man._vec(diff2)))
Example #16
0
def test_chris_vectorfields():
    # now test that it works on embedded metrics
    # we test that D_xi (eta g eta) = 2(eta g nabla_xi eta)
    dvec = np.array([10, 3, 2, 3])
    p = dvec.shape[0]-1
    alpha = randint(1, 10, (p, p+1)) * .1
    man = RealFlag(dvec, alpha=alpha)
    n = man.n
    d = man.d
    
    slp = randn(n*d)
    Y0 = man.rand()
    slpxi = randn(n*d)

    aa = randn(n*d, n*d)
    aaxi = randn(n*d, n*d)

    def v_func(Y):
        return man.proj(Y, (aa @ (Y-Y0).reshape(-1)
                            + slp).reshape(n, d))

    YY = Y0.copy()
    xi = man.proj(YY, slpxi.reshape(n, d))

    nabla_xi_v, dv, cxv = calc_covar_numeric(
        man, YY, xi, v_func)

    def xi_func(Y):
        return man.proj(Y, (aaxi @ (Y-Y0).reshape(-1)
                            + slpxi).reshape(n, d))

    vv = v_func(YY)

    nabla_v_xi, dxi, cxxi = calc_covar_numeric(
        man, YY, vv, xi_func)
    diff = nabla_xi_v - nabla_v_xi
    # print(diff)
    # now do Lie bracket:
    dlt = 1e-7
    YnewXi = YY + dlt * xi
    Ynewvv = YY + dlt * vv
    vnewxi = v_func(YnewXi)
    xnewv = xi_func(Ynewvv)
    dxiv = (vnewxi - vv)/dlt
    dvxi = (xnewv - xi)/dlt
    diff2 = man.proj(YY, dxiv-dvxi)
    print(check_zero(diff - diff2))
Example #17
0
def test_christ_flat():
    """now test that christofel preserve metrics:
    on the flat space
    d_xi <v M v> = 2 <v M nabla_xi v>
     v = proj(W) @ (aa W + b)
    """
    alpha = randint(1, 10, 2) * .1
    beta = randint(1, 10, 2)[0] * .1
    n = 20
    d = 3
    man = ComplexPositiveSemidefinite(n, d, alpha=alpha, beta=beta)
    S = man.rand()

    xi = man.randvec(S)
    xi = man.randvec(S)
    aa = crandn(n * d, n * d)
    bb = crandn(n * d)
    cc = crandn(d * d, d * d)
    dd = hsym(crandn(d, d))

    def v_func_flat(S):
        # a function from the manifold
        # to ambient
        csp = hsym((cc @ S.P.reshape(-1)).reshape(d, d))

        return psd_ambient((aa @ S.Y.reshape(-1) + bb).reshape(n, d), csp + dd)

    vv = v_func_flat(S)
    dlt = 1e-7
    Snew = psd_point(S.Y + dlt * xi.tY, S.P + dlt * xi.tP)
    vnew = v_func_flat(Snew)

    val = man.inner_product_amb(S, vv)
    valnew = man.inner_product_amb(Snew, vnew)
    d1 = (valnew - val) / dlt
    dv = (vnew - vv).scalar_mul(1 / dlt)
    nabla_xi_v = dv + man.g_inv(S, man.christoffel_form(S, xi, vv))
    nabla_xi_va = dv + man.g_inv(
        S,
        super(ComplexPositiveSemidefinite, man).christoffel_form(S, xi, vv))
    print(check_zero(man._vec(nabla_xi_v) - man._vec(nabla_xi_va)))
    d2 = man.inner(S, vv, nabla_xi_v)

    print(d1)
    print(2 * d2)
def test_projection(man, X):
    print("test projection")
    NN = 10
    ret = np.zeros(NN)

    for i in range(NN):
        omg = man._rand_ambient()
        Upr = man.proj(X, omg)
        ret[i] = check_zero(
            np.concatenate([
                stU(X, Upr).reshape(-1),
                stV(X, Upr).reshape(-1),
                symP(X, Upr).reshape(-1),
                Hz(man, X, Upr).reshape(-1)
            ]))
    print(ret)

    if check_zero(ret) > 1e-8:
        print("not all works")
    else:
        print("All good")
    print("test randvec")
    ret_pr = np.zeros(NN)
    for i in range(NN):
        XX = man.rand()
        H = man.randvec(XX)
        Ue = man._rand_ambient()
        Upr = man.proj(XX, Ue)
        ret_pr[i] = man.inner(XX, Ue, H) - man.inner(XX, Upr, H)
        ret[i] = check_zero(stU(XX, H)) + check_zero(stV(XX, H)) +\
            check_zero(symP(XX, H)) + check_zero(Hz(man, XX, H))
    print(ret)
    if check_zero(ret) > 1e-9:
        print("not all works")
    else:
        print("All good")
    print("check inner of projection = inner of original")
    print(ret_pr)
    if check_zero(ret_pr) > 1e-8:
        print("not all works")
    else:
        print("All good")
Example #19
0
def test_lyapunov():
    alpha = randint(1, 10, 2) * .1
    beta = randint(1, 10, 1)[0] * .02
    n = 5
    d = 3
    man = ComplexPositiveSemidefinite(n, d, alpha=alpha, beta=beta)
    S = man.rand()

    P = S.P
    B = crandn(d, d)
    alpha1 = alpha[1]

    def L(X, P):
        Piv = la.inv(P)
        return (alpha1 - 2 * beta) * X + beta * (P @ X @ Piv + Piv @ X @ P)

    X = extended_lyapunov(alpha1, beta, P, B)
    # L(X, P)
    print(check_zero(B - L(X, P)))
def test_chris_vectorfields():
    # now test that it works on embedded metrics
    # we test that D_xi (eta g eta) = 2(eta g nabla_xi eta)
    n, d = (5, 3)
    A = make_sym_pos(n)
    B = make_sym_pos(d)

    man = RealStiefelWoodbury(n, d, A=A, B=B)

    slp = randn(n * d)
    Y0 = man.rand()
    slpxi = randn(n * d)

    aa = randn(n * d, n * d)
    aaxi = randn(n * d, n * d)

    def v_func(Y):
        return man.proj(Y, (aa @ (Y - Y0).reshape(-1) + slp).reshape(n, d))

    YY = Y0.copy()
    xi = man.proj(YY, slpxi.reshape(n, d))

    nabla_xi_v, dv, cxv = calc_covar_numeric(man, YY, xi, v_func)

    def xi_func(Y):
        return man.proj(Y, (aaxi @ (Y - Y0).reshape(-1) + slpxi).reshape(n, d))

    vv = v_func(YY)

    nabla_v_xi, dxi, cxxi = calc_covar_numeric(man, YY, vv, xi_func)
    diff = nabla_xi_v - nabla_v_xi
    print(diff)
    # now do Lie bracket:
    dlt = 1e-7
    YnewXi = YY + dlt * xi
    Ynewvv = YY + dlt * vv
    vnewxi = v_func(YnewXi)
    xnewv = xi_func(Ynewvv)
    dxiv = (vnewxi - vv) / dlt
    dvxi = (xnewv - xi) / dlt
    diff2 = man.proj(YY, dxiv - dvxi)
    print(check_zero(diff - diff2))
Example #21
0
def test_covariance_deriv():
    # now test full:
    # do covariant derivatives
    # check that it works, preseving everything
    n, d = (5, 3)
    alpha = randint(1, 10, 2) * .1
    beta = randint(1, 10, 2)[0] * .01
    man = ComplexPositiveSemidefinite(n, d, alpha=alpha, beta=beta)
    S = man.rand()

    aa = crandn(n * d, n * d)
    cc = crandn(d * d, d * d)
    icpt = man._rand_ambient()

    def omg_func(S):
        csp = hsym((cc @ S.P.reshape(-1)).reshape(d, d))
        return psd_ambient(
            (aa @ S.Y.reshape(-1) + icpt.tY.reshape(-1)).reshape(n, d),
            csp + icpt.tP)

    xi = man.randvec(S)
    egrad = omg_func(S)
    ecsp = hsym((cc @ xi.tP.reshape(-1)).reshape(d, d))
    ehess = psd_ambient((aa @ xi.tY.reshape(-1)).reshape(n, d), ecsp)

    val1 = man.ehess2rhess(S, egrad, ehess, xi)

    def rgrad_func(W):
        return man.proj_g_inv(W, omg_func(W))

    if False:
        first = ehess
        a = man.J_g_inv(S, egrad)
        rgrad = man.proj_g_inv(S, egrad)
        second = man.D_g(S, xi, man.g_inv(S, egrad)).scalar_mul(-1)
        aout = man.solve_J_g_inv_Jst(S, a)
        third = man.proj(S, man.D_g_inv_Jst(S, xi, aout)).scalar_mul(-1)
        fourth = man.christoffel_form(S, xi, rgrad)
        val1a1 = man.proj_g_inv(S, first + second + fourth) + third
        print(check_zero(man._vec(val1 - val1a1)))
    elif True:
        d_xi_rgrad = num_deriv_amb(man, S, xi, rgrad_func)
        rgrad = man.proj_g_inv(S, egrad)
        fourth = man.christoffel_form(S, xi, rgrad)
        val1a = man.proj(S, d_xi_rgrad) + man.proj_g_inv(S, fourth)
        print(check_zero(man._vec(val1 - val1a)))

    # nabla_v_xi, dxi, cxxi
    val2a, _, _ = calc_covar_numeric(man, S, xi, omg_func)
    val2, _, _ = calc_covar_numeric(man, S, xi, rgrad_func)
    # val2_p = project(prj, val2)
    val2_p = man.proj(S, val2)
    # print(val1)
    # print(val2_p)
    print(check_zero(man._vec(val1) - man._vec(val2_p)))
    if True:
        H = xi
        valrangeA_ = ehess + man.g(S, man.D_proj(
            S, H, man.g_inv(S, egrad))) - man.D_g(
                S, H, man.g_inv(S, egrad)) +\
            man.christoffel_form(S, H, man.proj_g_inv(S, egrad))
        valrangeB = man.proj_g_inv(S, valrangeA_)
    valrange = man.ehess2rhess_alt(S, egrad, ehess, xi)
    print(check_zero(man._vec(valrange) - man._vec(val2_p)))
    print(check_zero(man._vec(valrange) - man._vec(val1)))
    print(check_zero(man._vec(valrange) - man._vec(valrangeB)))
def test_chris_vectorfields():
    # now test that it works on embedded metrics
    # we test that D_xi (eta g eta) = 2(eta g nabla_xi eta)
    alpha = randint(1, 10, 2) * .1
    gamma = randint(1, 10, 2) * .1
    beta = randint(1, 10, 2)[0] * .1

    m = 4
    n = 5
    p = 3
    man = ComplexFixedRank(m, n, p, alpha=alpha, beta=beta, gamma=gamma)

    S0 = man.rand()
    aaU = crandn(m*p, m*p)
    intcU = crandn(m*p)
    aaV = crandn(n*p, n*p)
    intcV = crandn(n*p)
    
    cc = crandn(p*p, p*p)
    p_intc = hsym(crandn(p, p))

    inct_xi = man._rand_ambient()
    aa_xiU = crandn(m*p, m*p)
    aa_xiV = crandn(n*p, n*p)
    cc_xi = crandn(p*p, p*p)
    
    def v_func(S):
        # a function from the manifold
        # to ambient
        csp = hsym((cc @ (S.P-S0.P).reshape(-1)).reshape(p, p))
        
        return man.proj(S, fr_ambient(
            (aaU @ (S.U-S0.U).reshape(-1) + intcU).reshape(m, p),
            (aaV @ (S.V-S0.V).reshape(-1) + intcV).reshape(n, p),
            csp + p_intc))

    SS = fr_point(S0.U, S0.V, S0.P)
    xi = man.proj(SS, inct_xi)

    nabla_xi_v, dv, cxv = calc_covar_numeric(
        man, SS, xi, v_func)

    def xi_func(S):
        csp_xi = hsym((cc_xi @ (S.P-S0.P).reshape(-1)).reshape(p, p))
        xi_amb = fr_ambient(
            (aa_xiU @ (S.U-S0.U).reshape(-1) +
             inct_xi.tU.reshape(-1)).reshape(m, p),
            (aa_xiV @ (S.V-S0.V).reshape(-1) +
             inct_xi.tV.reshape(-1)).reshape(n, p),
            csp_xi + inct_xi.tP)
        return man.proj(S, xi_amb)

    vv = v_func(SS)

    nabla_v_xi, dxi, cxxi = calc_covar_numeric(
        man, SS, vv, xi_func)
    diff = nabla_xi_v - nabla_v_xi
    print(diff.tU, diff.tV, diff.tP)
    # now do Lie bracket:
    dlt = 1e-7
    SnewXi = fr_point(SS.U+dlt*xi.tU,
                      SS.V+dlt*xi.tV,
                      SS.P+dlt*xi.tP)
    Snewvv = fr_point(SS.U+dlt*vv.tU,
                      SS.V+dlt*vv.tV,
                      SS.P+dlt*vv.tP)
    vnewxi = v_func(SnewXi)
    xnewv = xi_func(Snewvv)
    dxiv = (vnewxi - vv).scalar_mul(1/dlt)
    dvxi = (xnewv - xi).scalar_mul(1/dlt)
    diff2 = man.proj(SS, dxiv-dvxi)
    print(check_zero(man._vec(diff) - man._vec(diff2)))
Example #23
0
def test_all_projections():
    alpha = randint(1, 10, 2) * .1
    beta = randint(1, 10, 1)[0] * .02
    n = 5
    d = 3
    man = ComplexPositiveSemidefinite(n, d, alpha=alpha, beta=beta)
    print(man)
    S = man.rand()

    test_inner(man, S)
    test_J(man, S)

    # now check metric, Jst etc
    # check Jst: vectorize the operator J then compare Jst with jmat.T
    jmat = make_j_mat(man, S)
    test_Jst(man, S, jmat)
    ginv_mat = make_g_inv_mat(man, S)
    ee = man._rand_ambient()
    g1 = man._unvec(ginv_mat @ man._vec(ee))
    print(check_zero(man.g_inv(S, ee).tP - g1.tP))
    print(check_zero(man.g_inv(S, ee).tY - g1.tY))
    # test g_inv_Jst
    for ii in range(10):
        a = man._rand_range_J()
        avec = man._vec_range_J(a)
        jtout = ginv_mat @ jmat.T @ avec
        jtout2 = man._vec(man.g_inv_Jst(S, a))
        diff = check_zero(jtout - jtout2)
        print(diff)
    # test projection
    test_projection(man, S)
    # now diff projection

    for i in range(1):
        e = man._rand_ambient()
        S1 = man.rand()
        xi = man.randvec(S1)
        dlt = 1e-7
        S2 = psd_point(S1.Y + dlt * xi.tY, S1.P + dlt * xi.tP)

        # S = psd_point(S1.Y, S1.P)
        d1P = (man.proj(S2, e).tP - man.proj(S1, e).tP) / dlt
        d1Y = (man.proj(S2, e).tY - man.proj(S1, e).tY) / dlt
        d2 = man.D_proj(S1, xi, e)
        print(check_zero(d1P - d2.tP) + check_zero(d1Y - d2.tY))

    for i in range(10):
        a = man._rand_range_J()
        eta = man._rand_ambient()
        print(man.base_inner_ambient(eta, man.Jst(S, a)))
        print((trace((eta.tP.T.conjugate() - eta.tP) @ a['P'] +
                     (man.alpha[1] * eta.tY.T.conjugate() @ S.Y + man.beta *
                      (S.Pinv @ eta.tP.T.conjugate() -
                       eta.tP.T.conjugate() @ S.Pinv)) @ a['YP'])).real)

        print((trace(2 * eta.tP.T.conjugate() @ a['P']) + trace(
            (man.alpha[1] * eta.tY.T.conjugate() @ S.Y + man.beta *
             (S.Pinv @ eta.tP.T.conjugate() - eta.tP.T.conjugate() @ S.Pinv))
            @ a['YP'])).real)

        print((trace(
            eta.tP.T.conjugate() @ (2 * a['P'] + man.beta *
                                    (a['YP'] @ S.Pinv - S.Pinv @ a['YP']))) +
               trace(eta.tY.T.conjugate() @ (man.alpha[1] * S.Y @ a['YP']))
               ).real)

        print(man.base_inner_E_J(man.J(S, eta), a))
        print((
            trace((eta.tP - eta.tP.T.conjugate()).T.conjugate() @ a['P'] +
                  (man.alpha[1] * S.Y.T.conjugate() @ eta.tY + man.beta *
                   (eta.tP @ S.Pinv - S.Pinv @ eta.tP)).T.conjugate() @ a['YP']
                  )).real)

    for i in range(10):
        a = man._rand_range_J()
        beta = man.beta
        alf = man.alpha
        anew1 = man.J(S, man.g_inv_Jst(S, a))

        anew = {}
        saYP = a['YP'] + a['YP'].T.conjugate()
        anew['P'] = 4 / beta * S.P @ a['P'] @ S.P + S.P @ saYP - saYP @ S.P
        anew['YP'] = alf[1] * a['YP'] + beta * (
            ((2 / man.beta) * S.P @ a['P'] @ S.P + S.P @ a['YP'] -
             a['YP'] @ S.P) @ S.Pinv - S.Pinv @ (
                 (2 / man.beta) * S.P @ a['P'] @ S.P + S.P @ a['YP'] -
                 a['YP'] @ S.P))

        anew['YP'] = alf[1] * a['YP'] + (
            (2 * S.P @ a['P'] + beta * S.P @ a['YP'] @ S.Pinv - beta * a['YP'])
            - (2 * a['P'] @ S.P + beta * a['YP'] -
               beta * S.Pinv @ a['YP'] @ S.P))

        anew['YP'] = (alf[1] - 2 * beta) * a['YP'] + (
            (2 * S.P @ a['P'] + beta * S.P @ a['YP'] @ S.Pinv) -
            (2 * a['P'] @ S.P - beta * S.Pinv @ a['YP'] @ S.P))

        anew['YP'] = (alf[1] - 2 * beta) * a['YP'] + (
            (2 * S.P @ a['P'] - 2 * a['P'] @ S.P +
             beta * S.P @ a['YP'] @ S.Pinv + beta * S.Pinv @ a['YP'] @ S.P))
        print(check_zero(man._vec_range_J(anew1) - man._vec_range_J(anew)))

    for i in range(10):
        a = man._rand_range_J()
        b1 = man.J(S, man.g_inv_Jst(S, a))
        b2 = man.J_g_inv_Jst(S, a)
        print(check_zero(man._vec_range_J(b1) - man._vec_range_J(b2)))
        a1 = man.solve_J_g_inv_Jst(S, b1)
        print(check_zero(man._vec_range_J(a) - man._vec_range_J(a1)))

    for ii in range(10):
        E = man._rand_ambient()
        a2 = man.J_g_inv(S, E)
        a1 = man.J(S, man.g_inv(S, E))
        print(check_zero(man._vec_range_J(a1) - man._vec_range_J(a2)))

    for i in range(20):
        Uran = man._rand_ambient()
        Upr = man.proj(S, man.g_inv(S, Uran))
        Upr2 = man.proj_g_inv(S, Uran)
        print(check_zero(man._vec(Upr) - man._vec(Upr2)))

    for ii in range(10):
        a = man._rand_range_J()
        xi = man.randvec(S)
        jtout2 = man.Jst(S, a)
        dlt = 1e-7
        Snew = psd_point(S.Y + dlt * xi.tY, S.P + dlt * xi.tP)
        jtout2a = man.Jst(Snew, a)
        d1 = (jtout2a - jtout2).scalar_mul(1 / dlt)
        d2 = man.D_Jst(S, xi, a)
        print(check_zero(man._vec(d2) - man._vec(d1)))

    for ii in range(10):
        S1 = man.rand()
        eta = man._rand_ambient()
        xi = man.randvec(S1)
        a1 = man.J(S1, eta)
        dlt = 1e-8
        Snew = psd_point(S1.Y + dlt * xi.tY, S1.P + dlt * xi.tP)
        a2 = man.J(Snew, eta)
        d1 = {
            'P': (a2['P'] - a1['P']) / dlt,
            'YP': (a2['YP'] - a1['YP']) / dlt
        }
        d2 = man.D_J(S1, xi, eta)
        print(check_zero(man._vec_range_J(d2) - man._vec_range_J(d1)))

    # derives metrics
    for ii in range(10):
        S1 = man.rand()
        xi = man.randvec(S1)
        omg1 = man._rand_ambient()
        omg2 = man._rand_ambient()
        dlt = 1e-7
        S2 = psd_point(S1.Y + dlt * xi.tY, S1.P + dlt * xi.tP)
        p1 = man.inner(S1, omg1, omg2)
        p2 = man.inner(S2, omg1, omg2)
        der1 = (p2 - p1) / dlt
        der2 = man.base_inner_ambient(man.D_g(S1, xi, omg2), omg1)
        print(der1 - der2)
        if np.abs(der1 - der2) > 1e-4:
            print(der1, der2)
            break

    # cross term for christofel
    for i in range(10):
        S1 = man.rand()
        xi = man.randvec(S1)
        eta1 = man.randvec(S1)
        eta2 = man.randvec(S1)
        dr1 = man.D_g(S1, xi, eta1)
        x12 = man.contract_D_g(S1, eta1, eta2)

        p1 = man.base_inner_ambient(dr1, eta2)
        p2 = man.base_inner_ambient(x12, xi)
        print(p1, p2, p1 - p2)

    # now test christofel:
    # two things: symmetric on vector fields
    # and christofel relation
    # in the case metric
    for i in range(10):
        S1 = man.rand()
        xi = man.randvec(S1)
        eta1 = man.randvec(S1)
        eta2 = man.randvec(S1)
        p1 = man.proj_g_inv(S1, man.christoffel_form(S1, xi, eta1))
        p2 = man.proj_g_inv(S1, man.christoffel_form(S1, eta1, xi))
        print(check_zero(man._vec(p1) - man._vec(p2)))
        v1 = man.base_inner_ambient(man.christoffel_form(S1, eta1, eta2), xi)
        v2 = man.base_inner_ambient(man.D_g(S1, eta1, eta2), xi)
        v3 = man.base_inner_ambient(man.D_g(S1, eta2, eta1), xi)
        v4 = man.base_inner_ambient(man.D_g(S1, xi, eta1), eta2)
        print(v1, 0.5 * (v2 + v3 - v4), v1 - 0.5 * (v2 + v3 - v4))
def test_rhess_02():
    alpha = randint(1, 10, 2) * .1
    gamma = randint(1, 10, 2) * .1
    beta = randint(1, 10, 2)[0] * .1

    m = 4
    n = 5
    p = 3
    man = ComplexFixedRank(m, n, p, alpha=alpha, beta=beta, gamma=gamma)

    S = man.rand()
    # simple function. Distance to a given matrix
    # || S - A||_F^2 Basically SVD
    A = crandn(m, n)

    def f(S):
        diff = (A - S.U @ S.P @ S.V.T.conj())
        return rtrace(diff @ diff.T.conj())

    def df(S):
        return fr_ambient(-2*A @ S.V @ S.P,
                          -2*A.T.conj() @ S.U @S.P,
                          2*(S.P-S.U.T.conj() @ A @ S.V))
    
    def ehess_vec(S, xi):
        return fr_ambient(-2*A @ (xi.tV @ S.P + S.V @ xi.tP),
                          -2*A.T.conj() @ (xi.tU @S.P + [email protected]),
                          2*(xi.tP - xi.tU.T.conj()@[email protected] -
                             S.U.T.conj()@[email protected]))
    
    def ehess_form(S, xi, eta):
        ev = ehess_vec(S, xi)
        return rtrace(ev.tU.T.conj() @ eta.tU) +\
            rtrace(ev.tV.T.conj() @ eta.tV) +\
            rtrace(ev.tP.T.conj() @ eta.tP)
    
    xxi = man.randvec(S)
    dlt = 1e-8
    Snew = fr_point(
        S.U+dlt*xxi.tU,
        S.V+dlt*xxi.tV,
        S.P + dlt*xxi.tP)
    d1 = (f(Snew) - f(S))/dlt
    d2 = df(S)
    print(d1 - man.base_inner_ambient(d2,  xxi))

    dv1 = (df(Snew) - df(S)).scalar_mul(1/dlt)
    dv2 = ehess_vec(S, xxi)
    print(man._vec(dv1-dv2))
    
    eeta = man.randvec(S)
    d1 = man.base_inner_ambient((df(Snew) - df(S)), eeta) / dlt
    ehess_val = ehess_form(S, xxi, eeta)
    
    print(man.base_inner_ambient(dv2, eeta))
    print(d1, ehess_val, d1-ehess_val)

    # now check the formula: ehess = xi (eta_func(f)) - <D_xi eta, df(Y)>
    # promote eta to a vector field.

    mU1 = crandn(m, m)
    mV1 = crandn(n, n)
    m2 = crandn(p, p)
    m_p = crandn(p*p, p*p)

    def eta_field(Sin):
        return man.proj(S, fr_ambient(
            mU1 @ (Sin.U - S.U) @ m2,
            mV1 @ (Sin.V - S.V) @ m2,
            hsym((m_p @ (Sin.P - S.P).reshape(-1)).reshape(p, p)))) + eeta

    # xietaf: should go to ehess(xi, eta) + df(Y) @ etafield)
    xietaf = (man.base_inner_ambient(df(Snew), eta_field(Snew)) -
              man.base_inner_ambient(df(S), eta_field(S))) / dlt
    # appy eta_func to f: should go to tr(m1 @ xxi @ m2 @ df(Y).T.conj())
    Dxietaf = man.base_inner_ambient(
        (eta_field(Snew) - eta_field(S)), df(S))/dlt
    # this is ehess. should be same as d1 or ehess_val
    print(xietaf-Dxietaf)
    print(xietaf-Dxietaf-ehess_val)

    # now check: rhess. Need to make sure xi, eta in the tangent space.
    # first compare this with numerical differentiation
    xi1 = man.proj(S, xxi)
    eta1 = man.proj(S, eeta)
    egvec = df(S)
    ehvec = ehess_vec(S, xi1)
    rhessvec = man.ehess2rhess(S, egvec, ehvec, xi1)

    # check it numerically:
    def rgrad_func(Y):
        return man.proj_g_inv(Y, df(Y))
    
    # val2a, _, _ = calc_covar_numeric_raw(man, W, xi1, df)
    val2, _, _ = calc_covar_numeric(man, S, xi1, rgrad_func)
    val2_p = man.proj(S, val2)
    # print(rhessvec)
    # print(val2_p)
    print(man._vec(rhessvec-val2_p))
    rhessval = man.inner(S, rhessvec, eta1)
    print(man.inner(S, val2, eta1))
    print(rhessval)

    # check symmetric:
    ehvec_e = ehess_vec(S, eta1)
    rhessvec_e = man.ehess2rhess(S, egvec, ehvec_e, eta1)
    rhessval_e = man.inner(S, rhessvec_e, xi1)
    print(rhessval_e)
    # the above computed inner_prod(Nabla_xi Pi * df, eta)
    # in the following check. Extend eta1 to eta_proj
    # (Pi Nabla_hat Pi g_inv df, g eta)
    # = D_xi (Pi g_inv df, g eta) - (Pi g_inv df g Pi Nabla_hat eta)
    
    def eta_proj(S):
        return man.proj(S, eta_field(S))
    print(check_zero(man._vec(eta1-eta_proj(S))))
    
    e1 = man.inner(S, man.proj_g_inv(S, df(S)), eta_proj(S))
    e1a = man.base_inner_ambient(df(S), eta_proj(S))
    print(e1, e1a, e1-e1a)
    Snew = fr_point(
        S.U + dlt*xi1.tU,
        S.V + dlt*xi1.tV,
        S.P + dlt*xi1.tP)
    e2 = man.inner(Snew, man.proj_g_inv(Snew, df(Snew)), eta_proj(Snew))
    e2a = man.base_inner_ambient(df(Snew), eta_proj(Snew))
    print(e2, e2a, e2-e2a)
    
    first = (e2 - e1)/dlt
    first1 = (man.base_inner_ambient(df(Snew), eta_proj(Snew)) -
              man.base_inner_ambient(df(S), eta_proj(S)))/dlt
    print(first-first1)
    
    val3, _, _ = calc_covar_numeric(man, S, xi1, eta_proj)
    second = man.inner(S, man.proj_g_inv(S, df(S)), man.proj(S, val3))
    second2 = man.inner(S, man.proj_g_inv(S, df(S)), val3)
    print(second, second2, second-second2)
    print('same as rhess_val %f' % (first-second))
def test_all_projections():
    dvec = np.array([10, 3, 2, 3])
    p = dvec.shape[0] - 1
    alpha = randint(1, 10, (p, p + 1)) * .1
    man = ComplexFlag(dvec, alpha=alpha)
    Y = man.rand()
    U = man._rand_ambient()
    Upr = man.proj(Y, U)

    test_inner(man, Y)
    test_J(man, Y)

    # now check metric, Jst etc
    # check Jst: vectorize the operator J then compare Jst with jmat.T.conjugate()
    jmat = make_j_mat(man, Y)
    test_Jst(man, Y, jmat)
    ginv_mat = make_g_inv_mat(man, Y)
    # test g_inv_Jst
    for ii in range(10):
        a = man._rand_range_J()
        avec = man._vec_range_J(a)
        jtout = man._unvec(ginv_mat @ jmat.T @ avec)

        jtout2 = man.g_inv_Jst(Y, a)
        diff = check_zero(jtout - jtout2)
        print(diff)
    # test projection
    test_projection(man, Y)

    for i in range(20):
        Uran = man._rand_ambient()
        Upr = man.proj(Y, man.g_inv(Y, Uran))
        Upr2 = man.proj_g_inv(Y, Uran)
        print(check_zero(Upr - Upr2))

    for ii in range(10):
        a = man._rand_range_J()
        xi = man._rand_ambient()
        jtout2 = man.Jst(Y, a)
        dlt = 1e-7
        Ynew = Y + dlt * xi
        jtout2a = man.Jst(Ynew, a)
        d1 = (jtout2a - jtout2) / dlt
        d2 = man.D_Jst(Y, xi, a)
        print(check_zero(d2 - d1))

    for ii in range(10):
        Y = man.rand()
        eta = man._rand_ambient()
        xi = man.randvec(Y)
        a1 = man.J(Y, eta)
        dlt = 1e-7
        Ynew = Y + dlt * xi
        a2 = man.J(Ynew, eta)
        d1 = (man._vec_range_J(a2) - man._vec_range_J(a1)) / dlt
        d2 = man._vec_range_J(man.D_J(Y, xi, eta))
        print(check_zero(d2 - d1))

    for ii in range(10):
        a = man._rand_range_J()
        xi = man._rand_ambient()
        jtout2 = man.g_inv_Jst(Y, a)
        dlt = 1e-7
        Ynew = Y + dlt * xi
        jtout2a = man.g_inv_Jst(Ynew, a)
        d1 = (jtout2a - jtout2) / dlt
        d2 = man.D_g_inv_Jst(Y, xi, a)
        print(check_zero(d2 - d1))

    for ii in range(10):
        arand = man._rand_range_J()
        a2 = man.solve_J_g_inv_Jst(Y, arand)
        a1 = man.J(Y, man.g_inv_Jst(Y, a2))
        print(check_zero(man._vec_range_J(a1) - man._vec_range_J(arand)))

    # derives
    for ii in range(10):
        Y1 = man.rand()
        xi = man.randvec(Y1)
        omg1 = man._rand_ambient()
        omg2 = man._rand_ambient()
        dlt = 1e-7
        Y2 = Y1 + dlt * xi
        p1 = man.inner(Y1, omg1, omg2)
        p2 = man.inner(Y2, omg1, omg2)
        der1 = (p2 - p1) / dlt
        der2 = man.base_inner_ambient(man.D_g(Y1, xi, omg2), omg1)
        print(check_zero(der1 - der2))

    # cross term for christofel
    for i in range(10):
        Y1 = man.rand()
        xi = man.randvec(Y1)
        omg1 = man._rand_ambient()
        omg2 = man._rand_ambient()
        dr1 = man.D_g(Y1, xi, omg1)
        x12 = man.contract_D_g(Y1, omg1, omg2)

        p1 = trace(dr1 @ omg2.T.conjugate()).real
        p2 = trace(x12 @ xi.T.conjugate()).real
        print(p1, p2, p1 - p2)

    # now test christofel:
    # two things: symmetric on vector fields
    # and christofel relation
    # in the case metric
    for i in range(10):
        Y1 = man.rand()
        xi = man.randvec(Y1)
        eta1 = man.randvec(Y1)
        eta2 = man.randvec(Y1)
        p1 = man.proj_g_inv(Y1, man.christoffel_form(Y1, xi, eta1))
        p2 = man.proj_g_inv(Y1, man.christoffel_form(Y1, eta1, xi))
        print(check_zero(p1 - p2))
        v1 = man.base_inner_ambient(man.christoffel_form(Y1, eta1, eta2), xi)
        v2 = man.base_inner_ambient(man.D_g(Y1, eta1, eta2), xi)
        v3 = man.base_inner_ambient(man.D_g(Y1, eta2, eta1), xi)
        v4 = man.base_inner_ambient(man.D_g(Y1, xi, eta1), eta2)
        print(v1, 0.5 * (v2 + v3 - v4), v1 - 0.5 * (v2 + v3 - v4))
        """
def test_rhess_02():
    np.random.seed(0)
    dvec = np.array([10, 3, 2, 3])
    p = dvec.shape[0] - 1
    alpha = randint(1, 10, (p, p + 1)) * .1
    man = ComplexFlag(dvec, alpha=alpha)
    n = man.n
    d = man.d

    Y = man.rand()
    UU = {}
    p = alpha.shape[0]
    VV = {}
    gidx = man._g_idx

    for rr in range(p):
        UU[rr] = make_sym_pos(n)
        VV[rr] = crandn(n, dvec[rr + 1])

    def f(Y):
        ss = 0
        for rr in range(p):
            br, er = gidx[rr + 1]
            wr = Y[:, br:er]
            ss += trace(UU[rr] @ wr @ wr.T.conjugate()).real
        return ss

    def df(W):
        ret = np.zeros_like(W)
        for rr in range(p):
            br, er = gidx[rr + 1]
            wr = W[:, br:er]
            ret[:, br:er] += 2 * UU[rr] @ wr
        return ret

    def ehess_form(W, xi, eta):
        ss = 0
        for rr in range(p):
            br, er = gidx[rr + 1]
            ss += 2 * trace(
                UU[rr] @ xi[:, br:er] @ eta[:, br:er].T.conjugate()).real
        return ss

    def ehess_vec(W, xi):
        ret = np.zeros_like(W)
        for rr in range(p):
            br, er = gidx[rr + 1]
            ret[:, br:er] += 2 * UU[rr] @ xi[:, br:er]
        return ret

    xxi = crandn(n, d)
    dlt = 1e-8
    Ynew = Y + dlt * xxi
    d1 = (f(Ynew) - f(Y)) / dlt
    d2 = df(Y)
    print(d1 - trace(d2 @ xxi.T.conjugate()).real)

    eeta = crandn(n, d)

    d1 = trace((df(Ynew) - df(Y)) @ eeta.T.conjugate()).real / dlt
    ehess_val = ehess_form(Y, xxi, eeta)
    # ehess_val2 = ehess_form(Y, eeta, xxi)
    dv2 = ehess_vec(Y, xxi)
    print(trace(dv2 @ eeta.T.conjugate()).real)
    print(d1, ehess_val, d1 - ehess_val)

    # now check the formula: ehess = xi (eta_func(f)) - <D_xi eta, df(Y)>
    # promote eta to a vector field.

    m1 = crandn(n, n)
    m2 = crandn(d, d)

    def eta_field(Yin):
        return m1 @ (Yin - Y) @ m2 + eeta

    # xietaf: should go to ehess(xi, eta) + df(Y) @ etafield)
    xietaf = trace(
        df(Ynew) @ eta_field(Ynew).T.conjugate() -
        df(Y) @ eta_field(Y).T.conjugate()).real / dlt
    # appy eta_func to f: should go to tr(m1 @ xxi @ m2 @ df(Y).T.conjugate())
    Dxietaf = trace(
        (eta_field(Ynew) - eta_field(Y)) @ df(Y).T.conjugate()).real / dlt
    # this is ehess. should be same as d1 or ehess_val
    print(xietaf - Dxietaf)
    print(xietaf - Dxietaf - ehess_val)

    # now check: rhess. Need to make sure xi, eta in the tangent space.
    # first compare this with numerical differentiation
    xi1 = man.proj(Y, xxi)
    eta1 = man.proj(Y, eeta)
    egvec = df(Y)
    ehvec = ehess_vec(Y, xi1)
    rhessvec = man.ehess2rhess(Y, egvec, ehvec, xi1)

    # check it numerically:
    def rgrad_func(Y):
        return man.proj_g_inv(Y, df(Y))

    val2, _, _ = calc_covar_numeric(man, Y, xi1, rgrad_func)
    val2_p = man.proj(Y, val2)
    # print(rhessvec)
    # print(val2_p)
    print(check_zero(rhessvec - val2_p))
    rhessval = man.inner(Y, rhessvec, eta1)
    print(man.inner(Y, val2, eta1))
    print(rhessval)

    # check symmetric:
    ehvec_e = ehess_vec(Y, eta1)
    ehess_valp = ehess_form(Y, xi1, eta1)

    rhessvec_e = man.ehess2rhess(Y, egvec, ehvec_e, eta1)
    rhessval_e = man.inner(Y, rhessvec_e, xi1)
    rhessval_e1 = man.rhess02(Y, xi1, eta1, egvec, ehess_valp)
    # rhessval_e2 = man.rhess02_alt(Y, xi1, eta1, egvec,
    #                              trace([email protected]()).real)
    # print(rhessval_e, rhessval_e1, rhessval_e2)
    print(rhessval_e, rhessval_e1, rhessval_e - rhessval_e1)

    print('rhessval_e %f ' % rhessval_e)

    # the above computed inner_prod(Nabla_xi Pi * df, eta)
    # in the following check. Extend eta1 to eta_proj
    # (Pi Nabla_hat Pi g_inv df, g eta)
    # = D_xi (Pi g_inv df, g eta) - (Pi g_inv df g Pi Nabla_hat eta)

    def eta_proj(Y):
        return man.proj(Y, eta_field(Y))

    print(check_zero(eta1 - eta_proj(Y)))

    e1 = man.inner(Y, man.proj_g_inv(Y, df(Y)), eta_proj(Y))
    e1a = trace(df(Y) @ eta_proj(Y).T.conjugate()).real
    print(e1, e1a, e1 - e1a)
    Ynew = Y + xi1 * dlt
    e2 = man.inner(Ynew, man.proj_g_inv(Ynew, df(Ynew)), eta_proj(Ynew))
    e2a = trace(df(Ynew) @ eta_proj(Ynew).T.conjugate()).real
    print(e2, e2a, e2 - e2a)

    first = (e2 - e1) / dlt
    first1 = trace(
        df(Ynew) @ eta_proj(Ynew).T.conjugate() -
        df(Y) @ eta_proj(Y).T.conjugate()).real / dlt
    print(first - first1)

    val3, _, _ = calc_covar_numeric(man, Y, xi1, eta_proj)
    second = man.inner(Y, man.proj_g_inv(Y, df(Y)), man.proj(Y, val3))
    second2 = man.inner(Y, man.proj_g_inv(Y, df(Y)), val3)
    print(second, second2, second - second2)
    print('same as rhess_val %f' % (first - second))
Example #27
0
def test_rhess_02():
    n, d = (50, 3)
    alpha = randint(1, 10, 2) * .1
    beta = randint(1, 10, 2)[0] * .1
    man = ComplexPositiveSemidefinite(n, d, alpha=alpha, beta=beta)

    S = man.rand()
    # simple function. Distance to a given matrix
    # || S - A||_F^2
    A = hsym(crandn(n, n))

    def f(S):
        diff = (A - S.Y @ S.P @ S.Y.T.conjugate())
        return trace(diff @ diff.T.conjugate())

    def df(S):
        return psd_ambient(-4 * A @ S.Y @ S.P,
                           2 * (S.P - S.Y.T.conjugate() @ A @ S.Y))

    def ehess_form(S, xi, eta):
        return (
            trace(-4 * A @ (xi.tY @ S.P + S.Y @ xi.tP) @ eta.tY.T.conjugate())
            + 2 * trace(
                (xi.tP - xi.tY.T.conjugate() @ A @ S.Y -
                 S.Y.T.conjugate() @ A @ xi.tY) @ eta.tP.T.conjugate())).real

    def ehess_vec(S, xi):
        return psd_ambient(
            -4 * A @ (xi.tY @ S.P + S.Y @ xi.tP),
            2 * (xi.tP - xi.tY.T.conjugate() @ A @ S.Y -
                 S.Y.T.conjugate() @ A @ xi.tY))

    xxi = man.randvec(S)
    dlt = 1e-8
    Snew = psd_point(S.Y + dlt * xxi.tY, S.P + dlt * xxi.tP)
    d1 = (f(Snew) - f(S)) / dlt
    d2 = df(S)
    print(d1 - man.base_inner_ambient(d2, xxi))

    eeta = man.randvec(S)

    d1 = man.base_inner_ambient((df(Snew) - df(S)), eeta) / dlt
    ehess_val = ehess_form(S, xxi, eeta)
    dv2 = ehess_vec(S, xxi)
    print(man.base_inner_ambient(dv2, eeta))
    print(d1, ehess_val, d1 - ehess_val)

    # now check the formula: ehess = xi (eta_func(f)) - <D_xi eta, df(Y)>
    # promote eta to a vector field.

    m1 = crandn(n, n)
    m2 = crandn(d, d)
    m_p = crandn(d * d, d * d)

    def eta_field(Sin):
        return man.proj(
            S,
            psd_ambient(m1 @ (Sin.Y - S.Y) @ m2,
                        hsym((m_p @ (Sin.P - S.P).reshape(-1)).reshape(
                            d, d)))) + eeta

    # xietaf: should go to ehess(xi, eta) + df(Y) @ etafield)
    xietaf = (man.base_inner_ambient(df(Snew), eta_field(Snew)) -
              man.base_inner_ambient(df(S), eta_field(S))) / dlt
    # appy eta_func to f: should go to tr(m1 @ xxi @ m2 @ df(Y).T)
    Dxietaf = man.base_inner_ambient(
        (eta_field(Snew) - eta_field(S)), df(S)) / dlt
    # this is ehess. should be same as d1 or ehess_val
    print(xietaf - Dxietaf)
    print(xietaf - Dxietaf - ehess_val)

    # now check: rhess. Need to make sure xi, eta in the tangent space.
    # first compare this with numerical differentiation
    xi1 = man.proj(S, xxi)
    eta1 = man.proj(S, eeta)
    egvec = df(S)
    ehvec = ehess_vec(S, xi1)
    rhessvec = man.ehess2rhess(S, egvec, ehvec, xi1)

    # check it numerically:
    def rgrad_func(Y):
        return man.proj_g_inv(Y, df(Y))

    # val2a, _, _ = calc_covar_numeric_raw(man, W, xi1, df)
    val2, _, _ = calc_covar_numeric(man, S, xi1, rgrad_func)
    val2_p = man.proj(S, val2)
    # print(rhessvec)
    # print(val2_p)
    print(man._vec(rhessvec - val2_p))
    rhessval = man.inner_product_amb(S, rhessvec, eta1)
    print(man.inner_product_amb(S, val2, eta1))
    print(rhessval)

    # check symmetric:
    ehvec_e = ehess_vec(S, eta1)
    rhessvec_e = man.ehess2rhess(S, egvec, ehvec_e, eta1)
    rhessval_e = man.inner_product_amb(S, rhessvec_e, xi1)
    print(rhessval_e)

    # the above computed inner_prod(Nabla_xi Pi * df, eta)
    # in the following check. Extend eta1 to eta_proj
    # (Pi Nabla_hat Pi g_inv df, g eta)
    # = D_xi (Pi g_inv df, g eta) - (Pi g_inv df g Pi Nabla_hat eta)

    def eta_proj(S):
        return man.proj(S, eta_field(S))

    print(check_zero(man._vec(eta1 - eta_proj(S))))

    e1 = man.inner(S, man.proj_g_inv(S, df(S)), eta_proj(S))
    e1a = man.base_inner_ambient(df(S), eta_proj(S))
    print(e1, e1a, e1 - e1a)
    Snew = psd_point(S.Y + dlt * xi1.tY, S.P + dlt * xi1.tP)
    e2 = man.inner(Snew, man.proj_g_inv(Snew, df(Snew)), eta_proj(Snew))
    e2a = man.base_inner_ambient(df(Snew), eta_proj(Snew))
    print(e2, e2a, e2 - e2a)

    first = (e2 - e1) / dlt
    first1 = (man.base_inner_ambient(df(Snew), eta_proj(Snew)) -
              man.base_inner_ambient(df(S), eta_proj(S))) / dlt
    print(first - first1)

    val3, _, _ = calc_covar_numeric(man, S, xi1, eta_proj)
    second = man.inner(S, man.proj_g_inv(S, df(S)), man.proj(S, val3))
    second2 = man.inner(S, man.proj_g_inv(S, df(S)), val3)
    print(second, second2, second - second2)
    print('same as rhess_val %f' % (first - second))
def optim_test():
    from pymanopt import Problem
    from pymanopt.solvers import TrustRegions
    from pymanopt.function import Callable

    n = 300

    # problem Tr(AXBX^T)
    for i in range(1):
        dvec = np.array([0, 5, 4, 10])
        dvec[0] = n - dvec[1:].sum()
        d = dvec[1:].sum()

        alpha = randint(1, 10, 2) * .1
        D = randint(1, 10, n) * 0.02 + 1
        OO = random_orthogonal(n)
        A = OO @ np.diag(D) @ OO.T.conjugate()
        B = make_sym_pos(d)

        p = dvec.shape[0] - 1
        alpha = randint(1, 10, (p, p + 1)) * .1
        alpha0 = randint(1, 10, (p))
        # alpha0 = randint(1, 2, (p))
        alpha = make_simple_alpha(alpha0, 0)

        man = ComplexFlag(dvec, alpha)

        @Callable
        def cost(X):
            return trace(A @ X @ B @ X.T.conjugate()).real

        @Callable
        def egrad(X):
            return 2 * A @ X @ B

        @Callable
        def ehess(X, H):
            return 2 * A @ H @ B

        X = man.rand()
        if False:
            xi = man.randvec(X)
            d1 = num_deriv(man, X, xi, cost)
            d2 = trace(egrad(X) @ xi.T.conjugate()).real
            print(check_zero(d1 - d2))

        prob = Problem(man, cost, egrad=egrad)
        XInit = man.rand()

        prob = Problem(man, cost, egrad=egrad, ehess=ehess)

        solver = TrustRegions(maxtime=100000, maxiter=100)
        opt = solver.solve(prob, x=XInit, Delta_bar=250)
        print(cost(opt))

        alpha0 = randint(1, 2, (p))
        alpha1 = make_simple_alpha(alpha0, 0)

        man1 = ComplexFlag(dvec, alpha=alpha1)
        prob = Problem(man1, cost, egrad=egrad, ehess=ehess)

        solver = TrustRegions(maxtime=100000, maxiter=100)
        opt = solver.solve(prob, x=XInit, Delta_bar=250)

        alpha0 = randint(1, 2, (p))
        alpha2 = make_simple_alpha(alpha0, -1)
        man1 = ComplexFlag(dvec, alpha=alpha2)
        prob = Problem(man1, cost, egrad=egrad, ehess=ehess)

        solver = TrustRegions(maxtime=100000, maxiter=100)
        opt = solver.solve(prob, x=XInit, Delta_bar=250)
def optim_test3():
    from pymanopt import Problem
    from pymanopt.solvers import TrustRegions
    from pymanopt.function import Callable
    n = 1000

    # problem Tr(AXBX^T)
    for i in range(1):
        # Stiefel manifold
        dvec = np.array([0, 50])
        dvec[0] = n - dvec[1:].sum()
        d = dvec[1:].sum()
        p = dvec.shape[0] - 1

        alpha = randint(1, 10, (p, p + 1)) * .1
        alpha0 = randint(1, 10, (p))
        # alpha0 = randint(1, 2, (p))
        alpha = make_simple_alpha(alpha0, 0)

        B = np.diag(np.concatenate([randint(1, 10, d), np.zeros(n - d)]))
        D = randint(1, 10, n) * 0.02 + 1
        OO = random_orthogonal(n)
        A = OO @ np.diag(D) @ OO.T
        man = ComplexFlag(dvec, alpha)
        cf = 10
        B2 = B @ B

        @Callable
        def cost(X):
            return cf * trace(
                B @ X @ st(X) @ B2 @ X @ st(X) @ B) +\
                trace(st(X) @ A @ X)

        @Callable
        def egrad(X):
            R = cf * 4 * B2 @ X @ st(X) @ B2 @ X + 2 * A @ X
            return R

        @Callable
        def ehess(X, H):
            return 4*cf*B2 @ H @ st(X) @ B2 @ X +\
                4*cf*B2 @ X @ st(H) @ B2 @ X +\
                4*cf*B2 @ X @ st(X) @ B2 @ H + 2*A @ H

        if False:
            X = man.rand()
            xi = man.randvec(X)
            d1 = num_deriv(man, X, xi, cost)
            d2 = trace(egrad(X) @ st(xi)).real
            print(check_zero(d1 - d2))
            d3 = num_deriv(man, X, xi, egrad)
            d4 = ehess(X, xi)
            print(check_zero(d3 - d4))

        XInit = man.rand()
        prob = Problem(man, cost, egrad=egrad, ehess=ehess)

        solver = TrustRegions(maxtime=100000, maxiter=100)
        opt = solver.solve(prob, x=XInit, Delta_bar=2500)
        print(cost(opt))
        if False:
            # print(opt)
            # double check:
            # print(cost(opt))
            min_val = 1e190
            # min_X = None
            for i in range(100):
                Xi = man.rand()
                c = cost(Xi)
                if c < min_val:
                    # min_X = Xi
                    min_val = c
                if i % 1000 == 0:
                    print('i=%d min=%f' % (i, min_val))
            print(min_val)
        alpha0 = randint(1, 2, (p))
        alpha1 = make_simple_alpha(alpha0, 0)

        man1 = ComplexFlag(dvec, alpha=alpha1)
        prob = Problem(man1, cost, egrad=egrad, ehess=ehess)

        solver = TrustRegions(maxtime=100000, maxiter=100)
        opt = solver.solve(prob, x=XInit, Delta_bar=250)

        alpha0 = randint(1, 2, (p))
        alpha2 = make_simple_alpha(alpha0, -1)
        man1 = ComplexFlag(dvec, alpha=alpha2)
        # man1 = RealStiefel(n, d, alpha=np.array([1, 1]))
        prob = Problem(man1, cost, egrad=egrad, ehess=ehess)

        solver = TrustRegions(maxtime=100000, maxiter=100)
        opt = solver.solve(prob, x=XInit, Delta_bar=250)
def test_covariance_deriv():
    # now test full:
    # do covariant derivatives
    alpha = randint(1, 10, 2) * .1
    gamma = randint(1, 10, 2) * .1
    beta = randint(1, 10, 2)[0] * .1

    m = 4
    n = 5
    p = 3
    man = ComplexFixedRank(m, n, p, alpha=alpha, beta=beta, gamma=gamma)
    
    S = man.rand()
    
    aaU = crandn(m*p, m*p)
    aaV = crandn(n*p, n*p)
    cc = crandn(p*p, p*p)
    icpt = man._rand_ambient()

    def omg_func(S):
        csp = hsym((cc @ S.P.reshape(-1)).reshape(p, p))
        return fr_ambient(
            (aaU @ S.U.reshape(-1) + icpt.tU.reshape(-1)).reshape(m, p),
            (aaV @ S.V.reshape(-1) + icpt.tV.reshape(-1)).reshape(n, p),
            csp + icpt.tP)

    xi = man.randvec(S)
    egrad = omg_func(S)
    ecsp = hsym((cc @ xi.tP.reshape(-1)).reshape(p, p))
    ehess = fr_ambient(
        (aaU @ xi.tU.reshape(-1)).reshape(m, p),
        (aaV @ xi.tV.reshape(-1)).reshape(n, p),
        ecsp)

    val1 = man.ehess2rhess(S, egrad, ehess, xi)

    def rgrad_func(W):
        return man.proj_g_inv(W, omg_func(W))

    if False:
        first = ehess
        a = man.J_g_inv(S, egrad)
        rgrad = man.proj_g_inv(S, egrad)
        second = man.D_g(
            S, xi, man.g_inv(S, egrad)).scalar_mul(-1)
        aout = man.solve_J_g_inv_Jst(S, a)
        third = man.proj(S, man.D_g_inv_Jst(S, xi, aout)).scalar_mul(-1)
        fourth = man.christoffel_form(S, xi, rgrad)
        val1a1 = man.proj_g_inv(S, first + second + fourth) + third
        print(check_zero(man._vec(val1-val1a1)))
    elif True:
        d_xi_rgrad = num_deriv_amb(man, S, xi, rgrad_func)
        rgrad = man.proj_g_inv(S, egrad)
        fourth = man.christoffel_form(S, xi, rgrad)
        val1a = man.proj(S, d_xi_rgrad) + man.proj_g_inv(S, fourth)
        print(check_zero(man._vec(val1-val1a)))

    # nabla_v_xi, dxi, cxxi
    val2a, _, _ = calc_covar_numeric(man, S, xi, omg_func)
    val2, _, _ = calc_covar_numeric(man, S, xi, rgrad_func)
    # val2_p = project(prj, val2)
    val2_p = man.proj(S, val2)
    # print(val1)
    # print(val2_p)
    print(check_zero(man._vec(val1)-man._vec(val2_p)))
    if True:
        H = xi
        valrangeA_ = ehess + man.g(S, man.D_proj(
            S, H, man.g_inv(S, egrad))) - man.D_g(
                S, H, man.g_inv(S, egrad)) +\
            man.christoffel_form(S, H, man.proj_g_inv(S, egrad))
        valrangeB = man.proj_g_inv(S, valrangeA_)
    valrange = man.ehess2rhess(S, egrad, ehess, xi)
    print(check_zero(man._vec(valrange)-man._vec(val2_p)))
    print(check_zero(man._vec(valrange)-man._vec(val1)))
    print(check_zero(man._vec(valrange)-man._vec(valrangeB)))