From 333cf7142fa00d7c97a91baad0294b952b798b8b Mon Sep 17 00:00:00 2001 From: Michele Mazzoni Date: Mon, 26 Jun 2017 16:23:43 +0200 Subject: [PATCH] Add to linalg (CPU-only): add_scalar, center_matrix, eigen_solver, eigen_solver_symmetric, qr_solver, svd, transpose_matrix, triangular_solver. --- .../mathematics/linalg/LinalgBackendBase.h | 125 +++++++ .../mathematics/linalg/LinalgBackendEigen.h | 126 +++++++ .../mathematics/linalg/LinalgNamespace.h | 206 ++++++++++++ .../linalg/backend/eigen/BasicOps.cpp | 23 ++ .../linalg/backend/eigen/Decompositions.cpp | 89 +++++ .../mathematics/linalg/backend/eigen/Misc.cpp | 45 +++ .../linalg/backend/eigen/Solvers.cpp | 107 ++++++ .../operations/Eigen3_operations_unittest.cc | 313 ++++++++++++++++++ 8 files changed, 1034 insertions(+) diff --git a/src/shogun/mathematics/linalg/LinalgBackendBase.h b/src/shogun/mathematics/linalg/LinalgBackendBase.h index 8dd02e1ccf5..8f4967b70f9 100644 --- a/src/shogun/mathematics/linalg/LinalgBackendBase.h +++ b/src/shogun/mathematics/linalg/LinalgBackendBase.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -121,6 +122,33 @@ namespace shogun DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_ADD_COL_VEC, SGMatrix) #undef BACKEND_GENERIC_ADD_COL_VEC +/** + * Wrapper method of add scalar operation. + * + * @see linalg::add_scalar + */ +#define BACKEND_GENERIC_ADD_SCALAR(Type, Container) \ + virtual void add_scalar(Container& a, Type b) const \ + { \ + SG_SNOTIMPLEMENTED; \ + } + DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_ADD_SCALAR, SGVector) + DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_ADD_SCALAR, SGMatrix) +#undef BACKEND_GENERIC_ADD_SCALAR + +/** + * Wrapper method of center matrix operation. + * + * @see linalg::center_matrix + */ +#define BACKEND_GENERIC_CENTER_MATRIX(Type, Container) \ + virtual void center_matrix(Container& A) const \ + { \ + SG_SNOTIMPLEMENTED; \ + } + DEFINE_FOR_NON_INTEGER_PTYPE(BACKEND_GENERIC_CENTER_MATRIX, SGMatrix) +#undef BACKEND_GENERIC_CENTER_MATRIX + /** * Wrapper method of Cholesky decomposition. * @@ -166,6 +194,38 @@ namespace shogun DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_DOT, SGVector) #undef BACKEND_GENERIC_DOT +/** + * Wrapper method of eigenvalues and eigenvectors computation. + * + * @see linalg::eigen_solver + */ +#define BACKEND_GENERIC_EIGEN_SOLVER(Type, Container) \ + virtual void eigen_solver( \ + const Container& A, SGVector& eigenvalues, \ + SGMatrix& eigenvectors) const \ + { \ + SG_SNOTIMPLEMENTED; \ + } + DEFINE_FOR_NON_INTEGER_PTYPE(BACKEND_GENERIC_EIGEN_SOLVER, SGMatrix) +#undef BACKEND_GENERIC_EIGEN_SOLVER + +/** + * Wrapper method of eigenvalues and eigenvectors computation + * for symmetric matrices. + * + * @see linalg::eigen_solver_symmetric + */ +#define BACKEND_GENERIC_EIGEN_SOLVER_SYMMETRIC(Type, Container) \ + virtual void eigen_solver_symmetric( \ + const Container& A, SGVector& eigenvalues, \ + SGMatrix& eigenvectors) const \ + { \ + SG_SNOTIMPLEMENTED; \ + } + DEFINE_FOR_NON_INTEGER_PTYPE( + BACKEND_GENERIC_EIGEN_SOLVER_SYMMETRIC, SGMatrix) +#undef BACKEND_GENERIC_EIGEN_SOLVER_SYMMETRIC + /** * Wrapper method of in-place matrix elementwise product. * @@ -301,6 +361,23 @@ namespace shogun DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_RANGE_FILL, SGMatrix) #undef BACKEND_GENERIC_RANGE_FILL +/** + * Wrapper method that solves a system of linear equations + * using QR decomposition. + * + * @see linalg::qr_solver + */ +#define BACKEND_GENERIC_QR_SOLVER(Type, Container) \ + virtual Container qr_solver( \ + const SGMatrix& A, const Container& b) const \ + { \ + SG_SNOTIMPLEMENTED; \ + return 0; \ + } + DEFINE_FOR_NON_INTEGER_PTYPE(BACKEND_GENERIC_QR_SOLVER, SGVector) + DEFINE_FOR_NON_INTEGER_PTYPE(BACKEND_GENERIC_QR_SOLVER, SGMatrix) +#undef BACKEND_GENERIC_QR_SOLVER + /** * Wrapper method of scale operation the operation result = alpha*A. * @@ -449,6 +526,21 @@ namespace shogun DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_BLOCK_ROWWISE_SUM, SGMatrix) #undef BACKEND_GENERIC_BLOCK_ROWWISE_SUM +/** + * Wrapper method of svd computation. + * + * @see linalg::svd + */ +#define BACKEND_GENERIC_SVD(Type, Container) \ + virtual void svd( \ + const Container& A, SGVector s, SGMatrix U, \ + bool thin_U) const \ + { \ + SG_SNOTIMPLEMENTED; \ + } + DEFINE_FOR_NON_INTEGER_PTYPE(BACKEND_GENERIC_SVD, SGMatrix) +#undef BACKEND_GENERIC_SVD + /** * Wrapper method of trace computation. * @@ -463,6 +555,39 @@ namespace shogun DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_TRACE, SGMatrix) #undef BACKEND_GENERIC_TRACE +/** + * Wrapper method of trace computation. + * + * @see linalg::transpose_matrix + */ +#define BACKEND_GENERIC_TRANSPOSE_MATRIX(Type, Container) \ + virtual Container transpose_matrix(const Container& A) const \ + { \ + SG_SNOTIMPLEMENTED; \ + return 0; \ + } + DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_TRANSPOSE_MATRIX, SGMatrix) +#undef BACKEND_GENERIC_TRANSPOSE_MATRIX + +/** + * Wrapper method of triangular solver. + * + * @see linalg::triangular_solver + */ +#define BACKEND_GENERIC_TRIANGULAR_SOLVER(Type, Container) \ + virtual Container triangular_solver( \ + const SGMatrix& L, const Container& b, \ + const bool lower = true) const \ + { \ + SG_SNOTIMPLEMENTED; \ + return 0; \ + } + DEFINE_FOR_NON_INTEGER_PTYPE( + BACKEND_GENERIC_TRIANGULAR_SOLVER, SGVector) + DEFINE_FOR_NON_INTEGER_PTYPE( + BACKEND_GENERIC_TRIANGULAR_SOLVER, SGMatrix) +#undef BACKEND_GENERIC_TRIANGULAR_SOLVER + /** * Wrapper method of set vector or matrix to zero. * diff --git a/src/shogun/mathematics/linalg/LinalgBackendEigen.h b/src/shogun/mathematics/linalg/LinalgBackendEigen.h index 519ec9fe463..875d7d13910 100644 --- a/src/shogun/mathematics/linalg/LinalgBackendEigen.h +++ b/src/shogun/mathematics/linalg/LinalgBackendEigen.h @@ -63,6 +63,19 @@ namespace shogun DEFINE_FOR_NUMERIC_PTYPE(BACKEND_GENERIC_ADD_COL_VEC, SGMatrix) #undef BACKEND_GENERIC_ADD_COL_VEC +/** Implementation of @see LinalgBackendBase::add_scalar */ +#define BACKEND_GENERIC_ADD_SCALAR(Type, Container) \ + virtual void add_scalar(Container& a, Type b) const; + DEFINE_FOR_NUMERIC_PTYPE(BACKEND_GENERIC_ADD_SCALAR, SGVector) + DEFINE_FOR_NUMERIC_PTYPE(BACKEND_GENERIC_ADD_SCALAR, SGMatrix) +#undef BACKEND_GENERIC_ADD_SCALAR + +/** Implementation of @see LinalgBackendBase::center_matrix */ +#define BACKEND_GENERIC_CENTER_MATRIX(Type, Container) \ + virtual void center_matrix(Container& A) const; + DEFINE_FOR_NON_INTEGER_PTYPE(BACKEND_GENERIC_CENTER_MATRIX, SGMatrix) +#undef BACKEND_GENERIC_CENTER_MATRIX + /** Implementation of @see LinalgBackendBase::cholesky_factor */ #define BACKEND_GENERIC_CHOLESKY_FACTOR(Type, Container) \ virtual Container cholesky_factor( \ @@ -84,6 +97,23 @@ namespace shogun DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_DOT, SGVector) #undef BACKEND_GENERIC_DOT +/** Implementation of @see LinalgBackendBase::eigen_solver */ +#define BACKEND_GENERIC_EIGEN_SOLVER(Type, Container) \ + virtual void eigen_solver( \ + const Container& A, SGVector& eigenvalues, \ + SGMatrix& eigenvectors) const; + DEFINE_FOR_NON_INTEGER_PTYPE(BACKEND_GENERIC_EIGEN_SOLVER, SGMatrix) +#undef BACKEND_GENERIC_EIGEN_SOLVER + +/** Implementation of @see LinalgBackendBase::eigen_solver_symmetric */ +#define BACKEND_GENERIC_EIGEN_SOLVER_SYMMETRIC(Type, Container) \ + virtual void eigen_solver_symmetric( \ + const Container& A, SGVector& eigenvalues, \ + SGMatrix& eigenvectors) const; + DEFINE_FOR_NON_INTEGER_PTYPE( + BACKEND_GENERIC_EIGEN_SOLVER_SYMMETRIC, SGMatrix) +#undef BACKEND_GENERIC_EIGEN_SOLVER_SYMMETRIC + /** Implementation of @see LinalgBackendBase::element_prod */ #define BACKEND_GENERIC_IN_PLACE_ELEMENT_PROD(Type, Container) \ virtual void element_prod( \ @@ -143,6 +173,14 @@ namespace shogun BACKEND_GENERIC_COMPLEX_MEAN(SGMatrix) #undef BACKEND_GENERIC_COMPLEX_MEAN +/** Implementation of @see LinalgBackendBase::qr_solver */ +#define BACKEND_GENERIC_QR_SOLVER(Type, Container) \ + virtual Container qr_solver( \ + const SGMatrix& A, const Container& b) const; + DEFINE_FOR_NON_INTEGER_PTYPE(BACKEND_GENERIC_QR_SOLVER, SGVector) + DEFINE_FOR_NON_INTEGER_PTYPE(BACKEND_GENERIC_QR_SOLVER, SGMatrix) +#undef BACKEND_GENERIC_QR_SOLVER + /** Implementation of @see LinalgBackendBase::range_fill */ #define BACKEND_GENERIC_RANGE_FILL(Type, Container) \ virtual void range_fill(Container& a, const Type start) const; @@ -220,12 +258,37 @@ namespace shogun DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_BLOCK_ROWWISE_SUM, SGMatrix) #undef BACKEND_GENERIC_BLOCK_ROWWISE_SUM +/** Implementation of @see LinalgBackendBase::svd */ +#define BACKEND_GENERIC_SVD(Type, Container) \ + virtual void svd( \ + const Container& A, SGVector s, Container U, \ + bool thin_U) const; + DEFINE_FOR_NON_INTEGER_PTYPE(BACKEND_GENERIC_SVD, SGMatrix) +#undef BACKEND_GENERIC_SVD + /** Implementation of @see LinalgBackendBase::trace */ #define BACKEND_GENERIC_TRACE(Type, Container) \ virtual Type trace(const Container& A) const; DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_TRACE, SGMatrix) #undef BACKEND_GENERIC_TRACE +/** Implementation of @see LinalgBackendBase::transpose_matrix */ +#define BACKEND_GENERIC_TRANSPOSE_MATRIX(Type, Container) \ + virtual Container transpose_matrix(const Container& A) const; + DEFINE_FOR_ALL_PTYPE(BACKEND_GENERIC_TRANSPOSE_MATRIX, SGMatrix) +#undef BACKEND_GENERIC_TRANSPOSE_MATRIX + +/** Implementation of @see LinalgBackendBase::triangular_solver */ +#define BACKEND_GENERIC_TRIANGULAR_SOLVER(Type, Container) \ + virtual Container triangular_solver( \ + const SGMatrix& L, const Container& b, const bool lower) \ + const; + DEFINE_FOR_NON_INTEGER_PTYPE( + BACKEND_GENERIC_TRIANGULAR_SOLVER, SGVector) + DEFINE_FOR_NON_INTEGER_PTYPE( + BACKEND_GENERIC_TRIANGULAR_SOLVER, SGMatrix) +#undef BACKEND_GENERIC_TRIANGULAR_SOLVER + /** Implementation of @see LinalgBackendBase::zero */ #define BACKEND_GENERIC_ZERO(Type, Container) \ virtual void zero(Container& a) const; @@ -263,6 +326,18 @@ namespace shogun const SGMatrix& A, index_t i, const SGVector& b, SGVector& result, T alpha, T beta) const; + /** Eigen3 vector add scalar method */ + template + void add_scalar_impl(SGVector& a, T b) const; + + /** Eigen3 matrix add scalar method */ + template + void add_scalar_impl(SGMatrix& a, T b) const; + + /** Eigen3 center matrix method */ + template + void center_matrix_impl(SGMatrix& A) const; + /** Eigen3 Cholesky decomposition */ template SGMatrix @@ -277,6 +352,27 @@ namespace shogun template T dot_impl(const SGVector& a, const SGVector& b) const; + /** Eigen3 eigenvalues and eigenvectors computation for real matrices. + */ + template + void eigen_solver_impl( + const SGMatrix& A, SGVector& eigenvalues, + SGMatrix& eigenvectors) const; + + /** Eigen3 eigenvalues and eigenvectors computation for complex + * matrices. */ + void eigen_solver_impl( + const SGMatrix& A, + SGVector& eigenvalues, + SGMatrix& eigenvectors) const; + + /** Eigen3 eigenvalues and eigenvectors computation of symmetric + * matrices */ + template + void eigen_solver_symmetric_impl( + const SGMatrix& A, SGVector& eigenvalues, + SGMatrix& eigenvectors) const; + /** Eigen3 matrix in-place elementwise product method */ template void element_prod_impl( @@ -326,6 +422,16 @@ namespace shogun template