[mlpack-git] master: Refactor to access SDPs through LRSDP::SDP(). (also change everything that used direct access through LRSDP.) (e66ba86)
gitdub at big.cc.gt.atl.ga.us
gitdub at big.cc.gt.atl.ga.us
Mon Feb 2 15:17:00 EST 2015
Repository : https://github.com/mlpack/mlpack
On branch : master
Link : https://github.com/mlpack/mlpack/compare/bb6e5c56aab07e6449d86021246b52a9e323f3a0...bd6cb33f8d8270b02a84e81e38727679bb6c319a
>---------------------------------------------------------------
commit e66ba860145b30110f11d7052155d7bfe6eb57d1
Author: Ryan Curtin <ryan at ratml.org>
Date: Mon Feb 2 14:59:16 2015 -0500
Refactor to access SDPs through LRSDP::SDP().
(also change everything that used direct access through LRSDP.)
>---------------------------------------------------------------
e66ba860145b30110f11d7052155d7bfe6eb57d1
src/mlpack/core/optimizers/sdp/lrsdp.hpp | 49 ++++++++--------------
src/mlpack/core/optimizers/sdp/primal_dual.hpp | 14 +++----
.../matrix_completion/matrix_completion.cpp | 10 ++---
src/mlpack/tests/lrsdp_test.cpp | 47 +++++++++++----------
4 files changed, 53 insertions(+), 67 deletions(-)
diff --git a/src/mlpack/core/optimizers/sdp/lrsdp.hpp b/src/mlpack/core/optimizers/sdp/lrsdp.hpp
index 511f635..9efff6e 100644
--- a/src/mlpack/core/optimizers/sdp/lrsdp.hpp
+++ b/src/mlpack/core/optimizers/sdp/lrsdp.hpp
@@ -28,7 +28,8 @@ class LRSDP
/**
* Create an LRSDP to be optimized. The solution will end up being a matrix
* of size (rows) x (rank). To construct each constraint and the objective
- * function, use the functions A(), B(), and C() to set them correctly.
+ * function, use the function SDP() in order to access the SDPType object
+ * associated with this optimizer.
*
* @param numConstraints Number of constraints in the problem.
* @param initialPoint Initial point of the optimization.
@@ -38,6 +39,17 @@ class LRSDP
const arma::mat& initialPoint);
/**
+ * Create an LRSDP object with the given SDP problem to be solved, and the
+ * given initial point. Note that the SDP may be modified later by calling
+ * SDP() to access the object.
+ *
+ * @param sdp SDP to be solved.
+ * @param initialPoint Initial point of the optimization.
+ */
+ LRSDP(const SDPType& sdp,
+ const arma::mat& initialPoint);
+
+ /**
* Optimize the LRSDP and return the final objective value. The given
* coordinates will be modified to contain the final solution.
*
@@ -45,37 +57,10 @@ class LRSDP
*/
double Optimize(arma::mat& coordinates);
- //! Return the objective function matrix (c).
- const typename SDPType::objective_matrix_type& C() const { return function.SDP().C(); }
-
- //! Modify the objective function matrix (c).
- typename SDPType::objective_matrix_type& C() { return function.SDP().C(); }
-
- //! Return the vector of sparse A matrices (which correspond to the sparse
- // constraints).
- const std::vector<arma::sp_mat>& SparseA() const { return function.SDP().SparseA(); }
-
- //! Modify the veector of sparse A matrices (which correspond to the sparse
- // constraints).
- std::vector<arma::sp_mat>& SparseA() { return function.SDP().SparseA(); }
-
- //! Return the vector of dense A matrices (which correspond to the dense
- // constraints).
- const std::vector<arma::mat>& DenseA() const { return function.SDP().DenseA(); }
-
- //! Modify the veector of dense A matrices (which correspond to the dense
- // constraints).
- std::vector<arma::mat>& DenseA() { return function.SDP().DenseA(); }
-
- //! Return the vector of sparse B values.
- const arma::vec& SparseB() const { return function.SDP().SparseB(); }
- //! Modify the vector of sparse B values.
- arma::vec& SparseB() { return function.SDP().SparseB(); }
-
- //! Return the vector of dense B values.
- const arma::vec& DenseB() const { return function.SDP().DenseB(); }
- //! Modify the vector of dense B values.
- arma::vec& DenseB() { return function.SDP().DenseB(); }
+ //! Return the SDP that will be solved.
+ const SDPType& SDP() const { return function.SDP(); }
+ //! Modify the SDP that will be solved.
+ SDPType& SDP() { return function.SDP(); }
//! Return the function to be optimized.
const LRSDPFunction<SDPType>& Function() const { return function; }
diff --git a/src/mlpack/core/optimizers/sdp/primal_dual.hpp b/src/mlpack/core/optimizers/sdp/primal_dual.hpp
index 7af3793..ed2ac9b 100644
--- a/src/mlpack/core/optimizers/sdp/primal_dual.hpp
+++ b/src/mlpack/core/optimizers/sdp/primal_dual.hpp
@@ -18,9 +18,9 @@ namespace optimization {
* @tparam SDPType
*/
template <typename SDPType>
-class PrimalDualSolver {
+class PrimalDualSolver
+{
public:
-
/**
* Construct a new solver instance from a given SDP instance.
* Uses a random, positive initialization point.
@@ -58,7 +58,7 @@ class PrimalDualSolver {
double Optimize(arma::mat& X,
arma::vec& ysparse,
arma::vec& ydense,
- arma::mat &Z);
+ arma::mat& Z);
/**
* Invoke the optimization procedure, and only return the primal variable.
@@ -73,7 +73,7 @@ class PrimalDualSolver {
}
//! Return the underlying SDP instance.
- const SDPType& Sdp() const { return sdp; }
+ const SDPType& SDP() const { return sdp; }
//! Modify tau. Typical values are 0.99.
double& Tau() { return tau; }
@@ -91,8 +91,7 @@ class PrimalDualSolver {
size_t& MaxIterations() { return maxIterations; }
private:
-
- //! The SDP problem instance to optimize
+ //! The SDP problem instance to optimize.
SDPType sdp;
//! Starting point for X. Needs to be positive definite.
@@ -114,7 +113,8 @@ class PrimalDualSolver {
//! The tolerance on the norm of XZ required before terminating.
double normXzTol;
- //! The tolerance required on the primal constraints required before terminating.
+ //! The tolerance required on the primal constraints required before
+ //! terminating.
double primalInfeasTol;
//! The tolerance required on the dual constraint required before terminating.
diff --git a/src/mlpack/methods/matrix_completion/matrix_completion.cpp b/src/mlpack/methods/matrix_completion/matrix_completion.cpp
index 4e19fe7..8994854 100644
--- a/src/mlpack/methods/matrix_completion/matrix_completion.cpp
+++ b/src/mlpack/methods/matrix_completion/matrix_completion.cpp
@@ -68,14 +68,14 @@ void MatrixCompletion::CheckValues()
void MatrixCompletion::InitSDP()
{
- sdp.C().eye(m + n, m + n);
- sdp.SparseB() = 2. * values;
+ sdp.SDP().C().eye(m + n, m + n);
+ sdp.SDP().SparseB() = 2. * values;
const size_t p = indices.n_cols;
for (size_t i = 0; i < p; i++)
{
- sdp.SparseA()[i].zeros(m + n, m + n);
- sdp.SparseA()[i](indices(0, i), m + indices(1, i)) = 1.;
- sdp.SparseA()[i](m + indices(1, i), indices(0, i)) = 1.;
+ sdp.SDP().SparseA()[i].zeros(m + n, m + n);
+ sdp.SDP().SparseA()[i](indices(0, i), m + indices(1, i)) = 1.;
+ sdp.SDP().SparseA()[i](m + indices(1, i), indices(0, i)) = 1.;
}
}
diff --git a/src/mlpack/tests/lrsdp_test.cpp b/src/mlpack/tests/lrsdp_test.cpp
index 6b93fa0..1fe0f77 100644
--- a/src/mlpack/tests/lrsdp_test.cpp
+++ b/src/mlpack/tests/lrsdp_test.cpp
@@ -58,22 +58,22 @@ void SetupLovaszTheta(const arma::mat& edges,
const size_t vertices = max(max(edges)) + 1;
// C = -(e e^T) = -ones().
- lovasz.C().ones(vertices, vertices);
- lovasz.C() *= -1;
+ lovasz.SDP().C().ones(vertices, vertices);
+ lovasz.SDP().C() *= -1;
// b_0 = 1; else = 0.
- lovasz.SparseB().zeros(edges.n_cols + 1);
- lovasz.SparseB()[0] = 1;
+ lovasz.SDP().SparseB().zeros(edges.n_cols + 1);
+ lovasz.SDP().SparseB()[0] = 1;
// A_0 = I_n.
- lovasz.SparseA()[0].eye(vertices, vertices);
+ lovasz.SDP().SparseA()[0].eye(vertices, vertices);
// A_ij only has ones at (i, j) and (j, i) and 0 elsewhere.
for (size_t i = 0; i < edges.n_cols; ++i)
{
- lovasz.SparseA()[i + 1].zeros(vertices, vertices);
- lovasz.SparseA()[i + 1](edges(0, i), edges(1, i)) = 1.;
- lovasz.SparseA()[i + 1](edges(1, i), edges(0, i)) = 1.;
+ lovasz.SDP().SparseA()[i + 1].zeros(vertices, vertices);
+ lovasz.SDP().SparseA()[i + 1](edges(0, i), edges(1, i)) = 1.;
+ lovasz.SDP().SparseA()[i + 1](edges(1, i), edges(0, i)) = 1.;
}
// Set the Lagrange multipliers right.
@@ -163,13 +163,13 @@ BOOST_AUTO_TEST_CASE(ErdosRenyiRandomGraphMaxCutSDP)
}
LRSDP<SDP<arma::sp_mat>> maxcut(laplacian.n_rows, 0, coordinates);
- maxcut.C() = laplacian;
- maxcut.C() *= -1.; // need to minimize the negative
- maxcut.SparseB().ones(laplacian.n_rows);
+ maxcut.SDP().C() = laplacian;
+ maxcut.SDP().C() *= -1.; // need to minimize the negative
+ maxcut.SDP().SparseB().ones(laplacian.n_rows);
for (size_t i = 0; i < laplacian.n_rows; ++i)
{
- maxcut.SparseA()[i].zeros(laplacian.n_rows, laplacian.n_rows);
- maxcut.SparseA()[i](i, i) = 1.;
+ maxcut.SDP().SparseA()[i].zeros(laplacian.n_rows, laplacian.n_rows);
+ maxcut.SDP().SparseA()[i](i, i) = 1.;
}
const double finalValue = maxcut.Optimize(coordinates);
@@ -192,15 +192,16 @@ BOOST_AUTO_TEST_CASE(ErdosRenyiRandomGraphMaxCutSDP)
*
* b_i = dot(A_i, X)
*
- * where the A_i's have iid entries from Normal(0, 1/p). We do this by solving the
- * the following semi-definite program
+ * where the A_i's have iid entries from Normal(0, 1/p). We do this by solving
+ * the the following semi-definite program
*
* min ||X||_* subj to dot(A_i, X) = b_i, i=1,...,p
*
- * where ||X||_* denotes the nuclear norm (sum of singular values) of X. The equivalent
- * SDP is
+ * where ||X||_* denotes the nuclear norm (sum of singular values) of X. The
+ * equivalent SDP is
*
- * min tr(W1) + tr(W2) : [ W1, X ; X', W2 ] is PSD, dot(A_i, X) = b_i, i=1,...,p
+ * min tr(W1) + tr(W2) : [ W1, X ; X', W2 ] is PSD,
+ * dot(A_i, X) = b_i, i = 1, ..., p
*
* For more details on matrix sensing and nuclear norm minimization, see
*
@@ -238,8 +239,8 @@ BOOST_AUTO_TEST_CASE(GaussianMatrixSensingSDP)
coordinates.eye(m + n, ceil(r));
LRSDP<SDP<arma::sp_mat>> sensing(0, p, coordinates);
- sensing.C().eye(m + n, m + n);
- sensing.DenseB() = 2. * b;
+ sensing.SDP().C().eye(m + n, m + n);
+ sensing.SDP().DenseB() = 2. * b;
const auto block_rows = arma::span(0, m - 1);
const auto block_cols = arma::span(m, m + n - 1);
@@ -247,9 +248,9 @@ BOOST_AUTO_TEST_CASE(GaussianMatrixSensingSDP)
for (size_t i = 0; i < p; ++i)
{
const arma::mat Ai = arma::reshape(A.row(i), n, m);
- sensing.DenseA()[i].zeros(m + n, m + n);
- sensing.DenseA()[i](block_rows, block_cols) = trans(Ai);
- sensing.DenseA()[i](block_cols, block_rows) = Ai;
+ sensing.SDP().DenseA()[i].zeros(m + n, m + n);
+ sensing.SDP().DenseA()[i](block_rows, block_cols) = trans(Ai);
+ sensing.SDP().DenseA()[i](block_cols, block_rows) = Ai;
}
double finalValue = sensing.Optimize(coordinates);
More information about the mlpack-git
mailing list