From 30d57abf59251344e115ce63c5d5793474fef2e7 Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Mon, 8 Apr 2019 15:18:45 -0400 Subject: [PATCH 01/13] changing glue and op to mat in ccov --- src/mlpack/core/arma_extend/CMakeLists.txt | 5 - src/mlpack/core/arma_extend/arma_extend.hpp | 9 - src/mlpack/core/arma_extend/fn_ccov.hpp | 34 --- .../core/arma_extend/glue_ccov_meat.hpp | 144 ----------- .../core/arma_extend/glue_ccov_proto.hpp | 15 -- src/mlpack/core/arma_extend/op_ccov_meat.hpp | 97 ------- src/mlpack/core/arma_extend/op_ccov_proto.hpp | 18 -- src/mlpack/core/math/CMakeLists.txt | 1 + src/mlpack/core/math/ccov.hpp | 242 ++++++++++++++++++ src/mlpack/core/math/lin_alg.cpp | 7 +- src/mlpack/tests/distribution_test.cpp | 9 +- src/mlpack/tests/gmm_test.cpp | 15 +- src/mlpack/tests/hmm_test.cpp | 3 +- src/mlpack/tests/lin_alg_test.cpp | 5 +- 14 files changed, 268 insertions(+), 336 deletions(-) delete mode 100644 src/mlpack/core/arma_extend/fn_ccov.hpp delete mode 100644 src/mlpack/core/arma_extend/glue_ccov_meat.hpp delete mode 100644 src/mlpack/core/arma_extend/glue_ccov_proto.hpp delete mode 100644 src/mlpack/core/arma_extend/op_ccov_meat.hpp delete mode 100644 src/mlpack/core/arma_extend/op_ccov_proto.hpp create mode 100644 src/mlpack/core/math/ccov.hpp diff --git a/src/mlpack/core/arma_extend/CMakeLists.txt b/src/mlpack/core/arma_extend/CMakeLists.txt index fc218442f4..30195a9b76 100644 --- a/src/mlpack/core/arma_extend/CMakeLists.txt +++ b/src/mlpack/core/arma_extend/CMakeLists.txt @@ -2,13 +2,8 @@ # Anything not in this list will not be compiled into mlpack. set(SOURCES arma_extend.hpp - fn_ccov.hpp fn_inplace_reshape.hpp - glue_ccov_meat.hpp - glue_ccov_proto.hpp hdf5_misc.hpp - op_ccov_meat.hpp - op_ccov_proto.hpp SpMat_extra_bones.hpp SpMat_extra_meat.hpp Mat_extra_bones.hpp diff --git a/src/mlpack/core/arma_extend/arma_extend.hpp b/src/mlpack/core/arma_extend/arma_extend.hpp index bcf6088a4b..c2aa4f5db2 100644 --- a/src/mlpack/core/arma_extend/arma_extend.hpp +++ b/src/mlpack/core/arma_extend/arma_extend.hpp @@ -5,9 +5,6 @@ * Include Armadillo extensions which currently are not part of the main * Armadillo codebase. * - * This will allow the use of the ccov() function (which performs the same - * function as cov(trans(X)) but without the cost of computing trans(X)). This - * also gives sparse matrix support, if it is necessary. */ #ifndef MLPACK_CORE_ARMA_EXTEND_ARMA_EXTEND_HPP #define MLPACK_CORE_ARMA_EXTEND_ARMA_EXTEND_HPP @@ -55,12 +52,6 @@ namespace arma { // u64/s64 #include "hdf5_misc.hpp" - // ccov() - #include "op_ccov_proto.hpp" - #include "op_ccov_meat.hpp" - #include "glue_ccov_proto.hpp" - #include "glue_ccov_meat.hpp" - #include "fn_ccov.hpp" // inplace_reshape() #include "fn_inplace_reshape.hpp" diff --git a/src/mlpack/core/arma_extend/fn_ccov.hpp b/src/mlpack/core/arma_extend/fn_ccov.hpp deleted file mode 100644 index 86f3ecb81d..0000000000 --- a/src/mlpack/core/arma_extend/fn_ccov.hpp +++ /dev/null @@ -1,34 +0,0 @@ -//! \addtogroup fn_ccov -//! @{ - - - -template -inline -const Op -ccov(const Base& X, const uword norm_type = 0) - { - arma_extra_debug_sigprint(); - - arma_debug_check( (norm_type > 1), "ccov(): norm_type must be 0 or 1"); - - return Op(X.get_ref(), norm_type, 0); - } - - - -template -inline -const Glue -cov(const Base& A, const Base& B, const uword norm_type = 0) - { - arma_extra_debug_sigprint(); - - arma_debug_check( (norm_type > 1), "ccov(): norm_type must be 0 or 1"); - - return Glue(A.get_ref(), B.get_ref(), norm_type); - } - - - -//! @} diff --git a/src/mlpack/core/arma_extend/glue_ccov_meat.hpp b/src/mlpack/core/arma_extend/glue_ccov_meat.hpp deleted file mode 100644 index c3589c368b..0000000000 --- a/src/mlpack/core/arma_extend/glue_ccov_meat.hpp +++ /dev/null @@ -1,144 +0,0 @@ -//! \addtogroup glue_cov -//! @{ - - - -template -inline -void -glue_ccov::direct_ccov(Mat& out, const Mat& A, const Mat& B, const uword norm_type) - { - arma_extra_debug_sigprint(); - - if(A.is_vec() && B.is_vec()) - { - arma_debug_check( (A.n_elem != B.n_elem), "ccov(): the number of elements in A and B must match" ); - - const eT* A_ptr = A.memptr(); - const eT* B_ptr = B.memptr(); - - eT A_acc = eT(0); - eT B_acc = eT(0); - eT out_acc = eT(0); - - const uword N = A.n_elem; - - for(uword i=0; i 1) ? eT(N-1) : eT(1) ) : eT(N); - - out.set_size(1,1); - out[0] = out_acc/norm_val; - } - else - { - arma_debug_assert_same_size(A, B, "ccov()"); - - const uword N = A.n_cols; - const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - - out = A * trans(B); - out -= (sum(A) * trans(sum(B))) / eT(N); - out /= norm_val; - } - } - - - -template -inline -void -glue_ccov::direct_ccov(Mat< std::complex >& out, const Mat< std::complex >& A, const Mat< std::complex >& B, const uword norm_type) - { - arma_extra_debug_sigprint(); - - typedef typename std::complex eT; - - if(A.is_vec() && B.is_vec()) - { - arma_debug_check( (A.n_elem != B.n_elem), "cov(): the number of elements in A and B must match" ); - - const eT* A_ptr = A.memptr(); - const eT* B_ptr = B.memptr(); - - eT A_acc = eT(0); - eT B_acc = eT(0); - eT out_acc = eT(0); - - const uword N = A.n_elem; - - for(uword i=0; i 1) ? eT(N-1) : eT(1) ) : eT(N); - - out.set_size(1,1); - out[0] = out_acc/norm_val; - } - else - { - arma_debug_assert_same_size(A, B, "ccov()"); - - const uword N = A.n_cols; - const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - - out = A * trans(conj(B)); - out -= (sum(A) * trans(conj(sum(B)))) / eT(N); - out /= norm_val; - } - } - - - -template -inline -void -glue_ccov::apply(Mat& out, const Glue& X) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT; - - const unwrap_check A_tmp(X.A, out); - const unwrap_check B_tmp(X.B, out); - - const Mat& A = A_tmp.M; - const Mat& B = B_tmp.M; - - const uword norm_type = X.aux_uword; - - if(&A != &B) - { - glue_ccov::direct_ccov(out, A, B, norm_type); - } - else - { - op_ccov::direct_ccov(out, A, norm_type); - } - - } - - - -//! @} diff --git a/src/mlpack/core/arma_extend/glue_ccov_proto.hpp b/src/mlpack/core/arma_extend/glue_ccov_proto.hpp deleted file mode 100644 index f5531175de..0000000000 --- a/src/mlpack/core/arma_extend/glue_ccov_proto.hpp +++ /dev/null @@ -1,15 +0,0 @@ -//! \addtogroup glue_ccov -//! @{ - -class glue_ccov - { - public: - - template inline static void direct_ccov(Mat& out, const Mat& A, const Mat& B, const uword norm_type); - template inline static void direct_ccov(Mat< std::complex >& out, const Mat< std::complex >& A, const Mat< std::complex >& B, const uword norm_type); - - template inline static void apply(Mat& out, const Glue& X); - }; - -//! @} - diff --git a/src/mlpack/core/arma_extend/op_ccov_meat.hpp b/src/mlpack/core/arma_extend/op_ccov_meat.hpp deleted file mode 100644 index 93c09f280a..0000000000 --- a/src/mlpack/core/arma_extend/op_ccov_meat.hpp +++ /dev/null @@ -1,97 +0,0 @@ -//! \addtogroup op_cov -//! @{ - - - -template -inline -void -op_ccov::direct_ccov(Mat& out, const Mat& A, const uword norm_type) - { - arma_extra_debug_sigprint(); - - if(A.is_vec()) - { - if(A.n_rows == 1) - { - out = var(trans(A), norm_type); - } - else - { - out = var(A, norm_type); - } - } - else - { - const uword N = A.n_cols; - const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - - const Col acc = sum(A, 1); - - out = A * trans(A); - out -= (acc * trans(acc)) / eT(N); - out /= norm_val; - } - } - - - -template -inline -void -op_ccov::direct_ccov(Mat< std::complex >& out, const Mat< std::complex >& A, const uword norm_type) - { - arma_extra_debug_sigprint(); - - typedef typename std::complex eT; - - if(A.is_vec()) - { - if(A.n_rows == 1) - { - const Mat tmp_mat = var(trans(A), norm_type); - out.set_size(1,1); - out[0] = tmp_mat[0]; - } - else - { - const Mat tmp_mat = var(A, norm_type); - out.set_size(1,1); - out[0] = tmp_mat[0]; - } - } - else - { - const uword N = A.n_cols; - const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - - const Col acc = sum(A, 1); - - out = A * trans(conj(A)); - out -= (acc * trans(conj(acc))) / eT(N); - out /= norm_val; - } - } - - - -template -inline -void -op_ccov::apply(Mat& out, const Op& in) - { - arma_extra_debug_sigprint(); - - typedef typename T1::elem_type eT; - - const unwrap_check tmp(in.m, out); - const Mat& A = tmp.M; - - const uword norm_type = in.aux_uword_a; - - op_ccov::direct_ccov(out, A, norm_type); - } - - - -//! @} diff --git a/src/mlpack/core/arma_extend/op_ccov_proto.hpp b/src/mlpack/core/arma_extend/op_ccov_proto.hpp deleted file mode 100644 index 4fb49eb65a..0000000000 --- a/src/mlpack/core/arma_extend/op_ccov_proto.hpp +++ /dev/null @@ -1,18 +0,0 @@ -//! \addtogroup op_cov -//! @{ - - - -class op_ccov - { - public: - - template inline static void direct_ccov(Mat& out, const Mat& X, const uword norm_type); - template inline static void direct_ccov(Mat< std::complex >& out, const Mat< std::complex >& X, const uword norm_type); - - template inline static void apply(Mat& out, const Op& in); - }; - - - -//! @} diff --git a/src/mlpack/core/math/CMakeLists.txt b/src/mlpack/core/math/CMakeLists.txt index 5188956838..d63acd66fe 100644 --- a/src/mlpack/core/math/CMakeLists.txt +++ b/src/mlpack/core/math/CMakeLists.txt @@ -4,6 +4,7 @@ set(SOURCES clamp.hpp columns_to_blocks.hpp columns_to_blocks.cpp + ccov.hpp lin_alg.hpp lin_alg_impl.hpp lin_alg.cpp diff --git a/src/mlpack/core/math/ccov.hpp b/src/mlpack/core/math/ccov.hpp new file mode 100644 index 0000000000..345870925e --- /dev/null +++ b/src/mlpack/core/math/ccov.hpp @@ -0,0 +1,242 @@ +/** + * @file ccov.hpp + * @author Ryan Curtin + * @author Conrad Sanderson + * + * ccov(X) is same as cov(trans(X)) but without the cost of computing trans(X) + * + * mlpack is free software; you may redistribute it and/or modify it under the + * terms of the 3-clause BSD license. You should have received a copy of the + * 3-clause BSD license along with mlpack. If not, see + * http://www.opensource.org/licenses/BSD-3-Clause for more information. + */ +#ifndef MLPACK_CORE_MATH_CCOV_HPP +#define MLPACK_CORE_MATH_CCOV_HPP + +namespace mlpack { +namespace math /** Miscellaneous math routines. */ { + +template +inline +arma::Mat +ccov(const arma::Mat& A, const arma::uword norm_type = 0) +{ + if (norm_type > 1) + { + Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; + } + + arma::Mat out; + + if (A.is_vec()) + { + if (A.n_rows == 1) + { + out = arma::var(arma::trans(A), norm_type); + } + else + { + out = arma::var(A, norm_type); + } + } + else + { + const arma::uword N = A.n_cols; + const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + + const arma::Col acc = arma::sum(A, 1); + + out = A * arma::trans(A); + out -= (acc * arma::trans(acc)) / eT(N); + out /= norm_val; + } + + return out; +} + + + +template +inline +arma::Mat< std::complex > +ccov(const arma::Mat< std::complex >& A, const arma::uword norm_type = 0) +{ + if (norm_type > 1) + { + Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; + } + + typedef typename std::complex eT; + + arma::Mat out; + + if (A.is_vec()) + { + if (A.n_rows == 1) + { + const arma::Mat tmp_mat = arma::var(arma::trans(A), norm_type); + out.set_size(1,1); + out[0] = tmp_mat[0]; + } + else + { + const arma::Mat tmp_mat = arma::var(A, norm_type); + out.set_size(1,1); + out[0] = tmp_mat[0]; + } + } + else + { + const arma::uword N = A.n_cols; + const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + + const arma::Col acc = arma::sum(A, 1); + + out = A * arma::trans(arma::conj(A)); + out -= (acc * arma::trans(arma::conj(acc))) / eT(N); + out /= norm_val; + } + + return out; +} + + + +template +inline +arma::Mat +ccov(const arma::Mat& A, const arma::Mat& B, const arma::uword norm_type = 0) +{ + if (norm_type > 1) + { + Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; + } + + arma::Mat out; + + if (A.is_vec() && B.is_vec()) + { + if (A.n_elem != B.n_elem) + { + Log::Fatal << "ccov(): the number of elements in A and B must match" << std::endl; + } + + const eT* A_ptr = A.memptr(); + const eT* B_ptr = B.memptr(); + + eT A_acc = eT(0); + eT B_acc = eT(0); + eT out_acc = eT(0); + + const arma::uword N = A.n_elem; + + for (arma::uword i=0; i 1) ? eT(N-1) : eT(1) ) : eT(N); + + out.set_size(1,1); + out[0] = out_acc/norm_val; + } + else + { + if ( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) ) + { + Log::Fatal << "ccov(): size of A and B must match" << std::endl; + } + + const arma::uword N = A.n_cols; + const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + + out = A * arma::trans(B); + out -= (sum(A) * arma::trans(sum(B))) / eT(N); + out /= norm_val; + } + + return out; +} + + + +template +inline +arma::Mat< std::complex > +ccov(const arma::Mat< std::complex >& A, const arma::Mat< std::complex >& B, const arma::uword norm_type = 0) +{ + if (norm_type > 1) + { + Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; + } + + typedef typename std::complex eT; + + arma::Mat out; + + if (A.is_vec() && B.is_vec()) + { + if (A.n_elem != B.n_elem) + { + Log::Fatal << "ccov(): the number of elements in A and B must match" << std::endl; + } + + const eT* A_ptr = A.memptr(); + const eT* B_ptr = B.memptr(); + + eT A_acc = eT(0); + eT B_acc = eT(0); + eT out_acc = eT(0); + + const arma::uword N = A.n_elem; + + for (arma::uword i=0; i 1) ? eT(N-1) : eT(1) ) : eT(N); + + out.set_size(1,1); + out[0] = out_acc/norm_val; + } + else + { + if ( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) ) + { + Log::Fatal << "ccov(): size of A and B must match" << std::endl; + } + + const arma::uword N = A.n_cols; + const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + + out = A * arma::trans(arma::conj(B)); + out -= (sum(A) * arma::trans(arma::conj(arma::sum(B)))) / eT(N); + out /= norm_val; + } + + return out; +} + + +} // namespace math +} // namespace mlpack + + +#endif // MLPACK_CORE_MATH_CCOV_HPP diff --git a/src/mlpack/core/math/lin_alg.cpp b/src/mlpack/core/math/lin_alg.cpp index 915d1a36a9..677c3ac93c 100644 --- a/src/mlpack/core/math/lin_alg.cpp +++ b/src/mlpack/core/math/lin_alg.cpp @@ -12,6 +12,7 @@ #include "lin_alg.hpp" #include #include +#include using namespace mlpack; using namespace math; @@ -60,7 +61,7 @@ void mlpack::math::WhitenUsingSVD(const arma::mat& x, arma::mat covX, u, v, invSMatrix, temp1; arma::vec sVector; - covX = ccov(x); + covX = mlpack::math::ccov(x); svd(u, sVector, v, covX); @@ -85,7 +86,7 @@ void mlpack::math::WhitenUsingEig(const arma::mat& x, arma::vec eigenvalues; // Get eigenvectors of covariance of input matrix. - eig_sym(eigenvalues, eigenvectors, ccov(x)); + eig_sym(eigenvalues, eigenvectors, mlpack::math::ccov(x)); // Generate diagonal matrix using 1 / sqrt(eigenvalues) for each value. VectorPower(eigenvalues, -0.5); @@ -135,7 +136,7 @@ void mlpack::math::Orthogonalize(const arma::mat& x, arma::mat& W) // eigendecomposition of the matrix A. arma::mat eigenvalues, eigenvectors; arma::vec egval; - eig_sym(egval, eigenvectors, ccov(x)); + eig_sym(egval, eigenvectors, mlpack::math::ccov(x)); VectorPower(egval, -0.5); eigenvalues.zeros(egval.n_elem, egval.n_elem); diff --git a/src/mlpack/tests/distribution_test.cpp b/src/mlpack/tests/distribution_test.cpp index 7add802d9e..bb808a8ddc 100644 --- a/src/mlpack/tests/distribution_test.cpp +++ b/src/mlpack/tests/distribution_test.cpp @@ -15,6 +15,7 @@ * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ #include +#include #include #include @@ -461,7 +462,7 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionRandomTest) // Now make sure that reflects the actual distribution. arma::vec obsMean = arma::mean(obs, 1); - arma::mat obsCov = ccov(obs); + arma::mat obsCov = mlpack::math::ccov(obs); // 10% tolerance because this can be noisy. BOOST_REQUIRE_CLOSE(obsMean[0], mean[0], 10.0); @@ -496,7 +497,7 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionTrainTest) // Find actual mean and covariance of data. arma::vec actualMean = arma::mean(observations, 1); - arma::mat actualCov = ccov(observations); + arma::mat actualCov = mlpack::math::ccov(observations); d.Train(observations); @@ -1418,7 +1419,7 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionRandomTest) // Make sure that reflects the actual distribution. arma::vec obsMean = arma::mean(obs, 1); - arma::mat obsCov = arma::ccov(obs); + arma::mat obsCov = mlpack::math::ccov(obs); // 10% tolerance because this can be noisy. BOOST_REQUIRE_CLOSE(obsMean(0), mean(0), 10.0); @@ -1446,7 +1447,7 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionTrainTest) // Calculate the actual mean and covariance of data using armadillo. arma::vec actualMean = arma::mean(observations, 1); - arma::mat actualCov = arma::ccov(observations); + arma::mat actualCov = mlpack::math::ccov(observations); // Estimate the parameters. d.Train(observations); diff --git a/src/mlpack/tests/gmm_test.cpp b/src/mlpack/tests/gmm_test.cpp index fd8edd8d4e..c7c3050ab5 100644 --- a/src/mlpack/tests/gmm_test.cpp +++ b/src/mlpack/tests/gmm_test.cpp @@ -11,6 +11,7 @@ * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ #include +#include #include #include @@ -109,7 +110,8 @@ BOOST_AUTO_TEST_CASE(GMMTrainEMOneGaussian) gmm.Train(data, 10); arma::vec actualMean = arma::mean(data, 1); - arma::mat actualCovar = ccov(data, 1 /* biased estimator */); + arma::uword norm_type = 1; + arma::mat actualCovar = mlpack::math::ccov(data, norm_type /* biased estimator */); // Check the model to see that it is correct. BOOST_REQUIRE_LT(arma::norm(gmm.Component(0).Mean() - actualMean), 1e-5); @@ -198,7 +200,9 @@ BOOST_AUTO_TEST_CASE(GMMTrainEMMultipleGaussians) // Calculate the actual means and covariances because they will probably // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); - covars[i] = ccov(data.cols(point, point + counts[i] - 1), 1 /* biased */); + arma::uword norm_type = 1; + arma::mat sub = data.cols(point, point + counts[i] - 1); + covars[i] = mlpack::math::ccov(sub, norm_type /* biased */); point += counts[i]; } @@ -694,7 +698,9 @@ BOOST_AUTO_TEST_CASE(UseExistingModelTest) // Calculate the actual means and covariances because they will probably // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); - covars[i] = ccov(data.cols(point, point + counts[i] - 1), 1 /* biased */); + arma::uword norm_type = 1; + arma::mat sub = data.cols(point, point + counts[i] - 1); + covars[i] = mlpack::math::ccov(sub, norm_type /* biased */); point += counts[i]; } @@ -854,8 +860,9 @@ BOOST_AUTO_TEST_CASE(DiagonalGMMTrainEMOneGaussian) gmm.Train(data, 10); arma::vec actualMean = arma::mean(data, 1); + arma::uword norm_type = 1; arma::vec actualCovar = arma::diagvec( - arma::ccov(data, 1 /* biased estimator */)); + mlpack::math::ccov(data, norm_type /* biased estimator */)); // Check the model to see that it is correct. CheckMatrices(gmm.Component(0).Mean(), actualMean); diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 3b7f838f39..0aeb7a6e29 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -9,6 +9,7 @@ * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ #include +#include #include #include #include @@ -1381,7 +1382,7 @@ BOOST_AUTO_TEST_CASE(DiagonalGMMHMMOneGaussianOneStateTrainingTest) // Generate the ground truth values. arma::vec actualMean = arma::mean(observations[0], 1); arma::vec actualCovar = arma::diagvec( - arma::ccov(observations[0], 1 /* biased estimator */)); + mlpack::math::ccov(observations[0], arma::uword(1) /* biased estimator */)); // Check the model to see that it is correct. CheckMatrices(hmm.Emission()[0].Component(0).Mean(), actualMean); diff --git a/src/mlpack/tests/lin_alg_test.cpp b/src/mlpack/tests/lin_alg_test.cpp index 0e335049c9..b7dbc3c15f 100644 --- a/src/mlpack/tests/lin_alg_test.cpp +++ b/src/mlpack/tests/lin_alg_test.cpp @@ -13,6 +13,7 @@ */ #include #include +#include #include #include "test_tools.hpp" @@ -89,7 +90,7 @@ BOOST_AUTO_TEST_CASE(TestWhitenUsingEig) Center(tmp, tmp_centered); WhitenUsingEig(tmp_centered, whitened, whitening_matrix); - mat newcov = ccov(whitened); + mat newcov = mlpack::math::ccov(whitened); for (int row = 0; row < 5; row++) { for (int col = 0; col < 5; col++) @@ -118,7 +119,7 @@ BOOST_AUTO_TEST_CASE(TestOrthogonalize) Orthogonalize(tmp, orth); // test orthogonality - mat test = ccov(orth); + mat test = mlpack::math::ccov(orth); double ival = test(0, 0); for (size_t row = 0; row < test.n_rows; row++) { From 9f746d341e7101e3f5d3dd7c5d0da110418f0046 Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Tue, 9 Apr 2019 06:56:04 -0400 Subject: [PATCH 02/13] removed unwanted variables --- src/mlpack/tests/gmm_test.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/mlpack/tests/gmm_test.cpp b/src/mlpack/tests/gmm_test.cpp index c7c3050ab5..327d1ce619 100644 --- a/src/mlpack/tests/gmm_test.cpp +++ b/src/mlpack/tests/gmm_test.cpp @@ -110,8 +110,7 @@ BOOST_AUTO_TEST_CASE(GMMTrainEMOneGaussian) gmm.Train(data, 10); arma::vec actualMean = arma::mean(data, 1); - arma::uword norm_type = 1; - arma::mat actualCovar = mlpack::math::ccov(data, norm_type /* biased estimator */); + arma::mat actualCovar = mlpack::math::ccov(data, arma::uword(1) /* biased estimator */); // Check the model to see that it is correct. BOOST_REQUIRE_LT(arma::norm(gmm.Component(0).Mean() - actualMean), 1e-5); @@ -200,9 +199,8 @@ BOOST_AUTO_TEST_CASE(GMMTrainEMMultipleGaussians) // Calculate the actual means and covariances because they will probably // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); - arma::uword norm_type = 1; - arma::mat sub = data.cols(point, point + counts[i] - 1); - covars[i] = mlpack::math::ccov(sub, norm_type /* biased */); + covars[i] = mlpack::math::ccov(arma::mat(data.cols(point, point + counts[i] - 1)), + arma::uword(1) /* biased */); point += counts[i]; } @@ -698,9 +696,8 @@ BOOST_AUTO_TEST_CASE(UseExistingModelTest) // Calculate the actual means and covariances because they will probably // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); - arma::uword norm_type = 1; - arma::mat sub = data.cols(point, point + counts[i] - 1); - covars[i] = mlpack::math::ccov(sub, norm_type /* biased */); + covars[i] = mlpack::math::ccov(arma::mat(data.cols(point, point + counts[i] - 1)), + arma::uword(1) /* biased */); point += counts[i]; } @@ -860,9 +857,8 @@ BOOST_AUTO_TEST_CASE(DiagonalGMMTrainEMOneGaussian) gmm.Train(data, 10); arma::vec actualMean = arma::mean(data, 1); - arma::uword norm_type = 1; arma::vec actualCovar = arma::diagvec( - mlpack::math::ccov(data, norm_type /* biased estimator */)); + mlpack::math::ccov(data, arma::uword(1) /* biased estimator */)); // Check the model to see that it is correct. CheckMatrices(gmm.Component(0).Mean(), actualMean); From 3615ff368c3d31ba816b4d341f15179f45ed0c4a Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Wed, 10 Apr 2019 03:08:24 -0400 Subject: [PATCH 03/13] style changes --- src/mlpack/core/math/ccov.hpp | 81 ++++++++++++++++++++--------------- src/mlpack/tests/gmm_test.cpp | 11 ++--- src/mlpack/tests/hmm_test.cpp | 3 +- 3 files changed, 55 insertions(+), 40 deletions(-) diff --git a/src/mlpack/core/math/ccov.hpp b/src/mlpack/core/math/ccov.hpp index 345870925e..340d54d809 100644 --- a/src/mlpack/core/math/ccov.hpp +++ b/src/mlpack/core/math/ccov.hpp @@ -25,9 +25,9 @@ ccov(const arma::Mat& A, const arma::uword norm_type = 0) { Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; } - + arma::Mat out; - + if (A.is_vec()) { if (A.n_rows == 1) @@ -42,15 +42,16 @@ ccov(const arma::Mat& A, const arma::uword norm_type = 0) else { const arma::uword N = A.n_cols; - const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - + const eT norm_val = (norm_type == 0) ? + ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + const arma::Col acc = arma::sum(A, 1); - + out = A * arma::trans(A); out -= (acc * arma::trans(acc)) / eT(N); out /= norm_val; } - + return out; } @@ -59,36 +60,38 @@ ccov(const arma::Mat& A, const arma::uword norm_type = 0) template inline arma::Mat< std::complex > -ccov(const arma::Mat< std::complex >& A, const arma::uword norm_type = 0) +ccov(const arma::Mat< std::complex >& A, + const arma::uword norm_type = 0) { if (norm_type > 1) { Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; } - + typedef typename std::complex eT; - + arma::Mat out; - + if (A.is_vec()) { if (A.n_rows == 1) { const arma::Mat tmp_mat = arma::var(arma::trans(A), norm_type); - out.set_size(1,1); + out.set_size(1, 1); out[0] = tmp_mat[0]; } else { const arma::Mat tmp_mat = arma::var(A, norm_type); - out.set_size(1,1); + out.set_size(1, 1); out[0] = tmp_mat[0]; } } else { const arma::uword N = A.n_cols; - const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + const eT norm_val = (norm_type == 0) ? + ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); const arma::Col acc = arma::sum(A, 1); @@ -96,7 +99,7 @@ ccov(const arma::Mat< std::complex >& A, const arma::uword norm_type = 0) out -= (acc * arma::trans(arma::conj(acc))) / eT(N); out /= norm_val; } - + return out; } @@ -105,20 +108,23 @@ ccov(const arma::Mat< std::complex >& A, const arma::uword norm_type = 0) template inline arma::Mat -ccov(const arma::Mat& A, const arma::Mat& B, const arma::uword norm_type = 0) +ccov(const arma::Mat& A, + const arma::Mat& B, + const arma::uword norm_type = 0) { if (norm_type > 1) { Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; } - + arma::Mat out; if (A.is_vec() && B.is_vec()) { if (A.n_elem != B.n_elem) { - Log::Fatal << "ccov(): the number of elements in A and B must match" << std::endl; + Log::Fatal << "ccov(): the number of elements in A and B must match" + << std::endl; } const eT* A_ptr = A.memptr(); @@ -130,7 +136,7 @@ ccov(const arma::Mat& A, const arma::Mat& B, const arma::uword norm_type const arma::uword N = A.n_elem; - for (arma::uword i=0; i& A, const arma::Mat& B, const arma::uword norm_type out_acc += A_tmp * B_tmp; } - out_acc -= (A_acc * B_acc)/eT(N); + out_acc -= (A_acc * B_acc) / eT(N); - const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + const eT norm_val = (norm_type == 0) ? + ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - out.set_size(1,1); + out.set_size(1, 1); out[0] = out_acc/norm_val; } else @@ -154,15 +161,16 @@ ccov(const arma::Mat& A, const arma::Mat& B, const arma::uword norm_type { Log::Fatal << "ccov(): size of A and B must match" << std::endl; } - + const arma::uword N = A.n_cols; - const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + const eT norm_val = (norm_type == 0) ? + ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); out = A * arma::trans(B); out -= (sum(A) * arma::trans(sum(B))) / eT(N); out /= norm_val; } - + return out; } @@ -171,22 +179,25 @@ ccov(const arma::Mat& A, const arma::Mat& B, const arma::uword norm_type template inline arma::Mat< std::complex > -ccov(const arma::Mat< std::complex >& A, const arma::Mat< std::complex >& B, const arma::uword norm_type = 0) +ccov(const arma::Mat< std::complex >& A, + const arma::Mat< std::complex >& B, + const arma::uword norm_type = 0) { if (norm_type > 1) { Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; } - + typedef typename std::complex eT; - + arma::Mat out; if (A.is_vec() && B.is_vec()) { if (A.n_elem != B.n_elem) { - Log::Fatal << "ccov(): the number of elements in A and B must match" << std::endl; + Log::Fatal << "ccov(): the number of elements in A and B must match" + << std::endl; } const eT* A_ptr = A.memptr(); @@ -198,7 +209,7 @@ ccov(const arma::Mat< std::complex >& A, const arma::Mat< std::complex >& const arma::uword N = A.n_elem; - for (arma::uword i=0; i >& A, const arma::Mat< std::complex >& out_acc += std::conj(A_tmp) * B_tmp; } - out_acc -= (std::conj(A_acc) * B_acc)/eT(N); + out_acc -= (std::conj(A_acc) * B_acc) / eT(N); - const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + const eT norm_val = (norm_type == 0) ? + ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - out.set_size(1,1); + out.set_size(1, 1); out[0] = out_acc/norm_val; } else @@ -224,13 +236,14 @@ ccov(const arma::Mat< std::complex >& A, const arma::Mat< std::complex >& } const arma::uword N = A.n_cols; - const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + const eT norm_val = (norm_type == 0) ? + ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); out = A * arma::trans(arma::conj(B)); out -= (sum(A) * arma::trans(arma::conj(arma::sum(B)))) / eT(N); out /= norm_val; } - + return out; } diff --git a/src/mlpack/tests/gmm_test.cpp b/src/mlpack/tests/gmm_test.cpp index 327d1ce619..c254fbb1aa 100644 --- a/src/mlpack/tests/gmm_test.cpp +++ b/src/mlpack/tests/gmm_test.cpp @@ -110,7 +110,8 @@ BOOST_AUTO_TEST_CASE(GMMTrainEMOneGaussian) gmm.Train(data, 10); arma::vec actualMean = arma::mean(data, 1); - arma::mat actualCovar = mlpack::math::ccov(data, arma::uword(1) /* biased estimator */); + arma::mat actualCovar = mlpack::math::ccov(data, + arma::uword(1) /* biased estimator */); // Check the model to see that it is correct. BOOST_REQUIRE_LT(arma::norm(gmm.Component(0).Mean() - actualMean), 1e-5); @@ -199,8 +200,8 @@ BOOST_AUTO_TEST_CASE(GMMTrainEMMultipleGaussians) // Calculate the actual means and covariances because they will probably // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); - covars[i] = mlpack::math::ccov(arma::mat(data.cols(point, point + counts[i] - 1)), - arma::uword(1) /* biased */); + covars[i] = mlpack::math::ccov(arma::mat(data.cols(point, + point + counts[i] - 1)),arma::uword(1) /* biased */); point += counts[i]; } @@ -696,8 +697,8 @@ BOOST_AUTO_TEST_CASE(UseExistingModelTest) // Calculate the actual means and covariances because they will probably // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); - covars[i] = mlpack::math::ccov(arma::mat(data.cols(point, point + counts[i] - 1)), - arma::uword(1) /* biased */); + covars[i] = mlpack::math::ccov(arma::mat(data.cols(point, + point + counts[i] - 1)),arma::uword(1) /* biased */); point += counts[i]; } diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 0aeb7a6e29..686f48bd95 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -1382,7 +1382,8 @@ BOOST_AUTO_TEST_CASE(DiagonalGMMHMMOneGaussianOneStateTrainingTest) // Generate the ground truth values. arma::vec actualMean = arma::mean(observations[0], 1); arma::vec actualCovar = arma::diagvec( - mlpack::math::ccov(observations[0], arma::uword(1) /* biased estimator */)); + mlpack::math::ccov(observations[0], + arma::uword(1) /* biased estimator */)); // Check the model to see that it is correct. CheckMatrices(hmm.Emission()[0].Component(0).Mean(), actualMean); From 61cd506dde3ff819cdffd2c6a7618648c0bd5b88 Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Wed, 10 Apr 2019 03:12:50 -0400 Subject: [PATCH 04/13] removing unwanted spaces --- src/mlpack/core/math/ccov.hpp | 2 +- src/mlpack/tests/gmm_test.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/core/math/ccov.hpp b/src/mlpack/core/math/ccov.hpp index 340d54d809..1006dbddc2 100644 --- a/src/mlpack/core/math/ccov.hpp +++ b/src/mlpack/core/math/ccov.hpp @@ -196,7 +196,7 @@ ccov(const arma::Mat< std::complex >& A, { if (A.n_elem != B.n_elem) { - Log::Fatal << "ccov(): the number of elements in A and B must match" + Log::Fatal << "ccov(): the number of elements in A and B must match" << std::endl; } diff --git a/src/mlpack/tests/gmm_test.cpp b/src/mlpack/tests/gmm_test.cpp index c254fbb1aa..37be462c9c 100644 --- a/src/mlpack/tests/gmm_test.cpp +++ b/src/mlpack/tests/gmm_test.cpp @@ -201,7 +201,7 @@ BOOST_AUTO_TEST_CASE(GMMTrainEMMultipleGaussians) // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); covars[i] = mlpack::math::ccov(arma::mat(data.cols(point, - point + counts[i] - 1)),arma::uword(1) /* biased */); + point + counts[i] - 1)), arma::uword(1) /* biased */); point += counts[i]; } @@ -698,7 +698,7 @@ BOOST_AUTO_TEST_CASE(UseExistingModelTest) // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); covars[i] = mlpack::math::ccov(arma::mat(data.cols(point, - point + counts[i] - 1)),arma::uword(1) /* biased */); + point + counts[i] - 1)), arma::uword(1) /* biased */); point += counts[i]; } From 9eb31d872813e8b9077278ef763530b76c9ad5c7 Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Thu, 11 Apr 2019 18:43:11 -0400 Subject: [PATCH 05/13] changed ccov to ColumnCovariance --- src/mlpack/core/math/lin_alg.cpp | 7 +++---- src/mlpack/prereqs.hpp | 1 + src/mlpack/tests/distribution_test.cpp | 9 ++++----- src/mlpack/tests/gmm_test.cpp | 16 ++++++++-------- src/mlpack/tests/hmm_test.cpp | 5 ++--- src/mlpack/tests/lin_alg_test.cpp | 5 ++--- 6 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/mlpack/core/math/lin_alg.cpp b/src/mlpack/core/math/lin_alg.cpp index 677c3ac93c..79794a5a8a 100644 --- a/src/mlpack/core/math/lin_alg.cpp +++ b/src/mlpack/core/math/lin_alg.cpp @@ -12,7 +12,6 @@ #include "lin_alg.hpp" #include #include -#include using namespace mlpack; using namespace math; @@ -61,7 +60,7 @@ void mlpack::math::WhitenUsingSVD(const arma::mat& x, arma::mat covX, u, v, invSMatrix, temp1; arma::vec sVector; - covX = mlpack::math::ccov(x); + covX = mlpack::math::ColumnCovariance(x); svd(u, sVector, v, covX); @@ -86,7 +85,7 @@ void mlpack::math::WhitenUsingEig(const arma::mat& x, arma::vec eigenvalues; // Get eigenvectors of covariance of input matrix. - eig_sym(eigenvalues, eigenvectors, mlpack::math::ccov(x)); + eig_sym(eigenvalues, eigenvectors, mlpack::math::ColumnCovariance(x)); // Generate diagonal matrix using 1 / sqrt(eigenvalues) for each value. VectorPower(eigenvalues, -0.5); @@ -136,7 +135,7 @@ void mlpack::math::Orthogonalize(const arma::mat& x, arma::mat& W) // eigendecomposition of the matrix A. arma::mat eigenvalues, eigenvectors; arma::vec egval; - eig_sym(egval, eigenvectors, mlpack::math::ccov(x)); + eig_sym(egval, eigenvectors, mlpack::math::ColumnCovariance(x)); VectorPower(egval, -0.5); eigenvalues.zeros(egval.n_elem, egval.n_elem); diff --git a/src/mlpack/prereqs.hpp b/src/mlpack/prereqs.hpp index a8e0a70809..62fb162581 100644 --- a/src/mlpack/prereqs.hpp +++ b/src/mlpack/prereqs.hpp @@ -115,6 +115,7 @@ or upgrade Boost to 1.59 or newer. // All code should have access to logging. #include #include +#include // This can be removed with Visual Studio supports an OpenMP version with // unsigned loop variables. diff --git a/src/mlpack/tests/distribution_test.cpp b/src/mlpack/tests/distribution_test.cpp index bb808a8ddc..83ecda846e 100644 --- a/src/mlpack/tests/distribution_test.cpp +++ b/src/mlpack/tests/distribution_test.cpp @@ -15,7 +15,6 @@ * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ #include -#include #include #include @@ -462,7 +461,7 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionRandomTest) // Now make sure that reflects the actual distribution. arma::vec obsMean = arma::mean(obs, 1); - arma::mat obsCov = mlpack::math::ccov(obs); + arma::mat obsCov = mlpack::math::ColumnCovariance(obs); // 10% tolerance because this can be noisy. BOOST_REQUIRE_CLOSE(obsMean[0], mean[0], 10.0); @@ -497,7 +496,7 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionTrainTest) // Find actual mean and covariance of data. arma::vec actualMean = arma::mean(observations, 1); - arma::mat actualCov = mlpack::math::ccov(observations); + arma::mat actualCov = mlpack::math::ColumnCovariance(observations); d.Train(observations); @@ -1419,7 +1418,7 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionRandomTest) // Make sure that reflects the actual distribution. arma::vec obsMean = arma::mean(obs, 1); - arma::mat obsCov = mlpack::math::ccov(obs); + arma::mat obsCov = mlpack::math::ColumnCovariance(obs); // 10% tolerance because this can be noisy. BOOST_REQUIRE_CLOSE(obsMean(0), mean(0), 10.0); @@ -1447,7 +1446,7 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionTrainTest) // Calculate the actual mean and covariance of data using armadillo. arma::vec actualMean = arma::mean(observations, 1); - arma::mat actualCov = mlpack::math::ccov(observations); + arma::mat actualCov = mlpack::math::ColumnCovariance(observations); // Estimate the parameters. d.Train(observations); diff --git a/src/mlpack/tests/gmm_test.cpp b/src/mlpack/tests/gmm_test.cpp index 37be462c9c..8f1087c470 100644 --- a/src/mlpack/tests/gmm_test.cpp +++ b/src/mlpack/tests/gmm_test.cpp @@ -11,7 +11,6 @@ * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ #include -#include #include #include @@ -110,8 +109,8 @@ BOOST_AUTO_TEST_CASE(GMMTrainEMOneGaussian) gmm.Train(data, 10); arma::vec actualMean = arma::mean(data, 1); - arma::mat actualCovar = mlpack::math::ccov(data, - arma::uword(1) /* biased estimator */); + arma::mat actualCovar = mlpack::math::ColumnCovariance(data, + arma::size_t(1) /* biased estimator */); // Check the model to see that it is correct. BOOST_REQUIRE_LT(arma::norm(gmm.Component(0).Mean() - actualMean), 1e-5); @@ -200,8 +199,8 @@ BOOST_AUTO_TEST_CASE(GMMTrainEMMultipleGaussians) // Calculate the actual means and covariances because they will probably // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); - covars[i] = mlpack::math::ccov(arma::mat(data.cols(point, - point + counts[i] - 1)), arma::uword(1) /* biased */); + covars[i] = mlpack::math::ColumnCovariance(arma::mat(data.cols(point, + point + counts[i] - 1)), arma::size_t(1) /* biased */); point += counts[i]; } @@ -697,8 +696,8 @@ BOOST_AUTO_TEST_CASE(UseExistingModelTest) // Calculate the actual means and covariances because they will probably // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); - covars[i] = mlpack::math::ccov(arma::mat(data.cols(point, - point + counts[i] - 1)), arma::uword(1) /* biased */); + covars[i] = mlpack::math::ColumnCovariance(arma::mat(data.cols(point, + point + counts[i] - 1)), arma::size_t(1) /* biased */); point += counts[i]; } @@ -859,7 +858,8 @@ BOOST_AUTO_TEST_CASE(DiagonalGMMTrainEMOneGaussian) arma::vec actualMean = arma::mean(data, 1); arma::vec actualCovar = arma::diagvec( - mlpack::math::ccov(data, arma::uword(1) /* biased estimator */)); + mlpack::math::ColumnCovariance(data, + arma::size_t(1) /* biased estimator */)); // Check the model to see that it is correct. CheckMatrices(gmm.Component(0).Mean(), actualMean); diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 686f48bd95..e8a2d99c7d 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -9,7 +9,6 @@ * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ #include -#include #include #include #include @@ -1382,8 +1381,8 @@ BOOST_AUTO_TEST_CASE(DiagonalGMMHMMOneGaussianOneStateTrainingTest) // Generate the ground truth values. arma::vec actualMean = arma::mean(observations[0], 1); arma::vec actualCovar = arma::diagvec( - mlpack::math::ccov(observations[0], - arma::uword(1) /* biased estimator */)); + mlpack::math::ColumnCovariance(observations[0], + arma::size_t(1) /* biased estimator */)); // Check the model to see that it is correct. CheckMatrices(hmm.Emission()[0].Component(0).Mean(), actualMean); diff --git a/src/mlpack/tests/lin_alg_test.cpp b/src/mlpack/tests/lin_alg_test.cpp index b7dbc3c15f..cd1f3ced85 100644 --- a/src/mlpack/tests/lin_alg_test.cpp +++ b/src/mlpack/tests/lin_alg_test.cpp @@ -13,7 +13,6 @@ */ #include #include -#include #include #include "test_tools.hpp" @@ -90,7 +89,7 @@ BOOST_AUTO_TEST_CASE(TestWhitenUsingEig) Center(tmp, tmp_centered); WhitenUsingEig(tmp_centered, whitened, whitening_matrix); - mat newcov = mlpack::math::ccov(whitened); + mat newcov = mlpack::math::ColumnCovariance(whitened); for (int row = 0; row < 5; row++) { for (int col = 0; col < 5; col++) @@ -119,7 +118,7 @@ BOOST_AUTO_TEST_CASE(TestOrthogonalize) Orthogonalize(tmp, orth); // test orthogonality - mat test = mlpack::math::ccov(orth); + mat test = mlpack::math::ColumnCovariance(orth); double ival = test(0, 0); for (size_t row = 0; row < test.n_rows; row++) { From 0077a0dcdb38d69fd4ee5dc1eb21e18a7dba62bb Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Thu, 11 Apr 2019 19:10:03 -0400 Subject: [PATCH 06/13] added neccessary includes --- src/mlpack/core/math/ccov.hpp | 166 +++------------------------------- 1 file changed, 11 insertions(+), 155 deletions(-) diff --git a/src/mlpack/core/math/ccov.hpp b/src/mlpack/core/math/ccov.hpp index 1006dbddc2..1a8b85b0bd 100644 --- a/src/mlpack/core/math/ccov.hpp +++ b/src/mlpack/core/math/ccov.hpp @@ -3,7 +3,7 @@ * @author Ryan Curtin * @author Conrad Sanderson * - * ccov(X) is same as cov(trans(X)) but without the cost of computing trans(X) + * ColumnCovariance(X) is same as cov(trans(X)) but without the cost of computing trans(X) * * mlpack is free software; you may redistribute it and/or modify it under the * terms of the 3-clause BSD license. You should have received a copy of the @@ -13,17 +13,20 @@ #ifndef MLPACK_CORE_MATH_CCOV_HPP #define MLPACK_CORE_MATH_CCOV_HPP +#include +#include + namespace mlpack { namespace math /** Miscellaneous math routines. */ { template inline arma::Mat -ccov(const arma::Mat& A, const arma::uword norm_type = 0) +ColumnCovariance(const arma::Mat& A, const arma::size_t norm_type = 0) { if (norm_type > 1) { - Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; + Log::Fatal << "ColumnCovariance(): norm_type must be 0 or 1" << std::endl; } arma::Mat out; @@ -41,7 +44,7 @@ ccov(const arma::Mat& A, const arma::uword norm_type = 0) } else { - const arma::uword N = A.n_cols; + const arma::size_t N = A.n_cols; const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); @@ -55,17 +58,15 @@ ccov(const arma::Mat& A, const arma::uword norm_type = 0) return out; } - - template inline arma::Mat< std::complex > -ccov(const arma::Mat< std::complex >& A, - const arma::uword norm_type = 0) +ColumnCovariance(const arma::Mat< std::complex >& A, + const arma::size_t norm_type = 0) { if (norm_type > 1) { - Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; + Log::Fatal << "ColumnCovariance(): norm_type must be 0 or 1" << std::endl; } typedef typename std::complex eT; @@ -89,7 +90,7 @@ ccov(const arma::Mat< std::complex >& A, } else { - const arma::uword N = A.n_cols; + const arma::size_t N = A.n_cols; const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); @@ -103,151 +104,6 @@ ccov(const arma::Mat< std::complex >& A, return out; } - - -template -inline -arma::Mat -ccov(const arma::Mat& A, - const arma::Mat& B, - const arma::uword norm_type = 0) -{ - if (norm_type > 1) - { - Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; - } - - arma::Mat out; - - if (A.is_vec() && B.is_vec()) - { - if (A.n_elem != B.n_elem) - { - Log::Fatal << "ccov(): the number of elements in A and B must match" - << std::endl; - } - - const eT* A_ptr = A.memptr(); - const eT* B_ptr = B.memptr(); - - eT A_acc = eT(0); - eT B_acc = eT(0); - eT out_acc = eT(0); - - const arma::uword N = A.n_elem; - - for (arma::uword i = 0; i < N; ++i) - { - const eT A_tmp = A_ptr[i]; - const eT B_tmp = B_ptr[i]; - - A_acc += A_tmp; - B_acc += B_tmp; - - out_acc += A_tmp * B_tmp; - } - - out_acc -= (A_acc * B_acc) / eT(N); - - const eT norm_val = (norm_type == 0) ? - ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - - out.set_size(1, 1); - out[0] = out_acc/norm_val; - } - else - { - if ( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) ) - { - Log::Fatal << "ccov(): size of A and B must match" << std::endl; - } - - const arma::uword N = A.n_cols; - const eT norm_val = (norm_type == 0) ? - ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - - out = A * arma::trans(B); - out -= (sum(A) * arma::trans(sum(B))) / eT(N); - out /= norm_val; - } - - return out; -} - - - -template -inline -arma::Mat< std::complex > -ccov(const arma::Mat< std::complex >& A, - const arma::Mat< std::complex >& B, - const arma::uword norm_type = 0) -{ - if (norm_type > 1) - { - Log::Fatal << "ccov(): norm_type must be 0 or 1" << std::endl; - } - - typedef typename std::complex eT; - - arma::Mat out; - - if (A.is_vec() && B.is_vec()) - { - if (A.n_elem != B.n_elem) - { - Log::Fatal << "ccov(): the number of elements in A and B must match" - << std::endl; - } - - const eT* A_ptr = A.memptr(); - const eT* B_ptr = B.memptr(); - - eT A_acc = eT(0); - eT B_acc = eT(0); - eT out_acc = eT(0); - - const arma::uword N = A.n_elem; - - for (arma::uword i = 0; i < N; ++i) - { - const eT A_tmp = A_ptr[i]; - const eT B_tmp = B_ptr[i]; - - A_acc += A_tmp; - B_acc += B_tmp; - - out_acc += std::conj(A_tmp) * B_tmp; - } - - out_acc -= (std::conj(A_acc) * B_acc) / eT(N); - - const eT norm_val = (norm_type == 0) ? - ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - - out.set_size(1, 1); - out[0] = out_acc/norm_val; - } - else - { - if ( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) ) - { - Log::Fatal << "ccov(): size of A and B must match" << std::endl; - } - - const arma::uword N = A.n_cols; - const eT norm_val = (norm_type == 0) ? - ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - - out = A * arma::trans(arma::conj(B)); - out -= (sum(A) * arma::trans(arma::conj(arma::sum(B)))) / eT(N); - out /= norm_val; - } - - return out; -} - - } // namespace math } // namespace mlpack From d064dd17ddeaac593ba18c7cd1f2fee9110a44a0 Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Fri, 12 Apr 2019 00:38:54 -0400 Subject: [PATCH 07/13] blunder - chnaged arma::size_t to size_t --- src/mlpack/core/math/ccov.hpp | 8 ++++---- src/mlpack/tests/gmm_test.cpp | 8 ++++---- src/mlpack/tests/hmm_test.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mlpack/core/math/ccov.hpp b/src/mlpack/core/math/ccov.hpp index 1a8b85b0bd..402fbb19d7 100644 --- a/src/mlpack/core/math/ccov.hpp +++ b/src/mlpack/core/math/ccov.hpp @@ -22,7 +22,7 @@ namespace math /** Miscellaneous math routines. */ { template inline arma::Mat -ColumnCovariance(const arma::Mat& A, const arma::size_t norm_type = 0) +ColumnCovariance(const arma::Mat& A, const size_t norm_type = 0) { if (norm_type > 1) { @@ -44,7 +44,7 @@ ColumnCovariance(const arma::Mat& A, const arma::size_t norm_type = 0) } else { - const arma::size_t N = A.n_cols; + const size_t N = A.n_cols; const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); @@ -62,7 +62,7 @@ template inline arma::Mat< std::complex > ColumnCovariance(const arma::Mat< std::complex >& A, - const arma::size_t norm_type = 0) + const size_t norm_type = 0) { if (norm_type > 1) { @@ -90,7 +90,7 @@ ColumnCovariance(const arma::Mat< std::complex >& A, } else { - const arma::size_t N = A.n_cols; + const size_t N = A.n_cols; const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); diff --git a/src/mlpack/tests/gmm_test.cpp b/src/mlpack/tests/gmm_test.cpp index 8f1087c470..f0a523bdff 100644 --- a/src/mlpack/tests/gmm_test.cpp +++ b/src/mlpack/tests/gmm_test.cpp @@ -110,7 +110,7 @@ BOOST_AUTO_TEST_CASE(GMMTrainEMOneGaussian) arma::vec actualMean = arma::mean(data, 1); arma::mat actualCovar = mlpack::math::ColumnCovariance(data, - arma::size_t(1) /* biased estimator */); + 1 /* biased estimator */); // Check the model to see that it is correct. BOOST_REQUIRE_LT(arma::norm(gmm.Component(0).Mean() - actualMean), 1e-5); @@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(GMMTrainEMMultipleGaussians) // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); covars[i] = mlpack::math::ColumnCovariance(arma::mat(data.cols(point, - point + counts[i] - 1)), arma::size_t(1) /* biased */); + point + counts[i] - 1)), 1 /* biased */); point += counts[i]; } @@ -697,7 +697,7 @@ BOOST_AUTO_TEST_CASE(UseExistingModelTest) // be different (this is easier to do before we shuffle the points). means[i] = arma::mean(data.cols(point, point + counts[i] - 1), 1); covars[i] = mlpack::math::ColumnCovariance(arma::mat(data.cols(point, - point + counts[i] - 1)), arma::size_t(1) /* biased */); + point + counts[i] - 1)), 1 /* biased */); point += counts[i]; } @@ -859,7 +859,7 @@ BOOST_AUTO_TEST_CASE(DiagonalGMMTrainEMOneGaussian) arma::vec actualMean = arma::mean(data, 1); arma::vec actualCovar = arma::diagvec( mlpack::math::ColumnCovariance(data, - arma::size_t(1) /* biased estimator */)); + 1 /* biased estimator */)); // Check the model to see that it is correct. CheckMatrices(gmm.Component(0).Mean(), actualMean); diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index e8a2d99c7d..9f50469787 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -1382,7 +1382,7 @@ BOOST_AUTO_TEST_CASE(DiagonalGMMHMMOneGaussianOneStateTrainingTest) arma::vec actualMean = arma::mean(observations[0], 1); arma::vec actualCovar = arma::diagvec( mlpack::math::ColumnCovariance(observations[0], - arma::size_t(1) /* biased estimator */)); + 1 /* biased estimator */)); // Check the model to see that it is correct. CheckMatrices(hmm.Emission()[0].Component(0).Mean(), actualMean); From a7008a61b0633f3e8041c7bf7a6311e9b33be06c Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Fri, 12 Apr 2019 06:06:06 -0400 Subject: [PATCH 08/13] header include conflicts resolved --- src/mlpack/core.hpp | 1 + src/mlpack/core/math/CMakeLists.txt | 3 +- src/mlpack/core/math/ccov.hpp | 83 ++------------------- src/mlpack/core/math/ccov_impl.hpp | 110 ++++++++++++++++++++++++++++ src/mlpack/core/math/lin_alg.cpp | 2 +- src/mlpack/prereqs.hpp | 1 - 6 files changed, 119 insertions(+), 81 deletions(-) create mode 100644 src/mlpack/core/math/ccov_impl.hpp diff --git a/src/mlpack/core.hpp b/src/mlpack/core.hpp index 394dee7822..2c6beae534 100644 --- a/src/mlpack/core.hpp +++ b/src/mlpack/core.hpp @@ -81,6 +81,7 @@ #include #include #include +#include #include #include #include diff --git a/src/mlpack/core/math/CMakeLists.txt b/src/mlpack/core/math/CMakeLists.txt index d63acd66fe..6bacd597f8 100644 --- a/src/mlpack/core/math/CMakeLists.txt +++ b/src/mlpack/core/math/CMakeLists.txt @@ -4,7 +4,6 @@ set(SOURCES clamp.hpp columns_to_blocks.hpp columns_to_blocks.cpp - ccov.hpp lin_alg.hpp lin_alg_impl.hpp lin_alg.cpp @@ -19,6 +18,8 @@ set(SOURCES range_impl.hpp round.hpp shuffle_data.hpp + ccov.hpp + ccov_impl.hpp ) # add directory name to sources diff --git a/src/mlpack/core/math/ccov.hpp b/src/mlpack/core/math/ccov.hpp index 402fbb19d7..e24ce2663e 100644 --- a/src/mlpack/core/math/ccov.hpp +++ b/src/mlpack/core/math/ccov.hpp @@ -13,8 +13,7 @@ #ifndef MLPACK_CORE_MATH_CCOV_HPP #define MLPACK_CORE_MATH_CCOV_HPP -#include -#include +#include namespace mlpack { namespace math /** Miscellaneous math routines. */ { @@ -22,90 +21,18 @@ namespace math /** Miscellaneous math routines. */ { template inline arma::Mat -ColumnCovariance(const arma::Mat& A, const size_t norm_type = 0) -{ - if (norm_type > 1) - { - Log::Fatal << "ColumnCovariance(): norm_type must be 0 or 1" << std::endl; - } - - arma::Mat out; - - if (A.is_vec()) - { - if (A.n_rows == 1) - { - out = arma::var(arma::trans(A), norm_type); - } - else - { - out = arma::var(A, norm_type); - } - } - else - { - const size_t N = A.n_cols; - const eT norm_val = (norm_type == 0) ? - ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - - const arma::Col acc = arma::sum(A, 1); - - out = A * arma::trans(A); - out -= (acc * arma::trans(acc)) / eT(N); - out /= norm_val; - } - - return out; -} +ColumnCovariance(const arma::Mat& A, const size_t norm_type = 0); template inline arma::Mat< std::complex > ColumnCovariance(const arma::Mat< std::complex >& A, - const size_t norm_type = 0) -{ - if (norm_type > 1) - { - Log::Fatal << "ColumnCovariance(): norm_type must be 0 or 1" << std::endl; - } - - typedef typename std::complex eT; - - arma::Mat out; - - if (A.is_vec()) - { - if (A.n_rows == 1) - { - const arma::Mat tmp_mat = arma::var(arma::trans(A), norm_type); - out.set_size(1, 1); - out[0] = tmp_mat[0]; - } - else - { - const arma::Mat tmp_mat = arma::var(A, norm_type); - out.set_size(1, 1); - out[0] = tmp_mat[0]; - } - } - else - { - const size_t N = A.n_cols; - const eT norm_val = (norm_type == 0) ? - ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - - const arma::Col acc = arma::sum(A, 1); - - out = A * arma::trans(arma::conj(A)); - out -= (acc * arma::trans(arma::conj(acc))) / eT(N); - out /= norm_val; - } - - return out; -} + const size_t norm_type = 0); } // namespace math } // namespace mlpack +// Include implementation +#include "ccov_impl.hpp" #endif // MLPACK_CORE_MATH_CCOV_HPP diff --git a/src/mlpack/core/math/ccov_impl.hpp b/src/mlpack/core/math/ccov_impl.hpp new file mode 100644 index 0000000000..48d9cb7fa3 --- /dev/null +++ b/src/mlpack/core/math/ccov_impl.hpp @@ -0,0 +1,110 @@ +/** + * @file ccov_impl.hpp + * @author Ryan Curtin + * @author Conrad Sanderson + * + * ColumnCovariance(X) is same as cov(trans(X)) but without the cost of computing trans(X) + * + * mlpack is free software; you may redistribute it and/or modify it under the + * terms of the 3-clause BSD license. You should have received a copy of the + * 3-clause BSD license along with mlpack. If not, see + * http://www.opensource.org/licenses/BSD-3-Clause for more information. + */ +#ifndef MLPACK_CORE_MATH_CCOV_IMPL_HPP +#define MLPACK_CORE_MATH_CCOV_IMPL_HPP + +#include "ccov.hpp" + +namespace mlpack { +namespace math /** Miscellaneous math routines. */ { + +template +inline +arma::Mat +ColumnCovariance(const arma::Mat& A, const size_t norm_type) +{ + if (norm_type > 1) + { + Log::Fatal << "ColumnCovariance(): norm_type must be 0 or 1" << std::endl; + } + + arma::Mat out; + + if (A.is_vec()) + { + if (A.n_rows == 1) + { + out = arma::var(arma::trans(A), norm_type); + } + else + { + out = arma::var(A, norm_type); + } + } + else + { + const size_t N = A.n_cols; + const eT norm_val = (norm_type == 0) ? + ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + + const arma::Col acc = arma::sum(A, 1); + + out = A * arma::trans(A); + out -= (acc * arma::trans(acc)) / eT(N); + out /= norm_val; + } + + return out; +} + +template +inline +arma::Mat< std::complex > +ColumnCovariance(const arma::Mat< std::complex >& A, + const size_t norm_type) +{ + if (norm_type > 1) + { + Log::Fatal << "ColumnCovariance(): norm_type must be 0 or 1" << std::endl; + } + + typedef typename std::complex eT; + + arma::Mat out; + + if (A.is_vec()) + { + if (A.n_rows == 1) + { + const arma::Mat tmp_mat = arma::var(arma::trans(A), norm_type); + out.set_size(1, 1); + out[0] = tmp_mat[0]; + } + else + { + const arma::Mat tmp_mat = arma::var(A, norm_type); + out.set_size(1, 1); + out[0] = tmp_mat[0]; + } + } + else + { + const size_t N = A.n_cols; + const eT norm_val = (norm_type == 0) ? + ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + + const arma::Col acc = arma::sum(A, 1); + + out = A * arma::trans(arma::conj(A)); + out -= (acc * arma::trans(arma::conj(acc))) / eT(N); + out /= norm_val; + } + + return out; +} + +} // namespace math +} // namespace mlpack + + +#endif // MLPACK_CORE_MATH_CCOV_IMPL_HPP diff --git a/src/mlpack/core/math/lin_alg.cpp b/src/mlpack/core/math/lin_alg.cpp index 79794a5a8a..822625a59b 100644 --- a/src/mlpack/core/math/lin_alg.cpp +++ b/src/mlpack/core/math/lin_alg.cpp @@ -10,7 +10,7 @@ * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ #include "lin_alg.hpp" -#include +#include #include using namespace mlpack; diff --git a/src/mlpack/prereqs.hpp b/src/mlpack/prereqs.hpp index 62fb162581..a8e0a70809 100644 --- a/src/mlpack/prereqs.hpp +++ b/src/mlpack/prereqs.hpp @@ -115,7 +115,6 @@ or upgrade Boost to 1.59 or newer. // All code should have access to logging. #include #include -#include // This can be removed with Visual Studio supports an OpenMP version with // unsigned loop variables. From f886c457d8a7de2badcace7dd672b8317eb677dd Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Fri, 12 Apr 2019 06:58:06 -0400 Subject: [PATCH 09/13] wrapping up the comment acc to style guide --- src/mlpack/core/math/ccov.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mlpack/core/math/ccov.hpp b/src/mlpack/core/math/ccov.hpp index e24ce2663e..d2e24f8ed1 100644 --- a/src/mlpack/core/math/ccov.hpp +++ b/src/mlpack/core/math/ccov.hpp @@ -3,7 +3,8 @@ * @author Ryan Curtin * @author Conrad Sanderson * - * ColumnCovariance(X) is same as cov(trans(X)) but without the cost of computing trans(X) + * ColumnCovariance(X) is same as cov(trans(X)) but without the cost + * of computing trans(X) * * mlpack is free software; you may redistribute it and/or modify it under the * terms of the 3-clause BSD license. You should have received a copy of the From 8a3aa2d8b131835a4a6d120d29f9583e688cb779 Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Tue, 16 Apr 2019 18:47:23 +0530 Subject: [PATCH 10/13] fast ColumnCovariance --- src/mlpack/core/math/ccov_impl.hpp | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/mlpack/core/math/ccov_impl.hpp b/src/mlpack/core/math/ccov_impl.hpp index 48d9cb7fa3..0ba47b941e 100644 --- a/src/mlpack/core/math/ccov_impl.hpp +++ b/src/mlpack/core/math/ccov_impl.hpp @@ -30,27 +30,19 @@ ColumnCovariance(const arma::Mat& A, const size_t norm_type) arma::Mat out; - if (A.is_vec()) + if (A.n_elem > 0) { - if (A.n_rows == 1) - { - out = arma::var(arma::trans(A), norm_type); - } - else - { - out = arma::var(A, norm_type); - } - } - else - { - const size_t N = A.n_cols; + const arma::Mat& AA = (A.n_cols == 1) + ? arma::Mat(const_cast(A.memptr()), A.n_cols, A.n_rows, false, false) + : arma::Mat(const_cast(A.memptr()), A.n_rows, A.n_cols, false, false); + + const size_t N = AA.n_cols; const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - const arma::Col acc = arma::sum(A, 1); + const arma::Mat tmp = AA.each_col() - arma::mean(AA,1); - out = A * arma::trans(A); - out -= (acc * arma::trans(acc)) / eT(N); + out = tmp * tmp.t(); out /= norm_val; } From 54980fd64c2db3539ee65558e84bcf18309a2cff Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Tue, 16 Apr 2019 18:51:29 +0530 Subject: [PATCH 11/13] resolving style issues --- src/mlpack/core/math/ccov_impl.hpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/mlpack/core/math/ccov_impl.hpp b/src/mlpack/core/math/ccov_impl.hpp index 0ba47b941e..6d6fdbfa99 100644 --- a/src/mlpack/core/math/ccov_impl.hpp +++ b/src/mlpack/core/math/ccov_impl.hpp @@ -33,20 +33,21 @@ ColumnCovariance(const arma::Mat& A, const size_t norm_type) if (A.n_elem > 0) { const arma::Mat& AA = (A.n_cols == 1) - ? arma::Mat(const_cast(A.memptr()), A.n_cols, A.n_rows, false, false) - : arma::Mat(const_cast(A.memptr()), A.n_rows, A.n_cols, false, false); + ? arma::Mat(const_cast(A.memptr()), A.n_cols, A.n_rows, false, + false) : arma::Mat(const_cast(A.memptr()), A.n_rows, A.n_cols, + false, false); const size_t N = AA.n_cols; const eT norm_val = (norm_type == 0) ? ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); - const arma::Mat tmp = AA.each_col() - arma::mean(AA,1); + const arma::Mat tmp = AA.each_col() - arma::mean(AA, 1); out = tmp * tmp.t(); out /= norm_val; } - return out; + return out; } template From fc869c24aa30635dca5ceb12672093b90e7445ae Mon Sep 17 00:00:00 2001 From: jeffinsam Date: Tue, 16 Apr 2019 18:54:44 +0530 Subject: [PATCH 12/13] missed a space --- src/mlpack/core/math/ccov_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/core/math/ccov_impl.hpp b/src/mlpack/core/math/ccov_impl.hpp index 6d6fdbfa99..45880abd77 100644 --- a/src/mlpack/core/math/ccov_impl.hpp +++ b/src/mlpack/core/math/ccov_impl.hpp @@ -47,7 +47,7 @@ ColumnCovariance(const arma::Mat& A, const size_t norm_type) out /= norm_val; } - return out; + return out; } template From c45afea4ed5a817d16560a3af724fc7b8bd6830a Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 23 Apr 2019 13:25:23 -0400 Subject: [PATCH 13/13] Slight style cleanups. --- src/mlpack/core/math/ccov_impl.hpp | 65 ++++++++++++++---------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/src/mlpack/core/math/ccov_impl.hpp b/src/mlpack/core/math/ccov_impl.hpp index 45880abd77..1a9103f995 100644 --- a/src/mlpack/core/math/ccov_impl.hpp +++ b/src/mlpack/core/math/ccov_impl.hpp @@ -19,44 +19,42 @@ namespace mlpack { namespace math /** Miscellaneous math routines. */ { template -inline -arma::Mat -ColumnCovariance(const arma::Mat& A, const size_t norm_type) +inline arma::Mat ColumnCovariance(const arma::Mat& x, + const size_t normType) { - if (norm_type > 1) + if (normType > 1) { - Log::Fatal << "ColumnCovariance(): norm_type must be 0 or 1" << std::endl; + Log::Fatal << "ColumnCovariance(): norm_type must be 0 or 1!" << std::endl; } arma::Mat out; - if (A.n_elem > 0) + if (x.n_elem > 0) { - const arma::Mat& AA = (A.n_cols == 1) - ? arma::Mat(const_cast(A.memptr()), A.n_cols, A.n_rows, false, - false) : arma::Mat(const_cast(A.memptr()), A.n_rows, A.n_cols, - false, false); + const arma::Mat& xAlias = (x.n_cols == 1) ? + arma::Mat(const_cast(x.memptr()), x.n_cols, x.n_rows, false, + false) : + arma::Mat(const_cast(x.memptr()), x.n_rows, x.n_cols, false, + false); - const size_t N = AA.n_cols; - const eT norm_val = (norm_type == 0) ? - ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + const size_t n = xAlias.n_cols; + const eT normVal = (normType == 0) ? ((n > 1) ? eT(n - 1) : eT(1)) : eT(n); - const arma::Mat tmp = AA.each_col() - arma::mean(AA, 1); + const arma::Mat tmp = xAlias.each_col() - arma::mean(xAlias, 1); out = tmp * tmp.t(); - out /= norm_val; + out /= normVal; } return out; } template -inline -arma::Mat< std::complex > -ColumnCovariance(const arma::Mat< std::complex >& A, - const size_t norm_type) +inline arma::Mat> ColumnCovariance( + const arma::Mat>& x, + const size_t normType) { - if (norm_type > 1) + if (normType > 1) { Log::Fatal << "ColumnCovariance(): norm_type must be 0 or 1" << std::endl; } @@ -65,32 +63,32 @@ ColumnCovariance(const arma::Mat< std::complex >& A, arma::Mat out; - if (A.is_vec()) + if (x.is_vec()) { - if (A.n_rows == 1) + if (x.n_rows == 1) { - const arma::Mat tmp_mat = arma::var(arma::trans(A), norm_type); + const arma::Mat tmpMat = arma::var(arma::trans(x), normType); out.set_size(1, 1); - out[0] = tmp_mat[0]; + out[0] = tmpMat[0]; } else { - const arma::Mat tmp_mat = arma::var(A, norm_type); + const arma::Mat tmpMat = arma::var(x, normType); out.set_size(1, 1); - out[0] = tmp_mat[0]; + out[0] = tmpMat[0]; } } else { - const size_t N = A.n_cols; - const eT norm_val = (norm_type == 0) ? - ( (N > 1) ? eT(N-1) : eT(1) ) : eT(N); + const size_t n = x.n_cols; + const eT normVal = (normType == 0) ? + ((n > 1) ? eT(n - 1) : eT(1)) : eT(n); - const arma::Col acc = arma::sum(A, 1); + const arma::Col acc = arma::sum(x, 1); - out = A * arma::trans(arma::conj(A)); - out -= (acc * arma::trans(arma::conj(acc))) / eT(N); - out /= norm_val; + out = x * arma::trans(arma::conj(x)); + out -= (acc * arma::trans(arma::conj(acc))) / eT(n); + out /= normVal; } return out; @@ -99,5 +97,4 @@ ColumnCovariance(const arma::Mat< std::complex >& A, } // namespace math } // namespace mlpack - #endif // MLPACK_CORE_MATH_CCOV_IMPL_HPP