[mlpack-git] master: Add tests for FastMKSModel. (0f4fd99)

gitdub at big.cc.gt.atl.ga.us gitdub at big.cc.gt.atl.ga.us
Tue Dec 22 18:34:47 EST 2015


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

On branch  : master
Link       : https://github.com/mlpack/mlpack/compare/eb41f4bc27b484c347acc006255104e2f8cc4eef...977afbec0648056124dcb206e0bf972a161d9b51

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

commit 0f4fd9950a96eafb8a4757d56a34299d9f079335
Author: ryan <ryan at ratml.org>
Date:   Tue Dec 22 18:23:49 2015 -0500

    Add tests for FastMKSModel.


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

0f4fd9950a96eafb8a4757d56a34299d9f079335
 src/mlpack/tests/fastmks_test.cpp | 756 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 754 insertions(+), 2 deletions(-)

diff --git a/src/mlpack/tests/fastmks_test.cpp b/src/mlpack/tests/fastmks_test.cpp
index 0a659a9..dd9f84b 100644
--- a/src/mlpack/tests/fastmks_test.cpp
+++ b/src/mlpack/tests/fastmks_test.cpp
@@ -6,8 +6,7 @@
  */
 #include <mlpack/core.hpp>
 #include <mlpack/methods/fastmks/fastmks.hpp>
-#include <mlpack/core/kernels/linear_kernel.hpp>
-#include <mlpack/core/kernels/polynomial_kernel.hpp>
+#include <mlpack/methods/fastmks/fastmks_model.hpp>
 
 #include <boost/test/unit_test.hpp>
 #include "old_boost_test_definitions.hpp"
@@ -307,4 +306,757 @@ BOOST_AUTO_TEST_CASE(SerializationTest)
   CheckMatrices(kernels, xmlKernels, textKernels, binaryKernels);
 }
 
+// Make sure that we get an exception if we try to build the wrong FastMKSModel.
+BOOST_AUTO_TEST_CASE(FastMKSModelWrongModelTest)
+{
+  PolynomialKernel pk(2.0);
+  arma::mat data = arma::randu<arma::mat>(5, 5);
+
+  FastMKSModel m(FastMKSModel::LINEAR_KERNEL);
+  BOOST_REQUIRE_THROW(m.BuildModel(data, pk, false, false, 2.0),
+      std::invalid_argument);
+}
+
+// Test the linear kernel mode of the FastMKSModel.
+BOOST_AUTO_TEST_CASE(FastMKSModelLinearTest)
+{
+  LinearKernel lk;
+  arma::mat referenceData = arma::randu<arma::mat>(10, 100);
+
+  FastMKS<LinearKernel> f(referenceData, lk);
+
+  FastMKSModel m(FastMKSModel::LINEAR_KERNEL);
+  FastMKSModel mNaive(FastMKSModel::LINEAR_KERNEL);
+  FastMKSModel mSingle(FastMKSModel::LINEAR_KERNEL);
+
+  m.BuildModel(referenceData, lk, false, false, 2.0);
+  mNaive.BuildModel(referenceData, lk, false, true, 2.0);
+  mSingle.BuildModel(referenceData, lk, true, false, 2.0);
+
+  // Now search, first monochromatically.
+  arma::Mat<size_t> indices, mIndices, mNaiveIndices, mSingleIndices;
+  arma::mat kernels, mKernels, mNaiveKernels, mSingleKernels;
+
+  f.Search(3, indices, kernels);
+  m.Search(3, mIndices, mKernels);
+  mNaive.Search(3, mNaiveIndices, mNaiveKernels);
+  mSingle.Search(3, mSingleIndices, mSingleKernels);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+
+  // Now test with a different query set.
+  arma::mat querySet = arma::randu<arma::mat>(10, 50);
+
+  f.Search(querySet, 3, indices, kernels);
+  m.Search(querySet, 3, mIndices, mKernels, 2.0);
+  mNaive.Search(querySet, 3, mNaiveIndices, mNaiveKernels, 2.0);
+  mSingle.Search(querySet, 3, mSingleIndices, mSingleKernels, 2.0);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+}
+
+// Test the polynomial kernel mode of the FastMKSModel.
+BOOST_AUTO_TEST_CASE(FastMKSModelPolynomialTest)
+{
+  PolynomialKernel pk(2.0);
+  arma::mat referenceData = arma::randu<arma::mat>(10, 100);
+
+  FastMKS<PolynomialKernel> f(referenceData, pk);
+
+  FastMKSModel m(FastMKSModel::POLYNOMIAL_KERNEL);
+  FastMKSModel mNaive(FastMKSModel::POLYNOMIAL_KERNEL);
+  FastMKSModel mSingle(FastMKSModel::POLYNOMIAL_KERNEL);
+
+  m.BuildModel(referenceData, pk, false, false, 2.0);
+  mNaive.BuildModel(referenceData, pk, false, true, 2.0);
+  mSingle.BuildModel(referenceData, pk, true, false, 2.0);
+
+  // Now search, first monochromatically.
+  arma::Mat<size_t> indices, mIndices, mNaiveIndices, mSingleIndices;
+  arma::mat kernels, mKernels, mNaiveKernels, mSingleKernels;
+
+  f.Search(3, indices, kernels);
+  m.Search(3, mIndices, mKernels);
+  mNaive.Search(3, mNaiveIndices, mNaiveKernels);
+  mSingle.Search(3, mSingleIndices, mSingleKernels);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+
+  // Now test with a different query set.
+  arma::mat querySet = arma::randu<arma::mat>(10, 50);
+
+  f.Search(querySet, 3, indices, kernels);
+  m.Search(querySet, 3, mIndices, mKernels, 2.0);
+  mNaive.Search(querySet, 3, mNaiveIndices, mNaiveKernels, 2.0);
+  mSingle.Search(querySet, 3, mSingleIndices, mSingleKernels, 2.0);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+}
+
+// Test the cosine distance mode of the FastMKSModel.
+BOOST_AUTO_TEST_CASE(FastMKSModelCosineTest)
+{
+  CosineDistance ck;
+  arma::mat referenceData = arma::randu<arma::mat>(10, 100);
+
+  FastMKS<CosineDistance> f(referenceData, ck);
+
+  FastMKSModel m(FastMKSModel::COSINE_DISTANCE);
+  FastMKSModel mNaive(FastMKSModel::COSINE_DISTANCE);
+  FastMKSModel mSingle(FastMKSModel::COSINE_DISTANCE);
+
+  m.BuildModel(referenceData, ck, false, false, 2.0);
+  mNaive.BuildModel(referenceData, ck, false, true, 2.0);
+  mSingle.BuildModel(referenceData, ck, true, false, 2.0);
+
+  // Now search, first monochromatically.
+  arma::Mat<size_t> indices, mIndices, mNaiveIndices, mSingleIndices;
+  arma::mat kernels, mKernels, mNaiveKernels, mSingleKernels;
+
+  f.Search(3, indices, kernels);
+  m.Search(3, mIndices, mKernels);
+  mNaive.Search(3, mNaiveIndices, mNaiveKernels);
+  mSingle.Search(3, mSingleIndices, mSingleKernels);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+
+  // Now test with a different query set.
+  arma::mat querySet = arma::randu<arma::mat>(10, 50);
+
+  f.Search(querySet, 3, indices, kernels);
+  m.Search(querySet, 3, mIndices, mKernels, 2.0);
+  mNaive.Search(querySet, 3, mNaiveIndices, mNaiveKernels, 2.0);
+  mSingle.Search(querySet, 3, mSingleIndices, mSingleKernels, 2.0);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+}
+
+// Test the Gaussian kernel mode of the FastMKSModel.
+BOOST_AUTO_TEST_CASE(FastMKSModelCosineTest)
+{
+  GaussianKernel gk(1.5);
+  arma::mat referenceData = arma::randu<arma::mat>(10, 100);
+
+  FastMKS<GaussianKernel> f(referenceData, gk);
+
+  FastMKSModel m(FastMKSModel::GAUSSIAN_KERNEL);
+  FastMKSModel mNaive(FastMKSModel::GAUSSIAN_KERNEL);
+  FastMKSModel mSingle(FastMKSModel::GAUSSIAN_KERNEL);
+
+  m.BuildModel(referenceData, ck, false, false, 2.0);
+  mNaive.BuildModel(referenceData, ck, false, true, 2.0);
+  mSingle.BuildModel(referenceData, ck, true, false, 2.0);
+
+  // Now search, first monochromatically.
+  arma::Mat<size_t> indices, mIndices, mNaiveIndices, mSingleIndices;
+  arma::mat kernels, mKernels, mNaiveKernels, mSingleKernels;
+
+  f.Search(3, indices, kernels);
+  m.Search(3, mIndices, mKernels);
+  mNaive.Search(3, mNaiveIndices, mNaiveKernels);
+  mSingle.Search(3, mSingleIndices, mSingleKernels);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+
+  // Now test with a different query set.
+  arma::mat querySet = arma::randu<arma::mat>(10, 50);
+
+  f.Search(querySet, 3, indices, kernels);
+  m.Search(querySet, 3, mIndices, mKernels, 2.0);
+  mNaive.Search(querySet, 3, mNaiveIndices, mNaiveKernels, 2.0);
+  mSingle.Search(querySet, 3, mSingleIndices, mSingleKernels, 2.0);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+}
+
+// Test the Epanechnikov kernel mode of the FastMKSModel.
+BOOST_AUTO_TEST_CASE(FastMKSModelEpanTest)
+{
+  EpanechnikovKernel ek(2.5);
+  arma::mat referenceData = arma::randu<arma::mat>(10, 100);
+
+  FastMKS<EpanechnikovKernel> f(referenceData, ek);
+
+  FastMKSModel m(FastMKSModel::EPANECHNIKOV_KERNEL);
+  FastMKSModel mNaive(FastMKSModel::EPANECHNIKOV_KERNEL);
+  FastMKSModel mSingle(FastMKSModel::EPANECHNIKOV_KERNEL);
+
+  m.BuildModel(referenceData, ek, false, false, 2.0);
+  mNaive.BuildModel(referenceData, ek, false, true, 2.0);
+  mSingle.BuildModel(referenceData, ek, true, false, 2.0);
+
+  // Now search, first monochromatically.
+  arma::Mat<size_t> indices, mIndices, mNaiveIndices, mSingleIndices;
+  arma::mat kernels, mKernels, mNaiveKernels, mSingleKernels;
+
+  f.Search(3, indices, kernels);
+  m.Search(3, mIndices, mKernels);
+  mNaive.Search(3, mNaiveIndices, mNaiveKernels);
+  mSingle.Search(3, mSingleIndices, mSingleKernels);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+
+  // Now test with a different query set.
+  arma::mat querySet = arma::randu<arma::mat>(10, 50);
+
+  f.Search(querySet, 3, indices, kernels);
+  m.Search(querySet, 3, mIndices, mKernels, 2.0);
+  mNaive.Search(querySet, 3, mNaiveIndices, mNaiveKernels, 2.0);
+  mSingle.Search(querySet, 3, mSingleIndices, mSingleKernels, 2.0);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+}
+
+// Test the triangular kernel mode of the FastMKSModel.
+BOOST_AUTO_TEST_CASE(FastMKSModelTriangularTest)
+{
+  TriangularKernel tk(2.0);
+  arma::mat referenceData = arma::randu<arma::mat>(10, 100);
+
+  FastMKS<TriangularKernel> f(referenceData, ck);
+
+  FastMKSModel m(FastMKSModel::TRIANGULAR_KERNEL);
+  FastMKSModel mNaive(FastMKSModel::TRIANGULAR_KERNEL);
+  FastMKSModel mSingle(FastMKSModel::TRIANGULAR_KERNEL);
+
+  m.BuildModel(referenceData, tk, false, false, 2.0);
+  mNaive.BuildModel(referenceData, tk, false, true, 2.0);
+  mSingle.BuildModel(referenceData, tk, true, false, 2.0);
+
+  // Now search, first monochromatically.
+  arma::Mat<size_t> indices, mIndices, mNaiveIndices, mSingleIndices;
+  arma::mat kernels, mKernels, mNaiveKernels, mSingleKernels;
+
+  f.Search(3, indices, kernels);
+  m.Search(3, mIndices, mKernels);
+  mNaive.Search(3, mNaiveIndices, mNaiveKernels);
+  mSingle.Search(3, mSingleIndices, mSingleKernels);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+
+  // Now test with a different query set.
+  arma::mat querySet = arma::randu<arma::mat>(10, 50);
+
+  f.Search(querySet, 3, indices, kernels);
+  m.Search(querySet, 3, mIndices, mKernels, 2.0);
+  mNaive.Search(querySet, 3, mNaiveIndices, mNaiveKernels, 2.0);
+  mSingle.Search(querySet, 3, mSingleIndices, mSingleKernels, 2.0);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+}
+
+// Test the hyperbolic tangent kernel mode of the FastMKSModel.
+BOOST_AUTO_TEST_CASE(FastMKSModelHyptanTest)
+{
+  HyperbolicTangentKernel htk(1.0, 0.5);
+  arma::mat referenceData = arma::randu<arma::mat>(10, 100);
+
+  FastMKS<HyperbolicTangentKernel> f(referenceData, htk);
+
+  FastMKSModel m(FastMKSModel::HYPTAN_KERNEL);
+  FastMKSModel mNaive(FastMKSModel::HYPTAN_KERNEL);
+  FastMKSModel mSingle(FastMKSModel::HYPTAN_KERNEL);
+
+  m.BuildModel(referenceData, htk, false, false, 2.0);
+  mNaive.BuildModel(referenceData, htk, false, true, 2.0);
+  mSingle.BuildModel(referenceData, htk, true, false, 2.0);
+
+  // Now search, first monochromatically.
+  arma::Mat<size_t> indices, mIndices, mNaiveIndices, mSingleIndices;
+  arma::mat kernels, mKernels, mNaiveKernels, mSingleKernels;
+
+  f.Search(3, indices, kernels);
+  m.Search(3, mIndices, mKernels);
+  mNaive.Search(3, mNaiveIndices, mNaiveKernels);
+  mSingle.Search(3, mSingleIndices, mSingleKernels);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+
+  // Now test with a different query set.
+  arma::mat querySet = arma::randu<arma::mat>(10, 50);
+
+  f.Search(querySet, 3, indices, kernels);
+  m.Search(querySet, 3, mIndices, mKernels, 2.0);
+  mNaive.Search(querySet, 3, mNaiveIndices, mNaiveKernels, 2.0);
+  mSingle.Search(querySet, 3, mSingleIndices, mSingleKernels, 2.0);
+
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mNaiveIndices.n_cols);
+  BOOST_REQUIRE_EQUAL(indices.n_cols, mSingleIndices.n_cols);
+
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mNaiveIndices.n_rows);
+  BOOST_REQUIRE_EQUAL(indices.n_rows, mSingleIndices.n_rows);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mNaiveKernels.n_cols);
+  BOOST_REQUIRE_EQUAL(kernels.n_cols, mSingleKernels.n_cols);
+
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mNaiveKernels.n_rows);
+  BOOST_REQUIRE_EQUAL(kernels.n_rows, mSingleKernels.n_rows);
+
+  for (size_t i = 0; i < indices.n_elem; ++i)
+  {
+    BOOST_REQUIRE_EQUAL(indices[i], mIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mNaiveIndices[i]);
+    BOOST_REQUIRE_EQUAL(indices[i], mSingleIndices[i]);
+
+    if (std::abs(kernels[i]) < 1e-5)
+    {
+      BOOST_REQUIRE_SMALL(mKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_SMALL(mSingleKernels[i], 1e-5);
+    }
+    else
+    {
+      BOOST_REQUIRE_CLOSE(kernels[i], mKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mNaiveKernels[i], 1e-5);
+      BOOST_REQUIRE_CLOSE(kernels[i], mSingleKernels[i], 1e-5);
+    }
+  }
+}
+
 BOOST_AUTO_TEST_SUITE_END();



More information about the mlpack-git mailing list