Exemplo n.º 1
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)
Exemplo n.º 2
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))