def solve_dist_with_man(man, A, X0, maxiter):
    from pymanopt import Problem
    from pymanopt.solvers import TrustRegions
    from pymanopt.function import Callable

    @Callable
    def cost(S):
        # if not(S.P.dtype == np.float):
        #    raise(ValueError("Non real"))
        diff = (A - S.U @ S.P @ S.V.T.conj())
        val = rtrace(diff @ diff.T.conj())
        # print('val=%f' % val)
        return val

    @Callable
    def egrad(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))
    
    @Callable
    def ehess(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]))

    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
示例#2
0
def run(backend=SUPPORTED_BACKENDS[0], quiet=True):
    """This example generates a random 128 x 128 symmetric matrix and finds the
    dominant invariant 3 dimensional subspace for this matrix, i.e., it finds
    the subspace spanned by the three eigenvectors with the largest
    eigenvalues.
    """
    num_rows = 128
    subspace_dimension = 3
    matrix = rnd.randn(num_rows, num_rows)
    matrix = 0.5 * (matrix + matrix.T)

    cost, egrad, ehess = create_cost_egrad_ehess(
        backend, matrix, subspace_dimension)
    manifold = Grassmann(num_rows, subspace_dimension)
    problem = pymanopt.Problem(manifold, cost=cost, egrad=egrad, ehess=ehess)
    if quiet:
        problem.verbosity = 0

    solver = TrustRegions()
    estimated_spanning_set = solver.solve(
        problem, Delta_bar=8*np.sqrt(subspace_dimension))

    if quiet:
        return

    eigenvalues, eigenvectors = la.eig(matrix)
    column_indices = np.argsort(eigenvalues)[-subspace_dimension:]
    spanning_set = eigenvectors[:, column_indices]
    print("Geodesic distance between true and estimated dominant subspace:",
          manifold.dist(spanning_set, estimated_spanning_set))
示例#3
0
文件: pca.py 项目: agoel00/MBAweb
def run(backend=SUPPORTED_BACKENDS[0], quiet=True):
    dimension = 3
    num_samples = 200
    num_components = 2
    samples = np.random.randn(num_samples, dimension) @ np.diag([3, 2, 1])
    samples -= samples.mean(axis=0)

    cost, egrad, ehess = create_cost_egrad_ehess(backend, samples,
                                                 num_components)
    manifold = Stiefel(dimension, num_components)
    problem = pymanopt.Problem(manifold, cost, egrad=egrad, ehess=ehess)
    if quiet:
        problem.verbosity = 0

    solver = TrustRegions()
    # from pymanopt.solvers import ConjugateGradient
    # solver = ConjugateGradient()
    estimated_span_matrix = solver.solve(problem)

    if quiet:
        return

    estimated_projector = estimated_span_matrix @ estimated_span_matrix.T

    eigenvalues, eigenvectors = np.linalg.eig(samples.T @ samples)
    indices = np.argsort(eigenvalues)[::-1][:num_components]
    span_matrix = eigenvectors[:, indices]
    projector = span_matrix @ span_matrix.T

    print(
        "Frobenius norm error between estimated and closed-form projection "
        "matrix:", np.linalg.norm(projector - estimated_projector))
示例#4
0
def run(quiet=True):
    dimension = 3
    num_samples = 200
    num_components = 2
    samples = np.random.randn(num_samples, dimension) @ np.diag([3, 2, 1])
    samples -= samples.mean(axis=0)
    samples_ = torch.from_numpy(samples)

    @pymanopt.function.PyTorch
    def cost(w):
        projector = torch.matmul(w, torch.transpose(w, 1, 0))
        return torch.norm(samples_ - torch.matmul(samples_, projector)) ** 2

    manifold = Stiefel(dimension, num_components)
    problem = pymanopt.Problem(manifold, cost, egrad=None, ehess=None)
    if quiet:
        problem.verbosity = 0

    solver = TrustRegions()
    # from pymanopt.solvers import ConjugateGradient
    # solver = ConjugateGradient()
    estimated_span_matrix = solver.solve(problem)

    if quiet:
        return

    estimated_projector = estimated_span_matrix @ estimated_span_matrix.T

    eigenvalues, eigenvectors = np.linalg.eig(samples.T @ samples)
    indices = np.argsort(eigenvalues)[::-1][:num_components]
    span_matrix = eigenvectors[:, indices]
    projector = span_matrix @ span_matrix.T

    print("Frobenius norm error between estimated and closed-form projection "
          "matrix:", np.linalg.norm(projector - estimated_projector))
def run(backend=SUPPORTED_BACKENDS[0], quiet=True):
    num_samples, num_weights = 200, 3

    solver = TrustRegions()
    manifold = Euclidean(3)

    for k in range(5):
        samples = rnd.randn(num_samples, num_weights)
        targets = rnd.randn(num_samples)

        cost, egrad, ehess = create_cost_egrad_ehess(backend, samples, targets)
        problem = pymanopt.Problem(manifold,
                                   cost,
                                   egrad=egrad,
                                   ehess=ehess,
                                   verbosity=0)

        estimated_weights = solver.solve(problem)
        if not quiet:
            print("Run {}".format(k + 1))
            print("Weights found by pymanopt (top) / "
                  "closed form solution (bottom)")
            print(estimated_weights)
            print(la.pinv(samples) @ targets)
            print("")
示例#6
0
def estimateR_weighted(S, W, D, R0):
    '''
    estimates the update of the rotation matrix for the second part of the iterations
    :param S : shape
    :param W : heatmap
    :param D : weight of the heatmap
    :param R0 : rotation matrix
    :return: R the new rotation matrix
    '''

    A = np.transpose(S)
    B = np.transpose(W)
    X0 = R0[0:2, :]
    store_E = Store()

    [m, n] = A.shape
    p = B.shape[1]

    At = np.zeros([n, m])
    At = np.transpose(A)

    # we use the optimization on a Stiefel manifold because R is constrained to be othogonal
    manifold = Stiefel(n, p, 1)

    ####################################################################################################################
    def cost(X):
        '''
        cost function of the manifold, the cost is trace(E'*D*E)/2 with E = A*X - B or store_E
        :param X : vector
        :return f : the cost
        '''

        if store_E.stored is None:
            store_E.stored = np.dot(A, np.transpose(X)) - B

        E = store_E.stored
        f = np.trace(np.dot(np.transpose(E), np.dot(D, E))) / 2

        return f

    ####################################################################################################################

    # setup the problem structure with manifold M and cost
    problem = Problem(manifold=manifold, cost=cost, verbosity=0)

    # setup the trust region algorithm to solve the problem
    TR = TrustRegions(maxiter=10)

    # solve the problem
    X = TR.solve(problem, X0)

    #print('X : ',X)
    return np.transpose(X)  # return R = X'
    def estimate_orth_subspaces(self, DataStruct):
        '''
        main optimization function
        '''

        # Grassman point?
        if LA.norm(np.dot(self.Q.T, self.Q) - np.eye(self.Q.shape[-1]),
                   ord='fro') > 1e-4:
            self._project_stiefel()

        # ----------------------------------------------------------------------- #

        # eGrad = grad(cost)
        # eHess = hessian(cost)

        # Perform optimization
        # ----------------------------------------------------------------------- #
        # ----------------------------------------------------------------------- #

        d, r = np.shape(self.Q)  # problem size
        print(d)

        manif = Stiefel(d, r)  # initialize manifold

        # instantiate problem
        problem = Problem(manifold=manif, cost=self._cost, verbosity=2)

        # initialize solver
        solver = TrustRegions(mingradnorm=1e-8,
                              minstepsize=1e-16,
                              logverbosity=1)

        # solve
        Xopt, optlog = solver.solve(problem)

        opt_subspaces = self._objfn(Xopt)

        # Align the axes within a subspace by variance high to low
        for j in range(self.numSubspaces):
            Aj = DataStruct.A[j]
            Qj = opt_subspaces[2].Q[j]
            # data projected onto subspace
            Aj_proj = np.dot((Aj - np.mean(Aj, 0)), Qj)
            if np.size(np.cov(Aj_proj.T)) < 2:
                V = 1
            else:
                V = LA.svd(np.cov(Aj_proj.T))[0]
            Qj = np.dot(Qj, V)
            opt_subspaces[2].Q[j] = Qj  # ranked top to low variance

        return opt_subspaces[2]
def ManoptOptimization(A, m):
    n = A.shape[0]
    T = A.shape[2]
    manifold = Stiefel(n, m, k=1)

    mycost = lambda x: cost(A, x)
    myegrad = lambda x: egrad(A, x)
    problem = Problem(manifold=manifold, cost=mycost, egrad=myegrad)

    solver = TrustRegions()
    print('# Start optimization using solver: trustregion')
    Xopt = solver.solve(problem)

    return Xopt
def rank_k_correlation_matrix_approximation(A, k):
    """
    Returns the matrix with unit-norm columns that is closests to A w.r.t. the
    Frobenius norm.
    """
    m, n = A.shape
    assert m == n, "matrix must be square"
    assert np.allclose(np.sum(A - A.T), 0), "matrix must be symmetric"

    manifold = Oblique(k, n)
    solver = TrustRegions()
    X = T.matrix()
    cost = 0.25 * T.sum((T.dot(X.T, X) - A) ** 2)

    problem = Problem(manifold=manifold, cost=cost, arg=X)
    return solver.solve(problem)
def rank_k_correlation_matrix_approximation(A, k):
    """
    Returns the matrix with unit-norm columns that is closests to A w.r.t. the
    Frobenius norm.
    """
    m, n = A.shape
    assert m == n, "matrix must be square"
    assert np.allclose(np.sum(A - A.T), 0), "matrix must be symmetric"

    manifold = Oblique(k, n)
    solver = TrustRegions()
    X = T.matrix()
    cost = 0.25 * T.sum((T.dot(X.T, X) - A)**2)

    problem = Problem(manifold=manifold, cost=cost, arg=X)
    return solver.solve(problem)
示例#11
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
示例#12
0
def optimizer_R_v1(W, D, S, R0):
    """
    :param W: heatmap constant
    :param D: weight of the keypoints
    :param S: shape of the object
    :param R0: initial R

    :return : the optimal R with fixed T and s
    the cost is ||(W-(RS))*sqrt(D)|| but in fact is the scale factor is already taken into account in S and T is taken into account in W
    """

    # this store object is needed because the manifold optimizer do not works if it is not implemented like that
    store = Store()

    # -------------------------------------COST FUNCTION-------------------------------------
    def cost(R):
        """
        :param R: rotation matrix variable
        :return : ||(W-(RS))*D^1/2||^2 = tr((W-(RS))*D*(W-(RS))')
        """

        if store.stored is None:
            store.stored = W - np.dot(R, S)

        X = store.stored
        f = np.trace(np.dot(X, np.dot(D, np.transpose(X)))) / 2

        return f

    # ----------------------------------------------------------------------------------------

    # we use the optimization on a Stiefel manifold because R is constrained to be othogonal
    manifold = Stiefel(3, 2, 1)

    # setup the problem structure with manifold M and cost
    problem = Problem(manifold=manifold, cost=cost, verbosity=0)

    # setup the trust region algorithm to solve the problem
    TR = TrustRegions(maxiter=15)

    # solve the problem
    R_opt = TR.solve(problem, R0)

    return np.transpose(R_opt)
def dominant_invariant_subspace(A, p):
    """
    Returns an orthonormal basis of the dominant invariant p-subspace of A.

    Arguments:
        - A
            A real, symmetric matrix A of size nxn
        - p
            integer p < n.
    Returns:
        A real, orthonormal matrix X of size nxp such that trace(X'*A*X)
        is maximized. That is, the columns of X form an orthonormal basis
        of a dominant subspace of dimension p of A. These span the same space
        as  the eigenvectors associated with the largest eigenvalues of A.
        Sign is important: 2 is deemed a larger eigenvalue than -5.
    """
    # Make sure the input matrix is square and symmetric
    n = A.shape[0]
    assert type(A) == np.ndarray, 'A must be a numpy array.'
    assert np.isreal(A).all(), 'A must be real.'
    assert A.shape[1] == n, 'A must be square.'
    assert np.linalg.norm(A-A.T) < n * np.spacing(1), 'A must be symmetric.'
    assert p <= n, 'p must be smaller than n.'

    # Define the cost on the Grassmann manifold
    Gr = Grassmann(n, p)
    X = T.matrix()
    cost = -T.dot(X.T, T.dot(A, X)).trace()

    # Setup the problem
    problem = Problem(manifold=Gr, cost=cost, arg=X)

    # Create a solver object
    solver = TrustRegions()

    # Solve
    Xopt = solver.solve(problem, Delta_bar=8*np.sqrt(p))

    return Xopt
示例#14
0
def run(backend=SUPPORTED_BACKENDS[0], quiet=True):
    num_rows = 1000
    rank = 5
    low_rank_factor = rnd.randn(num_rows, rank)
    matrix = low_rank_factor @ low_rank_factor.T

    cost, egrad, ehess = create_cost_egrad_ehess(backend, matrix, rank)
    manifold = PSDFixedRank(num_rows, rank)
    problem = pymanopt.Problem(manifold, cost=cost, egrad=egrad, ehess=ehess)
    if quiet:
        problem.verbosity = 0

    solver = TrustRegions(maxiter=500, minstepsize=1e-6)
    low_rank_factor_estimate = solver.solve(problem)

    if quiet:
        return

    print("Rank of target matrix:", la.matrix_rank(matrix))
    matrix_estimate = low_rank_factor_estimate @ low_rank_factor_estimate.T
    print("Frobenius norm error of low-rank estimate:",
          la.norm(matrix - matrix_estimate))
def run(backend=SUPPORTED_BACKENDS[0], quiet=True):
    num_rows = 10
    rank = 3
    matrix = rnd.randn(num_rows, num_rows)
    matrix = 0.5 * (matrix + matrix.T)

    # Solve the problem with pymanopt.
    cost, egrad, ehess = create_cost_egrad_ehess(backend, matrix, rank)
    manifold = Oblique(rank, num_rows)
    problem = pymanopt.Problem(manifold, cost, egrad=egrad, ehess=ehess)
    if quiet:
        problem.verbosity = 0

    solver = TrustRegions()
    X = solver.solve(problem)

    if quiet:
        return

    C = X.T @ X
    print("Diagonal elements:", np.diag(C))
    print("Eigenvalues:", np.sort(la.eig(C)[0].real)[::-1])
def dominant_invariant_subspace(A, p):
    """
    Returns an orthonormal basis of the dominant invariant p-subspace of A.

    Arguments:
        - A
            A real, symmetric matrix A of size nxn
        - p
            integer p < n.
    Returns:
        A real, orthonormal matrix X of size nxp such that trace(X'*A*X)
        is maximized. That is, the columns of X form an orthonormal basis
        of a dominant subspace of dimension p of A. These span the same space
        as  the eigenvectors associated with the largest eigenvalues of A.
        Sign is important: 2 is deemed a larger eigenvalue than -5.
    """
    # Make sure the input matrix is square and symmetric
    n = A.shape[0]
    assert type(A) == np.ndarray, 'A must be a numpy array.'
    assert np.isreal(A).all(), 'A must be real.'
    assert A.shape[1] == n, 'A must be square.'
    assert np.linalg.norm(A-A.T) < n * np.spacing(1), 'A must be symmetric.'
    assert p <= n, 'p must be smaller than n.'

    # Define the cost on the Grassmann manifold
    Gr = Grassmann(n, p)
    X = T.matrix()
    cost = -T.dot(X.T, T.dot(A, X)).trace()

    # Setup the problem
    problem = Problem(man=Gr, ad_cost=cost, ad_arg=X)

    # Create a solver object
    solver = TrustRegions()

    # Solve
    Xopt = solver.solve(problem, Delta_bar=8*np.sqrt(p))

    return Xopt
示例#17
0
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)
示例#18
0
if __name__ == "__main__":
    # Generate random data
    X = np.random.randn(3, 100)
    Y = X[0:1, :] - 2 * X[1:2, :] + np.random.randn(1, 100) + 5

    # Cost function is the sqaured test error
    w = T.matrix()
    b = T.matrix()
    cost = T.sum((Y - w.T.dot(X) - b[0, 0])**2)

    # A solver that involves the hessian
    solver = TrustRegions()

    # R^3 x R^1
    manifold = Product([Euclidean(3, 1), Euclidean(1, 1)])

    # Solve the problem with pymanopt
    problem = Problem(manifold=manifold, cost=cost, arg=[w, b], verbosity=0)
    wopt = solver.solve(problem)

    print('Weights found by pymanopt (top) / ' 'closed form solution (bottom)')

    print(wopt[0].T)
    print(wopt[1])

    X1 = np.concatenate((X, np.ones((1, 100))), axis=0)
    wclosed = np.linalg.inv(X1.dot(X1.T)).dot(X1).dot(Y.T)
    print(wclosed[0:3].T)
    print(wclosed[3])
    # Generate random data
    X = np.random.randn(3, 100).astype('float32')
    Y = (X[0:1, :] - 2*X[1:2, :] + np.random.randn(1, 100) + 5).astype(
        'float32')

    # Cost function is the sqaured test error
    w = tf.Variable(tf.zeros([3, 1]))
    b = tf.Variable(tf.zeros([1]))
    cost = tf.reduce_mean(tf.square(Y - tf.matmul(tf.transpose(w), X) - b))

    # first-order, second-order
    solver = TrustRegions()

    # R^3 x R^1
    manifold = Product([Euclidean(3, 1), Euclidean(1, 1)])

    # Solve the problem with pymanopt
    problem = Problem(manifold=manifold, cost=cost, arg=[w, b], verbosity=0)
    wopt = solver.solve(problem)

    print('Weights found by pymanopt (top) / '
          'closed form solution (bottom)')

    print(wopt[0].T)
    print(wopt[1])

    X1 = np.concatenate((X, np.ones((1, 100))), axis=0)
    wclosed = np.linalg.inv(X1.dot(X1.T)).dot(X1).dot(Y.T)
    print(wclosed[0:3].T)
    print(wclosed[3])
示例#20
0
    def manifold_fit(self, Y, X):
        from pymanopt.manifolds import Rotations, Euclidean, Product
        from pymanopt import Problem
        from pymanopt.solvers import TrustRegions
        # from minimal_varx import make_normalized_G

        cov_res, cov_xlag, cov_y_xlag = calc_extended_covariance(Y, X, self.p)
        self.set_covs(cov_res, cov_xlag)
        # m = X.shape[0]

        with_c = (self.mm_degree > self.agg_rnk) and (self.m - self.agg_rnk)
        C = Euclidean(self.mm_degree - self.agg_rnk, self.m - self.agg_rnk)
        RG = Rotations(self.m)
        if with_c:
            raise (ValueError(
                "This option is implemented only for self.agg_rnk == m"))
        if with_c:
            manifold = Product([RG, C])
        else:
            manifold = RG
        if not with_c:
            c_null = np.zeros(
                (self.mm_degree - self.agg_rnk, self.m - self.agg_rnk))
        else:
            c_null = None

        if with_c:

            def cost(x):
                o, c = x
                G = make_normalized_G(self, self.m, o, c)
                self.calc_states(G)
                return self.neg_log_llk
        else:

            def cost(x):
                G = make_normalized_G(self, self.m, x, c_null)
                self.calc_states(G)
                return self.neg_log_llk

        if with_c:

            def egrad(x):
                o, c = x
                grad_o, grad_c = self.map_o_c_grad(self._gradient_tensor, o, c)
                return [grad_o, grad_c]
        else:

            def egrad(x):
                grad_o, grad_c = self.map_o_c_grad(self._gradient_tensor, x,
                                                   c_null)

                return grad_o

        if with_c:

            def ehess(x, Heta):
                o, c = x
                eta = make_normalized_G(self, self.m, Heta[0], Heta[1])
                hess_raw = self.hessian_prod(eta)
                hess_o, hess_c = self.map_o_c_grad(hess_raw, o, c)
                return [hess_o, hess_c]

        else:

            def ehess(x, Heta):
                eta = make_normalized_G(self, self.m, Heta, c_null)
                hess_raw = self.hessian_prod(eta)
                hess_o, hess_c = self.map_o_c_grad(hess_raw, x, c_null)
                return hess_o

        if with_c:
            min_mle = Problem(manifold, cost, egrad=egrad, ehess=ehess)
        else:
            min_mle = Problem(manifold, cost, egrad=egrad, ehess=ehess)

        solver = TrustRegions()
        opt = solver.solve(min_mle)
        if with_c:
            G_opt = make_normalized_G(self, self.m, opt[0], opt[1])
        else:
            G_opt = make_normalized_G(self, self.m, opt, c_null)

        self.calc_H_F_Phi(G_opt, cov_y_xlag)
        return opt
示例#21
0
def nonlinear_eigenspace(L, k, alpha=1):
    """Nonlinear eigenvalue problem: total energy minimization.

    This example is motivated in [1]_ and was adapted from the manopt toolbox
    in Matlab.

    TODO : check this

    Parameters
    ----------
    L : array, shape=(n_channels, n_channels)
        Discrete Laplacian operator: the covariance matrix.
    alpha : float
        Given constant for optimization problem.
    k : int
        Determines how many eigenvalues are returned.

    Returns
    -------
    Xsol : array, shape=(n_channels, n_channels)
        Eigenvectors.
    S0 : array
        Eigenvalues.

    References
    ----------
    .. [1] "A Riemannian Newton Algorithm for Nonlinear Eigenvalue Problems",
       Zhi Zhao, Zheng-Jian Bai, and Xiao-Qing Jin, SIAM Journal on Matrix
       Analysis and Applications, 36(2), 752-774, 2015.

    """
    n = L.shape[0]
    assert L.shape[1] == n, 'L must be square.'

    # Grassmann manifold description
    manifold = Grassmann(n, k)
    manifold._dimension = 1  # hack

    # A solver that involves the hessian (check if correct TODO)
    solver = TrustRegions()

    # Cost function evaluation
    @pymanopt.function.Callable
    def cost(X):
        rhoX = np.sum(X**2, 1, keepdims=True)  # diag(X*X')
        val = 0.5 * np.trace(X.T @ (L * X)) + \
            (alpha / 4) * (rhoX.T @ mldivide(L, rhoX))
        return val

    # Euclidean gradient evaluation
    @pymanopt.function.Callable
    def egrad(X):
        rhoX = np.sum(X**2, 1, keepdims=True)  # diag(X*X')
        g = L @ X + alpha * np.diagflat(mldivide(L, rhoX)) @ X
        return g

    # Euclidean Hessian evaluation
    # Note: Manopt automatically converts it to the Riemannian counterpart.
    @pymanopt.function.Callable
    def ehess(X, U):
        rhoX = np.sum(X**2, 1, keepdims=True)  # np.diag(X * X')
        rhoXdot = 2 * np.sum(X.dot(U), 1)
        h = L @ U + alpha * np.diagflat(mldivide(L, rhoXdot)) @ X + \
            alpha * np.diagflat(mldivide(L, rhoX)) @ U
        return h

    # Initialization as suggested in above referenced paper.
    # randomly generate starting point for svd
    x = np.random.randn(n, k)
    [U, S, V] = linalg.svd(x, full_matrices=False)
    x = U.dot(V.T)
    S0, U0 = linalg.eig(L + alpha * np.diagflat(mldivide(L, np.sum(x**2, 1))))

    # Call manoptsolve to automatically call an appropriate solver.
    # Note: it calls the trust regions solver as we have all the required
    # ingredients, namely, gradient and Hessian, information.
    problem = Problem(manifold=manifold,
                      cost=cost,
                      egrad=egrad,
                      ehess=ehess,
                      verbosity=0)
    Xsol = solver.solve(problem, U0)

    return S0, Xsol
示例#22
0
def egrad(X):
    return -ABt


def ehess(X, S):
    return manifold.zerovec(X)


problem = Problem(manifold=manifold, cost=cost, egrad=egrad, ehess=ehess)
# problem = Problem(manifold=manifold, cost=cost)

solver = TrustRegions()
# solver = SteepestDescent()

X = solver.solve(problem)
# print(X)


def sol(ABt):
    # Compare with the known optimal solution\n",
    U, S, Vt = np.linalg.svd(ABt)
    UVt = np.dot(U, Vt)
    # The determinant of UVt is either 1 or -1, in theory\n",
    if abs(1.0 - np.linalg.det(UVt)) < 1e-10:
        Xopt = UVt
    elif abs(-1.0 - np.linalg.det(UVt)) < 1e-10:
        # UVt is in O(n) but not SO(n). This is easily corrected for:\n",
        J = np.diag(np.append(np.ones(n - 1), -1))
        Xopt = np.dot(np.dot(U, J), Vt)
    else:
def optim_test():
    from pymanopt import Problem
    from pymanopt.solvers import TrustRegions
    from pymanopt.function import Callable

    n = 100
    d = 20
    # problem Tr(AXBX^T)
    for i in range(1):
        D = randint(1, 10, n) * 0.02 + 1
        OO = random_orthogonal(n)
        A = OO @ np.diag(D) @ OO.T
        B = make_sym_pos(d)

        man = RealStiefelWoodbury(n,
                                  d,
                                  A=np.diag(D),
                                  B=np.diag(np.diagonal(B)))

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

        @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)
            print(check_zero(d1 - d2))

        XInit = man.rand()

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

        solver = TrustRegions(maxtime=100000, maxiter=100)
        man.retr_method = 'geo'
        opt = solver.solve(prob, x=XInit, Delta_bar=250)
        print(cost(opt))
        # 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)
        man1 = RealStiefelWoodbury(n, d, np.eye(n), np.eye(d))
        prob1 = Problem(man1, cost, egrad=egrad, ehess=ehess)
        man1.retr_method = 'svd'
        solver1 = TrustRegions(maxtime=100000, maxiter=100)
        opt1 = solver1.solve(prob1, x=XInit, Delta_bar=250)
示例#24
0
def optim_test():
    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):
        dvec = np.array([0, 30, 2, 1])
        dvec[0] = 1000 - dvec[1:].sum()
        d = dvec[1:].sum()
        D = randint(1, 10, n) * 0.02 + 1
        OO = random_orthogonal(n)
        A = OO @ np.diag(D) @ OO.T
        
        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 = RealFlag(dvec, alpha=alpha)

        @Callable
        def cost(X):
            return trace(A @ X @ B @ X.T)
        
        @Callable
        def egrad(X):
            return 2*A @ X @ B

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

        if False:
            X = man.rand()
            xi = man.randvec(X)
            d1 = num_deriv(man, X, xi, cost)
            d2 = trace(egrad(X) @ xi.T)
            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))

        if False:
            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)
        alpha_c = alpha.copy()
        alpha_c[:] = 1
        man1 = RealFlag(dvec, alpha=alpha_c)
        prob = Problem(
            man1, cost, egrad=egrad, ehess=ehess)

        solver = TrustRegions(maxtime=100000, maxiter=100)
        opt = solver.solve(prob, x=XInit, Delta_bar=250)
        alpha_c5 = alpha_c.copy()
        alpha_c5[:, 1:] = .5
        man1 = RealFlag(dvec, alpha=alpha_c5)
        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_test2():
    from pymanopt import Problem
    from pymanopt.solvers import TrustRegions
    from pymanopt.function import Callable

    n = 100
    d = 20
    # problem Tr(AXBX^T)
    for i in range(1):
        D = randint(1, 10, n) * 0.02 + 1
        OO = random_orthogonal(n)
        A = OO @ np.diag(D) @ OO.T.conj()
        B = make_sym_pos(d)

        alpha = randint(1, 10, 2) * .1
        alpha = alpha / alpha[0]
        print(alpha)
        man = ComplexStiefel(n, d, alpha)
        A2 = A @ A

        @Callable
        def cost(X):
            return rtrace(A @ X @ B @ X.T.conj() @ A2 @ X @ B @ X.T.conj() @ A)

        @Callable
        def egrad(X):
            R = 4 * A2 @ X @ B @ X.T.conj() @ A2 @ X @ B
            return R

        @Callable
        def ehess(X, H):
            return 4*A2 @ H @ B @ X.T.conj() @ A2 @ X @ B +\
                4*A2 @ X @ B @ H.T.conj() @ A2 @ X @ B +\
                4*A2 @ X @ B @ X.T.conj() @ A2 @ H @ B

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

        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=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)
        man1 = ComplexStiefel(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)

        man1 = ComplexStiefel(n, d, alpha=np.array([1, .5]))
        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 = 200
    d = 20
    # problem Tr(AXBX^T)
    for i in range(1):
        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.conj()

        alpha = randint(1, 10, 2)
        alpha = alpha / alpha[0]
        print(alpha)
        man = ComplexStiefel(n, d, alpha)
        cf = 10
        B2 = B @ B

        @Callable
        def cost(X):
            return cf * rtrace(
                B @ X @ X.T.conj() @ B2 @ X @ X.T.conj() @ B) +\
                rtrace(X.T.conj() @ A @ X)

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

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

        if False:
            X = man.rand()
            xi = man.randvec(X)
            d1 = num_deriv(man, X, xi, cost)
            d2 = rtrace(egrad(X) @ xi.T.conj())
            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)
        man1 = ComplexStiefel(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)

        man1 = ComplexStiefel(n, d, alpha=np.array([1, .5]))
        # man1 = ComplexStiefel(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)
         return shannon_rate(L, T)  
     return shannon_capacity_fact_fixed_time
    
 # instantiate manifold for Pymanopt               
 manifold_fact = Euclidean(n,n)
 # instantiate solver for Pymanopt
 solver = TrustRegions()
 
     
 #### find R_max via bisection method ####
 
 # min value T
 T1=1e-8
 shannon_capacity_fact_fixed_time = make_shannon_capacity_fact_fixed_time(T1)
 problem = Problem(manifold=manifold_fact, cost=shannon_capacity_fact_fixed_time, verbosity=0)
 L_opt1 = solver.solve(problem)
 p_1 = -shannon_capacity_fact_fixed_time(L_opt1)
 #print p_1
 
 Sigma_opt1 = np.dot(L_opt1,L_opt1.transpose())
 Sigma_opt_norm1 = Sigma_opt1/(np.trace(Sigma_opt1)) 
 
 eigs, eigvs = np.linalg.eig(Sigma_opt_norm1)
 eff_rank1 = np.square(np.sum(np.real(eigs)))/np.sum(np.square(np.real(eigs)))
 
 # max value T
 T2=10.
 shannon_capacity_fact_fixed_time = make_shannon_capacity_fact_fixed_time(T2)
 problem = Problem(manifold=manifold_fact, cost=shannon_capacity_fact_fixed_time, verbosity=0)
 L_opt2 = solver.solve(problem)
 p_2 = -shannon_capacity_fact_fixed_time(L_opt2)
示例#28
0
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)