[mlpack-svn] r13900 - in mlpack/trunk/src/mlpack/bindings/matlab: . kernel_pca lars nca nmf pca

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Tue Nov 20 15:07:17 EST 2012


Author: pmason8
Date: 2012-11-20 15:07:16 -0500 (Tue, 20 Nov 2012)
New Revision: 13900

Added:
   mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/
   mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/CMakeLists.txt
   mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/Makefile
   mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/kernel_pca.cpp
   mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/kernel_pca.m
   mlpack/trunk/src/mlpack/bindings/matlab/lars/
   mlpack/trunk/src/mlpack/bindings/matlab/lars/CMakeLists.txt
   mlpack/trunk/src/mlpack/bindings/matlab/lars/Makefile
   mlpack/trunk/src/mlpack/bindings/matlab/lars/lars.cpp
   mlpack/trunk/src/mlpack/bindings/matlab/lars/lars.m
   mlpack/trunk/src/mlpack/bindings/matlab/nca/
   mlpack/trunk/src/mlpack/bindings/matlab/nca/CMakeLists.txt
   mlpack/trunk/src/mlpack/bindings/matlab/nca/Makefile
   mlpack/trunk/src/mlpack/bindings/matlab/nca/nca.cpp
   mlpack/trunk/src/mlpack/bindings/matlab/nca/nca.m
   mlpack/trunk/src/mlpack/bindings/matlab/nmf/
   mlpack/trunk/src/mlpack/bindings/matlab/nmf/CMakeLists.txt
   mlpack/trunk/src/mlpack/bindings/matlab/nmf/Makefile
   mlpack/trunk/src/mlpack/bindings/matlab/nmf/nmf.cpp
   mlpack/trunk/src/mlpack/bindings/matlab/nmf/nmf.m
   mlpack/trunk/src/mlpack/bindings/matlab/pca/
   mlpack/trunk/src/mlpack/bindings/matlab/pca/CMakeLists.txt
   mlpack/trunk/src/mlpack/bindings/matlab/pca/Makefile
   mlpack/trunk/src/mlpack/bindings/matlab/pca/pca.cpp
   mlpack/trunk/src/mlpack/bindings/matlab/pca/pca.m
Modified:
   mlpack/trunk/src/mlpack/bindings/matlab/CMakeLists.txt
Log:
lars, nca, nmf, pca, kernel_pca

Modified: mlpack/trunk/src/mlpack/bindings/matlab/CMakeLists.txt
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/CMakeLists.txt	2012-11-19 21:52:44 UTC (rev 13899)
+++ mlpack/trunk/src/mlpack/bindings/matlab/CMakeLists.txt	2012-11-20 20:07:16 UTC (rev 13900)
@@ -130,6 +130,11 @@
 add_subdirectory(kmeans)
 add_subdirectory(range_search)
 add_subdirectory(gmm)
+add_subdirectory(pca)
+add_subdirectory(kernel_pca)
+add_subdirectory(lars)
+add_subdirectory(nca)
+add_subdirectory(nmf)
 
 # Create a target whose sole purpose is to modify the pathdef.m MATLAB file so
 # that the MLPACK toolbox is added to the MATLAB default path.

Added: mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/CMakeLists.txt
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/CMakeLists.txt	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/CMakeLists.txt	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,19 @@
+# Simple rules for building mex file.  The _mex suffix is necessary to avoid
+# target name conflicts, and the mex file must have a different name than the .m
+# file.
+add_library(kernel_pca_mex SHARED
+  kernel_pca.cpp
+)
+target_link_libraries(kernel_pca_mex
+  mlpack
+  ${LIBXML2_LIBRARIES}
+)
+
+# Installation rule.  Install both the mex and the MATLAB file.
+install(TARGETS kernel_pca_mex
+  LIBRARY DESTINATION "${MATLAB_TOOLBOX_DIR}/mlpack/"
+)
+install(FILES
+  kernel_pca.m
+  DESTINATION "${MATLAB_TOOLBOX_DIR}/mlpack/"
+)

Added: mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/Makefile
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/Makefile	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/Makefile	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,22 @@
+kernel_pca: kernel_pca.o
+	g++ -O -pthread -shared  \
+-Wl,--version-script,/opt/matlab/2010b/extern/lib/glnxa64/mexFunction.map \
+-Wl,--no-undefined -o 'mex_kernel_pca.mexa64' kernel_pca.o \
+-L../../build/lib -lmlpack \
+-Wl,-rpath-link,/opt/matlab/2010b/bin/glnxa64 \
+-L/opt/matlab/2010b/bin/glnxa64 -lmx -lmex -lmat -lm -lmwlapack \
+-Wl,-rpath=/net/hu19/pmason8/mlpack/trunk/build/lib \
+-L/usr/lib64 -larmadillo \
+
+kernel_pca.o:
+	g++ -c  \
+-I../../build/include \
+-I../../build/include/mlpack/methods/kernel_pca \
+-I/usr/include/libxml2 \
+-I/opt/matlab/2010b/extern/include \
+-DMATLAB_MEX_FILE \
+-ansi -D_GNU_SOURCE -fPIC -fno-omit-frame-pointer -pthread \
+-DMX_COMPAT_32 -O -DNDEBUG 'kernel_pca.cpp'
+
+clean:
+	rm -f *.o *.mexa64

Added: mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/kernel_pca.cpp
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/kernel_pca.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/kernel_pca.cpp	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,136 @@
+#include "mex.h"
+
+#include <mlpack/core.hpp>
+#include <mlpack/core/kernels/linear_kernel.hpp>
+#include <mlpack/core/kernels/gaussian_kernel.hpp>
+#include <mlpack/core/kernels/hyperbolic_tangent_kernel.hpp>
+#include <mlpack/core/kernels/laplacian_kernel.hpp>
+#include <mlpack/core/kernels/polynomial_kernel.hpp>
+#include <mlpack/core/kernels/cosine_distance.hpp>
+
+#include "kernel_pca.hpp"
+
+using namespace mlpack;
+using namespace mlpack::kpca;
+using namespace mlpack::kernel;
+using namespace std;
+using namespace arma;
+
+void mexFunction(int nlhs, mxArray *plhs[],
+                 int nrhs, const mxArray *prhs[])
+{
+  // argument checks
+  if (nrhs != 8) 
+  {
+    mexErrMsgTxt("Expecting eight arguments.");
+  }
+
+  if (nlhs != 1) 
+  {
+    mexErrMsgTxt("Output required.");
+  }
+
+  // Load input dataset.
+	if (mxDOUBLE_CLASS != mxGetClassID(prhs[0]))
+		mexErrMsgTxt("Input dataset must have type mxDOUBLE_CLASS.");
+
+  mat dataset(mxGetM(prhs[0]), mxGetN(prhs[0]));
+	double * values = mxGetPr(prhs[0]);
+	for (int i=0, num=mxGetNumberOfElements(prhs[0]); i<num; ++i)
+		dataset(i) = values[i];
+	
+  // Get the new dimensionality, if it is necessary.
+  size_t newDim = dataset.n_rows;
+	const int argNewDim = (int) mxGetScalar(prhs[2]);
+  if (argNewDim != 0)
+  {
+    newDim = argNewDim;
+
+    if (newDim > dataset.n_rows)
+    {
+			stringstream ss;
+      ss << "New dimensionality (" << newDim
+          << ") cannot be greater than existing dimensionality ("
+          << dataset.n_rows << ")!";
+			mexErrMsgTxt(ss.str().c_str());
+    }
+  }
+
+  // Get the kernel type and make sure it is valid.
+	if (mxCHAR_CLASS != mxGetClassID(prhs[1]))
+	{
+		mexErrMsgTxt("Kernel input must have type mxCHAR_CLASS.");
+	}
+	int bufLength = mxGetNumberOfElements(prhs[1]) + 1;
+	char * buf;
+	buf = (char *) mxCalloc(bufLength, sizeof(char));
+  mxGetString(prhs[1], buf, bufLength);
+	string kernelType(buf);
+	mxFree(buf);
+
+	// scale parameter
+	const bool scaleData = (mxGetScalar(prhs[3]) == 1.0);
+
+  if (kernelType == "linear")
+  {
+    KernelPCA<LinearKernel> kpca(LinearKernel(), scaleData);
+    kpca.Apply(dataset, newDim);
+  }
+  else if (kernelType == "gaussian")
+  {
+		const double bandwidth = mxGetScalar(prhs[3]);
+
+    GaussianKernel kernel(bandwidth);
+    KernelPCA<GaussianKernel> kpca(kernel, scaleData);
+    kpca.Apply(dataset, newDim);
+  }
+  else if (kernelType == "polynomial")
+  {
+		const double degree = mxGetScalar(prhs[4]);
+		const double offset = mxGetScalar(prhs[5]);
+
+    PolynomialKernel kernel(offset, degree);
+    KernelPCA<PolynomialKernel> kpca(kernel, scaleData);
+    kpca.Apply(dataset, newDim);
+  }
+  else if (kernelType == "hyptan")
+  {
+	  const double scale = mxGetScalar(prhs[6]);
+		const double offset = mxGetScalar(prhs[5]);
+
+    HyperbolicTangentKernel kernel(scale, offset);
+    KernelPCA<HyperbolicTangentKernel> kpca(kernel, scaleData);
+    kpca.Apply(dataset, newDim);
+  }
+  else if (kernelType == "laplacian")
+  {
+		const double bandwidth = mxGetScalar(prhs[7]);
+
+    LaplacianKernel kernel(bandwidth);
+    KernelPCA<LaplacianKernel> kpca(kernel, scaleData);
+    kpca.Apply(dataset, newDim);
+  }
+  else if (kernelType == "cosine")
+  {
+    KernelPCA<CosineDistance> kpca(CosineDistance(), scaleData);
+    kpca.Apply(dataset, newDim);
+  }
+  else
+  {
+    // Invalid kernel type.
+		stringstream ss;
+    ss << "Invalid kernel type ('" << kernelType << "'); valid choices "
+        << "are 'linear', 'gaussian', 'polynomial', 'hyptan', 'laplacian', and "
+        << "'cosine'.";
+		mexErrMsgTxt(ss.str().c_str());
+  }
+
+  // Now returning results to matlab
+	plhs[0] = mxCreateDoubleMatrix(dataset.n_rows, dataset.n_cols, mxREAL);
+	values = mxGetPr(plhs[0]);
+	for (int i = 0; i < dataset.n_rows * dataset.n_cols; ++i)
+	{
+		values[i] = dataset(i);
+	}
+
+}

Added: mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/kernel_pca.m
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/kernel_pca.m	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/kernel_pca/kernel_pca.m	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,71 @@
+function result = kernel_pca(dataPoints, kernel, varargin)
+%Kernel Principal Components Analysis
+%
+%  This program performs Kernel Principal Components Analysis (KPCA) on the
+%  specified dataset with the specified kernel.  This will transform the data
+%  onto the kernel principal components, and optionally reduce the dimensionality
+%  by ignoring the kernel principal components with the smallest eigenvalues.
+%  
+%  For the case where a linear kernel is used, this reduces to regular PCA.
+%  
+%  The kernels that are supported are listed below:
+%  
+%   * 'linear': the standard linear dot product (same as normal PCA):
+%      K(x, y) = x^T y
+%  
+%   * 'gaussian': a Gaussian kernel; requires bandwidth:
+%      K(x, y) = exp(-(|| x - y || ^ 2) / (2 * (bandwidth ^ 2)))
+%  
+%   * 'polynomial': polynomial kernel; requires offset and degree:
+%      K(x, y) = (x^T y + offset) ^ degree
+%  
+%   * 'hyptan': hyperbolic tangent kernel; requires scale and offset:
+%      K(x, y) = tanh(scale * (x^T y) + offset)
+%  
+%   * 'laplacian': Laplacian kernel; requires bandwidth:
+%      K(x, y) = exp(-(|| x - y ||) / bandwidth)
+%  
+%   * 'cosine': cosine distance:
+%      K(x, y) = 1 - (x^T y) / (|| x || * || y ||)
+%  
+%  The parameters for each of the kernels should be specified with the options
+%  bandwidth, kernel_scale, offset, or degree (or a combination of those
+%  options).
+%
+%Parameters
+% dataPoints         - (required) Input dataset to perform KPCA on.
+% kernel             - (required) The kernel to use.
+% new_dimensionality - (optional) If not 0, reduce the dimensionality of the
+%                      dataset by ignoring the dimensions with the smallest
+%                      eighenvalues.
+% bandwidth          - (optional) Bandwidt, for gaussian or laplacian kernels. 
+%                      Default value is 1.
+% degree             - (optional)  Degree of polynomial, for 'polynomial' kernel. 
+%                      Default value 1.
+% kernel_scale       - (optional) Scale, for 'hyptan' kernel.  Default value 1.
+% offset             - (optional) Offset, for 'hyptan' and 'polynomial' kernels.
+%								       Default value is 1.
+% scale              - (optional) If true, the data will be scaled before performing
+%                      KPCA such that the variance of each feature is 1.
+
+% a parser for the inputs
+p = inputParser;
+p.addParamValue('new_dimensionality', @isscalar);
+p.addParamValue('offset', @isscalar);
+p.addParamValue('kernel_scale', @isscalar);
+p.addParamValue('bandwidth', @isscalar);
+p.addParamValue('degree', @isscalar);
+p.addParamValue('scale', false, @(x) (x == true) || (x == false));
+
+% parsing the varargin options
+p.parse(varargin{:});
+parsed = p.Results;
+
+% interfacing with mlpack. transposing to machine learning standards. 
+result = mex_kernel_pca(dataPoints', kernel, ...
+	parsed.new_dimensionality, parsed.scale, ...
+	parsed.degree, parsed.offset, ...
+	parsed.kernel_scale, parsed.bandwidth);
+
+result = result';
+

Added: mlpack/trunk/src/mlpack/bindings/matlab/lars/CMakeLists.txt
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/lars/CMakeLists.txt	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/lars/CMakeLists.txt	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,19 @@
+# Simple rules for building mex file.  The _mex suffix is necessary to avoid
+# target name conflicts, and the mex file must have a different name than the .m
+# file.
+add_library(lars_mex SHARED
+  lars.cpp
+)
+target_link_libraries(lars_mex
+  mlpack
+  ${LIBXML2_LIBRARIES}
+)
+
+# Installation rule.  Install both the mex and the MATLAB file.
+install(TARGETS lars_mex
+  LIBRARY DESTINATION "${MATLAB_TOOLBOX_DIR}/mlpack/"
+)
+install(FILES
+  lars.m
+  DESTINATION "${MATLAB_TOOLBOX_DIR}/mlpack/"
+)

Added: mlpack/trunk/src/mlpack/bindings/matlab/lars/Makefile
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/lars/Makefile	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/lars/Makefile	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,22 @@
+lars: lars.o
+	g++ -O -pthread -shared  \
+-Wl,--version-script,/opt/matlab/2010b/extern/lib/glnxa64/mexFunction.map \
+-Wl,--no-undefined -o 'mex_lars.mexa64' lars.o \
+-L../../build/lib -lmlpack \
+-Wl,-rpath-link,/opt/matlab/2010b/bin/glnxa64 \
+-L/opt/matlab/2010b/bin/glnxa64 -lmx -lmex -lmat -lm -lmwlapack \
+-Wl,-rpath=/net/hu19/pmason8/mlpack/trunk/build/lib \
+-L/usr/lib64 -larmadillo \
+
+lars.o:
+	g++ -c  \
+-I../../build/include \
+-I../../build/include/mlpack/methods/lars \
+-I/usr/include/libxml2 \
+-I/opt/matlab/2010b/extern/include \
+-DMATLAB_MEX_FILE \
+-ansi -D_GNU_SOURCE -fPIC -fno-omit-frame-pointer -pthread \
+-DMX_COMPAT_32 -O -DNDEBUG 'lars.cpp'
+
+clean:
+	rm -f *.o *.mexa64

Added: mlpack/trunk/src/mlpack/bindings/matlab/lars/lars.cpp
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/lars/lars.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/lars/lars.cpp	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,58 @@
+#include "mex.h"
+
+#include <mlpack/core.hpp>
+
+#include "lars.hpp"
+
+using namespace arma;
+using namespace std;
+using namespace mlpack;
+using namespace mlpack::regression;
+
+void mexFunction(int nlhs, mxArray *plhs[],
+                 int nrhs, const mxArray *prhs[])
+{
+  // argument checks
+  if (nrhs != 4) 
+  {
+    mexErrMsgTxt("Expecting four inputs.");
+  }
+
+  if (nlhs != 1) 
+  {
+    mexErrMsgTxt("Output required.");
+  }
+
+	double lambda1 = mxGetScalar(prhs[2]);
+	double lambda2 = mxGetScalar(prhs[3]);
+	bool useCholesky = (mxGetScalar(prhs[3]) == 1.0);
+
+	// loading covariates
+	mat matX(mxGetM(prhs[0]), mxGetN(prhs[0]));
+	double * values = mxGetPr(prhs[0]);
+	for (int i=0, num=mxGetNumberOfElements(prhs[0]); i<num; ++i)
+		matX(i) = values[i];
+
+	// loading responses
+	mat matY(mxGetM(prhs[1]), mxGetN(prhs[1]));
+	values = mxGetPr(prhs[1]);
+	for (int i=0, num=mxGetNumberOfElements(prhs[1]); i<num; ++i)
+		matY(i) = values[i];
+
+  if (matY.n_cols > 1)
+    mexErrMsgTxt("Only one column or row allowed in responses file!");
+
+  if (matY.n_elem != matX.n_rows)
+    mexErrMsgTxt("Number of responses must be equal to number of rows of X!");
+
+  // Do LARS.
+  LARS lars(useCholesky, lambda1, lambda2);
+  vec beta;
+  lars.Regress(matX, matY.unsafe_col(0), beta, false /* do not transpose */);
+
+	// return to matlab
+	plhs[0] = mxCreateDoubleMatrix(beta.n_elem, 1, mxREAL);
+	values = mxGetPr(plhs[0]);
+	for (int i = 0; i < beta.n_elem; ++i)
+		values[i] = beta(i);
+}

Added: mlpack/trunk/src/mlpack/bindings/matlab/lars/lars.m
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/lars/lars.m	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/lars/lars.m	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,48 @@
+function beta = lars(X, Y, varargin)
+%LARS
+%
+%  An implementation of LARS: Least Angle Regression (Stagewise/laSso).  This is
+%  a stage-wise homotopy-based algorithm for L1-regularized linear regression
+%  (LASSO) and L1+L2-regularized linear regression (Elastic Net).
+%  
+%  Let X be a matrix where each row is a point and each column is a dimension,
+%  and let y be a vector of targets.
+%  
+%  The Elastic Net problem is to solve
+%  
+%    min_beta 0.5 || X * beta - y ||_2^2 + lambda_1 ||beta||_1 +
+%        0.5 lambda_2 ||beta||_2^2
+%  
+%  If lambda_1 > 0 and lambda_2 = 0, the problem is the LASSO.
+%  If lambda_1 > 0 and lambda_2 > 0, the problem is the Elastic Net.
+%  If lambda_1 = 0 and lambda_2 > 0, the problem is Ridge Regression.
+%  If lambda_1 = 0 and lambda_2 = 0, the problem is unregularized linear
+%  regression.
+%  
+%  For efficiency reasons, it is not recommended to use this algorithm with
+%  lambda_1 = 0.
+%
+%Parameters
+% X         		 - (required) Matrix containing covariates.
+% Y              - (required) Matrix containing y.
+% lambda1			   - (optional) Default value 0. l1-penalty regularization.
+% lambda2				 - (optional) Default value 0. l2-penalty regularization.
+% useCholesky    - (optional) Use Cholesky decomposition during computation
+%                             rather than explicitly computing the full Gram
+%                             matrix.
+
+% a parser for the inputs
+p = inputParser;
+p.addParamValue('lambda1', @isscalar);
+p.addParamValue('lambda2', @isscalar);
+p.addParamValue('useCholesky', false, @(x) (x == true) || (x == false));
+
+% parsing the varargin options
+p.parse(varargin{:});
+parsed = p.Results;
+
+% interfacing with mlpack. Does not require transposing.
+beta = mex_lars(X, Y, ...
+	parsed.lambda1, parsed.lambda2, parsed.useCholesky);
+
+

Added: mlpack/trunk/src/mlpack/bindings/matlab/nca/CMakeLists.txt
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/nca/CMakeLists.txt	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/nca/CMakeLists.txt	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,19 @@
+# Simple rules for building mex file.  The _mex suffix is necessary to avoid
+# target name conflicts, and the mex file must have a different name than the .m
+# file.
+add_library(nca_mex SHARED
+  nca.cpp
+)
+target_link_libraries(nca_mex
+  mlpack
+  ${LIBXML2_LIBRARIES}
+)
+
+# Installation rule.  Install both the mex and the MATLAB file.
+install(TARGETS nca_mex
+  LIBRARY DESTINATION "${MATLAB_TOOLBOX_DIR}/mlpack/"
+)
+install(FILES
+  nca.m
+  DESTINATION "${MATLAB_TOOLBOX_DIR}/mlpack/"
+)

Added: mlpack/trunk/src/mlpack/bindings/matlab/nca/Makefile
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/nca/Makefile	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/nca/Makefile	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,22 @@
+nca: nca.o
+	g++ -O -pthread -shared  \
+-Wl,--version-script,/opt/matlab/2010b/extern/lib/glnxa64/mexFunction.map \
+-Wl,--no-undefined -o 'mex_nca.mexa64' nca.o \
+-L../../build/lib -lmlpack \
+-Wl,-rpath-link,/opt/matlab/2010b/bin/glnxa64 \
+-L/opt/matlab/2010b/bin/glnxa64 -lmx -lmex -lmat -lm -lmwlapack \
+-Wl,-rpath=/net/hu19/pmason8/mlpack/trunk/build/lib \
+-L/usr/lib64 -larmadillo \
+
+nca.o:
+	g++ -c  \
+-I../../build/include \
+-I../../build/include/mlpack/methods/nca \
+-I/usr/include/libxml2 \
+-I/opt/matlab/2010b/extern/include \
+-DMATLAB_MEX_FILE \
+-ansi -D_GNU_SOURCE -fPIC -fno-omit-frame-pointer -pthread \
+-DMX_COMPAT_32 -O -DNDEBUG 'nca.cpp'
+
+clean:
+	rm -f *.o *.mexa64

Added: mlpack/trunk/src/mlpack/bindings/matlab/nca/nca.cpp
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/nca/nca.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/nca/nca.cpp	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,55 @@
+#include "mex.h"
+
+#include <mlpack/core.hpp>
+#include <mlpack/core/metrics/lmetric.hpp>
+
+#include "nca.hpp"
+
+using namespace mlpack;
+using namespace mlpack::nca;
+using namespace mlpack::metric;
+using namespace std;
+using namespace arma;
+
+void mexFunction(int nlhs, mxArray *plhs[],
+                 int nrhs, const mxArray *prhs[])
+{
+  // argument checks
+  if (nrhs != 2) 
+  {
+    mexErrMsgTxt("Expecting two inputs.");
+  }
+
+  if (nlhs != 1) 
+  {
+    mexErrMsgTxt("Output required.");
+  }
+
+  // Load data.
+	mat data(mxGetM(prhs[0]), mxGetN(prhs[0]));
+	double * values = mxGetPr(prhs[0]);
+	for (int i=0, num=mxGetNumberOfElements(prhs[0]); i<num; ++i)
+		data(i) = values[i];
+
+	// load labels
+	umat labels(mxGetNumberOfElements(prhs[1]), 1);
+	values = mxGetPr(prhs[1]);
+	for (int i=0, num=mxGetNumberOfElements(prhs[1]); i<num; ++i)
+		labels(i) = (int) values[i];
+
+	// dimension checks
+	if (labels.n_elem != data.n_cols)
+		mexErrMsgTxt("Labels vector and data have unmatching dimensions.");
+
+  // Now create the NCA object and run the optimization.
+  NCA<LMetric<2> > nca(data, labels.unsafe_col(0));
+
+  mat distance;
+  nca.LearnDistance(distance);
+
+	// return to matlab
+	plhs[0] = mxCreateDoubleMatrix(distance.n_rows, distance.n_cols, mxREAL);
+	values = mxGetPr(plhs[0]);
+	for (int i = 0; i < distance.n_elem; ++i)
+		values[i] = distance(i);
+}

Added: mlpack/trunk/src/mlpack/bindings/matlab/nca/nca.m
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/nca/nca.m	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/nca/nca.m	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,24 @@
+function result = nca(dataPoints, labels)
+%Neighborhood Components Analysis (NCA)
+%
+%  This program implements Neighborhood Components Analysis, both a linear
+%  dimensionality reduction technique and a distance learning technique.  The
+%  method seeks to improve k-nearest-neighbor classification on a dataset by
+%  scaling the dimensions.  The method is nonparametric, and does not require a
+%  value of k.  It works by using stochastic ("soft") neighbor assignments and
+%  using optimization techniques over the gradient of the accuracy of the
+%  neighbor assignments.
+%  
+%  To work, this algorithm needs labeled data.  It can be given as the last row
+%  of the input dataset (--input_file), or alternatively in a separate file
+%  (--labels_file).
+%
+%Parameters:
+% dataPoints - Input dataset to run NCA on.
+% labels     - Labels for input dataset.
+
+% interfacing with mlpack. transposing to machine learning standards. 
+result = mex_nca(dataPoints', labels);
+result = result';
+
+

Added: mlpack/trunk/src/mlpack/bindings/matlab/nmf/CMakeLists.txt
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/nmf/CMakeLists.txt	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/nmf/CMakeLists.txt	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,19 @@
+# Simple rules for building mex file.  The _mex suffix is necessary to avoid
+# target name conflicts, and the mex file must have a different name than the .m
+# file.
+add_library(nmf_mex SHARED
+  nmf.cpp
+)
+target_link_libraries(nmf_mex
+  mlpack
+  ${LIBXML2_LIBRARIES}
+)
+
+# Installation rule.  Install both the mex and the MATLAB file.
+install(TARGETS nmf_mex
+  LIBRARY DESTINATION "${MATLAB_TOOLBOX_DIR}/mlpack/"
+)
+install(FILES
+  nmf.m
+  DESTINATION "${MATLAB_TOOLBOX_DIR}/mlpack/"
+)

Added: mlpack/trunk/src/mlpack/bindings/matlab/nmf/Makefile
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/nmf/Makefile	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/nmf/Makefile	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,22 @@
+nmf: nmf.o
+	g++ -O -pthread -shared  \
+-Wl,--version-script,/opt/matlab/2010b/extern/lib/glnxa64/mexFunction.map \
+-Wl,--no-undefined -o 'mex_nmf.mexa64' nmf.o \
+-L../../build/lib -lmlpack \
+-Wl,-rpath-link,/opt/matlab/2010b/bin/glnxa64 \
+-L/opt/matlab/2010b/bin/glnxa64 -lmx -lmex -lmat -lm -lmwlapack \
+-Wl,-rpath=/net/hu19/pmason8/mlpack/trunk/build/lib \
+-L/usr/lib64 -larmadillo \
+
+nmf.o:
+	g++ -c  \
+-I../../build/include \
+-I../../build/include/mlpack/methods/nmf \
+-I/usr/include/libxml2 \
+-I/opt/matlab/2010b/extern/include \
+-DMATLAB_MEX_FILE \
+-ansi -D_GNU_SOURCE -fPIC -fno-omit-frame-pointer -pthread \
+-DMX_COMPAT_32 -O -DNDEBUG 'nmf.cpp'
+
+clean:
+	rm -f *.o *.mexa64

Added: mlpack/trunk/src/mlpack/bindings/matlab/nmf/nmf.cpp
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/nmf/nmf.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/nmf/nmf.cpp	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,106 @@
+#include "mex.h"
+
+#include <mlpack/core.hpp>
+
+#include "nmf.hpp"
+
+#include "random_init.hpp"
+#include "mult_dist_update_rules.hpp"
+#include "mult_div_update_rules.hpp"
+#include "als_update_rules.hpp"
+
+using namespace mlpack;
+using namespace mlpack::nmf;
+using namespace std;
+
+void mexFunction(int nlhs, mxArray *plhs[],
+                 int nrhs, const mxArray *prhs[])
+{
+  // argument checks
+  if (nrhs != 6) 
+  {
+    mexErrMsgTxt("Expecting six inputs.");
+  }
+
+  if (nlhs != 2) 
+  {
+    mexErrMsgTxt("Two outputs required.");
+  }
+
+	const size_t seed = (size_t) mxGetScalar(prhs[5]);
+
+  // Initialize random seed.
+  if (seed != 0)
+    math::RandomSeed(seed);
+  else
+    math::RandomSeed((size_t) std::time(NULL));
+
+  // Gather parameters.
+	const size_t r = (size_t) mxGetScalar(prhs[1]);
+	const size_t maxIterations = (size_t) mxGetScalar(prhs[2]);
+	const double minResidue = mxGetScalar(prhs[3]);
+
+	// update rule
+	int bufLength = mxGetNumberOfElements(prhs[4]) + 1;
+	char * buf = (char *) mxCalloc(bufLength, sizeof(char));
+  mxGetString(prhs[4], buf, bufLength);
+	string updateRules(buf);
+	mxFree(buf);
+
+  // Validate rank.
+  if (r < 1)
+  {
+    mexErrMsgTxt("The rank of the factorization cannot be less than 1.");
+  }
+
+  if ((updateRules != "multdist") &&
+      (updateRules != "multdiv") &&
+      (updateRules != "als"))
+  {
+		stringstream ss;
+  	ss << "Invalid update rules ('" << updateRules << "'); must be '"
+        << "multdist', 'multdiv', or 'als'.";
+		mexErrMsgTxt(ss.str().c_str());
+  }
+
+  // Load input dataset.
+  arma::mat V(mxGetM(prhs[0]), mxGetN(prhs[0]));
+	double * values = mxGetPr(prhs[0]);
+	for (int i=0, num=mxGetNumberOfElements(prhs[0]); i<num; ++i)
+		V(i) = values[i];
+
+  arma::mat W;
+  arma::mat H;
+
+  // Perform NMF with the specified update rules.
+  if (updateRules == "multdist")
+  {
+    NMF<> nmf(maxIterations, minResidue);
+    nmf.Apply(V, r, W, H);
+  }
+  else if (updateRules == "multdiv")
+  {
+    NMF<RandomInitialization,
+        WMultiplicativeDivergenceRule,
+        HMultiplicativeDivergenceRule> nmf(maxIterations, minResidue);
+    nmf.Apply(V, r, W, H);
+  }
+  else if (updateRules == "als")
+  {
+    NMF<RandomInitialization,
+        WAlternatingLeastSquaresRule,
+        HAlternatingLeastSquaresRule> nmf(maxIterations, minResidue);
+    nmf.Apply(V, r, W, H);
+  }
+
+	// return to matlab
+	plhs[0] = mxCreateDoubleMatrix(W.n_rows, W.n_cols, mxREAL);
+	values = mxGetPr(plhs[0]);
+	for (int i = 0; i < W.n_elem; ++i)
+		values[i] = W(i);
+
+	plhs[1] = mxCreateDoubleMatrix(H.n_rows, H.n_cols, mxREAL);
+	values = mxGetPr(plhs[0]);
+	for (int i = 0; i < H.n_elem; ++i)
+		values[i] = H(i);
+}

Added: mlpack/trunk/src/mlpack/bindings/matlab/nmf/nmf.m
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/nmf/nmf.m	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/nmf/nmf.m	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,58 @@
+function [W H] = nmf(dataPoints, rank, varargin)
+%Non-negative Matrix Factorization
+%
+%  This program performs non-negative matrix factorization on the given dataset,
+%  storing the resulting decomposed matrices in the specified files.  For an
+%  input dataset V, NMF decomposes V into two matrices W and H such that 
+%  
+%  V = W * H
+%  
+%  where all elements in W and H are non-negative.  If V is of size (n x m), then
+%  W will be of size (n x r) and H will be of size (r x m), where r is the rank
+%  of the factorization (specified by --rank).
+%  
+%  Optionally, the desired update rules for each NMF iteration can be chosen from
+%  the following list:
+%  
+%   - multdist: multiplicative distance-based update rules (Lee and Seung 1999)
+%   - multdiv: multiplicative divergence-based update rules (Lee and Seung 1999)
+%   - als: alternating least squares update rules (Paatero and Tapper 1994)
+%  
+%  The maximum number of iterations is specified with 'max_iterations', and the
+%  minimum residue required for algorithm termination is specified with
+%  'min_residue'.
+%
+%Parameters:
+% dataPoints        - (required) Input dataset to perform NMF on.
+% rank							- (required) Rank of the factorization.
+% max_iterations    - (optional) Number of iterations before NMF terminates.
+%																 (Default value 10000.)
+% min_residue			  - (optional) The minimum root mean square residue allowed for
+%                                each iteration, below which the program
+%                                terminates.  Default value 1e-05.
+% seed							- (optional) Random seed.If 0, 'std::time(NULL)' is used. 
+%														     Default 0.
+% update rules			- (optional) Update rules for each iteration; ( multdist |
+%                                multdiv | als ).  Default value 'multdist'.
+
+% a parser for the inputs
+p = inputParser;
+p.addParamValue('max_iterations', 10000, @isscalar);
+p.addParamValue('min_residue', 1e-05, @isscalar);
+p.addParamValue('update_rules', 'multdist', @ischar);
+p.addParamValue('seed', 0, @isscalar);
+
+% parsing the varargin options
+p.parse(varargin{:});
+parsed = p.Results;
+
+% interfacing with mlpack. transposing for machine learning standards. 
+[W H] = mex_nmf(dataPoints', rank, ...
+	parsed.max_iterations, parsed.min_residue, ...
+	parsed.update_rules, parsed.seed);
+W = W';
+H = H';
+
+
+
+

Added: mlpack/trunk/src/mlpack/bindings/matlab/pca/CMakeLists.txt
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/pca/CMakeLists.txt	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/pca/CMakeLists.txt	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,19 @@
+# Simple rules for building mex file.  The _mex suffix is necessary to avoid
+# target name conflicts, and the mex file must have a different name than the .m
+# file.
+add_library(pca_mex SHARED
+  pca.cpp
+)
+target_link_libraries(pca_mex
+  mlpack
+  ${LIBXML2_LIBRARIES}
+)
+
+# Installation rule.  Install both the mex and the MATLAB file.
+install(TARGETS pca_mex
+  LIBRARY DESTINATION "${MATLAB_TOOLBOX_DIR}/mlpack/"
+)
+install(FILES
+  pca.m
+  DESTINATION "${MATLAB_TOOLBOX_DIR}/mlpack/"
+)

Added: mlpack/trunk/src/mlpack/bindings/matlab/pca/Makefile
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/pca/Makefile	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/pca/Makefile	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,26 @@
+pca: pca.o
+	g++ -g -pthread -shared  \
+-Wl,--version-script,/opt/matlab/2010b/extern/lib/glnxa64/mexFunction.map \
+-Wl,--no-undefined -o 'mex_pca.mexa64' pca.o \
+-L../../build/lib -lmlpack \
+-Wl,-rpath-link,/opt/matlab/2010b/bin/glnxa64 \
+-L/opt/matlab/2010b/bin/glnxa64 -lmx -lmex -lmat -lm -lmwlapack \
+-Wl,-rpath=/net/hu19/pmason8/mlpack/trunk/build/lib \
+
+#-L/usr/lib64 -larmadillo \
+
+
+pca.o:
+	g++ -c  \
+-I../../build/include \
+-I../../build/include/mlpack/methods/pca \
+-I/usr/include/libxml2 \
+-I/opt/matlab/2010b/extern/include \
+-DMATLAB_MEX_FILE \
+-ansi -D_GNU_SOURCE -fPIC -fno-omit-frame-pointer -pthread \
+-DMX_COMPAT_32 -g 'pca.cpp'
+
+#-DMX_COMPAT_32 -O -DNDEBUG 'pca.cpp'
+
+clean:
+	rm -f *.o *.mexa64

Added: mlpack/trunk/src/mlpack/bindings/matlab/pca/pca.cpp
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/pca/pca.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/pca/pca.cpp	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,62 @@
+#include "mex.h"
+
+#include <mlpack/core.hpp>
+
+#include "pca.hpp"
+
+using namespace mlpack;
+using namespace mlpack::pca;
+using namespace std;
+
+void mexFunction(int nlhs, mxArray *plhs[],
+                 int nrhs, const mxArray *prhs[])
+{
+  // argument checks
+  if (nrhs != 3) 
+  {
+    mexErrMsgTxt("Expecting three inputs.");
+  }
+
+  if (nlhs != 1) 
+  {
+    mexErrMsgTxt("Output required.");
+  }
+
+  // loading the data
+  double * mexDataPoints = mxGetPr(prhs[0]);
+  size_t numPoints = mxGetN(prhs[0]);
+  size_t numDimensions = mxGetM(prhs[0]);
+  arma::mat dataset(numDimensions, numPoints);
+  for (int i = 0, n = numPoints * numDimensions; i < n; ++i) 
+    dataset(i) = mexDataPoints[i];
+
+  // Find out what dimension we want.
+  size_t newDimension = dataset.n_rows; // No reduction, by default.
+
+	if (mxGetScalar(prhs[1]) != 0.0)
+  {
+    // Validate the parameter.
+		newDimension = (size_t) mxGetScalar(prhs[1]);
+    if (newDimension > dataset.n_rows)
+    {
+			std::stringstream ss;
+      ss << "New dimensionality (" << newDimension
+          << ") cannot be greater than existing dimensionality ("
+          << dataset.n_rows << ")!";
+			mexErrMsgTxt(ss.str().c_str());
+    }
+  }
+
+  // Get the options for running PCA.
+	const bool scale = (mxGetScalar(prhs[2]) == 1.0);
+
+  // Perform PCA.
+  PCA p(scale);
+  p.Apply(dataset, newDimension);
+
+  // Now returning results to matlab
+	plhs[0] = mxCreateDoubleMatrix(dataset.n_rows, dataset.n_cols, mxREAL);
+	double * values = mxGetPr(plhs[0]);
+	for (int i = 0; i < dataset.n_rows * dataset.n_cols; ++i)
+		values[i] = dataset(i);
+}

Added: mlpack/trunk/src/mlpack/bindings/matlab/pca/pca.m
===================================================================
--- mlpack/trunk/src/mlpack/bindings/matlab/pca/pca.m	                        (rev 0)
+++ mlpack/trunk/src/mlpack/bindings/matlab/pca/pca.m	2012-11-20 20:07:16 UTC (rev 13900)
@@ -0,0 +1,33 @@
+function result = pca(dataPoints, varargin)
+%Principal Components Analysis
+%
+%  This program performs principal components analysis on the given dataset.  It
+%  will transform the data onto its principal components, optionally performing
+%  dimensionality reduction by ignoring the principal components with the
+%  smallest eigenvalues.
+%
+%Parameters:
+% dataPoints        - (required) Matrix to perform PCA on.
+% newDimensionality - (optional) Desired dimensionality of output dataset.  If 0,
+%                                no dimensionality reduction is performed. 
+%                                Default value 0.
+% scale             - (optional) If set, the data will be scaled before running
+%                                PCA, such that the variance of each feature is
+%                                1. Default value is false.
+
+% a parser for the inputs
+p = inputParser;
+p.addParamValue('newDimensionality', 0, @isscalar);
+p.addParamValue('scale', false, @(x) (x == true) || (x == false));
+
+% parsing the varargin options
+p.parse(varargin{:});
+parsed = p.Results;
+
+% interfacing with mlpack
+result = mex_pca(dataPoints', parsed.newDimensionality, parsed.scale);
+result = result';
+
+
+
+




More information about the mlpack-svn mailing list