Title: | An R Interface to the 'ROPTLIB' Library for Riemannian Manifold Optimization |
---|---|
Description: | An R interface to version 0.3 of the 'ROPTLIB' optimization library (see <https://www.math.fsu.edu/~whuang2/> for more information). Optimize real- valued functions over manifolds such as Stiefel, Grassmann, and Symmetric Positive Definite matrices. For details see Martin et. al. (2020) <doi:10.18637/jss.v093.i01>. Note that the optional ldr package used in some of this package's examples can be obtained from either JSS <https://www.jstatsoft.org/index.php/jss/article/view/v061i03/2886> or from the CRAN archives <https://cran.r-project.org/src/contrib/Archive/ldr/ldr_1.3.3.tar.gz>. |
Authors: | Kofi P. Adragni [aut, cph], Sean R. Martin [aut, cre, cph], Andrew M. Raim [aut, cph], Wen Huang [aut, cph] |
Maintainer: | Sean R. Martin <[email protected]> |
License: | GPL (>= 2) |
Version: | 1.0.1 |
Built: | 2024-11-26 06:41:27 UTC |
Source: | CRAN |
Internal design of the ManifoldOptim portion of the embedded C++ code. Most ManifoldOptim users should not need this. ROPTLIB source code is also included in this package, but is not described here; see Huang et al (2016a) for documentation on that portion of the code.
src/ManifoldOptim/BrockettProblem.cpp
:The Brockett problem, written as a module that can be invoked from within
the ManifoldOptim package. This serves as an example for package authors
who wish to expose modules to their users. Code to invoke this example from
outside of the ManifoldOptim package is provided in
inst/examples/brockett/cpp_pkg
.
src/ManifoldOptim/ManifoldOptim.cpp
:Contains the main function ManifoldOptim
which takes a problem
constructed in R, sets it up in ROPTLIB, runs it, and returns the result.
src/ManifoldOptim/ManifoldOptimModule.cpp
:Defines an Rcpp module for ManifoldOptim which exposes C++ classes such as
RProblem
. This module provides the most common means in which R users
will interact with ManifoldOptim.
src/ManifoldOptim/ManifoldFactory.h
:The GetManifold
function constructs a Manifold object based on its
name and dimensions. Manifold classes are defined in ROPTLIB.
src/ManifoldOptim/ProblemAdapter.h
:Defines the ProblemAdapter
class, which takes a
ManifoldOptimProblem
, which is defined in the ManifoldOptim
API, and plugs it into the ROPTLIB API as an ROPTLIB Problem
subclass.
src/ManifoldOptim/RProblem.h
:Defines the RProblem
class, which allows the objective, gradient,
and Hessian functions to be defined in R. When a function in the ROPTLIB
library invokes the objective, gradient, or Hessian, this class invokes
the appropriate function in R.
src/ManifoldOptim/SolverFactory.h
:The GetSolver
function constructs a Solver object based on its name,
a given Problem
, an initial value, and an initial Hessian. Solver
classes are defined in ROPTLIB.
src/ManifoldOptim/Util.h
:Defines a few utility functions, especially to assist in translating between the ManifoldOptim C++ API and the ROPTLIB API.
src/ManifoldOptim/VariableFactory.h
:The GetVariable
function returns an optimization variable suitable
for a given Manifold, based on its name and dimension. Optimization
variables for supported Manifolds are defined in ROPTLIB.
inst/include/ManifoldOptimException.h
:Defines ManifoldOptimException
, which is a subclass of STL
exception
.
inst/include/ManifoldOptim.h
:For users of the ManifoldOptim C++ API, this is the main header file to
include. For an example, see inst/examples/brockett/cpp_sourceCpp/
.
inst/include/ManifoldOptimProblem.h
:Defines ManifoldOptimProblem
, which is the base class
for all optimization problems in the ManifoldOptim API. This class
facilitates writing problems with Armadillo, which can be
instantiated and manipulated in R, and solved through ROPTLIB.
This class assumes only that the optimization variable is a
one-dimensional vector; the user must reshape it into the appropriate
form (e.g. a matrix or list of matrices) when evaluating the objective,
gradient, and Hessian functions.
Wen Huang, P.A. Absil, K.A. Gallivan, Paul Hand (2016a). "ROPTLIB: an object-oriented C++ library for optimization on Riemannian manifolds." Technical Report FSU16-14, Florida State University.
Conrad Sanderson and Ryan Curtin. Armadillo: a template-based C++ library for linear algebra. Journal of Open Source Software, Vol. 1, pp. 26, 2016.
S. Martin, A. Raim, W. Huang, and K. Adragni (2020). "ManifoldOptim: An R Interface to the ROPTLIB Library for Riemannian Manifold Optimization." Journal of Statistical Software, 93(1):1-32.
Get parameters to initialize numerical differentiation
get.deriv.params(EpsNumericalGrad = 1e-06, EpsNumericalHessEta = 1e-04)
get.deriv.params(EpsNumericalGrad = 1e-06, EpsNumericalHessEta = 1e-04)
EpsNumericalGrad |
The "epsilon" used to perturb the objective functon when computing numerical gradients |
EpsNumericalHessEta |
The "epsilon" used to perturb the objective functon when computing numerical HessEta |
List containing input arguments for numerical differentiation
Get parameters to initialize manifold
get.manifold.params(IsCheckParams = FALSE)
get.manifold.params(IsCheckParams = FALSE)
IsCheckParams |
Should internal manifold object check inputs and print summary message before optimization (TRUE or FALSE) |
List containing input arguments for manifold
Get parameters to initialize solver
get.solver.params( isconvex = FALSE, DEBUG = 0, Tolerance = 1e-04, Max_Iteration = 1000, IsCheckParams = FALSE, IsCheckGradHess = FALSE, ... )
get.solver.params( isconvex = FALSE, DEBUG = 0, Tolerance = 1e-04, Max_Iteration = 1000, IsCheckParams = FALSE, IsCheckGradHess = FALSE, ... )
isconvex |
Indicator for whether the function is convex (TRUE or FALSE) |
DEBUG |
Verbosity level in {0,1,2,3}. Use 0 for quietest with no messages printed. Use 3 for most verbose, |
Tolerance |
Tolerance used to assess convergence. See Huang et al (2016b) for details on how this is used, |
Max_Iteration |
Maximum iterations to be used by the solver (a non-negative integer), |
IsCheckParams |
Should solver check inputs and print summary message before optimization (TRUE or FALSE), |
IsCheckGradHess |
Check correctness of the gradient and Hessian functions (TRUE or FALSE). |
... |
Additional arguments to pass to the solver. These are not
validated by the |
Solver-specific parameters may also be added to the object returned
from get.solver.params
, via standard list manipulation. Interested
users should refer to Huang et al (2016b) for available options.
List containing input arguments for solver
Wen Huang, P.A. Absil, K.A. Gallivan, Paul Hand (2016a). "ROPTLIB: an object-oriented C++ library for optimization on Riemannian manifolds." Technical Report FSU16-14, Florida State University.
Wen Huang, Kyle A. Gallivan, and P.A. Absil (2016b). Riemannian Manifold Optimization Library. URL https://www.math.fsu.edu/~whuang2/pdf/USER_MANUAL_for_2016-04-29.pdf
S. Martin, A. Raim, W. Huang, and K. Adragni (2020). "ManifoldOptim: An R Interface to the ROPTLIB Library for Riemannian Manifold Optimization." Journal of Statistical Software, 93(1):1-32.
Get definitions for simple manifolds
get.stiefel.defn(n, p, numofmani = 1L, ParamSet = 1L) get.grassmann.defn(n, p, numofmani = 1L, ParamSet = 1L) get.spd.defn(n, numofmani = 1L, ParamSet = 1L) get.sphere.defn(n, numofmani = 1L, ParamSet = 1L) get.euclidean.defn(n, m, numofmani = 1L, ParamSet = 1L) get.lowrank.defn(n, m, p, numofmani = 1L, ParamSet = 1L) get.orthgroup.defn(n, numofmani = 1L, ParamSet = 1L)
get.stiefel.defn(n, p, numofmani = 1L, ParamSet = 1L) get.grassmann.defn(n, p, numofmani = 1L, ParamSet = 1L) get.spd.defn(n, numofmani = 1L, ParamSet = 1L) get.sphere.defn(n, numofmani = 1L, ParamSet = 1L) get.euclidean.defn(n, m, numofmani = 1L, ParamSet = 1L) get.lowrank.defn(n, m, p, numofmani = 1L, ParamSet = 1L) get.orthgroup.defn(n, numofmani = 1L, ParamSet = 1L)
n |
Dimension for manifold object (see Details) |
p |
Dimension for manifold object (see Details) |
numofmani |
Multiplicity of this space. For example, use
|
ParamSet |
A positive integer indicating a set of properties for the manifold which can be used by the solver. See Huang et al (2016b) for details. |
m |
Dimension for manifold object (see Details) |
The functions define manifolds as follows:
get.stiefel.defn
: Stiefel manifold
get.grassmann.defn
: Grassmann manifold of -dimensional
subspaces in
get.spd.defn
: Manifold of symmetric positive
definite matrices
get.sphere.defn
: Manifold of -dimensional vectors on
the unit sphere
get.euclidean.defn
: Euclidean space
get.lowrank.defn
: Low-rank manifold
get.orthgroup.defn
: Orthonormal group
List containing input arguments and name field denoting the type of manifold
Wen Huang, P.A. Absil, K.A. Gallivan, Paul Hand (2016a). "ROPTLIB: an object-oriented C++ library for optimization on Riemannian manifolds." Technical Report FSU16-14, Florida State University.
Wen Huang, Kyle A. Gallivan, and P.A. Absil (2016b). Riemannian Manifold Optimization Library. URL https://www.math.fsu.edu/~whuang2/pdf/USER_MANUAL_for_2016-04-29.pdf
S. Martin, A. Raim, W. Huang, and K. Adragni (2020). "ManifoldOptim: An R Interface to the ROPTLIB Library for Riemannian Manifold Optimization." Journal of Statistical Software, 93(1):1-32.
Optimize a function on a manifold.
manifold.optim( prob, mani.defn, method = "LRBFGS", mani.params = get.manifold.params(), solver.params = get.solver.params(), deriv.params = get.deriv.params(), x0 = NULL, H0 = NULL, has.hhr = FALSE ) moptim( prob, mani.defn, method = "LRBFGS", mani.params = get.manifold.params(), solver.params = get.solver.params(), deriv.params = get.deriv.params(), x0 = NULL, H0 = NULL, has.hhr = FALSE )
manifold.optim( prob, mani.defn, method = "LRBFGS", mani.params = get.manifold.params(), solver.params = get.solver.params(), deriv.params = get.deriv.params(), x0 = NULL, H0 = NULL, has.hhr = FALSE ) moptim( prob, mani.defn, method = "LRBFGS", mani.params = get.manifold.params(), solver.params = get.solver.params(), deriv.params = get.deriv.params(), x0 = NULL, H0 = NULL, has.hhr = FALSE )
prob |
|
mani.defn |
Either a Product manifold definition or one of the Manifold definitions |
method |
Name of optimization method. Currently supported methods are:
See Huang et al (2016a, 2016b) for details. |
mani.params |
Arguments to configure the manifold. Construct with get.manifold.params |
solver.params |
Arguments to configure the solver. Construct with get.solver.params |
deriv.params |
Arguments to configure numerical differentiation for gradient and Hessian, which are used if those functions are not specified. Construct with get.deriv.params |
x0 |
Starting point for optimization. A numeric vector whose dimension matches the total dimension of the overall problem |
H0 |
Initial value of Hessian. A |
has.hhr |
Indicates whether to apply the idea in Huang et al (2015) section 4.1 (TRUE or FALSE) |
moptim
is an alias for manifold.optim
.
xopt |
Point returned by the solver |
fval |
Value of the function evaluated at |
normgf |
Norm of the final gradient |
normgfgf0 |
Norm of the gradient at final iterate divided by norm of the gradient at initiate iterate |
iter |
Number of iterations taken by the solver |
num.obj.eval |
Number of function evaluations |
num.grad.eval |
Number of gradient evaluations |
nR |
Number of retraction evaluations |
nV |
Number of occasions in which vector transport is first computed |
nVp |
Number of remaining computations of vector transport (excluding count in nV) |
nH |
Number of actions of Hessian |
elapsed |
Elapsed time for the solver (in seconds) |
Wen Huang, P.A. Absil, K.A. Gallivan, Paul Hand (2016a). "ROPTLIB: an object-oriented C++ library for optimization on Riemannian manifolds." Technical Report FSU16-14, Florida State University.
Wen Huang, Kyle A. Gallivan, and P.A. Absil (2016b). Riemannian Manifold Optimization Library. URL https://www.math.fsu.edu/~whuang2/pdf/USER_MANUAL_for_2016-04-29.pdf
Wen Huang, K.A. Gallivan, and P.A. Absil (2015). A Broyden Class of Quasi-Newton Methods for Riemannian Optimization. SIAM Journal on Optimization, 25(3):1660-1685.
S. Martin, A. Raim, W. Huang, and K. Adragni (2020). "ManifoldOptim: An R Interface to the ROPTLIB Library for Riemannian Manifold Optimization." Journal of Statistical Software, 93(1):1-32.
## Not run: # ----- Example with objective and gradient written in R ----- set.seed(1234) p <- 5; n <- 150 B <- matrix(rnorm(n*n), nrow=n) B <- B + t(B) D <- diag(p:1, p) tx <- function(x) { matrix(x, n, p) } f <- function(x) { X <- tx(x); Trace( t(X) %*% B %*% X %*% D ) } g <- function(x) { X <- tx(x); 2 * B %*% X %*% D } mod <- Module("ManifoldOptim_module", PACKAGE = "ManifoldOptim") prob <- new(mod$RProblem, f, g) x0 <- as.numeric(orthonorm(matrix(rnorm(n*p), nrow=n, ncol=p))) mani.params <- get.manifold.params(IsCheckParams = TRUE) solver.params <- get.solver.params(IsCheckParams = TRUE) mani.defn <- get.stiefel.defn(n, p) res <- manifold.optim(prob, mani.defn, method = "RTRSR1", mani.params = mani.params, solver.params = solver.params, x0 = x0) print(res) head(tx(res$xopt)) ## End(Not run) ## Not run: library(ManifoldOptim) library(RcppArmadillo) # ----- Example with objective and gradient written in C++ ----- set.seed(1234) p <- 5; n <- 150 B <- matrix(rnorm(n*n), nrow=n) B <- B + t(B) # force symmetric D <- diag(p:1, p) # The Problem class is written in C++. Get a handle to it and set it up from R Rcpp::sourceCpp(code = ' //[[Rcpp::depends(RcppArmadillo,ManifoldOptim)]] #include <RcppArmadillo.h> #include <ManifoldOptim.h> using namespace Rcpp; using namespace arma; class BrockettProblem : public MatrixManifoldOptimProblem { public: BrockettProblem(const arma::mat& B, const arma::mat& D) : MatrixManifoldOptimProblem(false, true), m_B(B), m_D(D) { } virtual ~BrockettProblem() { } double objFun(const arma::mat& X) const { return arma::trace(X.t() * m_B * X * m_D); } arma::mat gradFun(const arma::mat& X) const { return 2 * m_B * X * m_D; } const arma::mat& GetB() const { return m_B; } const arma::mat& GetD() const { return m_D; } private: arma::mat m_B; arma::mat m_D; }; RCPP_MODULE(Brockett_module) { class_<BrockettProblem>("BrockettProblem") .constructor<mat,mat>() .method("objFun", &BrockettProblem::objFun) .method("gradFun", &BrockettProblem::gradFun) .method("GetB", &BrockettProblem::GetB) .method("GetD", &BrockettProblem::GetD) ; } ') prob <- new(BrockettProblem, B, D) X0 <- orthonorm(matrix(rnorm(n*p), nrow=n, ncol=p)) x0 <- as.numeric(X0) tx <- function(x) { matrix(x, n, p) } mani.params <- get.manifold.params(IsCheckParams = TRUE) solver.params <- get.solver.params(DEBUG = 0, Tolerance = 1e-4, Max_Iteration = 1000, IsCheckParams = TRUE, IsCheckGradHess = FALSE) mani.defn <- get.stiefel.defn(n, p) res <- manifold.optim(prob, mani.defn, method = "RTRSR1", mani.params = mani.params, solver.params = solver.params, x0 = x0) print(res) head(tx(res$xopt)) ## End(Not run)
## Not run: # ----- Example with objective and gradient written in R ----- set.seed(1234) p <- 5; n <- 150 B <- matrix(rnorm(n*n), nrow=n) B <- B + t(B) D <- diag(p:1, p) tx <- function(x) { matrix(x, n, p) } f <- function(x) { X <- tx(x); Trace( t(X) %*% B %*% X %*% D ) } g <- function(x) { X <- tx(x); 2 * B %*% X %*% D } mod <- Module("ManifoldOptim_module", PACKAGE = "ManifoldOptim") prob <- new(mod$RProblem, f, g) x0 <- as.numeric(orthonorm(matrix(rnorm(n*p), nrow=n, ncol=p))) mani.params <- get.manifold.params(IsCheckParams = TRUE) solver.params <- get.solver.params(IsCheckParams = TRUE) mani.defn <- get.stiefel.defn(n, p) res <- manifold.optim(prob, mani.defn, method = "RTRSR1", mani.params = mani.params, solver.params = solver.params, x0 = x0) print(res) head(tx(res$xopt)) ## End(Not run) ## Not run: library(ManifoldOptim) library(RcppArmadillo) # ----- Example with objective and gradient written in C++ ----- set.seed(1234) p <- 5; n <- 150 B <- matrix(rnorm(n*n), nrow=n) B <- B + t(B) # force symmetric D <- diag(p:1, p) # The Problem class is written in C++. Get a handle to it and set it up from R Rcpp::sourceCpp(code = ' //[[Rcpp::depends(RcppArmadillo,ManifoldOptim)]] #include <RcppArmadillo.h> #include <ManifoldOptim.h> using namespace Rcpp; using namespace arma; class BrockettProblem : public MatrixManifoldOptimProblem { public: BrockettProblem(const arma::mat& B, const arma::mat& D) : MatrixManifoldOptimProblem(false, true), m_B(B), m_D(D) { } virtual ~BrockettProblem() { } double objFun(const arma::mat& X) const { return arma::trace(X.t() * m_B * X * m_D); } arma::mat gradFun(const arma::mat& X) const { return 2 * m_B * X * m_D; } const arma::mat& GetB() const { return m_B; } const arma::mat& GetD() const { return m_D; } private: arma::mat m_B; arma::mat m_D; }; RCPP_MODULE(Brockett_module) { class_<BrockettProblem>("BrockettProblem") .constructor<mat,mat>() .method("objFun", &BrockettProblem::objFun) .method("gradFun", &BrockettProblem::gradFun) .method("GetB", &BrockettProblem::GetB) .method("GetD", &BrockettProblem::GetD) ; } ') prob <- new(BrockettProblem, B, D) X0 <- orthonorm(matrix(rnorm(n*p), nrow=n, ncol=p)) x0 <- as.numeric(X0) tx <- function(x) { matrix(x, n, p) } mani.params <- get.manifold.params(IsCheckParams = TRUE) solver.params <- get.solver.params(DEBUG = 0, Tolerance = 1e-4, Max_Iteration = 1000, IsCheckParams = TRUE, IsCheckGradHess = FALSE) mani.defn <- get.stiefel.defn(n, p) res <- manifold.optim(prob, mani.defn, method = "RTRSR1", mani.params = mani.params, solver.params = solver.params, x0 = x0) print(res) head(tx(res$xopt)) ## End(Not run)
Orthonormalize the columns of a matrix
orthonorm(u)
orthonorm(u)
u |
A matrix |
manifold.optim
resultsPrint results
## S3 method for class 'ManifoldOptim' print(x, ...)
## S3 method for class 'ManifoldOptim' print(x, ...)
x |
A |
... |
Not currently used |
Define a problem for ManifoldOptim to solve.
A problem definition contains an objective function and a gradient
function
. The gradient
is computed as if
is defined
on a Euclidean space. If
is not specified it will be computed
numerically, which is potentially much slower.
The easiest way to define a problem is completely in R. Example 1
below illustrates how to construct a problem using a given and
. Example 2 constructs the same problem without providing
.
The
Rcpp Module
framework (Eddelbuettel, 2013) creates underlying
C++ objects necessary to invoke the ROPTLIB
library.
The performance of solving an RProblem
may be too slow for some
applications; here, the C++ optimizer calls R functions,
which requires some overhead. A faster alternative is to code your problem
in C++ directly, and allow it to be manipulated in R. An
example is provided in this package, under
tests/brockett/cpp_standalone/
. Example 3 below shows how to
instantiate this problem.
Package authors may want to use ManifoldOptim
within a package to solve
a problem written in C++. In this case, the author would probably
not want to use sourceCpp
, but instead have the problem compiled
when the package was installed. An example is provided within this package;
tests/brockett/cpp_pkg/driver.R
instantiates the problem defined in:
src/ManifoldOptim/BrockettProblem.cpp
.
Dirk Eddelbuettel. Seamless R and C++ Integration with Rcpp, Chapter 7: Modules, pages 83-102. Springer New York, New York, NY, 2013.
Wen Huang, P.A. Absil, K.A. Gallivan, Paul Hand (2016a). "ROPTLIB: an object-oriented C++ library for optimization on Riemannian manifolds." Technical Report FSU16-14, Florida State University.
S. Martin, A. Raim, W. Huang, and K. Adragni (2020). "ManifoldOptim: An R Interface to the ROPTLIB Library for Riemannian Manifold Optimization." Journal of Statistical Software, 93(1):1-32.
## Not run: # --- Example 1: Define a problem in R --- f <- function(x) { ... } g <- function(x) { ... } mod <- Module("ManifoldOptim_module", PACKAGE = "ManifoldOptim") prob <- new(mod$RProblem, f, g) # --- Example 2: Define a problem in R without specifying gradient --- f <- function(x) { ... } mod <- Module("ManifoldOptim_module", PACKAGE = "ManifoldOptim") prob <- new(mod$RProblem, f) # --- Example 3: Instantiate a problem written in C++ --- p <- 5; n <- 150 B <- matrix(rnorm(n*n), nrow=n) B <- B + t(B) # force symmetric D <- diag(p:1, p) Rcpp::sourceCpp("brockett_problem.cpp") prob <- new(BrockettProblem, B, D) ## End(Not run)
## Not run: # --- Example 1: Define a problem in R --- f <- function(x) { ... } g <- function(x) { ... } mod <- Module("ManifoldOptim_module", PACKAGE = "ManifoldOptim") prob <- new(mod$RProblem, f, g) # --- Example 2: Define a problem in R without specifying gradient --- f <- function(x) { ... } mod <- Module("ManifoldOptim_module", PACKAGE = "ManifoldOptim") prob <- new(mod$RProblem, f) # --- Example 3: Instantiate a problem written in C++ --- p <- 5; n <- 150 B <- matrix(rnorm(n*n), nrow=n) B <- B + t(B) # force symmetric D <- diag(p:1, p) Rcpp::sourceCpp("brockett_problem.cpp") prob <- new(BrockettProblem, B, D) ## End(Not run)
Define a product manifold composed of simpler manifolds
get.product.defn(...)
get.product.defn(...)
... |
One or more simpler Manifold definitions |
List containing manifold definitions for the product manifold
mani.defn1 <- get.product.defn(get.sphere.defn(n=5), get.spd.defn(n=5)) mani.defn2 <- get.product.defn( get.stiefel.defn(n=10, p=5), get.stiefel.defn(n=7, p=3), get.grassmann.defn(n=10, p=5) ) ## Not run: # --- Estimate jointly: Sigma in SPD manifold and mu in sphere manifold --- library(mvtnorm) n <- 400 p <- 3 mu.true <- rep(1/sqrt(p), p) Sigma.true <- diag(2,p) + 0.1 y <- rmvnorm(n, mean = mu.true, sigma = Sigma.true) tx <- function(x) { idx.mu <- 1:p idx.S <- 1:p^2 + p mu <- x[idx.mu] S <- matrix(x[idx.S], p, p) list(mu = mu, Sigma = S) } f <- function(x) { par <- tx(x) -sum(dmvnorm(y, mean = par$mu, sigma = par$Sigma, log = TRUE)) } mod <- Module("ManifoldOptim_module", PACKAGE = "ManifoldOptim") prob <- new(mod$RProblem, f) mu0 <- diag(1, p)[,1] Sigma0 <- diag(1, p) x0 <- c(mu0, as.numeric(Sigma0)) mani.defn <- get.product.defn(get.sphere.defn(p), get.spd.defn(p)) mani.params <- get.manifold.params() solver.params <- get.solver.params(isconvex = TRUE) res <- manifold.optim(prob, mani.defn, method = "LRBFGS", mani.params = mani.params, solver.params = solver.params, x0 = x0) ## End(Not run)
mani.defn1 <- get.product.defn(get.sphere.defn(n=5), get.spd.defn(n=5)) mani.defn2 <- get.product.defn( get.stiefel.defn(n=10, p=5), get.stiefel.defn(n=7, p=3), get.grassmann.defn(n=10, p=5) ) ## Not run: # --- Estimate jointly: Sigma in SPD manifold and mu in sphere manifold --- library(mvtnorm) n <- 400 p <- 3 mu.true <- rep(1/sqrt(p), p) Sigma.true <- diag(2,p) + 0.1 y <- rmvnorm(n, mean = mu.true, sigma = Sigma.true) tx <- function(x) { idx.mu <- 1:p idx.S <- 1:p^2 + p mu <- x[idx.mu] S <- matrix(x[idx.S], p, p) list(mu = mu, Sigma = S) } f <- function(x) { par <- tx(x) -sum(dmvnorm(y, mean = par$mu, sigma = par$Sigma, log = TRUE)) } mod <- Module("ManifoldOptim_module", PACKAGE = "ManifoldOptim") prob <- new(mod$RProblem, f) mu0 <- diag(1, p)[,1] Sigma0 <- diag(1, p) x0 <- c(mu0, as.numeric(Sigma0)) mani.defn <- get.product.defn(get.sphere.defn(p), get.spd.defn(p)) mani.params <- get.manifold.params() solver.params <- get.solver.params(isconvex = TRUE) res <- manifold.optim(prob, mani.defn, method = "LRBFGS", mani.params = mani.params, solver.params = solver.params, x0 = x0) ## End(Not run)
Compute the trace of a square matrix
Trace(X)
Trace(X)
X |
A matrix |