[mlpack-git] master: Refactor to access SDPs through LRSDP::SDP(). (also change everything that used direct access through LRSDP.) (07b0cbc)

gitdub at big.cc.gt.atl.ga.us gitdub at big.cc.gt.atl.ga.us
Thu Mar 5 22:15:07 EST 2015


Repository : https://github.com/mlpack/mlpack

On branch  : master
Link       : https://github.com/mlpack/mlpack/compare/904762495c039e345beba14c1142fd719b3bd50e...f94823c800ad6f7266995c700b1b630d5ffdcf40

>---------------------------------------------------------------

commit 07b0cbc1f443bf5e3e831eb1c8582897c2bfb713
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.)


>---------------------------------------------------------------

07b0cbc1f443bf5e3e831eb1c8582897c2bfb713
 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