diff --git a/.ci/ci.yaml b/.ci/ci.yaml index 89adaec398..b3153479cc 100644 --- a/.ci/ci.yaml +++ b/.ci/ci.yaml @@ -27,10 +27,6 @@ jobs: binding: 'go' go.version: '1.11.0' CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF' - R: - binding: 'R' - R.version: '4.0.0' - CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=ON' Markdown: CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_MARKDOWN_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' @@ -59,11 +55,6 @@ jobs: python.version: '2.7' go.version: '1.11.0' CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF' - R: - binding: 'R' - python.version: '2.7' - R.version: '4.0.0' - CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=ON' steps: - template: macos-steps.yaml diff --git a/.ci/linux-steps.yaml b/.ci/linux-steps.yaml index 84538f59b4..75cd4e2194 100644 --- a/.ci/linux-steps.yaml +++ b/.ci/linux-steps.yaml @@ -34,15 +34,6 @@ steps: sudo tar -C /opt/ -xvpf julia-1.3.0-linux-x86_64.tar.gz fi - if [ "$(binding)" == "R" ]; then - if [ "a$(R.version)" != "a" ]; then - sudo add-apt-repository 'deb https://cloud.r-project.org/bin/linux/ubuntu xenial-cran40/' - sudo apt-get -y update - sudo apt-get install -y r-base-core - fi - sudo Rscript -e "install.packages(c('Rcpp', 'RcppArmadillo', 'RcppEnsmallen', 'BH', 'roxygen2', 'testthat'))" - fi - # Install armadillo. curl https://data.kurg.org/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo* cmake . && make && sudo make install && cd .. diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index 09ee11f538..ac4441bb67 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -25,14 +25,6 @@ steps: brew cask install julia fi - if [ "$(binding)" == "R" ]; then - if [ "a$(R.version)" != "a" ]; then - brew cask install r - fi - brew cask install gfortran - Rscript -e "install.packages(c('Rcpp', 'RcppArmadillo', 'RcppEnsmallen', 'BH', 'roxygen2', 'testthat'), repos = 'http://cran.us.r-project.org')" - fi - git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf displayName: 'Install Build Dependencies' diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8640c26471..e40ceb91ca 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,7 @@ on: - master release: types: [published, created, edited] -name: R CMD check mlpack +name: mlpack.mlpack jobs: cancel: @@ -26,7 +26,7 @@ jobs: access_token: ${{ secrets.GITHUB_TOKEN }} jobR: - name: Build mlpack_r_tarball + name: mlpack R tarball if: ${{ github.repository == 'mlpack/mlpack' }} runs-on: ubuntu-20.04 @@ -78,11 +78,15 @@ jobs: - name: CMake run: | mkdir build - cd build && cmake -DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=ON .. + cd build && cmake -DDEBUG=OFF -DPROFILE=OFF -DBUILD_CLI_EXECUTABLES=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=ON .. - name: Build run: | - cd build && make R -j2 + cd build && make -j2 + + - name: Run tests via ctest + run: | + cd build && CTEST_OUTPUT_ON_FAILURE=1 ctest -T Test . - name: Upload R packages uses: actions/upload-artifact@v2 @@ -94,16 +98,16 @@ jobs: needs: jobR runs-on: ${{ matrix.config.os }} - name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + name: ${{ matrix.config.name }} if: ${{ github.repository == 'mlpack/mlpack' }} strategy: fail-fast: false matrix: config: - - {os: windows-latest, r: '4.0'} - - {os: macOS-latest, r: 'release'} - - {os: ubuntu-20.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"} + - {os: windows-latest, r: '4.0', name: 'Windows R'} + - {os: macOS-latest, r: 'release', name: 'macOS R'} + - {os: ubuntu-20.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest", name: 'Linux R'} env: @@ -151,4 +155,6 @@ jobs: uses: actions/upload-artifact@master with: name: ${{ runner.os }}-r${{ matrix.config.r }}-results - path: check + path: | + check/mlpack.Rcheck/00check.log + check/mlpack.Rcheck/00install.out diff --git a/CMakeLists.txt b/CMakeLists.txt index f041e321e6..8235d8fc29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -568,6 +568,7 @@ add_custom_target(mlpack_arma_config ALL COMMAND ${CMAKE_COMMAND} -D ARMADILLO_INCLUDE_DIR="${ARMADILLO_INCLUDE_DIR}" -D OPENMP_FOUND="${OPENMP_FOUND}" + -D CMAKE_SIZEOF_VOID_P="${CMAKE_SIZEOF_VOID_P}" -P CMake/CreateArmaConfigInfo.cmake WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Updating arma_config.hpp (if necessary)") diff --git a/HISTORY.md b/HISTORY.md index 5acdedcb4f..b839c8dc9e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,6 +4,8 @@ * Added Softmin activation function as layer in ann/layer. + * Fix spurious ARMA_64BIT_WORD compilation warnings on 32-bit systems (#2665). + ### mlpack 3.4.1 ###### 2020-09-07 * Fix incorrect parsing of required matrix/model parameters for command-line diff --git a/src/mlpack/bindings/R/print_R.cpp b/src/mlpack/bindings/R/print_R.cpp index bf047c2769..5b089cbd28 100644 --- a/src/mlpack/bindings/R/print_R.cpp +++ b/src/mlpack/bindings/R/print_R.cpp @@ -92,7 +92,8 @@ void PrintR(const util::BindingDetails& doc, cout << "#'" << endl; // Next, print information on the output options. - cout << "#' @return A list with several components:" << endl; + if (outputOptions.size() > 0) + cout << "#' @return A list with several components:" << endl; for (size_t i = 0; i < outputOptions.size(); ++i) { diff --git a/src/mlpack/bindings/R/print_doc_functions_impl.hpp b/src/mlpack/bindings/R/print_doc_functions_impl.hpp index 2273f83197..76b956812e 100644 --- a/src/mlpack/bindings/R/print_doc_functions_impl.hpp +++ b/src/mlpack/bindings/R/print_doc_functions_impl.hpp @@ -229,7 +229,9 @@ std::string ProgramCall(const bool markdown, // Find out if we have any output options first. std::ostringstream ossOutput; - oss << "output <- "; + ossOutput << PrintOutputOptions(markdown, args...); + if (ossOutput.str() != "") + oss << "output <- "; oss << programName << "("; // Now process each input option. diff --git a/src/mlpack/bindings/markdown/print_docs.cpp b/src/mlpack/bindings/markdown/print_docs.cpp index 5d8a55e140..10805e8209 100644 --- a/src/mlpack/bindings/markdown/print_docs.cpp +++ b/src/mlpack/bindings/markdown/print_docs.cpp @@ -166,15 +166,31 @@ void PrintDocs(const std::string& bindingName, } cout << endl; - // Next, iterate through the list of output options. - cout << "### Output options" << endl; - cout << endl; - string outputInfo = PrintOutputOptionInfo(); - if (outputInfo.size() > 0) - cout << outputInfo << endl; - cout << endl; - cout << "| ***name*** | ***type*** | ***description*** |" << endl; - cout << "|------------|------------|-------------------|" << endl; + // Determine if there are any output options, to see if we need + // to print the header of the output options table. + bool hasOutputOptions = false; + for (map::iterator it = parameters.begin(); + it != parameters.end(); ++it) + { + if (!it->second.input) + { + hasOutputOptions = true; + break; + } + } + + if (hasOutputOptions) + { + // Next, iterate through the list of output options. + cout << "### Output options" << endl; + cout << endl; + string outputInfo = PrintOutputOptionInfo(); + if (outputInfo.size() > 0) + cout << outputInfo << endl; + cout << endl; + cout << "| ***name*** | ***type*** | ***description*** |" << endl; + cout << "|------------|------------|-------------------|" << endl; + } for (map::iterator it = parameters.begin(); it != parameters.end(); ++it) { diff --git a/src/mlpack/methods/ann/layer/softmax_impl.hpp b/src/mlpack/methods/ann/layer/softmax_impl.hpp index 757431fa28..24fcec04b4 100644 --- a/src/mlpack/methods/ann/layer/softmax_impl.hpp +++ b/src/mlpack/methods/ann/layer/softmax_impl.hpp @@ -28,12 +28,12 @@ Softmax::Softmax() template template void Softmax::Forward( - const InputType& input, OutputType& output) + const InputType& input, + OutputType& output) { - InputType inputMax = arma::repmat(arma::max(input, 0), input.n_rows, 1); - output = inputMax + arma::log(arma::repmat( - arma::sum(arma::exp(input - inputMax), 0), input.n_rows, 1)); - output = arma::exp(input - output); + InputType softmaxInput = arma::exp(input.each_row() - + arma::max(input, 0)); + output = softmaxInput.each_row() / sum(softmaxInput, 0); } template diff --git a/src/mlpack/methods/ann/layer/softmin_impl.hpp b/src/mlpack/methods/ann/layer/softmin_impl.hpp index 7693ca11dd..686010a0e8 100644 --- a/src/mlpack/methods/ann/layer/softmin_impl.hpp +++ b/src/mlpack/methods/ann/layer/softmin_impl.hpp @@ -30,10 +30,9 @@ void Softmin::Forward( const InputType& input, OutputType& output) { - InputType inputMin = arma::repmat(arma::min(input,0), input.n_rows, 1); - output = arma::repmat(arma::log(arma::sum( - arma::exp(-(input - inputMin)),0)), input.n_rows, 1); - output = arma::exp(-(input - inputMin) - output); + InputType softminInput = arma::exp(-(input.each_row() - + arma::min(input, 0))); + output = softminInput.each_row() / sum(softminInput, 0); } template diff --git a/src/mlpack/tests/CMakeLists.txt b/src/mlpack/tests/CMakeLists.txt index 9f158c5037..562ec91e5d 100644 --- a/src/mlpack/tests/CMakeLists.txt +++ b/src/mlpack/tests/CMakeLists.txt @@ -1,30 +1,19 @@ # mlpack test executable. add_executable(mlpack_test - async_learning_test.cpp - augmented_rnns_tasks_test.cpp callback_test.cpp cf_test.cpp - cli_binding_test.cpp - io_test.cpp - cosine_tree_test.cpp dcgan_test.cpp - det_test.cpp - distribution_test.cpp drusilla_select_test.cpp emst_test.cpp fastmks_test.cpp facilities_test.cpp gan_test.cpp - hoeffding_tree_test.cpp hpt_test.cpp hyperplane_test.cpp init_rules_test.cpp kde_test.cpp krann_search_test.cpp ksinit_test.cpp - lars_test.cpp - layer_names_test.cpp - lin_alg_test.cpp linear_svm_test.cpp lmnn_test.cpp local_coordinate_coding_test.cpp @@ -34,13 +23,11 @@ add_executable(mlpack_test math_test.cpp matrix_completion_test.cpp maximal_inputs_test.cpp - metric_test.cpp mlpack_test.cpp mock_categorical_data.hpp nbc_test.cpp nmf_test.cpp nystroem_method_test.cpp - octree_test.cpp perceptron_test.cpp prefixedoutstream_test.cpp python_binding_test.cpp @@ -48,33 +35,21 @@ add_executable(mlpack_test qdafn_test.cpp radical_test.cpp random_test.cpp - range_search_test.cpp - rectangle_tree_test.cpp reward_clipping_test.cpp rl_components_test.cpp serialization.cpp serialization.hpp serialization_test.cpp - sfinae_test.cpp - sort_policy_test.cpp - spill_tree_test.cpp - string_encoding_test.cpp - sumtree_test.cpp termination_policy_test.cpp test_function_tools.hpp test_tools.hpp timer_test.cpp - tree_test.cpp - tree_traits_test.cpp - ub_tree_test.cpp union_find_test.cpp - vantage_point_tree_test.cpp wgan_test.cpp main_tests/cf_test.cpp main_tests/det_test.cpp main_tests/emst_test.cpp main_tests/fastmks_test.cpp - main_tests/hoeffding_tree_test.cpp main_tests/kde_test.cpp main_tests/krann_test.cpp main_tests/linear_svm_test.cpp @@ -86,7 +61,6 @@ add_executable(mlpack_test main_tests/nmf_test.cpp main_tests/perceptron_test.cpp main_tests/radical_test.cpp - main_tests/range_search_test.cpp main_tests/test_helper.hpp ) @@ -102,52 +76,76 @@ add_executable(mlpack_catch_test ann_visitor_test.cpp armadillo_svd_test.cpp arma_extend_test.cpp + async_learning_test.cpp + augmented_rnns_tasks_test.cpp bayesian_linear_regression_test.cpp bias_svd_test.cpp binarize_test.cpp block_krylov_svd_test.cpp + cli_binding_test.cpp convolutional_network_test.cpp convolution_test.cpp + cosine_tree_test.cpp cv_test.cpp dbscan_test.cpp decision_stump_test.cpp decision_tree_test.cpp + det_test.cpp + distribution_test.cpp gmm_test.cpp hmm_test.cpp feedforward_network_test.cpp + hoeffding_tree_test.cpp image_load_test.cpp imputation_test.cpp + io_test.cpp kernel_pca_test.cpp kernel_test.cpp kernel_traits_test.cpp kfn_test.cpp kmeans_test.cpp knn_test.cpp + lars_test.cpp + layer_names_test.cpp + lin_alg_test.cpp linear_regression_test.cpp load_save_test.cpp loss_functions_test.cpp main.cpp + metric_test.cpp mean_shift_test.cpp nca_test.cpp + octree_test.cpp one_hot_encoding_test.cpp pca_test.cpp quic_svd_test.cpp random_forest_test.cpp randomized_svd_test.cpp + range_search_test.cpp rbm_network_test.cpp + rectangle_tree_test.cpp recurrent_network_test.cpp regularized_svd_test.cpp scaling_test.cpp serialization_catch.cpp serialization_catch.hpp + sfinae_test.cpp softmax_regression_test.cpp + sort_policy_test.cpp sparse_autoencoder_test.cpp sparse_coding_test.cpp + spill_tree_test.cpp split_data_test.cpp + string_encoding_test.cpp + sumtree_test.cpp svd_batch_test.cpp svd_incremental_test.cpp svdplusplus_test.cpp test_catch_tools.hpp + tree_test.cpp + tree_traits_test.cpp + ub_tree_test.cpp + vantage_point_tree_test.cpp main_tests/adaboost_test.cpp main_tests/gmm_generate_test.cpp main_tests/gmm_probability_test.cpp @@ -162,6 +160,7 @@ add_executable(mlpack_catch_test main_tests/dbscan_test.cpp main_tests/decision_stump_test.cpp main_tests/decision_tree_test.cpp + main_tests/hoeffding_tree_test.cpp main_tests/image_converter_test.cpp main_tests/kernel_pca_test.cpp main_tests/kfn_test.cpp @@ -179,6 +178,7 @@ add_executable(mlpack_catch_test main_tests/random_forest_test.cpp main_tests/softmax_regression_test.cpp main_tests/sparse_coding_test.cpp + main_tests/range_search_test.cpp main_tests/test_helper.hpp ) @@ -227,10 +227,8 @@ add_custom_command(TARGET mlpack_test # The list of long running parallel tests set(parallel_tests - "AsyncLearningTest;" "LocalCoordinateCodingTest;" "CFTest;" - "LARSTest;" "LogisticRegressionTest;" "LinearSVMTest") diff --git a/src/mlpack/tests/async_learning_test.cpp b/src/mlpack/tests/async_learning_test.cpp index e3acc87add..4e8f03e9e3 100644 --- a/src/mlpack/tests/async_learning_test.cpp +++ b/src/mlpack/tests/async_learning_test.cpp @@ -24,17 +24,15 @@ #include -#include -#include "test_tools.hpp" +#include "catch.hpp" using namespace mlpack; using namespace mlpack::ann; using namespace mlpack::rl; -BOOST_AUTO_TEST_SUITE(AsyncLearningTest); // Test async one step q-learning in Cart Pole. -BOOST_AUTO_TEST_CASE(OneStepQLearningTest) +TEST_CASE("OneStepQLearningTest", "[AsyncLearningTest]") { /** * This is for the Travis CI server, in your own machine you should use more @@ -106,11 +104,11 @@ BOOST_AUTO_TEST_CASE(OneStepQLearningTest) } } - BOOST_REQUIRE_EQUAL(success, true); + REQUIRE(success == true); } // Test async one step Sarsa in Cart Pole. -BOOST_AUTO_TEST_CASE(OneStepSarsaTest) +TEST_CASE("OneStepSarsaTest", "[AsyncLearningTest]") { /** * This is for the Travis CI server, in your own machine you shuold use more @@ -184,11 +182,11 @@ BOOST_AUTO_TEST_CASE(OneStepSarsaTest) } } - BOOST_REQUIRE_EQUAL(success, true); + REQUIRE(success == true); } // Test async n step q-learning in Cart Pole. -BOOST_AUTO_TEST_CASE(NStepQLearningTest) +TEST_CASE("NStepQLearningTest", "[AsyncLearningTest]") { /** * This is for the Travis CI server, in your own machine you shuold use more @@ -233,7 +231,7 @@ BOOST_AUTO_TEST_CASE(NStepQLearningTest) { size_t maxEpisode = 100000; if (testEpisodes > maxEpisode) - BOOST_REQUIRE(false); + REQUIRE(false); testEpisodes++; rewards[pos++] = reward; pos %= rewards.n_elem; @@ -249,5 +247,3 @@ BOOST_AUTO_TEST_CASE(NStepQLearningTest) agent.Train(measure); Log::Debug << "Total test episodes: " << testEpisodes << std::endl; } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/augmented_rnns_tasks_test.cpp b/src/mlpack/tests/augmented_rnns_tasks_test.cpp index c8856a7570..17fd801394 100644 --- a/src/mlpack/tests/augmented_rnns_tasks_test.cpp +++ b/src/mlpack/tests/augmented_rnns_tasks_test.cpp @@ -22,8 +22,7 @@ #include #include -#include -#include "test_tools.hpp" +#include "catch.hpp" using std::vector; using std::pair; @@ -51,8 +50,10 @@ class HardCodedCopyModel size_t zeroCnt = 0, oneCnt = 0; for (size_t i = 1; i < input.n_rows; i += 2) { - size_t& addVar = (input.at(i, 0) == 0) ? zeroCnt : oneCnt; - ++addVar; + if (input.at(i, 0) == 0) + ++zeroCnt; + else + ++oneCnt; } assert(oneCnt % zeroCnt == 0); nRepeats = oneCnt / zeroCnt; @@ -158,7 +159,7 @@ class HardCodedAddModel predictors = predictors.t(); predictors.reshape(3, predictors.n_elem / 3); assert(predictors.n_rows == 3); - int num_A = 0, num_B = 0; + size_t num_A = 0, num_B = 0; bool num = false; // True iff we have already seen the separating symbol. size_t cnt = 0; for (size_t i = 0; i < predictors.n_cols; ++i) @@ -219,12 +220,11 @@ class HardCodedAddModel } }; -BOOST_AUTO_TEST_SUITE(AugmentedRNNsTasks); // Test of CopyTask instance generator. // The data from generator is fed to the dummy hard-coded model above // that should be able to solve the task perfectly. -BOOST_AUTO_TEST_CASE(CopyTaskTest) +TEST_CASE("CopyTaskTest", "[AugmentedRNNsTasks]") { // Check the setup on various lengths... for (size_t maxLen = 2; maxLen <= 16; ++maxLen) @@ -242,8 +242,7 @@ BOOST_AUTO_TEST_CASE(CopyTaskTest) arma::field predResponse; model.Predict(testPredictor, predResponse); // A single failure is a failure. - BOOST_REQUIRE_GE(SequencePrecision(testResponse, predResponse), - 0.99); + REQUIRE(SequencePrecision(testResponse, predResponse) >= 0.99); } } } @@ -251,7 +250,7 @@ BOOST_AUTO_TEST_CASE(CopyTaskTest) // Test of SortTask instance generator. // The data from generator is fed to the dummy hard-coded model above // that should be able to solve the task perfectly. -BOOST_AUTO_TEST_CASE(SortTaskTest) +TEST_CASE("SortTaskTest", "[AugmentedRNNsTasks]") { size_t bitLen = 5; for (size_t maxLen = 2; maxLen <= 16; ++maxLen) @@ -266,15 +265,14 @@ BOOST_AUTO_TEST_CASE(SortTaskTest) arma::field predResponse; model.Predict(testPredictor, predResponse); // A single failure is a failure. - BOOST_REQUIRE_GE(SequencePrecision(testResponse, predResponse), - 0.99); + REQUIRE(SequencePrecision(testResponse, predResponse) >= 0.99); } } // Test of AddTask instance generator. // The data from generator is fed to the dummy hard-coded model above // that should be able to solve the task perfectly. -BOOST_AUTO_TEST_CASE(AddTaskTest) +TEST_CASE("AddTaskTest", "[AugmentedRNNsTasks]") { for (size_t bitLen = 2; bitLen <= 16; ++bitLen) { @@ -288,9 +286,6 @@ BOOST_AUTO_TEST_CASE(AddTaskTest) arma::field predResponse; model.Predict(testPredictor, predResponse); // A single failure is a failure. - BOOST_REQUIRE_GE(SequencePrecision(testResponse, predResponse), - 0.99); + REQUIRE(SequencePrecision(testResponse, predResponse) >= 0.99); } } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/cli_binding_test.cpp b/src/mlpack/tests/cli_binding_test.cpp index bb21bf2ad1..391a0bfe1a 100644 --- a/src/mlpack/tests/cli_binding_test.cpp +++ b/src/mlpack/tests/cli_binding_test.cpp @@ -13,8 +13,8 @@ #include #include -#include -#include "test_tools.hpp" +#include "catch.hpp" +#include "test_catch_tools.hpp" using namespace std; using namespace mlpack; @@ -22,42 +22,40 @@ using namespace mlpack::bindings; using namespace mlpack::bindings::cli; using namespace mlpack::kernel; -BOOST_AUTO_TEST_SUITE(CLIBindingTest); - /** * Ensure that we can construct a CLIOption object, and that it will add itself * to the CLI instance. */ -BOOST_AUTO_TEST_CASE(CLIOptionTest) +TEST_CASE("CLIOptionTest", "[CLIOptionTest]") { IO::ClearSettings(); CLIOption co1(0.0, "test", "test2", "t", "double", false, true, false); // Now check that it's in CLI. - BOOST_REQUIRE_GT(IO::Parameters().count("test"), 0); - BOOST_REQUIRE_GT(IO::Aliases().count('t'), 0); - BOOST_REQUIRE_EQUAL(IO::Parameters()["test"].desc, "test2"); - BOOST_REQUIRE_EQUAL(IO::Parameters()["test"].name, "test"); - BOOST_REQUIRE_EQUAL(IO::Parameters()["test"].alias, 't'); - BOOST_REQUIRE_EQUAL(IO::Parameters()["test"].noTranspose, false); - BOOST_REQUIRE_EQUAL(IO::Parameters()["test"].required, false); - BOOST_REQUIRE_EQUAL(IO::Parameters()["test"].input, true); - BOOST_REQUIRE_EQUAL(IO::Parameters()["test"].cppType, "double"); + REQUIRE(IO::Parameters().count("test") > 0); + REQUIRE(IO::Aliases().count('t') > 0); + REQUIRE(IO::Parameters()["test"].desc == "test2"); + REQUIRE(IO::Parameters()["test"].name == "test"); + REQUIRE(IO::Parameters()["test"].alias == 't'); + REQUIRE(IO::Parameters()["test"].noTranspose == false); + REQUIRE(IO::Parameters()["test"].required == false); + REQUIRE(IO::Parameters()["test"].input == true); + REQUIRE(IO::Parameters()["test"].cppType == "double"); CLIOption co2(arma::mat(), "mat", "mat2", "m", "arma::mat", true, true, true); // Now check that it's in CLI. - BOOST_REQUIRE_GT(IO::Parameters().count("mat"), 0); - BOOST_REQUIRE_GT(IO::Aliases().count('m'), 0); - BOOST_REQUIRE_EQUAL(IO::Parameters()["mat"].desc, "mat2"); - BOOST_REQUIRE_EQUAL(IO::Parameters()["mat"].name, "mat"); - BOOST_REQUIRE_EQUAL(IO::Parameters()["mat"].alias, 'm'); - BOOST_REQUIRE_EQUAL(IO::Parameters()["mat"].noTranspose, true); - BOOST_REQUIRE_EQUAL(IO::Parameters()["mat"].required, true); - BOOST_REQUIRE_EQUAL(IO::Parameters()["mat"].input, true); - BOOST_REQUIRE_EQUAL(IO::Parameters()["mat"].cppType, "arma::mat"); + REQUIRE(IO::Parameters().count("mat") > 0); + REQUIRE(IO::Aliases().count('m') > 0); + REQUIRE(IO::Parameters()["mat"].desc == "mat2"); + REQUIRE(IO::Parameters()["mat"].name == "mat"); + REQUIRE(IO::Parameters()["mat"].alias == 'm'); + REQUIRE(IO::Parameters()["mat"].noTranspose == true); + REQUIRE(IO::Parameters()["mat"].required == true); + REQUIRE(IO::Parameters()["mat"].input == true); + REQUIRE(IO::Parameters()["mat"].cppType == "arma::mat"); IO::ClearSettings(); } @@ -65,7 +63,7 @@ BOOST_AUTO_TEST_CASE(CLIOptionTest) /** * Make sure GetParam() works. */ -BOOST_AUTO_TEST_CASE(GetParamDoubleTest) +TEST_CASE("GetParamDoubleTest", "[CLIOptionTest]") { util::ParamData d; double x = 5.0; @@ -75,10 +73,10 @@ BOOST_AUTO_TEST_CASE(GetParamDoubleTest) GetParam((util::ParamData&) d, (const void*) NULL, (void*) &output); - BOOST_REQUIRE_EQUAL(*output, 5.0); + REQUIRE(*output == 5.0); } -BOOST_AUTO_TEST_CASE(GetParamLoadedMatTest) +TEST_CASE("GetParamLoadedMatTest", "[CLIOptionTest]") { util::ParamData d; // Create value. @@ -94,13 +92,13 @@ BOOST_AUTO_TEST_CASE(GetParamLoadedMatTest) GetParam((util::ParamData&) d, (void*) NULL, (void*) &output); - BOOST_REQUIRE_EQUAL(output->n_rows, 5); - BOOST_REQUIRE_EQUAL(output->n_cols, 5); + REQUIRE(output->n_rows == 5); + REQUIRE(output->n_cols == 5); for (size_t i = 0; i < 25; ++i) - BOOST_REQUIRE_EQUAL((*output)[i], 1.0); + REQUIRE((*output)[i] == 1.0); } -BOOST_AUTO_TEST_CASE(GetParamUnloadedMatTest) +TEST_CASE("GetParamUnloadedMatTest", "[CLIOptionTest]") { util::ParamData d; // Create value. @@ -120,15 +118,15 @@ BOOST_AUTO_TEST_CASE(GetParamUnloadedMatTest) GetParam((util::ParamData&) d, (void*) NULL, (void*) &output); - BOOST_REQUIRE_EQUAL(output->n_rows, 5); - BOOST_REQUIRE_EQUAL(output->n_cols, 5); + REQUIRE(output->n_rows == 5); + REQUIRE(output->n_cols == 5); for (size_t i = 0; i < 25; ++i) - BOOST_REQUIRE_EQUAL((*output)[i], 1.0); + REQUIRE((*output)[i] == 1.0); remove("test.csv"); } -BOOST_AUTO_TEST_CASE(GetParamUmatTest) +TEST_CASE("GetParamUmatTest", "[CLIOptionTest]") { util::ParamData d; // Create value. @@ -145,13 +143,13 @@ BOOST_AUTO_TEST_CASE(GetParamUmatTest) GetParam>((util::ParamData&) d, (void*) NULL, (void*) &output); - BOOST_REQUIRE_EQUAL(output->n_rows, 5); - BOOST_REQUIRE_EQUAL(output->n_cols, 5); + REQUIRE(output->n_rows == 5); + REQUIRE(output->n_cols == 5); for (size_t i = 0; i < 25; ++i) - BOOST_REQUIRE_EQUAL((*output)[i], 1.0); + REQUIRE((*output)[i] == 1.0); } -BOOST_AUTO_TEST_CASE(GetParamUnloadedUmatTest) +TEST_CASE("GetParamUnloadedUmatTest", "[CLIOptionTest]") { util::ParamData d; // Create value. @@ -171,15 +169,15 @@ BOOST_AUTO_TEST_CASE(GetParamUnloadedUmatTest) GetParam>((util::ParamData&) d, (void*) NULL, (void*) &output); - BOOST_REQUIRE_EQUAL(output->n_rows, 5); - BOOST_REQUIRE_EQUAL(output->n_cols, 5); + REQUIRE(output->n_rows == 5); + REQUIRE(output->n_cols == 5); for (size_t i = 0; i < 25; ++i) - BOOST_REQUIRE_EQUAL((*output)[i], 1.0); + REQUIRE((*output)[i] == 1.0); remove("test.csv"); } -BOOST_AUTO_TEST_CASE(GetParamDatasetInfoMatTest) +TEST_CASE("GetParamDatasetInfoMatTest", "[CLIOptionTest]") { util::ParamData d; @@ -215,20 +213,20 @@ BOOST_AUTO_TEST_CASE(GetParamDatasetInfoMatTest) GetParam>((util::ParamData&) d, (void*) NULL, (void*) &output); - BOOST_REQUIRE_EQUAL(get<0>(*output).Dimensionality(), 3); - BOOST_REQUIRE_EQUAL((int) get<0>(*output).Type(0), + REQUIRE(get<0>(*output).Dimensionality() == 3); + REQUIRE((int) get<0>(*output).Type(0) == (int) data::Datatype::numeric); - BOOST_REQUIRE_EQUAL((int) get<0>(*output).Type(1), + REQUIRE((int) get<0>(*output).Type(1) == (int) data::Datatype::numeric); - BOOST_REQUIRE_EQUAL((int) get<0>(*output).Type(2), + REQUIRE((int) get<0>(*output).Type(2) == (int) data::Datatype::categorical); - BOOST_REQUIRE_EQUAL(get<1>(*output).n_rows, 3); - BOOST_REQUIRE_EQUAL(get<1>(*output).n_cols, 7); + REQUIRE(get<1>(*output).n_rows == 3); + REQUIRE(get<1>(*output).n_cols == 7); remove("test.csv"); } -BOOST_AUTO_TEST_CASE(GetParamModelTest) +TEST_CASE("GetParamModelTest", "[CLIOptionTest]") { util::ParamData d; @@ -249,13 +247,13 @@ BOOST_AUTO_TEST_CASE(GetParamModelTest) GetParam((util::ParamData&) d, (void*) NULL, (void*) &output); - BOOST_REQUIRE_EQUAL((*output)->Bandwidth(), 5.0); + REQUIRE((*output)->Bandwidth() == 5.0); remove("kernel.bin"); delete *output; } -BOOST_AUTO_TEST_CASE(RawParamDoubleTest) +TEST_CASE("RawParamDoubleTest", "[CLIOptionTest]") { // This should function the same as GetParam for doubles. util::ParamData d; @@ -266,10 +264,10 @@ BOOST_AUTO_TEST_CASE(RawParamDoubleTest) GetParam((util::ParamData&) d, (const void*) NULL, (void*) &output); - BOOST_REQUIRE_EQUAL(*output, 5.0); + REQUIRE(*output == 5.0); } -BOOST_AUTO_TEST_CASE(RawParamMatTest) +TEST_CASE("RawParamMatTest", "[CLIOptionTest]") { // This should return the matrix as-is without loading. util::ParamData d; @@ -286,13 +284,13 @@ BOOST_AUTO_TEST_CASE(RawParamMatTest) GetRawParam((util::ParamData&) d, (void*) NULL, (void*) &output); - BOOST_REQUIRE_EQUAL(output->n_rows, 5); - BOOST_REQUIRE_EQUAL(output->n_cols, 5); + REQUIRE(output->n_rows == 5); + REQUIRE(output->n_cols == 5); for (size_t i = 0; i < 25; ++i) - BOOST_REQUIRE_EQUAL((*output)[i], 1.0); + REQUIRE((*output)[i] == 1.0); } -BOOST_AUTO_TEST_CASE(GetRawParamModelTest) +TEST_CASE("GetRawParamModelTest", "[CLIOptionTest]") { util::ParamData d; @@ -311,10 +309,10 @@ BOOST_AUTO_TEST_CASE(GetRawParamModelTest) GetRawParam>((util::ParamData&) d, (void*) NULL, (void*) &output); - BOOST_REQUIRE_EQUAL(get<0>(*output)->Bandwidth(), 5.0); + REQUIRE(get<0>(*output)->Bandwidth() == 5.0); } -BOOST_AUTO_TEST_CASE(GetRawParamDatasetInfoTest) +TEST_CASE("GetRawParamDatasetInfoTest", "[CLIOptionTest]") { util::ParamData d; @@ -339,13 +337,13 @@ BOOST_AUTO_TEST_CASE(GetRawParamDatasetInfoTest) GetRawParam>((util::ParamData&) d, (void*) NULL, (void*) &output); - BOOST_REQUIRE_EQUAL(get<0>(*output).Dimensionality(), 3); - BOOST_REQUIRE_EQUAL(get<1>(*output).n_rows, 3); - BOOST_REQUIRE_EQUAL(get<1>(*output).n_cols, 3); + REQUIRE(get<0>(*output).Dimensionality() == 3); + REQUIRE(get<1>(*output).n_rows == 3); + REQUIRE(get<1>(*output).n_cols == 3); } // Check that we can successfully write a matrix to file. -BOOST_AUTO_TEST_CASE(OutputParamMatTest) +TEST_CASE("OutputParamMatTest", "[CLIOptionTest]") { util::ParamData d; @@ -363,7 +361,7 @@ BOOST_AUTO_TEST_CASE(OutputParamMatTest) (void*) NULL); arma::mat m2; - BOOST_REQUIRE(data::Load("test.csv", m2)); + REQUIRE(data::Load("test.csv", m2)); CheckMatrices(m, m2); @@ -371,7 +369,7 @@ BOOST_AUTO_TEST_CASE(OutputParamMatTest) } // Check that we can successfully write an unsigned matrix to file. -BOOST_AUTO_TEST_CASE(OutputParamUmatTest) +TEST_CASE("OutputParamUmatTest", "[CLIOptionTest]") { util::ParamData d; @@ -389,7 +387,7 @@ BOOST_AUTO_TEST_CASE(OutputParamUmatTest) (void*) NULL); arma::Mat m2; - BOOST_REQUIRE(data::Load("test.csv", m2)); + REQUIRE(data::Load("test.csv", m2)); CheckMatrices(m, m2); @@ -397,7 +395,7 @@ BOOST_AUTO_TEST_CASE(OutputParamUmatTest) } // Check that we can successfully write a model to file. -BOOST_AUTO_TEST_CASE(OutputParamModelTest) +TEST_CASE("OutputParamModelTest", "[CLIOptionTest]") { util::ParamData d; @@ -414,15 +412,15 @@ BOOST_AUTO_TEST_CASE(OutputParamModelTest) (void*) NULL); GaussianKernel gk2(1.0); - BOOST_REQUIRE(data::Load("kernel.bin", "model", gk2)); + REQUIRE(data::Load("kernel.bin", "model", gk2)); - BOOST_REQUIRE_EQUAL(gk.Bandwidth(), gk2.Bandwidth()); + REQUIRE(gk.Bandwidth() == gk2.Bandwidth()); remove("kernel.bin"); } // Test setting a primitive type parameter. -BOOST_AUTO_TEST_CASE(SetParamDoubleTest) +TEST_CASE("SetParamDoubleTest", "[CLIOptionTest]") { util::ParamData d; @@ -440,11 +438,11 @@ BOOST_AUTO_TEST_CASE(SetParamDoubleTest) GetParam((util::ParamData&) d, (const void*) NULL, (void*) &dd3); - BOOST_REQUIRE_EQUAL((*dd3), dd2); + REQUIRE((*dd3) == dd2); } // Test that setting a flag works. -BOOST_AUTO_TEST_CASE(SetParamBoolTest) +TEST_CASE("SetParamBoolTest", "[CLIOptionTest]") { util::ParamData d; @@ -458,11 +456,11 @@ BOOST_AUTO_TEST_CASE(SetParamBoolTest) boost::any a(b2); SetParam((util::ParamData&) d, (const void*) &a, (void*) NULL); - BOOST_REQUIRE_EQUAL(boost::any_cast(d.value), true); + REQUIRE(boost::any_cast(d.value) == true); } // Test that calling SetParam on a matrix sets the string correctly. -BOOST_AUTO_TEST_CASE(SetParamMatrixTest) +TEST_CASE("SetParamMatrixTest", "[CLIOptionTest]") { util::ParamData d; @@ -481,11 +479,11 @@ BOOST_AUTO_TEST_CASE(SetParamMatrixTest) // Make sure the change went through. tuple& t = *boost::any_cast>(&d.value); - BOOST_REQUIRE_EQUAL(get<1>(t), "new.csv"); + REQUIRE(get<1>(t) == "new.csv"); } // Test that calling SetParam on a model sets the string correctly. -BOOST_AUTO_TEST_CASE(SetParamModelTest) +TEST_CASE("SetParamModelTest", "[CLIOptionTest]") { util::ParamData d; @@ -505,12 +503,12 @@ BOOST_AUTO_TEST_CASE(SetParamModelTest) tuple& t = *boost::any_cast>(&d.value); - BOOST_REQUIRE_EQUAL(get<1>(t), "new_kernel.bin"); + REQUIRE(get<1>(t) == "new_kernel.bin"); } // Test that calling SetParam on a mat/DatasetInfo successfully sets the // filename. -BOOST_AUTO_TEST_CASE(SetParamDatasetInfoMatTest) +TEST_CASE("SetParamDatasetInfoMatTest", "[CLIOptionTest]") { util::ParamData d; @@ -535,12 +533,12 @@ BOOST_AUTO_TEST_CASE(SetParamDatasetInfoMatTest) tuple, string>& t3 = *boost::any_cast, string>>(&d.value); - BOOST_REQUIRE_EQUAL(get<1>(t3), "new_filename.csv"); + REQUIRE(get<1>(t3) == "new_filename.csv"); } // Test that GetAllocatedMemory() will properly return NULL for a non-model // type. -BOOST_AUTO_TEST_CASE(GetAllocatedMemoryNonModelTest) +TEST_CASE("GetAllocatedMemoryNonModelTest", "[CLIOptionTest]") { util::ParamData d; @@ -553,7 +551,7 @@ BOOST_AUTO_TEST_CASE(GetAllocatedMemoryNonModelTest) GetAllocatedMemory((util::ParamData&) d, (const void*) NULL, (void*) &result); - BOOST_REQUIRE_EQUAL(result, (void*) NULL); + REQUIRE(result == (void*) NULL); // Also test with a matrix type. arma::mat test(10, 10, arma::fill::ones); @@ -566,12 +564,12 @@ BOOST_AUTO_TEST_CASE(GetAllocatedMemoryNonModelTest) GetAllocatedMemory((util::ParamData&) d, (const void*) NULL, (void*) &result); - BOOST_REQUIRE_EQUAL(result, (void*) NULL); + REQUIRE(result == (void*) NULL); } // Test that GetAllocatedMemory() will properly return pointers for a // serializable model type. -BOOST_AUTO_TEST_CASE(GetAllocatedMemoryModelTest) +TEST_CASE("GetAllocatedMemoryModelTest", "[CLIOptionTest]") { util::ParamData d; @@ -586,12 +584,12 @@ BOOST_AUTO_TEST_CASE(GetAllocatedMemoryModelTest) GetAllocatedMemory((util::ParamData&) d, (const void*) NULL, (void*) &result); - BOOST_REQUIRE_EQUAL(&g, (GaussianKernel*) result); + REQUIRE(&g == (GaussianKernel*) result); } // Test that calling DeleteAllocatedMemory() on non-model types does not delete // pointers. -BOOST_AUTO_TEST_CASE(DeleteAllocatedMemoryNonModelTest) +TEST_CASE("DeleteAllocatedMemoryNonModelTest", "[CLIOptionTest]") { util::ParamData d; @@ -613,7 +611,7 @@ BOOST_AUTO_TEST_CASE(DeleteAllocatedMemoryNonModelTest) // Test that DeleteAllocatedMemory() will properly delete pointers for a // serializable model type. -BOOST_AUTO_TEST_CASE(DeleteAllocatedMemoryModelTest) +TEST_CASE("DeleteAllocatedMemoryModelTest", "[CLIOptionTest]") { // This test will just delete it, and we'll hope that it worked and that // valgrind won't throw any issues (so really we can't *quite* test this in @@ -630,5 +628,3 @@ BOOST_AUTO_TEST_CASE(DeleteAllocatedMemoryModelTest) DeleteAllocatedMemory((util::ParamData&) d, (const void*) NULL, (void*) NULL); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/cosine_tree_test.cpp b/src/mlpack/tests/cosine_tree_test.cpp index a08ee7f254..66c6f08fcd 100644 --- a/src/mlpack/tests/cosine_tree_test.cpp +++ b/src/mlpack/tests/cosine_tree_test.cpp @@ -13,10 +13,8 @@ #include #include -#include -#include "test_tools.hpp" - -BOOST_AUTO_TEST_SUITE(CosineTreeTest); +#include "catch.hpp" +#include "test_catch_tools.hpp" using namespace mlpack; using namespace mlpack::tree; @@ -25,7 +23,7 @@ using namespace mlpack::tree; * Constructs a cosine tree with epsilon = 1. Checks if the root node is split * further, as it shouldn't be. */ -BOOST_AUTO_TEST_CASE(CosineTreeNoSplit) +TEST_CASE("CosineTreeNoSplit", "[CosineTreeTest]") { // Initialize constants required for the test. const size_t numRows = 10; @@ -44,14 +42,14 @@ BOOST_AUTO_TEST_CASE(CosineTreeNoSplit) // Since epsilon is one, there should be no splitting and the only vector in // the basis should come from the root node. - BOOST_REQUIRE_EQUAL(basis.n_cols, 1); + REQUIRE(basis.n_cols == 1); } /** * Checks CosineTree::CosineNodeSplit() by doing a depth first search on a * random dataset and checking if it satisfies the split condition. */ -BOOST_AUTO_TEST_CASE(CosineNodeCosineSplit) +TEST_CASE("CosineNodeCosineSplit", "[CosineTreeTest]") { // Initialize constants required for the test. const size_t numRows = 500; @@ -96,7 +94,7 @@ BOOST_AUTO_TEST_CASE(CosineNodeCosineSplit) rightIndices = currentRight->VectorIndices(); // The columns in the popped should be split into left and right nodes. - BOOST_REQUIRE_EQUAL(currentNode->NumColumns(), leftIndices.size() + + REQUIRE(currentNode->NumColumns() == leftIndices.size() + rightIndices.size()); // Calculate the cosine values for each of the columns in the node. @@ -125,12 +123,10 @@ BOOST_AUTO_TEST_CASE(CosineNodeCosineSplit) { // Check with some precision. for (i = 0; i < leftIndices.size(); ++i) - BOOST_REQUIRE_LT(cosineMax - cosines(i), - cosines(i) - cosineMin + precision); + REQUIRE(cosineMax - cosines(i) < cosines(i) - cosineMin + precision); for (j = 0, k = i; j < rightIndices.size(); ++j, ++k) - BOOST_REQUIRE_GT(cosineMax - cosines(k), - cosines(k) - cosineMin - precision); + REQUIRE(cosineMax - cosines(k) > cosines(k) - cosineMin - precision); } else { @@ -156,7 +152,7 @@ BOOST_AUTO_TEST_CASE(CosineNodeCosineSplit) numMax2Errors++; // One of the maximum cosine values should be correct - BOOST_REQUIRE_EQUAL(std::min(numMax1Errors, numMax2Errors), 0); + REQUIRE(std::min(numMax1Errors, numMax2Errors) == 0); } } } @@ -166,7 +162,7 @@ BOOST_AUTO_TEST_CASE(CosineNodeCosineSplit) * Checks CosineTree::ModifiedGramSchmidt() by creating a random basis for the * vector subspace and checking if all the vectors are orthogonal to each other. */ -BOOST_AUTO_TEST_CASE(CosineTreeModifiedGramSchmidt) +TEST_CASE("CosineTreeModifiedGramSchmidt", "[CosineTreeTest]") { // Initialize constants required for the test. const size_t numRows = 100; @@ -201,8 +197,8 @@ BOOST_AUTO_TEST_CASE(CosineTreeModifiedGramSchmidt) for (; j != basisQueue.end(); ++j) { currentNode = *j; - BOOST_REQUIRE_SMALL(arma::dot(currentNode->BasisVector(), newBasisVector), - 1e-5); + REQUIRE(arma::dot(currentNode->BasisVector(), newBasisVector) == + Approx(0.0).margin(1e-5)); } // Add the obtained vector to the basis. @@ -225,7 +221,7 @@ BOOST_AUTO_TEST_CASE(CosineTreeModifiedGramSchmidt) /** * Test the copy constructor & copy assignment using Cosine trees. */ -BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorCosineTreeTest) +TEST_CASE("CopyConstructorAndOperatorCosineTreeTest", "[CosineTreeTest]") { // Initialize constants required for the test. const size_t numRows = 10; @@ -318,15 +314,15 @@ BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorCosineTreeTest) for (size_t i = 0; i < v1.size(); ++i) { - BOOST_REQUIRE_EQUAL(v1.at(i), v2.at(i)); - BOOST_REQUIRE_EQUAL(v1.at(i), v3.at(i)); + REQUIRE(v1.at(i) == v2.at(i)); + REQUIRE(v1.at(i) == v3.at(i)); } } /** * Test the move constructor & move assignment using Cosine trees. */ -BOOST_AUTO_TEST_CASE(MoveConstructorAndOperatorCosineTreeTest) +TEST_CASE("MoveConstructorAndOperatorCosineTreeTest", "[CosineTreeTest]") { // Initialize constants required for the test. const size_t numRows = 10; @@ -431,9 +427,7 @@ BOOST_AUTO_TEST_CASE(MoveConstructorAndOperatorCosineTreeTest) for (size_t i = 0; i < v1.size(); ++i) { - BOOST_REQUIRE_EQUAL(v1.at(i), v2.at(i)); - BOOST_REQUIRE_EQUAL(v1.at(i), v3.at(i)); + REQUIRE(v1.at(i) == v2.at(i)); + REQUIRE(v1.at(i) == v3.at(i)); } } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/det_test.cpp b/src/mlpack/tests/det_test.cpp index 4a16bbd060..c0989768eb 100644 --- a/src/mlpack/tests/det_test.cpp +++ b/src/mlpack/tests/det_test.cpp @@ -11,8 +11,7 @@ * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ #include -#include -#include "test_tools.hpp" +#include "catch.hpp" // This trick does not work on Windows. We will have to comment out the tests // that depend on it. @@ -33,13 +32,11 @@ using namespace mlpack; using namespace mlpack::det; using namespace std; -BOOST_AUTO_TEST_SUITE(DETTest); - // Tests for the private functions. We cannot perform these if we are on // Windows because we cannot make private functions accessible using the macro // trick above. #ifndef _WIN32 -BOOST_AUTO_TEST_CASE(TestGetMaxMinVals) +TEST_CASE("TestGetMaxMinVals", "[DETTest]") { arma::mat testData(3, 5); @@ -49,15 +46,15 @@ BOOST_AUTO_TEST_CASE(TestGetMaxMinVals) DTree tree(testData); - BOOST_REQUIRE_EQUAL(tree.MaxVals()[0], 7); - BOOST_REQUIRE_EQUAL(tree.MinVals()[0], 3); - BOOST_REQUIRE_EQUAL(tree.MaxVals()[1], 7); - BOOST_REQUIRE_EQUAL(tree.MinVals()[1], 0); - BOOST_REQUIRE_EQUAL(tree.MaxVals()[2], 8); - BOOST_REQUIRE_EQUAL(tree.MinVals()[2], 1); + REQUIRE(tree.MaxVals()[0] == 7); + REQUIRE(tree.MinVals()[0] == 3); + REQUIRE(tree.MaxVals()[1] == 7); + REQUIRE(tree.MinVals()[1] == 0); + REQUIRE(tree.MaxVals()[2] == 8); + REQUIRE(tree.MinVals()[2] == 1); } -BOOST_AUTO_TEST_CASE(TestComputeNodeError) +TEST_CASE("TestComputeNodeError", "[DETTest]") { arma::vec maxVals("7 7 8"); arma::vec minVals("3 0 1"); @@ -65,17 +62,18 @@ BOOST_AUTO_TEST_CASE(TestComputeNodeError) DTree testDTree(maxVals, minVals, 5); double trueNodeError = -log(4.0) - log(7.0) - log(7.0); - BOOST_REQUIRE_CLOSE((double) testDTree.logNegError, trueNodeError, 1e-10); + REQUIRE((double) testDTree.logNegError == + Approx(trueNodeError).epsilon(1e-12)); testDTree.start = 3; testDTree.end = 5; double nodeError = testDTree.LogNegativeError(5); trueNodeError = 2 * log(2.0 / 5.0) - log(4.0) - log(7.0) - log(7.0); - BOOST_REQUIRE_CLOSE(nodeError, trueNodeError, 1e-10); + REQUIRE(nodeError == Approx(trueNodeError).epsilon(1e-12)); } -BOOST_AUTO_TEST_CASE(TestWithinRange) +TEST_CASE("TestWithinRange", "[DETTest]") { arma::vec maxVals("7 7 8"); arma::vec minVals("3 0 1"); @@ -85,14 +83,14 @@ BOOST_AUTO_TEST_CASE(TestWithinRange) arma::vec testQuery(3); testQuery << 4.5 << 2.5 << 2; - BOOST_REQUIRE_EQUAL(testDTree.WithinRange(testQuery), true); + REQUIRE(testDTree.WithinRange(testQuery) == true); testQuery << 8.5 << 2.5 << 2; - BOOST_REQUIRE_EQUAL(testDTree.WithinRange(testQuery), false); + REQUIRE(testDTree.WithinRange(testQuery) == false); } -BOOST_AUTO_TEST_CASE(TestFindSplit) +TEST_CASE("TestFindSplit", "[DETTest]") { arma::mat testData(3, 5); @@ -108,20 +106,21 @@ BOOST_AUTO_TEST_CASE(TestFindSplit) size_t trueDim = 2; double trueSplit = 5.5; double trueLeftError = 2 * log(2.0 / 5.0) - (log(7.0) + log(4.0) + log(4.5)); - double trueRightError = 2 * log(3.0 / 5.0) - (log(7.0) + log(4.0) + log(2.5)); + double trueRightError = 2 * log(3.0 / 5.0) - (log(7.0) + log(4.0) + + log(2.5)); testDTree.logVolume = log(7.0) + log(4.0) + log(7.0); - BOOST_REQUIRE(testDTree.FindSplit( + REQUIRE(testDTree.FindSplit( testData, obDim, obSplit, obLeftError, obRightError, 1)); - BOOST_REQUIRE(trueDim == obDim); - BOOST_REQUIRE_CLOSE(trueSplit, obSplit, 1e-10); + REQUIRE(trueDim == obDim); + REQUIRE(trueSplit == Approx(obSplit).epsilon(1e-12)); - BOOST_REQUIRE_CLOSE(trueLeftError, obLeftError, 1e-10); - BOOST_REQUIRE_CLOSE(trueRightError, obRightError, 1e-10); + REQUIRE(trueLeftError == Approx(obLeftError).epsilon(1e-12)); + REQUIRE(trueRightError == Approx(obRightError).epsilon(1e-12)); } -BOOST_AUTO_TEST_CASE(TestSplitData) +TEST_CASE("TestSplitData", "[DETTest]") { arma::mat testData(3, 5); @@ -140,16 +139,16 @@ BOOST_AUTO_TEST_CASE(TestSplitData) size_t splitInd = testDTree.SplitData( testData, splitDim, trueSplitVal, oTest); - BOOST_REQUIRE_EQUAL(splitInd, 2); // 2 points on left side. + REQUIRE(splitInd == 2); // 2 points on left side. - BOOST_REQUIRE_EQUAL(oTest[0], 1); - BOOST_REQUIRE_EQUAL(oTest[1], 4); - BOOST_REQUIRE_EQUAL(oTest[2], 3); - BOOST_REQUIRE_EQUAL(oTest[3], 2); - BOOST_REQUIRE_EQUAL(oTest[4], 5); + REQUIRE(oTest[0] == 1); + REQUIRE(oTest[1] == 4); + REQUIRE(oTest[2] == 3); + REQUIRE(oTest[3] == 2); + REQUIRE(oTest[4] == 5); } -BOOST_AUTO_TEST_CASE(TestSparseFindSplit) +TEST_CASE("TestSparseFindSplit", "[DETTest]") { arma::mat realData(4, 7); @@ -173,17 +172,17 @@ BOOST_AUTO_TEST_CASE(TestSparseFindSplit) (log(7.0) + log(6.5) + log(8.0) + log(6.0)); testDTree.logVolume = log(7.0) + log(7.0) + log(8.0) + log(6.0); - BOOST_REQUIRE(testDTree.FindSplit( + REQUIRE(testDTree.FindSplit( testData, obDim, obSplit, obLeftError, obRightError, 1)); - BOOST_REQUIRE(trueDim == obDim); - BOOST_REQUIRE_CLOSE(trueSplit, obSplit, 1e-10); + REQUIRE(trueDim == obDim); + REQUIRE(trueSplit == Approx(obSplit).epsilon(1e-12)); - BOOST_REQUIRE_CLOSE(trueLeftError, obLeftError, 1e-10); - BOOST_REQUIRE_CLOSE(trueRightError, obRightError, 1e-10); + REQUIRE(trueLeftError == Approx(obLeftError).epsilon(1e-12)); + REQUIRE(trueRightError == Approx(obRightError).epsilon(1e-12)); } -BOOST_AUTO_TEST_CASE(TestSparseSplitData) +TEST_CASE("TestSparseSplitData", "[DETTest]") { arma::mat realData(4, 7); @@ -205,22 +204,22 @@ BOOST_AUTO_TEST_CASE(TestSparseSplitData) size_t splitInd = testDTree.SplitData( testData, splitDim, trueSplitVal, oTest); - BOOST_REQUIRE_EQUAL(splitInd, 3); // 2 points on left side. + REQUIRE(splitInd == 3); // 2 points on left side. - BOOST_REQUIRE_EQUAL(oTest[0], 1); - BOOST_REQUIRE_EQUAL(oTest[1], 4); - BOOST_REQUIRE_EQUAL(oTest[2], 3); - BOOST_REQUIRE_EQUAL(oTest[3], 2); - BOOST_REQUIRE_EQUAL(oTest[4], 5); - BOOST_REQUIRE_EQUAL(oTest[5], 6); - BOOST_REQUIRE_EQUAL(oTest[6], 7); + REQUIRE(oTest[0] == 1); + REQUIRE(oTest[1] == 4); + REQUIRE(oTest[2] == 3); + REQUIRE(oTest[3] == 2); + REQUIRE(oTest[4] == 5); + REQUIRE(oTest[5] == 6); + REQUIRE(oTest[6] == 7); } #endif // Tests for the public functions. -BOOST_AUTO_TEST_CASE(TestGrow) +TEST_CASE("TestGrow", "[DETTest]") { arma::mat testData(3, 5); @@ -244,34 +243,36 @@ BOOST_AUTO_TEST_CASE(TestGrow) DTree testDTree(testData); double alpha = testDTree.Grow(testData, oTest, false, 2, 1); - BOOST_REQUIRE_EQUAL(oTest[0], 0); - BOOST_REQUIRE_EQUAL(oTest[1], 3); - BOOST_REQUIRE_EQUAL(oTest[2], 1); - BOOST_REQUIRE_EQUAL(oTest[3], 2); - BOOST_REQUIRE_EQUAL(oTest[4], 4); + REQUIRE(oTest[0] == 0); + REQUIRE(oTest[1] == 3); + REQUIRE(oTest[2] == 1); + REQUIRE(oTest[3] == 2); + REQUIRE(oTest[4] == 4); // Test the structure of the tree. - BOOST_REQUIRE(testDTree.Left()->Left() == NULL); - BOOST_REQUIRE(testDTree.Left()->Right() == NULL); - BOOST_REQUIRE(testDTree.Right()->Left()->Left() == NULL); - BOOST_REQUIRE(testDTree.Right()->Left()->Right() == NULL); - BOOST_REQUIRE(testDTree.Right()->Right()->Left() == NULL); - BOOST_REQUIRE(testDTree.Right()->Right()->Right() == NULL); + REQUIRE(testDTree.Left()->Left() == NULL); + REQUIRE(testDTree.Left()->Right() == NULL); + REQUIRE(testDTree.Right()->Left()->Left() == NULL); + REQUIRE(testDTree.Right()->Left()->Right() == NULL); + REQUIRE(testDTree.Right()->Right()->Left() == NULL); + REQUIRE(testDTree.Right()->Right()->Right() == NULL); - BOOST_REQUIRE(testDTree.SubtreeLeaves() == 3); + REQUIRE(testDTree.SubtreeLeaves() == 3); - BOOST_REQUIRE(testDTree.SplitDim() == 2); - BOOST_REQUIRE_CLOSE(testDTree.SplitValue(), 5.5, 1e-5); - BOOST_REQUIRE(testDTree.Right()->SplitDim() == 1); - BOOST_REQUIRE_CLOSE(testDTree.Right()->SplitValue(), 0.5, 1e-5); + REQUIRE(testDTree.SplitDim() == 2); + REQUIRE(testDTree.SplitValue() == Approx(5.5).epsilon(1e-7)); + REQUIRE(testDTree.Right()->SplitDim() == 1); + REQUIRE(testDTree.Right()->SplitValue() == Approx(0.5).epsilon(1e-7)); // Test node errors for every node (these are private functions). #ifndef _WIN32 - BOOST_REQUIRE_CLOSE(testDTree.logNegError, rootError, 1e-10); - BOOST_REQUIRE_CLOSE(testDTree.Left()->logNegError, lError, 1e-10); - BOOST_REQUIRE_CLOSE(testDTree.Right()->logNegError, rError, 1e-10); - BOOST_REQUIRE_CLOSE(testDTree.Right()->Left()->logNegError, rlError, 1e-10); - BOOST_REQUIRE_CLOSE(testDTree.Right()->Right()->logNegError, rrError, 1e-10); + REQUIRE(testDTree.logNegError == Approx(rootError).epsilon(1e-12)); + REQUIRE(testDTree.Left()->logNegError == Approx(lError).epsilon(1e-12)); + REQUIRE(testDTree.Right()->logNegError == Approx(rError).epsilon(1e-12)); + REQUIRE(testDTree.Right()->Left()->logNegError == + Approx(rlError).epsilon(1e-12)); + REQUIRE(testDTree.Right()->Right()->logNegError == + Approx(rrError).epsilon(1e-12)); #endif // Test alpha. @@ -281,10 +282,10 @@ BOOST_AUTO_TEST_CASE(TestGrow) rAlpha = std::log(-(std::exp(rError) - (std::exp(rlError) + std::exp(rrError)))); - BOOST_REQUIRE_CLOSE(alpha, min(rootAlpha, rAlpha), 1e-10); + REQUIRE(alpha == Approx(min(rootAlpha, rAlpha)).epsilon(1e-12)); } -BOOST_AUTO_TEST_CASE(TestPruneAndUpdate) +TEST_CASE("TestPruneAndUpdate", "[DETTest]") { arma::mat testData(3, 5); @@ -298,18 +299,19 @@ BOOST_AUTO_TEST_CASE(TestPruneAndUpdate) double alpha = testDTree.Grow(testData, oTest, false, 2, 1); alpha = testDTree.PruneAndUpdate(alpha, testData.n_cols, false); - BOOST_REQUIRE_CLOSE(alpha, numeric_limits::max(), 1e-10); - BOOST_REQUIRE(testDTree.SubtreeLeaves() == 1); + REQUIRE(alpha == Approx(numeric_limits::max()).epsilon(1e-12)); + REQUIRE(testDTree.SubtreeLeaves() == 1); double rootError = -log(4.0) - log(7.0) - log(7.0); - BOOST_REQUIRE_CLOSE(testDTree.LogNegError(), rootError, 1e-10); - BOOST_REQUIRE_CLOSE(testDTree.SubtreeLeavesLogNegError(), rootError, 1e-10); - BOOST_REQUIRE(testDTree.Left() == NULL); - BOOST_REQUIRE(testDTree.Right() == NULL); + REQUIRE(testDTree.LogNegError() == Approx(rootError).epsilon(1e-12)); + REQUIRE(testDTree.SubtreeLeavesLogNegError() == + Approx(rootError).epsilon(1e-12)); + REQUIRE(testDTree.Left() == NULL); + REQUIRE(testDTree.Right() == NULL); } -BOOST_AUTO_TEST_CASE(TestComputeValue) +TEST_CASE("TestComputeValue", "[DETTest]") { arma::mat testData(3, 5); @@ -334,22 +336,22 @@ BOOST_AUTO_TEST_CASE(TestComputeValue) double d2 = (1.0 / 5.0) / exp(log(4.0) + log(0.5) + log(2.5)); double d3 = (2.0 / 5.0) / exp(log(4.0) + log(6.5) + log(2.5)); - BOOST_REQUIRE_CLOSE(d1, testDTree.ComputeValue(q1), 1e-10); - BOOST_REQUIRE_CLOSE(d2, testDTree.ComputeValue(q2), 1e-10); - BOOST_REQUIRE_CLOSE(d3, testDTree.ComputeValue(q3), 1e-10); - BOOST_REQUIRE_CLOSE(0.0, testDTree.ComputeValue(q4), 1e-10); + REQUIRE(d1 == Approx(testDTree.ComputeValue(q1)).epsilon(1e-12)); + REQUIRE(d2 == Approx(testDTree.ComputeValue(q2)).epsilon(1e-12)); + REQUIRE(d3 == Approx(testDTree.ComputeValue(q3)).epsilon(1e-12)); + REQUIRE(0.0 == Approx(testDTree.ComputeValue(q4)).epsilon(1e-12)); alpha = testDTree.PruneAndUpdate(alpha, testData.n_cols, false); double d = 1.0 / exp(log(4.0) + log(7.0) + log(7.0)); - BOOST_REQUIRE_CLOSE(d, testDTree.ComputeValue(q1), 1e-10); - BOOST_REQUIRE_CLOSE(d, testDTree.ComputeValue(q2), 1e-10); - BOOST_REQUIRE_CLOSE(d, testDTree.ComputeValue(q3), 1e-10); - BOOST_REQUIRE_CLOSE(0.0, testDTree.ComputeValue(q4), 1e-10); + REQUIRE(d == Approx(testDTree.ComputeValue(q1)).epsilon(1e-12)); + REQUIRE(d == Approx(testDTree.ComputeValue(q2)).epsilon(1e-12)); + REQUIRE(d == Approx(testDTree.ComputeValue(q3)).epsilon(1e-12)); + REQUIRE(0.0 == Approx(testDTree.ComputeValue(q4)).epsilon(1e-12)); } -BOOST_AUTO_TEST_CASE(TestVariableImportance) +TEST_CASE("TestVariableImportance", "[DETTest]") { arma::mat testData(3, 5); @@ -377,12 +379,14 @@ BOOST_AUTO_TEST_CASE(TestVariableImportance) testDTree.ComputeVariableImportance(imps); - BOOST_REQUIRE_CLOSE((double) 0.0, imps[0], 1e-10); - BOOST_REQUIRE_CLOSE((double) (rError - (rlError + rrError)), imps[1], 1e-10); - BOOST_REQUIRE_CLOSE((double) (rootError - (lError + rError)), imps[2], 1e-10); + REQUIRE((double) 0.0 == Approx(imps[0]).epsilon(1e-12)); + REQUIRE((double) (rError - (rlError + rrError)) == + Approx(imps[1]).epsilon(1e-12)); + REQUIRE((double) (rootError - (lError + rError)) == + Approx(imps[2]).epsilon(1e-12)); } -BOOST_AUTO_TEST_CASE(TestSparsePruneAndUpdate) +TEST_CASE("TestSparsePruneAndUpdate", "[DETTest]") { arma::mat realData(3, 5); @@ -399,18 +403,19 @@ BOOST_AUTO_TEST_CASE(TestSparsePruneAndUpdate) double alpha = testDTree.Grow(testData, oTest, false, 2, 1); alpha = testDTree.PruneAndUpdate(alpha, testData.n_cols, false); - BOOST_REQUIRE_CLOSE(alpha, numeric_limits::max(), 1e-10); - BOOST_REQUIRE(testDTree.SubtreeLeaves() == 1); + REQUIRE(alpha == Approx(numeric_limits::max()).epsilon(1e-12)); + REQUIRE(testDTree.SubtreeLeaves() == 1); double rootError = -log(4.0) - log(7.0) - log(7.0); - BOOST_REQUIRE_CLOSE(testDTree.LogNegError(), rootError, 1e-10); - BOOST_REQUIRE_CLOSE(testDTree.SubtreeLeavesLogNegError(), rootError, 1e-10); - BOOST_REQUIRE(testDTree.Left() == NULL); - BOOST_REQUIRE(testDTree.Right() == NULL); + REQUIRE(testDTree.LogNegError() == Approx(rootError).epsilon(1e-12)); + REQUIRE(testDTree.SubtreeLeavesLogNegError() == + Approx(rootError).epsilon(1e-12)); + REQUIRE(testDTree.Left() == NULL); + REQUIRE(testDTree.Right() == NULL); } -BOOST_AUTO_TEST_CASE(TestSparseComputeValue) +TEST_CASE("TestSparseComputeValue", "[DETTest]") { arma::mat realData(3, 5); @@ -438,25 +443,25 @@ BOOST_AUTO_TEST_CASE(TestSparseComputeValue) double d2 = (1.0 / 5.0) / exp(log(4.0) + log(0.5) + log(2.5)); double d3 = (2.0 / 5.0) / exp(log(4.0) + log(6.5) + log(2.5)); - BOOST_REQUIRE_CLOSE(d1, testDTree.ComputeValue(q1), 1e-10); - BOOST_REQUIRE_CLOSE(d2, testDTree.ComputeValue(q2), 1e-10); - BOOST_REQUIRE_CLOSE(d3, testDTree.ComputeValue(q3), 1e-10); - BOOST_REQUIRE_CLOSE(0.0, testDTree.ComputeValue(q4), 1e-10); + REQUIRE(d1 == Approx(testDTree.ComputeValue(q1)).epsilon(1e-12)); + REQUIRE(d2 == Approx(testDTree.ComputeValue(q2)).epsilon(1e-12)); + REQUIRE(d3 == Approx(testDTree.ComputeValue(q3)).epsilon(1e-12)); + REQUIRE(0.0 == Approx(testDTree.ComputeValue(q4)).epsilon(1e-12)); alpha = testDTree.PruneAndUpdate(alpha, testData.n_cols, false); double d = 1.0 / exp(log(4.0) + log(7.0) + log(7.0)); - BOOST_REQUIRE_CLOSE(d, testDTree.ComputeValue(q1), 1e-10); - BOOST_REQUIRE_CLOSE(d, testDTree.ComputeValue(q2), 1e-10); - BOOST_REQUIRE_CLOSE(d, testDTree.ComputeValue(q3), 1e-10); - BOOST_REQUIRE_CLOSE(0.0, testDTree.ComputeValue(q4), 1e-10); + REQUIRE(d == Approx(testDTree.ComputeValue(q1)).epsilon(1e-12)); + REQUIRE(d == Approx(testDTree.ComputeValue(q2)).epsilon(1e-12)); + REQUIRE(d == Approx(testDTree.ComputeValue(q3)).epsilon(1e-12)); + REQUIRE(0.0 == Approx(testDTree.ComputeValue(q4)).epsilon(1e-12)); } /** * These are not yet implemented. * -BOOST_AUTO_TEST_CASE(TestTagTree) +TEST_CASE("TestTagTree", "[DETTest]") { MatType testData(3, 5); @@ -469,7 +474,7 @@ BOOST_AUTO_TEST_CASE(TestTagTree) delete testDTree; } -BOOST_AUTO_TEST_CASE(TestFindBucket) +TEST_CASE("TestFindBucket", "[DETTest]") { MatType testData(3, 5); @@ -484,24 +489,24 @@ BOOST_AUTO_TEST_CASE(TestFindBucket) // Test functions in dt_utils.hpp -BOOST_AUTO_TEST_CASE(TestTrainer) +TEST_CASE("TestTrainer", "[DETTest]") { } -BOOST_AUTO_TEST_CASE(TestPrintVariableImportance) +TEST_CASE("TestPrintVariableImportance", "[DETTest]") { } -BOOST_AUTO_TEST_CASE(TestPrintLeafMembership) +TEST_CASE("TestPrintLeafMembership", "[DETTest]") { } */ // Test the copy constructor and the copy operator. -BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorTest) +TEST_CASE("CopyConstructorAndOperatorTest", "[DETTest]") { arma::mat testData(3, 5); @@ -544,76 +549,76 @@ BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorTest) delete testDTree; // Test the data of copied tree (using copy constructor). - BOOST_REQUIRE_EQUAL(testDTree2.MaxVals()[0], maxVals0); - BOOST_REQUIRE_EQUAL(testDTree2.MinVals()[0], minVals0); - BOOST_REQUIRE_EQUAL(testDTree2.MaxVals()[1], maxVals1); - BOOST_REQUIRE_EQUAL(testDTree2.MinVals()[1], minVals1); - BOOST_REQUIRE_EQUAL(testDTree2.MaxVals()[2], maxVals2); - BOOST_REQUIRE_EQUAL(testDTree2.MinVals()[2], minVals2); + REQUIRE(testDTree2.MaxVals()[0] == maxVals0); + REQUIRE(testDTree2.MinVals()[0] == minVals0); + REQUIRE(testDTree2.MaxVals()[1] == maxVals1); + REQUIRE(testDTree2.MinVals()[1] == minVals1); + REQUIRE(testDTree2.MaxVals()[2] == maxVals2); + REQUIRE(testDTree2.MinVals()[2] == minVals2); // Test the data of the copied tree (using the copy operator). - BOOST_REQUIRE_EQUAL(testDTree3.MaxVals()[0], maxVals0); - BOOST_REQUIRE_EQUAL(testDTree3.MinVals()[0], minVals0); - BOOST_REQUIRE_EQUAL(testDTree3.MaxVals()[1], maxVals1); - BOOST_REQUIRE_EQUAL(testDTree3.MinVals()[1], minVals1); - BOOST_REQUIRE_EQUAL(testDTree3.MaxVals()[2], maxVals2); - BOOST_REQUIRE_EQUAL(testDTree3.MinVals()[2], minVals2); + REQUIRE(testDTree3.MaxVals()[0] == maxVals0); + REQUIRE(testDTree3.MinVals()[0] == minVals0); + REQUIRE(testDTree3.MaxVals()[1] == maxVals1); + REQUIRE(testDTree3.MinVals()[1] == minVals1); + REQUIRE(testDTree3.MaxVals()[2] == maxVals2); + REQUIRE(testDTree3.MinVals()[2] == minVals2); // Test the structure of the tree copied using the copy constructor. - BOOST_REQUIRE(testDTree2.Left()->Left() == NULL); - BOOST_REQUIRE(testDTree2.Left()->Right() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Left()->Left() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Left()->Right() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Right()->Left() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Right()->Right() == NULL); + REQUIRE(testDTree2.Left()->Left() == NULL); + REQUIRE(testDTree2.Left()->Right() == NULL); + REQUIRE(testDTree2.Right()->Left()->Left() == NULL); + REQUIRE(testDTree2.Right()->Left()->Right() == NULL); + REQUIRE(testDTree2.Right()->Right()->Left() == NULL); + REQUIRE(testDTree2.Right()->Right()->Right() == NULL); // Test the structure of the tree copied using the copy operator. - BOOST_REQUIRE(testDTree3.Left()->Left() == NULL); - BOOST_REQUIRE(testDTree3.Left()->Right() == NULL); - BOOST_REQUIRE(testDTree3.Right()->Left()->Left() == NULL); - BOOST_REQUIRE(testDTree3.Right()->Left()->Right() == NULL); - BOOST_REQUIRE(testDTree3.Right()->Right()->Left() == NULL); - BOOST_REQUIRE(testDTree3.Right()->Right()->Right() == NULL); + REQUIRE(testDTree3.Left()->Left() == NULL); + REQUIRE(testDTree3.Left()->Right() == NULL); + REQUIRE(testDTree3.Right()->Left()->Left() == NULL); + REQUIRE(testDTree3.Right()->Left()->Right() == NULL); + REQUIRE(testDTree3.Right()->Right()->Left() == NULL); + REQUIRE(testDTree3.Right()->Right()->Right() == NULL); // Test the data of the tree copied using the copy constructor. - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MaxVals()[0], maxValsL0); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MaxVals()[1], maxValsL1); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MaxVals()[2], maxValsL2); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MinVals()[0], minValsL0); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MinVals()[1], minValsL1); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MinVals()[2], minValsL2); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MaxVals()[0], maxValsR0); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MaxVals()[1], maxValsR1); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MaxVals()[2], maxValsR2); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MinVals()[0], minValsR0); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MinVals()[1], minValsR1); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MinVals()[2], minValsR2); - BOOST_REQUIRE(testDTree2.SplitDim() == 2); - BOOST_REQUIRE_CLOSE(testDTree2.SplitValue(), 5.5, 1e-5); - BOOST_REQUIRE(testDTree2.Right()->SplitDim() == 1); - BOOST_REQUIRE_CLOSE(testDTree2.Right()->SplitValue(), 0.5, 1e-5); + REQUIRE(testDTree2.Left()->MaxVals()[0] == maxValsL0); + REQUIRE(testDTree2.Left()->MaxVals()[1] == maxValsL1); + REQUIRE(testDTree2.Left()->MaxVals()[2] == maxValsL2); + REQUIRE(testDTree2.Left()->MinVals()[0] == minValsL0); + REQUIRE(testDTree2.Left()->MinVals()[1] == minValsL1); + REQUIRE(testDTree2.Left()->MinVals()[2] == minValsL2); + REQUIRE(testDTree2.Right()->MaxVals()[0] == maxValsR0); + REQUIRE(testDTree2.Right()->MaxVals()[1] == maxValsR1); + REQUIRE(testDTree2.Right()->MaxVals()[2] == maxValsR2); + REQUIRE(testDTree2.Right()->MinVals()[0] == minValsR0); + REQUIRE(testDTree2.Right()->MinVals()[1] == minValsR1); + REQUIRE(testDTree2.Right()->MinVals()[2] == minValsR2); + REQUIRE(testDTree2.SplitDim() == 2); + REQUIRE(testDTree2.SplitValue() == Approx(5.5).epsilon(1e-7)); + REQUIRE(testDTree2.Right()->SplitDim() == 1); + REQUIRE(testDTree2.Right()->SplitValue() == Approx(0.5).epsilon(1e-7)); // Test the data of the tree copied using the copy operator. - BOOST_REQUIRE_EQUAL(testDTree3.Left()->MaxVals()[0], maxValsL0); - BOOST_REQUIRE_EQUAL(testDTree3.Left()->MaxVals()[1], maxValsL1); - BOOST_REQUIRE_EQUAL(testDTree3.Left()->MaxVals()[2], maxValsL2); - BOOST_REQUIRE_EQUAL(testDTree3.Left()->MinVals()[0], minValsL0); - BOOST_REQUIRE_EQUAL(testDTree3.Left()->MinVals()[1], minValsL1); - BOOST_REQUIRE_EQUAL(testDTree3.Left()->MinVals()[2], minValsL2); - BOOST_REQUIRE_EQUAL(testDTree3.Right()->MaxVals()[0], maxValsR0); - BOOST_REQUIRE_EQUAL(testDTree3.Right()->MaxVals()[1], maxValsR1); - BOOST_REQUIRE_EQUAL(testDTree3.Right()->MaxVals()[2], maxValsR2); - BOOST_REQUIRE_EQUAL(testDTree3.Right()->MinVals()[0], minValsR0); - BOOST_REQUIRE_EQUAL(testDTree3.Right()->MinVals()[1], minValsR1); - BOOST_REQUIRE_EQUAL(testDTree3.Right()->MinVals()[2], minValsR2); - BOOST_REQUIRE(testDTree3.SplitDim() == 2); - BOOST_REQUIRE_CLOSE(testDTree3.SplitValue(), 5.5, 1e-5); - BOOST_REQUIRE(testDTree3.Right()->SplitDim() == 1); - BOOST_REQUIRE_CLOSE(testDTree3.Right()->SplitValue(), 0.5, 1e-5); + REQUIRE(testDTree3.Left()->MaxVals()[0] == maxValsL0); + REQUIRE(testDTree3.Left()->MaxVals()[1] == maxValsL1); + REQUIRE(testDTree3.Left()->MaxVals()[2] == maxValsL2); + REQUIRE(testDTree3.Left()->MinVals()[0] == minValsL0); + REQUIRE(testDTree3.Left()->MinVals()[1] == minValsL1); + REQUIRE(testDTree3.Left()->MinVals()[2] == minValsL2); + REQUIRE(testDTree3.Right()->MaxVals()[0] == maxValsR0); + REQUIRE(testDTree3.Right()->MaxVals()[1] == maxValsR1); + REQUIRE(testDTree3.Right()->MaxVals()[2] == maxValsR2); + REQUIRE(testDTree3.Right()->MinVals()[0] == minValsR0); + REQUIRE(testDTree3.Right()->MinVals()[1] == minValsR1); + REQUIRE(testDTree3.Right()->MinVals()[2] == minValsR2); + REQUIRE(testDTree3.SplitDim() == 2); + REQUIRE(testDTree3.SplitValue() == Approx(5.5).epsilon(1e-7)); + REQUIRE(testDTree3.Right()->SplitDim() == 1); + REQUIRE(testDTree3.Right()->SplitValue() == Approx(0.5).epsilon(1e-7)); } // Test the move constructor. -BOOST_AUTO_TEST_CASE(MoveConstructorTest) +TEST_CASE("MoveConstructorTest", "[DETTest]") { arma::mat testData(3, 5); @@ -653,50 +658,50 @@ BOOST_AUTO_TEST_CASE(MoveConstructorTest) DTree testDTree2(std::move(*testDTree)); // Check default values of the original tree. - BOOST_REQUIRE_EQUAL(testDTree->LogNegError(), -DBL_MAX); - BOOST_REQUIRE(testDTree->Left() == (DTree*) NULL); - BOOST_REQUIRE(testDTree->Right() == (DTree*) NULL); + REQUIRE(testDTree->LogNegError() == -DBL_MAX); + REQUIRE(testDTree->Left() == (DTree*) NULL); + REQUIRE(testDTree->Right() == (DTree*) NULL); // Delete the original tree. delete testDTree; // Test the data of the moved tree. - BOOST_REQUIRE_EQUAL(testDTree2.MaxVals()[0], maxVals0); - BOOST_REQUIRE_EQUAL(testDTree2.MinVals()[0], minVals0); - BOOST_REQUIRE_EQUAL(testDTree2.MaxVals()[1], maxVals1); - BOOST_REQUIRE_EQUAL(testDTree2.MinVals()[1], minVals1); - BOOST_REQUIRE_EQUAL(testDTree2.MaxVals()[2], maxVals2); - BOOST_REQUIRE_EQUAL(testDTree2.MinVals()[2], minVals2); + REQUIRE(testDTree2.MaxVals()[0] == maxVals0); + REQUIRE(testDTree2.MinVals()[0] == minVals0); + REQUIRE(testDTree2.MaxVals()[1] == maxVals1); + REQUIRE(testDTree2.MinVals()[1] == minVals1); + REQUIRE(testDTree2.MaxVals()[2] == maxVals2); + REQUIRE(testDTree2.MinVals()[2] == minVals2); // Test the structure of the moved tree. - BOOST_REQUIRE(testDTree2.Left()->Left() == NULL); - BOOST_REQUIRE(testDTree2.Left()->Right() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Left()->Left() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Left()->Right() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Right()->Left() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Right()->Right() == NULL); + REQUIRE(testDTree2.Left()->Left() == NULL); + REQUIRE(testDTree2.Left()->Right() == NULL); + REQUIRE(testDTree2.Right()->Left()->Left() == NULL); + REQUIRE(testDTree2.Right()->Left()->Right() == NULL); + REQUIRE(testDTree2.Right()->Right()->Left() == NULL); + REQUIRE(testDTree2.Right()->Right()->Right() == NULL); // Test the data of the moved tree. - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MaxVals()[0], maxValsL0); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MaxVals()[1], maxValsL1); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MaxVals()[2], maxValsL2); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MinVals()[0], minValsL0); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MinVals()[1], minValsL1); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MinVals()[2], minValsL2); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MaxVals()[0], maxValsR0); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MaxVals()[1], maxValsR1); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MaxVals()[2], maxValsR2); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MinVals()[0], minValsR0); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MinVals()[1], minValsR1); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MinVals()[2], minValsR2); - BOOST_REQUIRE(testDTree2.SplitDim() == 2); - BOOST_REQUIRE_CLOSE(testDTree2.SplitValue(), 5.5, 1e-5); - BOOST_REQUIRE(testDTree2.Right()->SplitDim() == 1); - BOOST_REQUIRE_CLOSE(testDTree2.Right()->SplitValue(), 0.5, 1e-5); + REQUIRE(testDTree2.Left()->MaxVals()[0] == maxValsL0); + REQUIRE(testDTree2.Left()->MaxVals()[1] == maxValsL1); + REQUIRE(testDTree2.Left()->MaxVals()[2] == maxValsL2); + REQUIRE(testDTree2.Left()->MinVals()[0] == minValsL0); + REQUIRE(testDTree2.Left()->MinVals()[1] == minValsL1); + REQUIRE(testDTree2.Left()->MinVals()[2] == minValsL2); + REQUIRE(testDTree2.Right()->MaxVals()[0] == maxValsR0); + REQUIRE(testDTree2.Right()->MaxVals()[1] == maxValsR1); + REQUIRE(testDTree2.Right()->MaxVals()[2] == maxValsR2); + REQUIRE(testDTree2.Right()->MinVals()[0] == minValsR0); + REQUIRE(testDTree2.Right()->MinVals()[1] == minValsR1); + REQUIRE(testDTree2.Right()->MinVals()[2] == minValsR2); + REQUIRE(testDTree2.SplitDim() == 2); + REQUIRE(testDTree2.SplitValue() == Approx(5.5).epsilon(1e-7)); + REQUIRE(testDTree2.Right()->SplitDim() == 1); + REQUIRE(testDTree2.Right()->SplitValue() == Approx(0.5).epsilon(1e-7)); } // Test the move operator. -BOOST_AUTO_TEST_CASE(MoveOperatorTest) +TEST_CASE("MoveOperatorTest", "[DETTest]") { arma::mat testData(3, 5); @@ -736,46 +741,44 @@ BOOST_AUTO_TEST_CASE(MoveOperatorTest) DTree testDTree2 = std::move(*testDTree); // Check default values of the original tree. - BOOST_REQUIRE_EQUAL(testDTree->LogNegError(), -DBL_MAX); - BOOST_REQUIRE(testDTree->Left() == (DTree*) NULL); - BOOST_REQUIRE(testDTree->Right() == (DTree*) NULL); + REQUIRE(testDTree->LogNegError() == -DBL_MAX); + REQUIRE(testDTree->Left() == (DTree*) NULL); + REQUIRE(testDTree->Right() == (DTree*) NULL); // Delete the original tree. delete testDTree; // Test the data of the moved tree. - BOOST_REQUIRE_EQUAL(testDTree2.MaxVals()[0], maxVals0); - BOOST_REQUIRE_EQUAL(testDTree2.MinVals()[0], minVals0); - BOOST_REQUIRE_EQUAL(testDTree2.MaxVals()[1], maxVals1); - BOOST_REQUIRE_EQUAL(testDTree2.MinVals()[1], minVals1); - BOOST_REQUIRE_EQUAL(testDTree2.MaxVals()[2], maxVals2); - BOOST_REQUIRE_EQUAL(testDTree2.MinVals()[2], minVals2); + REQUIRE(testDTree2.MaxVals()[0] == maxVals0); + REQUIRE(testDTree2.MinVals()[0] == minVals0); + REQUIRE(testDTree2.MaxVals()[1] == maxVals1); + REQUIRE(testDTree2.MinVals()[1] == minVals1); + REQUIRE(testDTree2.MaxVals()[2] == maxVals2); + REQUIRE(testDTree2.MinVals()[2] == minVals2); // Test the structure of the moved tree. - BOOST_REQUIRE(testDTree2.Left()->Left() == NULL); - BOOST_REQUIRE(testDTree2.Left()->Right() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Left()->Left() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Left()->Right() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Right()->Left() == NULL); - BOOST_REQUIRE(testDTree2.Right()->Right()->Right() == NULL); + REQUIRE(testDTree2.Left()->Left() == NULL); + REQUIRE(testDTree2.Left()->Right() == NULL); + REQUIRE(testDTree2.Right()->Left()->Left() == NULL); + REQUIRE(testDTree2.Right()->Left()->Right() == NULL); + REQUIRE(testDTree2.Right()->Right()->Left() == NULL); + REQUIRE(testDTree2.Right()->Right()->Right() == NULL); // Test the data of moved tree. - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MaxVals()[0], maxValsL0); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MaxVals()[1], maxValsL1); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MaxVals()[2], maxValsL2); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MinVals()[0], minValsL0); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MinVals()[1], minValsL1); - BOOST_REQUIRE_EQUAL(testDTree2.Left()->MinVals()[2], minValsL2); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MaxVals()[0], maxValsR0); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MaxVals()[1], maxValsR1); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MaxVals()[2], maxValsR2); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MinVals()[0], minValsR0); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MinVals()[1], minValsR1); - BOOST_REQUIRE_EQUAL(testDTree2.Right()->MinVals()[2], minValsR2); - BOOST_REQUIRE(testDTree2.SplitDim() == 2); - BOOST_REQUIRE_CLOSE(testDTree2.SplitValue(), 5.5, 1e-5); - BOOST_REQUIRE(testDTree2.Right()->SplitDim() == 1); - BOOST_REQUIRE_CLOSE(testDTree2.Right()->SplitValue(), 0.5, 1e-5); + REQUIRE(testDTree2.Left()->MaxVals()[0] == maxValsL0); + REQUIRE(testDTree2.Left()->MaxVals()[1] == maxValsL1); + REQUIRE(testDTree2.Left()->MaxVals()[2] == maxValsL2); + REQUIRE(testDTree2.Left()->MinVals()[0] == minValsL0); + REQUIRE(testDTree2.Left()->MinVals()[1] == minValsL1); + REQUIRE(testDTree2.Left()->MinVals()[2] == minValsL2); + REQUIRE(testDTree2.Right()->MaxVals()[0] == maxValsR0); + REQUIRE(testDTree2.Right()->MaxVals()[1] == maxValsR1); + REQUIRE(testDTree2.Right()->MaxVals()[2] == maxValsR2); + REQUIRE(testDTree2.Right()->MinVals()[0] == minValsR0); + REQUIRE(testDTree2.Right()->MinVals()[1] == minValsR1); + REQUIRE(testDTree2.Right()->MinVals()[2] == minValsR2); + REQUIRE(testDTree2.SplitDim() == 2); + REQUIRE(testDTree2.SplitValue() == Approx(5.5).epsilon(1e-7)); + REQUIRE(testDTree2.Right()->SplitDim() == 1); + REQUIRE(testDTree2.Right()->SplitValue() == Approx(0.5).epsilon(1e-7)); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/distribution_test.cpp b/src/mlpack/tests/distribution_test.cpp index 35103130b9..ab7d606a9f 100644 --- a/src/mlpack/tests/distribution_test.cpp +++ b/src/mlpack/tests/distribution_test.cpp @@ -19,17 +19,15 @@ #include #include -#include -#include "test_tools.hpp" -#include "serialization.hpp" +#include "catch.hpp" +#include "serialization_catch.hpp" +#include "test_catch_tools.hpp" using namespace mlpack; using namespace mlpack::distribution; using namespace mlpack::metric; using namespace mlpack::math; -BOOST_AUTO_TEST_SUITE(DistributionTest); - /*********************************/ /** Discrete Distribution Tests **/ /*********************************/ @@ -37,38 +35,38 @@ BOOST_AUTO_TEST_SUITE(DistributionTest); /** * Make sure we initialize correctly. */ -BOOST_AUTO_TEST_CASE(DiscreteDistributionConstructorTest) +TEST_CASE("DiscreteDistributionConstructorTest", "[DistributionTest]") { DiscreteDistribution d(5); - BOOST_REQUIRE_EQUAL(d.Probabilities().n_elem, 5); - BOOST_REQUIRE_CLOSE(d.Probability("0"), 0.2, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("1"), 0.2, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("2"), 0.2, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("3"), 0.2, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("4"), 0.2, 1e-5); + REQUIRE(d.Probabilities().n_elem == 5); + REQUIRE(d.Probability("0") == Approx(0.2).epsilon(1e-7)); + REQUIRE(d.Probability("1") == Approx(0.2).epsilon(1e-7)); + REQUIRE(d.Probability("2") == Approx(0.2).epsilon(1e-7)); + REQUIRE(d.Probability("3") == Approx(0.2).epsilon(1e-7)); + REQUIRE(d.Probability("4") == Approx(0.2).epsilon(1e-7)); } /** * Make sure we get the probabilities of observations right. */ -BOOST_AUTO_TEST_CASE(DiscreteDistributionProbabilityTest) +TEST_CASE("DiscreteDistributionProbabilityTest", "[DistributionTest]") { DiscreteDistribution d(5); d.Probabilities() = "0.2 0.4 0.1 0.1 0.2"; - BOOST_REQUIRE_CLOSE(d.Probability("0"), 0.2, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("1"), 0.4, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("2"), 0.1, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("3"), 0.1, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("4"), 0.2, 1e-5); + REQUIRE(d.Probability("0") == Approx(0.2).epsilon(1e-7)); + REQUIRE(d.Probability("1") == Approx(0.4).epsilon(1e-7)); + REQUIRE(d.Probability("2") == Approx(0.1).epsilon(1e-7)); + REQUIRE(d.Probability("3") == Approx(0.1).epsilon(1e-7)); + REQUIRE(d.Probability("4") == Approx(0.2).epsilon(1e-7)); } /** * Make sure we get random observations correct. */ -BOOST_AUTO_TEST_CASE(DiscreteDistributionRandomTest) +TEST_CASE("DiscreteDistributionRandomTest", "[DistributionTest]") { DiscreteDistribution d(arma::Col("3")); @@ -85,15 +83,15 @@ BOOST_AUTO_TEST_CASE(DiscreteDistributionRandomTest) actualProb /= accu(actualProb); // 8% tolerance, because this can be a noisy process. - BOOST_REQUIRE_CLOSE(actualProb(0), 0.3, 8.0); - BOOST_REQUIRE_CLOSE(actualProb(1), 0.6, 8.0); - BOOST_REQUIRE_CLOSE(actualProb(2), 0.1, 8.0); + REQUIRE(actualProb(0) == Approx(0.3).epsilon(0.08)); + REQUIRE(actualProb(1) == Approx(0.6).epsilon(0.08)); + REQUIRE(actualProb(2) == Approx(0.1).epsilon(0.08)); } /** * Make sure we can estimate from observations correctly. */ -BOOST_AUTO_TEST_CASE(DiscreteDistributionTrainTest) +TEST_CASE("DiscreteDistributionTrainTest", "[DistributionTest]") { DiscreteDistribution d(4); @@ -101,16 +99,16 @@ BOOST_AUTO_TEST_CASE(DiscreteDistributionTrainTest) d.Train(obs); - BOOST_REQUIRE_CLOSE(d.Probability("0"), 0.25, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("1"), 0.25, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("2"), 0.375, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("3"), 0.125, 1e-5); + REQUIRE(d.Probability("0") == Approx(0.25).epsilon(1e-7)); + REQUIRE(d.Probability("1") == Approx(0.25).epsilon(1e-7)); + REQUIRE(d.Probability("2") == Approx(0.375).epsilon(1e-7)); + REQUIRE(d.Probability("3") == Approx(0.125).epsilon(1e-7)); } /** * Estimate from observations with probabilities. */ -BOOST_AUTO_TEST_CASE(DiscreteDistributionTrainProbTest) +TEST_CASE("DiscreteDistributionTrainProbTest", "[DistributionTest]") { DiscreteDistribution d(3); @@ -120,15 +118,15 @@ BOOST_AUTO_TEST_CASE(DiscreteDistributionTrainProbTest) d.Train(obs, prob); - BOOST_REQUIRE_CLOSE(d.Probability("0"), 0.25, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("1"), 0.25, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("2"), 0.5, 1e-5); + REQUIRE(d.Probability("0") == Approx(0.25).epsilon(1e-7)); + REQUIRE(d.Probability("1") == Approx(0.25).epsilon(1e-7)); + REQUIRE(d.Probability("2") == Approx(0.5).epsilon(1e-7)); } /** * Achieve multidimensional probability distribution. */ -BOOST_AUTO_TEST_CASE(MultiDiscreteDistributionTrainProbTest) +TEST_CASE("MultiDiscreteDistributionTrainProbTest", "[DistributionTest]") { DiscreteDistribution d("10 10 10"); @@ -137,29 +135,29 @@ BOOST_AUTO_TEST_CASE(MultiDiscreteDistributionTrainProbTest) "0 0 0 1 1 2 2 2 2 2;"); d.Train(obs); - BOOST_REQUIRE_CLOSE(d.Probability("0 0 0"), 0.009, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("0 1 2"), 0.015, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("2 1 0"), 0.054, 1e-5); + REQUIRE(d.Probability("0 0 0") == Approx(0.009).epsilon(1e-7)); + REQUIRE(d.Probability("0 1 2") == Approx(0.015).epsilon(1e-7)); + REQUIRE(d.Probability("2 1 0") == Approx(0.054).epsilon(1e-7)); } /** * Make sure we initialize multidimensional probability distribution * correctly. */ -BOOST_AUTO_TEST_CASE(MultiDiscreteDistributionConstructorTest) +TEST_CASE("MultiDiscreteDistributionConstructorTest", "[DistributionTest]") { DiscreteDistribution d("4 4 4 4"); - BOOST_REQUIRE_EQUAL(d.Probabilities(0).size(), 4); - BOOST_REQUIRE_EQUAL(d.Dimensionality(), 4); - BOOST_REQUIRE_CLOSE(d.Probability("0 0 0 0"), 0.00390625, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("0 1 2 3"), 0.00390625, 1e-5); + REQUIRE(d.Probabilities(0).size() == 4); + REQUIRE(d.Dimensionality() == 4); + REQUIRE(d.Probability("0 0 0 0") == Approx(0.00390625).epsilon(1e-7)); + REQUIRE(d.Probability("0 1 2 3") == Approx(0.00390625).epsilon(1e-7)); } /** * Achieve multidimensional probability distribution. */ -BOOST_AUTO_TEST_CASE(MultiDiscreteDistributionTrainTest) +TEST_CASE("MultiDiscreteDistributionTrainTest", "[DistributionTest]") { std::vector pro; pro.push_back(arma::vec("0.1, 0.3, 0.6")); @@ -168,16 +166,16 @@ BOOST_AUTO_TEST_CASE(MultiDiscreteDistributionTrainTest) DiscreteDistribution d(pro); - BOOST_REQUIRE_CLOSE(d.Probability("0 0 0"), 0.0083333, 1e-3); - BOOST_REQUIRE_CLOSE(d.Probability("0 1 2"), 0.0166666, 1e-3); - BOOST_REQUIRE_CLOSE(d.Probability("2 1 0"), 0.05, 1e-5); + REQUIRE(d.Probability("0 0 0") == Approx(0.0083333).epsilon(1e-5)); + REQUIRE(d.Probability("0 1 2") == Approx(0.0166666).epsilon(1e-5)); + REQUIRE(d.Probability("2 1 0") == Approx(0.05).epsilon(1e-7)); } /** * Estimate multidimensional probability distribution from observations with * probabilities. */ -BOOST_AUTO_TEST_CASE(MultiDiscreteDistributionTrainProTest) +TEST_CASE("MultiDiscreteDistributionTrainProTest", "[DistributionTest]") { DiscreteDistribution d("5 5 5"); @@ -189,16 +187,16 @@ BOOST_AUTO_TEST_CASE(MultiDiscreteDistributionTrainProTest) d.Train(obs, prob); - BOOST_REQUIRE_CLOSE(d.Probability("0 0 0"), 0.00390625, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("1 0 1"), 0.0078125, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("2 1 0"), 0.015625, 1e-5); + REQUIRE(d.Probability("0 0 0") == Approx(0.00390625).epsilon(1e-7)); + REQUIRE(d.Probability("1 0 1") == Approx(0.0078125).epsilon(1e-7)); + REQUIRE(d.Probability("2 1 0") == Approx(0.015625).epsilon(1e-7)); } /** * Test the LogProbability() function, for multiple points in the multivariate * Discrete case. */ -BOOST_AUTO_TEST_CASE(DiscreteLogProbabilityTest) +TEST_CASE("DiscreteLogProbabilityTest", "[DistributionTest]") { // Same case as before. DiscreteDistribution d("5 5"); @@ -210,17 +208,17 @@ BOOST_AUTO_TEST_CASE(DiscreteLogProbabilityTest) d.LogProbability(obs, logProb); - BOOST_REQUIRE_EQUAL(logProb.n_elem, 2); + REQUIRE(logProb.n_elem == 2); - BOOST_REQUIRE_CLOSE(logProb(0), -3.2188758248682, 1e-3); - BOOST_REQUIRE_CLOSE(logProb(1), -3.2188758248682, 1e-3); + REQUIRE(logProb(0) == Approx(-3.2188758248682).epsilon(1e-5)); + REQUIRE(logProb(1) == Approx(-3.2188758248682).epsilon(1e-5)); } /** * Test the Probability() function, for multiple points in the multivariate * Discrete case. */ -BOOST_AUTO_TEST_CASE(DiscreteProbabilityTest) +TEST_CASE("DiscreteProbabilityTest", "[DistributionTest]") { // Same case as before. DiscreteDistribution d("5 5"); @@ -232,10 +230,10 @@ BOOST_AUTO_TEST_CASE(DiscreteProbabilityTest) d.Probability(obs, prob); - BOOST_REQUIRE_EQUAL(prob.n_elem, 2); + REQUIRE(prob.n_elem == 2); - BOOST_REQUIRE_CLOSE(prob(0), 0.0400000000000, 1e-3); - BOOST_REQUIRE_CLOSE(prob(1), 0.0400000000000, 1e-3); + REQUIRE(prob(0) == Approx(0.0400000000000).epsilon(1e-5)); + REQUIRE(prob(1) == Approx(0.0400000000000).epsilon(1e-5)); } /*********************************/ @@ -245,32 +243,33 @@ BOOST_AUTO_TEST_CASE(DiscreteProbabilityTest) /** * Make sure Gaussian distributions are initialized correctly. */ -BOOST_AUTO_TEST_CASE(GaussianDistributionEmptyConstructor) +TEST_CASE("GaussianDistributionEmptyConstructor", "[DistributionTest]") { GaussianDistribution d; - BOOST_REQUIRE_EQUAL(d.Mean().n_elem, 0); - BOOST_REQUIRE_EQUAL(d.Covariance().n_elem, 0); + REQUIRE(d.Mean().n_elem == 0); + REQUIRE(d.Covariance().n_elem == 0); } /** * Make sure Gaussian distributions are initialized to the correct * dimensionality. */ -BOOST_AUTO_TEST_CASE(GaussianDistributionDimensionalityConstructor) +TEST_CASE("GaussianDistributionDimensionalityConstructor", + "[DistributionTest]") { GaussianDistribution d(4); - BOOST_REQUIRE_EQUAL(d.Mean().n_elem, 4); - BOOST_REQUIRE_EQUAL(d.Covariance().n_rows, 4); - BOOST_REQUIRE_EQUAL(d.Covariance().n_cols, 4); + REQUIRE(d.Mean().n_elem == 4); + REQUIRE(d.Covariance().n_rows == 4); + REQUIRE(d.Covariance().n_cols == 4); } /** * Make sure Gaussian distributions are initialized correctly when we give a * mean and covariance. */ -BOOST_AUTO_TEST_CASE(GaussianDistributionDistributionConstructor) +TEST_CASE("GaussianDistributionDistributionConstructor", "[DistributionTest]") { arma::vec mean(3); arma::mat covariance(3, 3); @@ -283,17 +282,17 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionDistributionConstructor) GaussianDistribution d(mean, covariance); for (size_t i = 0; i < 3; ++i) - BOOST_REQUIRE_CLOSE(d.Mean()[i], mean[i], 1e-5); + REQUIRE(d.Mean()[i] == Approx(mean[i]).epsilon(1e-7)); for (size_t i = 0; i < 3; ++i) for (size_t j = 0; j < 3; ++j) - BOOST_REQUIRE_CLOSE(d.Covariance()(i, j), covariance(i, j), 1e-5); + REQUIRE(d.Covariance()(i, j) == Approx(covariance(i, j)).epsilon(1e-7)); } /** * Make sure the probability of observations is correct. */ -BOOST_AUTO_TEST_CASE(GaussianDistributionProbabilityTest) +TEST_CASE("GaussianDistributionProbabilityTest", "[DistributionTest]") { arma::vec mean("5 6 3 3 2"); arma::mat cov("6 1 1 1 2;" @@ -304,52 +303,63 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionProbabilityTest) GaussianDistribution d(mean, cov); - BOOST_REQUIRE_CLOSE(d.LogProbability("0 1 2 3 4"), -13.432076798791542, 1e-5); - BOOST_REQUIRE_CLOSE(d.LogProbability("3 2 3 7 8"), -15.814880322345738, 1e-5); - BOOST_REQUIRE_CLOSE(d.LogProbability("2 2 0 8 1"), -13.754462857772776, 1e-5); - BOOST_REQUIRE_CLOSE(d.LogProbability("2 1 5 0 1"), -13.283283233107898, 1e-5); - BOOST_REQUIRE_CLOSE(d.LogProbability("3 0 5 1 0"), -13.800326511545279, 1e-5); - BOOST_REQUIRE_CLOSE(d.LogProbability("4 0 6 1 0"), -14.900192463287908, 1e-5); + REQUIRE(d.LogProbability("0 1 2 3 4") == + Approx(-13.432076798791542).epsilon(1e-7)); + REQUIRE(d.LogProbability("3 2 3 7 8") == + Approx(-15.814880322345738).epsilon(1e-7)); + REQUIRE(d.LogProbability("2 2 0 8 1") == + Approx(-13.754462857772776).epsilon(1e-7)); + REQUIRE(d.LogProbability("2 1 5 0 1") == + Approx(-13.283283233107898).epsilon(1e-7)); + REQUIRE(d.LogProbability("3 0 5 1 0") == + Approx(-13.800326511545279).epsilon(1e-7)); + REQUIRE(d.LogProbability("4 0 6 1 0") == + Approx(-14.900192463287908).epsilon(1e-7)); } /** * Test GaussianDistribution::Probability() in the univariate case. */ -BOOST_AUTO_TEST_CASE(GaussianUnivariateProbabilityTest) +TEST_CASE("GaussianUnivariateProbabilityTest", "[DistributionTest]") { GaussianDistribution g(arma::vec("0.0"), arma::mat("1.0")); // Simple case. - BOOST_REQUIRE_CLOSE(g.Probability(arma::vec("0.0")), 0.398942280401433, 1e-5); - BOOST_REQUIRE_CLOSE(g.Probability(arma::vec("1.0")), 0.241970724519143, 1e-5); - BOOST_REQUIRE_CLOSE(g.Probability(arma::vec("-1.0")), 0.241970724519143, - 1e-5); + REQUIRE(g.Probability(arma::vec("0.0")) == + Approx(0.398942280401433).epsilon(1e-7)); + REQUIRE(g.Probability(arma::vec("1.0")) == + Approx(0.241970724519143).epsilon(1e-7)); + REQUIRE(g.Probability(arma::vec("-1.0")) == + Approx(0.241970724519143).epsilon(1e-7)); // A few more cases... arma::mat covariance; covariance = 2.0; g.Covariance(std::move(covariance)); - BOOST_REQUIRE_CLOSE(g.Probability(arma::vec("0.0")), 0.282094791773878, 1e-5); - BOOST_REQUIRE_CLOSE(g.Probability(arma::vec("1.0")), 0.219695644733861, 1e-5); - BOOST_REQUIRE_CLOSE(g.Probability(arma::vec("-1.0")), 0.219695644733861, - 1e-5); + REQUIRE(g.Probability(arma::vec("0.0")) == + Approx(0.282094791773878).epsilon(1e-7)); + REQUIRE(g.Probability(arma::vec("1.0")) == + Approx(0.219695644733861).epsilon(1e-7)); + REQUIRE(g.Probability(arma::vec("-1.0")) == + Approx(0.219695644733861).epsilon(1e-7)); g.Mean().fill(1.0); covariance = 1.0; g.Covariance(std::move(covariance)); - BOOST_REQUIRE_CLOSE(g.Probability(arma::vec("1.0")), 0.398942280401433, 1e-5); + REQUIRE(g.Probability(arma::vec("1.0")) == + Approx(0.398942280401433).epsilon(1e-7)); covariance = 2.0; g.Covariance(std::move(covariance)); - BOOST_REQUIRE_CLOSE(g.Probability(arma::vec("-1.0")), 0.103776874355149, - 1e-5); + REQUIRE(g.Probability(arma::vec("-1.0")) == + Approx(0.103776874355149).epsilon(1e-7)); } /** * Test GaussianDistribution::Probability() in the multivariate case. */ -BOOST_AUTO_TEST_CASE(GaussianMultivariateProbabilityTest) +TEST_CASE("GaussianMultivariateProbabilityTest", "[DistributionTest]") { // Simple case. arma::vec mean = "0 0"; @@ -358,37 +368,37 @@ BOOST_AUTO_TEST_CASE(GaussianMultivariateProbabilityTest) GaussianDistribution g(mean, cov); - BOOST_REQUIRE_CLOSE(g.Probability(x), 0.159154943091895, 1e-5); + REQUIRE(g.Probability(x) == Approx(0.159154943091895).epsilon(1e-7)); arma::mat covariance; covariance = "2 0; 0 2"; g.Covariance(std::move(covariance)); - BOOST_REQUIRE_CLOSE(g.Probability(x), 0.0795774715459477, 1e-5); + REQUIRE(g.Probability(x) == Approx(0.0795774715459477).epsilon(1e-7)); x = "1 1"; - BOOST_REQUIRE_CLOSE(g.Probability(x), 0.0482661763150270, 1e-5); - BOOST_REQUIRE_CLOSE(g.Probability(-x), 0.0482661763150270, 1e-5); + REQUIRE(g.Probability(x) == Approx(0.0482661763150270).epsilon(1e-7)); + REQUIRE(g.Probability(-x) == Approx(0.0482661763150270).epsilon(1e-7)); g.Mean() = "1 1"; - BOOST_REQUIRE_CLOSE(g.Probability(x), 0.0795774715459477, 1e-5); + REQUIRE(g.Probability(x) == Approx(0.0795774715459477).epsilon(1e-7)); g.Mean() *= -1; - BOOST_REQUIRE_CLOSE(g.Probability(-x), 0.0795774715459477, 1e-5); + REQUIRE(g.Probability(-x) == Approx(0.0795774715459477).epsilon(1e-7)); g.Mean() = "1 1"; covariance = "2 1.5; 1.5 4"; g.Covariance(std::move(covariance)); - BOOST_REQUIRE_CLOSE(g.Probability(x), 0.066372199406187285, 1e-5); + REQUIRE(g.Probability(x) == Approx(0.066372199406187285).epsilon(1e-7)); g.Mean() *= -1; - BOOST_REQUIRE_CLOSE(g.Probability(-x), 0.066372199406187285, 1e-5); + REQUIRE(g.Probability(-x) == Approx(0.066372199406187285).epsilon(1e-7)); g.Mean() = "1 1"; x = "-1 4"; - BOOST_REQUIRE_CLOSE(g.Probability(x), 0.00072147262356379415, 1e-5); - BOOST_REQUIRE_CLOSE(g.Probability(-x), 0.00085851785428674523, 1e-5); + REQUIRE(g.Probability(x) == Approx(0.00072147262356379415).epsilon(1e-7)); + REQUIRE(g.Probability(-x) == Approx(0.00085851785428674523).epsilon(1e-7)); // Higher-dimensional case. x = "0 1 2 3 4"; @@ -401,19 +411,19 @@ BOOST_AUTO_TEST_CASE(GaussianMultivariateProbabilityTest) "2 0 1 0 6"; g.Covariance(std::move(covariance)); - BOOST_REQUIRE_CLOSE(g.Probability(x), 1.4673143531128877e-06, 1e-5); - BOOST_REQUIRE_CLOSE(g.Probability(-x), 7.7404143494891786e-09, 1e-8); + REQUIRE(g.Probability(x) == Approx(1.4673143531128877e-06).epsilon(1e-7)); + REQUIRE(g.Probability(-x) == Approx(7.7404143494891786e-09).epsilon(1e-10)); g.Mean() *= -1; - BOOST_REQUIRE_CLOSE(g.Probability(-x), 1.4673143531128877e-06, 1e-5); - BOOST_REQUIRE_CLOSE(g.Probability(x), 7.7404143494891786e-09, 1e-8); + REQUIRE(g.Probability(-x) == Approx(1.4673143531128877e-06).epsilon(1e-7)); + REQUIRE(g.Probability(x) == Approx(7.7404143494891786e-09).epsilon(1e-10)); } /** * Test the phi() function, for multiple points in the multivariate Gaussian * case. */ -BOOST_AUTO_TEST_CASE(GaussianMultipointMultivariateProbabilityTest) +TEST_CASE("GaussianMultipointMultivariateProbabilityTest", "[DistributionTest]") { // Same case as before. arma::vec mean = "5 6 3 3 2"; @@ -433,20 +443,20 @@ BOOST_AUTO_TEST_CASE(GaussianMultipointMultivariateProbabilityTest) GaussianDistribution g(mean, cov); g.LogProbability(points, phis); - BOOST_REQUIRE_EQUAL(phis.n_elem, 6); + REQUIRE(phis.n_elem == 6); - BOOST_REQUIRE_CLOSE(phis(0), -13.432076798791542, 1e-5); - BOOST_REQUIRE_CLOSE(phis(1), -15.814880322345738, 1e-5); - BOOST_REQUIRE_CLOSE(phis(2), -13.754462857772776, 1e-5); - BOOST_REQUIRE_CLOSE(phis(3), -13.283283233107898, 1e-5); - BOOST_REQUIRE_CLOSE(phis(4), -13.800326511545279, 1e-5); - BOOST_REQUIRE_CLOSE(phis(5), -14.900192463287908, 1e-5); + REQUIRE(phis(0) == Approx(-13.432076798791542).epsilon(1e-7)); + REQUIRE(phis(1) == Approx(-15.814880322345738).epsilon(1e-7)); + REQUIRE(phis(2) == Approx(-13.754462857772776).epsilon(1e-7)); + REQUIRE(phis(3) == Approx(-13.283283233107898).epsilon(1e-7)); + REQUIRE(phis(4) == Approx(-13.800326511545279).epsilon(1e-7)); + REQUIRE(phis(5) == Approx(-14.900192463287908).epsilon(1e-7)); } /** * Make sure random observations follow the probability distribution correctly. */ -BOOST_AUTO_TEST_CASE(GaussianDistributionRandomTest) +TEST_CASE("GaussianDistributionRandomTest", "[DistributionTest]") { arma::vec mean("1.0 2.25"); arma::mat cov("0.85 0.60;" @@ -464,19 +474,19 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionRandomTest) arma::mat obsCov = mlpack::math::ColumnCovariance(obs); // 10% tolerance because this can be noisy. - BOOST_REQUIRE_CLOSE(obsMean[0], mean[0], 10.0); - BOOST_REQUIRE_CLOSE(obsMean[1], mean[1], 10.0); + REQUIRE(obsMean[0] == Approx(mean[0]).epsilon(0.1)); + REQUIRE(obsMean[1] == Approx(mean[1]).epsilon(0.1)); - BOOST_REQUIRE_CLOSE(obsCov(0, 0), cov(0, 0), 10.0); - BOOST_REQUIRE_CLOSE(obsCov(0, 1), cov(0, 1), 10.0); - BOOST_REQUIRE_CLOSE(obsCov(1, 0), cov(1, 0), 10.0); - BOOST_REQUIRE_CLOSE(obsCov(1, 1), cov(1, 1), 10.0); + REQUIRE(obsCov(0, 0) == Approx(cov(0, 0)).epsilon(0.1)); + REQUIRE(obsCov(0, 1) == Approx(cov(0, 1)).epsilon(0.1)); + REQUIRE(obsCov(1, 0) == Approx(cov(1, 0)).epsilon(0.1)); + REQUIRE(obsCov(1, 1) == Approx(cov(1, 1)).epsilon(0.1)); } /** * Make sure that we can properly estimate from given observations. */ -BOOST_AUTO_TEST_CASE(GaussianDistributionTrainTest) +TEST_CASE("GaussianDistributionTrainTest", "[DistributionTest]") { arma::vec mean("1.0 3.0 0.0 2.5"); arma::mat cov("3.0 0.0 1.0 4.0;" @@ -502,18 +512,22 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionTrainTest) // Check that everything is estimated right. for (size_t i = 0; i < 4; ++i) - BOOST_REQUIRE_SMALL(d.Mean()[i] - actualMean[i], 1e-5); + REQUIRE(d.Mean()[i] - actualMean[i] == Approx(0.0).margin(1e-5)); for (size_t i = 0; i < 4; ++i) for (size_t j = 0; j < 4; ++j) - BOOST_REQUIRE_SMALL(d.Covariance()(i, j) - actualCov(i, j), 1e-5); + { + REQUIRE(d.Covariance()(i, j) - actualCov(i, j) == + Approx(0.0).margin(1e-5)); + } } /** * This test verifies the fitting of GaussianDistribution works properly when * probabilities for each sample is given. */ -BOOST_AUTO_TEST_CASE(GaussianDistributionTrainWithProbabilitiesTest) +TEST_CASE("GaussianDistributionTrainWithProbabilitiesTest", + "[DistributionTest]") { arma::vec mean = ("5.0"); arma::vec cov = ("2.0"); @@ -538,18 +552,19 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionTrainWithProbabilitiesTest) GaussianDistribution guDist2; guDist2.Train(rdata); - BOOST_REQUIRE_CLOSE(guDist.Mean()[0], guDist2.Mean()[0], 6); - BOOST_REQUIRE_CLOSE(guDist.Covariance()[0], guDist2.Covariance()[0], 6); + REQUIRE(guDist.Mean()[0] == Approx(guDist2.Mean()[0]).epsilon(0.06)); + REQUIRE(guDist.Covariance()[0] == + Approx(guDist2.Covariance()[0]).epsilon(0.06)); - BOOST_REQUIRE_CLOSE(guDist.Mean()[0], mean[0], 6); - BOOST_REQUIRE_CLOSE(guDist.Covariance()[0], cov[0], 6); + REQUIRE(guDist.Mean()[0] == Approx(mean[0]).epsilon(0.06)); + REQUIRE(guDist.Covariance()[0] == Approx(cov[0]).epsilon(0.06)); } /** * This test ensures that the same result is obtained when trained with * probabilities all set to 1 and with no probabilities at all. */ -BOOST_AUTO_TEST_CASE(GaussianDistributionWithProbabilties1Test) +TEST_CASE("GaussianDistributionWithProbabilties1Test", "[DistributionTest]") { arma::vec mean = ("5.0"); arma::vec cov = ("4.0"); @@ -573,8 +588,9 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionWithProbabilties1Test) GaussianDistribution guDist2; guDist2.Train(rdata, probabilities); - BOOST_REQUIRE_CLOSE(guDist.Mean()[0], guDist2.Mean()[0], 1e-15); - BOOST_REQUIRE_CLOSE(guDist.Covariance()[0], guDist2.Covariance()[0], 1e-2); + REQUIRE(guDist.Mean()[0] == Approx(guDist2.Mean()[0]).epsilon(1e-17)); + REQUIRE(guDist.Covariance()[0] == + Approx(guDist2.Covariance()[0]).epsilon(1e-4)); } /** @@ -585,7 +601,8 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionWithProbabilties1Test) * We expect that the distribution we recover after training to be the same as * the second normal distribution (the one with high probabilities). */ -BOOST_AUTO_TEST_CASE(GaussianDistributionTrainWithTwoDistProbabilitiesTest) +TEST_CASE("GaussianDistributionTrainWithTwoDistProbabilitiesTest", + "[DistributionTest]") { arma::vec mean1 = ("5.0"); arma::vec cov1 = ("4.0"); @@ -626,8 +643,8 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionTrainWithTwoDistProbabilitiesTest) GaussianDistribution guDist; guDist.Train(rdata, probabilities); - BOOST_REQUIRE_CLOSE(guDist.Mean()[0], mean1[0], 5); - BOOST_REQUIRE_CLOSE(guDist.Covariance()[0], cov1[0], 5); + REQUIRE(guDist.Mean()[0] == Approx(mean1[0]).epsilon(0.05)); + REQUIRE(guDist.Covariance()[0] == Approx(cov1[0]).epsilon(0.05)); } /******************************/ @@ -637,7 +654,7 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionTrainWithTwoDistProbabilitiesTest) * Make sure that using an object to fit one reference set and then asking * to fit another works properly. */ -BOOST_AUTO_TEST_CASE(GammaDistributionTrainTest) +TEST_CASE("GammaDistributionTrainTest", "[DistributionTest]") { // Create a gamma distribution random generator. double alphaReal = 5.3; @@ -659,8 +676,8 @@ BOOST_AUTO_TEST_CASE(GammaDistributionTrainTest) gDist.Train(rdata); // Training must estimate d pairs of alpha and beta parameters. - BOOST_REQUIRE_EQUAL(gDist.Dimensionality(), d); - BOOST_REQUIRE_EQUAL(gDist.Dimensionality(), d); + REQUIRE(gDist.Dimensionality() == d); + REQUIRE(gDist.Dimensionality() == d); // Create a N' x d' gamma distribution, fit results without new object. size_t N2 = 350; @@ -676,15 +693,15 @@ BOOST_AUTO_TEST_CASE(GammaDistributionTrainTest) gDist.Train(rdata2); // Training must estimate d' pairs of alpha and beta parameters. - BOOST_REQUIRE_EQUAL(gDist.Dimensionality(), d2); - BOOST_REQUIRE_EQUAL(gDist.Dimensionality(), d2); + REQUIRE(gDist.Dimensionality() == d2); + REQUIRE(gDist.Dimensionality() == d2); } /** * This test verifies that the fitting procedure for GammaDistribution works * properly when probabilities for each sample is given. */ -BOOST_AUTO_TEST_CASE(GammaDistributionTrainWithProbabilitiesTest) +TEST_CASE("GammaDistributionTrainWithProbabilitiesTest", "[DistributionTest]") { double alphaReal = 5.4; double betaReal = 6.7; @@ -711,24 +728,24 @@ BOOST_AUTO_TEST_CASE(GammaDistributionTrainWithProbabilitiesTest) GammaDistribution gDist2; gDist2.Train(rdata); - BOOST_REQUIRE_CLOSE(gDist2.Alpha(0), gDist.Alpha(0), 1.5); - BOOST_REQUIRE_CLOSE(gDist2.Beta(0), gDist.Beta(0), 1.5); + REQUIRE(gDist2.Alpha(0) == Approx(gDist.Alpha(0)).epsilon(0.015)); + REQUIRE(gDist2.Beta(0) == Approx(gDist.Beta(0)).epsilon(0.015)); - BOOST_REQUIRE_CLOSE(gDist2.Alpha(1), gDist.Alpha(1), 1.5); - BOOST_REQUIRE_CLOSE(gDist2.Beta(1), gDist.Beta(1), 1.5); + REQUIRE(gDist2.Alpha(1) == Approx(gDist.Alpha(1)).epsilon(0.015)); + REQUIRE(gDist2.Beta(1) == Approx(gDist.Beta(1)).epsilon(0.015)); - BOOST_REQUIRE_CLOSE(alphaReal, gDist.Alpha(0), 3.0); - BOOST_REQUIRE_CLOSE(betaReal, gDist.Beta(0), 3.0); + REQUIRE(alphaReal == Approx(gDist.Alpha(0)).epsilon(0.03)); + REQUIRE(betaReal == Approx(gDist.Beta(0)).epsilon(0.03)); - BOOST_REQUIRE_CLOSE(alphaReal, gDist.Alpha(1), 3.0); - BOOST_REQUIRE_CLOSE(betaReal, gDist.Beta(1), 3.0); + REQUIRE(alphaReal == Approx(gDist.Alpha(1)).epsilon(0.03)); + REQUIRE(betaReal == Approx(gDist.Beta(1)).epsilon(0.03)); } /** * This test ensures that the same result is obtained when trained with * probabilities all set to 1 and with no probabilities at all. */ -BOOST_AUTO_TEST_CASE(GammaDistributionTrainAllProbabilities1Test) +TEST_CASE("GammaDistributionTrainAllProbabilities1Test", "[DistributionTest]") { double alphaReal = 5.4; double betaReal = 6.7; @@ -753,11 +770,11 @@ BOOST_AUTO_TEST_CASE(GammaDistributionTrainAllProbabilities1Test) arma::vec allProbabilities1(N, arma::fill::ones); gDist2.Train(rdata, allProbabilities1); - BOOST_REQUIRE_CLOSE(gDist2.Alpha(0), gDist.Alpha(0), 1e-5); - BOOST_REQUIRE_CLOSE(gDist2.Beta(0), gDist.Beta(0), 1e-5); + REQUIRE(gDist2.Alpha(0) == Approx(gDist.Alpha(0)).epsilon(1e-7)); + REQUIRE(gDist2.Beta(0) == Approx(gDist.Beta(0)).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(gDist2.Alpha(1), gDist.Alpha(1), 1e-5); - BOOST_REQUIRE_CLOSE(gDist2.Beta(1), gDist.Beta(1), 1e-5); + REQUIRE(gDist2.Alpha(1) == Approx(gDist.Alpha(1)).epsilon(1e-7)); + REQUIRE(gDist2.Beta(1) == Approx(gDist.Beta(1)).epsilon(1e-7)); } /** @@ -767,7 +784,8 @@ BOOST_AUTO_TEST_CASE(GammaDistributionTrainAllProbabilities1Test) * gamma distribution recovered has the same parameters as the second gamma * distribution with high probabilities. */ -BOOST_AUTO_TEST_CASE(GammaDistributionTrainTwoDistProbabilities1Test) +TEST_CASE("GammaDistributionTrainTwoDistProbabilities1Test", + "[DistributionTest]") { double alphaReal = 5.4; double betaReal = 6.7; @@ -807,11 +825,11 @@ BOOST_AUTO_TEST_CASE(GammaDistributionTrainTwoDistProbabilities1Test) GammaDistribution gDist; gDist.Train(rdata, probabilities); - BOOST_REQUIRE_CLOSE(alphaReal2, gDist.Alpha(0), 5); - BOOST_REQUIRE_CLOSE(betaReal2, gDist.Beta(0), 5); + REQUIRE(alphaReal2 == Approx(gDist.Alpha(0)).epsilon(0.05)); + REQUIRE(betaReal2 == Approx(gDist.Beta(0)).epsilon(0.05)); - BOOST_REQUIRE_CLOSE(alphaReal2, gDist.Alpha(1), 5); - BOOST_REQUIRE_CLOSE(betaReal2, gDist.Beta(1), 5); + REQUIRE(alphaReal2 == Approx(gDist.Alpha(1)).epsilon(0.05)); + REQUIRE(betaReal2 == Approx(gDist.Beta(1)).epsilon(0.05)); } /** @@ -820,7 +838,7 @@ BOOST_AUTO_TEST_CASE(GammaDistributionTrainTwoDistProbabilities1Test) * with different alpha/beta parameters so we make sure we don't have some weird * bug that always converges to the same number. */ -BOOST_AUTO_TEST_CASE(GammaDistributionFittingTest) +TEST_CASE("GammaDistributionFittingTest", "[DistributionTest]") { // Offset from the actual alpha/beta. 10% is quite a relaxed tolerance since // the random points we generate are few (for test speed) and might be fitted @@ -848,8 +866,8 @@ BOOST_AUTO_TEST_CASE(GammaDistributionFittingTest) gDist.Train(rdata); // Estimated parameter must be close to real. - BOOST_REQUIRE_CLOSE(gDist.Alpha(0), alphaReal, errorTolerance); - BOOST_REQUIRE_CLOSE(gDist.Beta(0), betaReal, errorTolerance); + REQUIRE(gDist.Alpha(0) == Approx(alphaReal).epsilon(errorTolerance / 100)); + REQUIRE(gDist.Beta(0) == Approx(betaReal).epsilon(errorTolerance / 100)); /** Iteration 2 (different parameter set) **/ @@ -869,15 +887,15 @@ BOOST_AUTO_TEST_CASE(GammaDistributionFittingTest) gDist2.Train(rdata2); // Estimated parameter must be close to real. - BOOST_REQUIRE_CLOSE(gDist2.Alpha(0), alphaReal2, errorTolerance); - BOOST_REQUIRE_CLOSE(gDist2.Beta(0), betaReal2, errorTolerance); + REQUIRE(gDist2.Alpha(0) == Approx(alphaReal2).epsilon(errorTolerance / 100)); + REQUIRE(gDist2.Beta(0) == Approx(betaReal2).epsilon(errorTolerance / 100)); } /** * Test that Train() and the constructor that takes data give the same resulting * distribution. */ -BOOST_AUTO_TEST_CASE(GammaDistributionTrainConstructorTest) +TEST_CASE("GammaDistributionTrainConstructorTest", "[DistributionTest]") { const arma::mat data = arma::randu(10, 500); @@ -887,8 +905,8 @@ BOOST_AUTO_TEST_CASE(GammaDistributionTrainConstructorTest) for (size_t i = 0; i < 10; ++i) { - BOOST_REQUIRE_CLOSE(d1.Alpha(i), d2.Alpha(i), 1e-5); - BOOST_REQUIRE_CLOSE(d1.Beta(i), d2.Beta(i), 1e-5); + REQUIRE(d1.Alpha(i) == Approx(d2.Alpha(i)).epsilon(1e-7)); + REQUIRE(d1.Beta(i) == Approx(d2.Beta(i)).epsilon(1e-7)); } } @@ -896,7 +914,7 @@ BOOST_AUTO_TEST_CASE(GammaDistributionTrainConstructorTest) * Test that Train() with a dataset and Train() with dataset statistics return * the same results. */ -BOOST_AUTO_TEST_CASE(GammaDistributionTrainStatisticsTest) +TEST_CASE("GammaDistributionTrainStatisticsTest", "[DistributionTest]") { const arma::mat data = arma::randu(1, 500); @@ -910,15 +928,15 @@ BOOST_AUTO_TEST_CASE(GammaDistributionTrainStatisticsTest) const arma::vec logMeanx = arma::log(meanx); d2.Train(logMeanx, meanLogx, meanx); - BOOST_REQUIRE_CLOSE(d1.Alpha(0), d2.Alpha(0), 1e-5); - BOOST_REQUIRE_CLOSE(d1.Beta(0), d2.Beta(0), 1e-5); + REQUIRE(d1.Alpha(0) == Approx(d2.Alpha(0)).epsilon(1e-7)); + REQUIRE(d1.Beta(0) == Approx(d2.Beta(0)).epsilon(1e-7)); } /** * Tests that Random() generates points that can be reasonably well fit by the * distribution that generated them. */ -BOOST_AUTO_TEST_CASE(GammaDistributionRandomTest) +TEST_CASE("GammaDistributionRandomTest", "[DistributionTest]") { const arma::vec a("2.0 2.5 3.0"), b("0.4 0.6 1.3"); const size_t numPoints = 2000; @@ -934,12 +952,12 @@ BOOST_AUTO_TEST_CASE(GammaDistributionRandomTest) GammaDistribution d2(data); for (size_t i = 0; i < 3; ++i) { - BOOST_REQUIRE_CLOSE(d2.Alpha(i), a(i), 10); // Within 10% - BOOST_REQUIRE_CLOSE(d2.Beta(i), b(i), 10); + REQUIRE(d2.Alpha(i) == Approx(a(i)).epsilon(0.1)); // Within 10% + REQUIRE(d2.Beta(i) == Approx(b(i)).epsilon(0.1)); } } -BOOST_AUTO_TEST_CASE(GammaDistributionProbabilityTest) +TEST_CASE("GammaDistributionProbabilityTest", "[DistributionTest]") { // Train two 1-dimensional distributions. const arma::vec a1("2.0"), b1("0.9"), a2("3.1"), b2("1.4"); @@ -949,16 +967,16 @@ BOOST_AUTO_TEST_CASE(GammaDistributionProbabilityTest) // Evaluated at wolfram|alpha GammaDistribution d1(a1, b1); d1.Probability(x1, prob1); - BOOST_REQUIRE_CLOSE(prob1(0), 0.267575, 1e-3); + REQUIRE(prob1(0) == Approx(0.267575).epsilon(1e-5)); // Evaluated at wolfram|alpha GammaDistribution d2(a2, b2); d2.Probability(x2, prob2); - BOOST_REQUIRE_CLOSE(prob2(0), 0.189043, 1e-3); + REQUIRE(prob2(0) == Approx(0.189043).epsilon(1e-5)); // Check that the overload that returns the probability for 1 dimension // agrees. - BOOST_REQUIRE_CLOSE(prob2(0), d2.Probability(2.94, 0), 1e-5); + REQUIRE(prob2(0) == Approx(d2.Probability(2.94, 0)).epsilon(1e-7)); // Combine into one 2-dimensional distribution. const arma::vec a3("2.0 3.1"), b3("0.9 1.4"); @@ -971,11 +989,11 @@ BOOST_AUTO_TEST_CASE(GammaDistributionProbabilityTest) // 1-dimensional distributions (evaluated at wolfram|alpha). GammaDistribution d3(a3, b3); d3.Probability(x3, prob3); - BOOST_REQUIRE_CLOSE(prob3(0), 0.04408, 1e-2); - BOOST_REQUIRE_CLOSE(prob3(1), 0.026165, 1e-2); + REQUIRE(prob3(0) == Approx(0.04408).epsilon(1e-4)); + REQUIRE(prob3(1) == Approx(0.026165).epsilon(1e-4)); } -BOOST_AUTO_TEST_CASE(GammaDistributionLogProbabilityTest) +TEST_CASE("GammaDistributionLogProbabilityTest", "[DistributionTest]") { // Train two 1-dimensional distributions. const arma::vec a1("2.0"), b1("0.9"), a2("3.1"), b2("1.4"); @@ -985,16 +1003,16 @@ BOOST_AUTO_TEST_CASE(GammaDistributionLogProbabilityTest) // Evaluated at wolfram|alpha GammaDistribution d1(a1, b1); d1.LogProbability(x1, logprob1); - BOOST_REQUIRE_CLOSE(logprob1(0), std::log(0.267575), 1e-3); + REQUIRE(logprob1(0) == Approx(std::log(0.267575)).epsilon(1e-5)); // Evaluated at wolfram|alpha GammaDistribution d2(a2, b2); d2.LogProbability(x2, logprob2); - BOOST_REQUIRE_CLOSE(logprob2(0), std::log(0.189043), 1e-3); + REQUIRE(logprob2(0) == Approx(std::log(0.189043)).epsilon(1e-5)); // Check that the overload that returns the log probability for // 1 dimension agrees. - BOOST_REQUIRE_CLOSE(logprob2(0), d2.LogProbability(2.94, 0), 1e-5); + REQUIRE(logprob2(0) == Approx(d2.LogProbability(2.94, 0)).epsilon(1e-7)); // Combine into one 2-dimensional distribution. const arma::vec a3("2.0 3.1"), b3("0.9 1.4"); @@ -1008,14 +1026,14 @@ BOOST_AUTO_TEST_CASE(GammaDistributionLogProbabilityTest) // 1-dimensional distributions (evaluated at wolfram|alpha). GammaDistribution d3(a3, b3); d3.LogProbability(x3, logprob3); - BOOST_REQUIRE_CLOSE(logprob3(0), std::log(0.04408), 1e-3); - BOOST_REQUIRE_CLOSE(logprob3(1), std::log(0.026165), 1e-3); + REQUIRE(logprob3(0) == Approx(std::log(0.04408)).epsilon(1e-5)); + REQUIRE(logprob3(1) == Approx(std::log(0.026165)).epsilon(1e-5)); } /** * Discrete Distribution serialization test. */ -BOOST_AUTO_TEST_CASE(DiscreteDistributionTest) +TEST_CASE("DiscreteDistributionTest", "[DistributionTest]") { // I assume that I am properly saving vectors, so, this should be // straightforward. @@ -1036,15 +1054,15 @@ BOOST_AUTO_TEST_CASE(DiscreteDistributionTest) const double prob = t.Probability(obs); if (prob == 0.0) { - BOOST_REQUIRE_SMALL(xmlT.Probability(obs), 1e-8); - BOOST_REQUIRE_SMALL(textT.Probability(obs), 1e-8); - BOOST_REQUIRE_SMALL(binaryT.Probability(obs), 1e-8); + REQUIRE(xmlT.Probability(obs) == Approx(0.0).margin(1e-8)); + REQUIRE(textT.Probability(obs) == Approx(0.0).margin(1e-8)); + REQUIRE(binaryT.Probability(obs) == Approx(0.0).margin(1e-8)); } else { - BOOST_REQUIRE_CLOSE(prob, xmlT.Probability(obs), 1e-8); - BOOST_REQUIRE_CLOSE(prob, textT.Probability(obs), 1e-8); - BOOST_REQUIRE_CLOSE(prob, binaryT.Probability(obs), 1e-8); + REQUIRE(prob == Approx(xmlT.Probability(obs)).epsilon(1e-10)); + REQUIRE(prob == Approx(textT.Probability(obs)).epsilon(1e-10)); + REQUIRE(prob == Approx(binaryT.Probability(obs)).epsilon(1e-10)); } } } @@ -1052,7 +1070,7 @@ BOOST_AUTO_TEST_CASE(DiscreteDistributionTest) /** * Gaussian Distribution serialization test. */ -BOOST_AUTO_TEST_CASE(GaussianDistributionTest) +TEST_CASE("GaussianDistributionTest", "[DistributionTest]") { arma::vec mean(10); mean.randu(); @@ -1066,9 +1084,9 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionTest) SerializeObjectAll(g, xmlG, textG, binaryG); - BOOST_REQUIRE_EQUAL(g.Dimensionality(), xmlG.Dimensionality()); - BOOST_REQUIRE_EQUAL(g.Dimensionality(), textG.Dimensionality()); - BOOST_REQUIRE_EQUAL(g.Dimensionality(), binaryG.Dimensionality()); + REQUIRE(g.Dimensionality() == xmlG.Dimensionality()); + REQUIRE(g.Dimensionality() == textG.Dimensionality()); + REQUIRE(g.Dimensionality() == binaryG.Dimensionality()); // First, check the means. CheckMatrices(g.Mean(), xmlG.Mean(), textG.Mean(), binaryG.Mean()); @@ -1088,18 +1106,21 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionTest) if (prob == 0.0) { - BOOST_REQUIRE_SMALL(xmlG.Probability(randomObs.unsafe_col(i)), 1e-8); - BOOST_REQUIRE_SMALL(textG.Probability(randomObs.unsafe_col(i)), 1e-8); - BOOST_REQUIRE_SMALL(binaryG.Probability(randomObs.unsafe_col(i)), 1e-8); + REQUIRE(xmlG.Probability(randomObs.unsafe_col(i)) == + Approx(0.0).margin(1e-8)); + REQUIRE(textG.Probability(randomObs.unsafe_col(i)) == + Approx(0.0).margin(1e-8)); + REQUIRE(binaryG.Probability(randomObs.unsafe_col(i)) == + Approx(0.0).margin(1e-8)); } else { - BOOST_REQUIRE_CLOSE(prob, xmlG.Probability(randomObs.unsafe_col(i)), - 1e-8); - BOOST_REQUIRE_CLOSE(prob, textG.Probability(randomObs.unsafe_col(i)), - 1e-8); - BOOST_REQUIRE_CLOSE(prob, binaryG.Probability(randomObs.unsafe_col(i)), - 1e-8); + REQUIRE(prob == + Approx(xmlG.Probability(randomObs.unsafe_col(i))).epsilon(1e-10)); + REQUIRE(prob == + Approx(textG.Probability(randomObs.unsafe_col(i))).epsilon(1e-10)); + REQUIRE(prob == + Approx(binaryG.Probability(randomObs.unsafe_col(i))).epsilon(1e-10)); } } } @@ -1107,7 +1128,7 @@ BOOST_AUTO_TEST_CASE(GaussianDistributionTest) /** * Laplace Distribution serialization test. */ -BOOST_AUTO_TEST_CASE(LaplaceDistributionTest) +TEST_CASE("LaplaceDistributionTest", "[DistributionTest]") { arma::vec mean(20); mean.randu(); @@ -1117,9 +1138,9 @@ BOOST_AUTO_TEST_CASE(LaplaceDistributionTest) SerializeObjectAll(l, xmlL, textL, binaryL); - BOOST_REQUIRE_CLOSE(l.Scale(), xmlL.Scale(), 1e-8); - BOOST_REQUIRE_CLOSE(l.Scale(), textL.Scale(), 1e-8); - BOOST_REQUIRE_CLOSE(l.Scale(), binaryL.Scale(), 1e-8); + REQUIRE(l.Scale() == Approx(xmlL.Scale()).epsilon(1e-10)); + REQUIRE(l.Scale() == Approx(textL.Scale()).epsilon(1e-10)); + REQUIRE(l.Scale() == Approx(binaryL.Scale()).epsilon(1e-10)); CheckMatrices(l.Mean(), xmlL.Mean(), textL.Mean(), binaryL.Mean()); } @@ -1127,15 +1148,15 @@ BOOST_AUTO_TEST_CASE(LaplaceDistributionTest) /** * Laplace Distribution Probability Test. */ -BOOST_AUTO_TEST_CASE(LaplaceDistributionProbabilityTest) +TEST_CASE("LaplaceDistributionProbabilityTest", "[DistributionTest]") { LaplaceDistribution l(arma::vec("0.0"), 1.0); // Simple case. - BOOST_REQUIRE_CLOSE(l.Probability(arma::vec("0.0")), - 0.500000000000000, 1e-5); - BOOST_REQUIRE_CLOSE(l.Probability(arma::vec("1.0")), - 0.183939720585721, 1e-5); + REQUIRE(l.Probability(arma::vec("0.0")) == + Approx(0.500000000000000).epsilon(1e-7)); + REQUIRE(l.Probability(arma::vec("1.0")) == + Approx(0.183939720585721).epsilon(1e-7)); arma::mat points = "0.0 1.0;"; @@ -1143,24 +1164,24 @@ BOOST_AUTO_TEST_CASE(LaplaceDistributionProbabilityTest) l.Probability(points, probabilities); - BOOST_REQUIRE_EQUAL(probabilities.n_elem, 2); + REQUIRE(probabilities.n_elem == 2); - BOOST_REQUIRE_CLOSE(probabilities(0), 0.500000000000000, 1e-5); - BOOST_REQUIRE_CLOSE(probabilities(1), 0.183939720585721, 1e-5); + REQUIRE(probabilities(0) == Approx(0.500000000000000).epsilon(1e-7)); + REQUIRE(probabilities(1) == Approx(0.183939720585721).epsilon(1e-7)); } /** * Laplace Distribution Log Probability Test. */ -BOOST_AUTO_TEST_CASE(LaplaceDistributionLogProbabilityTest) +TEST_CASE("LaplaceDistributionLogProbabilityTest", "[DistributionTest]") { LaplaceDistribution l(arma::vec("0.0"), 1.0); // Simple case. - BOOST_REQUIRE_CLOSE(l.LogProbability(arma::vec("0.0")), - -0.693147180559945, 1e-5); - BOOST_REQUIRE_CLOSE(l.LogProbability(arma::vec("1.0")), - -1.693147180559946, 1e-5); + REQUIRE(l.LogProbability(arma::vec("0.0")) == + Approx(-0.693147180559945).epsilon(1e-7)); + REQUIRE(l.LogProbability(arma::vec("1.0")) == + Approx(-1.693147180559946).epsilon(1e-7)); arma::mat points = "0.0 1.0;"; @@ -1168,18 +1189,19 @@ BOOST_AUTO_TEST_CASE(LaplaceDistributionLogProbabilityTest) l.LogProbability(points, logProbabilities); - BOOST_REQUIRE_EQUAL(logProbabilities.n_elem, 2); + REQUIRE(logProbabilities.n_elem == 2); - BOOST_REQUIRE_CLOSE(logProbabilities(0), -0.693147180559945, - 1e-5); - BOOST_REQUIRE_CLOSE(logProbabilities(1), -1.693147180559946, - 1e-5); + REQUIRE(logProbabilities(0) == + Approx(-0.693147180559945).epsilon(1e-7)); + + REQUIRE(logProbabilities(1) == + Approx(-1.693147180559946).epsilon(1e-7)); } /** * Mahalanobis Distance serialization test. */ -BOOST_AUTO_TEST_CASE(MahalanobisDistanceTest) +TEST_CASE("MahalanobisDistanceTest", "[DistributionTest]") { MahalanobisDistance<> d; d.Covariance().randu(50, 50); @@ -1198,7 +1220,7 @@ BOOST_AUTO_TEST_CASE(MahalanobisDistanceTest) /** * Regression distribution serialization test. */ -BOOST_AUTO_TEST_CASE(RegressionDistributionTest) +TEST_CASE("RegressionDistributionTest", "[DistributionTest]") { // Generate some random data. arma::mat data; @@ -1225,15 +1247,15 @@ BOOST_AUTO_TEST_CASE(RegressionDistributionTest) // Check the regression function. if (rd.Rf().Lambda() == 0.0) { - BOOST_REQUIRE_SMALL(xmlRd.Rf().Lambda(), 1e-8); - BOOST_REQUIRE_SMALL(textRd.Rf().Lambda(), 1e-8); - BOOST_REQUIRE_SMALL(binaryRd.Rf().Lambda(), 1e-8); + REQUIRE(xmlRd.Rf().Lambda() == Approx(0.0).margin(1e-8)); + REQUIRE(textRd.Rf().Lambda() == Approx(0.0).margin(1e-8)); + REQUIRE(binaryRd.Rf().Lambda() == Approx(0.0).margin(1e-8)); } else { - BOOST_REQUIRE_CLOSE(rd.Rf().Lambda(), xmlRd.Rf().Lambda(), 1e-8); - BOOST_REQUIRE_CLOSE(rd.Rf().Lambda(), textRd.Rf().Lambda(), 1e-8); - BOOST_REQUIRE_CLOSE(rd.Rf().Lambda(), binaryRd.Rf().Lambda(), 1e-8); + REQUIRE(rd.Rf().Lambda() == Approx(xmlRd.Rf().Lambda()).epsilon(1e-10)); + REQUIRE(rd.Rf().Lambda() == Approx(textRd.Rf().Lambda()).epsilon(1e-10)); + REQUIRE(rd.Rf().Lambda() == Approx(binaryRd.Rf().Lambda()).epsilon(1e-10)); } CheckMatrices(rd.Rf().Parameters(), @@ -1250,31 +1272,32 @@ BOOST_AUTO_TEST_CASE(RegressionDistributionTest) * Make sure Diagonal Covariance Gaussian distributions are initialized * correctly. */ -BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionEmptyConstructor) +TEST_CASE("DiagonalGaussianDistributionEmptyConstructor", "[DistributionTest]") { DiagonalGaussianDistribution d; - BOOST_REQUIRE_EQUAL(d.Mean().n_elem, 0); - BOOST_REQUIRE_EQUAL(d.Covariance().n_elem, 0); + REQUIRE(d.Mean().n_elem == 0); + REQUIRE(d.Covariance().n_elem == 0); } /** * Make sure Diagonal Covariance Gaussian distributions are initialized to * the correct dimensionality. */ -BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionDimensionalityConstructor) +TEST_CASE("DiagonalGaussianDistributionDimensionalityConstructor", + "[DistributionTest]") { DiagonalGaussianDistribution d(4); - BOOST_REQUIRE_EQUAL(d.Mean().n_elem, 4); - BOOST_REQUIRE_EQUAL(d.Covariance().n_elem, 4); + REQUIRE(d.Mean().n_elem == 4); + REQUIRE(d.Covariance().n_elem == 4); } /** * Make sure Diagonal Covariance Gaussian distributions are initialized * correctly when we give a mean and covariance. */ -BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionConstructor) +TEST_CASE("DiagonalGaussianDistributionConstructor", "[DistributionTest]") { arma::vec mean = arma::randu(3); arma::vec covariance = arma::randu(3); @@ -1284,8 +1307,8 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionConstructor) // Make sure the mean and covariance is correct. for (size_t i = 0; i < 3; ++i) { - BOOST_REQUIRE_CLOSE(d.Mean()(i), mean(i), 1e-5); - BOOST_REQUIRE_CLOSE(d.Covariance()(i), covariance(i), 1e-5); + REQUIRE(d.Mean()(i) == Approx(mean(i)).epsilon(1e-7)); + REQUIRE(d.Covariance()(i) == Approx(covariance(i)).epsilon(1e-7)); } } @@ -1293,7 +1316,7 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionConstructor) * Make sure the probability of observations is correct. * The values were calculated using 'dmvnorm' in R. */ -BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionProbabilityTest) +TEST_CASE("DiagonalGaussianDistributionProbabilityTest", "[DistributionTest]") { arma::vec mean("2 5 3 4 1"); arma::vec cov("3 1 5 3 2"); @@ -1301,56 +1324,56 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionProbabilityTest) DiagonalGaussianDistribution d(mean, cov); // Observations lists randomly selected. - BOOST_REQUIRE_CLOSE(d.LogProbability("3 5 2 7 8"), -20.861264167855161, - 1e-5); - BOOST_REQUIRE_CLOSE(d.LogProbability("7 8 4 0 5"), -22.277930834521829, - 1e-5); - BOOST_REQUIRE_CLOSE(d.LogProbability("6 8 7 7 5"), -21.111264167855161, - 1e-5); - BOOST_REQUIRE_CLOSE(d.LogProbability("2 9 5 6 3"), -16.911264167855162, - 1e-5); - BOOST_REQUIRE_CLOSE(d.LogProbability("5 8 2 9 7"), -26.111264167855161, - 1e-5); + REQUIRE(d.LogProbability("3 5 2 7 8") == + Approx(-20.861264167855161).epsilon(1e-7)); + REQUIRE(d.LogProbability("7 8 4 0 5") == + Approx(-22.277930834521829).epsilon(1e-7)); + REQUIRE(d.LogProbability("6 8 7 7 5") == + Approx(-21.111264167855161).epsilon(1e-7)); + REQUIRE(d.LogProbability("2 9 5 6 3") == + Approx(-16.9112641678551621).epsilon(1e-7)); + REQUIRE(d.LogProbability("5 8 2 9 7") == + Approx(-26.111264167855161).epsilon(1e-7)); } /** * Test DiagonalGaussianDistribution::Probability() in the univariate case. * The values were calculated using 'dmvnorm' in R. */ -BOOST_AUTO_TEST_CASE(DiagonalGaussianUnivariateProbabilityTest) +TEST_CASE("DiagonalGaussianUnivariateProbabilityTest", "[DistributionTest]") { DiagonalGaussianDistribution d(arma::vec("0.0"), arma::vec("1.0")); // Mean: 0.0, Covariance: 1.0 - BOOST_REQUIRE_CLOSE(d.Probability("0.0"), 0.3989422804014327, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("1.0"), 0.24197072451914337, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("-1.0"), 0.24197072451914337, 1e-5); + REQUIRE(d.Probability("0.0") == Approx(0.3989422804014327).epsilon(1e-7)); + REQUIRE(d.Probability("1.0") == Approx(0.24197072451914337).epsilon(1e-7)); + REQUIRE(d.Probability("-1.0") == Approx(0.24197072451914337).epsilon(1e-7)); // Mean: 0.0, Covariance: 2.0 d.Covariance("2.0"); - BOOST_REQUIRE_CLOSE(d.Probability("0.0"), 0.28209479177387814, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("1.0"), 0.21969564473386122, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("-1.0"), 0.21969564473386122, 1e-5); + REQUIRE(d.Probability("0.0") == Approx(0.28209479177387814).epsilon(1e-7)); + REQUIRE(d.Probability("1.0") == Approx(0.21969564473386122).epsilon(1e-7)); + REQUIRE(d.Probability("-1.0") == Approx(0.21969564473386122).epsilon(1e-7)); // Mean: 1.0, Covariance: 1.0 d.Mean() = "1.0"; d.Covariance("1.0"); - BOOST_REQUIRE_CLOSE(d.Probability("0.0"), 0.24197072451914337, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("1.0"), 0.3989422804014327, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("-1.0"), 0.053990966513188056, 1e-5); + REQUIRE(d.Probability("0.0") == Approx(0.24197072451914337).epsilon(1e-7)); + REQUIRE(d.Probability("1.0") == Approx(0.3989422804014327).epsilon(1e-7)); + REQUIRE(d.Probability("-1.0") == Approx(0.053990966513188056).epsilon(1e-7)); // Mean: 1.0, Covariance: 2.0 d.Covariance("2.0"); - BOOST_REQUIRE_CLOSE(d.Probability("0.0"), 0.21969564473386122, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("1.0"), 0.28209479177387814, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability("-1.0"), 0.10377687435514872, 1e-5); + REQUIRE(d.Probability("0.0") == Approx(0.21969564473386122).epsilon(1e-7)); + REQUIRE(d.Probability("1.0") == Approx(0.28209479177387814).epsilon(1e-7)); + REQUIRE(d.Probability("-1.0") == Approx(0.10377687435514872).epsilon(1e-7)); } /** * Test DiagonalGaussianDistribution::Probability() in the multivariate case. * The values were calculated using 'dmvnorm' in R. */ -BOOST_AUTO_TEST_CASE(DiagonalGaussianMultivariateProbabilityTest) +TEST_CASE("DiagonalGaussianMultivariateProbabilityTest", "[DistributionTest]") { arma::vec mean("0 0"); arma::vec cov("2 2"); @@ -1358,27 +1381,28 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianMultivariateProbabilityTest) DiagonalGaussianDistribution d(mean, cov); - BOOST_REQUIRE_CLOSE(d.Probability(obs), 0.079577471545947673, 1e-5); + REQUIRE(d.Probability(obs) == Approx(0.079577471545947673).epsilon(1e-7)); obs = "1 1"; - BOOST_REQUIRE_CLOSE(d.Probability(obs), 0.048266176315026957, 1e-5); + REQUIRE(d.Probability(obs) == Approx(0.048266176315026957).epsilon(1e-7)); d.Mean() = "1 3"; - BOOST_REQUIRE_CLOSE(d.Probability(obs), 0.029274915762159581, 1e-5); - BOOST_REQUIRE_CLOSE(d.Probability(-obs), 0.00053618878559782773, 1e-5); + REQUIRE(d.Probability(obs) == Approx(0.029274915762159581).epsilon(1e-7)); + REQUIRE(d.Probability(-obs) == Approx(0.00053618878559782773).epsilon(1e-7)); // Higher dimensional case. d.Mean() = "1 3 6 2 7"; d.Covariance("3 1 5 3 2"); obs = "2 5 7 3 8"; - BOOST_REQUIRE_CLOSE(d.Probability(obs), 7.2790083003378082e-05, 1e-5); + REQUIRE(d.Probability(obs) == Approx(7.2790083003378082e-05).epsilon(1e-7)); } /** * Test the phi() function, for multiple points in the multivariate Gaussian * case. The values were calculated using 'dmvnorm' in R. */ -BOOST_AUTO_TEST_CASE(DiagonalGaussianMultipointMultivariateProbabilityTest) +TEST_CASE("DiagonalGaussianMultipointMultivariateProbabilityTest", + "[DistributionTest]") { arma::vec mean = "2 5 3 7 2"; arma::vec cov("9 2 1 4 8"); @@ -1391,20 +1415,20 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianMultipointMultivariateProbabilityTest) DiagonalGaussianDistribution d(mean, cov); d.LogProbability(points, phis); - BOOST_REQUIRE_EQUAL(phis.n_elem, 6); + REQUIRE(phis.n_elem == 6); - BOOST_REQUIRE_CLOSE(phis(0), -12.453302051926864, 1e-5); - BOOST_REQUIRE_CLOSE(phis(1), -10.147746496371308, 1e-5); - BOOST_REQUIRE_CLOSE(phis(2), -13.210246496371308, 1e-5); - BOOST_REQUIRE_CLOSE(phis(3), -19.724135385260197, 1e-5); - BOOST_REQUIRE_CLOSE(phis(4), -21.585246496371308, 1e-5); - BOOST_REQUIRE_CLOSE(phis(5), -13.647746496371308, 1e-5); + REQUIRE(phis(0) == Approx(-12.453302051926864).epsilon(1e-7)); + REQUIRE(phis(1) == Approx(-10.147746496371308).epsilon(1e-7)); + REQUIRE(phis(2) == Approx(-13.210246496371308).epsilon(1e-7)); + REQUIRE(phis(3) == Approx(-19.724135385260197).epsilon(1e-7)); + REQUIRE(phis(4) == Approx(-21.585246496371308).epsilon(1e-7)); + REQUIRE(phis(5) == Approx(-13.647746496371308).epsilon(1e-7)); } /** * Make sure random observations follow the probability distribution correctly. */ -BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionRandomTest) +TEST_CASE("DiagonalGaussianDistributionRandomTest", "[DistributionTest]") { arma::vec mean("2.5 1.25"); arma::vec cov("0.50 0.25"); @@ -1421,17 +1445,17 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionRandomTest) arma::mat obsCov = mlpack::math::ColumnCovariance(obs); // 10% tolerance because this can be noisy. - BOOST_REQUIRE_CLOSE(obsMean(0), mean(0), 10.0); - BOOST_REQUIRE_CLOSE(obsMean(1), mean(1), 10.0); + REQUIRE(obsMean(0) == Approx(mean(0)).epsilon(0.1)); + REQUIRE(obsMean(1) == Approx(mean(1)).epsilon(0.1)); - BOOST_REQUIRE_CLOSE(obsCov(0, 0), cov(0), 10); - BOOST_REQUIRE_CLOSE(obsCov(1, 1), cov(1), 10); + REQUIRE(obsCov(0, 0) == Approx(cov(0)).epsilon(0.1)); + REQUIRE(obsCov(1, 1) == Approx(cov(1)).epsilon(0.1)); } /** * Make sure that we can properly estimate from given observations. */ -BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionTrainTest) +TEST_CASE("DiagonalGaussianDistributionTrainTest", "[DistributionTest]") { arma::vec mean("2.5 1.5 8.2 3.1"); arma::vec cov("1.2 3.1 8.3 4.3"); @@ -1454,8 +1478,8 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionTrainTest) // Check that the estimated parameters are right. for (size_t i = 0; i < 4; ++i) { - BOOST_REQUIRE_SMALL(d.Mean()(i) - actualMean(i), 1e-5); - BOOST_REQUIRE_SMALL(d.Covariance()(i) - actualCov(i, i), 1e-5); + REQUIRE(d.Mean()(i) - actualMean(i) == Approx(0.0).margin(1e-5)); + REQUIRE(d.Covariance()(i) - actualCov(i, i) == Approx(0.0).margin(1e-5)); } } @@ -1463,7 +1487,7 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianDistributionTrainTest) * Make sure the unbiased estimator of the weighted sample works correctly. * The values were calculated using 'cov.wt' in R. */ -BOOST_AUTO_TEST_CASE(DiagonalGaussianUnbiasedEstimatorTest) +TEST_CASE("DiagonalGaussianUnbiasedEstimatorTest", "[DistributionTest]") { // Generate the observations. arma::mat observations("3 5 2 7;" @@ -1478,15 +1502,15 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianUnbiasedEstimatorTest) // Estimate the parameters. d.Train(observations, probs); - BOOST_REQUIRE_CLOSE(d.Mean()(0), 4.5, 1e-5); - BOOST_REQUIRE_CLOSE(d.Mean()(1), 4.4, 1e-5); - BOOST_REQUIRE_CLOSE(d.Mean()(2), 3.5, 1e-5); - BOOST_REQUIRE_CLOSE(d.Mean()(3), 6.8, 1e-5); + REQUIRE(d.Mean()(0) == Approx(4.5).epsilon(1e-7)); + REQUIRE(d.Mean()(1) == Approx(4.4).epsilon(1e-7)); + REQUIRE(d.Mean()(2) == Approx(3.5).epsilon(1e-7)); + REQUIRE(d.Mean()(3) == Approx(6.8).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(d.Covariance()(0), 3.78571428571428603, 1e-5); - BOOST_REQUIRE_CLOSE(d.Covariance()(1), 6.34285714285714253, 1e-5); - BOOST_REQUIRE_CLOSE(d.Covariance()(2), 6.64285714285714235, 1e-5); - BOOST_REQUIRE_CLOSE(d.Covariance()(3), 2.22857142857142865, 1e-5); + REQUIRE(d.Covariance()(0) == Approx(3.78571428571428603).epsilon(1e-7)); + REQUIRE(d.Covariance()(1) == Approx(6.34285714285714253).epsilon(1e-7)); + REQUIRE(d.Covariance()(2) == Approx(6.64285714285714235).epsilon(1e-7)); + REQUIRE(d.Covariance()(3) == Approx(2.22857142857142865).epsilon(1e-7)); } /** @@ -1494,7 +1518,7 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianUnbiasedEstimatorTest) * the weighted mean and covariance reduce to the unweighted sample mean and * covariance. */ -BOOST_AUTO_TEST_CASE(DiagonalGaussianWeightedParametersReductionTest) +TEST_CASE("DiagonalGaussianWeightedParametersReductionTest", "[DistributionTest]") { arma::vec mean("2.5 1.5 8.2 3.1"); arma::vec cov("1.2 3.1 8.3 4.3"); @@ -1516,9 +1540,7 @@ BOOST_AUTO_TEST_CASE(DiagonalGaussianWeightedParametersReductionTest) // Check if these are equal. for (size_t i = 0; i < 4; ++i) { - BOOST_REQUIRE_CLOSE(d1.Mean()(i), d2.Mean()(i), 1e-5); - BOOST_REQUIRE_CLOSE(d1.Covariance()(i), d2.Covariance()(i), 1e-5); + REQUIRE(d1.Mean()(i) == Approx(d2.Mean()(i)).epsilon(1e-7)); + REQUIRE(d1.Covariance()(i) == Approx(d2.Covariance()(i)).epsilon(1e-7)); } } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/hoeffding_tree_test.cpp b/src/mlpack/tests/hoeffding_tree_test.cpp index 341fac69e3..32a87e29fb 100644 --- a/src/mlpack/tests/hoeffding_tree_test.cpp +++ b/src/mlpack/tests/hoeffding_tree_test.cpp @@ -17,9 +17,9 @@ #include #include -#include -#include "test_tools.hpp" -#include "serialization.hpp" +#include "catch.hpp" +#include "test_catch_tools.hpp" +#include "serialization_catch.hpp" #include @@ -30,9 +30,7 @@ using namespace mlpack::math; using namespace mlpack::data; using namespace mlpack::tree; -BOOST_AUTO_TEST_SUITE(HoeffdingTreeTest); - -BOOST_AUTO_TEST_CASE(GiniImpurityPerfectSimpleTest) +TEST_CASE("GiniImpurityPerfectSimpleTest", "[HoeffdingTreeTest]") { // Make a simple test for Gini impurity with one class. In this case it // should always be 0. We'll assemble the count matrix by hand. @@ -44,10 +42,10 @@ BOOST_AUTO_TEST_CASE(GiniImpurityPerfectSimpleTest) counts(1, 1) = 0; // 0 points in category 1 with class 1. // Since the split gets us nothing, there should be no gain. - BOOST_REQUIRE_SMALL(GiniImpurity::Evaluate(counts), 1e-10); + REQUIRE(GiniImpurity::Evaluate(counts) == Approx(0.0).margin(1e-10)); } -BOOST_AUTO_TEST_CASE(GiniImpurityImperfectSimpleTest) +TEST_CASE("GiniImpurityImperfectSimpleTest", "[HoeffdingTreeTest]") { // Make a simple test where a split will give us perfect classification. arma::Mat counts(2, 2); // 2 categories, 2 classes. @@ -60,10 +58,10 @@ BOOST_AUTO_TEST_CASE(GiniImpurityImperfectSimpleTest) // The impurity before the split should be 0.5^2 + 0.5^2 = 0.5. // The impurity after the split should be 0. // So the gain should be 0.5. - BOOST_REQUIRE_CLOSE(GiniImpurity::Evaluate(counts), 0.5, 1e-5); + REQUIRE(GiniImpurity::Evaluate(counts) == Approx(0.5).epsilon(1e-7)); } -BOOST_AUTO_TEST_CASE(GiniImpurityBadSplitTest) +TEST_CASE("GiniImpurityBadSplitTest", "[HoeffdingTreeTest]") { // Make a simple test where a split gets us nothing. arma::Mat counts(2, 2); @@ -72,14 +70,14 @@ BOOST_AUTO_TEST_CASE(GiniImpurityBadSplitTest) counts(1, 0) = 5; counts(1, 1) = 5; - BOOST_REQUIRE_SMALL(GiniImpurity::Evaluate(counts), 1e-10); + REQUIRE(GiniImpurity::Evaluate(counts) == Approx(0.0).margin(1e-10)); } /** * A hand-crafted more difficult test for the Gini impurity, where four * categories and three classes are available. */ -BOOST_AUTO_TEST_CASE(GiniImpurityThreeClassTest) +TEST_CASE("GiniImpurityThreeClassTest", "[HoeffdingTreeTest]") { arma::Mat counts(3, 4); @@ -106,34 +104,34 @@ BOOST_AUTO_TEST_CASE(GiniImpurityThreeClassTest) // (category 2) 0.28571 * 0.66667 - // (category 2) 0.23810 * 0.34 // = 0.26145 - BOOST_REQUIRE_CLOSE(GiniImpurity::Evaluate(counts), 0.26145, 1e-3); + REQUIRE(GiniImpurity::Evaluate(counts) == Approx(0.26145).epsilon(1e-5)); } -BOOST_AUTO_TEST_CASE(GiniImpurityZeroTest) +TEST_CASE("GiniImpurityZeroTest", "[HoeffdingTreeTest]") { // When nothing has been seen, the gini impurity should be zero. arma::Mat counts = arma::zeros>(10, 10); - BOOST_REQUIRE_SMALL(GiniImpurity::Evaluate(counts), 1e-10); + REQUIRE(GiniImpurity::Evaluate(counts) == Approx(0.0).margin(1e-10)); } /** * Test that the range of Gini impurities is correct for a handful of class * sizes. */ -BOOST_AUTO_TEST_CASE(GiniImpurityRangeTest) +TEST_CASE("GiniImpurityRangeTest", "[HoeffdingTreeTest]") { - BOOST_REQUIRE_CLOSE(GiniImpurity::Range(1), 0, 1e-5); - BOOST_REQUIRE_CLOSE(GiniImpurity::Range(2), 0.5, 1e-5); - BOOST_REQUIRE_CLOSE(GiniImpurity::Range(3), 0.66666667, 1e-5); - BOOST_REQUIRE_CLOSE(GiniImpurity::Range(4), 0.75, 1e-5); - BOOST_REQUIRE_CLOSE(GiniImpurity::Range(5), 0.8, 1e-5); - BOOST_REQUIRE_CLOSE(GiniImpurity::Range(10), 0.9, 1e-5); - BOOST_REQUIRE_CLOSE(GiniImpurity::Range(100), 0.99, 1e-5); - BOOST_REQUIRE_CLOSE(GiniImpurity::Range(1000), 0.999, 1e-5); + REQUIRE(GiniImpurity::Range(1) == Approx(0).epsilon(1e-7)); + REQUIRE(GiniImpurity::Range(2) == Approx(0.5).epsilon(1e-7)); + REQUIRE(GiniImpurity::Range(3) == Approx(0.66666667).epsilon(1e-7)); + REQUIRE(GiniImpurity::Range(4) == Approx(0.75).epsilon(1e-7)); + REQUIRE(GiniImpurity::Range(5) == Approx(0.8).epsilon(1e-7)); + REQUIRE(GiniImpurity::Range(10) == Approx(0.9).epsilon(1e-7)); + REQUIRE(GiniImpurity::Range(100) == Approx(0.99).epsilon(1e-7)); + REQUIRE(GiniImpurity::Range(1000) == Approx(0.999).epsilon(1e-7)); } -BOOST_AUTO_TEST_CASE(HoeffdingInformationGainPerfectSimpleTest) +TEST_CASE("HoeffdingInformationGainPerfectSimpleTest", "[HoeffdingTreeTest]") { // Make a simple test for Gini impurity with one class. In this case it // should always be 0. We'll assemble the count matrix by hand. @@ -145,10 +143,11 @@ BOOST_AUTO_TEST_CASE(HoeffdingInformationGainPerfectSimpleTest) counts(1, 1) = 0; // 0 points in category 1 with class 1. // Since the split gets us nothing, there should be no gain. - BOOST_REQUIRE_SMALL(HoeffdingInformationGain::Evaluate(counts), 1e-10); + REQUIRE(HoeffdingInformationGain::Evaluate(counts) == + Approx(0.0).margin(1e-10)); } -BOOST_AUTO_TEST_CASE(HoeffdingInformationGainImperfectSimpleTest) +TEST_CASE("HoeffdingInformationGainImperfectSimpleTest", "[HoeffdingTreeTest]") { // Make a simple test where a split will give us perfect classification. arma::Mat counts(2, 2); // 2 categories, 2 classes. @@ -161,10 +160,11 @@ BOOST_AUTO_TEST_CASE(HoeffdingInformationGainImperfectSimpleTest) // The impurity before the split should be 0.5 log2(0.5) + 0.5 log2(0.5) = -1. // The impurity after the split should be 0. // So the gain should be 1. - BOOST_REQUIRE_CLOSE(HoeffdingInformationGain::Evaluate(counts), 1.0, 1e-5); + REQUIRE(HoeffdingInformationGain::Evaluate(counts) == + Approx(1.0).epsilon(1e-7)); } -BOOST_AUTO_TEST_CASE(HoeffdingInformationGainBadSplitTest) +TEST_CASE("HoeffdingInformationGainBadSplitTest", "[HoeffdingTreeTest]") { // Make a simple test where a split gets us nothing. arma::Mat counts(2, 2); @@ -173,14 +173,14 @@ BOOST_AUTO_TEST_CASE(HoeffdingInformationGainBadSplitTest) counts(1, 0) = 5; counts(1, 1) = 5; - BOOST_REQUIRE_SMALL(HoeffdingInformationGain::Evaluate(counts), 1e-10); + REQUIRE(HoeffdingInformationGain::Evaluate(counts) == Approx(0.0).margin(1e-10)); } /** * A hand-crafted more difficult test for the Gini impurity, where four * categories and three classes are available. */ -BOOST_AUTO_TEST_CASE(HoeffdingInformationGainThreeClassTest) +TEST_CASE("HoeffdingInformationGainThreeClassTest", "[HoeffdingTreeTest]") { arma::Mat counts(3, 4); @@ -207,39 +207,39 @@ BOOST_AUTO_TEST_CASE(HoeffdingInformationGainThreeClassTest) // (category 2) 0.28571 * -1.5850 - // (category 3) 0.23810 * -0.92193 // = 0.64116649 - BOOST_REQUIRE_CLOSE(HoeffdingInformationGain::Evaluate(counts), 0.64116649, - 1e-5); + REQUIRE(HoeffdingInformationGain::Evaluate(counts) == + Approx(0.64116649).epsilon(1e-7)); } -BOOST_AUTO_TEST_CASE(HoeffdingInformationGainZeroTest) +TEST_CASE("HoeffdingInformationGainZeroTest", "[HoeffdingTreeTest]") { // When nothing has been seen, the information gain should be zero. arma::Mat counts = arma::zeros>(10, 10); - BOOST_REQUIRE_SMALL(HoeffdingInformationGain::Evaluate(counts), 1e-10); + REQUIRE(HoeffdingInformationGain::Evaluate(counts) == Approx(0.0).margin(1e-10)); } /** * Test that the range of information gains is correct for a handful of class * sizes. */ -BOOST_AUTO_TEST_CASE(HoeffdingInformationGainRangeTest) +TEST_CASE("HoeffdingInformationGainRangeTest", "[HoeffdingTreeTest]") { - BOOST_REQUIRE_CLOSE(HoeffdingInformationGain::Range(1), 0, 1e-5); - BOOST_REQUIRE_CLOSE(HoeffdingInformationGain::Range(2), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(HoeffdingInformationGain::Range(3), 1.5849625, 1e-5); - BOOST_REQUIRE_CLOSE(HoeffdingInformationGain::Range(4), 2, 1e-5); - BOOST_REQUIRE_CLOSE(HoeffdingInformationGain::Range(5), 2.32192809, 1e-5); - BOOST_REQUIRE_CLOSE(HoeffdingInformationGain::Range(10), 3.32192809, 1e-5); - BOOST_REQUIRE_CLOSE(HoeffdingInformationGain::Range(100), 6.64385619, 1e-5); - BOOST_REQUIRE_CLOSE(HoeffdingInformationGain::Range(1000), 9.96578428, 1e-5); + REQUIRE(HoeffdingInformationGain::Range(1) == Approx(0).epsilon(1e-7)); + REQUIRE(HoeffdingInformationGain::Range(2) == Approx(1.0).epsilon(1e-7)); + REQUIRE(HoeffdingInformationGain::Range(3) == Approx(1.5849625).epsilon(1e-7)); + REQUIRE(HoeffdingInformationGain::Range(4) == Approx(2).epsilon(1e-7)); + REQUIRE(HoeffdingInformationGain::Range(5) == Approx(2.32192809).epsilon(1e-7)); + REQUIRE(HoeffdingInformationGain::Range(10) == Approx(3.32192809).epsilon(1e-7)); + REQUIRE(HoeffdingInformationGain::Range(100) == Approx(6.64385619).epsilon(1e-7)); + REQUIRE(HoeffdingInformationGain::Range(1000) == Approx(9.96578428).epsilon(1e-7)); } /** * Feed the HoeffdingCategoricalSplit class many examples, all from the same * class, and verify that the majority class is correct. */ -BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitMajorityClassTest) +TEST_CASE("HoeffdingCategoricalSplitMajorityClassTest", "[HoeffdingTreeTest]") { // Ten categories, three classes. HoeffdingCategoricalSplit split(10, 3); @@ -247,14 +247,15 @@ BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitMajorityClassTest) for (size_t i = 0; i < 500; ++i) { split.Train(mlpack::math::RandInt(0, 10), 1); - BOOST_REQUIRE_EQUAL(split.MajorityClass(), 1); + REQUIRE(split.MajorityClass() == 1); } } /** * A harder majority class example. */ -BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitHarderMajorityClassTest) +TEST_CASE("HoeffdingCategoricalSplitHarderMajorityClassTest", + "[HoeffdingTreeTest]") { // Ten categories, three classes. HoeffdingCategoricalSplit split(10, 3); @@ -264,7 +265,7 @@ BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitHarderMajorityClassTest) { split.Train(mlpack::math::RandInt(0, 10), 1); split.Train(mlpack::math::RandInt(0, 10), 2); - BOOST_REQUIRE_EQUAL(split.MajorityClass(), 1); + REQUIRE(split.MajorityClass() == 1); } } @@ -272,7 +273,7 @@ BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitHarderMajorityClassTest) * Ensure that the fitness function is positive when we pass some data that * would result in an improvement if it was split. */ -BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitEasyFitnessCheck) +TEST_CASE("HoeffdingCategoricalSplitEasyFitnessCheck", "[HoeffdingTreeTest]") { HoeffdingCategoricalSplit split(5, 3); @@ -289,23 +290,24 @@ BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitEasyFitnessCheck) double bestGain, secondBestGain; split.EvaluateFitnessFunction(bestGain, secondBestGain); - BOOST_REQUIRE_GT(bestGain, 0.0); - BOOST_REQUIRE_SMALL(secondBestGain, 1e-10); + REQUIRE(bestGain > 0.0); + REQUIRE(secondBestGain == Approx(0.0).margin(1e-10)); } /** * Ensure that the fitness function returns 0 (no improvement) when a split * would not get us any improvement. */ -BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitNoImprovementFitnessTest) +TEST_CASE("HoeffdingCategoricalSplitNoImprovementFitnessTest", + "[HoeffdingTreeTest]") { HoeffdingCategoricalSplit split(2, 2); // No training has yet happened, so a split would get us nothing. double bestGain, secondBestGain; split.EvaluateFitnessFunction(bestGain, secondBestGain); - BOOST_REQUIRE_SMALL(bestGain, 1e-10); - BOOST_REQUIRE_SMALL(secondBestGain, 1e-10); + REQUIRE(bestGain == Approx(0.0).margin(1e-10)); + REQUIRE(secondBestGain == Approx(0.0).margin(1e-10)); split.Train(0, 0); split.Train(1, 0); @@ -314,14 +316,14 @@ BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitNoImprovementFitnessTest) // Now, a split still gets us only 50% accuracy in each split bin. split.EvaluateFitnessFunction(bestGain, secondBestGain); - BOOST_REQUIRE_SMALL(bestGain, 1e-10); - BOOST_REQUIRE_SMALL(secondBestGain, 1e-10); + REQUIRE(bestGain == Approx(0.0).margin(1e-10)); + REQUIRE(secondBestGain == Approx(0.0).margin(1e-10)); } /** * Test that when we do split, we get reasonable split information. */ -BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitSplitTest) +TEST_CASE("HoeffdingCategoricalSplitSplitTest", "[HoeffdingTreeTest]") { HoeffdingCategoricalSplit split(3, 3); // 3 categories. @@ -334,17 +336,17 @@ BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitSplitTest) arma::Col childMajorities; split.Split(childMajorities, splitInfo); - BOOST_REQUIRE_EQUAL(childMajorities.n_elem, 3); - BOOST_REQUIRE_EQUAL(splitInfo.CalculateDirection(0), 0); - BOOST_REQUIRE_EQUAL(splitInfo.CalculateDirection(1), 1); - BOOST_REQUIRE_EQUAL(splitInfo.CalculateDirection(2), 2); + REQUIRE(childMajorities.n_elem == 3); + REQUIRE(splitInfo.CalculateDirection(0) == 0); + REQUIRE(splitInfo.CalculateDirection(1) == 1); + REQUIRE(splitInfo.CalculateDirection(2) == 2); } /** * If we feed the HoeffdingTree a ton of points of the same class, it should * not suggest that we split. */ -BOOST_AUTO_TEST_CASE(HoeffdingTreeNoSplitTest) +TEST_CASE("HoeffdingTreeNoSplitTest", "[HoeffdingTreeTest]") { // Make all dimensions categorical. data::DatasetInfo info(3); @@ -370,7 +372,7 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeNoSplitTest) testPoint(2) = mlpack::math::RandInt(0, 2); split.Train(testPoint, 0); // Always label 0. - BOOST_REQUIRE_EQUAL(split.SplitCheck(), 0); + REQUIRE(split.SplitCheck() == 0); } } @@ -378,7 +380,7 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeNoSplitTest) * If we feed the HoeffdingTree a ton of points of two different classes, it * should very clearly suggest that we split (eventually). */ -BOOST_AUTO_TEST_CASE(HoeffdingTreeEasySplitTest) +TEST_CASE("HoeffdingTreeEasySplitTest", "[HoeffdingTreeTest]") { // It'll be a two-dimensional dataset with two categories each. In the first // dimension, category 0 will only receive points with class 0, and category 1 @@ -399,14 +401,14 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeEasySplitTest) } // Now it should be ready to split. - BOOST_REQUIRE_EQUAL(tree.SplitCheck(), 2); - BOOST_REQUIRE_EQUAL(tree.SplitDimension(), 0); + REQUIRE(tree.SplitCheck() == 2); + REQUIRE(tree.SplitDimension() == 0); } /** * If we force a success probability of 1, it should never split. */ -BOOST_AUTO_TEST_CASE(HoeffdingTreeProbability1SplitTest) +TEST_CASE("HoeffdingTreeProbability1SplitTest", "[HoeffdingTreeTest]") { // It'll be a two-dimensional dataset with two categories each. In the first // dimension, category 0 will only receive points with class 0, and category 1 @@ -427,8 +429,8 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeProbability1SplitTest) } // But because the success probability is 1, it should never split. - BOOST_REQUIRE_EQUAL(split.SplitCheck(), 0); - BOOST_REQUIRE_EQUAL(split.SplitDimension(), size_t(-1)); + REQUIRE(split.SplitCheck() == 0); + REQUIRE(split.SplitDimension() == size_t(-1)); } /** @@ -436,7 +438,7 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeProbability1SplitTest) * perfect classification, another gives almost perfect classification (with 10% * error). Splits should occur after many samples. */ -BOOST_AUTO_TEST_CASE(HoeffdingTreeAlmostPerfectSplit) +TEST_CASE("HoeffdingTreeAlmostPerfectSplit", "[HoeffdingTreeTest]") { // Two categories and two dimensions. data::DatasetInfo info(2); @@ -462,16 +464,16 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeAlmostPerfectSplit) } // Ensure that splitting should happen. - BOOST_REQUIRE_EQUAL(split.SplitCheck(), 2); + REQUIRE(split.SplitCheck() == 2); // Make sure that it's split on the correct dimension. - BOOST_REQUIRE_EQUAL(split.SplitDimension(), 1); + REQUIRE(split.SplitDimension() == 1); } /** * Test that the HoeffdingTree class will not split if the two features are * equally good. */ -BOOST_AUTO_TEST_CASE(HoeffdingTreeEqualSplitTest) +TEST_CASE("HoeffdingTreeEqualSplitTest", "[HoeffdingTreeTest]") { // Two categories and two dimensions. data::DatasetInfo info(2); @@ -490,7 +492,7 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeEqualSplitTest) } // Ensure that splitting should not happen. - BOOST_REQUIRE_EQUAL(split.SplitCheck(), 0); + REQUIRE(split.SplitCheck() == 0); } // This is used in the next test. @@ -503,7 +505,7 @@ using HoeffdingSizeTNumericSplit = HoeffdingNumericSplit("cat0", 0); @@ -550,10 +552,10 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeSimpleDatasetTest) streamTree.Train(dataset.col(i), labels[i]); // Each tree should have a single split. - BOOST_REQUIRE_EQUAL(batchTree.NumChildren(), 3); - BOOST_REQUIRE_EQUAL(streamTree.NumChildren(), 3); - BOOST_REQUIRE_EQUAL(batchTree.SplitDimension(), 1); - BOOST_REQUIRE_EQUAL(streamTree.SplitDimension(), 1); + REQUIRE(batchTree.NumChildren() == 3); + REQUIRE(streamTree.NumChildren() == 3); + REQUIRE(batchTree.SplitDimension() == 1); + REQUIRE(streamTree.SplitDimension() == 1); // Now, classify all the points in the dataset. arma::Row batchLabels(9000); @@ -565,15 +567,15 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeSimpleDatasetTest) for (size_t i = 0; i < 9000; ++i) { - BOOST_REQUIRE_EQUAL(labels[i], streamLabels[i]); - BOOST_REQUIRE_EQUAL(labels[i], batchLabels[i]); + REQUIRE(labels[i] == streamLabels[i]); + REQUIRE(labels[i] == batchLabels[i]); } } /** * Make sure that a tree that does not split on anything. */ -BOOST_AUTO_TEST_CASE(NumDescendantsTest1) +TEST_CASE("NumDescendantsTest1", "[HoeffdingTreeTest]") { // Generate data. arma::mat dataset(3, 500); @@ -593,13 +595,13 @@ BOOST_AUTO_TEST_CASE(NumDescendantsTest1) for (size_t i = 0; i < 500; ++i) streamTree.Train(dataset.col(i), labels[i]); // As there is just one label, there are no descendants. - BOOST_REQUIRE_EQUAL(streamTree.NumDescendants(), 0); + REQUIRE(streamTree.NumDescendants() == 0); } /** * Test that a tree that does split has some descendants. */ -BOOST_AUTO_TEST_CASE(NumDescendantsTest2) +TEST_CASE("NumDescendantsTest2", "[HoeffdingTreeTest]") { DatasetInfo info(3); info.MapString("cat0", 0); @@ -641,14 +643,14 @@ BOOST_AUTO_TEST_CASE(NumDescendantsTest2) HoeffdingCategoricalSplit> TreeType; TreeType batchTree(dataset, info, labels, 3, false); - BOOST_REQUIRE_EQUAL(batchTree.NumDescendants(), 3); + REQUIRE(batchTree.NumDescendants() == 3); } /** * Test that the HoeffdingNumericSplit class has a fitness function value of 0 * before it's seen enough points. */ -BOOST_AUTO_TEST_CASE(HoeffdingNumericSplitFitnessFunctionTest) +TEST_CASE("HoeffdingNumericSplitFitnessFunctionTest", "[HoeffdingTreeTest]") { HoeffdingNumericSplit split(5, 10, 100); @@ -659,22 +661,23 @@ BOOST_AUTO_TEST_CASE(HoeffdingNumericSplitFitnessFunctionTest) split.Train(mlpack::math::Random(), mlpack::math::RandInt(5)); double bestGain, secondBestGain; split.EvaluateFitnessFunction(bestGain, secondBestGain); - BOOST_REQUIRE_SMALL(bestGain, 1e-10); - BOOST_REQUIRE_SMALL(secondBestGain, 1e-10); + REQUIRE(bestGain == Approx(0.0).margin(1e-10)); + REQUIRE(secondBestGain == Approx(0.0).margin(1e-10)); } } /** * Make sure the majority class is correct in the samples before binning. */ -BOOST_AUTO_TEST_CASE(HoeffdingNumericSplitPreBinningMajorityClassTest) +TEST_CASE("HoeffdingNumericSplitPreBinningMajorityClassTest", + "[HoeffdingTreeTest]") { HoeffdingNumericSplit split(3, 10, 100); for (size_t i = 0; i < 100; ++i) { split.Train(mlpack::math::Random(), 1); - BOOST_REQUIRE_EQUAL(split.MajorityClass(), 1); + REQUIRE(split.MajorityClass() == 1); } } @@ -683,7 +686,7 @@ BOOST_AUTO_TEST_CASE(HoeffdingNumericSplitPreBinningMajorityClassTest) * HoeffdingNumericSplit bins it reasonably into two bins and returns sensible * Gini impurity numbers. */ -BOOST_AUTO_TEST_CASE(HoeffdingNumericSplitBimodalTest) +TEST_CASE("HoeffdingNumericSplitBimodalTest", "[HoeffdingTreeTest]") { // 2 classes, 2 bins, 200 samples before binning. HoeffdingNumericSplit split(2, 2, 200); @@ -696,32 +699,32 @@ BOOST_AUTO_TEST_CASE(HoeffdingNumericSplitBimodalTest) // Push the majority class to 1. split.Train(-mlpack::math::Random() - 0.3, 1); - BOOST_REQUIRE_EQUAL(split.MajorityClass(), 1); + REQUIRE(split.MajorityClass() == 1); // Push the majority class back to 0. split.Train(mlpack::math::Random() + 0.3, 0); split.Train(mlpack::math::Random() + 0.3, 0); - BOOST_REQUIRE_EQUAL(split.MajorityClass(), 0); + REQUIRE(split.MajorityClass() == 0); // Now the binning should be complete, and so the impurity should be // (0.5 * (1 - 0.5)) * 2 = 0.50 (it will be 0 in the two created children). double bestGain, secondBestGain; split.EvaluateFitnessFunction(bestGain, secondBestGain); - BOOST_REQUIRE_CLOSE(bestGain, 0.50, 0.03); - BOOST_REQUIRE_SMALL(secondBestGain, 1e-10); + REQUIRE(bestGain == Approx(0.50).epsilon(0.0003)); + REQUIRE(secondBestGain == Approx(0.0).margin(1e-10)); // Make sure that if we do create children, that the correct number of // children is created, and that the bins end up in the right place. NumericSplitInfo<> info; arma::Col childMajorities; split.Split(childMajorities, info); - BOOST_REQUIRE_EQUAL(childMajorities.n_elem, 2); + REQUIRE(childMajorities.n_elem == 2); // Now check the split info. for (size_t i = 0; i < 10; ++i) { - BOOST_REQUIRE_NE(info.CalculateDirection(mlpack::math::Random() + 0.3), - info.CalculateDirection(-mlpack::math::Random() - 0.3)); + REQUIRE(info.CalculateDirection(mlpack::math::Random() + 0.3) != + info.CalculateDirection(-mlpack::math::Random() - 0.3)); } } @@ -730,7 +733,7 @@ BOOST_AUTO_TEST_CASE(HoeffdingNumericSplitBimodalTest) * less than 1.0 is class 0 and anything greater is class 1. Then make sure it * can perform a perfect split. */ -BOOST_AUTO_TEST_CASE(BinaryNumericSplitSimpleSplitTest) +TEST_CASE("BinaryNumericSplitSimpleSplitTest", "[HoeffdingTreeTest]") { BinaryNumericSplit split(2); // 2 classes. @@ -745,8 +748,8 @@ BOOST_AUTO_TEST_CASE(BinaryNumericSplitSimpleSplitTest) // impurity for the children is 0. double bestGain, secondBestGain; split.EvaluateFitnessFunction(bestGain, secondBestGain); - BOOST_REQUIRE_CLOSE(bestGain, 0.5, 1e-5); - BOOST_REQUIRE_GT(bestGain, secondBestGain); + REQUIRE(bestGain == Approx(0.5).epsilon(1e-7)); + REQUIRE(bestGain > secondBestGain); } // Now, when we ask it to split, ensure that the split value is reasonable. @@ -754,21 +757,21 @@ BOOST_AUTO_TEST_CASE(BinaryNumericSplitSimpleSplitTest) BinaryNumericSplitInfo<> splitInfo; split.Split(childMajorities, splitInfo); - BOOST_REQUIRE_EQUAL(childMajorities[0], 0); - BOOST_REQUIRE_EQUAL(childMajorities[1], 1); - BOOST_REQUIRE_EQUAL(splitInfo.CalculateDirection(0.5), 0); - BOOST_REQUIRE_EQUAL(splitInfo.CalculateDirection(1.5), 1); - BOOST_REQUIRE_EQUAL(splitInfo.CalculateDirection(0.0), 0); - BOOST_REQUIRE_EQUAL(splitInfo.CalculateDirection(-1.0), 0); - BOOST_REQUIRE_EQUAL(splitInfo.CalculateDirection(0.9), 0); - BOOST_REQUIRE_EQUAL(splitInfo.CalculateDirection(1.1), 1); + REQUIRE(childMajorities[0] == 0); + REQUIRE(childMajorities[1] == 1); + REQUIRE(splitInfo.CalculateDirection(0.5) == 0); + REQUIRE(splitInfo.CalculateDirection(1.5) == 1); + REQUIRE(splitInfo.CalculateDirection(0.0) == 0); + REQUIRE(splitInfo.CalculateDirection(-1.0) == 0); + REQUIRE(splitInfo.CalculateDirection(0.9) == 0); + REQUIRE(splitInfo.CalculateDirection(1.1) == 1); } /** * Create a BinaryNumericSplit object, feed it samples in the same way as * before, but with four classes. */ -BOOST_AUTO_TEST_CASE(BinaryNumericSplitSimpleFourClassSplitTest) +TEST_CASE("BinaryNumericSplitSimpleFourClassSplitTest", "[HoeffdingTreeTest]") { BinaryNumericSplit split(4); // 4 classes. @@ -785,8 +788,8 @@ BOOST_AUTO_TEST_CASE(BinaryNumericSplitSimpleFourClassSplitTest) // perfect child, giving a gain of 0.75 - 3 * (1/3 * 2/3) = 0.25. double bestGain, secondBestGain; split.EvaluateFitnessFunction(bestGain, secondBestGain); - BOOST_REQUIRE_CLOSE(bestGain, 0.25, 1e-5); - BOOST_REQUIRE_GE(bestGain, secondBestGain); + REQUIRE(bestGain == Approx(0.25).epsilon(1e-7)); + REQUIRE(bestGain >= secondBestGain); } // Now, when we ask it to split, ensure that the split value is reasonable. @@ -796,14 +799,14 @@ BOOST_AUTO_TEST_CASE(BinaryNumericSplitSimpleFourClassSplitTest) // We don't really care where it splits -- it can split anywhere. But it has // to split in only two directions. - BOOST_REQUIRE_EQUAL(childMajorities.n_elem, 2); + REQUIRE(childMajorities.n_elem == 2); } /** * Create a HoeffdingTree that uses the HoeffdingNumericSplit and make sure it * can split meaningfully on the correct dimension. */ -BOOST_AUTO_TEST_CASE(NumericHoeffdingTreeTest) +TEST_CASE("NumericHoeffdingTreeTest", "[HoeffdingTreeTest]") { // Generate data. arma::mat dataset(3, 9000); @@ -836,10 +839,10 @@ BOOST_AUTO_TEST_CASE(NumericHoeffdingTreeTest) streamTree.Train(dataset.col(i), labels[i]); // Each tree should have at least one split. - BOOST_REQUIRE_GT(batchTree.NumChildren(), 0); - BOOST_REQUIRE_GT(streamTree.NumChildren(), 0); - BOOST_REQUIRE_EQUAL(batchTree.SplitDimension(), 1); - BOOST_REQUIRE_EQUAL(streamTree.SplitDimension(), 1); + REQUIRE(batchTree.NumChildren() > 0); + REQUIRE(streamTree.NumChildren() > 0); + REQUIRE(batchTree.SplitDimension() == 1); + REQUIRE(streamTree.SplitDimension() == 1); // Now, classify all the points in the dataset. arma::Row batchLabels(9000); @@ -860,15 +863,15 @@ BOOST_AUTO_TEST_CASE(NumericHoeffdingTreeTest) } // 66% accuracy shouldn't be too much to ask... - BOOST_REQUIRE_GT(streamCorrect, 6000); - BOOST_REQUIRE_GT(batchCorrect, 6000); + REQUIRE(streamCorrect > 6000); + REQUIRE(batchCorrect > 6000); } /** * The same as the previous test, but with the numeric binary split, and with a * categorical feature. */ -BOOST_AUTO_TEST_CASE(BinaryNumericHoeffdingTreeTest) +TEST_CASE("BinaryNumericHoeffdingTreeTest", "[HoeffdingTreeTest]") { // Generate data. arma::mat dataset(4, 9000); @@ -905,10 +908,10 @@ BOOST_AUTO_TEST_CASE(BinaryNumericHoeffdingTreeTest) streamTree.Train(dataset.col(i), labels[i]); // Each tree should have at least one split. - BOOST_REQUIRE_GT(batchTree.NumChildren(), 0); - BOOST_REQUIRE_GT(streamTree.NumChildren(), 0); - BOOST_REQUIRE_EQUAL(batchTree.SplitDimension(), 1); - BOOST_REQUIRE_EQUAL(streamTree.SplitDimension(), 1); + REQUIRE(batchTree.NumChildren() > 0); + REQUIRE(streamTree.NumChildren() > 0); + REQUIRE(batchTree.SplitDimension() == 1); + REQUIRE(streamTree.SplitDimension() == 1); // Now, classify all the points in the dataset. arma::Row batchLabels(9000); @@ -929,14 +932,14 @@ BOOST_AUTO_TEST_CASE(BinaryNumericHoeffdingTreeTest) } // Require a pretty high accuracy: 95%. - BOOST_REQUIRE_GT(streamCorrect, 8550); - BOOST_REQUIRE_GT(batchCorrect, 8550); + REQUIRE(streamCorrect > 8550); + REQUIRE(batchCorrect > 8550); } /** * Test majority probabilities. */ -BOOST_AUTO_TEST_CASE(MajorityProbabilityTest) +TEST_CASE("MajorityProbabilityTest", "[HoeffdingTreeTest]") { data::DatasetInfo info(1); HoeffdingTree<> tree(info, 3); @@ -950,15 +953,15 @@ BOOST_AUTO_TEST_CASE(MajorityProbabilityTest) double probability; tree.Classify(arma::vec("1"), prediction, probability); - BOOST_REQUIRE_EQUAL(prediction, 0); - BOOST_REQUIRE_CLOSE(probability, 1.0, 1e-5); + REQUIRE(prediction == 0); + REQUIRE(probability == Approx(1.0).epsilon(1e-7)); // Make it impure. tree.Train(arma::vec("4"), 1); tree.Classify(arma::vec("3"), prediction, probability); - BOOST_REQUIRE_EQUAL(prediction, 0); - BOOST_REQUIRE_CLOSE(probability, 0.75, 1e-5); + REQUIRE(prediction == 0); + REQUIRE(probability == Approx(0.75).epsilon(1e-7)); // Flip the majority class. tree.Train(arma::vec("4"), 1); @@ -967,14 +970,14 @@ BOOST_AUTO_TEST_CASE(MajorityProbabilityTest) tree.Train(arma::vec("4"), 1); tree.Classify(arma::vec("3"), prediction, probability); - BOOST_REQUIRE_EQUAL(prediction, 1); - BOOST_REQUIRE_CLOSE(probability, 0.625, 1e-5); + REQUIRE(prediction == 1); + REQUIRE(probability == Approx(0.625).epsilon(1e-7)); } /** * Make sure that batch training mode outperforms non-batch mode. */ -BOOST_AUTO_TEST_CASE(BatchTrainingTest) +TEST_CASE("BatchTrainingTest", "[HoeffdingTreeTest]") { // We need to create a dataset with some amount of complexity, that must be // split in a handful of ways to accurately classify the data. An expanding @@ -1050,11 +1053,11 @@ BOOST_AUTO_TEST_CASE(BatchTrainingTest) // The batch tree must be a bit better than the stream tree. But not too // much, since the accuracy is already going to be very high. - BOOST_REQUIRE_GE(batchCorrect, streamCorrect); + REQUIRE(batchCorrect >= streamCorrect); } // Make sure that changing the confidence properly propagates to all leaves. -BOOST_AUTO_TEST_CASE(ConfidenceChangeTest) +TEST_CASE("ConfidenceChangeTest", "[HoeffdingTreeTest]") { // Generate data. arma::mat dataset(4, 9000); @@ -1091,7 +1094,7 @@ BOOST_AUTO_TEST_CASE(ConfidenceChangeTest) ++i; } - BOOST_REQUIRE_LT(i, 9000); + REQUIRE(i < 9000); // Now we have split the root node, but we need to make sure we can feed // through the rest of the points while requiring a confidence of 1.0, and @@ -1107,11 +1110,11 @@ BOOST_AUTO_TEST_CASE(ConfidenceChangeTest) } for (size_t c = 0; c < tree.NumChildren(); ++c) - BOOST_REQUIRE_EQUAL(tree.Child(c).NumChildren(), 0); + REQUIRE(tree.Child(c).NumChildren() == 0); } //! Make sure parameter changes are propagated to children. -BOOST_AUTO_TEST_CASE(ParameterChangeTest) +TEST_CASE("ParameterChangeTest", "[HoeffdingTreeTest]") { // Generate data. arma::mat dataset(4, 9000); @@ -1154,17 +1157,17 @@ BOOST_AUTO_TEST_CASE(ParameterChangeTest) HoeffdingTree<>* node = stack.top(); stack.pop(); - BOOST_REQUIRE_CLOSE(node->SuccessProbability(), 0.7, 1e-5); - BOOST_REQUIRE_EQUAL(node->MinSamples(), 17); - BOOST_REQUIRE_EQUAL(node->MaxSamples(), 192); - BOOST_REQUIRE_EQUAL(node->CheckInterval(), 3); + REQUIRE(node->SuccessProbability() == Approx(0.7).epsilon(1e-7)); + REQUIRE(node->MinSamples() == 17); + REQUIRE(node->MaxSamples() == 192); + REQUIRE(node->CheckInterval() == 3); for (size_t i = 0; i < node->NumChildren(); ++i) stack.push(&node->Child(i)); } } -BOOST_AUTO_TEST_CASE(MultipleSerializationTest) +TEST_CASE("MultipleSerializationTest", "[HoeffdingTreeTest]") { // Generate data. arma::mat dataset(4, 9000); @@ -1217,12 +1220,12 @@ BOOST_AUTO_TEST_CASE(MultipleSerializationTest) for (size_t i = 0; i < deepPredictions.n_elem; ++i) { - BOOST_REQUIRE_EQUAL(shallowPredictions[i], deepPredictions[i]); + REQUIRE(shallowPredictions[i] == deepPredictions[i]); } } // Test the Hoeffding tree model. -BOOST_AUTO_TEST_CASE(HoeffdingTreeModelTest) +TEST_CASE("HoeffdingTreeModelTest", "[HoeffdingTreeTest]") { // Generate data. arma::mat dataset(4, 3000); @@ -1289,19 +1292,19 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeModelTest) for (size_t i = 0; i < 3000; ++i) { // Check consistency of predictions. - BOOST_REQUIRE_EQUAL(predictions[i], predictions2[i]); + REQUIRE(predictions[i] == predictions2[i]); if (labels[i] == predictions[i]) ++correct; } // Require at least 95% accuracy. - BOOST_REQUIRE_GT(correct, 2850); + REQUIRE(correct > 2850); } } // Test the Hoeffding tree model in batch mode. -BOOST_AUTO_TEST_CASE(HoeffdingTreeModelBatchTest) +TEST_CASE("HoeffdingTreeModelBatchTest", "[HoeffdingTreeTest]") { // Generate data. arma::mat dataset(4, 3000); @@ -1366,18 +1369,18 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeModelBatchTest) for (size_t i = 0; i < 3000; ++i) { // Check consistency of predictions. - BOOST_REQUIRE_EQUAL(predictions[i], predictions2[i]); + REQUIRE(predictions[i] == predictions2[i]); if (labels[i] == predictions[i]) ++correct; } // Require at least 95% accuracy. - BOOST_REQUIRE_GT(correct, 2850); + REQUIRE(correct > 2850); } } -BOOST_AUTO_TEST_CASE(HoeffdingTreeModelSerializationTest) +TEST_CASE("HoeffdingTreeModelSerializationTest", "[HoeffdingTreeTest]") { // Generate data. arma::mat dataset(4, 3000); @@ -1452,15 +1455,13 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeModelSerializationTest) for (size_t i = 0; i < 3000; ++i) { // Check consistency of predictions and probabilities. - BOOST_REQUIRE_EQUAL(predictions[i], predictionsXml[i]); - BOOST_REQUIRE_EQUAL(predictions[i], predictionsText[i]); - BOOST_REQUIRE_EQUAL(predictions[i], predictionsBinary[i]); + REQUIRE(predictions[i] == predictionsXml[i]); + REQUIRE(predictions[i] == predictionsText[i]); + REQUIRE(predictions[i] == predictionsBinary[i]); - BOOST_REQUIRE_CLOSE(probabilities[i], probabilitiesXml[i], 1e-5); - BOOST_REQUIRE_CLOSE(probabilities[i], probabilitiesText[i], 1e-5); - BOOST_REQUIRE_CLOSE(probabilities[i], probabilitiesBinary[i], 1e-5); + REQUIRE(probabilities[i] == Approx(probabilitiesXml[i]).epsilon(1e-7)); + REQUIRE(probabilities[i] == Approx(probabilitiesText[i]).epsilon(1e-7)); + REQUIRE(probabilities[i] == Approx(probabilitiesBinary[i]).epsilon(1e-7)); } } } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/io_test.cpp b/src/mlpack/tests/io_test.cpp index 80aef17fbe..9bf3df03a3 100644 --- a/src/mlpack/tests/io_test.cpp +++ b/src/mlpack/tests/io_test.cpp @@ -29,8 +29,7 @@ static const std::string testName = ""; #include #include -#include -#include "test_tools.hpp" +#include "catch.hpp" using namespace mlpack; using namespace mlpack::util; @@ -46,8 +45,6 @@ struct IOTestDestroyer IOTestDestroyer() { IO::ClearSettings(); } }; -BOOST_FIXTURE_TEST_SUITE(IOTest, IOTestDestroyer); - /** * Before running a test that uses the CLI options, we have to add the default * options that are required for CLI to function, since it will be destroyed at @@ -72,7 +69,7 @@ void AddRequiredCLIOptions() * Tests that CLI works as intended, namely that IO::Add propagates * successfully. */ -BOOST_AUTO_TEST_CASE(TestCLIAdd) +TEST_CASE_METHOD(IOTestDestroyer, "TestCLIAdd", "[IOTest]") { AddRequiredCLIOptions(); @@ -81,19 +78,17 @@ BOOST_AUTO_TEST_CASE(TestCLIAdd) CLIOption b(false, "global/bool", "True or false.", "a", "bool"); // IO::HasParam should return false here. - BOOST_REQUIRE(!IO::HasParam("global/bool")); + REQUIRE(!IO::HasParam("global/bool")); // Check that our aliasing works. - BOOST_REQUIRE_EQUAL(IO::HasParam("global/bool"), - IO::HasParam("a")); - BOOST_REQUIRE_EQUAL(IO::GetParam("global/bool"), - IO::GetParam("a")); + REQUIRE(IO::HasParam("global/bool") == IO::HasParam("a")); + REQUIRE(IO::GetParam("global/bool") == IO::GetParam("a")); } /** * Tests that the various PARAM_* macros work properly. */ -BOOST_AUTO_TEST_CASE(TestOption) +TEST_CASE_METHOD(IOTestDestroyer, "TestOption", "[IOTest]") { AddRequiredCLIOptions(); @@ -101,13 +96,13 @@ BOOST_AUTO_TEST_CASE(TestOption) // this. PARAM_IN(int, "test_parent/test", "test desc", "", 42, false); - BOOST_REQUIRE_EQUAL(IO::GetParam("test_parent/test"), 42); + REQUIRE(IO::GetParam("test_parent/test") == 42); } /** * Test that duplicate flags are filtered out correctly. */ -BOOST_AUTO_TEST_CASE(TestDuplicateFlag) +TEST_CASE_METHOD(IOTestDestroyer, "TestDuplicateFlag", "[IOTest]") { AddRequiredCLIOptions(); @@ -120,14 +115,15 @@ BOOST_AUTO_TEST_CASE(TestDuplicateFlag) argv[2] = "--test"; // This should not throw an exception. - BOOST_REQUIRE_NO_THROW( + REQUIRE_NOTHROW( ParseCommandLine(argc, const_cast(argv))); } /** * Test that duplicate options throw an exception. */ -BOOST_AUTO_TEST_CASE(TestDuplicateParam) +TEST_CASE_METHOD(IOTestDestroyer, "TestDuplicateParam", + "[IOTest]") { AddRequiredCLIOptions(); @@ -141,7 +137,7 @@ BOOST_AUTO_TEST_CASE(TestDuplicateParam) // This should throw an exception. Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(ParseCommandLine(argc, const_cast(argv)), + REQUIRE_THROWS_AS(ParseCommandLine(argc, const_cast(argv)), std::runtime_error); Log::Fatal.ignoreInput = false; } @@ -149,16 +145,17 @@ BOOST_AUTO_TEST_CASE(TestDuplicateParam) /** * Ensure that a Boolean option which we define is set correctly. */ -BOOST_AUTO_TEST_CASE(TestBooleanOption) +TEST_CASE_METHOD(IOTestDestroyer, "TestBooleanOption", + "[IOTest]") { AddRequiredCLIOptions(); PARAM_FLAG("flag_test", "flag test description", ""); - BOOST_REQUIRE_EQUAL(IO::HasParam("flag_test"), false); + REQUIRE(IO::HasParam("flag_test") == false); // Now check that CLI reflects that it is false by default. - BOOST_REQUIRE_EQUAL(IO::GetParam("flag_test"), false); + REQUIRE(IO::GetParam("flag_test") == false); // Now, if we specify this flag, it should be true. int argc = 2; @@ -168,14 +165,15 @@ BOOST_AUTO_TEST_CASE(TestBooleanOption) ParseCommandLine(argc, const_cast(argv)); - BOOST_REQUIRE_EQUAL(IO::GetParam("flag_test"), true); - BOOST_REQUIRE_EQUAL(IO::HasParam("flag_test"), true); + REQUIRE(IO::GetParam("flag_test") == true); + REQUIRE(IO::HasParam("flag_test") == true); } /** * Test that a vector option works correctly. */ -BOOST_AUTO_TEST_CASE(TestVectorOption) +TEST_CASE_METHOD(IOTestDestroyer, "TestVectorOption", + "[IOTest]") { AddRequiredCLIOptions(); @@ -191,20 +189,21 @@ BOOST_AUTO_TEST_CASE(TestVectorOption) ParseCommandLine(argc, const_cast(argv)); - BOOST_REQUIRE(IO::HasParam("test_vec")); + REQUIRE(IO::HasParam("test_vec")); vector v = IO::GetParam>("test_vec"); - BOOST_REQUIRE_EQUAL(v.size(), 3); - BOOST_REQUIRE_EQUAL(v[0], 1); - BOOST_REQUIRE_EQUAL(v[1], 2); - BOOST_REQUIRE_EQUAL(v[2], 4); + REQUIRE(v.size() == 3); + REQUIRE(v[0] == 1); + REQUIRE(v[1] == 2); + REQUIRE(v[2] == 4); } /** * Test that we can use a vector option by specifying it many times. */ -BOOST_AUTO_TEST_CASE(TestVectorOption2) +TEST_CASE_METHOD(IOTestDestroyer, "TestVectorOption2", + "[IOTest]") { AddRequiredCLIOptions(); @@ -222,17 +221,18 @@ BOOST_AUTO_TEST_CASE(TestVectorOption2) ParseCommandLine(argc, const_cast(argv)); - BOOST_REQUIRE(IO::HasParam("test2_vec")); + REQUIRE(IO::HasParam("test2_vec")); vector v = IO::GetParam>("test2_vec"); - BOOST_REQUIRE_EQUAL(v.size(), 3); - BOOST_REQUIRE_EQUAL(v[0], 1); - BOOST_REQUIRE_EQUAL(v[1], 2); - BOOST_REQUIRE_EQUAL(v[2], 4); + REQUIRE(v.size() == 3); + REQUIRE(v[0] == 1); + REQUIRE(v[1] == 2); + REQUIRE(v[2] == 4); } -BOOST_AUTO_TEST_CASE(InputColVectorParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "InputColVectorParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -250,24 +250,25 @@ BOOST_AUTO_TEST_CASE(InputColVectorParamTest) ParseCommandLine(argc, const_cast(argv)); // The --vector parameter should exist. - BOOST_REQUIRE(IO::HasParam("vector")); + REQUIRE(IO::HasParam("vector")); // The --vector_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("vector_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("vector_file"), runtime_error); Log::Fatal.ignoreInput = false; arma::vec vec1 = IO::GetParam("vector"); arma::vec vec2 = IO::GetParam("vector"); - BOOST_REQUIRE_EQUAL(vec1.n_rows, 63); - BOOST_REQUIRE_EQUAL(vec2.n_rows, 63); + REQUIRE(vec1.n_rows == 63); + REQUIRE(vec2.n_rows == 63); for (size_t i = 0; i < vec1.n_elem; ++i) - BOOST_REQUIRE_CLOSE(vec1[i], vec2[i], 1e-10); + REQUIRE(vec1[i] == Approx(vec2[i]).epsilon(1e-12)); } -BOOST_AUTO_TEST_CASE(InputUnsignedColVectorParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "InputUnsignedColVectorParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -285,24 +286,25 @@ BOOST_AUTO_TEST_CASE(InputUnsignedColVectorParamTest) ParseCommandLine(argc, const_cast(argv)); // The --vector parameter should exist. - BOOST_REQUIRE(IO::HasParam("vector")); + REQUIRE(IO::HasParam("vector")); // The --vector_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("vector_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("vector_file"), runtime_error); Log::Fatal.ignoreInput = false; arma::Col vec1 = IO::GetParam>("vector"); arma::Col vec2 = IO::GetParam>("vector"); - BOOST_REQUIRE_EQUAL(vec1.n_rows, 63); - BOOST_REQUIRE_EQUAL(vec2.n_rows, 63); + REQUIRE(vec1.n_rows == 63); + REQUIRE(vec2.n_rows == 63); for (size_t i = 0; i < vec1.n_elem; ++i) - BOOST_REQUIRE_EQUAL(vec1[i], vec2[i]); + REQUIRE(vec1[i] == vec2[i]); } -BOOST_AUTO_TEST_CASE(InputRowVectorParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "InputRowVectorParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -320,24 +322,25 @@ BOOST_AUTO_TEST_CASE(InputRowVectorParamTest) ParseCommandLine(argc, const_cast(argv)); // The --vector parameter should exist. - BOOST_REQUIRE(IO::HasParam("row")); + REQUIRE(IO::HasParam("row")); // The --vector_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("row_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("row_file"), runtime_error); Log::Fatal.ignoreInput = false; arma::rowvec vec1 = IO::GetParam("row"); arma::rowvec vec2 = IO::GetParam("row"); - BOOST_REQUIRE_EQUAL(vec1.n_cols, 7); - BOOST_REQUIRE_EQUAL(vec2.n_cols, 7); + REQUIRE(vec1.n_cols == 7); + REQUIRE(vec2.n_cols == 7); for (size_t i = 0; i < vec1.n_elem; ++i) - BOOST_REQUIRE_CLOSE(vec1[i], vec2[i], 1e-10); + REQUIRE(vec1[i] == Approx(vec2[i]).epsilon(1e-12)); } -BOOST_AUTO_TEST_CASE(InputUnsignedRowVectorParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "InputUnsignedRowVectorParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -355,24 +358,25 @@ BOOST_AUTO_TEST_CASE(InputUnsignedRowVectorParamTest) ParseCommandLine(argc, const_cast(argv)); // The --vector parameter should exist. - BOOST_REQUIRE(IO::HasParam("row")); + REQUIRE(IO::HasParam("row")); // The --vector_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("row_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("row_file"), runtime_error); Log::Fatal.ignoreInput = false; arma::Row vec1 = IO::GetParam>("row"); arma::Row vec2 = IO::GetParam>("row"); - BOOST_REQUIRE_EQUAL(vec1.n_cols, 7); - BOOST_REQUIRE_EQUAL(vec2.n_cols, 7); + REQUIRE(vec1.n_cols == 7); + REQUIRE(vec2.n_cols == 7); for (size_t i = 0; i < vec1.n_elem; ++i) - BOOST_REQUIRE_EQUAL(vec1[i], vec2[i]); + REQUIRE(vec1[i] == vec2[i]); } -BOOST_AUTO_TEST_CASE(OutputColParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "OutputColParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -390,11 +394,11 @@ BOOST_AUTO_TEST_CASE(OutputColParamTest) ParseCommandLine(argc, const_cast(argv)); // The --vector parameter should exist. - BOOST_REQUIRE(IO::HasParam("vector")); + REQUIRE(IO::HasParam("vector")); // The --vector_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("vector_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("vector_file"), runtime_error); Log::Fatal.ignoreInput = false; // Since it's an output parameter, we don't need any input and don't need to @@ -411,15 +415,16 @@ BOOST_AUTO_TEST_CASE(OutputColParamTest) arma::vec dataset2; data::Load("test.csv", dataset2); - BOOST_REQUIRE_EQUAL(dataset.n_rows, dataset2.n_rows); + REQUIRE(dataset.n_rows == dataset2.n_rows); for (size_t i = 0; i < dataset.n_elem; ++i) - BOOST_REQUIRE_CLOSE(dataset[i], dataset2[i], 1e-10); + REQUIRE(dataset[i] == Approx(dataset2[i]).epsilon(1e-12)); // Remove the file. remove("test.csv"); } -BOOST_AUTO_TEST_CASE(OutputUnsignedColParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "OutputUnsignedColParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -437,11 +442,11 @@ BOOST_AUTO_TEST_CASE(OutputUnsignedColParamTest) ParseCommandLine(argc, const_cast(argv)); // The --vector parameter should exist. - BOOST_REQUIRE(IO::HasParam("vector")); + REQUIRE(IO::HasParam("vector")); // The --vector_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("vector_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("vector_file"), runtime_error); Log::Fatal.ignoreInput = false; // Since it's an output parameter, we don't need any input and don't need to @@ -458,15 +463,16 @@ BOOST_AUTO_TEST_CASE(OutputUnsignedColParamTest) arma::Col dataset2; data::Load("test.csv", dataset2); - BOOST_REQUIRE_EQUAL(dataset.n_rows, dataset2.n_rows); + REQUIRE(dataset.n_rows == dataset2.n_rows); for (size_t i = 0; i < dataset.n_elem; ++i) - BOOST_REQUIRE_EQUAL(dataset[i], dataset2[i]); + REQUIRE(dataset[i] == dataset2[i]); // Remove the file. remove("test.csv"); } -BOOST_AUTO_TEST_CASE(OutputRowParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "OutputRowParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -484,11 +490,11 @@ BOOST_AUTO_TEST_CASE(OutputRowParamTest) ParseCommandLine(argc, const_cast(argv)); // The --row parameter should exist. - BOOST_REQUIRE(IO::HasParam("row")); + REQUIRE(IO::HasParam("row")); // The --row_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("row_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("row_file"), runtime_error); Log::Fatal.ignoreInput = false; // Since it's an output parameter, we don't need any input and don't need to @@ -505,15 +511,15 @@ BOOST_AUTO_TEST_CASE(OutputRowParamTest) arma::rowvec dataset2; data::Load("test.csv", dataset2); - BOOST_REQUIRE_EQUAL(dataset.n_cols, dataset2.n_cols); + REQUIRE(dataset.n_cols == dataset2.n_cols); for (size_t i = 0; i < dataset.n_elem; ++i) - BOOST_REQUIRE_CLOSE(dataset[i], dataset2[i], 1e-10); + REQUIRE(dataset[i] == Approx(dataset2[i]).epsilon(1e-12)); // Remove the file. remove("test.csv"); } -BOOST_AUTO_TEST_CASE(OutputUnsignedRowParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "OutputUnsignedRowParamTest", "[IOTest]") { AddRequiredCLIOptions(); @@ -531,11 +537,11 @@ BOOST_AUTO_TEST_CASE(OutputUnsignedRowParamTest) ParseCommandLine(argc, const_cast(argv)); // The --row parameter should exist. - BOOST_REQUIRE(IO::HasParam("row")); + REQUIRE(IO::HasParam("row")); // The --row_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("row_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("row_file"), runtime_error); Log::Fatal.ignoreInput = false; // Since it's an output parameter, we don't need any input and don't need to @@ -552,15 +558,16 @@ BOOST_AUTO_TEST_CASE(OutputUnsignedRowParamTest) arma::Row dataset2; data::Load("test.csv", dataset2); - BOOST_REQUIRE_EQUAL(dataset.n_cols, dataset2.n_cols); + REQUIRE(dataset.n_cols == dataset2.n_cols); for (size_t i = 0; i < dataset.n_elem; ++i) - BOOST_REQUIRE_EQUAL(dataset[i], dataset2[i]); + REQUIRE(dataset[i] == dataset2[i]); // Remove the file. remove("test.csv"); } -BOOST_AUTO_TEST_CASE(InputMatrixParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "InputMatrixParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -579,27 +586,28 @@ BOOST_AUTO_TEST_CASE(InputMatrixParamTest) ParseCommandLine(argc, const_cast(argv)); // The --matrix parameter should exist. - BOOST_REQUIRE(IO::HasParam("matrix")); + REQUIRE(IO::HasParam("matrix")); // The --matrix_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("matrix_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("matrix_file"), runtime_error); Log::Fatal.ignoreInput = false; arma::mat dataset = IO::GetParam("matrix"); arma::mat dataset2 = IO::GetParam("matrix"); - BOOST_REQUIRE_EQUAL(dataset.n_rows, 3); - BOOST_REQUIRE_EQUAL(dataset.n_cols, 1000); - BOOST_REQUIRE_EQUAL(dataset2.n_rows, 3); - BOOST_REQUIRE_EQUAL(dataset2.n_cols, 1000); + REQUIRE(dataset.n_rows == 3); + REQUIRE(dataset.n_cols == 1000); + REQUIRE(dataset2.n_rows == 3); + REQUIRE(dataset2.n_cols == 1000); for (size_t i = 0; i < dataset.n_elem; ++i) - BOOST_REQUIRE_CLOSE(dataset[i], dataset2[i], 1e-10); + REQUIRE(dataset[i] == Approx(dataset2[i]).epsilon(1e-12)); } // Make sure we can correctly load required matrix parameters. -BOOST_AUTO_TEST_CASE(RequiredInputMatrixParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "RequiredInputMatrixParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -618,27 +626,28 @@ BOOST_AUTO_TEST_CASE(RequiredInputMatrixParamTest) ParseCommandLine(argc, const_cast(argv)); // The --matrix parameter should exist. - BOOST_REQUIRE(IO::HasParam("matrix")); + REQUIRE(IO::HasParam("matrix")); // The --matrix_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("matrix_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("matrix_file"), runtime_error); Log::Fatal.ignoreInput = false; arma::mat dataset = IO::GetParam("matrix"); arma::mat dataset2 = IO::GetParam("matrix"); - BOOST_REQUIRE_EQUAL(dataset.n_rows, 3); - BOOST_REQUIRE_EQUAL(dataset.n_cols, 1000); - BOOST_REQUIRE_EQUAL(dataset2.n_rows, 3); - BOOST_REQUIRE_EQUAL(dataset2.n_cols, 1000); + REQUIRE(dataset.n_rows == 3); + REQUIRE(dataset.n_cols == 1000); + REQUIRE(dataset2.n_rows == 3); + REQUIRE(dataset2.n_cols == 1000); for (size_t i = 0; i < dataset.n_elem; ++i) - BOOST_REQUIRE_CLOSE(dataset[i], dataset2[i], 1e-10); + REQUIRE(dataset[i] == Approx(dataset2[i]).epsilon(1e-12)); } // Make sure loading required matrix options by alias succeeds. -BOOST_AUTO_TEST_CASE(RequiredInputMatrixParamAliasTest) +TEST_CASE_METHOD(IOTestDestroyer, "RequiredInputMatrixParamAliasTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -657,27 +666,28 @@ BOOST_AUTO_TEST_CASE(RequiredInputMatrixParamAliasTest) ParseCommandLine(argc, const_cast(argv)); // The --matrix parameter should exist. - BOOST_REQUIRE(IO::HasParam("matrix")); + REQUIRE(IO::HasParam("matrix")); // The --matrix_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("matrix_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("matrix_file"), runtime_error); Log::Fatal.ignoreInput = false; arma::mat dataset = IO::GetParam("matrix"); arma::mat dataset2 = IO::GetParam("matrix"); - BOOST_REQUIRE_EQUAL(dataset.n_rows, 3); - BOOST_REQUIRE_EQUAL(dataset.n_cols, 1000); - BOOST_REQUIRE_EQUAL(dataset2.n_rows, 3); - BOOST_REQUIRE_EQUAL(dataset2.n_cols, 1000); + REQUIRE(dataset.n_rows == 3); + REQUIRE(dataset.n_cols == 1000); + REQUIRE(dataset2.n_rows == 3); + REQUIRE(dataset2.n_cols == 1000); for (size_t i = 0; i < dataset.n_elem; ++i) - BOOST_REQUIRE_CLOSE(dataset[i], dataset2[i], 1e-10); + REQUIRE(dataset[i] == Approx(dataset2[i]).epsilon(1e-12)); } // Make sure that when we don't pass a required matrix, parsing fails. -BOOST_AUTO_TEST_CASE(RequiredUnspecifiedInputMatrixParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "RequiredUnspecifiedInputMatrixParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -692,12 +702,13 @@ BOOST_AUTO_TEST_CASE(RequiredUnspecifiedInputMatrixParamTest) // The const-cast is a little hacky but should be fine... Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(ParseCommandLine(argc, const_cast(argv)), + REQUIRE_THROWS_AS(ParseCommandLine(argc, const_cast(argv)), std::exception); Log::Fatal.ignoreInput = false; } -BOOST_AUTO_TEST_CASE(InputMatrixNoTransposeParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "InputMatrixNoTransposeParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -716,26 +727,27 @@ BOOST_AUTO_TEST_CASE(InputMatrixNoTransposeParamTest) ParseCommandLine(argc, const_cast(argv)); // The --matrix parameter should exist. - BOOST_REQUIRE(IO::HasParam("matrix")); + REQUIRE(IO::HasParam("matrix")); // The --matrix_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("matrix_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("matrix_file"), runtime_error); Log::Fatal.ignoreInput = false; arma::mat dataset = IO::GetParam("matrix"); arma::mat dataset2 = IO::GetParam("matrix"); - BOOST_REQUIRE_EQUAL(dataset.n_rows, 1000); - BOOST_REQUIRE_EQUAL(dataset.n_cols, 3); - BOOST_REQUIRE_EQUAL(dataset2.n_rows, 1000); - BOOST_REQUIRE_EQUAL(dataset2.n_cols, 3); + REQUIRE(dataset.n_rows == 1000); + REQUIRE(dataset.n_cols == 3); + REQUIRE(dataset2.n_rows == 1000); + REQUIRE(dataset2.n_cols == 3); for (size_t i = 0; i < dataset.n_elem; ++i) - BOOST_REQUIRE_CLOSE(dataset[i], dataset2[i], 1e-10); + REQUIRE(dataset[i] == Approx(dataset2[i]).epsilon(1e-12)); } -BOOST_AUTO_TEST_CASE(OutputMatrixParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "OutputMatrixParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -753,11 +765,11 @@ BOOST_AUTO_TEST_CASE(OutputMatrixParamTest) ParseCommandLine(argc, const_cast(argv)); // The --matrix parameter should exist. - BOOST_REQUIRE(IO::HasParam("matrix")); + REQUIRE(IO::HasParam("matrix")); // The --matrix_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("matrix_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("matrix_file"), runtime_error); Log::Fatal.ignoreInput = false; // Since it's an output parameter, we don't need any input and don't need to @@ -774,16 +786,16 @@ BOOST_AUTO_TEST_CASE(OutputMatrixParamTest) arma::mat dataset2; data::Load("test.csv", dataset2); - BOOST_REQUIRE_EQUAL(dataset.n_cols, dataset2.n_cols); - BOOST_REQUIRE_EQUAL(dataset.n_rows, dataset2.n_rows); + REQUIRE(dataset.n_cols == dataset2.n_cols); + REQUIRE(dataset.n_rows == dataset2.n_rows); for (size_t i = 0; i < dataset.n_elem; ++i) - BOOST_REQUIRE_CLOSE(dataset[i], dataset2[i], 1e-10); + REQUIRE(dataset[i] == Approx(dataset2[i]).epsilon(1e-12)); // Remove the file. remove("test.csv"); } -BOOST_AUTO_TEST_CASE(OutputMatrixNoTransposeParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "OutputMatrixNoTransposeParamTest", "[IOTest]") { AddRequiredCLIOptions(); @@ -801,11 +813,11 @@ BOOST_AUTO_TEST_CASE(OutputMatrixNoTransposeParamTest) ParseCommandLine(argc, const_cast(argv)); // The --matrix parameter should exist. - BOOST_REQUIRE(IO::HasParam("matrix")); + REQUIRE(IO::HasParam("matrix")); // The --matrix_file parameter should not exist (it should be transparent from // inside the program). Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(IO::HasParam("matrix_file"), runtime_error); + REQUIRE_THROWS_AS(IO::HasParam("matrix_file"), runtime_error); Log::Fatal.ignoreInput = false; // Since it's an output parameter, we don't need any input and don't need to @@ -822,16 +834,17 @@ BOOST_AUTO_TEST_CASE(OutputMatrixNoTransposeParamTest) arma::mat dataset2; data::Load("test.csv", dataset2, true, false); - BOOST_REQUIRE_EQUAL(dataset.n_cols, dataset2.n_cols); - BOOST_REQUIRE_EQUAL(dataset.n_rows, dataset2.n_rows); + REQUIRE(dataset.n_cols == dataset2.n_cols); + REQUIRE(dataset.n_rows == dataset2.n_rows); for (size_t i = 0; i < dataset.n_elem; ++i) - BOOST_REQUIRE_CLOSE(dataset[i], dataset2[i], 1e-10); + REQUIRE(dataset[i] == Approx(dataset2[i]).epsilon(1e-12)); // Remove the file. remove("test.csv"); } -BOOST_AUTO_TEST_CASE(IntParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "IntParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -846,11 +859,12 @@ BOOST_AUTO_TEST_CASE(IntParamTest) ParseCommandLine(argc, const_cast(argv)); - BOOST_REQUIRE(IO::HasParam("int")); - BOOST_REQUIRE_EQUAL(IO::GetParam("int"), 3); + REQUIRE(IO::HasParam("int")); + REQUIRE(IO::GetParam("int") == 3); } -BOOST_AUTO_TEST_CASE(StringParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "StringParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -865,11 +879,12 @@ BOOST_AUTO_TEST_CASE(StringParamTest) ParseCommandLine(argc, const_cast(argv)); - BOOST_REQUIRE(IO::HasParam("string")); - BOOST_REQUIRE_EQUAL(IO::GetParam("string"), string("3")); + REQUIRE(IO::HasParam("string")); + REQUIRE(IO::GetParam("string") == string("3")); } -BOOST_AUTO_TEST_CASE(DoubleParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "DoubleParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -884,11 +899,11 @@ BOOST_AUTO_TEST_CASE(DoubleParamTest) ParseCommandLine(argc, const_cast(argv)); - BOOST_REQUIRE(IO::HasParam("double")); - BOOST_REQUIRE_CLOSE(IO::GetParam("double"), 3.12, 1e-10); + REQUIRE(IO::HasParam("double")); + REQUIRE(IO::GetParam("double") == Approx(3.12).epsilon(1e-12)); } -BOOST_AUTO_TEST_CASE(RequiredOptionTest) +TEST_CASE_METHOD(IOTestDestroyer, "RequiredOptionTest", "[IOTest]") { AddRequiredCLIOptions(); @@ -900,12 +915,13 @@ BOOST_AUTO_TEST_CASE(RequiredOptionTest) int argc = 1; Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(ParseCommandLine(argc, const_cast(argv)), + REQUIRE_THROWS_AS(ParseCommandLine(argc, const_cast(argv)), runtime_error); Log::Fatal.ignoreInput = false; } -BOOST_AUTO_TEST_CASE(UnknownOptionTest) +TEST_CASE_METHOD(IOTestDestroyer, "UnknownOptionTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -916,7 +932,7 @@ BOOST_AUTO_TEST_CASE(UnknownOptionTest) int argc = 2; Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(ParseCommandLine(argc, const_cast(argv)), + REQUIRE_THROWS_AS(ParseCommandLine(argc, const_cast(argv)), runtime_error); Log::Fatal.ignoreInput = false; } @@ -924,7 +940,8 @@ BOOST_AUTO_TEST_CASE(UnknownOptionTest) /** * Test that GetPrintableParam() works. */ -BOOST_AUTO_TEST_CASE(UnmappedParamTest) +TEST_CASE_METHOD(IOTestDestroyer, "UnmappedParamTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -949,15 +966,15 @@ BOOST_AUTO_TEST_CASE(UnmappedParamTest) ParseCommandLine(argc, const_cast(argv)); // Now check that we can get unmapped parameters. - BOOST_REQUIRE_EQUAL(IO::GetPrintableParam("matrix"), + REQUIRE(IO::GetPrintableParam("matrix") == "'test_data_3_1000.csv' (3x1000 matrix)"); // This will have size 0x0 since it's an output parameter, and it hasn't been // set since ParseCommandLine() was called. - BOOST_REQUIRE_EQUAL(IO::GetPrintableParam("matrix2"), + REQUIRE(IO::GetPrintableParam("matrix2") == "'file2.csv' (0x0 matrix)"); - BOOST_REQUIRE_EQUAL(IO::GetPrintableParam("kernel"), + REQUIRE(IO::GetPrintableParam("kernel") == "kernel.txt"); - BOOST_REQUIRE_EQUAL(IO::GetPrintableParam("kernel2"), + REQUIRE(IO::GetPrintableParam("kernel2") == "kernel2.txt"); remove("kernel.txt"); @@ -967,7 +984,7 @@ BOOST_AUTO_TEST_CASE(UnmappedParamTest) * Test that we can serialize a model and then deserialize it through the CLI * interface. */ -BOOST_AUTO_TEST_CASE(SerializationTest) +TEST_CASE_METHOD(IOTestDestroyer, "IOSerializationTest", "[IOTest]") { AddRequiredCLIOptions(); @@ -1001,7 +1018,7 @@ BOOST_AUTO_TEST_CASE(SerializationTest) // Load the kernel from file. GaussianKernel* gk2 = IO::GetParam("kernel"); - BOOST_REQUIRE_CLOSE(gk2->Bandwidth(), 0.5, 1e-5); + REQUIRE(gk2->Bandwidth() == Approx(0.5).epsilon(1e-7)); // Clean up the memory... delete gk2; @@ -1013,7 +1030,8 @@ BOOST_AUTO_TEST_CASE(SerializationTest) /** * Test that an exception is thrown when a required model is not specified. */ -BOOST_AUTO_TEST_CASE(RequiredModelTest) +TEST_CASE_METHOD(IOTestDestroyer, "RequiredModelTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -1026,7 +1044,7 @@ BOOST_AUTO_TEST_CASE(RequiredModelTest) int argc = 1; Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(ParseCommandLine(argc, const_cast(argv)), + REQUIRE_THROWS_AS(ParseCommandLine(argc, const_cast(argv)), runtime_error); Log::Fatal.ignoreInput = false; } @@ -1034,7 +1052,8 @@ BOOST_AUTO_TEST_CASE(RequiredModelTest) /** * Test that we can load both a dataset and its associated info. */ -BOOST_AUTO_TEST_CASE(MatrixAndDatasetInfoTest) +TEST_CASE_METHOD(IOTestDestroyer, "MatrixAndDatasetInfoTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -1074,32 +1093,32 @@ BOOST_AUTO_TEST_CASE(MatrixAndDatasetInfoTest) DatasetInfo info = move(get<0>(IO::GetParam("dataset"))); arma::mat dataset = move(get<1>(IO::GetParam("dataset"))); - BOOST_REQUIRE_EQUAL(info.Dimensionality(), 3); + REQUIRE(info.Dimensionality() == 3); - BOOST_REQUIRE(info.Type(0) == Datatype::categorical); - BOOST_REQUIRE_EQUAL(info.NumMappings(0), 3); - BOOST_REQUIRE(info.Type(1) == Datatype::numeric); - BOOST_REQUIRE(info.Type(2) == Datatype::categorical); - BOOST_REQUIRE_EQUAL(info.NumMappings(2), 2); + REQUIRE(info.Type(0) == Datatype::categorical); + REQUIRE(info.NumMappings(0) == 3); + REQUIRE(info.Type(1) == Datatype::numeric); + REQUIRE(info.Type(2) == Datatype::categorical); + REQUIRE(info.NumMappings(2) == 2); - BOOST_REQUIRE_EQUAL(dataset.n_rows, 3); - BOOST_REQUIRE_EQUAL(dataset.n_cols, 4); + REQUIRE(dataset.n_rows == 3); + REQUIRE(dataset.n_cols == 4); // The first dimension must all be different (except the ones that are the // same). - BOOST_REQUIRE_EQUAL(dataset(0, 0), dataset(0, 3)); - BOOST_REQUIRE_NE(dataset(0, 0), dataset(0, 1)); - BOOST_REQUIRE_NE(dataset(0, 1), dataset(0, 2)); - BOOST_REQUIRE_NE(dataset(0, 2), dataset(0, 0)); + REQUIRE(dataset(0, 0) == dataset(0, 3)); + REQUIRE(dataset(0, 0) != dataset(0, 1)); + REQUIRE(dataset(0, 1) != dataset(0, 2)); + REQUIRE(dataset(0, 2) != dataset(0, 0)); - BOOST_REQUIRE_CLOSE(dataset(1, 0), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(dataset(1, 1), 2.34, 1e-5); - BOOST_REQUIRE_CLOSE(dataset(1, 2), 1.03e5, 1e-5); - BOOST_REQUIRE_CLOSE(dataset(1, 3), -1.3, 1e-5); + REQUIRE(dataset(1, 0) == Approx(1.0).epsilon(1e-7)); + REQUIRE(dataset(1, 1) == Approx(2.34).epsilon(1e-7)); + REQUIRE(dataset(1, 2) == Approx(1.03e5).epsilon(1e-7)); + REQUIRE(dataset(1, 3) == Approx(-1.3).epsilon(1e-7)); - BOOST_REQUIRE_EQUAL(dataset(2, 0), dataset(2, 2)); - BOOST_REQUIRE_EQUAL(dataset(2, 1), dataset(2, 3)); - BOOST_REQUIRE_NE(dataset(2, 0), dataset(2, 1)); + REQUIRE(dataset(2, 0) == dataset(2, 2)); + REQUIRE(dataset(2, 1) == dataset(2, 3)); + REQUIRE(dataset(2, 0) != dataset(2, 1)); remove("test.arff"); } @@ -1107,7 +1126,7 @@ BOOST_AUTO_TEST_CASE(MatrixAndDatasetInfoTest) /** * Test that we can access a parameter before we load it. */ -BOOST_AUTO_TEST_CASE(RawIntegralParameter) +TEST_CASE_METHOD(IOTestDestroyer, "RawIntegralParameter", "[IOTest]") { AddRequiredCLIOptions(); @@ -1123,14 +1142,14 @@ BOOST_AUTO_TEST_CASE(RawIntegralParameter) IO::GetRawParam("double") = 3.0; // Now when we get it, it should be what we just set it to. - BOOST_REQUIRE_CLOSE(IO::GetParam("double"), 3.0, 1e-5); + REQUIRE(IO::GetParam("double") == Approx(3.0).epsilon(1e-7)); } /** * Test that we can load a dataset with a pre-set mapping through * IO::GetRawParam(). */ -BOOST_AUTO_TEST_CASE(RawDatasetInfoLoadParameter) +TEST_CASE_METHOD(IOTestDestroyer, "RawDatasetInfoLoadParameter", "[IOTest]") { AddRequiredCLIOptions(); @@ -1181,18 +1200,18 @@ BOOST_AUTO_TEST_CASE(RawDatasetInfoLoadParameter) std::get<1>(IO::GetParam>("tuple")); // Check the values. - BOOST_REQUIRE_CLOSE(dataset(0, 0), 2.0, 1e-5); - BOOST_REQUIRE_CLOSE(dataset(1, 0), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(dataset(2, 0), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(dataset(0, 1), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(dataset(1, 1), 2.34, 1e-5); - BOOST_REQUIRE_SMALL(dataset(2, 1), 1e-5); - BOOST_REQUIRE_SMALL(dataset(0, 2), 1e-5); - BOOST_REQUIRE_CLOSE(dataset(1, 2), 1.03e+5, 1e-5); - BOOST_REQUIRE_CLOSE(dataset(2, 2), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(dataset(0, 3), 2.0, 1e-5); - BOOST_REQUIRE_CLOSE(dataset(1, 3), -1.3, 1e-5); - BOOST_REQUIRE_SMALL(dataset(2, 3), 1e-5); + REQUIRE(dataset(0, 0) == Approx(2.0).epsilon(1e-7)); + REQUIRE(dataset(1, 0) == Approx(1.0).epsilon(1e-7)); + REQUIRE(dataset(2, 0) == Approx(1.0).epsilon(1e-7)); + REQUIRE(dataset(0, 1) == Approx(1.0).epsilon(1e-7)); + REQUIRE(dataset(1, 1) == Approx(2.34).epsilon(1e-7)); + REQUIRE(dataset(2, 1) == Approx(0.0).margin(1e-5)); + REQUIRE(dataset(0, 2) == Approx(0.0).margin(1e-5)); + REQUIRE(dataset(1, 2) == Approx(1.03e+5).epsilon(1e-7)); + REQUIRE(dataset(2, 2) == Approx(1.0).epsilon(1e-7)); + REQUIRE(dataset(0, 3) == Approx(2.0).epsilon(1e-7)); + REQUIRE(dataset(1, 3) == Approx(-1.3).epsilon(1e-7)); + REQUIRE(dataset(2, 3) == Approx(0.0).margin(1e-5)); remove("test.arff"); } @@ -1200,7 +1219,8 @@ BOOST_AUTO_TEST_CASE(RawDatasetInfoLoadParameter) /** * Make sure typenames are properly stored. */ -BOOST_AUTO_TEST_CASE(CppNameTest) +TEST_CASE_METHOD(IOTestDestroyer, "CppNameTest", + "[IOTest]") { AddRequiredCLIOptions(); @@ -1209,9 +1229,7 @@ BOOST_AUTO_TEST_CASE(CppNameTest) PARAM_DOUBLE_IN("double", "Test double", "d", 0.0); // Check that the C++ typenames are right. - BOOST_REQUIRE_EQUAL(IO::Parameters().at("matrix").cppType, "arma::mat"); - BOOST_REQUIRE_EQUAL(IO::Parameters().at("help").cppType, "bool"); - BOOST_REQUIRE_EQUAL(IO::Parameters().at("double").cppType, "double"); + REQUIRE(IO::Parameters().at("matrix").cppType == "arma::mat"); + REQUIRE(IO::Parameters().at("help").cppType == "bool"); + REQUIRE(IO::Parameters().at("double").cppType == "double"); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/lars_test.cpp b/src/mlpack/tests/lars_test.cpp index cbbe5687a3..68f89db8fc 100644 --- a/src/mlpack/tests/lars_test.cpp +++ b/src/mlpack/tests/lars_test.cpp @@ -10,19 +10,15 @@ * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ -// Note: We don't use BOOST_REQUIRE_CLOSE in the code below because we need -// to use FPC_WEAK, and it's not at all intuitive how to do that. #include #include -#include -#include "test_tools.hpp" +#include "catch.hpp" +#include "test_catch_tools.hpp" using namespace mlpack; using namespace mlpack::regression; -BOOST_AUTO_TEST_SUITE(LARSTest); - void GenerateProblem( arma::mat& X, arma::rowvec& y, size_t nPoints, size_t nDims) { @@ -40,17 +36,18 @@ void LARSVerifyCorrectness(arma::vec beta, arma::vec errCorr, double lambda) if (beta(j) == 0) { // Make sure that |errCorr(j)| <= lambda. - BOOST_REQUIRE_SMALL(std::max(fabs(errCorr(j)) - lambda, 0.0), tol); + REQUIRE(std::max(fabs(errCorr(j)) - lambda, 0.0) == + Approx(0.0).margin(tol)); } else if (beta(j) < 0) { // Make sure that errCorr(j) == lambda. - BOOST_REQUIRE_SMALL(errCorr(j) - lambda, tol); + REQUIRE(errCorr(j) - lambda == Approx(0.0).margin(tol)); } else // beta(j) > 0 { // Make sure that errCorr(j) == -lambda. - BOOST_REQUIRE_SMALL(errCorr(j) + lambda, tol); + REQUIRE(errCorr(j) + lambda == Approx(0.0).margin(tol)); } } } @@ -85,23 +82,23 @@ void LassoTest(size_t nPoints, size_t nDims, bool elasticNet, bool useCholesky) } } -BOOST_AUTO_TEST_CASE(LARSTestLassoCholesky) +TEST_CASE("LARSTestLassoCholesky", "[LARSTest]") { LassoTest(100, 10, false, true); } -BOOST_AUTO_TEST_CASE(LARSTestLassoGram) +TEST_CASE("LARSTestLassoGram", "[LARSTest]") { LassoTest(100, 10, false, false); } -BOOST_AUTO_TEST_CASE(LARSTestElasticNetCholesky) +TEST_CASE("LARSTestElasticNetCholesky", "[LARSTest]") { LassoTest(100, 10, true, true); } -BOOST_AUTO_TEST_CASE(LARSTestElasticNetGram) +TEST_CASE("LARSTestElasticNetGram", "[LARSTest]") { LassoTest(100, 10, true, false); } @@ -109,7 +106,7 @@ BOOST_AUTO_TEST_CASE(LARSTestElasticNetGram) // Ensure that LARS doesn't crash when the data has linearly dependent features // (meaning that there is a singularity). This test uses the Cholesky // factorization. -BOOST_AUTO_TEST_CASE(CholeskySingularityTest) +TEST_CASE("CholeskySingularityTest", "[LARSTest]") { arma::mat X; arma::mat Y; @@ -133,7 +130,7 @@ BOOST_AUTO_TEST_CASE(CholeskySingularityTest) } // Same as the above test but with no cholesky factorization. -BOOST_AUTO_TEST_CASE(NoCholeskySingularityTest) +TEST_CASE("NoCholeskySingularityTest", "[LARSTest]") { arma::mat X; arma::mat Y; @@ -158,7 +155,7 @@ BOOST_AUTO_TEST_CASE(NoCholeskySingularityTest) } // Make sure that Predict() provides reasonable enough solutions. -BOOST_AUTO_TEST_CASE(PredictTest) +TEST_CASE("PredictTest", "[LARSTest]") { for (size_t i = 0; i < 2; ++i) { @@ -185,20 +182,20 @@ BOOST_AUTO_TEST_CASE(PredictTest) lars.Predict(X, predictions); arma::vec adjPred = X * predictions.t(); - BOOST_REQUIRE_EQUAL(predictions.n_elem, 1000); + REQUIRE(predictions.n_elem == 1000); for (size_t i = 0; i < betaOptPred.n_elem; ++i) { if (std::abs(betaOptPred[i]) < 1e-5) - BOOST_REQUIRE_SMALL(adjPred[i], 1e-5); + REQUIRE(adjPred[i] == Approx(0.0).margin(1e-5)); else - BOOST_REQUIRE_CLOSE(adjPred[i], betaOptPred[i], 1e-5); + REQUIRE(adjPred[i] == Approx(betaOptPred[i]).epsilon(1e-7)); } } } } } -BOOST_AUTO_TEST_CASE(PredictRowMajorTest) +TEST_CASE("PredictRowMajorTest", "[LARSTest]") { arma::mat X; arma::rowvec y; @@ -217,20 +214,20 @@ BOOST_AUTO_TEST_CASE(PredictRowMajorTest) lars.Predict(X, colMajorPred); lars.Predict(X.t(), rowMajorPred, true); - BOOST_REQUIRE_EQUAL(colMajorPred.n_elem, rowMajorPred.n_elem); + REQUIRE(colMajorPred.n_elem == rowMajorPred.n_elem); for (size_t i = 0; i < colMajorPred.n_elem; ++i) { if (std::abs(colMajorPred[i]) < 1e-5) - BOOST_REQUIRE_SMALL(rowMajorPred[i], 1e-5); + REQUIRE(rowMajorPred[i] == Approx(0.0).margin(1e-5)); else - BOOST_REQUIRE_CLOSE(colMajorPred[i], rowMajorPred[i], 1e-5); + REQUIRE(colMajorPred[i] == Approx(rowMajorPred[i]).epsilon(1e-7)); } } /** * Make sure that if we train twice, there is no issue. */ -BOOST_AUTO_TEST_CASE(RetrainTest) +TEST_CASE("RetrainTest", "[LARSTest]") { arma::mat origX; arma::rowvec origY; @@ -257,7 +254,7 @@ BOOST_AUTO_TEST_CASE(RetrainTest) * Make sure if we train twice using the Cholesky decomposition, there is no * issue. */ -BOOST_AUTO_TEST_CASE(RetrainCholeskyTest) +TEST_CASE("RetrainCholeskyTest", "[LARSTest]") { arma::mat origX; arma::rowvec origY; @@ -284,7 +281,7 @@ BOOST_AUTO_TEST_CASE(RetrainCholeskyTest) * Make sure that we get correct solution coefficients when running training * and accessing solution coefficients separately. */ -BOOST_AUTO_TEST_CASE(TrainingAndAccessingBetaTest) +TEST_CASE("TrainingAndAccessingBetaTest", "[LARSTest]") { arma::mat X; arma::rowvec y; @@ -298,16 +295,16 @@ BOOST_AUTO_TEST_CASE(TrainingAndAccessingBetaTest) LARS lars2; lars2.Train(X, y); - BOOST_REQUIRE_EQUAL(beta.n_elem, lars2.Beta().n_elem); + REQUIRE(beta.n_elem == lars2.Beta().n_elem); for (size_t i = 0; i < beta.n_elem; ++i) - BOOST_REQUIRE_CLOSE(beta[i], lars2.Beta()[i], 1e-5); + REQUIRE(beta[i] == Approx(lars2.Beta()[i]).epsilon(1e-7)); } /** * Make sure that we learn the same when running training separately and through * constructor. Test it with default parameters. */ -BOOST_AUTO_TEST_CASE(TrainingConstructorWithDefaultsTest) +TEST_CASE("TrainingConstructorWithDefaultsTest", "[LARSTest]") { arma::mat X; arma::rowvec y; @@ -320,16 +317,16 @@ BOOST_AUTO_TEST_CASE(TrainingConstructorWithDefaultsTest) LARS lars2(X, y); - BOOST_REQUIRE_EQUAL(beta.n_elem, lars2.Beta().n_elem); + REQUIRE(beta.n_elem == lars2.Beta().n_elem); for (size_t i = 0; i < beta.n_elem; ++i) - BOOST_REQUIRE_CLOSE(beta[i], lars2.Beta()[i], 1e-5); + REQUIRE(beta[i] == Approx(lars2.Beta()[i]).epsilon(1e-7)); } /** * Make sure that we learn the same when running training separately and through * constructor. Test it with non default parameters. */ -BOOST_AUTO_TEST_CASE(TrainingConstructorWithNonDefaultsTest) +TEST_CASE("TrainingConstructorWithNonDefaultsTest", "[LARSTest]") { arma::mat X; arma::rowvec y; @@ -347,15 +344,15 @@ BOOST_AUTO_TEST_CASE(TrainingConstructorWithNonDefaultsTest) LARS lars2(X, y, transposeData, useCholesky, lambda1, lambda2); - BOOST_REQUIRE_EQUAL(beta.n_elem, lars2.Beta().n_elem); + REQUIRE(beta.n_elem == lars2.Beta().n_elem); for (size_t i = 0; i < beta.n_elem; ++i) - BOOST_REQUIRE_CLOSE(beta[i], lars2.Beta()[i], 1e-5); + REQUIRE(beta[i] == Approx(lars2.Beta()[i]).epsilon(1e-7)); } /** * Test that LARS::Train() returns finite error value. */ -BOOST_AUTO_TEST_CASE(LARSTrainReturnCorrelation) +TEST_CASE("LARSTrainReturnCorrelation", "[LARSTest]") { arma::mat X; arma::mat Y; @@ -373,35 +370,35 @@ BOOST_AUTO_TEST_CASE(LARSTrainReturnCorrelation) arma::vec betaOpt1; double error = lars1.Train(X, y, betaOpt1); - BOOST_REQUIRE_EQUAL(std::isfinite(error), true); + REQUIRE(std::isfinite(error) == true); // Test without Cholesky decomposition and with lasso. LARS lars2(false, lambda1, 0.0); arma::vec betaOpt2; error = lars2.Train(X, y, betaOpt2); - BOOST_REQUIRE_EQUAL(std::isfinite(error), true); + REQUIRE(std::isfinite(error) == true); // Test with Cholesky decomposition and with elasticnet. LARS lars3(true, lambda1, lambda2); arma::vec betaOpt3; error = lars3.Train(X, y, betaOpt3); - BOOST_REQUIRE_EQUAL(std::isfinite(error), true); + REQUIRE(std::isfinite(error) == true); // Test without Cholesky decomposition and with elasticnet. LARS lars4(false, lambda1, lambda2); arma::vec betaOpt4; error = lars4.Train(X, y, betaOpt4); - BOOST_REQUIRE_EQUAL(std::isfinite(error), true); + REQUIRE(std::isfinite(error) == true); } /** * Test that LARS::ComputeError() returns error value less than 1 * and greater than 0. */ -BOOST_AUTO_TEST_CASE(LARSTestComputeError) +TEST_CASE("LARSTestComputeError", "[LARSTest]") { arma::mat X; arma::mat Y; @@ -416,15 +413,15 @@ BOOST_AUTO_TEST_CASE(LARSTestComputeError) double train1 = lars1.Train(X, y, betaOpt1); double cost = lars1.ComputeError(X, y); - BOOST_REQUIRE_EQUAL(cost <= 1, true); - BOOST_REQUIRE_EQUAL(cost >= 0, true); - BOOST_REQUIRE_EQUAL(cost == train1, true); + REQUIRE(cost <= 1); + REQUIRE(cost >= 0); + REQUIRE(cost == train1); } /** * Simple test for LARS copy constructor. */ -BOOST_AUTO_TEST_CASE(LARSCopyConstructorTest) +TEST_CASE("LARSCopyConstructorTest", "[LARSTest]") { arma::mat features, Y; arma::rowvec targets; @@ -447,13 +444,13 @@ BOOST_AUTO_TEST_CASE(LARSCopyConstructorTest) // The output of both models should be the same. CheckMatrices(predictions, predictionsFromCopiedModel); // Check if we can train the model again. - BOOST_REQUIRE_NO_THROW(models[0].Train(features, targets)); + REQUIRE_NOTHROW(models[0].Train(features, targets)); // Check if we can train the copied model. mlpack::regression::LARS glm2(false, 0.1, 0.1); models.emplace_back(glm2); // Call the copy constructor. - BOOST_REQUIRE_NO_THROW(glm2.Train(features, targets)); - BOOST_REQUIRE_NO_THROW(models[1].Train(features, targets)); + REQUIRE_NOTHROW(glm2.Train(features, targets)); + REQUIRE_NOTHROW(models[1].Train(features, targets)); // Create a copy using assignment operator. mlpack::regression::LARS glm3 = glm2; @@ -462,5 +459,3 @@ BOOST_AUTO_TEST_CASE(LARSCopyConstructorTest) // The output of both models should be the same. CheckMatrices(predictions, predictionsFromCopiedModel); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/layer_names_test.cpp b/src/mlpack/tests/layer_names_test.cpp index 23722e2b75..9d94f0ff67 100644 --- a/src/mlpack/tests/layer_names_test.cpp +++ b/src/mlpack/tests/layer_names_test.cpp @@ -15,18 +15,15 @@ #include #include -#include -#include "test_tools.hpp" +#include "catch.hpp" using namespace mlpack; using namespace ann; -BOOST_AUTO_TEST_SUITE(LayerNamesTest); - /** * Test if the LayerNameVisitor works properly. */ -BOOST_AUTO_TEST_CASE(LayerNameVisitorTest) +TEST_CASE("LayerNameVisitorTest", "[LayerNamesTest]") { LayerTypes<> atrousConvolution = new AtrousConvolution<>(); LayerTypes<> alphaDropout = new AlphaDropout<>(); @@ -63,70 +60,70 @@ BOOST_AUTO_TEST_CASE(LayerNameVisitorTest) // Bilinear interpolation is not yet supported by the string converter. LayerTypes<> unsupportedLayer = new BilinearInterpolation<>(); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - atrousConvolution) == "atrousconvolution"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - alphaDropout) == "alphadropout"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - batchNorm) == "batchnorm"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - constant) == "constant"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - convolution) == "convolution"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - dropConnect) == "dropconnect"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - dropout) == "dropout"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - flexibleReLU) == "flexiblerelu"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - layerNorm) == "layernorm"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - linear) == "linear"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - linearNoBias) == "linearnobias"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - maxPooling) == "maxpooling"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - meanPooling) == "meanpooling"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - multiplyConstant) == "multiplyconstant"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - reLULayer) == "relu"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - transposedConvolution) == "transposedconvolution"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - identityLayer) == "identity"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - tanHLayer) == "tanh"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - eLU) == "elu"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - hardTanH) == "hardtanh"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - leakyReLU) == "leakyrelu"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - pReLU) == "prelu"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - sigmoidLayer) == "sigmoid"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - logSoftMax) == "logsoftmax"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - unsupportedLayer) == "unsupported"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - lstmLayer) == "lstm"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - creluLayer) == "crelu"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - highwayLayer) == "highway"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - gruLayer) == "gru"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - glimpseLayer) == "glimpse"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - fastlstmLayer) == "fastlstm"); - BOOST_REQUIRE(boost::apply_visitor(LayerNameVisitor(), - weightnormLayer) == "weightnorm"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + atrousConvolution) == "atrousconvolution"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + alphaDropout) == "alphadropout"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + batchNorm) == "batchnorm"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + constant) == "constant"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + convolution) == "convolution"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + dropConnect) == "dropconnect"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + dropout) == "dropout"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + flexibleReLU) == "flexiblerelu"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + layerNorm) == "layernorm"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + linear) == "linear"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + linearNoBias) == "linearnobias"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + maxPooling) == "maxpooling"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + meanPooling) == "meanpooling"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + multiplyConstant) == "multiplyconstant"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + reLULayer) == "relu"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + transposedConvolution) == "transposedconvolution"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + identityLayer) == "identity"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + tanHLayer) == "tanh"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + eLU) == "elu"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + hardTanH) == "hardtanh"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + leakyReLU) == "leakyrelu"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + pReLU) == "prelu"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + sigmoidLayer) == "sigmoid"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + logSoftMax) == "logsoftmax"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + unsupportedLayer) == "unsupported"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + lstmLayer) == "lstm"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + creluLayer) == "crelu"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + highwayLayer) == "highway"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + gruLayer) == "gru"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + glimpseLayer) == "glimpse"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + fastlstmLayer) == "fastlstm"); + REQUIRE(boost::apply_visitor(LayerNameVisitor(), + weightnormLayer) == "weightnorm"); // Delete all instances. boost::apply_visitor(DeleteVisitor(), atrousConvolution); boost::apply_visitor(DeleteVisitor(), alphaDropout); @@ -161,5 +158,3 @@ BOOST_AUTO_TEST_CASE(LayerNameVisitorTest) boost::apply_visitor(DeleteVisitor(), fastlstmLayer); boost::apply_visitor(DeleteVisitor(), weightnormLayer); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/lin_alg_test.cpp b/src/mlpack/tests/lin_alg_test.cpp index 47a4448804..7454564c20 100644 --- a/src/mlpack/tests/lin_alg_test.cpp +++ b/src/mlpack/tests/lin_alg_test.cpp @@ -14,20 +14,18 @@ #include #include -#include -#include "test_tools.hpp" +#include "catch.hpp" +#include "test_catch_tools.hpp" using namespace arma; using namespace mlpack; using namespace mlpack::math; -BOOST_AUTO_TEST_SUITE(LinAlgTest); - /** * Test for linalg__private::Center(). There are no edge cases here, so we'll * just try it once for now. */ -BOOST_AUTO_TEST_CASE(TestCenterA) +TEST_CASE("TestCenterA", "[LinAlgTest]") { mat tmp(5, 5); // [[0 0 0 0 0] @@ -51,11 +49,16 @@ BOOST_AUTO_TEST_CASE(TestCenterA) // [-6 -3 0 3 6 ] // [-8 -4 0 4 8]] for (int row = 0; row < 5; row++) + { for (int col = 0; col < 5; col++) - BOOST_REQUIRE_CLOSE(tmp_out(row, col), (double) (col - 2) * row, 1e-5); + { + REQUIRE(tmp_out(row, col) == + Approx((double) (col - 2) * row).epsilon(1e-7)); + } + } } -BOOST_AUTO_TEST_CASE(TestCenterB) +TEST_CASE("TestCenterB", "[LinAlgTest]") { mat tmp(5, 6); for (int row = 0; row < 5; row++) @@ -74,11 +77,16 @@ BOOST_AUTO_TEST_CASE(TestCenterB) // [-7.5 -4.5 -1.5 1.5 1.5 4.5] // [-10 -6 -2 2 6 10 ]] for (int row = 0; row < 5; row++) + { for (int col = 0; col < 6; col++) - BOOST_REQUIRE_CLOSE(tmp_out(row, col), (double) (col - 2.5) * row, 1e-5); + { + REQUIRE(tmp_out(row, col) == + Approx((double) (col - 2.5) * row).epsilon(1e-7)); + } + } } -BOOST_AUTO_TEST_CASE(TestOrthogonalize) +TEST_CASE("TestOrthogonalize", "[LinAlgTest]") { // Generate a random matrix; then, orthogonalize it and test if it's // orthogonal. @@ -96,18 +104,18 @@ BOOST_AUTO_TEST_CASE(TestOrthogonalize) if (row == col) { if (std::abs(test(row, col)) > 1e-10) - BOOST_REQUIRE_CLOSE(test(row, col), ival, 1e-10); + REQUIRE(test(row, col) == Approx(ival).epsilon(1e-11)); } else { - BOOST_REQUIRE_SMALL(test(row, col), 1e-10); + REQUIRE(test(row, col) == Approx(0.0).margin(1e-10)); } } } } // Test RemoveRows(). -BOOST_AUTO_TEST_CASE(TestRemoveRows) +TEST_CASE("TestRemoveRows", "[LinAlgTest]") { // Run this test several times. for (size_t run = 0; run < 10; ++run) @@ -150,7 +158,7 @@ BOOST_AUTO_TEST_CASE(TestRemoveRows) else { // Compare. - BOOST_REQUIRE_EQUAL(accu(input.row(row) == output.row(outputRow)), 200); + REQUIRE(accu(input.row(row) == output.row(outputRow)) == 200); // Increment output row counter. ++outputRow; @@ -159,7 +167,7 @@ BOOST_AUTO_TEST_CASE(TestRemoveRows) } } -BOOST_AUTO_TEST_CASE(TestSvecSmat) +TEST_CASE("TestSvecSmat", "[LinAlgTest]") { arma::mat X(3, 3); X(0, 0) = 0; X(0, 1) = 1, X(0, 2) = 2; @@ -168,23 +176,24 @@ BOOST_AUTO_TEST_CASE(TestSvecSmat) arma::vec sx; Svec(X, sx); - BOOST_REQUIRE_CLOSE(sx(0), 0, 1e-7); - BOOST_REQUIRE_CLOSE(sx(1), M_SQRT2 * 1., 1e-7); - BOOST_REQUIRE_CLOSE(sx(2), M_SQRT2 * 2., 1e-7); - BOOST_REQUIRE_CLOSE(sx(3), 3., 1e-7); - BOOST_REQUIRE_CLOSE(sx(4), M_SQRT2 * 4., 1e-7); - BOOST_REQUIRE_CLOSE(sx(5), 5., 1e-7); + REQUIRE(sx(0) == Approx(0).epsilon(1e-9)); + REQUIRE(sx(1) == Approx(M_SQRT2 * 1.).epsilon(1e-9)); + REQUIRE(sx(2) == Approx(M_SQRT2 * 2.).epsilon(1e-9)); + REQUIRE(sx(3) == Approx(3.).epsilon(1e-9)); + REQUIRE(sx(4) == Approx(M_SQRT2 * 4.).epsilon(1e-9)); + REQUIRE(sx(5) == Approx(5.).epsilon(1e-9)); arma::mat Xtest; Smat(sx, Xtest); - BOOST_REQUIRE_EQUAL(Xtest.n_rows, 3); - BOOST_REQUIRE_EQUAL(Xtest.n_cols, 3); + REQUIRE(Xtest.n_rows == 3); + REQUIRE(Xtest.n_cols == 3); for (size_t i = 0; i < 3; ++i) for (size_t j = 0; j < 3; ++j) - BOOST_REQUIRE_CLOSE(X(i, j), Xtest(i, j), 1e-7); + REQUIRE(X(i, j) == Approx(Xtest(i, j)).epsilon(1e-9)); + } -BOOST_AUTO_TEST_CASE(TestSparseSvec) +TEST_CASE("TestSparseSvec", "[LinAlgTest]") { arma::sp_mat X; X.zeros(3, 3); @@ -200,15 +209,15 @@ BOOST_AUTO_TEST_CASE(TestSparseSvec) const double v4 = sx(4); const double v5 = sx(5); - BOOST_REQUIRE_CLOSE(v0, 0, 1e-7); - BOOST_REQUIRE_CLOSE(v1, M_SQRT2 * 1., 1e-7); - BOOST_REQUIRE_CLOSE(v2, 0, 1e-7); - BOOST_REQUIRE_CLOSE(v3, 0, 1e-7); - BOOST_REQUIRE_CLOSE(v4, 0, 1e-7); - BOOST_REQUIRE_CLOSE(v5, 0, 1e-7); + REQUIRE(v0 == Approx(0).epsilon(1e-9)); + REQUIRE(v1 == Approx(M_SQRT2 * 1.).epsilon(1e-9)); + REQUIRE(v2 == Approx(0).epsilon(1e-9)); + REQUIRE(v3 == Approx(0).epsilon(1e-9)); + REQUIRE(v4 == Approx(0).epsilon(1e-9)); + REQUIRE(v5 == Approx(0).epsilon(1e-9)); } -BOOST_AUTO_TEST_CASE(TestSymKronIdSimple) +TEST_CASE("TestSymKronIdSimple", "[LinAlgTest]") { arma::mat A(3, 3); A(0, 0) = 1; A(0, 1) = 2, A(0, 2) = 3; @@ -226,12 +235,12 @@ BOOST_AUTO_TEST_CASE(TestSymKronIdSimple) arma::vec rhs; Svec(Rhs, rhs); - BOOST_REQUIRE_EQUAL(lhs.n_elem, rhs.n_elem); + REQUIRE(lhs.n_elem == rhs.n_elem); for (size_t j = 0; j < lhs.n_elem; ++j) - BOOST_REQUIRE_CLOSE(lhs(j), rhs(j), 1e-5); + REQUIRE(lhs(j) == Approx(rhs(j)).epsilon(1e-7)); } -BOOST_AUTO_TEST_CASE(TestSymKronId) +TEST_CASE("TestSymKronId", "[LinAlgTest]") { const size_t n = 10; arma::mat A = arma::randu(n, n); @@ -252,10 +261,8 @@ BOOST_AUTO_TEST_CASE(TestSymKronId) arma::vec rhs; Svec(Rhs, rhs); - BOOST_REQUIRE_EQUAL(lhs.n_elem, rhs.n_elem); + REQUIRE(lhs.n_elem == rhs.n_elem); for (size_t j = 0; j < lhs.n_elem; ++j) - BOOST_REQUIRE_CLOSE(lhs(j), rhs(j), 1e-5); + REQUIRE(lhs(j) == Approx(rhs(j)).epsilon(1e-7)); } } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/main_tests/hoeffding_tree_test.cpp b/src/mlpack/tests/main_tests/hoeffding_tree_test.cpp index f3f45cbd40..af4373fb66 100644 --- a/src/mlpack/tests/main_tests/hoeffding_tree_test.cpp +++ b/src/mlpack/tests/main_tests/hoeffding_tree_test.cpp @@ -18,8 +18,8 @@ static const std::string testName = "HoeffdingTree"; #include #include "test_helper.hpp" -#include -#include "../test_tools.hpp" +#include "../catch.hpp" +#include "../test_catch_tools.hpp" using namespace mlpack; using namespace data; @@ -41,27 +41,25 @@ struct HoeffdingTreeTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(HoeffdingTreeMainTest, - HoeffdingTreeTestFixture); - /** * Check that number of output points and * number of input points are equal. */ -BOOST_AUTO_TEST_CASE(HoeffdingTreeOutputDimensionTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, "HoeffdingTreeOutputDimensionTest", + "[HoeffdingTreeMainTest][BindingTest]") { arma::mat inputData; DatasetInfo info; if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); arma::Row labels; if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); arma::mat testData; if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); size_t testSize = testData.n_cols; @@ -75,36 +73,34 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeOutputDimensionTest) mlpackMain(); // Check that number of output points are equal to number of input points. - BOOST_REQUIRE_EQUAL( - IO::GetParam>("predictions").n_cols, testSize); - BOOST_REQUIRE_EQUAL(IO::GetParam("probabilities").n_cols, - testSize); + REQUIRE(IO::GetParam>("predictions").n_cols == testSize); + REQUIRE(IO::GetParam("probabilities").n_cols == testSize); // Check number of output rows equals 1 for probabilities and predictions. - BOOST_REQUIRE_EQUAL( - IO::GetParam>("predictions").n_rows, 1); - BOOST_REQUIRE_EQUAL( - IO::GetParam("probabilities").n_rows, 1); + REQUIRE(IO::GetParam>("predictions").n_rows == 1); + REQUIRE(IO::GetParam("probabilities").n_rows == 1); } /** * Check that number of output points and number * of input points are equal for categorical dataset. */ -BOOST_AUTO_TEST_CASE(HoeffdingTreeCategoricalOutputDimensionTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, + "HoeffdingTreeCategoricalOutputDimensionTest", + "[HoeffdingTreeMainTest][BindingTest]") { arma::mat inputData; DatasetInfo info; if (!data::Load("braziltourism.arff", inputData, info)) - BOOST_FAIL("Cannot load train dataset braziltourism.arff!"); + FAIL("Cannot load train dataset braziltourism.arff!"); arma::Row labels; if (!data::Load("braziltourism_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for braziltourism_labels.txt"); + FAIL("Cannot load labels for braziltourism_labels.txt"); arma::mat testData; if (!data::Load("braziltourism_test.arff", testData, info)) - BOOST_FAIL("Cannot load test dataset braziltourism_test.arff!"); + FAIL("Cannot load test dataset braziltourism_test.arff!"); size_t testSize = testData.n_cols; @@ -118,36 +114,33 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeCategoricalOutputDimensionTest) mlpackMain(); // Check that number of output points are equal to number of input points. - BOOST_REQUIRE_EQUAL(IO::GetParam> - ("predictions").n_cols, testSize); - BOOST_REQUIRE_EQUAL(IO::GetParam("probabilities").n_cols, - testSize); + REQUIRE(IO::GetParam>("predictions").n_cols == testSize); + REQUIRE(IO::GetParam("probabilities").n_cols == testSize); // Check number of output rows equals 1 for probabilities and predictions. - BOOST_REQUIRE_EQUAL( - IO::GetParam>("predictions").n_rows, 1); - BOOST_REQUIRE_EQUAL( - IO::GetParam("probabilities").n_rows, 1); + REQUIRE(IO::GetParam>("predictions").n_rows == 1); + REQUIRE(IO::GetParam("probabilities").n_rows == 1); } /** * Check whether providing labels explicitly and extracting from last * dimension give the same output. */ -BOOST_AUTO_TEST_CASE(HoeffdingTreeLabelLessTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, "HoeffdingTreeLabelLessTest", + "[HoeffdingTreeMainTest][BindingTest]") { arma::mat inputData; DatasetInfo info; if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); arma::Row labels; if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); arma::mat testData; if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Append labels to the training set. inputData.resize(inputData.n_rows+1, inputData.n_cols); @@ -165,17 +158,13 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeLabelLessTest) mlpackMain(); // Check that number of output points are equal to number of input points. - BOOST_REQUIRE_EQUAL( - IO::GetParam>("predictions").n_cols, testSize); - BOOST_REQUIRE_EQUAL(IO::GetParam("probabilities").n_cols, - testSize); + REQUIRE(IO::GetParam>("predictions").n_cols == testSize); + REQUIRE(IO::GetParam("probabilities").n_cols == testSize); // Check number of output rows equals number of classes in case of // probabilities and 1 for predictions. - BOOST_REQUIRE_EQUAL( - IO::GetParam>("predictions").n_rows, 1); - BOOST_REQUIRE_EQUAL( - IO::GetParam("probabilities").n_rows, 1); + REQUIRE(IO::GetParam>("predictions").n_rows == 1); + REQUIRE(IO::GetParam("probabilities").n_rows == 1); // Reset passed parameters. IO::GetSingleton().Parameters()["training"].wasPassed = false; @@ -199,16 +188,12 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeLabelLessTest) mlpackMain(); // Check that number of output points are equal to number of input points. - BOOST_REQUIRE_EQUAL( - IO::GetParam>("predictions").n_cols, testSize); - BOOST_REQUIRE_EQUAL( - IO::GetParam("probabilities").n_cols, testSize); + REQUIRE(IO::GetParam>("predictions").n_cols == testSize); + REQUIRE(IO::GetParam("probabilities").n_cols == testSize); // Check number of output rows equals 1 for probabilities and predictions. - BOOST_REQUIRE_EQUAL( - IO::GetParam>("predictions").n_rows, 1); - BOOST_REQUIRE_EQUAL( - IO::GetParam("probabilities").n_rows, 1); + REQUIRE(IO::GetParam>("predictions").n_rows == 1); + REQUIRE(IO::GetParam("probabilities").n_rows == 1); // Check that initial and current predictions are same. CheckMatrices( @@ -220,20 +205,21 @@ BOOST_AUTO_TEST_CASE(HoeffdingTreeLabelLessTest) /** * Ensure that saved model can be used again. */ -BOOST_AUTO_TEST_CASE(HoeffdingModelReuseTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, "HoeffdingModelReuseTest", + "[HoeffdingTreeMainTest][BindingTest]") { arma::mat inputData; DatasetInfo info; if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); arma::Row labels; if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); arma::mat testData; if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); size_t testSize = testData.n_cols; @@ -257,7 +243,7 @@ BOOST_AUTO_TEST_CASE(HoeffdingModelReuseTest) IO::GetSingleton().Parameters()["test"].wasPassed = false; if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input trained model. SetInputParam("test", std::make_tuple(info, testData)); @@ -267,15 +253,12 @@ BOOST_AUTO_TEST_CASE(HoeffdingModelReuseTest) mlpackMain(); // Check that number of output points are equal to number of input points. - BOOST_REQUIRE_EQUAL( - IO::GetParam>("predictions").n_cols, testSize); - BOOST_REQUIRE_EQUAL( - IO::GetParam("probabilities").n_cols, testSize); + REQUIRE(IO::GetParam>("predictions").n_cols == testSize); + REQUIRE(IO::GetParam("probabilities").n_cols == testSize); // Check number of output rows equals 1 for probabilities and predictions. - BOOST_REQUIRE_EQUAL( - IO::GetParam>("predictions").n_rows, 1); - BOOST_REQUIRE_EQUAL(IO::GetParam("probabilities").n_rows, 1); + REQUIRE(IO::GetParam>("predictions").n_rows == 1); + REQUIRE(IO::GetParam("probabilities").n_rows == 1); // Check that initial predictions and predictions using saved model are same. CheckMatrices( @@ -287,20 +270,21 @@ BOOST_AUTO_TEST_CASE(HoeffdingModelReuseTest) /** * Ensure that saved model trained on categorical dataset can be used again. */ -BOOST_AUTO_TEST_CASE(HoeffdingModelCategoricalReuseTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, "HoeffdingModelCategoricalReuseTest", + "[HoeffdingTreeMainTest][BindingTest]") { arma::mat inputData; DatasetInfo info; if (!data::Load("braziltourism.arff", inputData, info)) - BOOST_FAIL("Cannot load train dataset braziltourism.arff!"); + FAIL("Cannot load train dataset braziltourism.arff!"); arma::Row labels; if (!data::Load("braziltourism_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for braziltourism_labels.txt"); + FAIL("Cannot load labels for braziltourism_labels.txt"); arma::mat testData; if (!data::Load("braziltourism_test.arff", testData, info)) - BOOST_FAIL("Cannot load test dataset braziltourism_test.arff!"); + FAIL("Cannot load test dataset braziltourism_test.arff!"); size_t testSize = testData.n_cols; @@ -324,7 +308,7 @@ BOOST_AUTO_TEST_CASE(HoeffdingModelCategoricalReuseTest) probabilities = std::move(IO::GetParam("probabilities")); if (!data::Load("braziltourism_test.arff", testData, info)) - BOOST_FAIL("Cannot load test dataset braziltourism_test.arff!"); + FAIL("Cannot load test dataset braziltourism_test.arff!"); // Input trained model. SetInputParam("test", std::make_tuple(info, testData)); @@ -334,16 +318,12 @@ BOOST_AUTO_TEST_CASE(HoeffdingModelCategoricalReuseTest) mlpackMain(); // Check that number of output points are equal to number of input points. - BOOST_REQUIRE_EQUAL( - IO::GetParam>("predictions").n_cols, testSize); - BOOST_REQUIRE_EQUAL( - IO::GetParam("probabilities").n_cols, testSize); + REQUIRE(IO::GetParam>("predictions").n_cols == testSize); + REQUIRE(IO::GetParam("probabilities").n_cols == testSize); // Check number of output rows equals 1 for probabilities and predictions. - BOOST_REQUIRE_EQUAL( - IO::GetParam>("predictions").n_rows, 1); - BOOST_REQUIRE_EQUAL( - IO::GetParam("probabilities").n_rows, 1); + REQUIRE(IO::GetParam>("predictions").n_rows == 1); + REQUIRE(IO::GetParam("probabilities").n_rows == 1); // Check that initial predictions and predictions using saved model are same. CheckMatrices( @@ -355,21 +335,22 @@ BOOST_AUTO_TEST_CASE(HoeffdingModelCategoricalReuseTest) /** * Ensure that small min_samples creates larger model. */ -BOOST_AUTO_TEST_CASE(HoeffdingMinSamplesTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, "HoeffdingMinSamplesTest", + "[HoeffdingTreeMainTest][BindingTest]") { arma::mat inputData; DatasetInfo info; int nodes; if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); arma::Row labels; if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); arma::mat testData; if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input training data. SetInputParam("training", std::make_tuple(info, inputData)); @@ -395,13 +376,13 @@ BOOST_AUTO_TEST_CASE(HoeffdingMinSamplesTest) bindings::tests::CleanMemory(); if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input training data. SetInputParam("training", std::make_tuple(info, inputData)); @@ -416,29 +397,29 @@ BOOST_AUTO_TEST_CASE(HoeffdingMinSamplesTest) mlpackMain(); // Check that small min_samples creates larger model. - BOOST_REQUIRE_LT( - (IO::GetParam("output_model"))->NumNodes(), + REQUIRE((IO::GetParam("output_model"))->NumNodes() < nodes); } /** * Ensure that large max_samples creates smaller model. */ -BOOST_AUTO_TEST_CASE(HoeffdingMaxSamplesTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, "HoeffdingMaxSamplesTest", + "[HoeffdingTreeMainTest][BindingTest]") { arma::mat inputData; DatasetInfo info; int nodes; if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); arma::Row labels; if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); arma::mat testData; if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input training data. SetInputParam("training", std::make_tuple(info, inputData)); @@ -464,13 +445,13 @@ BOOST_AUTO_TEST_CASE(HoeffdingMaxSamplesTest) bindings::tests::CleanMemory(); if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input training data. SetInputParam("training", std::make_tuple(info, inputData)); @@ -485,28 +466,29 @@ BOOST_AUTO_TEST_CASE(HoeffdingMaxSamplesTest) mlpackMain(); // Check that large max_samples creates smaller model. - BOOST_REQUIRE_LT(nodes, + REQUIRE(nodes < (IO::GetParam("output_model"))->NumNodes()); } /** * Ensure that small confidence value creates larger model. */ -BOOST_AUTO_TEST_CASE(HoeffdingConfidenceTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, "HoeffdingConfidenceTest", + "[HoeffdingTreeMainTest][BindingTest]") { arma::mat inputData; DatasetInfo info; int nodes; if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); arma::Row labels; if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); arma::mat testData; if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input training data. SetInputParam("training", std::make_tuple(info, inputData)); @@ -531,13 +513,13 @@ BOOST_AUTO_TEST_CASE(HoeffdingConfidenceTest) bindings::tests::CleanMemory(); if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input training data. SetInputParam("training", std::make_tuple(info, inputData)); @@ -551,28 +533,29 @@ BOOST_AUTO_TEST_CASE(HoeffdingConfidenceTest) mlpackMain(); // Check that higher confidence creates smaller tree. - BOOST_REQUIRE_LT(nodes, + REQUIRE(nodes < (IO::GetParam("output_model"))->NumNodes()); } /** * Ensure that large number of passes creates larger model. */ -BOOST_AUTO_TEST_CASE(HoeffdingPassesTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, "HoeffdingPassesTest", + "[HoeffdingTreeMainTest][BindingTest]") { arma::mat inputData; DatasetInfo info; int nodes; if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); arma::Row labels; if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); arma::mat testData; if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input training data. SetInputParam("training", std::make_tuple(info, inputData)); @@ -597,13 +580,13 @@ BOOST_AUTO_TEST_CASE(HoeffdingPassesTest) bindings::tests::CleanMemory(); if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input training data. SetInputParam("training", std::make_tuple(info, inputData)); @@ -618,27 +601,29 @@ BOOST_AUTO_TEST_CASE(HoeffdingPassesTest) mlpackMain(); // Check that model with larger number of passes has greater number of nodes. - BOOST_REQUIRE_LT(nodes, + REQUIRE(nodes < (IO::GetParam("output_model"))->NumNodes()); } /** * Ensure that the root node has 2 children when splitting strategy is binary. */ -BOOST_AUTO_TEST_CASE(HoeffdingBinarySplittingStrategyTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, + "HoeffdingBinarySplittingStrategyTest", + "[HoeffdingTreeMainTest][BindingTest]") { arma::mat inputData; DatasetInfo info; if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); arma::Row labels; if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); arma::mat testData; if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input training data. SetInputParam("training", std::make_tuple(info, inputData)); @@ -655,28 +640,30 @@ BOOST_AUTO_TEST_CASE(HoeffdingBinarySplittingStrategyTest) mlpackMain(); // Check that number of children is 2. - BOOST_REQUIRE_EQUAL( - (IO::GetParam("output_model"))->NumNodes()-1, 2); + REQUIRE( + (IO::GetParam("output_model"))->NumNodes() - 1 == 2); } /** * Ensure that the number of children varies with varying 'bins' in domingos. */ -BOOST_AUTO_TEST_CASE(HoeffdingDomingosSplittingStrategyTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, + "HoeffdingDomingosSplittingStrategyTest", + "[HoeffdingTreeMainTest][BindingTest]") { arma::mat inputData; DatasetInfo info; int nodes; if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); arma::Row labels; if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); arma::mat testData; if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input training data. SetInputParam("training", std::make_tuple(info, inputData)); @@ -705,13 +692,13 @@ BOOST_AUTO_TEST_CASE(HoeffdingDomingosSplittingStrategyTest) bindings::tests::CleanMemory(); if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); // Input training data. SetInputParam("training", std::make_tuple(info, inputData)); @@ -727,30 +714,31 @@ BOOST_AUTO_TEST_CASE(HoeffdingDomingosSplittingStrategyTest) mlpackMain(); // Check that both models have different number of nodes. - BOOST_CHECK_NE( - (IO::GetParam("output_model"))->NumNodes(), nodes); + CHECK((IO::GetParam("output_model"))->NumNodes() != + nodes); } /** * Ensure that the model doesn't split if observations before binning * is greater than total number of samples passed. */ -BOOST_AUTO_TEST_CASE(HoeffdingBinningTest) +TEST_CASE_METHOD(HoeffdingTreeTestFixture, "HoeffdingBinningTest", + "[HoeffdingTreeMainTest][BindingTests]") { arma::mat inputData; arma::mat modData; arma::Row modLabels; DatasetInfo info; if (!data::Load("vc2.csv", inputData, info)) - BOOST_FAIL("Cannot load train dataset vc2.csv!"); + FAIL("Cannot load train dataset vc2.csv!"); arma::Row labels; if (!data::Load("vc2_labels.txt", labels)) - BOOST_FAIL("Cannot load labels for vc2_labels.txt"); + FAIL("Cannot load labels for vc2_labels.txt"); arma::mat testData; if (!data::Load("vc2_test.csv", testData, info)) - BOOST_FAIL("Cannot load test dataset vc2.csv!"); + FAIL("Cannot load test dataset vc2.csv!"); modData = inputData.cols(0, 49); modLabels = labels.cols(0, 49); @@ -772,8 +760,6 @@ BOOST_AUTO_TEST_CASE(HoeffdingBinningTest) mlpackMain(); // Check that no splitting has happened. - BOOST_REQUIRE_EQUAL( - (IO::GetParam("output_model"))->NumNodes(), 1); + REQUIRE((IO::GetParam("output_model"))->NumNodes() + == 1); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/main_tests/range_search_test.cpp b/src/mlpack/tests/main_tests/range_search_test.cpp index 8102aae4e9..3d9fd08bb5 100644 --- a/src/mlpack/tests/main_tests/range_search_test.cpp +++ b/src/mlpack/tests/main_tests/range_search_test.cpp @@ -17,7 +17,7 @@ static const std::string testName = "RangeSearchMain"; #include "test_helper.hpp" #include #include "range_search_utils.hpp" -#include +#include "../catch.hpp" using namespace mlpack; @@ -37,34 +37,35 @@ struct RangeSearchTestFixture } }; -BOOST_FIXTURE_TEST_SUITE(RangeSearchMainTest, RangeSearchTestFixture); - /** * Check that we have to specify a reference set or input model. */ -BOOST_AUTO_TEST_CASE(RangeSearchNoReference) +TEST_CASE_METHOD(RangeSearchTestFixture, "RangeSearchNoReference", + "[RangeSearchMainTest][BindingTests]") { Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error); + REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error); Log::Fatal.ignoreInput = false; } /** * Check that we cannot pass an incorrect parameter. */ -BOOST_AUTO_TEST_CASE(RangeSearchWrongParameter) +TEST_CASE_METHOD(RangeSearchTestFixture, "RangeSearchWrongParameter", + "[RangeSearchMainTest][BindingTests]") { string wrongString = "abc"; Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(SetInputParam("RST", wrongString), std::runtime_error); + REQUIRE_THROWS_AS(SetInputParam("RST", wrongString), std::runtime_error); Log::Fatal.ignoreInput = false; } /** * Check that we have to specify a query if an input model is specified. */ -BOOST_AUTO_TEST_CASE(RangeSearchInputModelNoQuery) +TEST_CASE_METHOD(RangeSearchTestFixture, "RangeSearchInputModelNoQuery", + "[RangeSearchMainTest][BindingTests]") { arma::mat inputData; double minVal = 0, maxVal = 3; @@ -72,7 +73,7 @@ BOOST_AUTO_TEST_CASE(RangeSearchInputModelNoQuery) string neighborsFile = "neighbors.csv"; if (!data::Load("iris.csv", inputData)) - BOOST_FAIL("Unable to load dataset iris.csv!"); + FAIL("Unable to load dataset iris.csv!"); SetInputParam("reference", move(inputData)); SetInputParam("min", minVal); @@ -86,7 +87,7 @@ BOOST_AUTO_TEST_CASE(RangeSearchInputModelNoQuery) SetInputParam("input_model", move(IO::GetParam("output_model"))); Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error); + REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error); Log::Fatal.ignoreInput = false; remove(neighborsFile.c_str()); @@ -96,7 +97,8 @@ BOOST_AUTO_TEST_CASE(RangeSearchInputModelNoQuery) /** * Check that we cannot specify a tree type which is not available or wrong. */ -BOOST_AUTO_TEST_CASE(RangeSearchDifferentTree) +TEST_CASE_METHOD(RangeSearchTestFixture, "RangeSearchDifferentTree", + "[RangeSearchMainTest][BindingTests]") { arma::mat inputData; double minVal = 0, maxVal = 3; @@ -104,7 +106,7 @@ BOOST_AUTO_TEST_CASE(RangeSearchDifferentTree) string neighborsFile = "neighbors.csv"; string wrongTreeType = "RST"; if (!data::Load("iris.csv", inputData)) - BOOST_FAIL("Unable to load dataset iris.csv!"); + FAIL("Unable to load dataset iris.csv!"); SetInputParam("reference", move(inputData)); SetInputParam("min", minVal); @@ -114,7 +116,7 @@ BOOST_AUTO_TEST_CASE(RangeSearchDifferentTree) SetInputParam("tree_type", wrongTreeType); Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error); + REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error); Log::Fatal.ignoreInput = false; remove(neighborsFile.c_str()); @@ -124,7 +126,8 @@ BOOST_AUTO_TEST_CASE(RangeSearchDifferentTree) /** * Check that we cannot specify both a reference set and input model. */ -BOOST_AUTO_TEST_CASE(RangeSearchBothReferenceAndModel) +TEST_CASE_METHOD(RangeSearchTestFixture, "RangeSearchBothReferenceAndModel", + "[RangeSearchMainTest][BindingTests]") { arma::mat inputData, queryData; double minVal = 0, maxVal = 3; @@ -132,9 +135,9 @@ BOOST_AUTO_TEST_CASE(RangeSearchBothReferenceAndModel) string neighborsFile = "neighbors.csv"; if (!data::Load("iris.csv", inputData)) - BOOST_FAIL("Unable to load dataset iris.csv!"); + FAIL("Unable to load dataset iris.csv!"); if (!data::Load("iris_test.csv", queryData)) - BOOST_FAIL("Unable to load dataset iris_test.csv!"); + FAIL("Unable to load dataset iris_test.csv!"); SetInputParam("reference", move(inputData)); SetInputParam("min", minVal); @@ -149,7 +152,7 @@ BOOST_AUTO_TEST_CASE(RangeSearchBothReferenceAndModel) SetInputParam("query", move(queryData)); Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error); + REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error); Log::Fatal.ignoreInput = false; remove(neighborsFile.c_str()); @@ -161,7 +164,8 @@ BOOST_AUTO_TEST_CASE(RangeSearchBothReferenceAndModel) * by comparing with pre-calculated neighbor and distance values, when no query * set is specified. */ -BOOST_AUTO_TEST_CASE(RangeSearchTest) +TEST_CASE_METHOD(RangeSearchTestFixture, "RangeSearchTest", + "[RangeSearchMainTest][BindingTests]") { arma::mat x = {{0, 3, 3, 4, 3, 1}, {4, 4, 4, 5, 5, 2}, @@ -208,7 +212,8 @@ BOOST_AUTO_TEST_CASE(RangeSearchTest) * Check that the correct output is returned for a small synthetic input case, * when a query set is provided. */ -BOOST_AUTO_TEST_CASE(RangeSeachTestwithQuery) +TEST_CASE_METHOD(RangeSearchTestFixture, "RangeSeachTestwithQuery", + "[RangeSearchMainTest][BindingTests]") { arma::mat queryData = {{5, 3, 1}, {4, 2, 4}, {3, 1, 7}}; arma::mat x = {{0, 3, 3, 4, 3, 1}, @@ -252,7 +257,8 @@ BOOST_AUTO_TEST_CASE(RangeSeachTestwithQuery) * Train a model using a synthetic dataset and then output the model, and ensure * it can be used again. */ -BOOST_AUTO_TEST_CASE(ModelCheck) +TEST_CASE_METHOD(RangeSearchTestFixture, "ModelCheck", + "[RangeSearchMainTest][BindingTests]") { arma::mat inputData, queryData; double minVal = 0, maxVal = 3; @@ -262,9 +268,9 @@ BOOST_AUTO_TEST_CASE(ModelCheck) vector> distances, distancetemp; if (!data::Load("iris.csv", inputData)) - BOOST_FAIL("Unable to load dataset iris.csv!"); + FAIL("Unable to load dataset iris.csv!"); if (!data::Load("iris_test.csv", queryData)) - BOOST_FAIL("Unable to load dataset iris_test.csv!"); + FAIL("Unable to load dataset iris_test.csv!"); SetInputParam("reference", move(inputData)); SetInputParam("min", minVal); @@ -292,8 +298,8 @@ BOOST_AUTO_TEST_CASE(ModelCheck) CheckMatrices(neighbors, neighborsTemp); CheckMatrices(distances, distancetemp); - BOOST_REQUIRE_EQUAL(ModelToString(outputModel), - ModelToString(IO::GetParam("output_model"))); + REQUIRE(ModelToString(outputModel) == + ModelToString(IO::GetParam("output_model"))); remove(neighborsFile.c_str()); remove(distanceFile.c_str()); @@ -303,11 +309,12 @@ BOOST_AUTO_TEST_CASE(ModelCheck) * Check that the models are different but the results are the same for three * different leaf size parameters. */ -BOOST_AUTO_TEST_CASE(LeafValueTesting) +TEST_CASE_METHOD(RangeSearchTestFixture, "LeafValueTesting", + "[RangeSearchMainTest][BindingTests]") { arma::mat inputData; if (!data::Load("iris.csv", inputData)) - BOOST_FAIL("Unable to load dataset iris.csv!"); + FAIL("Unable to load dataset iris.csv!"); string distanceFile = "distances.csv"; string neighborsFile = "neighbors.csv"; @@ -349,8 +356,8 @@ BOOST_AUTO_TEST_CASE(LeafValueTesting) CheckMatrices(neighbors, neighborsTemp); CheckMatrices(distances, distancestemp); - BOOST_REQUIRE_NE(ModelToString(outputModel1), - ModelToString(IO::GetParam("output_model"))); + REQUIRE(ModelToString(outputModel1) != + ModelToString(IO::GetParam("output_model"))); if (i != leafSizes.size() - 1) delete IO::GetParam("output_model"); @@ -367,7 +374,8 @@ BOOST_AUTO_TEST_CASE(LeafValueTesting) * different tree types. We use the default kd-tree as the base model to * compare against. */ -BOOST_AUTO_TEST_CASE(TreeTypeTesting) +TEST_CASE_METHOD(RangeSearchTestFixture, "TreeTypeTesting", + "[RangeSearchMainTest][BindingTests]") { string distanceFile = "distances.csv"; string neighborsFile = "neighbors.csv"; @@ -381,9 +389,9 @@ BOOST_AUTO_TEST_CASE(TreeTypeTesting) "max-rp", "ub", "oct"}; if (!data::Load("iris.csv", inputData)) - BOOST_FAIL("Unable to load dataset iris.csv!"); + FAIL("Unable to load dataset iris.csv!"); if (!data::Load("iris_test.csv", queryData)) - BOOST_FAIL("Unable to load dataset iris_test.csv!"); + FAIL("Unable to load dataset iris_test.csv!"); // Define base parameters with the kd-tree. SetInputParam("tree_type", trees[0]); @@ -403,9 +411,9 @@ BOOST_AUTO_TEST_CASE(TreeTypeTesting) for (size_t i = 1; i < trees.size(); ++i) { if (!data::Load("iris.csv", inputData)) - BOOST_FAIL("Unable to load dataset iris.csv!"); + FAIL("Unable to load dataset iris.csv!"); if (!data::Load("iris_test.csv", queryData)) - BOOST_FAIL("Unable to load dataset iris_test.csv!"); + FAIL("Unable to load dataset iris_test.csv!"); SetInputParam("min", minVal); SetInputParam("max", maxVal); @@ -422,8 +430,8 @@ BOOST_AUTO_TEST_CASE(TreeTypeTesting) CheckMatrices(neighbors, neighborsTemp); CheckMatrices(distances, distancestemp); - BOOST_REQUIRE_NE(ModelToString(outputModel1), - ModelToString(IO::GetParam("output_model"))); + REQUIRE(ModelToString(outputModel1) != + ModelToString(IO::GetParam("output_model"))); if (i != trees.size() - 1) delete IO::GetParam("output_model"); @@ -439,7 +447,8 @@ BOOST_AUTO_TEST_CASE(TreeTypeTesting) * Project the data onto a random basis and ensure that this gives identical * results to non-projected data but different models. */ -BOOST_AUTO_TEST_CASE(RandomBasisTesting) +TEST_CASE_METHOD(RangeSearchTestFixture, "RandomBasisTesting", + "[RangeSearchMainTest][BindingTests]") { string distanceFile = "distances.csv"; string neighborsFile = "neighbors.csv"; @@ -447,9 +456,9 @@ BOOST_AUTO_TEST_CASE(RandomBasisTesting) arma::mat queryData, inputData; if (!data::Load("iris.csv", inputData)) - BOOST_FAIL("Unable to load dataset iris.csv!"); + FAIL("Unable to load dataset iris.csv!"); if (!data::Load("iris_test.csv", queryData)) - BOOST_FAIL("Unable to load dataset iris_test.csv!"); + FAIL("Unable to load dataset iris_test.csv!"); SetInputParam("min", minVal); SetInputParam("max", maxVal); @@ -470,8 +479,8 @@ BOOST_AUTO_TEST_CASE(RandomBasisTesting) mlpackMain(); - BOOST_REQUIRE_NE(ModelToString(outputModel), - ModelToString(IO::GetParam("output_model"))); + REQUIRE(ModelToString(outputModel) != + ModelToString(IO::GetParam("output_model"))); delete outputModel; @@ -482,7 +491,8 @@ BOOST_AUTO_TEST_CASE(RandomBasisTesting) /** * Ensure that naive mode gives the same result, but different models. */ -BOOST_AUTO_TEST_CASE(NaiveModeTest) +TEST_CASE_METHOD(RangeSearchTestFixture, "NaiveModeTest", + "[RangeSearchMainTest][BindingTests]") { string distanceFile = "distances.csv"; string neighborsFile = "neighbors.csv"; @@ -493,9 +503,9 @@ BOOST_AUTO_TEST_CASE(NaiveModeTest) vector> distances, distancestemp; if (!data::Load("iris.csv", inputData)) - BOOST_FAIL("Unable to load dataset iris.csv!"); + FAIL("Unable to load dataset iris.csv!"); if (!data::Load("iris_test.csv", queryData)) - BOOST_FAIL("Unable to load dataset iris_test.csv!"); + FAIL("Unable to load dataset iris_test.csv!"); SetInputParam("min", minVal); SetInputParam("max", maxVal); @@ -524,8 +534,8 @@ BOOST_AUTO_TEST_CASE(NaiveModeTest) CheckMatrices(neighbors, neighborsTemp); CheckMatrices(distances, distancestemp); - BOOST_REQUIRE_NE(ModelToString(outputModel), - ModelToString(IO::GetParam("output_model"))); + REQUIRE(ModelToString(outputModel) != + ModelToString(IO::GetParam("output_model"))); delete outputModel; @@ -536,7 +546,8 @@ BOOST_AUTO_TEST_CASE(NaiveModeTest) /** * Ensure that single-tree mode gives the same result but different models. */ -BOOST_AUTO_TEST_CASE(SingleModeTest) +TEST_CASE_METHOD(RangeSearchTestFixture, "SingleModeTest", + "[RangeSearchMainTest][BindingTests]") { string distanceFile = "distances.csv"; string neighborsFile = "neighbors.csv"; @@ -547,9 +558,9 @@ BOOST_AUTO_TEST_CASE(SingleModeTest) vector> distances, distancestemp; if (!data::Load("iris.csv", inputData)) - BOOST_FAIL("Unable to load dataset iris.csv!"); + FAIL("Unable to load dataset iris.csv!"); if (!data::Load("iris_test.csv", queryData)) - BOOST_FAIL("Unable to load dataset iris_test.csv!"); + FAIL("Unable to load dataset iris_test.csv!"); SetInputParam("min", minVal); SetInputParam("max", maxVal); @@ -577,13 +588,11 @@ BOOST_AUTO_TEST_CASE(SingleModeTest) CheckMatrices(neighbors, neighborsTemp); CheckMatrices(distances, distancestemp); - BOOST_REQUIRE_NE(ModelToString(outputModel), - ModelToString(IO::GetParam("output_model"))); + REQUIRE(ModelToString(outputModel) != + ModelToString(IO::GetParam("output_model"))); delete outputModel; remove(neighborsFile.c_str()); remove(distanceFile.c_str()); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/main_tests/range_search_utils.hpp b/src/mlpack/tests/main_tests/range_search_utils.hpp index 8f1385eafb..f628b741ff 100644 --- a/src/mlpack/tests/main_tests/range_search_utils.hpp +++ b/src/mlpack/tests/main_tests/range_search_utils.hpp @@ -12,10 +12,10 @@ #ifndef MLPACK_TESTS_MAIN_TESTS_RANGE_SEARCH_TEST_UTILS_HPP #define MLPACK_TESTS_MAIN_TESTS_RANGE_SEARCH_TEST_UTILS_HPP -#include #include #include #include +#include "../catch.hpp" /** * Convert a model to a string using the text_oarchive of boost::serialization. @@ -42,15 +42,15 @@ inline void CheckMatrices(std::vector>& vec1, std::vector>& vec2, const double tolerance = 1e-3) { - BOOST_REQUIRE_EQUAL(vec1.size() , vec2.size()); + REQUIRE(vec1.size() == vec2.size()); for (size_t i = 0; i < vec1.size(); ++i) { - BOOST_REQUIRE_EQUAL(vec1[i].size(), vec2[i].size()); + REQUIRE(vec1[i].size() == vec2[i].size()); std::sort(vec1[i].begin(), vec1[i].end()); std::sort(vec2[i].begin(), vec2[i].end()); for (size_t j = 0 ; j < vec1[i].size(); ++j) { - BOOST_REQUIRE_CLOSE(vec1[i][j], vec2[i][j], tolerance); + REQUIRE(vec1[i][j] == Approx(vec2[i][j]).epsilon(tolerance)); } } } @@ -64,15 +64,15 @@ inline void CheckMatrices(std::vector>& vec1, inline void CheckMatrices(std::vector>& vec1, std::vector>& vec2) { - BOOST_REQUIRE_EQUAL(vec1.size() , vec2.size()); + REQUIRE(vec1.size() == vec2.size()); for (size_t i = 0; i < vec1.size(); ++i) { - BOOST_REQUIRE_EQUAL(vec1[i].size(), vec2[i].size()); + REQUIRE(vec1[i].size() == vec2[i].size()); std::sort(vec1[i].begin(), vec1[i].end()); std::sort(vec2[i].begin(), vec2[i].end()); for (size_t j = 0; j < vec1[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(vec1[i][j], vec2[i][j]); + REQUIRE(vec1[i][j] == vec2[i][j]); } } } diff --git a/src/mlpack/tests/metric_test.cpp b/src/mlpack/tests/metric_test.cpp index dffe3211fc..db3f164650 100644 --- a/src/mlpack/tests/metric_test.cpp +++ b/src/mlpack/tests/metric_test.cpp @@ -10,21 +10,19 @@ */ #include #include -#include +#include "catch.hpp" #include #include #include -#include "test_tools.hpp" +#include "test_catch_tools.hpp" using namespace std; using namespace mlpack::metric; -BOOST_AUTO_TEST_SUITE(MetricTest); - /** * Simple test for L-1 metric. */ -BOOST_AUTO_TEST_CASE(L1MetricTest) +TEST_CASE("L1MetricTest", "[MetricTest]") { arma::vec a1(5); a1.randn(); @@ -40,17 +38,17 @@ BOOST_AUTO_TEST_CASE(L1MetricTest) ManhattanDistance lMetric; - BOOST_REQUIRE_CLOSE((double) arma::accu(arma::abs(a1 - b1)), - lMetric.Evaluate(a1, b1), 1e-5); + REQUIRE((double) arma::accu(arma::abs(a1 - b1)) == + Approx(lMetric.Evaluate(a1, b1)).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE((double) arma::accu(arma::abs(a2 - b2)), - lMetric.Evaluate(a2, b2), 1e-5); + REQUIRE((double) arma::accu(arma::abs(a2 - b2)) == + Approx(lMetric.Evaluate(a2, b2)).epsilon(1e-7)); } /** * Simple test for L-2 metric. */ -BOOST_AUTO_TEST_CASE(L2MetricTest) +TEST_CASE("L2MetricTest", "[MetricTest]") { arma::vec a1(5); a1.randn(); @@ -66,17 +64,17 @@ BOOST_AUTO_TEST_CASE(L2MetricTest) EuclideanDistance lMetric; - BOOST_REQUIRE_CLOSE((double) sqrt(arma::accu(arma::square(a1 - b1))), - lMetric.Evaluate(a1, b1), 1e-5); + REQUIRE((double) sqrt(arma::accu(arma::square(a1 - b1))) == + Approx(lMetric.Evaluate(a1, b1)).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE((double) sqrt(arma::accu(arma::square(a2 - b2))), - lMetric.Evaluate(a2, b2), 1e-5); + REQUIRE((double) sqrt(arma::accu(arma::square(a2 - b2))) == + Approx(lMetric.Evaluate(a2, b2)).epsilon(1e-7)); } /** * Simple test for L-Infinity metric. */ -BOOST_AUTO_TEST_CASE(LINFMetricTest) +TEST_CASE("LINFMetricTest", "[MetricTest]") { arma::vec a1(5); a1.randn(); @@ -92,50 +90,52 @@ BOOST_AUTO_TEST_CASE(LINFMetricTest) ChebyshevDistance lMetric; - BOOST_REQUIRE_CLOSE((double) arma::as_scalar(arma::max(arma::abs(a1 - b1))), - lMetric.Evaluate(a1, b1), 1e-5); + REQUIRE((double) arma::as_scalar(arma::max(arma::abs(a1 - b1))) == + Approx(lMetric.Evaluate(a1, b1)).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE((double) arma::as_scalar(arma::max(arma::abs(a2 - b2))), - lMetric.Evaluate(a2, b2), 1e-5); + REQUIRE((double) arma::as_scalar(arma::max(arma::abs(a2 - b2))) == + Approx(lMetric.Evaluate(a2, b2)).epsilon(1e-7)); } /** * Simple test for IoU metric. */ -BOOST_AUTO_TEST_CASE(IoUMetricTest) +TEST_CASE("IoUMetricTest", "[MetricTest]") { arma::vec bbox1(4), bbox2(4); bbox1 << 1 << 2 << 100 << 200; bbox2 << 1 << 2 << 100 << 200; // IoU of same bounding boxes equals 1.0. - BOOST_REQUIRE_CLOSE(1.0, IoU<>::Evaluate(bbox1, bbox2), 1e-4); + REQUIRE(1.0 == Approx(IoU<>::Evaluate(bbox1, bbox2)).epsilon(1e-6)); // Use coordinate system to represent bounding boxes. // Bounding boxes represent {x0, y0, x1, y1}. bbox1 << 39 << 63 << 203 << 112; bbox2 << 54 << 66 << 198 << 114; // Value calculated using Python interpreter. - BOOST_REQUIRE_CLOSE(IoU::Evaluate(bbox1, bbox2), 0.7980093, 1e-4); + REQUIRE(IoU::Evaluate(bbox1, bbox2) == + Approx(0.7980093).epsilon(1e-6)); bbox1 << 31 << 69 << 201 << 125; bbox2 << 18 << 63 << 235 << 135; // Value calculated using Python interpreter. - BOOST_REQUIRE_CLOSE(IoU::Evaluate(bbox1, bbox2), 0.612479577, 1e-4); + REQUIRE(IoU::Evaluate(bbox1, bbox2) == + Approx(0.612479577).epsilon(1e-6)); // Use hieght - width representation of bounding boxes. // Bounding boxes represent {x0, y0, h, w}. bbox1 << 49 << 75 << 154 << 50; bbox2 << 42 << 78 << 144 << 48; // Value calculated using Python interpreter. - BOOST_REQUIRE_CLOSE(IoU<>::Evaluate(bbox1, bbox2), 0.7898879, 1e-4); + REQUIRE(IoU<>::Evaluate(bbox1, bbox2) == Approx(0.7898879).epsilon(1e-6)); bbox1 << 35 << 51 << 161 << 59; bbox2 << 36 << 60 << 144 << 48; // Value calculated using Python interpreter. - BOOST_REQUIRE_CLOSE(IoU<>::Evaluate(bbox1, bbox2), 0.7309670, 1e-4); + REQUIRE(IoU<>::Evaluate(bbox1, bbox2) == Approx(0.7309670).epsilon(1e-6)); } -BOOST_AUTO_TEST_CASE(NMSMetricTest) +TEST_CASE("NMSMetricTest", "[MetricTest]") { arma::mat bbox, selectedBoundingBox, desiredBoundingBox; arma::vec bbox1(4), bbox2(4), bbox3(4); @@ -172,13 +172,13 @@ BOOST_AUTO_TEST_CASE(NMSMetricTest) selectedBoundingBox = bbox.cols(selectedIndices); - BOOST_REQUIRE_EQUAL(selectedBoundingBox.n_cols, 2); - BOOST_REQUIRE_EQUAL(selectedBoundingBox.n_rows, 4); + REQUIRE(selectedBoundingBox.n_cols == 2); + REQUIRE(selectedBoundingBox.n_rows == 4); CheckMatrices(desiredBoundingBox, selectedBoundingBox); for (size_t i = 0; i < desiredIndices.n_elem; i++) { - BOOST_REQUIRE_EQUAL(desiredIndices[i], selectedIndices[i]); + REQUIRE(desiredIndices[i] == selectedIndices[i]); } // Clean up. @@ -201,8 +201,8 @@ BOOST_AUTO_TEST_CASE(NMSMetricTest) selectedBoundingBox = bbox.cols(selectedIndices); - BOOST_REQUIRE_EQUAL(selectedBoundingBox.n_cols, 2); - BOOST_REQUIRE_EQUAL(selectedBoundingBox.n_rows, 4); + REQUIRE(selectedBoundingBox.n_cols == 2); + REQUIRE(selectedBoundingBox.n_rows == 4); CheckMatrices(desiredBoundingBox, selectedBoundingBox); // Clean up. @@ -233,8 +233,8 @@ BOOST_AUTO_TEST_CASE(NMSMetricTest) selectedBoundingBox = bbox.cols(selectedIndices); - BOOST_REQUIRE_EQUAL(selectedBoundingBox.n_cols, 2); - BOOST_REQUIRE_EQUAL(selectedBoundingBox.n_rows, 4); + REQUIRE(selectedBoundingBox.n_cols == 2); + REQUIRE(selectedBoundingBox.n_rows == 4); CheckMatrices(desiredBoundingBox, selectedBoundingBox); // Clean up. @@ -266,8 +266,8 @@ BOOST_AUTO_TEST_CASE(NMSMetricTest) selectedIndices); selectedBoundingBox = bbox.cols(selectedIndices); - BOOST_REQUIRE_EQUAL(selectedBoundingBox.n_cols, 2); - BOOST_REQUIRE_EQUAL(selectedBoundingBox.n_rows, 4); + REQUIRE(selectedBoundingBox.n_cols == 2); + REQUIRE(selectedBoundingBox.n_rows == 4); CheckMatrices(desiredBoundingBox, selectedBoundingBox); // Clean up. @@ -297,15 +297,15 @@ BOOST_AUTO_TEST_CASE(NMSMetricTest) selectedIndices, 0.7); selectedBoundingBox = bbox.cols(selectedIndices); - BOOST_REQUIRE_EQUAL(selectedBoundingBox.n_cols, 2); - BOOST_REQUIRE_EQUAL(selectedBoundingBox.n_rows, 4); + REQUIRE(selectedBoundingBox.n_cols == 2); + REQUIRE(selectedBoundingBox.n_rows == 4); CheckMatrices(desiredBoundingBox, selectedBoundingBox); } /** * */ -BOOST_AUTO_TEST_CASE(BLEUScoreTest) +TEST_CASE("BLEUScoreTest", "[MetricTest]") { typedef typename std::vector WordVector; std::vector> referenceCorpus @@ -330,34 +330,32 @@ BOOST_AUTO_TEST_CASE(BLEUScoreTest) //! We are not using smoothing function here. bleu.Evaluate(referenceCorpus, translationCorpus); - BOOST_REQUIRE_CLOSE_FRACTION(bleu.BLEUScore(), 0.0, 1e-05); - BOOST_REQUIRE_EQUAL(bleu.BrevityPenalty(), 1.0); - BOOST_REQUIRE_EQUAL(bleu.Ratio(), 1.0); - BOOST_REQUIRE_EQUAL(bleu.TranslationLength(), 12); - BOOST_REQUIRE_EQUAL(bleu.ReferenceLength(), 12); + REQUIRE(bleu.BLEUScore() == Approx(0.0).epsilon(1e-5)); + REQUIRE(bleu.BrevityPenalty() == 1.0); + REQUIRE(bleu.Ratio() == 1.0); + REQUIRE(bleu.TranslationLength() == 12); + REQUIRE(bleu.ReferenceLength() == 12); std::vector expectedPrecision = {0.666666f, 0.5555555f, 0.3333333f, 0.0f}; for (size_t i = 0; i < bleu.Precisions().size(); ++i) { - BOOST_REQUIRE_CLOSE_FRACTION(bleu.Precisions()[i], - expectedPrecision[i], 1e-04); + REQUIRE(bleu.Precisions()[i] == + Approx((double)expectedPrecision[i]).epsilon(1e-4)); } //! We will use smoothing function here by setting smooth to true. bleu.Evaluate(referenceCorpus, translationCorpus, true); - BOOST_REQUIRE_CLOSE_FRACTION(bleu.BLEUScore(), 0.459307, 1e-05); - BOOST_REQUIRE_EQUAL(bleu.BrevityPenalty(), 1.0); - BOOST_REQUIRE_EQUAL(bleu.Ratio(), 1.0); - BOOST_REQUIRE_EQUAL(bleu.TranslationLength(), 12); - BOOST_REQUIRE_EQUAL(bleu.ReferenceLength(), 12); + REQUIRE(bleu.BLEUScore() == Approx(0.459307).epsilon(1e-5)); + REQUIRE(bleu.BrevityPenalty() == 1.0); + REQUIRE(bleu.Ratio() == 1.0); + REQUIRE(bleu.TranslationLength() == 12); + REQUIRE(bleu.ReferenceLength() == 12); expectedPrecision = {0.692308f, 0.6f, 0.428571f, 0.25f}; for (size_t i = 0; i < bleu.Precisions().size(); ++i) { - BOOST_REQUIRE_CLOSE_FRACTION(bleu.Precisions()[i], - expectedPrecision[i], 1e-04); + REQUIRE(bleu.Precisions()[i] == + Approx(expectedPrecision[i]).epsilon(1e-4)); } } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/octree_test.cpp b/src/mlpack/tests/octree_test.cpp index a15285e093..989eaa8c92 100644 --- a/src/mlpack/tests/octree_test.cpp +++ b/src/mlpack/tests/octree_test.cpp @@ -12,9 +12,9 @@ #include #include -#include -#include "test_tools.hpp" -#include "serialization.hpp" +#include "catch.hpp" +#include "test_catch_tools.hpp" +#include "serialization_catch.hpp" using namespace mlpack; using namespace mlpack::math; @@ -22,28 +22,26 @@ using namespace mlpack::tree; using namespace mlpack::metric; using namespace mlpack::bound; -BOOST_AUTO_TEST_SUITE(OctreeTest); - /** * Build a quad-tree (2-d octree) on 4 points, and guarantee four points are * created. */ -BOOST_AUTO_TEST_CASE(SimpleQuadtreeTest) +TEST_CASE("SimpleQuadtreeTest", "[OctreeTest]") { // Four corners of the unit square. arma::mat dataset("0 0 1 1; 0 1 0 1"); Octree<> t(dataset, 1); - BOOST_REQUIRE_EQUAL(t.NumChildren(), 4); - BOOST_REQUIRE_EQUAL(t.Dataset().n_cols, 4); - BOOST_REQUIRE_EQUAL(t.Dataset().n_rows, 2); - BOOST_REQUIRE_EQUAL(t.NumDescendants(), 4); - BOOST_REQUIRE_EQUAL(t.NumPoints(), 0); + REQUIRE(t.NumChildren() == 4); + REQUIRE(t.Dataset().n_cols == 4); + REQUIRE(t.Dataset().n_rows == 2); + REQUIRE(t.NumDescendants() == 4); + REQUIRE(t.NumPoints() == 0); for (size_t i = 0; i < 4; ++i) { - BOOST_REQUIRE_EQUAL(t.Child(i).NumDescendants(), 1); - BOOST_REQUIRE_EQUAL(t.Child(i).NumPoints(), 1); + REQUIRE(t.Child(i).NumDescendants() == 1); + REQUIRE(t.Child(i).NumPoints() == 1); } } @@ -51,62 +49,62 @@ BOOST_AUTO_TEST_CASE(SimpleQuadtreeTest) * Build an octree on 3 points and make sure that only three children are * created. */ -BOOST_AUTO_TEST_CASE(OctreeMissingChildTest) +TEST_CASE("OctreeMissingChildTest", "[OctreeTest]") { // Only three corners of the unit square. arma::mat dataset("0 0 1; 0 1 1"); Octree<> t(dataset, 1); - BOOST_REQUIRE_EQUAL(t.NumChildren(), 3); - BOOST_REQUIRE_EQUAL(t.Dataset().n_cols, 3); - BOOST_REQUIRE_EQUAL(t.Dataset().n_rows, 2); - BOOST_REQUIRE_EQUAL(t.NumDescendants(), 3); - BOOST_REQUIRE_EQUAL(t.NumPoints(), 0); + REQUIRE(t.NumChildren() == 3); + REQUIRE(t.Dataset().n_cols == 3); + REQUIRE(t.Dataset().n_rows == 2); + REQUIRE(t.NumDescendants() == 3); + REQUIRE(t.NumPoints() == 0); for (size_t i = 0; i < 3; ++i) { - BOOST_REQUIRE_EQUAL(t.Child(i).NumDescendants(), 1); - BOOST_REQUIRE_EQUAL(t.Child(i).NumPoints(), 1); + REQUIRE(t.Child(i).NumDescendants() == 1); + REQUIRE(t.Child(i).NumPoints() == 1); } } /** * Ensure that building an empty octree does not fail. */ -BOOST_AUTO_TEST_CASE(EmptyOctreeTest) +TEST_CASE("EmptyOctreeTest", "[OctreeTest]") { arma::mat dataset; Octree<> t(dataset); - BOOST_REQUIRE_EQUAL(t.NumChildren(), 0); - BOOST_REQUIRE_EQUAL(t.Dataset().n_cols, 0); - BOOST_REQUIRE_EQUAL(t.Dataset().n_rows, 0); - BOOST_REQUIRE_EQUAL(t.NumDescendants(), 0); - BOOST_REQUIRE_EQUAL(t.NumPoints(), 0); + REQUIRE(t.NumChildren() == 0); + REQUIRE(t.Dataset().n_cols == 0); + REQUIRE(t.Dataset().n_rows == 0); + REQUIRE(t.NumDescendants() == 0); + REQUIRE(t.NumPoints() == 0); } /** * Ensure that maxLeafSize is respected. */ -BOOST_AUTO_TEST_CASE(MaxLeafSizeTest) +TEST_CASE("MaxLeafSizeTest", "[OctreeTest]") { arma::mat dataset(5, 15, arma::fill::randu); Octree<> t1(dataset, 20); Octree<> t2(std::move(dataset), 20); - BOOST_REQUIRE_EQUAL(t1.NumChildren(), 0); - BOOST_REQUIRE_EQUAL(t1.NumDescendants(), 15); - BOOST_REQUIRE_EQUAL(t1.NumPoints(), 15); + REQUIRE(t1.NumChildren() == 0); + REQUIRE(t1.NumDescendants() == 15); + REQUIRE(t1.NumPoints() == 15); - BOOST_REQUIRE_EQUAL(t2.NumChildren(), 0); - BOOST_REQUIRE_EQUAL(t2.NumDescendants(), 15); - BOOST_REQUIRE_EQUAL(t2.NumPoints(), 15); + REQUIRE(t2.NumChildren() == 0); + REQUIRE(t2.NumDescendants() == 15); + REQUIRE(t2.NumPoints() == 15); } /** * Check that the mappings given are correct. */ -BOOST_AUTO_TEST_CASE(MappingsTest) +TEST_CASE("MappingsTest", "[OctreeTest]") { // Test with both constructors. arma::mat dataset(3, 5, arma::fill::randu); @@ -118,17 +116,17 @@ BOOST_AUTO_TEST_CASE(MappingsTest) for (size_t i = 0; i < oldFromNewCopy.size(); ++i) { - BOOST_REQUIRE_SMALL(arma::norm(datacopy.col(oldFromNewCopy[i]) - - t1.Dataset().col(i)), 1e-3); - BOOST_REQUIRE_SMALL(arma::norm(datacopy.col(oldFromNewMove[i]) - - t2.Dataset().col(i)), 1e-3); + REQUIRE(arma::norm(datacopy.col(oldFromNewCopy[i]) - + t1.Dataset().col(i)) == Approx(0.0).margin(1e-3)); + REQUIRE(arma::norm(datacopy.col(oldFromNewMove[i]) - + t2.Dataset().col(i)) == Approx(0.0).margin(1e-3)); } } /** * Check that the reverse mappings are correct too. */ -BOOST_AUTO_TEST_CASE(ReverseMappingsTest) +TEST_CASE("ReverseMappingsTest", "[OctreeTest]") { // Test with both constructors. arma::mat dataset(3, 300, arma::fill::randu); @@ -141,13 +139,14 @@ BOOST_AUTO_TEST_CASE(ReverseMappingsTest) for (size_t i = 0; i < oldFromNewCopy.size(); ++i) { - BOOST_REQUIRE_SMALL(arma::norm(datacopy.col(oldFromNewCopy[i]) - - t1.Dataset().col(i)), 1e-3); - BOOST_REQUIRE_SMALL(arma::norm(datacopy.col(oldFromNewMove[i]) - - t2.Dataset().col(i)), 1e-3); + REQUIRE(arma::norm(datacopy.col(oldFromNewCopy[i]) - + t1.Dataset().col(i)) == Approx(0.0).margin(1e-3)); + REQUIRE(arma::norm(datacopy.col(oldFromNewMove[i]) - + t2.Dataset().col(i)) == Approx(0.0).margin(1e-3)); - BOOST_REQUIRE_EQUAL(newFromOldCopy[oldFromNewCopy[i]], i); - BOOST_REQUIRE_EQUAL(newFromOldMove[oldFromNewMove[i]], i); + + REQUIRE(newFromOldCopy[oldFromNewCopy[i]] == i); + REQUIRE(newFromOldMove[oldFromNewMove[i]] == i); } } @@ -160,14 +159,14 @@ void CheckOverlap(TreeType& node) // Check each combination of children. for (size_t i = 0; i < node.NumChildren(); ++i) for (size_t j = i + 1; j < node.NumChildren(); ++j) - BOOST_REQUIRE_EQUAL(node.Child(i).Bound().Overlap(node.Child(j).Bound()), + REQUIRE(node.Child(i).Bound().Overlap(node.Child(j).Bound()) == 0.0); // We need exact equality here. for (size_t i = 0; i < node.NumChildren(); ++i) CheckOverlap(node.Child(i)); } -BOOST_AUTO_TEST_CASE(OverlapTest) +TEST_CASE("OverlapTest", "[OctreeTest]") { // Test with both constructors. arma::mat dataset(3, 300, arma::fill::randu); @@ -193,8 +192,8 @@ void CheckFurthestDistances(TreeType& node) for (size_t i = 0; i < node.NumPoints(); ++i) { // Handle floating-point inaccuracies. - BOOST_REQUIRE_LE(metric::EuclideanDistance::Evaluate( - node.Dataset().col(node.Point(i)), center), + REQUIRE(metric::EuclideanDistance::Evaluate( + node.Dataset().col(node.Point(i)), center) <= node.FurthestPointDistance() * (1 + 1e-5)); } @@ -202,16 +201,16 @@ void CheckFurthestDistances(TreeType& node) for (size_t i = 0; i < node.NumDescendants(); ++i) { // Handle floating-point inaccuracies. - BOOST_REQUIRE_LE(metric::EuclideanDistance::Evaluate( + REQUIRE(metric::EuclideanDistance::Evaluate( node.Dataset().col(node.Descendant(i)), - center), node.FurthestDescendantDistance() * (1 + 1e-5)); + center) <= node.FurthestDescendantDistance() * (1 + 1e-5)); } for (size_t i = 0; i < node.NumChildren(); ++i) CheckFurthestDistances(node.Child(i)); } -BOOST_AUTO_TEST_CASE(FurthestDistanceTest) +TEST_CASE("FurthestDistanceTest", "[OctreeTest]") { // Test with both constructors. arma::mat dataset(3, 500, arma::fill::randu); @@ -231,12 +230,12 @@ BOOST_AUTO_TEST_CASE(FurthestDistanceTest) template void CheckNumChildren(TreeType& node) { - BOOST_REQUIRE_LE(node.NumChildren(), std::pow(2, node.Dataset().n_rows)); + REQUIRE(node.NumChildren() <= std::pow(2, node.Dataset().n_rows)); for (size_t i = 0; i < node.NumChildren(); ++i) CheckNumChildren(node.Child(i)); } -BOOST_AUTO_TEST_CASE(MaxNumChildrenTest) +TEST_CASE("MaxNumChildrenTest", "[OctreeTest]") { for (size_t d = 1; d < 10; ++d) { @@ -253,37 +252,39 @@ BOOST_AUTO_TEST_CASE(MaxNumChildrenTest) template void CheckSameNode(TreeType& node1, TreeType& node2) { - BOOST_REQUIRE_EQUAL(node1.NumChildren(), node2.NumChildren()); - BOOST_REQUIRE_NE(&node1.Dataset(), &node2.Dataset()); + REQUIRE(node1.NumChildren() == node2.NumChildren()); + REQUIRE(&node1.Dataset() != &node2.Dataset()); // Make sure the children actually got copied. for (size_t i = 0; i < node1.NumChildren(); ++i) - BOOST_REQUIRE_NE(&node1.Child(i), &node2.Child(i)); + REQUIRE(&node1.Child(i) != &node2.Child(i)); // Check that all the points are the same. - BOOST_REQUIRE_EQUAL(node1.NumPoints(), node2.NumPoints()); - BOOST_REQUIRE_EQUAL(node1.NumDescendants(), node2.NumDescendants()); + REQUIRE(node1.NumPoints() == node2.NumPoints()); + REQUIRE(node1.NumDescendants() == node2.NumDescendants()); for (size_t i = 0; i < node1.NumPoints(); ++i) - BOOST_REQUIRE_EQUAL(node1.Point(i), node2.Point(i)); + REQUIRE(node1.Point(i) == node2.Point(i)); for (size_t i = 0; i < node1.NumDescendants(); ++i) - BOOST_REQUIRE_EQUAL(node1.Descendant(i), node2.Descendant(i)); + REQUIRE(node1.Descendant(i) == node2.Descendant(i)); // Check that the bound is the same. - BOOST_REQUIRE_EQUAL(node1.Bound().Dim(), node2.Bound().Dim()); + REQUIRE(node1.Bound().Dim() == node2.Bound().Dim()); for (size_t d = 0; d < node1.Bound().Dim(); ++d) { - BOOST_REQUIRE_CLOSE(node1.Bound()[d].Lo(), node2.Bound()[d].Lo(), 1e-5); - BOOST_REQUIRE_CLOSE(node1.Bound()[d].Hi(), node2.Bound()[d].Hi(), 1e-5); + REQUIRE(node1.Bound()[d].Lo() == + Approx(node2.Bound()[d].Lo()).epsilon(1e-7)); + REQUIRE(node1.Bound()[d].Hi() == + Approx(node2.Bound()[d].Hi()).epsilon(1e-7)); } // Check that the furthest point and descendant distance are the same. - BOOST_REQUIRE_CLOSE(node1.FurthestPointDistance(), - node2.FurthestPointDistance(), 1e-5); - BOOST_REQUIRE_CLOSE(node1.FurthestDescendantDistance(), - node2.FurthestDescendantDistance(), 1e-5); + REQUIRE(node1.FurthestPointDistance() == + Approx(node2.FurthestPointDistance()).epsilon(1e-7)); + REQUIRE(node1.FurthestDescendantDistance() == + Approx(node2.FurthestDescendantDistance()).epsilon(1e-7)); } -BOOST_AUTO_TEST_CASE(CopyConstructorTest) +TEST_CASE("CopyConstructorTest", "[OctreeTest]") { // Use a small random dataset. arma::mat dataset(3, 100, arma::fill::randu); @@ -297,7 +298,7 @@ BOOST_AUTO_TEST_CASE(CopyConstructorTest) /** * Test the move constructor. */ -BOOST_AUTO_TEST_CASE(MoveConstructorTest) +TEST_CASE("OcTreeTestMoveConstructorTest", "[OctreeTest]") { // Use a small random dataset. arma::mat dataset(3, 100, arma::fill::randu); @@ -309,14 +310,14 @@ BOOST_AUTO_TEST_CASE(MoveConstructorTest) Octree<> t2(std::move(t)); // Make sure the original tree has no data. - BOOST_REQUIRE_EQUAL(t.Dataset().n_rows, 0); - BOOST_REQUIRE_EQUAL(t.Dataset().n_cols, 0); - BOOST_REQUIRE_EQUAL(t.NumChildren(), 0); - BOOST_REQUIRE_EQUAL(t.NumPoints(), 0); - BOOST_REQUIRE_EQUAL(t.NumDescendants(), 0); - BOOST_REQUIRE_SMALL(t.FurthestPointDistance(), 1e-5); - BOOST_REQUIRE_SMALL(t.FurthestDescendantDistance(), 1e-5); - BOOST_REQUIRE_EQUAL(t.Bound().Dim(), 0); + REQUIRE(t.Dataset().n_rows == 0); + REQUIRE(t.Dataset().n_cols == 0); + REQUIRE(t.NumChildren() == 0); + REQUIRE(t.NumPoints() == 0); + REQUIRE(t.NumDescendants() == 0); + REQUIRE(t.FurthestPointDistance() == Approx(0.0).margin(1e-5)); + REQUIRE(t.FurthestDescendantDistance() == Approx(0.0).margin(1e-5)); + REQUIRE(t.Bound().Dim() == 0); // Check that the new tree is the same as our copy. CheckSameNode(tcopy, t2); @@ -325,7 +326,7 @@ BOOST_AUTO_TEST_CASE(MoveConstructorTest) /** * Test serialization. */ -BOOST_AUTO_TEST_CASE(SerializationTest) +TEST_CASE("OctreeSerializationTest", "[OctreeTest]") { // Use a small random dataset. arma::mat dataset(3, 500, arma::fill::randu); @@ -345,5 +346,3 @@ BOOST_AUTO_TEST_CASE(SerializationTest) delete binaryTree; delete textTree; } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/range_search_test.cpp b/src/mlpack/tests/range_search_test.cpp index 33dd5c56ca..7bd714beaf 100644 --- a/src/mlpack/tests/range_search_test.cpp +++ b/src/mlpack/tests/range_search_test.cpp @@ -13,8 +13,9 @@ #include #include #include -#include -#include "test_tools.hpp" + +#include "catch.hpp" +#include "test_catch_tools.hpp" using namespace mlpack; using namespace mlpack::range; @@ -24,8 +25,6 @@ using namespace mlpack::bound; using namespace mlpack::metric; using namespace std; -BOOST_AUTO_TEST_SUITE(RangeSearchTest); - // Get our results into a sorted format, so we can actually then test for // correctness. void SortResults(const vector>& neighbors, @@ -62,7 +61,7 @@ void CleanTree(TreeType& node) * dataset is in one dimension for simplicity -- the correct functionality of * distance functions is not tested here. */ -BOOST_AUTO_TEST_CASE(ExhaustiveSyntheticTest) +TEST_CASE("ExhaustiveSyntheticTest", "[RangeSearchTest]") { // Set up our data. arma::mat data(1, 11); @@ -111,109 +110,109 @@ BOOST_AUTO_TEST_CASE(ExhaustiveSyntheticTest) vector>> sortedOutput; SortResults(neighbors, distances, sortedOutput); - BOOST_REQUIRE(sortedOutput[newFromOld[0]].size() == 4); - BOOST_REQUIRE(sortedOutput[newFromOld[0]][0].second == newFromOld[2]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[0]][0].first, 0.10, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[0]][1].second == newFromOld[5]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[0]][1].first, 0.27, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[0]][2].second == newFromOld[1]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[0]][2].first, 0.30, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[0]][3].second == newFromOld[8]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[0]][3].first, 0.40, 1e-5); + REQUIRE(sortedOutput[newFromOld[0]].size() == 4); + REQUIRE(sortedOutput[newFromOld[0]][0].second == newFromOld[2]); + REQUIRE(sortedOutput[newFromOld[0]][0].first == Approx(0.10).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[0]][1].second == newFromOld[5]); + REQUIRE(sortedOutput[newFromOld[0]][1].first == Approx(0.27).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[0]][2].second == newFromOld[1]); + REQUIRE(sortedOutput[newFromOld[0]][2].first == Approx(0.30).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[0]][3].second == newFromOld[8]); + REQUIRE(sortedOutput[newFromOld[0]][3].first == Approx(0.40).epsilon(1e-7)); // Neighbors of point 1. - BOOST_REQUIRE(sortedOutput[newFromOld[1]].size() == 6); - BOOST_REQUIRE(sortedOutput[newFromOld[1]][0].second == newFromOld[8]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[1]][0].first, 0.10, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[1]][1].second == newFromOld[2]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[1]][1].first, 0.20, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[1]][2].second == newFromOld[0]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[1]][2].first, 0.30, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[1]][3].second == newFromOld[9]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[1]][3].first, 0.55, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[1]][4].second == newFromOld[5]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[1]][4].first, 0.57, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[1]][5].second == newFromOld[10]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[1]][5].first, 0.65, 1e-5); + REQUIRE(sortedOutput[newFromOld[1]].size() == 6); + REQUIRE(sortedOutput[newFromOld[1]][0].second == newFromOld[8]); + REQUIRE(sortedOutput[newFromOld[1]][0].first == Approx(0.10).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[1]][1].second == newFromOld[2]); + REQUIRE(sortedOutput[newFromOld[1]][1].first == Approx(0.20).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[1]][2].second == newFromOld[0]); + REQUIRE(sortedOutput[newFromOld[1]][2].first == Approx(0.30).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[1]][3].second == newFromOld[9]); + REQUIRE(sortedOutput[newFromOld[1]][3].first == Approx(0.55).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[1]][4].second == newFromOld[5]); + REQUIRE(sortedOutput[newFromOld[1]][4].first == Approx(0.57).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[1]][5].second == newFromOld[10]); + REQUIRE(sortedOutput[newFromOld[1]][5].first == Approx(0.65).epsilon(1e-7)); // Neighbors of point 2. - BOOST_REQUIRE(sortedOutput[newFromOld[2]].size() == 4); - BOOST_REQUIRE(sortedOutput[newFromOld[2]][0].second == newFromOld[0]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[2]][0].first, 0.10, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[2]][1].second == newFromOld[1]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[2]][1].first, 0.20, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[2]][2].second == newFromOld[8]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[2]][2].first, 0.30, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[2]][3].second == newFromOld[5]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[2]][3].first, 0.37, 1e-5); + REQUIRE(sortedOutput[newFromOld[2]].size() == 4); + REQUIRE(sortedOutput[newFromOld[2]][0].second == newFromOld[0]); + REQUIRE(sortedOutput[newFromOld[2]][0].first == Approx(0.10).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[2]][1].second == newFromOld[1]); + REQUIRE(sortedOutput[newFromOld[2]][1].first == Approx(0.20).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[2]][2].second == newFromOld[8]); + REQUIRE(sortedOutput[newFromOld[2]][2].first == Approx(0.30).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[2]][3].second == newFromOld[5]); + REQUIRE(sortedOutput[newFromOld[2]][3].first == Approx(0.37).epsilon(1e-7)); // Neighbors of point 3. - BOOST_REQUIRE(sortedOutput[newFromOld[3]].size() == 2); - BOOST_REQUIRE(sortedOutput[newFromOld[3]][0].second == newFromOld[10]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[3]][0].first, 0.25, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[3]][1].second == newFromOld[9]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[3]][1].first, 0.35, 1e-5); + REQUIRE(sortedOutput[newFromOld[3]].size() == 2); + REQUIRE(sortedOutput[newFromOld[3]][0].second == newFromOld[10]); + REQUIRE(sortedOutput[newFromOld[3]][0].first == Approx(0.25).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[3]][1].second == newFromOld[9]); + REQUIRE(sortedOutput[newFromOld[3]][1].first == Approx(0.35).epsilon(1e-7)); // Neighbors of point 4. - BOOST_REQUIRE(sortedOutput[newFromOld[4]].size() == 0); + REQUIRE(sortedOutput[newFromOld[4]].size() == 0); // Neighbors of point 5. - BOOST_REQUIRE(sortedOutput[newFromOld[5]].size() == 4); - BOOST_REQUIRE(sortedOutput[newFromOld[5]][0].second == newFromOld[0]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[5]][0].first, 0.27, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[5]][1].second == newFromOld[2]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[5]][1].first, 0.37, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[5]][2].second == newFromOld[1]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[5]][2].first, 0.57, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[5]][3].second == newFromOld[8]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[5]][3].first, 0.67, 1e-5); + REQUIRE(sortedOutput[newFromOld[5]].size() == 4); + REQUIRE(sortedOutput[newFromOld[5]][0].second == newFromOld[0]); + REQUIRE(sortedOutput[newFromOld[5]][0].first == Approx(0.27).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[5]][1].second == newFromOld[2]); + REQUIRE(sortedOutput[newFromOld[5]][1].first == Approx(0.37).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[5]][2].second == newFromOld[1]); + REQUIRE(sortedOutput[newFromOld[5]][2].first == Approx(0.57).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[5]][3].second == newFromOld[8]); + REQUIRE(sortedOutput[newFromOld[5]][3].first == Approx(0.67).epsilon(1e-7)); // Neighbors of point 6. - BOOST_REQUIRE(sortedOutput[newFromOld[6]].size() == 1); - BOOST_REQUIRE(sortedOutput[newFromOld[6]][0].second == newFromOld[7]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[6]][0].first, 0.70, 1e-5); + REQUIRE(sortedOutput[newFromOld[6]].size() == 1); + REQUIRE(sortedOutput[newFromOld[6]][0].second == newFromOld[7]); + REQUIRE(sortedOutput[newFromOld[6]][0].first == Approx(0.70).epsilon(1e-7)); // Neighbors of point 7. - BOOST_REQUIRE(sortedOutput[newFromOld[7]].size() == 1); - BOOST_REQUIRE(sortedOutput[newFromOld[7]][0].second == newFromOld[6]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[7]][0].first, 0.70, 1e-5); + REQUIRE(sortedOutput[newFromOld[7]].size() == 1); + REQUIRE(sortedOutput[newFromOld[7]][0].second == newFromOld[6]); + REQUIRE(sortedOutput[newFromOld[7]][0].first == Approx(0.70).epsilon(1e-7)); // Neighbors of point 8. - BOOST_REQUIRE(sortedOutput[newFromOld[8]].size() == 6); - BOOST_REQUIRE(sortedOutput[newFromOld[8]][0].second == newFromOld[1]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[8]][0].first, 0.10, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[8]][1].second == newFromOld[2]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[8]][1].first, 0.30, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[8]][2].second == newFromOld[0]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[8]][2].first, 0.40, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[8]][3].second == newFromOld[9]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[8]][3].first, 0.45, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[8]][4].second == newFromOld[10]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[8]][4].first, 0.55, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[8]][5].second == newFromOld[5]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[8]][5].first, 0.67, 1e-5); + REQUIRE(sortedOutput[newFromOld[8]].size() == 6); + REQUIRE(sortedOutput[newFromOld[8]][0].second == newFromOld[1]); + REQUIRE(sortedOutput[newFromOld[8]][0].first == Approx(0.10).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[8]][1].second == newFromOld[2]); + REQUIRE(sortedOutput[newFromOld[8]][1].first == Approx(0.30).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[8]][2].second == newFromOld[0]); + REQUIRE(sortedOutput[newFromOld[8]][2].first == Approx(0.40).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[8]][3].second == newFromOld[9]); + REQUIRE(sortedOutput[newFromOld[8]][3].first == Approx(0.45).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[8]][4].second == newFromOld[10]); + REQUIRE(sortedOutput[newFromOld[8]][4].first == Approx(0.55).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[8]][5].second == newFromOld[5]); + REQUIRE(sortedOutput[newFromOld[8]][5].first == Approx(0.67).epsilon(1e-7)); // Neighbors of point 9. - BOOST_REQUIRE(sortedOutput[newFromOld[9]].size() == 4); - BOOST_REQUIRE(sortedOutput[newFromOld[9]][0].second == newFromOld[10]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[9]][0].first, 0.10, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[9]][1].second == newFromOld[3]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[9]][1].first, 0.35, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[9]][2].second == newFromOld[8]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[9]][2].first, 0.45, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[9]][3].second == newFromOld[1]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[9]][3].first, 0.55, 1e-5); + REQUIRE(sortedOutput[newFromOld[9]].size() == 4); + REQUIRE(sortedOutput[newFromOld[9]][0].second == newFromOld[10]); + REQUIRE(sortedOutput[newFromOld[9]][0].first == Approx(0.10).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[9]][1].second == newFromOld[3]); + REQUIRE(sortedOutput[newFromOld[9]][1].first == Approx(0.35).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[9]][2].second == newFromOld[8]); + REQUIRE(sortedOutput[newFromOld[9]][2].first == Approx(0.45).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[9]][3].second == newFromOld[1]); + REQUIRE(sortedOutput[newFromOld[9]][3].first == Approx(0.55).epsilon(1e-7)); // Neighbors of point 10. - BOOST_REQUIRE(sortedOutput[newFromOld[10]].size() == 4); - BOOST_REQUIRE(sortedOutput[newFromOld[10]][0].second == newFromOld[9]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[10]][0].first, 0.10, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[10]][1].second == newFromOld[3]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[10]][1].first, 0.25, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[10]][2].second == newFromOld[8]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[10]][2].first, 0.55, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[10]][3].second == newFromOld[1]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[10]][3].first, 0.65, 1e-5); + REQUIRE(sortedOutput[newFromOld[10]].size() == 4); + REQUIRE(sortedOutput[newFromOld[10]][0].second == newFromOld[9]); + REQUIRE(sortedOutput[newFromOld[10]][0].first == Approx(0.10).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[10]][1].second == newFromOld[3]); + REQUIRE(sortedOutput[newFromOld[10]][1].first == Approx(0.25).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[10]][2].second == newFromOld[8]); + REQUIRE(sortedOutput[newFromOld[10]][2].first == Approx(0.55).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[10]][3].second == newFromOld[1]); + REQUIRE(sortedOutput[newFromOld[10]][3].first == Approx(0.65).epsilon(1e-7)); // Now do it again with a different range: [sqrt(0.5) 1.0]. if (rs->ReferenceTree()) @@ -222,61 +221,61 @@ BOOST_AUTO_TEST_CASE(ExhaustiveSyntheticTest) SortResults(neighbors, distances, sortedOutput); // Neighbors of point 0. - BOOST_REQUIRE(sortedOutput[newFromOld[0]].size() == 2); - BOOST_REQUIRE(sortedOutput[newFromOld[0]][0].second == newFromOld[9]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[0]][0].first, 0.85, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[0]][1].second == newFromOld[10]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[0]][1].first, 0.95, 1e-5); + REQUIRE(sortedOutput[newFromOld[0]].size() == 2); + REQUIRE(sortedOutput[newFromOld[0]][0].second == newFromOld[9]); + REQUIRE(sortedOutput[newFromOld[0]][0].first == Approx(0.85).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[0]][1].second == newFromOld[10]); + REQUIRE(sortedOutput[newFromOld[0]][1].first == Approx(0.95).epsilon(1e-7)); // Neighbors of point 1. - BOOST_REQUIRE(sortedOutput[newFromOld[1]].size() == 1); - BOOST_REQUIRE(sortedOutput[newFromOld[1]][0].second == newFromOld[3]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[1]][0].first, 0.90, 1e-5); + REQUIRE(sortedOutput[newFromOld[1]].size() == 1); + REQUIRE(sortedOutput[newFromOld[1]][0].second == newFromOld[3]); + REQUIRE(sortedOutput[newFromOld[1]][0].first == Approx(0.90).epsilon(1e-7)); // Neighbors of point 2. - BOOST_REQUIRE(sortedOutput[newFromOld[2]].size() == 2); - BOOST_REQUIRE(sortedOutput[newFromOld[2]][0].second == newFromOld[9]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[2]][0].first, 0.75, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[2]][1].second == newFromOld[10]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[2]][1].first, 0.85, 1e-5); + REQUIRE(sortedOutput[newFromOld[2]].size() == 2); + REQUIRE(sortedOutput[newFromOld[2]][0].second == newFromOld[9]); + REQUIRE(sortedOutput[newFromOld[2]][0].first == Approx(0.75).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[2]][1].second == newFromOld[10]); + REQUIRE(sortedOutput[newFromOld[2]][1].first == Approx(0.85).epsilon(1e-7)); // Neighbors of point 3. - BOOST_REQUIRE(sortedOutput[newFromOld[3]].size() == 2); - BOOST_REQUIRE(sortedOutput[newFromOld[3]][0].second == newFromOld[8]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[3]][0].first, 0.80, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[3]][1].second == newFromOld[1]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[3]][1].first, 0.90, 1e-5); + REQUIRE(sortedOutput[newFromOld[3]].size() == 2); + REQUIRE(sortedOutput[newFromOld[3]][0].second == newFromOld[8]); + REQUIRE(sortedOutput[newFromOld[3]][0].first == Approx(0.80).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[3]][1].second == newFromOld[1]); + REQUIRE(sortedOutput[newFromOld[3]][1].first == Approx(0.90).epsilon(1e-7)); // Neighbors of point 4. - BOOST_REQUIRE(sortedOutput[newFromOld[4]].size() == 0); + REQUIRE(sortedOutput[newFromOld[4]].size() == 0); // Neighbors of point 5. - BOOST_REQUIRE(sortedOutput[newFromOld[5]].size() == 0); + REQUIRE(sortedOutput[newFromOld[5]].size() == 0); // Neighbors of point 6. - BOOST_REQUIRE(sortedOutput[newFromOld[6]].size() == 0); + REQUIRE(sortedOutput[newFromOld[6]].size() == 0); // Neighbors of point 7. - BOOST_REQUIRE(sortedOutput[newFromOld[7]].size() == 0); + REQUIRE(sortedOutput[newFromOld[7]].size() == 0); // Neighbors of point 8. - BOOST_REQUIRE(sortedOutput[newFromOld[8]].size() == 1); - BOOST_REQUIRE(sortedOutput[newFromOld[8]][0].second == newFromOld[3]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[8]][0].first, 0.80, 1e-5); + REQUIRE(sortedOutput[newFromOld[8]].size() == 1); + REQUIRE(sortedOutput[newFromOld[8]][0].second == newFromOld[3]); + REQUIRE(sortedOutput[newFromOld[8]][0].first == Approx(0.80).epsilon(1e-7)); // Neighbors of point 9. - BOOST_REQUIRE(sortedOutput[newFromOld[9]].size() == 2); - BOOST_REQUIRE(sortedOutput[newFromOld[9]][0].second == newFromOld[2]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[9]][0].first, 0.75, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[9]][1].second == newFromOld[0]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[9]][1].first, 0.85, 1e-5); + REQUIRE(sortedOutput[newFromOld[9]].size() == 2); + REQUIRE(sortedOutput[newFromOld[9]][0].second == newFromOld[2]); + REQUIRE(sortedOutput[newFromOld[9]][0].first == Approx(0.75).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[9]][1].second == newFromOld[0]); + REQUIRE(sortedOutput[newFromOld[9]][1].first == Approx(0.85).epsilon(1e-7)); // Neighbors of point 10. - BOOST_REQUIRE(sortedOutput[newFromOld[10]].size() == 2); - BOOST_REQUIRE(sortedOutput[newFromOld[10]][0].second == newFromOld[2]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[10]][0].first, 0.85, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[10]][1].second == newFromOld[0]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[10]][1].first, 0.95, 1e-5); + REQUIRE(sortedOutput[newFromOld[10]].size() == 2); + REQUIRE(sortedOutput[newFromOld[10]][0].second == newFromOld[2]); + REQUIRE(sortedOutput[newFromOld[10]][0].first == Approx(0.85).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[10]][1].second == newFromOld[0]); + REQUIRE(sortedOutput[newFromOld[10]][1].first == Approx(0.95).epsilon(1e-7)); // Now do it again with a different range: [1.0 inf]. if (rs->ReferenceTree()) @@ -286,161 +285,161 @@ BOOST_AUTO_TEST_CASE(ExhaustiveSyntheticTest) SortResults(neighbors, distances, sortedOutput); // Neighbors of point 0. - BOOST_REQUIRE(sortedOutput[newFromOld[0]].size() == 4); - BOOST_REQUIRE(sortedOutput[newFromOld[0]][0].second == newFromOld[3]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[0]][0].first, 1.20, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[0]][1].second == newFromOld[7]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[0]][1].first, 1.35, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[0]][2].second == newFromOld[6]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[0]][2].first, 2.05, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[0]][3].second == newFromOld[4]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[0]][3].first, 5.00, 1e-5); + REQUIRE(sortedOutput[newFromOld[0]].size() == 4); + REQUIRE(sortedOutput[newFromOld[0]][0].second == newFromOld[3]); + REQUIRE(sortedOutput[newFromOld[0]][0].first == Approx(1.20).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[0]][1].second == newFromOld[7]); + REQUIRE(sortedOutput[newFromOld[0]][1].first == Approx(1.35).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[0]][2].second == newFromOld[6]); + REQUIRE(sortedOutput[newFromOld[0]][2].first == Approx(2.05).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[0]][3].second == newFromOld[4]); + REQUIRE(sortedOutput[newFromOld[0]][3].first == Approx(5.00).epsilon(1e-7)); // Neighbors of point 1. - BOOST_REQUIRE(sortedOutput[newFromOld[1]].size() == 3); - BOOST_REQUIRE(sortedOutput[newFromOld[1]][0].second == newFromOld[7]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[1]][0].first, 1.65, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[1]][1].second == newFromOld[6]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[1]][1].first, 2.35, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[1]][2].second == newFromOld[4]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[1]][2].first, 4.70, 1e-5); + REQUIRE(sortedOutput[newFromOld[1]].size() == 3); + REQUIRE(sortedOutput[newFromOld[1]][0].second == newFromOld[7]); + REQUIRE(sortedOutput[newFromOld[1]][0].first == Approx(1.65).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[1]][1].second == newFromOld[6]); + REQUIRE(sortedOutput[newFromOld[1]][1].first == Approx(2.35).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[1]][2].second == newFromOld[4]); + REQUIRE(sortedOutput[newFromOld[1]][2].first == Approx(4.70).epsilon(1e-7)); // Neighbors of point 2. - BOOST_REQUIRE(sortedOutput[newFromOld[2]].size() == 4); - BOOST_REQUIRE(sortedOutput[newFromOld[2]][0].second == newFromOld[3]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[2]][0].first, 1.10, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[2]][1].second == newFromOld[7]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[2]][1].first, 1.45, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[2]][2].second == newFromOld[6]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[2]][2].first, 2.15, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[2]][3].second == newFromOld[4]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[2]][3].first, 4.90, 1e-5); + REQUIRE(sortedOutput[newFromOld[2]].size() == 4); + REQUIRE(sortedOutput[newFromOld[2]][0].second == newFromOld[3]); + REQUIRE(sortedOutput[newFromOld[2]][0].first == Approx(1.10).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[2]][1].second == newFromOld[7]); + REQUIRE(sortedOutput[newFromOld[2]][1].first == Approx(1.45).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[2]][2].second == newFromOld[6]); + REQUIRE(sortedOutput[newFromOld[2]][2].first == Approx(2.15).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[2]][3].second == newFromOld[4]); + REQUIRE(sortedOutput[newFromOld[2]][3].first == Approx(4.90).epsilon(1e-7)); // Neighbors of point 3. - BOOST_REQUIRE(sortedOutput[newFromOld[3]].size() == 6); - BOOST_REQUIRE(sortedOutput[newFromOld[3]][0].second == newFromOld[2]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[3]][0].first, 1.10, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[3]][1].second == newFromOld[0]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[3]][1].first, 1.20, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[3]][2].second == newFromOld[5]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[3]][2].first, 1.47, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[3]][3].second == newFromOld[7]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[3]][3].first, 2.55, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[3]][4].second == newFromOld[6]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[3]][4].first, 3.25, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[3]][5].second == newFromOld[4]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[3]][5].first, 3.80, 1e-5); + REQUIRE(sortedOutput[newFromOld[3]].size() == 6); + REQUIRE(sortedOutput[newFromOld[3]][0].second == newFromOld[2]); + REQUIRE(sortedOutput[newFromOld[3]][0].first == Approx(1.10).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[3]][1].second == newFromOld[0]); + REQUIRE(sortedOutput[newFromOld[3]][1].first == Approx(1.20).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[3]][2].second == newFromOld[5]); + REQUIRE(sortedOutput[newFromOld[3]][2].first == Approx(1.47).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[3]][3].second == newFromOld[7]); + REQUIRE(sortedOutput[newFromOld[3]][3].first == Approx(2.55).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[3]][4].second == newFromOld[6]); + REQUIRE(sortedOutput[newFromOld[3]][4].first == Approx(3.25).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[3]][5].second == newFromOld[4]); + REQUIRE(sortedOutput[newFromOld[3]][5].first == Approx(3.80).epsilon(1e-7)); // Neighbors of point 4. - BOOST_REQUIRE(sortedOutput[newFromOld[4]].size() == 10); - BOOST_REQUIRE(sortedOutput[newFromOld[4]][0].second == newFromOld[3]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[4]][0].first, 3.80, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[4]][1].second == newFromOld[10]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[4]][1].first, 4.05, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[4]][2].second == newFromOld[9]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[4]][2].first, 4.15, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[4]][3].second == newFromOld[8]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[4]][3].first, 4.60, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[4]][4].second == newFromOld[1]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[4]][4].first, 4.70, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[4]][5].second == newFromOld[2]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[4]][5].first, 4.90, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[4]][6].second == newFromOld[0]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[4]][6].first, 5.00, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[4]][7].second == newFromOld[5]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[4]][7].first, 5.27, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[4]][8].second == newFromOld[7]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[4]][8].first, 6.35, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[4]][9].second == newFromOld[6]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[4]][9].first, 7.05, 1e-5); + REQUIRE(sortedOutput[newFromOld[4]].size() == 10); + REQUIRE(sortedOutput[newFromOld[4]][0].second == newFromOld[3]); + REQUIRE(sortedOutput[newFromOld[4]][0].first == Approx(3.80).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[4]][1].second == newFromOld[10]); + REQUIRE(sortedOutput[newFromOld[4]][1].first == Approx(4.05).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[4]][2].second == newFromOld[9]); + REQUIRE(sortedOutput[newFromOld[4]][2].first == Approx(4.15).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[4]][3].second == newFromOld[8]); + REQUIRE(sortedOutput[newFromOld[4]][3].first == Approx(4.60).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[4]][4].second == newFromOld[1]); + REQUIRE(sortedOutput[newFromOld[4]][4].first == Approx(4.70).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[4]][5].second == newFromOld[2]); + REQUIRE(sortedOutput[newFromOld[4]][5].first == Approx(4.90).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[4]][6].second == newFromOld[0]); + REQUIRE(sortedOutput[newFromOld[4]][6].first == Approx(5.00).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[4]][7].second == newFromOld[5]); + REQUIRE(sortedOutput[newFromOld[4]][7].first == Approx(5.27).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[4]][8].second == newFromOld[7]); + REQUIRE(sortedOutput[newFromOld[4]][8].first == Approx(6.35).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[4]][9].second == newFromOld[6]); + REQUIRE(sortedOutput[newFromOld[4]][9].first == Approx(7.05).epsilon(1e-7)); // Neighbors of point 5. - BOOST_REQUIRE(sortedOutput[newFromOld[5]].size() == 6); - BOOST_REQUIRE(sortedOutput[newFromOld[5]][0].second == newFromOld[7]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[5]][0].first, 1.08, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[5]][1].second == newFromOld[9]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[5]][1].first, 1.12, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[5]][2].second == newFromOld[10]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[5]][2].first, 1.22, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[5]][3].second == newFromOld[3]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[5]][3].first, 1.47, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[5]][4].second == newFromOld[6]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[5]][4].first, 1.78, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[5]][5].second == newFromOld[4]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[5]][5].first, 5.27, 1e-5); + REQUIRE(sortedOutput[newFromOld[5]].size() == 6); + REQUIRE(sortedOutput[newFromOld[5]][0].second == newFromOld[7]); + REQUIRE(sortedOutput[newFromOld[5]][0].first == Approx(1.08).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[5]][1].second == newFromOld[9]); + REQUIRE(sortedOutput[newFromOld[5]][1].first == Approx(1.12).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[5]][2].second == newFromOld[10]); + REQUIRE(sortedOutput[newFromOld[5]][2].first == Approx(1.22).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[5]][3].second == newFromOld[3]); + REQUIRE(sortedOutput[newFromOld[5]][3].first == Approx(1.47).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[5]][4].second == newFromOld[6]); + REQUIRE(sortedOutput[newFromOld[5]][4].first == Approx(1.78).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[5]][5].second == newFromOld[4]); + REQUIRE(sortedOutput[newFromOld[5]][5].first == Approx(5.27).epsilon(1e-7)); // Neighbors of point 6. - BOOST_REQUIRE(sortedOutput[newFromOld[6]].size() == 9); - BOOST_REQUIRE(sortedOutput[newFromOld[6]][0].second == newFromOld[5]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[6]][0].first, 1.78, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[6]][1].second == newFromOld[0]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[6]][1].first, 2.05, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[6]][2].second == newFromOld[2]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[6]][2].first, 2.15, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[6]][3].second == newFromOld[1]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[6]][3].first, 2.35, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[6]][4].second == newFromOld[8]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[6]][4].first, 2.45, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[6]][5].second == newFromOld[9]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[6]][5].first, 2.90, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[6]][6].second == newFromOld[10]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[6]][6].first, 3.00, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[6]][7].second == newFromOld[3]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[6]][7].first, 3.25, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[6]][8].second == newFromOld[4]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[6]][8].first, 7.05, 1e-5); + REQUIRE(sortedOutput[newFromOld[6]].size() == 9); + REQUIRE(sortedOutput[newFromOld[6]][0].second == newFromOld[5]); + REQUIRE(sortedOutput[newFromOld[6]][0].first == Approx(1.78).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[6]][1].second == newFromOld[0]); + REQUIRE(sortedOutput[newFromOld[6]][1].first == Approx(2.05).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[6]][2].second == newFromOld[2]); + REQUIRE(sortedOutput[newFromOld[6]][2].first == Approx(2.15).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[6]][3].second == newFromOld[1]); + REQUIRE(sortedOutput[newFromOld[6]][3].first == Approx(2.35).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[6]][4].second == newFromOld[8]); + REQUIRE(sortedOutput[newFromOld[6]][4].first == Approx(2.45).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[6]][5].second == newFromOld[9]); + REQUIRE(sortedOutput[newFromOld[6]][5].first == Approx(2.90).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[6]][6].second == newFromOld[10]); + REQUIRE(sortedOutput[newFromOld[6]][6].first == Approx(3.00).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[6]][7].second == newFromOld[3]); + REQUIRE(sortedOutput[newFromOld[6]][7].first == Approx(3.25).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[6]][8].second == newFromOld[4]); + REQUIRE(sortedOutput[newFromOld[6]][8].first == Approx(7.05).epsilon(1e-7)); // Neighbors of point 7. - BOOST_REQUIRE(sortedOutput[newFromOld[7]].size() == 9); - BOOST_REQUIRE(sortedOutput[newFromOld[7]][0].second == newFromOld[5]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[7]][0].first, 1.08, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[7]][1].second == newFromOld[0]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[7]][1].first, 1.35, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[7]][2].second == newFromOld[2]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[7]][2].first, 1.45, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[7]][3].second == newFromOld[1]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[7]][3].first, 1.65, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[7]][4].second == newFromOld[8]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[7]][4].first, 1.75, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[7]][5].second == newFromOld[9]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[7]][5].first, 2.20, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[7]][6].second == newFromOld[10]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[7]][6].first, 2.30, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[7]][7].second == newFromOld[3]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[7]][7].first, 2.55, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[7]][8].second == newFromOld[4]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[7]][8].first, 6.35, 1e-5); + REQUIRE(sortedOutput[newFromOld[7]].size() == 9); + REQUIRE(sortedOutput[newFromOld[7]][0].second == newFromOld[5]); + REQUIRE(sortedOutput[newFromOld[7]][0].first == Approx(1.08).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[7]][1].second == newFromOld[0]); + REQUIRE(sortedOutput[newFromOld[7]][1].first == Approx(1.35).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[7]][2].second == newFromOld[2]); + REQUIRE(sortedOutput[newFromOld[7]][2].first == Approx(1.45).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[7]][3].second == newFromOld[1]); + REQUIRE(sortedOutput[newFromOld[7]][3].first == Approx(1.65).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[7]][4].second == newFromOld[8]); + REQUIRE(sortedOutput[newFromOld[7]][4].first == Approx(1.75).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[7]][5].second == newFromOld[9]); + REQUIRE(sortedOutput[newFromOld[7]][5].first == Approx(2.20).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[7]][6].second == newFromOld[10]); + REQUIRE(sortedOutput[newFromOld[7]][6].first == Approx(2.30).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[7]][7].second == newFromOld[3]); + REQUIRE(sortedOutput[newFromOld[7]][7].first == Approx(2.55).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[7]][8].second == newFromOld[4]); + REQUIRE(sortedOutput[newFromOld[7]][8].first == Approx(6.35).epsilon(1e-7)); // Neighbors of point 8. - BOOST_REQUIRE(sortedOutput[newFromOld[8]].size() == 3); - BOOST_REQUIRE(sortedOutput[newFromOld[8]][0].second == newFromOld[7]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[8]][0].first, 1.75, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[8]][1].second == newFromOld[6]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[8]][1].first, 2.45, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[8]][2].second == newFromOld[4]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[8]][2].first, 4.60, 1e-5); + REQUIRE(sortedOutput[newFromOld[8]].size() == 3); + REQUIRE(sortedOutput[newFromOld[8]][0].second == newFromOld[7]); + REQUIRE(sortedOutput[newFromOld[8]][0].first == Approx(1.75).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[8]][1].second == newFromOld[6]); + REQUIRE(sortedOutput[newFromOld[8]][1].first == Approx(2.45).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[8]][2].second == newFromOld[4]); + REQUIRE(sortedOutput[newFromOld[8]][2].first == Approx(4.60).epsilon(1e-7)); // Neighbors of point 9. - BOOST_REQUIRE(sortedOutput[newFromOld[9]].size() == 4); - BOOST_REQUIRE(sortedOutput[newFromOld[9]][0].second == newFromOld[5]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[9]][0].first, 1.12, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[9]][1].second == newFromOld[7]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[9]][1].first, 2.20, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[9]][2].second == newFromOld[6]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[9]][2].first, 2.90, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[9]][3].second == newFromOld[4]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[9]][3].first, 4.15, 1e-5); + REQUIRE(sortedOutput[newFromOld[9]].size() == 4); + REQUIRE(sortedOutput[newFromOld[9]][0].second == newFromOld[5]); + REQUIRE(sortedOutput[newFromOld[9]][0].first == Approx(1.12).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[9]][1].second == newFromOld[7]); + REQUIRE(sortedOutput[newFromOld[9]][1].first == Approx(2.20).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[9]][2].second == newFromOld[6]); + REQUIRE(sortedOutput[newFromOld[9]][2].first == Approx(2.90).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[9]][3].second == newFromOld[4]); + REQUIRE(sortedOutput[newFromOld[9]][3].first == Approx(4.15).epsilon(1e-7)); // Neighbors of point 10. - BOOST_REQUIRE(sortedOutput[newFromOld[10]].size() == 4); - BOOST_REQUIRE(sortedOutput[newFromOld[10]][0].second == newFromOld[5]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[10]][0].first, 1.22, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[10]][1].second == newFromOld[7]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[10]][1].first, 2.30, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[10]][2].second == newFromOld[6]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[10]][2].first, 3.00, 1e-5); - BOOST_REQUIRE(sortedOutput[newFromOld[10]][3].second == newFromOld[4]); - BOOST_REQUIRE_CLOSE(sortedOutput[newFromOld[10]][3].first, 4.05, 1e-5); + REQUIRE(sortedOutput[newFromOld[10]].size() == 4); + REQUIRE(sortedOutput[newFromOld[10]][0].second == newFromOld[5]); + REQUIRE(sortedOutput[newFromOld[10]][0].first == Approx(1.22).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[10]][1].second == newFromOld[7]); + REQUIRE(sortedOutput[newFromOld[10]][1].first == Approx(2.30).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[10]][2].second == newFromOld[6]); + REQUIRE(sortedOutput[newFromOld[10]][2].first == Approx(3.00).epsilon(1e-7)); + REQUIRE(sortedOutput[newFromOld[10]][3].second == newFromOld[4]); + REQUIRE(sortedOutput[newFromOld[10]][3].first == Approx(4.05).epsilon(1e-7)); // Clean the memory. delete rs; @@ -455,13 +454,13 @@ BOOST_AUTO_TEST_CASE(ExhaustiveSyntheticTest) * * Errors are produced if the results are not identical. */ -BOOST_AUTO_TEST_CASE(DualTreeVsNaive1) +TEST_CASE("DualTreeVsNaive1", "[RangeSearchTest]") { arma::mat dataForTree; // Hard-coded filename: bad! if (!data::Load("test_data_3_1000.csv", dataForTree)) - BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!"); + FAIL("Cannot load test dataset test_data_3_1000.csv!"); // Set up matrices to work with. arma::mat dualQuery(dataForTree); @@ -487,13 +486,13 @@ BOOST_AUTO_TEST_CASE(DualTreeVsNaive1) for (size_t i = 0; i < sortedTree.size(); ++i) { - BOOST_REQUIRE(sortedTree[i].size() == sortedNaive[i].size()); + REQUIRE(sortedTree[i].size() == sortedNaive[i].size()); for (size_t j = 0; j < sortedTree[i].size(); ++j) { - BOOST_REQUIRE(sortedTree[i][j].second == sortedNaive[i][j].second); - BOOST_REQUIRE_CLOSE(sortedTree[i][j].first, sortedNaive[i][j].first, - 1e-5); + REQUIRE(sortedTree[i][j].second == sortedNaive[i][j].second); + REQUIRE(sortedTree[i][j].first == + Approx(sortedNaive[i][j].first).epsilon(1e-7)); } } } @@ -504,14 +503,14 @@ BOOST_AUTO_TEST_CASE(DualTreeVsNaive1) * * Errors are produced if the results are not identical. */ -BOOST_AUTO_TEST_CASE(DualTreeVsNaive2) +TEST_CASE("DualTreeVsNaive2", "[RangeSearchTest]") { arma::mat dataForTree; // Hard-coded filename: bad! // Code duplication: also bad! if (!data::Load("test_data_3_1000.csv", dataForTree)) - BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!"); + FAIL("Cannot load test dataset test_data_3_1000.csv!"); // Set up matrices to work with. arma::mat dualQuery(dataForTree); @@ -536,13 +535,13 @@ BOOST_AUTO_TEST_CASE(DualTreeVsNaive2) for (size_t i = 0; i < sortedTree.size(); ++i) { - BOOST_REQUIRE(sortedTree[i].size() == sortedNaive[i].size()); + REQUIRE(sortedTree[i].size() == sortedNaive[i].size()); for (size_t j = 0; j < sortedTree[i].size(); ++j) { - BOOST_REQUIRE(sortedTree[i][j].second == sortedNaive[i][j].second); - BOOST_REQUIRE_CLOSE(sortedTree[i][j].first, sortedNaive[i][j].first, - 1e-5); + REQUIRE(sortedTree[i][j].second == sortedNaive[i][j].second); + REQUIRE(sortedTree[i][j].first == + Approx(sortedNaive[i][j].first).epsilon(1e-7)); } } } @@ -553,14 +552,14 @@ BOOST_AUTO_TEST_CASE(DualTreeVsNaive2) * * Errors are produced if the results are not identical. */ -BOOST_AUTO_TEST_CASE(SingleTreeVsNaive) +TEST_CASE("SingleTreeVsNaive", "[RangeSearchTest]") { arma::mat dataForTree; // Hard-coded filename: bad! // Code duplication: also bad! if (!data::Load("test_data_3_1000.csv", dataForTree)) - BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!"); + FAIL("Cannot load test dataset test_data_3_1000.csv!"); // Set up matrices to work with (may not be necessary with no ALIAS_MATRIX?). arma::mat singleQuery(dataForTree); @@ -585,13 +584,13 @@ BOOST_AUTO_TEST_CASE(SingleTreeVsNaive) for (size_t i = 0; i < sortedTree.size(); ++i) { - BOOST_REQUIRE(sortedTree[i].size() == sortedNaive[i].size()); + REQUIRE(sortedTree[i].size() == sortedNaive[i].size()); for (size_t j = 0; j < sortedTree[i].size(); ++j) { - BOOST_REQUIRE(sortedTree[i][j].second == sortedNaive[i][j].second); - BOOST_REQUIRE_CLOSE(sortedTree[i][j].first, sortedNaive[i][j].first, - 1e-5); + REQUIRE(sortedTree[i][j].second == sortedNaive[i][j].second); + REQUIRE(sortedTree[i][j].first == + Approx(sortedNaive[i][j].first).epsilon(1e-7)); } } } @@ -600,7 +599,7 @@ BOOST_AUTO_TEST_CASE(SingleTreeVsNaive) * Ensure that dual tree range search with cover trees works by comparing * with the kd-tree implementation. */ -BOOST_AUTO_TEST_CASE(CoverTreeTest) +TEST_CASE("CoverTreeTest", "[RangeSearchTest]") { arma::mat data; data.randu(8, 1000); // 1000 points in 8 dimensions. @@ -662,11 +661,11 @@ BOOST_AUTO_TEST_CASE(CoverTreeTest) { for (size_t j = 0; j < kdSorted[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(kdSorted[i][j].second, coverSorted[i][j].second); - BOOST_REQUIRE_CLOSE(kdSorted[i][j].first, coverSorted[i][j].first, - 1e-5); + REQUIRE(kdSorted[i][j].second == coverSorted[i][j].second); + REQUIRE(kdSorted[i][j].first == + Approx(coverSorted[i][j].first).epsilon(1e-7)); } - BOOST_REQUIRE_EQUAL(kdSorted[i].size(), coverSorted[i].size()); + REQUIRE(kdSorted[i].size() == coverSorted[i].size()); } } } @@ -675,7 +674,7 @@ BOOST_AUTO_TEST_CASE(CoverTreeTest) * Ensure that dual tree range search with cover trees works when using * two datasets. */ -BOOST_AUTO_TEST_CASE(CoverTreeTwoDatasetsTest) +TEST_CASE("CoverTreeTwoDatasetsTest", "[RangeSearchTest]") { arma::mat data; data.randu(8, 1000); // 1000 points in 8 dimensions. @@ -740,11 +739,11 @@ BOOST_AUTO_TEST_CASE(CoverTreeTwoDatasetsTest) { for (size_t j = 0; j < kdSorted[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(kdSorted[i][j].second, coverSorted[i][j].second); - BOOST_REQUIRE_CLOSE(kdSorted[i][j].first, coverSorted[i][j].first, - 1e-5); + REQUIRE(kdSorted[i][j].second == coverSorted[i][j].second); + REQUIRE(kdSorted[i][j].first == + Approx(coverSorted[i][j].first).epsilon(1e-7)); } - BOOST_REQUIRE_EQUAL(kdSorted[i].size(), coverSorted[i].size()); + REQUIRE(kdSorted[i].size() == coverSorted[i].size()); } } } @@ -752,7 +751,7 @@ BOOST_AUTO_TEST_CASE(CoverTreeTwoDatasetsTest) /** * Ensure that single-tree cover tree range search works. */ -BOOST_AUTO_TEST_CASE(CoverTreeSingleTreeTest) +TEST_CASE("CoverTreeSingleTreeTest", "[RangeSearchTest]") { arma::mat data; data.randu(8, 1000); // 1000 points in 8 dimensions. @@ -814,11 +813,11 @@ BOOST_AUTO_TEST_CASE(CoverTreeSingleTreeTest) { for (size_t j = 0; j < kdSorted[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(kdSorted[i][j].second, coverSorted[i][j].second); - BOOST_REQUIRE_CLOSE(kdSorted[i][j].first, coverSorted[i][j].first, - 1e-5); + REQUIRE(kdSorted[i][j].second == coverSorted[i][j].second); + REQUIRE(kdSorted[i][j].first == + Approx(coverSorted[i][j].first).epsilon(1e-7)); } - BOOST_REQUIRE_EQUAL(kdSorted[i].size(), coverSorted[i].size()); + REQUIRE(kdSorted[i].size() == coverSorted[i].size()); } } } @@ -826,7 +825,7 @@ BOOST_AUTO_TEST_CASE(CoverTreeSingleTreeTest) /** * Ensure that single-tree ball tree range search works. */ -BOOST_AUTO_TEST_CASE(SingleBallTreeTest) +TEST_CASE("SingleBallTreeTest", "[RangeSearchTest]") { arma::mat data; data.randu(8, 1000); // 1000 points in 8 dimensions. @@ -888,11 +887,11 @@ BOOST_AUTO_TEST_CASE(SingleBallTreeTest) { for (size_t j = 0; j < kdSorted[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(kdSorted[i][j].second, ballSorted[i][j].second); - BOOST_REQUIRE_CLOSE(kdSorted[i][j].first, ballSorted[i][j].first, - 1e-5); + REQUIRE(kdSorted[i][j].second == ballSorted[i][j].second); + REQUIRE(kdSorted[i][j].first == + Approx(ballSorted[i][j].first).epsilon(1e-7)); } - BOOST_REQUIRE_EQUAL(kdSorted[i].size(), ballSorted[i].size()); + REQUIRE(kdSorted[i].size() == ballSorted[i].size()); } } } @@ -901,7 +900,7 @@ BOOST_AUTO_TEST_CASE(SingleBallTreeTest) * Ensure that dual tree range search with ball trees works by comparing * with the kd-tree implementation. */ -BOOST_AUTO_TEST_CASE(DualBallTreeTest) +TEST_CASE("DualBallTreeTest", "[RangeSearchTest]") { arma::mat data; data.randu(8, 1000); // 1000 points in 8 dimensions. @@ -962,11 +961,11 @@ BOOST_AUTO_TEST_CASE(DualBallTreeTest) { for (size_t j = 0; j < kdSorted[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(kdSorted[i][j].second, ballSorted[i][j].second); - BOOST_REQUIRE_CLOSE(kdSorted[i][j].first, ballSorted[i][j].first, - 1e-5); + REQUIRE(kdSorted[i][j].second == ballSorted[i][j].second); + REQUIRE(kdSorted[i][j].first == + Approx(ballSorted[i][j].first).epsilon(1e-7)); } - BOOST_REQUIRE_EQUAL(kdSorted[i].size(), ballSorted[i].size()); + REQUIRE(kdSorted[i].size() == ballSorted[i].size()); } } } @@ -975,7 +974,7 @@ BOOST_AUTO_TEST_CASE(DualBallTreeTest) * Ensure that dual tree range search with ball trees works when using * two datasets. */ -BOOST_AUTO_TEST_CASE(DualBallTreeTest2) +TEST_CASE("DualBallTreeTest2", "[RangeSearchTest]") { arma::mat data; data.randu(8, 1000); // 1000 points in 8 dimensions. @@ -1038,12 +1037,12 @@ BOOST_AUTO_TEST_CASE(DualBallTreeTest2) // Now compare the results. for (size_t i = 0; i < kdSorted.size(); ++i) { - BOOST_REQUIRE_EQUAL(kdSorted[i].size(), ballSorted[i].size()); + REQUIRE(kdSorted[i].size() == ballSorted[i].size()); for (size_t j = 0; j < kdSorted[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(kdSorted[i][j].second, ballSorted[i][j].second); - BOOST_REQUIRE_CLOSE(kdSorted[i][j].first, ballSorted[i][j].first, - 1e-5); + REQUIRE(kdSorted[i][j].second == ballSorted[i][j].second); + REQUIRE(kdSorted[i][j].first == + Approx(ballSorted[i][j].first).epsilon (1e-7)); } } } @@ -1053,7 +1052,7 @@ BOOST_AUTO_TEST_CASE(DualBallTreeTest2) * Make sure that no results are returned when we build a range search object * with no reference set. */ -BOOST_AUTO_TEST_CASE(EmptySearchTest) +TEST_CASE("EmptySearchTest", "[RangeSearchTest]") { RangeSearch rs; @@ -1062,20 +1061,20 @@ BOOST_AUTO_TEST_CASE(EmptySearchTest) rs.Search(math::Range(0.0, 10.0), neighbors, distances); - BOOST_REQUIRE_EQUAL(neighbors.size(), 0); - BOOST_REQUIRE_EQUAL(distances.size(), 0); + REQUIRE(neighbors.size() == 0); + REQUIRE(distances.size() == 0); // Now check with a query set. arma::mat querySet = arma::randu(3, 100); - BOOST_REQUIRE_THROW(rs.Search(querySet, math::Range(0.0, 10.0), neighbors, + REQUIRE_THROWS_AS(rs.Search(querySet, math::Range(0.0, 10.0), neighbors, distances), std::invalid_argument); } /** * Make sure things work right after Train() is called. */ -BOOST_AUTO_TEST_CASE(TrainTest) +TEST_CASE("RangeSearchTrainTest", "[RangeSearchTest]") { RangeSearch<> empty; @@ -1090,8 +1089,8 @@ BOOST_AUTO_TEST_CASE(TrainTest) empty.Search(math::Range(0.5, 0.7), neighbors, distances); baseline.Search(math::Range(0.5, 0.7), baselineNeighbors, baselineDistances); - BOOST_REQUIRE_EQUAL(neighbors.size(), baselineNeighbors.size()); - BOOST_REQUIRE_EQUAL(distances.size(), baselineDistances.size()); + REQUIRE(neighbors.size() == baselineNeighbors.size()); + REQUIRE(distances.size() == baselineDistances.size()); // Sort the results before comparing. vector>> sorted; @@ -1101,11 +1100,12 @@ BOOST_AUTO_TEST_CASE(TrainTest) for (size_t i = 0; i < sorted.size(); ++i) { - BOOST_REQUIRE_EQUAL(sorted[i].size(), baselineSorted[i].size()); + REQUIRE(sorted[i].size() == baselineSorted[i].size()); for (size_t j = 0; j < sorted[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(sorted[i][j].second, baselineSorted[i][j].second); - BOOST_REQUIRE_CLOSE(sorted[i][j].first, baselineSorted[i][j].first, 1e-5); + REQUIRE(sorted[i][j].second == baselineSorted[i][j].second); + REQUIRE(sorted[i][j].first == + Approx(baselineSorted[i][j].first).epsilon(1e-7)); } } } @@ -1113,7 +1113,7 @@ BOOST_AUTO_TEST_CASE(TrainTest) /** * Test training when a tree is given. */ -BOOST_AUTO_TEST_CASE(TrainTreeTest) +TEST_CASE("TrainTreeTest", "[RangeSearchTest]") { // Avoid mappings by using the cover tree. typedef RangeSearch RSType; @@ -1131,8 +1131,8 @@ BOOST_AUTO_TEST_CASE(TrainTreeTest) empty.Search(math::Range(0.5, 0.7), neighbors, distances); baseline.Search(math::Range(0.5, 0.7), baselineNeighbors, baselineDistances); - BOOST_REQUIRE_EQUAL(neighbors.size(), baselineNeighbors.size()); - BOOST_REQUIRE_EQUAL(distances.size(), baselineDistances.size()); + REQUIRE(neighbors.size() == baselineNeighbors.size()); + REQUIRE(distances.size() == baselineDistances.size()); // Sort the results before comparing. vector>> sorted; @@ -1142,11 +1142,12 @@ BOOST_AUTO_TEST_CASE(TrainTreeTest) for (size_t i = 0; i < sorted.size(); ++i) { - BOOST_REQUIRE_EQUAL(sorted[i].size(), baselineSorted[i].size()); + REQUIRE(sorted[i].size() == baselineSorted[i].size()); for (size_t j = 0; j < sorted[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(sorted[i][j].second, baselineSorted[i][j].second); - BOOST_REQUIRE_CLOSE(sorted[i][j].first, baselineSorted[i][j].first, 1e-5); + REQUIRE(sorted[i][j].second == baselineSorted[i][j].second); + REQUIRE(sorted[i][j].first == + Approx(baselineSorted[i][j].first).epsilon(1e-7)); } } } @@ -1154,20 +1155,20 @@ BOOST_AUTO_TEST_CASE(TrainTreeTest) /** * Test that training with a tree throws an exception when in naive mode. */ -BOOST_AUTO_TEST_CASE(NaiveTrainTreeTest) +TEST_CASE("NaiveTrainTreeTest", "[RangeSearchTest]") { RangeSearch<> empty(true); arma::mat dataset = arma::randu(5, 100); RangeSearch<>::Tree tree(dataset); - BOOST_REQUIRE_THROW(empty.Train(&tree), std::invalid_argument); + REQUIRE_THROWS_AS(empty.Train(&tree), std::invalid_argument); } /** * Test that the move constructor works. */ -BOOST_AUTO_TEST_CASE(MoveConstructorMatrixTest) +TEST_CASE("MoveConstructorMatrixTest", "[RangeSearchTest]") { arma::mat dataset = arma::randu(3, 100); arma::mat copy(dataset); @@ -1175,9 +1176,9 @@ BOOST_AUTO_TEST_CASE(MoveConstructorMatrixTest) RangeSearch<> movers(std::move(copy)); RangeSearch<> rs(dataset); - BOOST_REQUIRE_EQUAL(copy.n_elem, 0); - BOOST_REQUIRE_EQUAL(movers.ReferenceSet().n_rows, 3); - BOOST_REQUIRE_EQUAL(movers.ReferenceSet().n_cols, 100); + REQUIRE(copy.n_elem == 0); + REQUIRE(movers.ReferenceSet().n_rows == 3); + REQUIRE(movers.ReferenceSet().n_cols == 100); vector> moveNeighbors, neighbors; vector> moveDistances, distances; @@ -1185,8 +1186,8 @@ BOOST_AUTO_TEST_CASE(MoveConstructorMatrixTest) movers.Search(math::Range(0.5, 0.7), moveNeighbors, moveDistances); rs.Search(math::Range(0.5, 0.7), neighbors, distances); - BOOST_REQUIRE_EQUAL(neighbors.size(), moveNeighbors.size()); - BOOST_REQUIRE_EQUAL(distances.size(), moveDistances.size()); + REQUIRE(neighbors.size() == moveNeighbors.size()); + REQUIRE(distances.size() == moveDistances.size()); // Sort the results before comparing. vector>> sorted; @@ -1196,11 +1197,12 @@ BOOST_AUTO_TEST_CASE(MoveConstructorMatrixTest) for (size_t i = 0; i < sorted.size(); ++i) { - BOOST_REQUIRE_EQUAL(sorted[i].size(), moveSorted[i].size()); + REQUIRE(sorted[i].size() == moveSorted[i].size()); for (size_t j = 0; j < sorted[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(sorted[i][j].second, moveSorted[i][j].second); - BOOST_REQUIRE_CLOSE(sorted[i][j].first, moveSorted[i][j].first, 1e-5); + REQUIRE(sorted[i][j].second == moveSorted[i][j].second); + REQUIRE(sorted[i][j].first == + Approx(moveSorted[i][j].first).epsilon(1e-7)); } } } @@ -1208,7 +1210,7 @@ BOOST_AUTO_TEST_CASE(MoveConstructorMatrixTest) /** * Test that the std::move() Train() function works. */ -BOOST_AUTO_TEST_CASE(MoveTrainTest) +TEST_CASE("MoveTrainTest", "[RangeSearchTest]") { arma::mat dataset = arma::randu(3, 100); arma::mat copy(dataset); @@ -1217,9 +1219,9 @@ BOOST_AUTO_TEST_CASE(MoveTrainTest) movers.Train(std::move(copy)); RangeSearch<> rs(dataset); - BOOST_REQUIRE_EQUAL(copy.n_elem, 0); - BOOST_REQUIRE_EQUAL(movers.ReferenceSet().n_rows, 3); - BOOST_REQUIRE_EQUAL(movers.ReferenceSet().n_cols, 100); + REQUIRE(copy.n_elem == 0); + REQUIRE(movers.ReferenceSet().n_rows == 3); + REQUIRE(movers.ReferenceSet().n_cols == 100); vector> moveNeighbors, neighbors; vector> moveDistances, distances; @@ -1227,8 +1229,8 @@ BOOST_AUTO_TEST_CASE(MoveTrainTest) movers.Search(math::Range(0.5, 0.7), moveNeighbors, moveDistances); rs.Search(math::Range(0.5, 0.7), neighbors, distances); - BOOST_REQUIRE_EQUAL(neighbors.size(), moveNeighbors.size()); - BOOST_REQUIRE_EQUAL(distances.size(), moveDistances.size()); + REQUIRE(neighbors.size() == moveNeighbors.size()); + REQUIRE(distances.size() == moveDistances.size()); // Sort the results before comparing. vector>> sorted; @@ -1238,16 +1240,17 @@ BOOST_AUTO_TEST_CASE(MoveTrainTest) for (size_t i = 0; i < sorted.size(); ++i) { - BOOST_REQUIRE_EQUAL(sorted[i].size(), moveSorted[i].size()); + REQUIRE(sorted[i].size() == moveSorted[i].size()); for (size_t j = 0; j < sorted[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(sorted[i][j].second, moveSorted[i][j].second); - BOOST_REQUIRE_CLOSE(sorted[i][j].first, moveSorted[i][j].first, 1e-5); + REQUIRE(sorted[i][j].second == moveSorted[i][j].second); + REQUIRE(sorted[i][j].first == + Approx(moveSorted[i][j].first).epsilon(1e-7)); } } } -BOOST_AUTO_TEST_CASE(RSModelTest) +TEST_CASE("RSModelTest", "[RangeSearchTest]") { // Ensure that we can build an RSModel and get correct results. arma::mat queryData = arma::randu(10, 50); @@ -1284,7 +1287,7 @@ BOOST_AUTO_TEST_CASE(RSModelTest) models[26] = RSModel(RSModel::TreeTypes::OCTREE, true); models[27] = RSModel(RSModel::TreeTypes::OCTREE, false); - for (size_t j = 0; j < 2; ++j) + for (size_t j = 0; j < 3; ++j) { // Get a baseline. RangeSearch<> rs(referenceData); @@ -1314,27 +1317,27 @@ BOOST_AUTO_TEST_CASE(RSModelTest) models[i].Search(std::move(queryCopy), math::Range(0.25, 0.75), neighbors, distances); - BOOST_REQUIRE_EQUAL(neighbors.size(), baselineNeighbors.size()); - BOOST_REQUIRE_EQUAL(distances.size(), baselineDistances.size()); + REQUIRE(neighbors.size() == baselineNeighbors.size()); + REQUIRE(distances.size() == baselineDistances.size()); vector>> sorted; SortResults(neighbors, distances, sorted); for (size_t k = 0; k < sorted.size(); ++k) { - BOOST_REQUIRE_EQUAL(sorted[k].size(), baselineSorted[k].size()); + REQUIRE(sorted[k].size() == baselineSorted[k].size()); for (size_t l = 0; l < sorted[k].size(); ++l) { - BOOST_REQUIRE_EQUAL(sorted[k][l].second, baselineSorted[k][l].second); - BOOST_REQUIRE_CLOSE(sorted[k][l].first, baselineSorted[k][l].first, - 1e-5); + REQUIRE(sorted[k][l].second == baselineSorted[k][l].second); + REQUIRE(sorted[k][l].first == + Approx(baselineSorted[k][l].first).epsilon(1e-7)); } } } } } -BOOST_AUTO_TEST_CASE(RSModelMonochromaticTest) +TEST_CASE("RSModelMonochromaticTest", "[RangeSearchTest]") { // Ensure that we can build an RSModel and get correct results. arma::mat referenceData = arma::randu(10, 200); @@ -1370,7 +1373,7 @@ BOOST_AUTO_TEST_CASE(RSModelMonochromaticTest) models[26] = RSModel(RSModel::TreeTypes::OCTREE, true); models[27] = RSModel(RSModel::TreeTypes::OCTREE, false); - for (size_t j = 0; j < 2; ++j) + for (size_t j = 0; j < 3; ++j) { // Get a baseline. RangeSearch<> rs(referenceData); @@ -1397,20 +1400,20 @@ BOOST_AUTO_TEST_CASE(RSModelMonochromaticTest) models[i].Search(math::Range(0.25, 0.5), neighbors, distances); - BOOST_REQUIRE_EQUAL(neighbors.size(), baselineNeighbors.size()); - BOOST_REQUIRE_EQUAL(distances.size(), baselineDistances.size()); + REQUIRE(neighbors.size() == baselineNeighbors.size()); + REQUIRE(distances.size() == baselineDistances.size()); vector>> sorted; SortResults(neighbors, distances, sorted); for (size_t k = 0; k < sorted.size(); ++k) { - BOOST_REQUIRE_EQUAL(sorted[k].size(), baselineSorted[k].size()); + REQUIRE(sorted[k].size() == baselineSorted[k].size()); for (size_t l = 0; l < sorted[k].size(); ++l) { - BOOST_REQUIRE_EQUAL(sorted[k][l].second, baselineSorted[k][l].second); - BOOST_REQUIRE_CLOSE(sorted[k][l].first, baselineSorted[k][l].first, - 1e-5); + REQUIRE(sorted[k][l].second == baselineSorted[k][l].second); + REQUIRE(sorted[k][l].first == + Approx(baselineSorted[k][l].first).epsilon(1e-7)); } } } @@ -1421,7 +1424,7 @@ BOOST_AUTO_TEST_CASE(RSModelMonochromaticTest) * Make sure that the neighborPtr matrix isn't accidentally deleted. * See issue #478. */ -BOOST_AUTO_TEST_CASE(NeighborPtrDeleteTest) +TEST_CASE("NeighborPtrDeleteTest", "[RangeSearchTest]") { arma::mat dataset = arma::randu(5, 100); @@ -1438,14 +1441,14 @@ BOOST_AUTO_TEST_CASE(NeighborPtrDeleteTest) // These will (hopefully) fail is either the neighbors or the distances matrix // has been accidentally deleted. - BOOST_REQUIRE_EQUAL(neighbors.size(), 50); - BOOST_REQUIRE_EQUAL(distances.size(), 50); + REQUIRE(neighbors.size() == 50); + REQUIRE(distances.size() == 50); } /** * Test copy constructor and copy operator. */ -BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorTest) +TEST_CASE("RangeSearchCopyConstructorAndOperatorTest", "[RangeSearchTest]") { arma::mat dataset = arma::randu(5, 500); RangeSearch<> rs(std::move(dataset)); @@ -1463,26 +1466,26 @@ BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorTest) rs3.Search(math::Range(0.2, 0.3), neighbors3, distances3); // Check results. - BOOST_REQUIRE_EQUAL(distances.size(), distances2.size()); - BOOST_REQUIRE_EQUAL(distances.size(), distances3.size()); - BOOST_REQUIRE_EQUAL(neighbors.size(), neighbors2.size()); - BOOST_REQUIRE_EQUAL(neighbors.size(), neighbors3.size()); + REQUIRE(distances.size() == distances2.size()); + REQUIRE(distances.size() == distances3.size()); + REQUIRE(neighbors.size() == neighbors2.size()); + REQUIRE(neighbors.size() == neighbors3.size()); for (size_t i = 0; i < neighbors.size(); ++i) { - BOOST_REQUIRE_EQUAL(distances[i].size(), distances2[i].size()); - BOOST_REQUIRE_EQUAL(distances[i].size(), distances3[i].size()); - BOOST_REQUIRE_EQUAL(neighbors[i].size(), neighbors2[i].size()); - BOOST_REQUIRE_EQUAL(neighbors[i].size(), neighbors3[i].size()); + REQUIRE(distances[i].size() == distances2[i].size()); + REQUIRE(distances[i].size() == distances3[i].size()); + REQUIRE(neighbors[i].size() == neighbors2[i].size()); + REQUIRE(neighbors[i].size() == neighbors3[i].size()); for (size_t j = 0; j < neighbors[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(neighbors[i][j], neighbors2[i][j]); - BOOST_REQUIRE_EQUAL(neighbors[i][j], neighbors3[i][j]); + REQUIRE(neighbors[i][j] == neighbors2[i][j]); + REQUIRE(neighbors[i][j] == neighbors3[i][j]); // Distances will always be between 0.2 and 0.3. - BOOST_REQUIRE_CLOSE(distances[i][j], distances2[i][j], 1e-5); - BOOST_REQUIRE_CLOSE(distances[i][j], distances3[i][j], 1e-5); + REQUIRE(distances[i][j] == Approx(distances2[i][j]).epsilon(1e-7)); + REQUIRE(distances[i][j] == Approx(distances3[i][j]).epsilon(1e-7)); } } } @@ -1490,7 +1493,7 @@ BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorTest) /** * Test move constructor. */ -BOOST_AUTO_TEST_CASE(MoveConstructorTest) +TEST_CASE("RangeSearchMoveConstructorTest", "[RangeSearchTest]") { arma::mat dataset = arma::randu(5, 500); RangeSearch<>* rs = new RangeSearch<>(std::move(dataset)); @@ -1508,20 +1511,20 @@ BOOST_AUTO_TEST_CASE(MoveConstructorTest) rs2.Search(math::Range(0.2, 0.3), neighbors2, distances2); // Check results. - BOOST_REQUIRE_EQUAL(distances.size(), distances2.size()); - BOOST_REQUIRE_EQUAL(neighbors.size(), neighbors2.size()); + REQUIRE(distances.size() == distances2.size()); + REQUIRE(neighbors.size() == neighbors2.size()); for (size_t i = 0; i < neighbors.size(); ++i) { - BOOST_REQUIRE_EQUAL(distances[i].size(), distances2[i].size()); - BOOST_REQUIRE_EQUAL(neighbors[i].size(), neighbors2[i].size()); + REQUIRE(distances[i].size() == distances2[i].size()); + REQUIRE(neighbors[i].size() == neighbors2[i].size()); for (size_t j = 0; j < neighbors[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(neighbors[i][j], neighbors2[i][j]); + REQUIRE(neighbors[i][j] == neighbors2[i][j]); // Distances will always be between 0.2 and 0.3. - BOOST_REQUIRE_CLOSE(distances[i][j], distances2[i][j], 1e-5); + REQUIRE(distances[i][j] == Approx(distances2[i][j]).epsilon(1e-7)); } } } @@ -1529,7 +1532,7 @@ BOOST_AUTO_TEST_CASE(MoveConstructorTest) /** * Test move operator. */ -BOOST_AUTO_TEST_CASE(MoveOperatorTest) +TEST_CASE("RangeSearchMoveOperatorTest", "[RangeSearchTest]") { arma::mat dataset = arma::randu(5, 500); RangeSearch<>* rs = new RangeSearch<>(std::move(dataset)); @@ -1547,20 +1550,20 @@ BOOST_AUTO_TEST_CASE(MoveOperatorTest) rs2.Search(math::Range(0.2, 0.3), neighbors2, distances2); // Check results. - BOOST_REQUIRE_EQUAL(distances.size(), distances2.size()); - BOOST_REQUIRE_EQUAL(neighbors.size(), neighbors2.size()); + REQUIRE(distances.size() == distances2.size()); + REQUIRE(neighbors.size() == neighbors2.size()); for (size_t i = 0; i < neighbors.size(); ++i) { - BOOST_REQUIRE_EQUAL(distances[i].size(), distances2[i].size()); - BOOST_REQUIRE_EQUAL(neighbors[i].size(), neighbors2[i].size()); + REQUIRE(distances[i].size() == distances2[i].size()); + REQUIRE(neighbors[i].size() == neighbors2[i].size()); for (size_t j = 0; j < neighbors[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(neighbors[i][j], neighbors2[i][j]); + REQUIRE(neighbors[i][j] == neighbors2[i][j]); // Distances will always be between 0.2 and 0.3. - BOOST_REQUIRE_CLOSE(distances[i][j], distances2[i][j], 1e-5); + REQUIRE(distances[i][j] == Approx(distances2[i][j]).epsilon(1e-7)); } } } @@ -1569,7 +1572,7 @@ BOOST_AUTO_TEST_CASE(MoveOperatorTest) * Test copy constructor and copy operator in naive mode (so there are no * trees). */ -BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorNaiveTest) +TEST_CASE("CopyConstructorAndOperatorNaiveTest", "[RangeSearchTest]") { arma::mat dataset = arma::randu(5, 500); RangeSearch<> rs(std::move(dataset), true); @@ -1578,8 +1581,8 @@ BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorNaiveTest) RangeSearch<> rs2(rs); RangeSearch<> rs3 = rs; - BOOST_REQUIRE_EQUAL(rs2.Naive(), true); - BOOST_REQUIRE_EQUAL(rs3.Naive(), true); + REQUIRE(rs2.Naive() == true); + REQUIRE(rs3.Naive() == true); // Get results. vector> distances, distances2, distances3; @@ -1590,26 +1593,26 @@ BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorNaiveTest) rs3.Search(math::Range(0.2, 0.3), neighbors3, distances3); // Check results. - BOOST_REQUIRE_EQUAL(distances.size(), distances2.size()); - BOOST_REQUIRE_EQUAL(distances.size(), distances3.size()); - BOOST_REQUIRE_EQUAL(neighbors.size(), neighbors2.size()); - BOOST_REQUIRE_EQUAL(neighbors.size(), neighbors3.size()); + REQUIRE(distances.size() == distances2.size()); + REQUIRE(distances.size() == distances3.size()); + REQUIRE(neighbors.size() == neighbors2.size()); + REQUIRE(neighbors.size() == neighbors3.size()); for (size_t i = 0; i < neighbors.size(); ++i) { - BOOST_REQUIRE_EQUAL(distances[i].size(), distances2[i].size()); - BOOST_REQUIRE_EQUAL(distances[i].size(), distances3[i].size()); - BOOST_REQUIRE_EQUAL(neighbors[i].size(), neighbors2[i].size()); - BOOST_REQUIRE_EQUAL(neighbors[i].size(), neighbors3[i].size()); + REQUIRE(distances[i].size() == distances2[i].size()); + REQUIRE(distances[i].size() == distances3[i].size()); + REQUIRE(neighbors[i].size() == neighbors2[i].size()); + REQUIRE(neighbors[i].size() == neighbors3[i].size()); for (size_t j = 0; j < neighbors[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(neighbors[i][j], neighbors2[i][j]); - BOOST_REQUIRE_EQUAL(neighbors[i][j], neighbors3[i][j]); + REQUIRE(neighbors[i][j] == neighbors2[i][j]); + REQUIRE(neighbors[i][j] == neighbors3[i][j]); // Distances will always be between 0.2 and 0.3. - BOOST_REQUIRE_CLOSE(distances[i][j], distances2[i][j], 1e-5); - BOOST_REQUIRE_CLOSE(distances[i][j], distances3[i][j], 1e-5); + REQUIRE(distances[i][j] == Approx(distances2[i][j]).epsilon(1e-7)); + REQUIRE(distances[i][j] == Approx(distances3[i][j]).epsilon(1e-7)); } } } @@ -1617,7 +1620,7 @@ BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorNaiveTest) /** * Test move constructor. */ -BOOST_AUTO_TEST_CASE(MoveConstructorNaiveTest) +TEST_CASE("MoveConstructorNaiveTest", "[RangeSearchTest]") { arma::mat dataset = arma::randu(5, 500); RangeSearch<>* rs = new RangeSearch<>(std::move(dataset), true); @@ -1630,27 +1633,27 @@ BOOST_AUTO_TEST_CASE(MoveConstructorNaiveTest) RangeSearch<> rs2(std::move(*rs)); - BOOST_REQUIRE_EQUAL(rs2.Naive(), true); + REQUIRE(rs2.Naive() == true); delete rs; rs2.Search(math::Range(0.2, 0.3), neighbors2, distances2); // Check results. - BOOST_REQUIRE_EQUAL(distances.size(), distances2.size()); - BOOST_REQUIRE_EQUAL(neighbors.size(), neighbors2.size()); + REQUIRE(distances.size() == distances2.size()); + REQUIRE(neighbors.size() == neighbors2.size()); for (size_t i = 0; i < neighbors.size(); ++i) { - BOOST_REQUIRE_EQUAL(distances[i].size(), distances2[i].size()); - BOOST_REQUIRE_EQUAL(neighbors[i].size(), neighbors2[i].size()); + REQUIRE(distances[i].size() == distances2[i].size()); + REQUIRE(neighbors[i].size() == neighbors2[i].size()); for (size_t j = 0; j < neighbors[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(neighbors[i][j], neighbors2[i][j]); + REQUIRE(neighbors[i][j] == neighbors2[i][j]); // Distances will always be between 0.2 and 0.3. - BOOST_REQUIRE_CLOSE(distances[i][j], distances2[i][j], 1e-5); + REQUIRE(distances[i][j] == Approx(distances2[i][j]).epsilon(1e-7)); } } } @@ -1658,7 +1661,7 @@ BOOST_AUTO_TEST_CASE(MoveConstructorNaiveTest) /** * Test move operator. */ -BOOST_AUTO_TEST_CASE(MoveOperatorNaiveTest) +TEST_CASE("MoveOperatorNaiveTest", "[RangeSearchTest]") { arma::mat dataset = arma::randu(5, 500); RangeSearch<>* rs = new RangeSearch<>(std::move(dataset), true); @@ -1671,29 +1674,27 @@ BOOST_AUTO_TEST_CASE(MoveOperatorNaiveTest) RangeSearch<> rs2 = std::move(*rs); - BOOST_REQUIRE_EQUAL(rs2.Naive(), true); + REQUIRE(rs2.Naive() == true); delete rs; rs2.Search(math::Range(0.2, 0.3), neighbors2, distances2); // Check results. - BOOST_REQUIRE_EQUAL(distances.size(), distances2.size()); - BOOST_REQUIRE_EQUAL(neighbors.size(), neighbors2.size()); + REQUIRE(distances.size() == distances2.size()); + REQUIRE(neighbors.size() == neighbors2.size()); for (size_t i = 0; i < neighbors.size(); ++i) { - BOOST_REQUIRE_EQUAL(distances[i].size(), distances2[i].size()); - BOOST_REQUIRE_EQUAL(neighbors[i].size(), neighbors2[i].size()); + REQUIRE(distances[i].size() == distances2[i].size()); + REQUIRE(neighbors[i].size() == neighbors2[i].size()); for (size_t j = 0; j < neighbors[i].size(); ++j) { - BOOST_REQUIRE_EQUAL(neighbors[i][j], neighbors2[i][j]); + REQUIRE(neighbors[i][j] == neighbors2[i][j]); // Distances will always be between 0.2 and 0.3. - BOOST_REQUIRE_CLOSE(distances[i][j], distances2[i][j], 1e-5); + REQUIRE(distances[i][j] == Approx(distances2[i][j]).epsilon(1e-7)); } } } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/rectangle_tree_test.cpp b/src/mlpack/tests/rectangle_tree_test.cpp index 63117bd858..aa487df94f 100644 --- a/src/mlpack/tests/rectangle_tree_test.cpp +++ b/src/mlpack/tests/rectangle_tree_test.cpp @@ -16,35 +16,33 @@ #include #include -#include -#include "test_tools.hpp" +#include "catch.hpp" +#include "test_catch_tools.hpp" using namespace mlpack; using namespace mlpack::neighbor; using namespace mlpack::tree; using namespace mlpack::metric; -BOOST_AUTO_TEST_SUITE(RectangleTreeTest); - // Test the traits on RectangleTrees. -BOOST_AUTO_TEST_CASE(RectangleTreeTraitsTest) +TEST_CASE("RectangleTreeTraitsTest", "[RectangleTreeTraitsTest]") { // Children may be overlapping. bool b = TreeTraits>::HasOverlappingChildren; - BOOST_REQUIRE_EQUAL(b, true); + REQUIRE(b == true); // Points are not contained in multiple levels. b = TreeTraits>::HasSelfChildren; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); } // Test to make sure the tree can be contains the correct number of points after // it is constructed. -BOOST_AUTO_TEST_CASE(RectangleTreeConstructionCountTest) +TEST_CASE("RectangleTreeConstructionCountTest", "[RectangleTreeTraitsTest]") { arma::mat dataset; dataset.randu(3, 1000); // 1000 points in 3 dimensions. @@ -55,8 +53,8 @@ BOOST_AUTO_TEST_CASE(RectangleTreeConstructionCountTest) TreeType tree(dataset, 20, 6, 5, 2, 0); TreeType tree2 = tree; - BOOST_REQUIRE_EQUAL(tree.NumDescendants(), 1000); - BOOST_REQUIRE_EQUAL(tree2.NumDescendants(), 1000); + REQUIRE(tree.NumDescendants() == 1000); + REQUIRE(tree2.NumDescendants() == 1000); } /** @@ -92,7 +90,7 @@ std::vector GetAllPointsInTree(const TreeType& tree) // Test to ensure that none of the points in the tree are duplicates. This, // combined with the above test to see how many points are in the tree, should // ensure that we inserted all points. -BOOST_AUTO_TEST_CASE(RectangleTreeConstructionRepeatTest) +TEST_CASE("RectangleTreeConstructionRepeatTest", "[RectangleTreeTraitsTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -113,7 +111,7 @@ BOOST_AUTO_TEST_CASE(RectangleTreeConstructionRepeatTest) for (size_t k = 0; k < v1.n_rows; ++k) same &= (v1[k] == v2[k]); - BOOST_REQUIRE_NE(same, true); + REQUIRE(same != true); } } @@ -134,7 +132,7 @@ void CheckContainment(const TreeType& tree) if (tree.NumChildren() == 0) { for (size_t i = 0; i < tree.Count(); ++i) - BOOST_REQUIRE(tree.Bound().Contains( + REQUIRE(tree.Bound().Contains( tree.Dataset().unsafe_col(tree.Point(i)))); } else @@ -151,7 +149,7 @@ void CheckContainment(const TreeType& tree) std::numeric_limits::max()) || tree.Bound()[j].Contains(tree.Child(i).Bound()[j]); - BOOST_REQUIRE(success); + REQUIRE(success); } CheckContainment(tree.Child(i)); @@ -178,8 +176,8 @@ void CheckExactContainment(const TreeType& tree) if (tree.Dataset().col(tree.Point(j))[i] > max) max = tree.Dataset().col(tree.Point(j))[i]; } - BOOST_REQUIRE_EQUAL(max, tree.Bound()[i].Hi()); - BOOST_REQUIRE_EQUAL(min, tree.Bound()[i].Lo()); + REQUIRE(max == tree.Bound()[i].Hi()); + REQUIRE(min == tree.Bound()[i].Lo()); } } else @@ -196,8 +194,8 @@ void CheckExactContainment(const TreeType& tree) max = tree.Child(j).Bound()[i].Hi(); } - BOOST_REQUIRE_EQUAL(max, tree.Bound()[i].Hi()); - BOOST_REQUIRE_EQUAL(min, tree.Bound()[i].Lo()); + REQUIRE(max == tree.Bound()[i].Hi()); + REQUIRE(min == tree.Bound()[i].Lo()); } for (size_t i = 0; i < tree.NumChildren(); ++i) @@ -213,14 +211,14 @@ void CheckHierarchy(const TreeType& tree) { for (size_t i = 0; i < tree.NumChildren(); ++i) { - BOOST_REQUIRE_EQUAL(&tree, tree.Child(i).Parent()); + REQUIRE(&tree == tree.Child(i).Parent()); CheckHierarchy(tree.Child(i)); } } // Test to see if the bounds of the tree are correct. (Cover all bounds and // points beneath this node of the tree). -BOOST_AUTO_TEST_CASE(RectangleTreeContainmentTest) +TEST_CASE("RectangleTreeContainmentTest", "[RectangleTreeTraitsTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -249,23 +247,23 @@ void CheckFills(const TreeType& tree) { if (tree.IsLeaf()) { - BOOST_REQUIRE(tree.Count() >= tree.MinLeafSize() || tree.Parent() == NULL); - BOOST_REQUIRE(tree.Count() <= tree.MaxLeafSize()); + REQUIRE((tree.Count() >= tree.MinLeafSize() || tree.Parent() == NULL)); + REQUIRE(tree.Count() <= tree.MaxLeafSize()); } else { for (size_t i = 0; i < tree.NumChildren(); ++i) { - BOOST_REQUIRE(tree.NumChildren() >= tree.MinNumChildren() || - tree.Parent() == NULL); - BOOST_REQUIRE(tree.NumChildren() <= tree.MaxNumChildren()); + REQUIRE((tree.NumChildren() >= tree.MinNumChildren() || + tree.Parent() == NULL)); + REQUIRE(tree.NumChildren() <= tree.MaxNumChildren()); CheckFills(tree.Child(i)); } } } // Test to ensure that the minimum and maximum fills are satisfied. -BOOST_AUTO_TEST_CASE(CheckMinAndMaxFills) +TEST_CASE("CheckMinAndMaxFills", "[RectangleTreeTraitsTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -339,7 +337,7 @@ size_t CheckNumDescendants(const TreeType& tree) { if (tree.IsLeaf()) { - BOOST_REQUIRE_EQUAL(tree.NumDescendants(), tree.Count()); + REQUIRE(tree.NumDescendants() == tree.Count()); return tree.Count(); } @@ -348,14 +346,14 @@ size_t CheckNumDescendants(const TreeType& tree) for (size_t i = 0; i < tree.NumChildren(); ++i) numDescendants += CheckNumDescendants(tree.Child(i)); - BOOST_REQUIRE_EQUAL(tree.NumDescendants(), numDescendants); + REQUIRE(tree.NumDescendants() == numDescendants); return numDescendants; } // A test to ensure that all leaf nodes are stored on the same level of the // tree. -BOOST_AUTO_TEST_CASE(TreeBalance) +TEST_CASE("TreeBalance", "[RectangleTreeTraitsTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -365,15 +363,15 @@ BOOST_AUTO_TEST_CASE(TreeBalance) TreeType tree(dataset, 20, 6, 5, 2, 0); - BOOST_REQUIRE_EQUAL(GetMinLevel(tree), GetMaxLevel(tree)); - BOOST_REQUIRE_EQUAL(tree.TreeDepth(), GetMinLevel(tree)); + REQUIRE(GetMinLevel(tree) == GetMaxLevel(tree)); + REQUIRE(tree.TreeDepth() == GetMinLevel(tree)); } // A test to see if point deletion is working correctly. We build a tree, then // delete numIter points and test that the query gives correct results. It is // remotely possible that this test will give a false negative if it should // happen that two points are the same distance from a third point. -BOOST_AUTO_TEST_CASE(PointDeletion) +TEST_CASE("PointDeletion", "[RectangleTreeTraitsTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -404,14 +402,14 @@ BOOST_AUTO_TEST_CASE(PointDeletion) for (size_t k = 0; k < v1.n_rows; ++k) same &= (v1[k] == v2[k]); - BOOST_REQUIRE(!same); + REQUIRE(!same); } } for (size_t i = 0; i < allPoints.size(); ++i) delete allPoints[i]; - BOOST_REQUIRE_EQUAL(tree.NumDescendants(), 1000 - numIter); + REQUIRE(tree.NumDescendants() == 1000 - numIter); CheckContainment(tree); CheckExactContainment(tree); @@ -439,8 +437,8 @@ BOOST_AUTO_TEST_CASE(PointDeletion) for (size_t i = 0; i < neighbors1.size(); ++i) { - BOOST_REQUIRE_EQUAL(distances1[i], distances2[i]); - BOOST_REQUIRE_EQUAL(neighbors1[i], neighbors2[i]); + REQUIRE(distances1[i] == distances2[i]); + REQUIRE(neighbors1[i] == neighbors2[i]); } } @@ -450,7 +448,7 @@ BOOST_AUTO_TEST_CASE(PointDeletion) // negative if it should happen that two points are the same distance from a // third point. Note that this is extremely inefficient. You should not use // dynamic insertion until a better solution for resizing matrices is available. -BOOST_AUTO_TEST_CASE(PointDynamicAdd) +TEST_CASE("PointDynamicAdd", "[RectangleTreeTraitsTest]") { const int numIter = 50; arma::mat dataset; @@ -488,14 +486,14 @@ BOOST_AUTO_TEST_CASE(PointDynamicAdd) for (size_t k = 0; k < v1.n_rows; ++k) same &= (v1[k] == v2[k]); - BOOST_REQUIRE(!same); + REQUIRE(!same); } } for (size_t i = 0; i < allPoints.size(); ++i) delete allPoints[i]; - BOOST_REQUIRE_EQUAL(tree.NumDescendants(), 1000 + numIter); + REQUIRE(tree.NumDescendants() == 1000 + numIter); CheckContainment(tree); CheckExactContainment(tree); CheckNumDescendants(tree); @@ -520,14 +518,14 @@ BOOST_AUTO_TEST_CASE(PointDynamicAdd) for (size_t i = 0; i < neighbors1.size(); ++i) { - BOOST_REQUIRE_EQUAL(distances1[i], distances2[i]); - BOOST_REQUIRE_EQUAL(neighbors1[i], neighbors2[i]); + REQUIRE(distances1[i] == distances2[i]); + REQUIRE(neighbors1[i] == neighbors2[i]); } } // A test to ensure that the SingleTreeTraverser is working correctly by // comparing its results to the results of a naive search. -BOOST_AUTO_TEST_CASE(SingleTreeTraverserTest) +TEST_CASE("SingleTreeTraverserTest", "[RectangleTreeTraitsTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -540,7 +538,7 @@ BOOST_AUTO_TEST_CASE(SingleTreeTraverserTest) arma::mat> TreeType; TreeType rTree(dataset, 20, 6, 5, 2, 0); - BOOST_REQUIRE_EQUAL(rTree.NumDescendants(), 1000); + REQUIRE(rTree.NumDescendants() == 1000); CheckContainment(rTree); CheckExactContainment(rTree); @@ -560,14 +558,14 @@ BOOST_AUTO_TEST_CASE(SingleTreeTraverserTest) for (size_t i = 0; i < neighbors1.size(); ++i) { - BOOST_REQUIRE_EQUAL(neighbors1[i], neighbors2[i]); - BOOST_REQUIRE_EQUAL(distances1[i], distances2[i]); + REQUIRE(neighbors1[i] == neighbors2[i]); + REQUIRE(distances1[i] == distances2[i]); } } // A test to ensure that the SingleTreeTraverser is working correctly by // comparing its results to the results of a naive search. -BOOST_AUTO_TEST_CASE(XTreeTraverserTest) +TEST_CASE("XTreeTraverserTest", "[RectangleTreeTraitsTest]") { arma::mat dataset; @@ -583,7 +581,7 @@ BOOST_AUTO_TEST_CASE(XTreeTraverserTest) arma::mat> TreeType; TreeType xTree(dataset, 20, 6, 5, 2, 0); - BOOST_REQUIRE_EQUAL(xTree.NumDescendants(), numP); + REQUIRE(xTree.NumDescendants() == numP); CheckContainment(xTree); CheckExactContainment(xTree); @@ -603,12 +601,12 @@ BOOST_AUTO_TEST_CASE(XTreeTraverserTest) for (size_t i = 0; i < neighbors1.size(); ++i) { - BOOST_REQUIRE_EQUAL(neighbors1[i], neighbors2[i]); - BOOST_REQUIRE_EQUAL(distances1[i], distances2[i]); + REQUIRE(neighbors1[i] == neighbors2[i]); + REQUIRE(distances1[i] == distances2[i]); } } -BOOST_AUTO_TEST_CASE(HilbertRTreeTraverserTest) +TEST_CASE("HilbertRTreeTraverserTest", "[RectangleTreeTraitsTest]") { arma::mat dataset; @@ -624,7 +622,7 @@ BOOST_AUTO_TEST_CASE(HilbertRTreeTraverserTest) NeighborSearchStat, arma::mat> TreeType; TreeType hilbertRTree(dataset, 20, 6, 5, 2, 0); - BOOST_REQUIRE_EQUAL(hilbertRTree.NumDescendants(), numP); + REQUIRE(hilbertRTree.NumDescendants() == numP); CheckContainment(hilbertRTree); CheckExactContainment(hilbertRTree); @@ -644,8 +642,8 @@ BOOST_AUTO_TEST_CASE(HilbertRTreeTraverserTest) for (size_t i = 0; i < neighbors1.size(); ++i) { - BOOST_REQUIRE_EQUAL(neighbors1[i], neighbors2[i]); - BOOST_REQUIRE_EQUAL(distances1[i], distances2[i]); + REQUIRE(neighbors1[i] == neighbors2[i]); + REQUIRE(distances1[i] == distances2[i]); } } @@ -655,25 +653,30 @@ void CheckHilbertOrdering(const TreeType& tree) if (tree.IsLeaf()) { for (size_t i = 0; i < tree.NumPoints() - 1; ++i) - BOOST_REQUIRE_LE(tree.AuxiliaryInfo().HilbertValue().ComparePoints( + { + REQUIRE(tree.AuxiliaryInfo().HilbertValue().ComparePoints( tree.Dataset().col(tree.Point(i)), - tree.Dataset().col(tree.Point(i + 1))), + tree.Dataset().col(tree.Point(i + 1))) <= 0); + } - BOOST_REQUIRE_EQUAL(tree.AuxiliaryInfo().HilbertValue().CompareWith( - tree.Dataset().col(tree.Point(tree.NumPoints() - 1))), + + REQUIRE(tree.AuxiliaryInfo().HilbertValue().CompareWith( + tree.Dataset().col(tree.Point(tree.NumPoints() - 1))) == 0); } else { for (size_t i = 0; i < tree.NumChildren() - 1; ++i) - BOOST_REQUIRE_LE(tree.AuxiliaryInfo().HilbertValue().CompareValues( + { + REQUIRE(tree.AuxiliaryInfo().HilbertValue().CompareValues( tree.Child(i).AuxiliaryInfo().HilbertValue(), - tree.Child(i + 1).AuxiliaryInfo().HilbertValue()), + tree.Child(i + 1).AuxiliaryInfo().HilbertValue()) <= 0); + } - BOOST_REQUIRE_EQUAL(tree.AuxiliaryInfo().HilbertValue().CompareWith( - tree.Child(tree.NumChildren() - 1).AuxiliaryInfo().HilbertValue()), + REQUIRE(tree.AuxiliaryInfo().HilbertValue().CompareWith( + tree.Child(tree.NumChildren() - 1).AuxiliaryInfo().HilbertValue()) == 0); for (size_t i = 0; i < tree.NumChildren(); ++i) @@ -681,7 +684,7 @@ void CheckHilbertOrdering(const TreeType& tree) } } -BOOST_AUTO_TEST_CASE(HilbertRTreeOrderingTest) +TEST_CASE("HilbertRTreeOrderingTest", "[RectangleTreeTraitsTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -712,7 +715,7 @@ void CheckDiscreteHilbertValueSync(const TreeType& tree) const int equal = HilbertValue::CompareValues( value.LocalHilbertValues()->col(i), pointValue); - BOOST_REQUIRE_EQUAL(equal, 0); + REQUIRE(equal == 0); } } else @@ -722,7 +725,7 @@ void CheckDiscreteHilbertValueSync(const TreeType& tree) } } -BOOST_AUTO_TEST_CASE(DiscreteHilbertValueSyncTest) +TEST_CASE("DiscreteHilbertValueSyncTest", "[RectangleTreeTraitsTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -734,7 +737,7 @@ BOOST_AUTO_TEST_CASE(DiscreteHilbertValueSyncTest) CheckDiscreteHilbertValueSync(hilbertRTree); } -BOOST_AUTO_TEST_CASE(DiscreteHilbertValueTest) +TEST_CASE("DiscreteHilbertValueTest", "[RectangleTreeTraitsTest]") { arma::vec point01(1); arma::vec point02(1); @@ -742,56 +745,47 @@ BOOST_AUTO_TEST_CASE(DiscreteHilbertValueTest) point01[0] = -DBL_MAX; point02[0] = DBL_MAX; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point01, - point02), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point01, point02) == -1); point01[0] = -DBL_MAX; point02[0] = -100; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point01, - point02), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point01, point02) == -1); point01[0] = -100; point02[0] = -1; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point01, - point02), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point01, point02) == -1); point01[0] = -1; point02[0] = -std::numeric_limits::min(); - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point01, - point02), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point01, point02) == -1); point01[0] = -std::numeric_limits::min(); point02[0] = 0; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point01, - point02), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point01, point02) == -1); point01[0] = 0; point02[0] = std::numeric_limits::min(); - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point01, - point02), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point01, point02) == -1); point01[0] = std::numeric_limits::min(); point02[0] = 1; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point01, - point02), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point01, point02) == -1); point01[0] = 1; point02[0] = 100; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point01, - point02), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point01, point02) == -1); point01[0] = 100; point02[0] = DBL_MAX; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point01, - point02), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point01, point02) == -1); arma::vec point1(2); arma::vec point2(2); @@ -802,8 +796,7 @@ BOOST_AUTO_TEST_CASE(DiscreteHilbertValueTest) point2[0] = 0; point2[1] = 0; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point1, - point2), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point1, point2) == -1); point1[0] = -1; point1[1] = -1; @@ -811,8 +804,7 @@ BOOST_AUTO_TEST_CASE(DiscreteHilbertValueTest) point2[0] = 1; point2[1] = -1; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point1, - point2), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point1, point2) == -1); point1[0] = -1; point1[1] = -1; @@ -820,8 +812,7 @@ BOOST_AUTO_TEST_CASE(DiscreteHilbertValueTest) point2[0] = -1; point2[1] = 1; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point1, - point2), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point1, point2) == -1); point1[0] = -DBL_MAX + 1; point1[1] = -DBL_MAX + 1; @@ -829,8 +820,7 @@ BOOST_AUTO_TEST_CASE(DiscreteHilbertValueTest) point2[0] = -1; point2[1] = -1; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point1, - point2), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point1, point2) == -1); point1[0] = DBL_MAX * 0.75; point1[1] = DBL_MAX * 0.75; @@ -838,8 +828,7 @@ BOOST_AUTO_TEST_CASE(DiscreteHilbertValueTest) point2[0] = DBL_MAX * 0.25; point2[1] = DBL_MAX * 0.25; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point1, - point2), 1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point1, point2) == 1); arma::vec point3(4); arma::vec point4(4); @@ -854,8 +843,7 @@ BOOST_AUTO_TEST_CASE(DiscreteHilbertValueTest) point4[2] = 1.0; point4[3] = 1.0; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point3, - point4), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point3, point4) == -1); point3[0] = -DBL_MAX; point3[1] = DBL_MAX; @@ -867,8 +855,7 @@ BOOST_AUTO_TEST_CASE(DiscreteHilbertValueTest) point4[2] = DBL_MAX; point4[3] = DBL_MAX; - BOOST_REQUIRE_EQUAL(DiscreteHilbertValue::ComparePoints(point3, - point4), -1); + REQUIRE(DiscreteHilbertValue::ComparePoints(point3, point4) == -1); } template @@ -881,7 +868,7 @@ void CheckHilbertValue(const TreeType& tree) if (tree.IsLeaf()) { - BOOST_REQUIRE_EQUAL(value.OwnsLocalHilbertValues(), true); + REQUIRE(value.OwnsLocalHilbertValues() == true); return; } @@ -889,26 +876,26 @@ void CheckHilbertValue(const TreeType& tree) { const HilbertValue& childValue = tree.Child(i).AuxiliaryInfo().HilbertValue(); - BOOST_REQUIRE_EQUAL(value.ValueToInsert(), childValue.ValueToInsert()); + REQUIRE(value.ValueToInsert() == childValue.ValueToInsert()); } const HilbertValue& childValue = tree.Child(tree.NumChildren() - 1).AuxiliaryInfo().HilbertValue(); - BOOST_REQUIRE_EQUAL(value.LocalHilbertValues(), + REQUIRE(value.LocalHilbertValues() == childValue.LocalHilbertValues()); if (!tree.Parent()) - BOOST_REQUIRE_EQUAL(value.OwnsValueToInsert(), true); + REQUIRE(value.OwnsValueToInsert() == true); else - BOOST_REQUIRE_EQUAL(value.OwnsValueToInsert(), false); + REQUIRE(value.OwnsValueToInsert() == false); - BOOST_REQUIRE_EQUAL(value.OwnsLocalHilbertValues(), false); + REQUIRE(value.OwnsLocalHilbertValues() == false); for (size_t i = 0; i < tree.NumChildren(); ++i) CheckHilbertValue(tree.Child(i)); } -BOOST_AUTO_TEST_CASE(HilbertRTeeCopyConstructorTest) +TEST_CASE("HilbertRTeeCopyConstructorTest", "[RectangleTreeTraitsTest]") { typedef HilbertRTree, arma::mat> TreeType; @@ -928,7 +915,7 @@ BOOST_AUTO_TEST_CASE(HilbertRTeeCopyConstructorTest) CheckNumDescendants(copy); } -BOOST_AUTO_TEST_CASE(HilbertRTeeMoveConstructorTest) +TEST_CASE("HilbertRTeeMoveConstructorTest", "[RectangleTreeTraitsTest]") { typedef HilbertRTree, arma::mat> TreeType; @@ -971,14 +958,14 @@ void CheckOverlap(const TreeType& tree) if (!success) break; } - BOOST_REQUIRE_EQUAL(success, true); + REQUIRE(success == true); for (size_t i = 0; i < tree.NumChildren(); ++i) CheckOverlap(tree.Child(i)); } -BOOST_AUTO_TEST_CASE(RPlusTreeOverlapTest) +TEST_CASE("RPlusTreeOverlapTest", "[RectangleTreeTraitsTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -991,15 +978,15 @@ BOOST_AUTO_TEST_CASE(RPlusTreeOverlapTest) // Children can not be overlapping. bool b = TreeTraits::HasOverlappingChildren; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); // Ensure that all leaf nodes are at the same level. - BOOST_REQUIRE_EQUAL(GetMinLevel(rPlusTree), GetMaxLevel(rPlusTree)); - BOOST_REQUIRE_EQUAL(rPlusTree.TreeDepth(), GetMinLevel(rPlusTree)); + REQUIRE(GetMinLevel(rPlusTree) == GetMaxLevel(rPlusTree)); + REQUIRE(rPlusTree.TreeDepth() == GetMinLevel(rPlusTree)); } -BOOST_AUTO_TEST_CASE(RPlusTreeTraverserTest) +TEST_CASE("RPlusTreeTraverserTest", "[RectangleTreeTraitsTest]") { arma::mat dataset; @@ -1015,7 +1002,7 @@ BOOST_AUTO_TEST_CASE(RPlusTreeTraverserTest) arma::mat > TreeType; TreeType rPlusTree(dataset, 20, 6, 5, 2, 0); - BOOST_REQUIRE_EQUAL(rPlusTree.NumDescendants(), numP); + REQUIRE(rPlusTree.NumDescendants() == numP); CheckContainment(rPlusTree); CheckExactContainment(rPlusTree); @@ -1036,8 +1023,8 @@ BOOST_AUTO_TEST_CASE(RPlusTreeTraverserTest) for (size_t i = 0; i < neighbors1.size(); ++i) { - BOOST_REQUIRE_EQUAL(neighbors1[i], neighbors2[i]); - BOOST_REQUIRE_EQUAL(distances1[i], distances2[i]); + REQUIRE(neighbors1[i] == neighbors2[i]); + REQUIRE(distances1[i] == distances2[i]); } } @@ -1052,9 +1039,9 @@ void CheckRPlusPlusTreeBound(const TreeType& tree) // Ensure that the maximum bounding rectangle contains all children. for (size_t k = 0; k < tree.Bound().Dim(); ++k) { - BOOST_REQUIRE_LE(tree.Bound()[k].Hi(), + REQUIRE(tree.Bound()[k].Hi() <= tree.AuxiliaryInfo().OuterBound()[k].Hi()); - BOOST_REQUIRE_LE(tree.AuxiliaryInfo().OuterBound()[k].Lo(), + REQUIRE(tree.AuxiliaryInfo().OuterBound()[k].Lo() <= tree.Bound()[k].Lo()); } @@ -1062,7 +1049,7 @@ void CheckRPlusPlusTreeBound(const TreeType& tree) { // Ensure that the maximum bounding rectangle contains all points. for (size_t i = 0; i < tree.Count(); ++i) - BOOST_REQUIRE_EQUAL(true, + REQUIRE(true == tree.Bound().Contains(tree.Dataset().col(tree.Point(i)))); return; @@ -1089,13 +1076,13 @@ void CheckRPlusPlusTreeBound(const TreeType& tree) if (!success) break; } - BOOST_REQUIRE_EQUAL(success, true); + REQUIRE(success == true); for (size_t i = 0; i < tree.NumChildren(); ++i) CheckRPlusPlusTreeBound(tree.Child(i)); } -BOOST_AUTO_TEST_CASE(RPlusPlusTreeBoundTest) +TEST_CASE("RPlusPlusTreeBoundTest", "[RectangleTreeTraitsTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -1109,10 +1096,10 @@ BOOST_AUTO_TEST_CASE(RPlusPlusTreeBoundTest) // Children can not be overlapping. bool b = TreeTraits::HasOverlappingChildren; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); - BOOST_REQUIRE_EQUAL(GetMinLevel(rPlusPlusTree), GetMaxLevel(rPlusPlusTree)); - BOOST_REQUIRE_EQUAL(rPlusPlusTree.TreeDepth(), GetMinLevel(rPlusPlusTree)); + REQUIRE(GetMinLevel(rPlusPlusTree) == GetMaxLevel(rPlusPlusTree)); + REQUIRE(rPlusPlusTree.TreeDepth() == GetMinLevel(rPlusPlusTree)); // Check the MinimalSplitsNumberSweep. typedef RectangleTree, arma::mat > TreeType; TreeType rPlusPlusTree(dataset, 20, 6, 5, 2, 0); - BOOST_REQUIRE_EQUAL(rPlusPlusTree.NumDescendants(), numP); + REQUIRE(rPlusPlusTree.NumDescendants() == numP); CheckContainment(rPlusPlusTree); CheckExactContainment(rPlusPlusTree); @@ -1167,15 +1154,15 @@ BOOST_AUTO_TEST_CASE(RPlusPlusTreeTraverserTest) for (size_t i = 0; i < neighbors1.size(); ++i) { - BOOST_REQUIRE_EQUAL(neighbors1[i], neighbors2[i]); - BOOST_REQUIRE_EQUAL(distances1[i], distances2[i]); + REQUIRE(neighbors1[i] == neighbors2[i]); + REQUIRE(distances1[i] == distances2[i]); } } // Test the tree splitting. We set MaxLeafSize and MaxNumChildren rather low // to allow us to test by hand without adding hundreds of points. -BOOST_AUTO_TEST_CASE(RTreeSplitTest) +TEST_CASE("RTreeSplitTest", "[RectangleTreeTraitsTest]") { arma::mat data = arma::trans(arma::mat("0.0 0.0;" "0.0 1.0;" @@ -1194,9 +1181,9 @@ BOOST_AUTO_TEST_CASE(RTreeSplitTest) // There's technically no reason they have to be in a certain order, so we // use firstChild etc. to arbitrarily name them. - BOOST_REQUIRE_EQUAL(rTree.NumChildren(), 2); - BOOST_REQUIRE_EQUAL(rTree.NumDescendants(), 10); - BOOST_REQUIRE_EQUAL(rTree.TreeDepth(), 3); + REQUIRE(rTree.NumChildren() == 2); + REQUIRE(rTree.NumDescendants() == 10); + REQUIRE(rTree.TreeDepth() == 3); int firstChild = 0, secondChild = 1; if (rTree.Child(firstChild).NumChildren() == 2) @@ -1205,34 +1192,37 @@ BOOST_AUTO_TEST_CASE(RTreeSplitTest) secondChild = 0; } - BOOST_REQUIRE_SMALL(rTree.Child(firstChild).Bound()[0].Lo(), 1e-15); - BOOST_REQUIRE_CLOSE(rTree.Child(firstChild).Bound()[0].Hi(), 0.1, - 1e-15); - BOOST_REQUIRE_SMALL(rTree.Child(firstChild).Bound()[1].Lo(), 1e-15); - BOOST_REQUIRE_CLOSE(rTree.Child(firstChild).Bound()[1].Hi(), 1.0, - 1e-15); + REQUIRE(rTree.Child(firstChild).Bound()[0].Lo() == + Approx(0.0).margin(1e-15)); - BOOST_REQUIRE_CLOSE(rTree.Child(secondChild).Bound()[0].Lo(), 0.3, - 1e-15); - BOOST_REQUIRE_CLOSE(rTree.Child(secondChild).Bound()[0].Hi(), 1.0, - 1e-15); - BOOST_REQUIRE_CLOSE(rTree.Child(secondChild).Bound()[1].Lo(), 0.1, - 1e-15); - BOOST_REQUIRE_CLOSE(rTree.Child(secondChild).Bound()[1].Hi(), 0.9, - 1e-15); + REQUIRE(rTree.Child(firstChild).Bound()[0].Hi() == + Approx(0.1).epsilon(1e-17)); + REQUIRE(rTree.Child(firstChild).Bound()[1].Lo() == + Approx(0.0).margin(1e-15)); + REQUIRE(rTree.Child(firstChild).Bound()[1].Hi() == + Approx(1.0).epsilon(1e-17)); - BOOST_REQUIRE_EQUAL(rTree.Child(firstChild).NumChildren(), 1); - BOOST_REQUIRE_SMALL( - rTree.Child(firstChild).Child(0).Bound()[0].Lo(), 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(firstChild).Child(0).Bound()[0].Hi(), 0.1, - 1e-15); - BOOST_REQUIRE_SMALL( - rTree.Child(firstChild).Child(0).Bound()[1].Lo(), 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(firstChild).Child(0).Bound()[1].Hi(), 1.0, - 1e-15); - BOOST_REQUIRE_EQUAL(rTree.Child(firstChild).Child(0).Count(), 3); + REQUIRE(rTree.Child(secondChild).Bound()[0].Lo() == + Approx(0.3).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Bound()[0].Hi() == + Approx(1.0).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Bound()[1].Lo() == + Approx(0.1).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Bound()[1].Hi() == + Approx(0.9).epsilon(1e-17)); + + REQUIRE(rTree.Child(firstChild).NumChildren() == 1); + REQUIRE(rTree.Child(firstChild).Child(0).Bound()[0].Lo() == + Approx(0.0).margin(1e-15)); + + REQUIRE(rTree.Child(firstChild).Child(0).Bound()[0].Hi() == + Approx(0.1).epsilon(1e-17)); + REQUIRE(rTree.Child(firstChild).Child(0).Bound()[1].Lo() == + Approx(0.0).margin(1e-15)); + REQUIRE(rTree.Child(firstChild).Child(0).Bound()[1].Hi() == + Approx(1.0).epsilon(1e-17)); + + REQUIRE(rTree.Child(firstChild).Child(0).Count() == 3); int firstPrime = 0, secondPrime = 1; if (rTree.Child(secondChild).Child(firstPrime).Count() == 3) @@ -1241,41 +1231,33 @@ BOOST_AUTO_TEST_CASE(RTreeSplitTest) secondPrime = 0; } - BOOST_REQUIRE_EQUAL(rTree.Child(secondChild).NumChildren(), 2); - BOOST_REQUIRE_EQUAL( - rTree.Child(secondChild).Child(firstPrime).Count(), 4); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(firstPrime).Bound()[0].Lo(), - 0.3, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(firstPrime).Bound()[0].Hi(), - 0.7, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(firstPrime).Bound()[1].Lo(), - 0.3, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(firstPrime).Bound()[1].Hi(), - 0.7, 1e-15); + REQUIRE(rTree.Child(secondChild).NumChildren() == 2); + REQUIRE(rTree.Child(secondChild).Child(firstPrime).Count() == 4); + REQUIRE(rTree.Child(secondChild).Child(firstPrime).Bound()[0].Lo() == + Approx(0.3).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(firstPrime).Bound()[0].Hi() == + Approx(0.7).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(firstPrime).Bound()[1].Lo() == + Approx(0.3).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(firstPrime).Bound()[1].Hi() == + Approx(0.7).epsilon(1e-17)); - BOOST_REQUIRE_EQUAL( - rTree.Child(secondChild).Child(secondPrime).Count(), 3); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(secondPrime).Bound()[0].Lo(), - 0.9, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(secondPrime).Bound()[0].Hi(), - 1.0, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(secondPrime).Bound()[1].Lo(), - 0.1, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(secondPrime).Bound()[1].Hi(), - 0.9, 1e-15); + + REQUIRE(rTree.Child(secondChild).Child(secondPrime).Count() == 3); + REQUIRE(rTree.Child(secondChild).Child(secondPrime).Bound()[0].Lo() == + Approx(0.9).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(secondPrime).Bound()[0].Hi() == + Approx(1.0).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(secondPrime).Bound()[1].Lo() == + Approx(0.1).epsilon(1e-17)); + + REQUIRE(rTree.Child(secondChild).Child(secondPrime).Bound()[1].Hi() == + Approx(0.9).epsilon(1e-17)); } // Test the tree splitting. We set MaxLeafSize and MaxNumChildren rather low // to allow us to test by hand without adding hundreds of points. -BOOST_AUTO_TEST_CASE(RStarTreeSplitTest) +TEST_CASE("RStarTreeSplitTest", "[RectangleTreeTraitsTest]") { arma::mat data = arma::trans(arma::mat("0.0 0.0;" "0.0 1.0;" @@ -1295,9 +1277,9 @@ BOOST_AUTO_TEST_CASE(RStarTreeSplitTest) // There's technically no reason they have to be in a certain order, so we // use firstChild etc. to arbitrarily name them. - BOOST_REQUIRE_EQUAL(rTree.NumChildren(), 2); - BOOST_REQUIRE_EQUAL(rTree.NumDescendants(), 10); - BOOST_REQUIRE_EQUAL(rTree.TreeDepth(), 3); + REQUIRE(rTree.NumChildren() == 2); + REQUIRE(rTree.NumDescendants() == 10); + REQUIRE(rTree.TreeDepth() == 3); int firstChild = 0, secondChild = 1; if (rTree.Child(firstChild).NumChildren() == 2) @@ -1306,32 +1288,35 @@ BOOST_AUTO_TEST_CASE(RStarTreeSplitTest) secondChild = 0; } - BOOST_REQUIRE_SMALL(rTree.Child(firstChild).Bound()[0].Lo(), 1e-15); - BOOST_REQUIRE_CLOSE(rTree.Child(firstChild).Bound()[0].Hi(), 0.1, - 1e-15); - BOOST_REQUIRE_SMALL(rTree.Child(firstChild).Bound()[1].Lo(), 1e-15); - BOOST_REQUIRE_CLOSE(rTree.Child(firstChild).Bound()[1].Hi(), 1.0, - 1e-15); + REQUIRE(rTree.Child(firstChild).Bound()[0].Lo() == + Approx(0.0).margin(1e-15)); + REQUIRE(rTree.Child(firstChild).Bound()[0].Hi() == + Approx(0.1).epsilon(1e-17)); + REQUIRE(rTree.Child(firstChild).Bound()[1].Lo() == + Approx(0.0).margin(1e-15)); + REQUIRE(rTree.Child(firstChild).Bound()[1].Hi() == + Approx(1.0).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Bound()[0].Lo() == + Approx(0.3).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Bound()[0].Hi() == + Approx(1.0).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Bound()[1].Lo() == + Approx(0.1).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Bound()[1].Hi() == + Approx(0.9).epsilon(1e-17)); + REQUIRE(rTree.Child(firstChild).NumChildren() == 1); - BOOST_REQUIRE_CLOSE(rTree.Child(secondChild).Bound()[0].Lo(), 0.3, - 1e-15); - BOOST_REQUIRE_CLOSE(rTree.Child(secondChild).Bound()[0].Hi(), 1.0, - 1e-15); - BOOST_REQUIRE_CLOSE(rTree.Child(secondChild).Bound()[1].Lo(), 0.1, - 1e-15); - BOOST_REQUIRE_CLOSE(rTree.Child(secondChild).Bound()[1].Hi(), 0.9, - 1e-15); - BOOST_REQUIRE_EQUAL(rTree.Child(firstChild).NumChildren(), 1); - BOOST_REQUIRE_SMALL( - rTree.Child(firstChild).Child(0).Bound()[0].Lo(), 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(firstChild).Child(0).Bound()[0].Hi(), 0.1, 1e-15); - BOOST_REQUIRE_SMALL( - rTree.Child(firstChild).Child(0).Bound()[1].Lo(), 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(firstChild).Child(0).Bound()[1].Hi(), 1.0, 1e-15); - BOOST_REQUIRE_EQUAL(rTree.Child(firstChild).Child(0).Count(), 3); + REQUIRE(rTree.Child(firstChild).Child(0).Bound()[0].Lo() == + Approx(0.0).margin(1e-15)); + REQUIRE(rTree.Child(firstChild).Child(0).Bound()[0].Hi() == + Approx(0.1).epsilon(1e-17)); + + REQUIRE(rTree.Child(firstChild).Child(0).Bound()[1].Lo() == + Approx(0.0).margin(1e-15)); + REQUIRE(rTree.Child(firstChild).Child(0).Bound()[1].Hi() == + Approx(1.0).epsilon(1e-17)); + REQUIRE(rTree.Child(firstChild).Child(0).Count() == 3); int firstPrime = 0, secondPrime = 1; if (rTree.Child(secondChild).Child(firstPrime).Count() == 3) @@ -1340,48 +1325,37 @@ BOOST_AUTO_TEST_CASE(RStarTreeSplitTest) secondPrime = 0; } - BOOST_REQUIRE_EQUAL(rTree.Child(secondChild).NumChildren(), 2); - BOOST_REQUIRE_EQUAL( - rTree.Child(secondChild).Child(firstPrime).Count(), 4); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(firstPrime).Bound()[0].Lo(), - 0.3, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(firstPrime).Bound()[0].Hi(), - 0.7, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(firstPrime).Bound()[1].Lo(), - 0.3, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(firstPrime).Bound()[1].Hi(), - 0.7, 1e-15); - - BOOST_REQUIRE_EQUAL( - rTree.Child(secondChild).Child(secondPrime).Count(), 3); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(secondPrime).Bound()[0].Lo(), - 0.9, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(secondPrime).Bound()[0].Hi(), - 1.0, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(secondPrime).Bound()[1].Lo(), - 0.1, 1e-15); - BOOST_REQUIRE_CLOSE( - rTree.Child(secondChild).Child(secondPrime).Bound()[1].Hi(), - 0.9, 1e-15); + REQUIRE(rTree.Child(secondChild).NumChildren() == 2); + REQUIRE(rTree.Child(secondChild).Child(firstPrime).Count() == 4); + REQUIRE(rTree.Child(secondChild).Child(firstPrime).Bound()[0].Lo() == + Approx(0.3).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(firstPrime).Bound()[0].Hi() == + Approx(0.7).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(firstPrime).Bound()[1].Lo() == + Approx(0.3).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(firstPrime).Bound()[1].Lo() == + Approx(0.3).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(firstPrime).Bound()[1].Hi() == + Approx(0.7).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(secondPrime).Count() == 3); + REQUIRE(rTree.Child(secondChild).Child(secondPrime).Bound()[0].Lo() == + Approx(0.9).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(secondPrime).Bound()[0].Hi() == + Approx(1.0).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(secondPrime).Bound()[1].Lo() == + Approx(0.1).epsilon(1e-17)); + REQUIRE(rTree.Child(secondChild).Child(secondPrime).Bound()[1].Hi() == + Approx(0.9).epsilon(1e-17)); } -BOOST_AUTO_TEST_CASE(RectangleTreeMoveDatasetTest) +TEST_CASE("RectangleTreeMoveDatasetTest", "[RectangleTreeTraitsTest]") { arma::mat dataset = arma::randu(3, 1000); typedef RTree TreeType; TreeType tree(std::move(dataset)); - BOOST_REQUIRE_EQUAL(dataset.n_elem, 0); - BOOST_REQUIRE_EQUAL(tree.Dataset().n_rows, 3); - BOOST_REQUIRE_EQUAL(tree.Dataset().n_cols, 1000); + REQUIRE(dataset.n_elem == 0); + REQUIRE(tree.Dataset().n_rows == 3); + REQUIRE(tree.Dataset().n_cols == 1000); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/sfinae_test.cpp b/src/mlpack/tests/sfinae_test.cpp index 10a3aafadb..fce327996d 100644 --- a/src/mlpack/tests/sfinae_test.cpp +++ b/src/mlpack/tests/sfinae_test.cpp @@ -13,9 +13,7 @@ #include #include -#include - -BOOST_AUTO_TEST_SUITE(SFINAETest); +#include "catch.hpp" class A { @@ -97,7 +95,7 @@ HAS_ANY_METHOD_FORM(Model, HasModel); * Test at compile time the presence of methods of the specified forms with the * stated number of additional arguments. */ -BOOST_AUTO_TEST_CASE(HasMethodFormWithNAdditionalArgsTest) +TEST_CASE("HasMethodFormWithNAdditionalArgsTest", "[SFINAETest]") { static_assert(!HasM::WithNAdditionalArgs<0>::value, "value should be false"); @@ -145,7 +143,7 @@ BOOST_AUTO_TEST_CASE(HasMethodFormWithNAdditionalArgsTest) /* * Test at compile time the presence of methods of the specified forms. */ -BOOST_AUTO_TEST_CASE(HasMethodFormTest) +TEST_CASE("HasMethodFormTest", "[SFINAETest]") { static_assert(HasM::value, "value should be true"); @@ -168,7 +166,7 @@ BOOST_AUTO_TEST_CASE(HasMethodFormTest) * Test at compile time, for the presence/absence of a specific member * function in a class. */ -BOOST_AUTO_TEST_CASE(HasMethodNameTest) +TEST_CASE("HasMethodNameTest", "[SFINAETest]") { static_assert(!HasModel::value, "value should be false"); @@ -176,5 +174,3 @@ BOOST_AUTO_TEST_CASE(HasMethodNameTest) static_assert(HasModel::value, "value should be true"); static_assert(HasModel::value, "value should be true"); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/sort_policy_test.cpp b/src/mlpack/tests/sort_policy_test.cpp index 403903a68d..6418135f8e 100644 --- a/src/mlpack/tests/sort_policy_test.cpp +++ b/src/mlpack/tests/sort_policy_test.cpp @@ -16,8 +16,7 @@ #include #include -#include -#include "test_tools.hpp" +#include "catch.hpp" using namespace mlpack; using namespace mlpack::neighbor; @@ -25,47 +24,45 @@ using namespace mlpack::bound; using namespace mlpack::tree; using namespace mlpack::metric; -BOOST_AUTO_TEST_SUITE(SortPolicyTest); - // Tests for NearestNeighborSort /** * Ensure the best distance for nearest neighbors is 0. */ -BOOST_AUTO_TEST_CASE(NnsBestDistance) +TEST_CASE("NnsBestDistance", "[SortPolicyTest]") { - BOOST_REQUIRE(NearestNeighborSort::BestDistance() == 0); + REQUIRE(NearestNeighborSort::BestDistance() == 0); } /** * Ensure the worst distance for nearest neighbors is DBL_MAX. */ -BOOST_AUTO_TEST_CASE(NnsWorstDistance) +TEST_CASE("NnsWorstDistance", "[SortPolicyTest]") { - BOOST_REQUIRE(NearestNeighborSort::WorstDistance() == DBL_MAX); + REQUIRE(NearestNeighborSort::WorstDistance() == DBL_MAX); } /** * Make sure the comparison works for values strictly less than the reference. */ -BOOST_AUTO_TEST_CASE(NnsIsBetterStrict) +TEST_CASE("NnsIsBetterStrict", "[SortPolicyTest]") { - BOOST_REQUIRE(NearestNeighborSort::IsBetter(5.0, 6.0) == true); + REQUIRE(NearestNeighborSort::IsBetter(5.0, 6.0) == true); } /** * Warn in case the comparison is not strict. */ -BOOST_AUTO_TEST_CASE(NnsIsBetterNotStrict) +TEST_CASE("NnsIsBetterNotStrict", "[SortPolicyTest]") { - BOOST_WARN(NearestNeighborSort::IsBetter(6.0, 6.0) == true); + CHECK(NearestNeighborSort::IsBetter(6.0, 6.0) == true); } /** * Very simple sanity check to ensure that bounds are working alright. We will * use a one-dimensional bound for simplicity. */ -BOOST_AUTO_TEST_CASE(NnsNodeToNodeDistance) +TEST_CASE("NnsNodeToNodeDistance", "[SortPolicyTest]") { // Well, there's no easy way to make HRectBounds the way we want, so we have // to make them and then expand the region to include new points. @@ -89,8 +86,8 @@ BOOST_AUTO_TEST_CASE(NnsNodeToNodeDistance) nodeTwo.Bound() |= utility; // This should use the L2 distance. - BOOST_REQUIRE_CLOSE(NearestNeighborSort::BestNodeToNodeDistance(&nodeOne, - &nodeTwo), 4.0, 1e-5); + REQUIRE(NearestNeighborSort::BestNodeToNodeDistance(&nodeOne, &nodeTwo) == + Approx(4.0).epsilon(1e-7)); // And another just to be sure, from the other side. nodeTwo.Bound().Clear(); @@ -100,8 +97,8 @@ BOOST_AUTO_TEST_CASE(NnsNodeToNodeDistance) nodeTwo.Bound() |= utility; // Again, the distance is the L2 distance. - BOOST_REQUIRE_CLOSE(NearestNeighborSort::BestNodeToNodeDistance(&nodeOne, - &nodeTwo), 1.0, 1e-5); + REQUIRE(NearestNeighborSort::BestNodeToNodeDistance(&nodeOne, &nodeTwo) == + Approx(1.0).epsilon(1e-7)); // Now, when the bounds overlap. nodeTwo.Bound().Clear(); @@ -110,15 +107,15 @@ BOOST_AUTO_TEST_CASE(NnsNodeToNodeDistance) utility[0] = 0.5; nodeTwo.Bound() |= utility; - BOOST_REQUIRE_SMALL(NearestNeighborSort::BestNodeToNodeDistance(&nodeOne, - &nodeTwo), 1e-5); + REQUIRE(NearestNeighborSort::BestNodeToNodeDistance(&nodeOne, &nodeTwo) == + Approx(0.0).margin(1e-5)); } /** * Another very simple sanity check for the point-to-node case, again in one * dimension. */ -BOOST_AUTO_TEST_CASE(NnsPointToNodeDistance) +TEST_CASE("NnsPointToNodeDistance", "[SortPolicyTest]") { // Well, there's no easy way to make HRectBounds the way we want, so we have // to make them and then expand the region to include new points. @@ -137,20 +134,20 @@ BOOST_AUTO_TEST_CASE(NnsPointToNodeDistance) point[0] = -0.5; // The distance is the L2 distance. - BOOST_REQUIRE_CLOSE(NearestNeighborSort::BestPointToNodeDistance(point, - &node), 0.5, 1e-5); + REQUIRE(NearestNeighborSort::BestPointToNodeDistance(point, &node) == + Approx(0.5).epsilon(1e-7)); // Now from the other side of the bound. point[0] = 1.5; - BOOST_REQUIRE_CLOSE(NearestNeighborSort::BestPointToNodeDistance(point, - &node), 0.5, 1e-5); + REQUIRE(NearestNeighborSort::BestPointToNodeDistance(point, &node) == + Approx(0.5).epsilon(1e-7)); // And now when the point is inside the bound. point[0] = 0.5; - BOOST_REQUIRE_SMALL(NearestNeighborSort::BestPointToNodeDistance(point, - &node), 1e-5); + REQUIRE(NearestNeighborSort::BestPointToNodeDistance(point, &node) == + Approx(0.0).margin(1e-5)); } // Tests for FurthestNeighborSort @@ -158,40 +155,40 @@ BOOST_AUTO_TEST_CASE(NnsPointToNodeDistance) /** * Ensure the best distance for furthest neighbors is DBL_MAX. */ -BOOST_AUTO_TEST_CASE(FnsBestDistance) +TEST_CASE("FnsBestDistance", "[SortPolicyTest]") { - BOOST_REQUIRE(FurthestNeighborSort::BestDistance() == DBL_MAX); + REQUIRE(FurthestNeighborSort::BestDistance() == DBL_MAX); } /** * Ensure the worst distance for furthest neighbors is 0. */ -BOOST_AUTO_TEST_CASE(FnsWorstDistance) +TEST_CASE("FnsWorstDistance", "[SortPolicyTest]") { - BOOST_REQUIRE(FurthestNeighborSort::WorstDistance() == 0); + REQUIRE(FurthestNeighborSort::WorstDistance() == 0); } /** * Make sure the comparison works for values strictly less than the reference. */ -BOOST_AUTO_TEST_CASE(FnsIsBetterStrict) +TEST_CASE("FnsIsBetterStrict", "[SortPolicyTest]") { - BOOST_REQUIRE(FurthestNeighborSort::IsBetter(5.0, 4.0) == true); + REQUIRE(FurthestNeighborSort::IsBetter(5.0, 4.0) == true); } /** * Warn in case the comparison is not strict. */ -BOOST_AUTO_TEST_CASE(FnsIsBetterNotStrict) +TEST_CASE("FnsIsBetterNotStrict", "[SortPolicyTest]") { - BOOST_WARN(FurthestNeighborSort::IsBetter(6.0, 6.0) == true); + CHECK(FurthestNeighborSort::IsBetter(6.0, 6.0) == true); } /** * Very simple sanity check to ensure that bounds are working alright. We will * use a one-dimensional bound for simplicity. */ -BOOST_AUTO_TEST_CASE(FnsNodeToNodeDistance) +TEST_CASE("FnsNodeToNodeDistance", "[SortPolicyTest]") { // Well, there's no easy way to make HRectBounds the way we want, so we have // to make them and then expand the region to include new points. @@ -214,8 +211,8 @@ BOOST_AUTO_TEST_CASE(FnsNodeToNodeDistance) nodeTwo.Bound() |= utility; // This should use the L2 distance. - BOOST_REQUIRE_CLOSE(FurthestNeighborSort::BestNodeToNodeDistance(&nodeOne, - &nodeTwo), 6.0, 1e-5); + REQUIRE(FurthestNeighborSort::BestNodeToNodeDistance(&nodeOne, &nodeTwo) == + Approx(6.0).epsilon(1e-7)); // And another just to be sure, from the other side. nodeTwo.Bound().Clear(); @@ -225,8 +222,8 @@ BOOST_AUTO_TEST_CASE(FnsNodeToNodeDistance) nodeTwo.Bound() |= utility; // Again, the distance is the L2 distance. - BOOST_REQUIRE_CLOSE(FurthestNeighborSort::BestNodeToNodeDistance(&nodeOne, - &nodeTwo), 3.0, 1e-5); + REQUIRE(FurthestNeighborSort::BestNodeToNodeDistance(&nodeOne, &nodeTwo) == + Approx(3.0).epsilon(1e-7)); // Now, when the bounds overlap. nodeTwo.Bound().Clear(); @@ -235,15 +232,15 @@ BOOST_AUTO_TEST_CASE(FnsNodeToNodeDistance) utility[0] = 0.5; nodeTwo.Bound() |= utility; - BOOST_REQUIRE_CLOSE(FurthestNeighborSort::BestNodeToNodeDistance(&nodeOne, - &nodeTwo), 1.5, 1e-5); + REQUIRE(FurthestNeighborSort::BestNodeToNodeDistance(&nodeOne, &nodeTwo) == + Approx(1.5).epsilon(1e-7)); } /** * Another very simple sanity check for the point-to-node case, again in one * dimension. */ -BOOST_AUTO_TEST_CASE(FnsPointToNodeDistance) +TEST_CASE("FnsPointToNodeDistance", "[SortPolicyTest]") { // Well, there's no easy way to make HRectBounds the way we want, so we have // to make them and then expand the region to include new points. @@ -262,20 +259,18 @@ BOOST_AUTO_TEST_CASE(FnsPointToNodeDistance) point[0] = -0.5; // The distance is the L2 distance. - BOOST_REQUIRE_CLOSE(FurthestNeighborSort::BestPointToNodeDistance(point, - &node), 1.5, 1e-5); + REQUIRE(FurthestNeighborSort::BestPointToNodeDistance(point, &node) == + Approx(1.5).epsilon(1e-7)); // Now from the other side of the bound. point[0] = 1.5; - BOOST_REQUIRE_CLOSE(FurthestNeighborSort::BestPointToNodeDistance(point, - &node), 1.5, 1e-5); + REQUIRE(FurthestNeighborSort::BestPointToNodeDistance(point, &node) == + Approx(1.5).epsilon(1e-7)); // And now when the point is inside the bound. point[0] = 0.5; - BOOST_REQUIRE_CLOSE(FurthestNeighborSort::BestPointToNodeDistance(point, - &node), 0.5, 1e-5); + REQUIRE(FurthestNeighborSort::BestPointToNodeDistance(point, &node) == + Approx(0.5).epsilon(1e-7)); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/spill_tree_test.cpp b/src/mlpack/tests/spill_tree_test.cpp index 83677b5078..0a1569e800 100644 --- a/src/mlpack/tests/spill_tree_test.cpp +++ b/src/mlpack/tests/spill_tree_test.cpp @@ -13,21 +13,19 @@ #include #include -#include +#include "catch.hpp" #include using namespace mlpack; using namespace mlpack::tree; using namespace mlpack::metric; -BOOST_AUTO_TEST_SUITE(SpillTreeTest); - /** * Test to make sure the tree contains the correct number of points after * it is constructed. Also, it checks some invariants in the relation between * parent and child nodes. */ -BOOST_AUTO_TEST_CASE(SpillTreeConstructionCountTest) +TEST_CASE("SpillTreeConstructionCountTest", "[SpillTreeTest]") { arma::mat dataset; dataset.randu(3, 1000); // 1000 points in 3 dimensions. @@ -38,8 +36,8 @@ BOOST_AUTO_TEST_CASE(SpillTreeConstructionCountTest) TreeType tree1(dataset, 0); TreeType tree2 = tree1; - BOOST_REQUIRE_EQUAL(tree1.NumDescendants(), 1000); - BOOST_REQUIRE_EQUAL(tree2.NumDescendants(), 1000); + REQUIRE(tree1.NumDescendants() == 1000); + REQUIRE(tree2.NumDescendants() == 1000); // When overlapping buffer is greater than 0, it is possible to have repeated // points. So, let's check node by node, that the number of descendants @@ -68,18 +66,18 @@ BOOST_AUTO_TEST_CASE(SpillTreeConstructionCountTest) } if (node->IsLeaf()) - BOOST_REQUIRE_EQUAL(node->NumPoints(), node->NumDescendants()); + REQUIRE(node->NumPoints() == node->NumDescendants()); else - BOOST_REQUIRE_EQUAL(node->NumPoints(), 0); + REQUIRE(node->NumPoints() == 0); - BOOST_REQUIRE_EQUAL(node->NumDescendants(), numDesc); + REQUIRE(node->NumDescendants() == numDesc); } } /** * Test to check that parents and children are set correctly. */ -BOOST_AUTO_TEST_CASE(SpillTreeConstructionParentTest) +TEST_CASE("SpillTreeConstructionParentTest", "[SpillTreeTest]") { arma::mat dataset; dataset.randu(3, 1000); // 1000 points in 3 dimensions. @@ -98,13 +96,13 @@ BOOST_AUTO_TEST_CASE(SpillTreeConstructionParentTest) if (node->Left()) { nodes.push(node->Left()); - BOOST_REQUIRE_EQUAL(node, node->Left()->Parent()); + REQUIRE(node == node->Left()->Parent()); } if (node->Right()) { nodes.push(node->Right()); - BOOST_REQUIRE_EQUAL(node, node->Right()->Parent()); + REQUIRE(node == node->Right()->Parent()); } } } @@ -146,8 +144,8 @@ void SpillTreeHyperplaneTestAux() for (size_t i = 0; i < numDesc; ++i) { size_t descIndex = node->Left()->Descendant(i); - BOOST_REQUIRE_LE( - node->Hyperplane().Project(node->Dataset().col(descIndex)), + REQUIRE( + node->Hyperplane().Project(node->Dataset().col(descIndex)) < tau); } } @@ -159,9 +157,8 @@ void SpillTreeHyperplaneTestAux() for (size_t i = 0; i < numDesc; ++i) { size_t descIndex = node->Right()->Descendant(i); - BOOST_REQUIRE_GT( - node->Hyperplane().Project(node->Dataset().col(descIndex)), - -tau); + REQUIRE(node->Hyperplane().Project(node->Dataset().col(descIndex)) + > -tau); } } } @@ -176,7 +173,7 @@ void SpillTreeHyperplaneTestAux() for (size_t i = 0; i < numDesc; ++i) { size_t descIndex = node->Left()->Descendant(i); - BOOST_REQUIRE( + REQUIRE( node->Hyperplane().Left(node->Dataset().col(descIndex))); } } @@ -188,7 +185,7 @@ void SpillTreeHyperplaneTestAux() for (size_t i = 0; i < numDesc; ++i) { size_t descIndex = node->Right()->Descendant(i); - BOOST_REQUIRE( + REQUIRE( node->Hyperplane().Right(node->Dataset().col(descIndex))); } } @@ -208,7 +205,7 @@ void SpillTreeHyperplaneTestAux() * left by the node's splitting hyperplane, and the same for points in the * right child. */ -BOOST_AUTO_TEST_CASE(SpillTreeHyperplaneTest) +TEST_CASE("SpillTreeHyperplaneTest", "[SpillTreeTest]") { typedef SPTree SpillType1; typedef NonOrtSPTree SpillType2; @@ -225,7 +222,7 @@ BOOST_AUTO_TEST_CASE(SpillTreeHyperplaneTest) /** * Simple test for the move constructor. */ -BOOST_AUTO_TEST_CASE(SpillTreeMoveConstructorTest) +TEST_CASE("SpillTreeMoveConstructorTest", "[SpillTreeTest]") { arma::mat dataset = arma::randu(3, 1000); typedef SPTree TreeType; @@ -238,29 +235,29 @@ BOOST_AUTO_TEST_CASE(SpillTreeMoveConstructorTest) TreeType newTree(std::move(tree)); - BOOST_REQUIRE(tree.Left() == NULL); - BOOST_REQUIRE(tree.Right() == NULL); - BOOST_REQUIRE_EQUAL(tree.NumDescendants(), 0); + REQUIRE(tree.Left() == NULL); + REQUIRE(tree.Right() == NULL); + REQUIRE(tree.NumDescendants() == 0); - BOOST_REQUIRE_EQUAL(newTree.Left(), left); - BOOST_REQUIRE_EQUAL(newTree.Right(), right); - BOOST_REQUIRE_EQUAL(newTree.NumDescendants(), numDesc); + REQUIRE(newTree.Left() == left); + REQUIRE(newTree.Right() == right); + REQUIRE(newTree.NumDescendants() == numDesc); if (left) { - BOOST_REQUIRE(newTree.Left() != NULL); - BOOST_REQUIRE_EQUAL(newTree.Left()->Parent(), &newTree); + REQUIRE(newTree.Left() != NULL); + REQUIRE(newTree.Left()->Parent() == &newTree); } if (right) { - BOOST_REQUIRE(newTree.Right() != NULL); - BOOST_REQUIRE_EQUAL(newTree.Right()->Parent(), &newTree); + REQUIRE(newTree.Right() != NULL); + REQUIRE(newTree.Right()->Parent() == &newTree); } } /** * Simple test for the copy constructor. */ -BOOST_AUTO_TEST_CASE(SpillTreeCopyConstructorTest) +TEST_CASE("SpillTreeCopyConstructorTest", "[SpillTreeTest]") { arma::mat dataset = arma::randu(3, 1000); typedef SPTree TreeType; @@ -276,36 +273,34 @@ BOOST_AUTO_TEST_CASE(SpillTreeCopyConstructorTest) delete tree; - BOOST_REQUIRE_EQUAL(newTree.Dataset().n_rows, 3); - BOOST_REQUIRE_EQUAL(newTree.Dataset().n_cols, 1000); - BOOST_REQUIRE_EQUAL(newTree.NumDescendants(), numDesc); + REQUIRE(newTree.Dataset().n_rows == 3); + REQUIRE(newTree.Dataset().n_cols == 1000); + REQUIRE(newTree.NumDescendants() == numDesc); if (left) { - BOOST_REQUIRE(newTree.Left() != left); - BOOST_REQUIRE(newTree.Left() != NULL); - BOOST_REQUIRE_EQUAL(newTree.Left()->Parent(), &newTree); + REQUIRE(newTree.Left() != left); + REQUIRE(newTree.Left() != NULL); + REQUIRE(newTree.Left()->Parent() == &newTree); } if (right) { - BOOST_REQUIRE(newTree.Right() != right); - BOOST_REQUIRE(newTree.Right() != NULL); - BOOST_REQUIRE_EQUAL(newTree.Right()->Parent(), &newTree); + REQUIRE(newTree.Right() != right); + REQUIRE(newTree.Right() != NULL); + REQUIRE(newTree.Right()->Parent() == &newTree); } } /** * Simple test for the constructor that takes a rvalue reference to the dataset. */ -BOOST_AUTO_TEST_CASE(SpillTreeMoveDatasetTest) +TEST_CASE("SpillTreeMoveDatasetTest", "[SpillTreeTest]") { arma::mat dataset = arma::randu(3, 1000); typedef SPTree TreeType; TreeType tree(std::move(dataset)); - BOOST_REQUIRE_EQUAL(dataset.n_elem, 0); - BOOST_REQUIRE_EQUAL(tree.Dataset().n_rows, 3); - BOOST_REQUIRE_EQUAL(tree.Dataset().n_cols, 1000); + REQUIRE(dataset.n_elem == 0); + REQUIRE(tree.Dataset().n_rows == 3); + REQUIRE(tree.Dataset().n_cols == 1000); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/string_encoding_test.cpp b/src/mlpack/tests/string_encoding_test.cpp index b50eea8e6d..45c5555d39 100644 --- a/src/mlpack/tests/string_encoding_test.cpp +++ b/src/mlpack/tests/string_encoding_test.cpp @@ -20,15 +20,14 @@ #include #include #include -#include "test_tools.hpp" -#include "serialization.hpp" +#include "test_catch_tools.hpp" +#include "catch.hpp" +#include "serialization_catch.hpp" using namespace mlpack; using namespace mlpack::data; using namespace std; -BOOST_AUTO_TEST_SUITE(StringEncodingTest); - //! Common input for some tests. static vector stringEncodingInput = { "mlpack is an intuitive, fast, and flexible C++ machine learning library " @@ -64,21 +63,21 @@ void CheckVectors(const vector>& a, const vector>& b, const ValueType tolerance = 1e-5) { - BOOST_REQUIRE_EQUAL(a.size(), b.size()); + REQUIRE(a.size() == b.size()); for (size_t i = 0; i < a.size(); ++i) { - BOOST_REQUIRE_EQUAL(a[i].size(), b[i].size()); + REQUIRE(a[i].size() == b[i].size()); for (size_t j = 0; j < a[i].size(); ++j) - BOOST_REQUIRE_CLOSE(a[i][j], b[i][j], tolerance); + REQUIRE(a[i][j] == Approx(b[i][j]).epsilon(tolerance / 100)); } } /** * Test the dictionary encoding algorithm. */ -BOOST_AUTO_TEST_CASE(DictionaryEncodingTest) +TEST_CASE("DictionaryEncodingTest", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; @@ -97,7 +96,7 @@ BOOST_AUTO_TEST_CASE(DictionaryEncodingTest) { keysCount[keyValue.second]++; - BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1); + REQUIRE(keysCount[keyValue.second] == 1); } arma::mat expected = { @@ -115,7 +114,7 @@ BOOST_AUTO_TEST_CASE(DictionaryEncodingTest) /** * Test the dictionary encoding algorithm with unicode characters. */ -BOOST_AUTO_TEST_CASE(UnicodeDictionaryEncodingTest) +TEST_CASE("UnicodeDictionaryEncodingTest", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; @@ -134,7 +133,7 @@ BOOST_AUTO_TEST_CASE(UnicodeDictionaryEncodingTest) { keysCount[keyValue.second]++; - BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1); + REQUIRE(keysCount[keyValue.second] == 1); } arma::mat expected = { @@ -149,7 +148,7 @@ BOOST_AUTO_TEST_CASE(UnicodeDictionaryEncodingTest) /** * Test the one pass modification of the dictionary encoding algorithm. */ -BOOST_AUTO_TEST_CASE(OnePassDictionaryEncodingTest) +TEST_CASE("OnePassDictionaryEncodingTest", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; @@ -169,7 +168,7 @@ BOOST_AUTO_TEST_CASE(OnePassDictionaryEncodingTest) { keysCount[keyValue.second]++; - BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1); + REQUIRE(keysCount[keyValue.second] == 1); } vector> expected = { @@ -179,14 +178,14 @@ BOOST_AUTO_TEST_CASE(OnePassDictionaryEncodingTest) { 36, 37, 14, 38, 39, 8, 40, 1, 41, 42, 43, 44, 6, 45, 13 } }; - BOOST_REQUIRE(output == expected); + REQUIRE(output == expected); } /** * Test the SplitByAnyOf tokenizer. */ -BOOST_AUTO_TEST_CASE(SplitByAnyOfTokenizerTest) +TEST_CASE("SplitByAnyOfTokenizerTest", "[StringEncodingTest]") { std::vector tokens; boost::string_view line(stringEncodingInput[0]); @@ -204,16 +203,16 @@ BOOST_AUTO_TEST_CASE(SplitByAnyOfTokenizerTest) "bindings", "to", "other", "languages" }; - BOOST_REQUIRE_EQUAL(tokens.size(), expected.size()); + REQUIRE(tokens.size() == expected.size()); for (size_t i = 0; i < tokens.size(); ++i) - BOOST_REQUIRE_EQUAL(tokens[i], expected[i]); + REQUIRE(tokens[i] == expected[i]); } /** * Test the SplitByAnyOf tokenizer in case of unicode characters. */ -BOOST_AUTO_TEST_CASE(SplitByAnyOfTokenizerUnicodeTest) +TEST_CASE("SplitByAnyOfTokenizerUnicodeTest", "[StringEncodingTest]") { vector expectedUtf8Tokens = { "\xF0\x9F\x84\xBC\xF0\x9F\x84\xBB\xF0\x9F\x84\xBF\xF0\x9F\x84\xB0" @@ -236,16 +235,16 @@ BOOST_AUTO_TEST_CASE(SplitByAnyOfTokenizerUnicodeTest) token = tokenizer(line); } - BOOST_REQUIRE_EQUAL(tokens.size(), expectedUtf8Tokens.size()); + REQUIRE(tokens.size() == expectedUtf8Tokens.size()); for (size_t i = 0; i < tokens.size(); ++i) - BOOST_REQUIRE_EQUAL(tokens[i], expectedUtf8Tokens[i]); + REQUIRE(tokens[i] == expectedUtf8Tokens[i]); } /** * Test the CharExtract tokenizer. */ -BOOST_AUTO_TEST_CASE(DictionaryEncodingIndividualCharactersTest) +TEST_CASE("DictionaryEncodingIndividualCharactersTest", "[StringEncodingTest]") { vector input = { "GACCA", @@ -270,7 +269,7 @@ BOOST_AUTO_TEST_CASE(DictionaryEncodingIndividualCharactersTest) * Test the one pass modification of the dictionary encoding algorithm * in case of individual character encoding. */ -BOOST_AUTO_TEST_CASE(OnePassDictionaryEncodingIndividualCharactersTest) +TEST_CASE("OnePassDictionaryEncodingIndividualCharactersTest", "[StringEncodingTest]") { std::vector input = { "GACCA", @@ -289,13 +288,13 @@ BOOST_AUTO_TEST_CASE(OnePassDictionaryEncodingIndividualCharactersTest) { 1, 2, 4 } }; - BOOST_REQUIRE(output == expected); + REQUIRE(output == expected); } /** * Test the functionality of copy constructor. */ -BOOST_AUTO_TEST_CASE(StringEncodingCopyTest) +TEST_CASE("StringEncodingCopyTest", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; arma::sp_mat output; @@ -318,12 +317,12 @@ BOOST_AUTO_TEST_CASE(StringEncodingCopyTest) const DictionaryType& copiedDictionary = encoderCopy.Dictionary(); - BOOST_REQUIRE_EQUAL(naiveDictionary.size(), copiedDictionary.Size()); + REQUIRE(naiveDictionary.size() == copiedDictionary.Size()); for (const pair& keyValue : naiveDictionary) { - BOOST_REQUIRE(copiedDictionary.HasToken(keyValue.first)); - BOOST_REQUIRE_EQUAL(copiedDictionary.Value(keyValue.first), + REQUIRE(copiedDictionary.HasToken(keyValue.first)); + REQUIRE(copiedDictionary.Value(keyValue.first) == keyValue.second); } } @@ -331,7 +330,7 @@ BOOST_AUTO_TEST_CASE(StringEncodingCopyTest) /** * Test the move assignment operator. */ -BOOST_AUTO_TEST_CASE(StringEncodingMoveTest) +TEST_CASE("StringEncodingMoveTest", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; arma::sp_mat output; @@ -354,12 +353,12 @@ BOOST_AUTO_TEST_CASE(StringEncodingMoveTest) const DictionaryType& copiedDictionary = encoderCopy.Dictionary(); - BOOST_REQUIRE_EQUAL(naiveDictionary.size(), copiedDictionary.Size()); + REQUIRE(naiveDictionary.size() == copiedDictionary.Size()); for (const pair& keyValue : naiveDictionary) { - BOOST_REQUIRE(copiedDictionary.HasToken(keyValue.first)); - BOOST_REQUIRE_EQUAL(copiedDictionary.Value(keyValue.first), + REQUIRE(copiedDictionary.HasToken(keyValue.first)); + REQUIRE(copiedDictionary.Value(keyValue.first) == keyValue.second); } } @@ -377,16 +376,16 @@ void CheckDictionaries(const StringEncodingDictionary& expected, const MapType& mapping = obtained.Mapping(); const MapType& expectedMapping = expected.Mapping(); - BOOST_REQUIRE_EQUAL(mapping.size(), expectedMapping.size()); + REQUIRE(mapping.size() == expectedMapping.size()); for (auto& keyVal : expectedMapping) { - BOOST_REQUIRE_EQUAL(mapping.at(keyVal.first), keyVal.second); + REQUIRE(mapping.at(keyVal.first) == keyVal.second); } for (auto& keyVal : mapping) { - BOOST_REQUIRE_EQUAL(expectedMapping.at(keyVal.first), keyVal.second); + REQUIRE(expectedMapping.at(keyVal.first) == keyVal.second); } } @@ -413,14 +412,14 @@ void CheckDictionaries( const MapType& expectedMapping = expected.Mapping(); const MapType& mapping = obtained.Mapping(); - BOOST_REQUIRE_EQUAL(tokens.size(), expectedTokens.size()); - BOOST_REQUIRE_EQUAL(mapping.size(), expectedMapping.size()); - BOOST_REQUIRE_EQUAL(mapping.size(), tokens.size()); + REQUIRE(tokens.size() == expectedTokens.size()); + REQUIRE(mapping.size() == expectedMapping.size()); + REQUIRE(mapping.size() == tokens.size()); for (size_t i = 0; i < tokens.size(); ++i) { - BOOST_REQUIRE_EQUAL(tokens[i], expectedTokens[i]); - BOOST_REQUIRE_EQUAL(expectedMapping.at(tokens[i]), mapping.at(tokens[i])); + REQUIRE(tokens[i] == expectedTokens[i]); + REQUIRE(expectedMapping.at(tokens[i]) == mapping.at(tokens[i])); } } @@ -438,11 +437,11 @@ void CheckDictionaries(const StringEncodingDictionary& expected, const MapType& expectedMapping = expected.Mapping(); const MapType& mapping = obtained.Mapping(); - BOOST_REQUIRE_EQUAL(expected.Size(), obtained.Size()); + REQUIRE(expected.Size() == obtained.Size()); for (size_t i = 0; i < mapping.size(); ++i) { - BOOST_REQUIRE_EQUAL(mapping[i], expectedMapping[i]); + REQUIRE(mapping[i] == expectedMapping[i]); } } @@ -450,7 +449,7 @@ void CheckDictionaries(const StringEncodingDictionary& expected, * Serialization test for the general template of the StringEncodingDictionary * class. */ -BOOST_AUTO_TEST_CASE(StringEncodingDictionarySerialization) +TEST_CASE("StringEncodingDictionarySerialization", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; @@ -485,7 +484,7 @@ BOOST_AUTO_TEST_CASE(StringEncodingDictionarySerialization) * Serialization test for the dictionary encoding algorithm with * the SplitByAnyOf tokenizer. */ -BOOST_AUTO_TEST_CASE(SplitByAnyOfDictionaryEncodingSerialization) +TEST_CASE("SplitByAnyOfDictionaryEncodingSerialization", "[StringEncodingTest]") { using EncoderType = DictionaryEncoding; @@ -515,7 +514,7 @@ BOOST_AUTO_TEST_CASE(SplitByAnyOfDictionaryEncodingSerialization) * Serialization test for the dictionary encoding algorithm with * the CharExtract tokenizer. */ -BOOST_AUTO_TEST_CASE(CharExtractDictionaryEncodingSerialization) +TEST_CASE("CharExtractDictionaryEncodingSerialization", "[StringEncodingTest]") { using EncoderType = DictionaryEncoding; @@ -544,7 +543,7 @@ BOOST_AUTO_TEST_CASE(CharExtractDictionaryEncodingSerialization) /** * Test the Bag of Words encoding algorithm. */ -BOOST_AUTO_TEST_CASE(BagOfWordsEncodingTest) +TEST_CASE("BagOfWordsEncodingTest", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; @@ -563,7 +562,7 @@ BOOST_AUTO_TEST_CASE(BagOfWordsEncodingTest) { keysCount[keyValue.second]++; - BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1); + REQUIRE(keysCount[keyValue.second] == 1); } /* The expected values were obtained by the following Python script: @@ -619,7 +618,7 @@ BOOST_AUTO_TEST_CASE(BagOfWordsEncodingTest) /** * Test the Bag of Words encoding algorithm. The output is saved into a vector. */ -BOOST_AUTO_TEST_CASE(VectorBagOfWordsEncodingTest) +TEST_CASE("VectorBagOfWordsEncodingTest", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; @@ -639,7 +638,7 @@ BOOST_AUTO_TEST_CASE(VectorBagOfWordsEncodingTest) { keysCount[keyValue.second]++; - BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1); + REQUIRE(keysCount[keyValue.second] == 1); } /* The expected values were obtained by the same script as in @@ -653,13 +652,13 @@ BOOST_AUTO_TEST_CASE(VectorBagOfWordsEncodingTest) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; - BOOST_REQUIRE(output == expected); + REQUIRE(output == expected); } /** * Test the Bag of Words algorithm for individual characters. */ -BOOST_AUTO_TEST_CASE(BagOfWordsEncodingIndividualCharactersTest) +TEST_CASE("BagOfWordsEncodingIndividualCharactersTest", "[StringEncodingTest]") { vector input = { "GACCA", @@ -685,7 +684,7 @@ BOOST_AUTO_TEST_CASE(BagOfWordsEncodingIndividualCharactersTest) * Test the Bag of Words encoding algorithm in case of individual * characters encoding. The output type is vector>. */ -BOOST_AUTO_TEST_CASE(VectorBagOfWordsEncodingIndividualCharactersTest) +TEST_CASE("VectorBagOfWordsEncodingIndividualCharactersTest", "[StringEncodingTest]") { std::vector input = { "GACCA", @@ -704,7 +703,7 @@ BOOST_AUTO_TEST_CASE(VectorBagOfWordsEncodingIndividualCharactersTest) { 1, 1, 0, 1, 0 } }; - BOOST_REQUIRE(output == expected); + REQUIRE(output == expected); } /** @@ -712,7 +711,7 @@ BOOST_AUTO_TEST_CASE(VectorBagOfWordsEncodingIndividualCharactersTest) * and the smooth inverse document frequency type. These parameters are * the default ones. */ -BOOST_AUTO_TEST_CASE(RawCountSmoothIdfEncodingTest) +TEST_CASE("RawCountSmoothIdfEncodingTest", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; @@ -730,7 +729,7 @@ BOOST_AUTO_TEST_CASE(RawCountSmoothIdfEncodingTest) { keysCount[keyValue.second]++; - BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1); + REQUIRE(keysCount[keyValue.second] == 1); } /* The expected values were obtained by the following Python script: @@ -814,7 +813,7 @@ BOOST_AUTO_TEST_CASE(RawCountSmoothIdfEncodingTest) * and the smooth inverse document frequency type. These parameters are * the default ones. The output type is vector>. */ -BOOST_AUTO_TEST_CASE(VectorRawCountSmoothIdfEncodingTest) +TEST_CASE("VectorRawCountSmoothIdfEncodingTest", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; @@ -834,7 +833,7 @@ BOOST_AUTO_TEST_CASE(VectorRawCountSmoothIdfEncodingTest) { keysCount[keyValue.second]++; - BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1); + REQUIRE(keysCount[keyValue.second] == 1); } /* The expected values were obtained by the same script as in @@ -862,7 +861,7 @@ BOOST_AUTO_TEST_CASE(VectorRawCountSmoothIdfEncodingTest) * raw count term frequency type and the smooth inverse document frequency type. * These parameters are the default ones. */ -BOOST_AUTO_TEST_CASE(RawCountSmoothIdfEncodingIndividualCharactersTest) +TEST_CASE("RawCountSmoothIdfEncodingIndividualCharactersTest", "[StringEncodingTest]") { vector input = { "GACCA", @@ -943,7 +942,7 @@ BOOST_AUTO_TEST_CASE(RawCountSmoothIdfEncodingIndividualCharactersTest) * These parameters are the default ones. The output type is * vector>. */ -BOOST_AUTO_TEST_CASE(VectorRawCountSmoothIdfEncodingIndividualCharactersTest) +TEST_CASE("VectorRawCountSmoothIdfEncodingIndividualCharactersTest", "[StringEncodingTest]") { std::vector input = { "GACCA", @@ -971,7 +970,7 @@ BOOST_AUTO_TEST_CASE(VectorRawCountSmoothIdfEncodingIndividualCharactersTest) * Test the Tf-Idf encoding algorithm with the raw count term frequency type * and the non-smooth inverse document frequency type. */ -BOOST_AUTO_TEST_CASE(TfIdfRawCountEncodingTest) +TEST_CASE("TfIdfRawCountEncodingTest", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; @@ -991,7 +990,7 @@ BOOST_AUTO_TEST_CASE(TfIdfRawCountEncodingTest) { keysCount[keyValue.second]++; - BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1); + REQUIRE(keysCount[keyValue.second] == 1); } /* The expected values were obtained by almost the same script as in @@ -1021,7 +1020,7 @@ BOOST_AUTO_TEST_CASE(TfIdfRawCountEncodingTest) * and the non-smooth inverse document frequency type. The output type is * vector>. */ -BOOST_AUTO_TEST_CASE(VectorTfIdfRawCountEncodingTest) +TEST_CASE("VectorTfIdfRawCountEncodingTest", "[StringEncodingTest]") { using DictionaryType = StringEncodingDictionary; @@ -1040,7 +1039,7 @@ BOOST_AUTO_TEST_CASE(VectorTfIdfRawCountEncodingTest) { keysCount[keyValue.second]++; - BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1); + REQUIRE(keysCount[keyValue.second] == 1); } /* The expected values were obtained by almost the same script as in @@ -1069,7 +1068,7 @@ BOOST_AUTO_TEST_CASE(VectorTfIdfRawCountEncodingTest) * raw count term frequency type and the non-smooth inverse document frequency * type. */ -BOOST_AUTO_TEST_CASE(RawCountTfIdfEncodingIndividualCharactersTest) +TEST_CASE("RawCountTfIdfEncodingIndividualCharactersTest", "[StringEncodingTest]") { vector input = { "GACCA", @@ -1100,7 +1099,7 @@ BOOST_AUTO_TEST_CASE(RawCountTfIdfEncodingIndividualCharactersTest) * raw count term frequency type and the non-smooth inverse document frequency * type. The output type is vector>. */ -BOOST_AUTO_TEST_CASE(VectorRawCountTfIdfEncodingIndividualCharactersTest) +TEST_CASE("VectorRawCountTfIdfEncodingIndividualCharactersTest", "[StringEncodingTest]") { std::vector input = { "GACCA", @@ -1130,7 +1129,7 @@ BOOST_AUTO_TEST_CASE(VectorRawCountTfIdfEncodingIndividualCharactersTest) * Test the Tf-Idf encoding algorithm for individual characters with the * binary term frequency type and the smooth inverse document frequency type. */ -BOOST_AUTO_TEST_CASE(BinarySmoothIdfEncodingIndividualCharactersTest) +TEST_CASE("BinarySmoothIdfEncodingIndividualCharactersTest", "[StringEncodingTest]") { vector input = { "GACCA", @@ -1161,7 +1160,7 @@ BOOST_AUTO_TEST_CASE(BinarySmoothIdfEncodingIndividualCharactersTest) * binary term frequency type and the smooth inverse document frequency type. * The output type is vector>. */ -BOOST_AUTO_TEST_CASE(VectorBinarySmoothIdfEncodingIndividualCharactersTest) +TEST_CASE("VectorBinarySmoothIdfEncodingIndividualCharactersTest", "[StringEncodingTest]") { std::vector input = { "GACCA", @@ -1192,7 +1191,7 @@ BOOST_AUTO_TEST_CASE(VectorBinarySmoothIdfEncodingIndividualCharactersTest) * binary term frequency type and the non-smooth inverse document frequency * type. */ -BOOST_AUTO_TEST_CASE(BinaryTfIdfEncodingIndividualCharactersTest) +TEST_CASE("BinaryTfIdfEncodingIndividualCharactersTest", "[StringEncodingTest]") { vector input = { "GACCA", @@ -1223,7 +1222,7 @@ BOOST_AUTO_TEST_CASE(BinaryTfIdfEncodingIndividualCharactersTest) * sublinear term frequency type and the smooth inverse document frequency * type. */ -BOOST_AUTO_TEST_CASE(SublinearSmoothIdfEncodingIndividualCharactersTest) +TEST_CASE("SublinearSmoothIdfEncodingIndividualCharactersTest", "[StringEncodingTest]") { vector input = { "GACCA", @@ -1255,7 +1254,7 @@ BOOST_AUTO_TEST_CASE(SublinearSmoothIdfEncodingIndividualCharactersTest) * sublinear term frequency type and the non-smooth inverse document frequency * type. */ -BOOST_AUTO_TEST_CASE(SublinearTfIdfEncodingIndividualCharactersTest) +TEST_CASE("SublinearTfIdfEncodingIndividualCharactersTest", "[StringEncodingTest]") { vector input = { "GACCA", @@ -1287,7 +1286,7 @@ BOOST_AUTO_TEST_CASE(SublinearTfIdfEncodingIndividualCharactersTest) * standard term frequency type and the smooth inverse document frequency * type. */ -BOOST_AUTO_TEST_CASE(TermFrequencySmoothIdfEncodingIndividualCharactersTest) +TEST_CASE("TermFrequencySmoothIdfEncodingIndividualCharactersTest", "[StringEncodingTest]") { vector input = { "GACCA", @@ -1368,7 +1367,7 @@ BOOST_AUTO_TEST_CASE(TermFrequencySmoothIdfEncodingIndividualCharactersTest) * standard term frequency type and the non-smooth inverse document frequency * type. */ -BOOST_AUTO_TEST_CASE(TermFrequencyTfIdfEncodingIndividualCharactersTest) +TEST_CASE("TermFrequencyTfIdfEncodingIndividualCharactersTest", "[StringEncodingTest]") { vector input = { "GACCA", @@ -1399,7 +1398,7 @@ BOOST_AUTO_TEST_CASE(TermFrequencyTfIdfEncodingIndividualCharactersTest) * Serialization test for the Tf-Idf encoding algorithm with * the SplitByAnyOf tokenizer. */ -BOOST_AUTO_TEST_CASE(SplitByAnyOfTfIdfEncodingSerialization) +TEST_CASE("SplitByAnyOfTfIdfEncodingSerialization", "[StringEncodingTest]") { using EncoderType = TfIdfEncoding; @@ -1424,6 +1423,3 @@ BOOST_AUTO_TEST_CASE(SplitByAnyOfTfIdfEncodingSerialization) CheckMatrices(output, xmlOutput, textOutput, binaryOutput); } - -BOOST_AUTO_TEST_SUITE_END(); - diff --git a/src/mlpack/tests/sumtree_test.cpp b/src/mlpack/tests/sumtree_test.cpp index a6d446dcdc..bfc350b3de 100644 --- a/src/mlpack/tests/sumtree_test.cpp +++ b/src/mlpack/tests/sumtree_test.cpp @@ -13,18 +13,16 @@ #include -#include -#include "test_tools.hpp" +#include "catch.hpp" +#include "test_catch_tools.hpp" using namespace mlpack; using namespace mlpack::rl; -BOOST_AUTO_TEST_SUITE(SumTreeTest); - /** * Test that we set the element. */ -BOOST_AUTO_TEST_CASE(SetElement) +TEST_CASE("SetElement", "[SumTreeTest]") { SumTree sumtree(4); sumtree.Set(0, 1.0); @@ -32,16 +30,16 @@ BOOST_AUTO_TEST_CASE(SetElement) sumtree.Set(2, 0.6); sumtree.Set(3, 0.4); - BOOST_CHECK_CLOSE(sumtree.Sum(), 2.8, 1e-8); - BOOST_CHECK_CLOSE(sumtree.Sum(0, 1), 1.0, 1e-8); - BOOST_CHECK_CLOSE(sumtree.Sum(0, 3), 2.4, 1e-8); - BOOST_CHECK_CLOSE(sumtree.Sum(1, 4), 1.8, 1e-8); + CHECK(sumtree.Sum() == Approx(2.8).epsilon(1e-10)); + CHECK(sumtree.Sum(0, 1) == Approx(1.0).epsilon(1e-10)); + CHECK(sumtree.Sum(0, 3) == Approx(2.4).epsilon(1e-10)); + CHECK(sumtree.Sum(1, 4) == Approx(1.8).epsilon(1e-10)); } /** * Test that we get the element. */ -BOOST_AUTO_TEST_CASE(GetElement) +TEST_CASE("GetElement", "[SumTreeTest]") { SumTree sumtree(4); sumtree.Set(0, 1.0); @@ -49,17 +47,17 @@ BOOST_AUTO_TEST_CASE(GetElement) sumtree.Set(2, 0.6); sumtree.Set(3, 0.4); - BOOST_CHECK_CLOSE(sumtree.Get(0), 1.0, 1e-8); - BOOST_CHECK_CLOSE(sumtree.Get(1), 0.8, 1e-8); - BOOST_CHECK_CLOSE(sumtree.Get(2), 0.6, 1e-8); - BOOST_CHECK_CLOSE(sumtree.Get(3), 0.4, 1e-8); + CHECK(sumtree.Get(0) == Approx(1.0).epsilon(1e-10)); + CHECK(sumtree.Get(1) == Approx(0.8).epsilon(1e-10)); + CHECK(sumtree.Get(2) == Approx(0.6).epsilon(1e-10)); + CHECK(sumtree.Get(3) == Approx(0.4).epsilon(1e-10)); } /** * Test that we find the highest index in the array such that * Sum(arr[0] + arr[1] + arr[2] ... + arr[i]) <= mass. */ -BOOST_AUTO_TEST_CASE(FindPrefixSum) +TEST_CASE("FindPrefixSum", "[SumTreeTest]") { SumTree sumtree(4); sumtree.Set(0, 1.0); @@ -67,17 +65,17 @@ BOOST_AUTO_TEST_CASE(FindPrefixSum) sumtree.Set(2, 0.6); sumtree.Set(3, 0.4); - BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(0), 0); - BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(1), 1); - BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(2.8), 3); - BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(3.0), 3); + CHECK(sumtree.FindPrefixSum(0) <= 0.0); + CHECK(sumtree.FindPrefixSum(1) <= 1.0); + CHECK(sumtree.FindPrefixSum(2.8) <= 3.0); + CHECK(sumtree.FindPrefixSum(3.0) <= 3.0); } /** * Test that we find the highest index in the array such that * sum(arr[0] + arr[1] + arr[2] ... + arr[i]) <= mass. */ -BOOST_AUTO_TEST_CASE(BatchUpdate) +TEST_CASE("BatchUpdate", "[SumTreeTest]") { SumTree sumtree(4); arma::ucolvec indices = {0, 1, 2, 3}; @@ -85,10 +83,8 @@ BOOST_AUTO_TEST_CASE(BatchUpdate) sumtree.BatchUpdate(indices, data); - BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(0), 0); - BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(1), 1); - BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(2.8), 3); - BOOST_CHECK_EQUAL(sumtree.FindPrefixSum(3.0), 3); + CHECK(sumtree.FindPrefixSum(0) <= 0); + CHECK(sumtree.FindPrefixSum(1) <= 1); + CHECK(sumtree.FindPrefixSum(2.8) <= 3); + CHECK(sumtree.FindPrefixSum(3.0) <= 3); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/tree_test.cpp b/src/mlpack/tests/tree_test.cpp index 9efb8c8769..c5a606323f 100644 --- a/src/mlpack/tests/tree_test.cpp +++ b/src/mlpack/tests/tree_test.cpp @@ -19,8 +19,8 @@ #include #include -#include -#include "test_tools.hpp" +#include "catch.hpp" +#include "test_catch_tools.hpp" using namespace mlpack; using namespace mlpack::math; @@ -28,47 +28,45 @@ using namespace mlpack::tree; using namespace mlpack::metric; using namespace mlpack::bound; -BOOST_AUTO_TEST_SUITE(TreeTest); - /** * Ensure that a bound, by default, is empty and has no dimensionality. */ -BOOST_AUTO_TEST_CASE(HRectBoundEmptyConstructor) +TEST_CASE("HRectBoundEmptyConstructor", "[TreeTest]") { HRectBound b; - BOOST_REQUIRE_EQUAL((int) b.Dim(), 0); - BOOST_REQUIRE_EQUAL(b.MinWidth(), 0.0); + REQUIRE((int) b.Dim() == 0); + REQUIRE(b.MinWidth() == 0.0); } /** * Ensure that when we specify the dimensionality in the constructor, it is * correct, and the bounds are all the empty set. */ -BOOST_AUTO_TEST_CASE(HRectBoundDimConstructor) +TEST_CASE("HRectBoundDimConstructor", "[TreeTest]") { HRectBound b(2); // We'll do this with 2 and 5 dimensions. - BOOST_REQUIRE_EQUAL(b.Dim(), 2); - BOOST_REQUIRE_SMALL(b[0].Width(), 1e-5); - BOOST_REQUIRE_SMALL(b[1].Width(), 1e-5); + REQUIRE(b.Dim() == 2); + REQUIRE(b[0].Width() == Approx(0.0).margin(1e-5)); + REQUIRE(b[1].Width() == Approx(0.0).margin(1e-5)); b = HRectBound(5); - BOOST_REQUIRE_EQUAL(b.Dim(), 5); - BOOST_REQUIRE_SMALL(b[0].Width(), 1e-5); - BOOST_REQUIRE_SMALL(b[1].Width(), 1e-5); - BOOST_REQUIRE_SMALL(b[2].Width(), 1e-5); - BOOST_REQUIRE_SMALL(b[3].Width(), 1e-5); - BOOST_REQUIRE_SMALL(b[4].Width(), 1e-5); + REQUIRE(b.Dim() == 5); + REQUIRE(b[0].Width() == Approx(0.0).margin(1e-5)); + REQUIRE(b[1].Width() == Approx(0.0).margin(1e-5)); + REQUIRE(b[2].Width() == Approx(0.0).margin(1e-5)); + REQUIRE(b[3].Width() == Approx(0.0).margin(1e-5)); + REQUIRE(b[4].Width() == Approx(0.0).margin(1e-5)); - BOOST_REQUIRE_EQUAL(b.MinWidth(), 0.0); + REQUIRE(b.MinWidth() == 0.0); } /** * Test the copy constructor. */ -BOOST_AUTO_TEST_CASE(HRectBoundCopyConstructor) +TEST_CASE("HRectBoundCopyConstructor", "[TreeTest]") { HRectBound b(2); b[0] = Range(0.0, 2.0); @@ -77,18 +75,18 @@ BOOST_AUTO_TEST_CASE(HRectBoundCopyConstructor) HRectBound c(b); - BOOST_REQUIRE_EQUAL(c.Dim(), 2); - BOOST_REQUIRE_SMALL(c[0].Lo(), 1e-5); - BOOST_REQUIRE_CLOSE(c[0].Hi(), 2.0, 1e-5); - BOOST_REQUIRE_CLOSE(c[1].Lo(), 2.0, 1e-5); - BOOST_REQUIRE_CLOSE(c[1].Hi(), 3.0, 1e-5); - BOOST_REQUIRE_CLOSE(c.MinWidth(), 0.5, 1e-5); + REQUIRE(c.Dim() == 2); + REQUIRE(c[0].Lo() == Approx(0.0).margin(1e-5)); + REQUIRE(c[0].Hi() == Approx(2.0).epsilon(1e-7)); + REQUIRE(c[1].Lo() == Approx(2.0).epsilon(1e-7)); + REQUIRE(c[1].Hi() == Approx(3.0).epsilon(1e-7)); + REQUIRE(c.MinWidth() == Approx(0.5).epsilon(1e-7)); } /** * Test the assignment operator. */ -BOOST_AUTO_TEST_CASE(HRectBoundAssignmentOperator) +TEST_CASE("HRectBoundAssignmentOperator", "[TreeTest]") { HRectBound b(2); b[0] = Range(0.0, 2.0); @@ -99,18 +97,18 @@ BOOST_AUTO_TEST_CASE(HRectBoundAssignmentOperator) c = b; - BOOST_REQUIRE_EQUAL(c.Dim(), 2); - BOOST_REQUIRE_SMALL(c[0].Lo(), 1e-5); - BOOST_REQUIRE_CLOSE(c[0].Hi(), 2.0, 1e-5); - BOOST_REQUIRE_CLOSE(c[1].Lo(), 2.0, 1e-5); - BOOST_REQUIRE_CLOSE(c[1].Hi(), 3.0, 1e-5); - BOOST_REQUIRE_CLOSE(c.MinWidth(), 0.5, 1e-5); + REQUIRE(c.Dim() == 2); + REQUIRE(c[0].Lo() == Approx(0.0).margin(1e-5)); + REQUIRE(c[0].Hi() == Approx(2.0).epsilon(1e-7)); + REQUIRE(c[1].Lo() == Approx(2.0).epsilon(1e-7)); + REQUIRE(c[1].Hi() == Approx(3.0).epsilon(1e-7)); + REQUIRE(c.MinWidth() == Approx(0.5).epsilon(1e-7)); } /** * Test that clearing the dimensions resets the bound to empty. */ -BOOST_AUTO_TEST_CASE(HRectBoundClear) +TEST_CASE("HRectBoundClear", "[TreeTest]") { HRectBound b(2); // We'll do this with two dimensions only. @@ -121,12 +119,12 @@ BOOST_AUTO_TEST_CASE(HRectBoundClear) // Now we just need to make sure that we clear the range. b.Clear(); - BOOST_REQUIRE_SMALL(b[0].Width(), 1e-5); - BOOST_REQUIRE_SMALL(b[1].Width(), 1e-5); - BOOST_REQUIRE_SMALL(b.MinWidth(), 1e-5); + REQUIRE(b[0].Width() == Approx(0.0).margin(1e-5)); + REQUIRE(b[1].Width() == Approx(0.0).margin(1e-5)); + REQUIRE(b.MinWidth() == Approx(0.0).margin(1e-5)); } -BOOST_AUTO_TEST_CASE(HRectBoundMoveConstructor) +TEST_CASE("HRectBoundMoveConstructor", "[TreeTest]") { HRectBound b(2); b[0] = Range(0.0, 2.0); @@ -135,22 +133,22 @@ BOOST_AUTO_TEST_CASE(HRectBoundMoveConstructor) HRectBound b2(std::move(b)); - BOOST_REQUIRE_EQUAL(b.Dim(), 0); - BOOST_REQUIRE_EQUAL(b2.Dim(), 2); + REQUIRE(b.Dim() == 0); + REQUIRE(b2.Dim() == 2); - BOOST_REQUIRE_EQUAL(b.MinWidth(), 0.0); - BOOST_REQUIRE_EQUAL(b2.MinWidth(), 1.0); + REQUIRE(b.MinWidth() == 0.0); + REQUIRE(b2.MinWidth() == 1.0); - BOOST_REQUIRE_SMALL(b2[0].Lo(), 1e-5); - BOOST_REQUIRE_CLOSE(b2[0].Hi(), 2.0, 1e-5); - BOOST_REQUIRE_CLOSE(b2[1].Lo(), 2.0, 1e-5); - BOOST_REQUIRE_CLOSE(b2[1].Hi(), 4.0, 1e-5); + REQUIRE(b2[0].Lo() == Approx(0.0).margin(1e-5)); + REQUIRE(b2[0].Hi() == Approx(2.0).epsilon(1e-7)); + REQUIRE(b2[1].Lo() == Approx(2.0).epsilon(1e-7)); + REQUIRE(b2[1].Hi() == Approx(4.0).epsilon(1e-7)); } /** * Ensure that we get the correct center for our bound. */ -BOOST_AUTO_TEST_CASE(HRectBoundCenter) +TEST_CASE("HRectBoundCenter", "[TreeTest]") { // Create a simple 3-dimensional bound. HRectBound b(3); @@ -163,16 +161,16 @@ BOOST_AUTO_TEST_CASE(HRectBoundCenter) b.Center(center); - BOOST_REQUIRE_EQUAL(center.n_elem, 3); - BOOST_REQUIRE_CLOSE(center[0], 2.5, 1e-5); - BOOST_REQUIRE_CLOSE(center[1], -1.5, 1e-5); - BOOST_REQUIRE_CLOSE(center[2], 20.0, 1e-5); + REQUIRE(center.n_elem == 3); + REQUIRE(center[0] == Approx(2.5).epsilon(1e-7)); + REQUIRE(center[1] == Approx(-1.5).epsilon(1e-7)); + REQUIRE(center[2] == Approx(20.0).epsilon(1e-7)); } /** * Ensure the volume calculation is correct. */ -BOOST_AUTO_TEST_CASE(HRectBoundVolume) +TEST_CASE("HRectBoundVolume", "[TreeTest]") { // Create a simple 3-dimensional bound. HRectBound b(3); @@ -181,14 +179,14 @@ BOOST_AUTO_TEST_CASE(HRectBoundVolume) b[1] = Range(-2.0, -1.0); b[2] = Range(-10.0, 50.0); - BOOST_REQUIRE_CLOSE(b.Volume(), 300.0, 1e-5); + REQUIRE(b.Volume() == Approx(300.0).epsilon(1e-7)); } /** * Ensure that we calculate the correct minimum distance between a point and a * bound. */ -BOOST_AUTO_TEST_CASE(HRectBoundMinDistancePoint) +TEST_CASE("HRectBoundMinDistancePoint", "[TreeTest]") { // We'll do the calculation in five dimensions, and we'll use three cases for // the point: point is outside the bound; point is on the edge of the bound; @@ -205,22 +203,22 @@ BOOST_AUTO_TEST_CASE(HRectBoundMinDistancePoint) arma::vec point = "-2.0 0.0 10.0 3.0 3.0"; // This will be the Euclidean distance. - BOOST_REQUIRE_CLOSE(b.MinDistance(point), sqrt(95.0), 1e-5); + REQUIRE(b.MinDistance(point) == Approx(sqrt(95.0)).epsilon(1e-7)); point = "2.0 5.0 2.0 -5.0 1.0"; - BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5); + REQUIRE(b.MinDistance(point) == Approx(0.0).margin(1e-5)); point = "1.0 2.0 0.0 -2.0 1.5"; - BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5); + REQUIRE(b.MinDistance(point) == Approx(0.0).margin(1e-5)); } /** * Ensure that we calculate the correct minimum distance between a bound and * another bound. */ -BOOST_AUTO_TEST_CASE(HRectBoundMinDistanceBound) +TEST_CASE("HRectBoundMinDistanceBound", "[TreeTest]") { // We'll do the calculation in five dimensions, and we can use six cases. // The other bound is completely outside the bound; the other bound is on the @@ -244,8 +242,8 @@ BOOST_AUTO_TEST_CASE(HRectBoundMinDistanceBound) c[3] = Range(2.0, 5.0); c[4] = Range(3.0, 4.0); - BOOST_REQUIRE_CLOSE(b.MinDistance(c), sqrt(22.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MinDistance(b), sqrt(22.0), 1e-5); + REQUIRE(b.MinDistance(c) == Approx(sqrt(22.0)).epsilon(1e-7)); + REQUIRE(c.MinDistance(b) == Approx(sqrt(22.0)).epsilon(1e-7)); // The other bound is on the edge of the bound. c[0] = Range(-2.0, 0.0); @@ -254,8 +252,8 @@ BOOST_AUTO_TEST_CASE(HRectBoundMinDistanceBound) c[3] = Range(-10.0, -5.0); c[4] = Range(2.0, 3.0); - BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5); - BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5); + REQUIRE(b.MinDistance(c) == Approx(0.0).margin(1e-5)); + REQUIRE(c.MinDistance(b) == Approx(0.0).margin(1e-5)); // The other bound partially overlaps the bound. c[0] = Range(-2.0, 1.0); @@ -264,12 +262,12 @@ BOOST_AUTO_TEST_CASE(HRectBoundMinDistanceBound) c[3] = Range(-8.0, -4.0); c[4] = Range(0.0, 4.0); - BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5); - BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5); + REQUIRE(b.MinDistance(c) == Approx(0.0).margin(1e-5)); + REQUIRE(c.MinDistance(b) == Approx(0.0).margin(1e-5)); // The other bound fully overlaps the bound. - BOOST_REQUIRE_SMALL(b.MinDistance(b), 1e-5); - BOOST_REQUIRE_SMALL(c.MinDistance(c), 1e-5); + REQUIRE(b.MinDistance(b) == Approx(0.0).margin(1e-5)); + REQUIRE(c.MinDistance(c) == Approx(0.0).margin(1e-5)); // The other bound is entirely inside the bound / the other bound entirely // envelops the bound. @@ -279,19 +277,19 @@ BOOST_AUTO_TEST_CASE(HRectBoundMinDistanceBound) c[3] = Range(-7.0, 0.0); c[4] = Range(0.0, 5.0); - BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5); - BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5); + REQUIRE(b.MinDistance(c) == Approx(0.0).margin(1e-5)); + REQUIRE(c.MinDistance(b) == Approx(0.0).margin(1e-5)); // Now we must be sure that the minimum distance to itself is 0. - BOOST_REQUIRE_SMALL(b.MinDistance(b), 1e-5); - BOOST_REQUIRE_SMALL(c.MinDistance(c), 1e-5); + REQUIRE(b.MinDistance(b) == Approx(0.0).margin(1e-5)); + REQUIRE(c.MinDistance(c) == Approx(0.0).margin(1e-5)); } /** * Ensure that we calculate the correct maximum distance between a bound and a * point. This uses the same test cases as the MinDistance test. */ -BOOST_AUTO_TEST_CASE(HRectBoundMaxDistancePoint) +TEST_CASE("HRectBoundMaxDistancePoint", "[TreeTest]") { // We'll do the calculation in five dimensions, and we'll use three cases for // the point: point is outside the bound; point is on the edge of the bound; @@ -308,22 +306,22 @@ BOOST_AUTO_TEST_CASE(HRectBoundMaxDistancePoint) arma::vec point = "-2.0 0.0 10.0 3.0 3.0"; // This will be the Euclidean distance. - BOOST_REQUIRE_CLOSE(b.MaxDistance(point), sqrt(253.0), 1e-5); + REQUIRE(b.MaxDistance(point) == Approx(sqrt(253.0)).epsilon(1e-7)); point = "2.0 5.0 2.0 -5.0 1.0"; - BOOST_REQUIRE_CLOSE(b.MaxDistance(point), sqrt(46.0), 1e-5); + REQUIRE(b.MaxDistance(point) == Approx(sqrt(46.0)).epsilon(1e-7)); point = "1.0 2.0 0.0 -2.0 1.5"; - BOOST_REQUIRE_CLOSE(b.MaxDistance(point), sqrt(23.25), 1e-5); + REQUIRE(b.MaxDistance(point) == Approx(sqrt(23.25)).epsilon(1e-7)); } /** * Ensure that we calculate the correct maximum distance between a bound and * another bound. This uses the same test cases as the MinDistance test. */ -BOOST_AUTO_TEST_CASE(HRectBoundMaxDistanceBound) +TEST_CASE("HRectBoundMaxDistanceBound", "[TreeTest]") { // We'll do the calculation in five dimensions, and we can use six cases. // The other bound is completely outside the bound; the other bound is on the @@ -347,8 +345,8 @@ BOOST_AUTO_TEST_CASE(HRectBoundMaxDistanceBound) c[3] = Range(2.0, 5.0); c[4] = Range(3.0, 4.0); - BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(210.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(210.0), 1e-5); + REQUIRE(b.MaxDistance(c) == Approx(sqrt(210.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(b) == Approx(sqrt(210.0)).epsilon(1e-7)); // The other bound is on the edge of the bound. c[0] = Range(-2.0, 0.0); @@ -357,8 +355,8 @@ BOOST_AUTO_TEST_CASE(HRectBoundMaxDistanceBound) c[3] = Range(-10.0, -5.0); c[4] = Range(2.0, 3.0); - BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(134.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(134.0), 1e-5); + REQUIRE(b.MaxDistance(c) == Approx(sqrt(134.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(b) == Approx(sqrt(134.0)).epsilon(1e-7)); // The other bound partially overlaps the bound. c[0] = Range(-2.0, 1.0); @@ -367,12 +365,12 @@ BOOST_AUTO_TEST_CASE(HRectBoundMaxDistanceBound) c[3] = Range(-8.0, -4.0); c[4] = Range(0.0, 4.0); - BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(102.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(102.0), 1e-5); + REQUIRE(b.MaxDistance(c) == Approx(sqrt(102.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(b) == Approx(sqrt(102.0)).epsilon(1e-7)); // The other bound fully overlaps the bound. - BOOST_REQUIRE_CLOSE(b.MaxDistance(b), sqrt(46.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(c), sqrt(61.0), 1e-5); + REQUIRE(b.MaxDistance(b) == Approx(sqrt(46.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(c) == Approx(sqrt(61.0)).epsilon(1e-7)); // The other bound is entirely inside the bound / the other bound entirely // envelops the bound. @@ -382,13 +380,13 @@ BOOST_AUTO_TEST_CASE(HRectBoundMaxDistanceBound) c[3] = Range(-7.0, 0.0); c[4] = Range(0.0, 5.0); - BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(100.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(100.0), 1e-5); + REQUIRE(b.MaxDistance(c) == Approx(sqrt(100.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(b) == Approx(sqrt(100.0)).epsilon(1e-7)); // Identical bounds. This will be the sum of the squared widths in each // dimension. - BOOST_REQUIRE_CLOSE(b.MaxDistance(b), sqrt(46.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(c), sqrt(162.0), 1e-5); + REQUIRE(b.MaxDistance(b) == Approx(sqrt(46.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(c) == Approx(sqrt(162.0)).epsilon(1e-7)); // One last additional case. If the bound encloses only one point, the // maximum distance between it and itself is 0. @@ -397,7 +395,7 @@ BOOST_AUTO_TEST_CASE(HRectBoundMaxDistanceBound) d[0] = Range(2.0, 2.0); d[1] = Range(3.0, 3.0); - BOOST_REQUIRE_SMALL(d.MaxDistance(d), 1e-5); + REQUIRE(d.MaxDistance(d) == Approx(0.0).margin(1e-5)); } /** @@ -406,7 +404,7 @@ BOOST_AUTO_TEST_CASE(HRectBoundMaxDistanceBound) * and comparing the behavior to MinDistance() and MaxDistance() -- so this test * is assuming that those passed and operate correctly. */ -BOOST_AUTO_TEST_CASE(HRectBoundRangeDistanceBound) +TEST_CASE("HRectBoundRangeDistanceBound", "[TreeTest]") { for (int i = 0; i < 50; ++i) { @@ -439,14 +437,14 @@ BOOST_AUTO_TEST_CASE(HRectBoundRangeDistanceBound) Range r = a.RangeDistance(b); Range s = b.RangeDistance(a); - BOOST_REQUIRE_CLOSE(r.Lo(), s.Lo(), 1e-5); - BOOST_REQUIRE_CLOSE(r.Hi(), s.Hi(), 1e-5); + REQUIRE(r.Lo() == Approx(s.Lo()).epsilon(1e-7)); + REQUIRE(r.Hi() == Approx(s.Hi()).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(r.Lo(), a.MinDistance(b), 1e-5); - BOOST_REQUIRE_CLOSE(r.Hi(), a.MaxDistance(b), 1e-5); + REQUIRE(r.Lo() == Approx(a.MinDistance(b)).epsilon(1e-7)); + REQUIRE(r.Hi() == Approx(a.MaxDistance(b)).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(s.Lo(), b.MinDistance(a), 1e-5); - BOOST_REQUIRE_CLOSE(s.Hi(), b.MaxDistance(a), 1e-5); + REQUIRE(s.Lo() == Approx(b.MinDistance(a)).epsilon(1e-7)); + REQUIRE(s.Hi() == Approx(b.MaxDistance(a)).epsilon(1e-7)); } } @@ -457,7 +455,7 @@ BOOST_AUTO_TEST_CASE(HRectBoundRangeDistanceBound) * is assuming that those passed and operate correctly. This is for the * bound-to-point case. */ -BOOST_AUTO_TEST_CASE(HRectBoundRangeDistancePoint) +TEST_CASE("HRectBoundRangeDistancePoint", "[TreeTest]") { for (int i = 0; i < 20; ++i) { @@ -485,8 +483,8 @@ BOOST_AUTO_TEST_CASE(HRectBoundRangeDistancePoint) Range r = a.RangeDistance(point); - BOOST_REQUIRE_CLOSE(r.Lo(), a.MinDistance(point), 1e-5); - BOOST_REQUIRE_CLOSE(r.Hi(), a.MaxDistance(point), 1e-5); + REQUIRE(r.Lo() == Approx(a.MinDistance(point)).epsilon(1e-7)); + REQUIRE(r.Hi() == Approx(a.MaxDistance(point)).epsilon(1e-7)); } } } @@ -494,7 +492,7 @@ BOOST_AUTO_TEST_CASE(HRectBoundRangeDistancePoint) /** * Test that we can expand the bound to include a new point. */ -BOOST_AUTO_TEST_CASE(HRectBoundOrOperatorPoint) +TEST_CASE("HRectBoundOrOperatorPoint", "[TreeTest]") { // Because this should be independent in each dimension, we can essentially // run five test cases at once. @@ -511,23 +509,23 @@ BOOST_AUTO_TEST_CASE(HRectBoundOrOperatorPoint) b |= point; - BOOST_REQUIRE_CLOSE(b[0].Lo(), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[0].Hi(), 3.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[1].Lo(), 2.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[1].Hi(), 4.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[2].Lo(), -2.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[2].Hi(), 2.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[3].Lo(), -1.0, 1e-5); - BOOST_REQUIRE_SMALL(b[3].Hi(), 1e-5); - BOOST_REQUIRE_CLOSE(b[4].Lo(), 6.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[4].Hi(), 6.0, 1e-5); - BOOST_REQUIRE_SMALL(b.MinWidth(), 1e-5); + REQUIRE(b[0].Lo() == Approx(1.0).epsilon(1e-7)); + REQUIRE(b[0].Hi() == Approx(3.0).epsilon(1e-7)); + REQUIRE(b[1].Lo() == Approx(2.0).epsilon(1e-7)); + REQUIRE(b[1].Hi() == Approx(4.0).epsilon(1e-7)); + REQUIRE(b[2].Lo() == Approx(-2.0).epsilon(1e-7)); + REQUIRE(b[2].Hi() == Approx(2.0).epsilon(1e-7)); + REQUIRE(b[3].Lo() == Approx(-1.0).epsilon(1e-7)); + REQUIRE(b[3].Hi() == Approx(0.0).margin(1e-5)); + REQUIRE(b[4].Lo() == Approx(6.0).epsilon(1e-7)); + REQUIRE(b[4].Hi() == Approx(6.0).epsilon(1e-7)); + REQUIRE(b.MinWidth() == Approx(0.0).margin(1e-5)); } /** * Test that we can expand the bound to include another bound. */ -BOOST_AUTO_TEST_CASE(HRectBoundOrOperatorBound) +TEST_CASE("HRectBoundOrOperatorBound", "[TreeTest]") { // Because this should be independent in each dimension, we can run many tests // at once. @@ -558,55 +556,55 @@ BOOST_AUTO_TEST_CASE(HRectBoundOrOperatorBound) b |= c; d |= b; - BOOST_REQUIRE_CLOSE(b[0].Lo(), -3.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[0].Hi(), 3.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[0].Lo(), -3.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[0].Hi(), 3.0, 1e-5); + REQUIRE(b[0].Lo() == Approx(-3.0).epsilon(1e-7)); + REQUIRE(b[0].Hi() == Approx(3.0).epsilon(1e-7)); + REQUIRE(d[0].Lo() == Approx(-3.0).epsilon(1e-7)); + REQUIRE(d[0].Hi() == Approx(3.0).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(b[1].Lo(), 0.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[1].Hi(), 4.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[1].Lo(), 0.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[1].Hi(), 4.0, 1e-5); + REQUIRE(b[1].Lo() == Approx(0.0).epsilon(1e-7)); + REQUIRE(b[1].Hi() == Approx(4.0).epsilon(1e-7)); + REQUIRE(d[1].Lo() == Approx(0.0).epsilon(1e-7)); + REQUIRE(d[1].Hi() == Approx(4.0).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(b[2].Lo(), -3.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[2].Hi(), -1.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[2].Lo(), -3.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[2].Hi(), -1.0, 1e-5); + REQUIRE(b[2].Lo() == Approx(-3.0).epsilon(1e-7)); + REQUIRE(b[2].Hi() == Approx(-1.0).epsilon(1e-7)); + REQUIRE(d[2].Lo() == Approx(-3.0).epsilon(1e-7)); + REQUIRE(d[2].Hi() == Approx(-1.0).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(b[3].Lo(), 4.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[3].Hi(), 5.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[3].Lo(), 4.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[3].Hi(), 5.0, 1e-5); + REQUIRE(b[3].Lo() == Approx(4.0).epsilon(1e-7)); + REQUIRE(b[3].Hi() == Approx(5.0).epsilon(1e-7)); + REQUIRE(d[3].Lo() == Approx(4.0).epsilon(1e-7)); + REQUIRE(d[3].Hi() == Approx(5.0).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(b[4].Lo(), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[4].Hi(), 5.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[4].Lo(), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[4].Hi(), 5.0, 1e-5); + REQUIRE(b[4].Lo() == Approx(1.0).epsilon(1e-7)); + REQUIRE(b[4].Hi() == Approx(5.0).epsilon(1e-7)); + REQUIRE(d[4].Lo() == Approx(1.0).epsilon(1e-7)); + REQUIRE(d[4].Hi() == Approx(5.0).epsilon(1e-7)); - BOOST_REQUIRE_SMALL(b[5].Lo(), 1e-5); - BOOST_REQUIRE_CLOSE(b[5].Hi(), 2.0, 1e-5); - BOOST_REQUIRE_SMALL(d[5].Lo(), 1e-5); - BOOST_REQUIRE_CLOSE(d[5].Hi(), 2.0, 1e-5); + REQUIRE(b[5].Lo() == Approx(0.0).margin(1e-5)); + REQUIRE(b[5].Hi() == Approx(2.0).epsilon(1e-7)); + REQUIRE(d[5].Lo() == Approx(0.0).margin(1e-5)); + REQUIRE(d[5].Hi() == Approx(2.0).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(b[6].Lo(), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[6].Hi(), 3.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[6].Lo(), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[6].Hi(), 3.0, 1e-5); + REQUIRE(b[6].Lo() == Approx(1.0).epsilon(1e-7)); + REQUIRE(b[6].Hi() == Approx(3.0).epsilon(1e-7)); + REQUIRE(d[6].Lo() == Approx(1.0).epsilon(1e-7)); + REQUIRE(d[6].Hi() == Approx(3.0).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(b[7].Lo(), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(b[7].Hi(), 3.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[7].Lo(), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(d[7].Hi(), 3.0, 1e-5); + REQUIRE(b[7].Lo() == Approx(1.0).epsilon(1e-7)); + REQUIRE(b[7].Hi() == Approx(3.0).epsilon(1e-7)); + REQUIRE(d[7].Lo() == Approx(1.0).epsilon(1e-7)); + REQUIRE(d[7].Hi() == Approx(3.0).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(b.MinWidth(), 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(d.MinWidth(), 1.0, 1e-5); + REQUIRE(b.MinWidth() == Approx(1.0).epsilon(1e-7)); + REQUIRE(d.MinWidth() == Approx(1.0).epsilon(1e-7)); } /** * Test that the Contains() function correctly figures out whether or not a * point is in a bound. */ -BOOST_AUTO_TEST_CASE(HRectBoundContains) +TEST_CASE("HRectBoundContains", "[TreeTest]") { // We can test a couple different points: completely outside the bound, // adjacent in one dimension to the bound, adjacent in all dimensions to the @@ -619,30 +617,30 @@ BOOST_AUTO_TEST_CASE(HRectBoundContains) // Completely outside the range. arma::vec point = "-1.0 4.0 4.0"; - BOOST_REQUIRE(!b.Contains(point)); + REQUIRE(!b.Contains(point)); // Completely outside, but one dimension is in the range. point = "-1.0 4.0 1.0"; - BOOST_REQUIRE(!b.Contains(point)); + REQUIRE(!b.Contains(point)); // Outside, but one dimension is on the edge. point = "-1.0 0.0 3.0"; - BOOST_REQUIRE(!b.Contains(point)); + REQUIRE(!b.Contains(point)); // Two dimensions are on the edge, but one is outside. point = "0.0 0.0 3.0"; - BOOST_REQUIRE(!b.Contains(point)); + REQUIRE(!b.Contains(point)); // Completely on the edge (should be contained). point = "0.0 0.0 0.0"; - BOOST_REQUIRE(b.Contains(point)); + REQUIRE(b.Contains(point)); // Inside the range. point = "0.3 1.0 0.4"; - BOOST_REQUIRE(b.Contains(point)); + REQUIRE(b.Contains(point)); } -BOOST_AUTO_TEST_CASE(TestBallBound) +TEST_CASE("TestBallBound", "[TreeTest]") { BallBound<> b1; BallBound<> b2; @@ -661,57 +659,57 @@ BOOST_AUTO_TEST_CASE(TestBallBound) b2.Center()[2] = 4; b2.Radius() = 0.4; - BOOST_REQUIRE_CLOSE(b1.MinDistance(b2), 1-0.3-0.4, 1e-5); - BOOST_REQUIRE_CLOSE(b1.RangeDistance(b2).Hi(), 1+0.3+0.4, 1e-5); - BOOST_REQUIRE_CLOSE(b1.RangeDistance(b2).Lo(), 1-0.3-0.4, 1e-5); - BOOST_REQUIRE_CLOSE(b1.RangeDistance(b2).Hi(), 1+0.3+0.4, 1e-5); - BOOST_REQUIRE_CLOSE(b1.RangeDistance(b2).Lo(), 1-0.3-0.4, 1e-5); + REQUIRE(b1.MinDistance(b2) == Approx(1-0.3-0.4).epsilon(1e-7)); + REQUIRE(b1.RangeDistance(b2).Hi() == Approx(1+0.3+0.4).epsilon(1e-7)); + REQUIRE(b1.RangeDistance(b2).Lo() == Approx(1-0.3-0.4).epsilon(1e-7)); + REQUIRE(b1.RangeDistance(b2).Hi() == Approx(1+0.3+0.4).epsilon(1e-7)); + REQUIRE(b1.RangeDistance(b2).Lo() == Approx(1-0.3-0.4).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(b2.MinDistance(b1), 1-0.3-0.4, 1e-5); - BOOST_REQUIRE_CLOSE(b2.MaxDistance(b1), 1+0.3+0.4, 1e-5); - BOOST_REQUIRE_CLOSE(b2.RangeDistance(b1).Hi(), 1+0.3+0.4, 1e-5); - BOOST_REQUIRE_CLOSE(b2.RangeDistance(b1).Lo(), 1-0.3-0.4, 1e-5); + REQUIRE(b2.MinDistance(b1) == Approx(1-0.3-0.4).epsilon(1e-7)); + REQUIRE(b2.MaxDistance(b1) == Approx(1+0.3+0.4).epsilon(1e-7)); + REQUIRE(b2.RangeDistance(b1).Hi() == Approx(1+0.3+0.4).epsilon(1e-7)); + REQUIRE(b2.RangeDistance(b1).Lo() == Approx(1-0.3-0.4).epsilon(1e-7)); - BOOST_REQUIRE(b1.Contains(b1.Center())); - BOOST_REQUIRE(!b1.Contains(b2.Center())); + REQUIRE(b1.Contains(b1.Center())); + REQUIRE(!b1.Contains(b2.Center())); - BOOST_REQUIRE(!b2.Contains(b1.Center())); - BOOST_REQUIRE(b2.Contains(b2.Center())); + REQUIRE(!b2.Contains(b1.Center())); + REQUIRE(b2.Contains(b2.Center())); arma::vec b2point(3); // A point that's within the radius but not the center. b2point[0] = 1.1; b2point[1] = 2.1; b2point[2] = 4.1; - BOOST_REQUIRE(b2.Contains(b2point)); + REQUIRE(b2.Contains(b2point)); - BOOST_REQUIRE_SMALL(b1.MinDistance(b1.Center()), 1e-5); - BOOST_REQUIRE_CLOSE(b1.MinDistance(b2.Center()), 1 - 0.3, 1e-5); - BOOST_REQUIRE_CLOSE(b2.MinDistance(b1.Center()), 1 - 0.4, 1e-5); - BOOST_REQUIRE_CLOSE(b2.MaxDistance(b1.Center()), 1 + 0.4, 1e-5); - BOOST_REQUIRE_CLOSE(b1.MaxDistance(b2.Center()), 1 + 0.3, 1e-5); + REQUIRE(b1.MinDistance(b1.Center()) == Approx(0.0).margin(1e-5)); + REQUIRE(b1.MinDistance(b2.Center()) == Approx(1 - 0.3).epsilon(1e-7)); + REQUIRE(b2.MinDistance(b1.Center()) == Approx(1 - 0.4).epsilon(1e-7)); + REQUIRE(b2.MaxDistance(b1.Center()) == Approx(1 + 0.4).epsilon(1e-7)); + REQUIRE(b1.MaxDistance(b2.Center()) == Approx(1 + 0.3).epsilon(1e-7)); } -BOOST_AUTO_TEST_CASE(BallBoundMoveConstructor) +TEST_CASE("BallBoundMoveConstructor", "[TreeTest]") { BallBound<> b1(2.0, arma::vec("2 1 1")); BallBound<> b2(std::move(b1)); - BOOST_REQUIRE_EQUAL(b2.Dim(), 3); - BOOST_REQUIRE_EQUAL(b1.Dim(), 0); + REQUIRE(b2.Dim() == 3); + REQUIRE(b1.Dim() == 0); - BOOST_REQUIRE_CLOSE(b2.Center()[0], 2.0, 1e-5); - BOOST_REQUIRE_CLOSE(b2.Center()[1], 1.0, 1e-5); - BOOST_REQUIRE_CLOSE(b2.Center()[2], 1.0, 1e-5); + REQUIRE(b2.Center()[0] == Approx(2.0).epsilon(1e-7)); + REQUIRE(b2.Center()[1] == Approx(1.0).epsilon(1e-7)); + REQUIRE(b2.Center()[2] == Approx(1.0).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(b2.MinWidth(), 4.0, 1e-5); - BOOST_REQUIRE_SMALL(b1.MinWidth(), 1e-5); + REQUIRE(b2.MinWidth() == Approx(4.0).epsilon(1e-7)); + REQUIRE(b1.MinWidth() == Approx(0.0).margin(1e-5)); } /** * Ensure that we calculate the correct minimum distance between a point and a * bound. */ -BOOST_AUTO_TEST_CASE(HRectBoundRootMinDistancePoint) +TEST_CASE("HRectBoundRootMinDistancePoint", "[TreeTest]") { // We'll do the calculation in five dimensions, and we'll use three cases for // the point: point is outside the bound; point is on the edge of the bound; @@ -728,22 +726,22 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMinDistancePoint) arma::vec point = "-2.0 0.0 10.0 3.0 3.0"; // This will be the Euclidean distance. - BOOST_REQUIRE_CLOSE(b.MinDistance(point), sqrt(95.0), 1e-5); + REQUIRE(b.MinDistance(point) == Approx(sqrt(95.0)).epsilon(1e-7)); point = "2.0 5.0 2.0 -5.0 1.0"; - BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5); + REQUIRE(b.MinDistance(point) == Approx(0.0).margin(1e-5)); point = "1.0 2.0 0.0 -2.0 1.5"; - BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5); + REQUIRE(b.MinDistance(point) == Approx(0.0).margin(1e-5)); } /** * Ensure that we calculate the correct minimum distance between a bound and * another bound. */ -BOOST_AUTO_TEST_CASE(HRectBoundRootMinDistanceBound) +TEST_CASE("HRectBoundRootMinDistanceBound", "[TreeTest]") { // We'll do the calculation in five dimensions, and we can use six cases. // The other bound is completely outside the bound; the other bound is on the @@ -767,8 +765,8 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMinDistanceBound) c[3] = Range(2.0, 5.0); c[4] = Range(3.0, 4.0); - BOOST_REQUIRE_CLOSE(b.MinDistance(c), sqrt(22.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MinDistance(b), sqrt(22.0), 1e-5); + REQUIRE(b.MinDistance(c) == Approx(sqrt(22.0)).epsilon(1e-7)); + REQUIRE(c.MinDistance(b) == Approx(sqrt(22.0)).epsilon(1e-7)); // The other bound is on the edge of the bound. c[0] = Range(-2.0, 0.0); @@ -777,8 +775,8 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMinDistanceBound) c[3] = Range(-10.0, -5.0); c[4] = Range(2.0, 3.0); - BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5); - BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5); + REQUIRE(b.MinDistance(c) == Approx(0.0).margin(1e-5)); + REQUIRE(c.MinDistance(b) == Approx(0.0).margin(1e-5)); // The other bound partially overlaps the bound. c[0] = Range(-2.0, 1.0); @@ -787,12 +785,12 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMinDistanceBound) c[3] = Range(-8.0, -4.0); c[4] = Range(0.0, 4.0); - BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5); - BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5); + REQUIRE(b.MinDistance(c) == Approx(0.0).margin(1e-5)); + REQUIRE(c.MinDistance(b) == Approx(0.0).margin(1e-5)); // The other bound fully overlaps the bound. - BOOST_REQUIRE_SMALL(b.MinDistance(b), 1e-5); - BOOST_REQUIRE_SMALL(c.MinDistance(c), 1e-5); + REQUIRE(b.MinDistance(b) == Approx(0.0).margin(1e-5)); + REQUIRE(c.MinDistance(c) == Approx(0.0).margin(1e-5)); // The other bound is entirely inside the bound / the other bound entirely // envelops the bound. @@ -802,19 +800,19 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMinDistanceBound) c[3] = Range(-7.0, 0.0); c[4] = Range(0.0, 5.0); - BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5); - BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5); + REQUIRE(b.MinDistance(c) == Approx(0.0).margin(1e-5)); + REQUIRE(c.MinDistance(b) == Approx(0.0).margin(1e-5)); // Now we must be sure that the minimum distance to itself is 0. - BOOST_REQUIRE_SMALL(b.MinDistance(b), 1e-5); - BOOST_REQUIRE_SMALL(c.MinDistance(c), 1e-5); + REQUIRE(b.MinDistance(b) == Approx(0.0).margin(1e-5)); + REQUIRE(c.MinDistance(c) == Approx(0.0).margin(1e-5)); } /** * Ensure that we calculate the correct maximum distance between a bound and a * point. This uses the same test cases as the MinDistance test. */ -BOOST_AUTO_TEST_CASE(HRectBoundRootMaxDistancePoint) +TEST_CASE("HRectBoundRootMaxDistancePoint", "[TreeTest]") { // We'll do the calculation in five dimensions, and we'll use three cases for // the point: point is outside the bound; point is on the edge of the bound; @@ -831,22 +829,22 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMaxDistancePoint) arma::vec point = "-2.0 0.0 10.0 3.0 3.0"; // This will be the Euclidean distance. - BOOST_REQUIRE_CLOSE(b.MaxDistance(point), sqrt(253.0), 1e-5); + REQUIRE(b.MaxDistance(point) == Approx(sqrt(253.0)).epsilon(1e-7)); point = "2.0 5.0 2.0 -5.0 1.0"; - BOOST_REQUIRE_CLOSE(b.MaxDistance(point), sqrt(46.0), 1e-5); + REQUIRE(b.MaxDistance(point) == Approx(sqrt(46.0)).epsilon(1e-7)); point = "1.0 2.0 0.0 -2.0 1.5"; - BOOST_REQUIRE_CLOSE(b.MaxDistance(point), sqrt(23.25), 1e-5); + REQUIRE(b.MaxDistance(point) == Approx(sqrt(23.25)).epsilon(1e-7)); } /** * Ensure that we calculate the correct maximum distance between a bound and * another bound. This uses the same test cases as the MinDistance test. */ -BOOST_AUTO_TEST_CASE(HRectBoundRootMaxDistanceBound) +TEST_CASE("HRectBoundRootMaxDistanceBound", "[TreeTest]") { // We'll do the calculation in five dimensions, and we can use six cases. // The other bound is completely outside the bound; the other bound is on the @@ -870,8 +868,8 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMaxDistanceBound) c[3] = Range(2.0, 5.0); c[4] = Range(3.0, 4.0); - BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(210.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(210.0), 1e-5); + REQUIRE(b.MaxDistance(c) == Approx(sqrt(210.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(b) == Approx(sqrt(210.0)).epsilon(1e-7)); // The other bound is on the edge of the bound. c[0] = Range(-2.0, 0.0); @@ -880,8 +878,8 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMaxDistanceBound) c[3] = Range(-10.0, -5.0); c[4] = Range(2.0, 3.0); - BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(134.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(134.0), 1e-5); + REQUIRE(b.MaxDistance(c) == Approx(sqrt(134.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(b) == Approx(sqrt(134.0)).epsilon(1e-7)); // The other bound partially overlaps the bound. c[0] = Range(-2.0, 1.0); @@ -890,12 +888,12 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMaxDistanceBound) c[3] = Range(-8.0, -4.0); c[4] = Range(0.0, 4.0); - BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(102.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(102.0), 1e-5); + REQUIRE(b.MaxDistance(c) == Approx(sqrt(102.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(b) == Approx(sqrt(102.0)).epsilon(1e-7)); // The other bound fully overlaps the bound. - BOOST_REQUIRE_CLOSE(b.MaxDistance(b), sqrt(46.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(c), sqrt(61.0), 1e-5); + REQUIRE(b.MaxDistance(b) == Approx(sqrt(46.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(c) == Approx(sqrt(61.0)).epsilon(1e-7)); // The other bound is entirely inside the bound / the other bound entirely // envelops the bound. @@ -905,13 +903,13 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMaxDistanceBound) c[3] = Range(-7.0, 0.0); c[4] = Range(0.0, 5.0); - BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(100.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(100.0), 1e-5); + REQUIRE(b.MaxDistance(c) == Approx(sqrt(100.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(b) == Approx(sqrt(100.0)).epsilon(1e-7)); // Identical bounds. This will be the sum of the squared widths in each // dimension. - BOOST_REQUIRE_CLOSE(b.MaxDistance(b), sqrt(46.0), 1e-5); - BOOST_REQUIRE_CLOSE(c.MaxDistance(c), sqrt(162.0), 1e-5); + REQUIRE(b.MaxDistance(b) == Approx(sqrt(46.0)).epsilon(1e-7)); + REQUIRE(c.MaxDistance(c) == Approx(sqrt(162.0)).epsilon(1e-7)); // One last additional case. If the bound encloses only one point, the // maximum distance between it and itself is 0. @@ -920,7 +918,7 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMaxDistanceBound) d[0] = Range(2.0, 2.0); d[1] = Range(3.0, 3.0); - BOOST_REQUIRE_SMALL(d.MaxDistance(d), 1e-5); + REQUIRE(d.MaxDistance(d) == Approx(0.0).margin(1e-5)); } /** @@ -929,7 +927,7 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootMaxDistanceBound) * and comparing the behavior to MinDistance() and MaxDistance() -- so this test * is assuming that those passed and operate correctly. */ -BOOST_AUTO_TEST_CASE(HRectBoundRootRangeDistanceBound) +TEST_CASE("HRectBoundRootRangeDistanceBound", "[TreeTest]") { for (int i = 0; i < 50; ++i) { @@ -962,14 +960,14 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootRangeDistanceBound) Range r = a.RangeDistance(b); Range s = b.RangeDistance(a); - BOOST_REQUIRE_CLOSE(r.Lo(), s.Lo(), 1e-5); - BOOST_REQUIRE_CLOSE(r.Hi(), s.Hi(), 1e-5); + REQUIRE(r.Lo() == Approx(s.Lo()).epsilon(1e-7)); + REQUIRE(r.Hi() == Approx(s.Hi()).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(r.Lo(), a.MinDistance(b), 1e-5); - BOOST_REQUIRE_CLOSE(r.Hi(), a.MaxDistance(b), 1e-5); + REQUIRE(r.Lo() == Approx(a.MinDistance(b)).epsilon(1e-7)); + REQUIRE(r.Hi() == Approx(a.MaxDistance(b)).epsilon(1e-7)); - BOOST_REQUIRE_CLOSE(s.Lo(), b.MinDistance(a), 1e-5); - BOOST_REQUIRE_CLOSE(s.Hi(), b.MaxDistance(a), 1e-5); + REQUIRE(s.Lo() == Approx(b.MinDistance(a)).epsilon(1e-7)); + REQUIRE(s.Hi() == Approx(b.MaxDistance(a)).epsilon(1e-7)); } } @@ -980,7 +978,7 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootRangeDistanceBound) * is assuming that those passed and operate correctly. This is for the * bound-to-point case. */ -BOOST_AUTO_TEST_CASE(HRectBoundRootRangeDistancePoint) +TEST_CASE("HRectBoundRootRangeDistancePoint", "[TreeTest]") { for (int i = 0; i < 20; ++i) { @@ -1008,8 +1006,8 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootRangeDistancePoint) Range r = a.RangeDistance(point); - BOOST_REQUIRE_CLOSE(r.Lo(), a.MinDistance(point), 1e-5); - BOOST_REQUIRE_CLOSE(r.Hi(), a.MaxDistance(point), 1e-5); + REQUIRE(r.Lo() == Approx(a.MinDistance(point)).epsilon(1e-7)); + REQUIRE(r.Hi() == Approx(a.MaxDistance(point)).epsilon(1e-7)); } } } @@ -1017,7 +1015,7 @@ BOOST_AUTO_TEST_CASE(HRectBoundRootRangeDistancePoint) /** * Ensure that HRectBound::Diameter() works properly. */ -BOOST_AUTO_TEST_CASE(HRectBoundDiameter) +TEST_CASE("HRectBoundDiameter", "[TreeTest]") { HRectBound> b(4); b[0] = math::Range(0.0, 1.0); @@ -1025,7 +1023,7 @@ BOOST_AUTO_TEST_CASE(HRectBoundDiameter) b[2] = math::Range(2.0, 3.0); b[3] = math::Range(7.0, 7.0); - BOOST_REQUIRE_CLOSE(b.Diameter(), std::pow(3.0, 1.0 / 3.0), 1e-5); + REQUIRE(b.Diameter()== Approx(std::pow(3.0, 1.0 / 3.0)).epsilon(1e-7)); HRectBound> c(4); c[0] = math::Range(0.0, 1.0); @@ -1033,13 +1031,13 @@ BOOST_AUTO_TEST_CASE(HRectBoundDiameter) c[2] = math::Range(2.0, 3.0); c[3] = math::Range(0.0, 0.0); - BOOST_REQUIRE_CLOSE(c.Diameter(), 3.0, 1e-5); + REQUIRE(c.Diameter() == Approx(3.0).epsilon(1e-7)); HRectBound> d(2); d[0] = math::Range(2.2, 2.2); d[1] = math::Range(1.0, 1.0); - BOOST_REQUIRE_SMALL(d.Diameter(), 1e-5); + REQUIRE(d.Diameter() == Approx(0.0).margin(1e-5)); } /** @@ -1048,7 +1046,7 @@ BOOST_AUTO_TEST_CASE(HRectBoundDiameter) * BinarySpaceTree<>::count_. So, let's build a simple tree and make sure they * are the same. */ -BOOST_AUTO_TEST_CASE(TreeCountMismatch) +TEST_CASE("TreeCountMismatch", "[TreeTest]") { arma::mat dataset = "2.0 5.0 9.0 4.0 8.0 7.0;" "3.0 4.0 6.0 7.0 1.0 2.0 "; @@ -1056,20 +1054,20 @@ BOOST_AUTO_TEST_CASE(TreeCountMismatch) // Leaf size of 1. KDTree rootNode(dataset, 1); - BOOST_REQUIRE(rootNode.Count() == 6); - BOOST_REQUIRE(rootNode.Left()->Count() == 3); - BOOST_REQUIRE(rootNode.Left()->Left()->Count() == 2); - BOOST_REQUIRE(rootNode.Left()->Left()->Left()->Count() == 1); - BOOST_REQUIRE(rootNode.Left()->Left()->Right()->Count() == 1); - BOOST_REQUIRE(rootNode.Left()->Right()->Count() == 1); - BOOST_REQUIRE(rootNode.Right()->Count() == 3); - BOOST_REQUIRE(rootNode.Right()->Left()->Count() == 2); - BOOST_REQUIRE(rootNode.Right()->Left()->Left()->Count() == 1); - BOOST_REQUIRE(rootNode.Right()->Left()->Right()->Count() == 1); - BOOST_REQUIRE(rootNode.Right()->Right()->Count() == 1); + REQUIRE(rootNode.Count() == 6); + REQUIRE(rootNode.Left()->Count() == 3); + REQUIRE(rootNode.Left()->Left()->Count() == 2); + REQUIRE(rootNode.Left()->Left()->Left()->Count() == 1); + REQUIRE(rootNode.Left()->Left()->Right()->Count() == 1); + REQUIRE(rootNode.Left()->Right()->Count() == 1); + REQUIRE(rootNode.Right()->Count() == 3); + REQUIRE(rootNode.Right()->Left()->Count() == 2); + REQUIRE(rootNode.Right()->Left()->Left()->Count() == 1); + REQUIRE(rootNode.Right()->Left()->Right()->Count() == 1); + REQUIRE(rootNode.Right()->Right()->Count() == 1); } -BOOST_AUTO_TEST_CASE(CheckParents) +TEST_CASE("CheckParents", "[TreeTest]") { arma::mat dataset = "2.0 5.0 9.0 4.0 8.0 7.0;" "3.0 4.0 6.0 7.0 1.0 2.0 "; @@ -1077,25 +1075,25 @@ BOOST_AUTO_TEST_CASE(CheckParents) // Leaf size of 1. KDTree rootNode(dataset, 1); - BOOST_REQUIRE_EQUAL(rootNode.Parent(), + REQUIRE(rootNode.Parent() == (KDTree*) NULL); - BOOST_REQUIRE_EQUAL(&rootNode, rootNode.Left()->Parent()); - BOOST_REQUIRE_EQUAL(&rootNode, rootNode.Right()->Parent()); - BOOST_REQUIRE_EQUAL(rootNode.Left(), rootNode.Left()->Left()->Parent()); - BOOST_REQUIRE_EQUAL(rootNode.Left(), rootNode.Left()->Right()->Parent()); - BOOST_REQUIRE_EQUAL(rootNode.Left()->Left(), + REQUIRE(&rootNode == rootNode.Left()->Parent()); + REQUIRE(&rootNode == rootNode.Right()->Parent()); + REQUIRE(rootNode.Left() == rootNode.Left()->Left()->Parent()); + REQUIRE(rootNode.Left() == rootNode.Left()->Right()->Parent()); + REQUIRE(rootNode.Left()->Left() == rootNode.Left()->Left()->Left()->Parent()); - BOOST_REQUIRE_EQUAL(rootNode.Left()->Left(), + REQUIRE(rootNode.Left()->Left() == rootNode.Left()->Left()->Right()->Parent()); - BOOST_REQUIRE_EQUAL(rootNode.Right(), rootNode.Right()->Left()->Parent()); - BOOST_REQUIRE_EQUAL(rootNode.Right(), rootNode.Right()->Right()->Parent()); - BOOST_REQUIRE_EQUAL(rootNode.Right()->Left(), + REQUIRE(rootNode.Right() == rootNode.Right()->Left()->Parent()); + REQUIRE(rootNode.Right() == rootNode.Right()->Right()->Parent()); + REQUIRE(rootNode.Right()->Left() == rootNode.Right()->Left()->Left()->Parent()); - BOOST_REQUIRE_EQUAL(rootNode.Right()->Left(), + REQUIRE(rootNode.Right()->Left() == rootNode.Right()->Left()->Right()->Parent()); } -BOOST_AUTO_TEST_CASE(CheckDataset) +TEST_CASE("CheckDataset", "[TreeTest]") { arma::mat dataset = "2.0 5.0 9.0 4.0 8.0 7.0;" "3.0 4.0 6.0 7.0 1.0 2.0 "; @@ -1104,39 +1102,40 @@ BOOST_AUTO_TEST_CASE(CheckDataset) KDTree rootNode(dataset, 1); arma::mat* rootDataset = &rootNode.Dataset(); - BOOST_REQUIRE_EQUAL(&rootNode.Left()->Dataset(), rootDataset); - BOOST_REQUIRE_EQUAL(&rootNode.Right()->Dataset(), rootDataset); - BOOST_REQUIRE_EQUAL(&rootNode.Left()->Left()->Dataset(), rootDataset); - BOOST_REQUIRE_EQUAL(&rootNode.Left()->Right()->Dataset(), rootDataset); - BOOST_REQUIRE_EQUAL(&rootNode.Right()->Left()->Dataset(), rootDataset); - BOOST_REQUIRE_EQUAL(&rootNode.Right()->Right()->Dataset(), rootDataset); - BOOST_REQUIRE_EQUAL(&rootNode.Left()->Left()->Left()->Dataset(), + REQUIRE(&rootNode.Left()->Dataset() == rootDataset); + REQUIRE(&rootNode.Right()->Dataset() == rootDataset); + REQUIRE(&rootNode.Left()->Left()->Dataset() == rootDataset); + REQUIRE(&rootNode.Left()->Right()->Dataset() == rootDataset); + REQUIRE(&rootNode.Right()->Left()->Dataset() == rootDataset); + REQUIRE(&rootNode.Right()->Right()->Dataset() == rootDataset); + REQUIRE(&rootNode.Left()->Left()->Left()->Dataset() == rootDataset); - BOOST_REQUIRE_EQUAL(&rootNode.Left()->Left()->Right()->Dataset(), + REQUIRE(&rootNode.Left()->Left()->Right()->Dataset() == rootDataset); - BOOST_REQUIRE_EQUAL(&rootNode.Right()->Left()->Left()->Dataset(), + REQUIRE(&rootNode.Right()->Left()->Left()->Dataset() == rootDataset); - BOOST_REQUIRE_EQUAL(&rootNode.Right()->Left()->Right()->Dataset(), + REQUIRE(&rootNode.Right()->Left()->Right()->Dataset() == rootDataset); } // Ensure FurthestDescendantDistance() works. -BOOST_AUTO_TEST_CASE(FurthestDescendantDistanceTest) +TEST_CASE("FurthestDescendantDistanceTest", "[TreeTest]") { arma::mat dataset = "1; 3"; // One point. KDTree rootNode(dataset, 1); - BOOST_REQUIRE_SMALL(rootNode.FurthestDescendantDistance(), 1e-5); + REQUIRE(rootNode.FurthestDescendantDistance() == Approx(0.0).margin(1e-5)); dataset = "1 -1; 1 -1"; // Square of size [2, 2]. // Both points are contained in the one node. KDTree twoPoint(dataset); - BOOST_REQUIRE_CLOSE(twoPoint.FurthestDescendantDistance(), sqrt(2.0), 1e-5); + REQUIRE(twoPoint.FurthestDescendantDistance() == + Approx(sqrt(2.0)).epsilon(1e-7)); } // Ensure that FurthestPointDistance() works. -BOOST_AUTO_TEST_CASE(FurthestPointDistanceTest) +TEST_CASE("FurthestPointDistanceTest", "[TreeTest]") { arma::mat dataset; dataset.randu(5, 100); @@ -1154,7 +1153,7 @@ BOOST_AUTO_TEST_CASE(FurthestPointDistanceTest) nodeQueue.pop(); if (node->NumChildren() != 0) - BOOST_REQUIRE_EQUAL(node->FurthestPointDistance(), 0.0); + REQUIRE(node->FurthestPointDistance() == 0.0); else { // Get center. @@ -1172,7 +1171,7 @@ BOOST_AUTO_TEST_CASE(FurthestPointDistanceTest) // We don't require an exact value because FurthestPointDistance() can // just bound the value instead of returning the exact value. - BOOST_REQUIRE_LE(maxDist, node->FurthestPointDistance()); + REQUIRE(maxDist <= node->FurthestPointDistance()); if (node->Left()) nodeQueue.push(node->Left()); @@ -1182,7 +1181,7 @@ BOOST_AUTO_TEST_CASE(FurthestPointDistanceTest) } } -BOOST_AUTO_TEST_CASE(ParentDistanceTest) +TEST_CASE("ParentDistanceTest", "[TreeTest]") { arma::mat dataset; dataset.randu(5, 500); @@ -1193,7 +1192,7 @@ BOOST_AUTO_TEST_CASE(ParentDistanceTest) // The root's parent distance should be 0 (although maybe it doesn't actually // matter; I just want to be sure it's not an uninitialized value, which this // test *sort* of checks). - BOOST_REQUIRE_EQUAL(tree.ParentDistance(), 0.0); + REQUIRE(tree.ParentDistance() == 0.0); // Do a depth-first traversal and make sure the parent distance is the same as // we calculate. @@ -1217,15 +1216,17 @@ BOOST_AUTO_TEST_CASE(ParentDistanceTest) const double leftDistance = LMetric<2>::Evaluate(center, leftCenter); const double rightDistance = LMetric<2>::Evaluate(center, rightCenter); - BOOST_REQUIRE_CLOSE(leftDistance, node->Left()->ParentDistance(), 1e-5); - BOOST_REQUIRE_CLOSE(rightDistance, node->Right()->ParentDistance(), 1e-5); + REQUIRE(leftDistance == + Approx(node->Left()->ParentDistance()).epsilon(1e-7)); + REQUIRE(rightDistance == + Approx(node->Right()->ParentDistance()).epsilon(1e-7)); nodeStack.push(node->Left()); nodeStack.push(node->Right()); } } -BOOST_AUTO_TEST_CASE(ParentDistanceTestWithMapping) +TEST_CASE("ParentDistanceTestWithMapping", "[TreeTest]") { arma::mat dataset; dataset.randu(5, 500); @@ -1237,7 +1238,7 @@ BOOST_AUTO_TEST_CASE(ParentDistanceTestWithMapping) // The root's parent distance should be 0 (although maybe it doesn't actually // matter; I just want to be sure it's not an uninitialized value, which this // test *sort* of checks). - BOOST_REQUIRE_EQUAL(tree.ParentDistance(), 0.0); + REQUIRE(tree.ParentDistance() == 0.0); // Do a depth-first traversal and make sure the parent distance is the same as // we calculate. @@ -1261,8 +1262,10 @@ BOOST_AUTO_TEST_CASE(ParentDistanceTestWithMapping) const double leftDistance = LMetric<2>::Evaluate(center, leftCenter); const double rightDistance = LMetric<2>::Evaluate(center, rightCenter); - BOOST_REQUIRE_CLOSE(leftDistance, node->Left()->ParentDistance(), 1e-5); - BOOST_REQUIRE_CLOSE(rightDistance, node->Right()->ParentDistance(), 1e-5); + REQUIRE(leftDistance == + Approx(node->Left()->ParentDistance()).epsilon(1e-7)); + REQUIRE(rightDistance == + Approx(node->Right()->ParentDistance()).epsilon(1e-7)); nodeStack.push(node->Left()); nodeStack.push(node->Right()); @@ -1291,7 +1294,7 @@ void GenerateVectorOfTree(TreeType* node, * * Then, we do that whole process a handful of times. */ -BOOST_AUTO_TEST_CASE(KdTreeTest) +TEST_CASE("KdTreeTest", "[TreeTest]") { typedef KDTree TreeType; @@ -1319,15 +1322,15 @@ BOOST_AUTO_TEST_CASE(KdTreeTest) const arma::mat& treeset = root.Dataset(); // Ensure the size of the tree is correct. - BOOST_REQUIRE_EQUAL(root.Count(), size); + REQUIRE(root.Count() == size); // Check the forward and backward mappings for correctness. for (size_t i = 0; i < size; ++i) { for (size_t j = 0; j < dimensions; ++j) { - BOOST_REQUIRE_EQUAL(treeset(j, i), dataset(j, newToOld[i])); - BOOST_REQUIRE_EQUAL(treeset(j, oldToNew[i]), dataset(j, i)); + REQUIRE(treeset(j, i) == dataset(j, newToOld[i])); + REQUIRE(treeset(j, oldToNew[i]) == dataset(j, i)); } } @@ -1346,7 +1349,7 @@ BOOST_AUTO_TEST_CASE(KdTreeTest) for (size_t i = depth; i < 2 * depth && i < v.size(); ++i) for (size_t j = i + 1; j < 2 * depth && j < v.size(); ++j) if (v[i] != NULL && v[j] != NULL) - BOOST_REQUIRE(!v[i]->Bound().Contains(v[j]->Bound())); + REQUIRE(!v[i]->Bound().Contains(v[j]->Bound())); depth *= 2; } @@ -1360,7 +1363,7 @@ BOOST_AUTO_TEST_CASE(KdTreeTest) TreeType root(dataset); } -BOOST_AUTO_TEST_CASE(MaxRPTreeTest) +TEST_CASE("MaxRPTreeTest", "[TreeTest]") { typedef MaxRPTree TreeType; @@ -1388,15 +1391,15 @@ BOOST_AUTO_TEST_CASE(MaxRPTreeTest) const arma::mat& treeset = root.Dataset(); // Ensure the size of the tree is correct. - BOOST_REQUIRE_EQUAL(root.Count(), size); + REQUIRE(root.Count() == size); // Check the forward and backward mappings for correctness. for (size_t i = 0; i < size; ++i) { for (size_t j = 0; j < dimensions; ++j) { - BOOST_REQUIRE_EQUAL(treeset(j, i), dataset(j, newToOld[i])); - BOOST_REQUIRE_EQUAL(treeset(j, oldToNew[i]), dataset(j, i)); + REQUIRE(treeset(j, i) == dataset(j, newToOld[i])); + REQUIRE(treeset(j, oldToNew[i]) == dataset(j, i)); } } } @@ -1486,13 +1489,13 @@ void CheckMaxRPTreeSplit(const TreeType& tree) if (tree.IsLeaf()) return; - BOOST_REQUIRE_EQUAL(CheckHyperplaneSplit(tree), true); + REQUIRE(CheckHyperplaneSplit(tree) == true); CheckMaxRPTreeSplit(*tree.Left()); CheckMaxRPTreeSplit(*tree.Right()); } -BOOST_AUTO_TEST_CASE(MaxRPTreeSplitTest) +TEST_CASE("MaxRPTreeSplitTest", "[TreeTest]") { typedef MaxRPTree TreeType; arma::mat dataset; @@ -1502,7 +1505,7 @@ BOOST_AUTO_TEST_CASE(MaxRPTreeSplitTest) CheckMaxRPTreeSplit(root); } -BOOST_AUTO_TEST_CASE(RPTreeTest) +TEST_CASE("RPTreeTest", "[TreeTest]") { typedef RPTree TreeType; @@ -1530,15 +1533,15 @@ BOOST_AUTO_TEST_CASE(RPTreeTest) const arma::mat& treeset = root.Dataset(); // Ensure the size of the tree is correct. - BOOST_REQUIRE_EQUAL(root.Count(), size); + REQUIRE(root.Count() == size); // Check the forward and backward mappings for correctness. for (size_t i = 0; i < size; ++i) { for (size_t j = 0; j < dimensions; ++j) { - BOOST_REQUIRE_EQUAL(treeset(j, i), dataset(j, newToOld[i])); - BOOST_REQUIRE_EQUAL(treeset(j, oldToNew[i]), dataset(j, i)); + REQUIRE(treeset(j, i) == dataset(j, newToOld[i])); + REQUIRE(treeset(j, oldToNew[i]) == dataset(j, i)); } } } @@ -1571,7 +1574,7 @@ void CheckRPTreeSplit(const TreeType& tree) ElemType dist = MetricType::Evaluate(center, tree.Dataset().col(tree.Right()->Descendant(k))); - BOOST_REQUIRE_LE(maxDist, dist * + REQUIRE(maxDist <= dist * (1.0 + 10.0 * std::numeric_limits::epsilon())); } } @@ -1580,7 +1583,7 @@ void CheckRPTreeSplit(const TreeType& tree) CheckRPTreeSplit(*tree.Right()); } -BOOST_AUTO_TEST_CASE(RPTreeSplitTest) +TEST_CASE("RPTreeSplitTest", "[TreeTest]") { typedef RPTree TreeType; arma::mat dataset; @@ -1616,7 +1619,7 @@ bool CheckPointBounds(TreeType& node) * * Then, we do that whole process a handful of times. */ -BOOST_AUTO_TEST_CASE(BallTreeTest) +TEST_CASE("BallTreeTest", "[TreeTest]") { typedef BallTree TreeType; @@ -1645,15 +1648,15 @@ BOOST_AUTO_TEST_CASE(BallTreeTest) const arma::mat& treeset = root.Dataset(); // Ensure the size of the tree is correct. - BOOST_REQUIRE_EQUAL(root.NumDescendants(), size); + REQUIRE(root.NumDescendants() == size); // Check the forward and backward mappings for correctness. for (size_t i = 0; i < size; ++i) { for (size_t j = 0; j < dimensions; ++j) { - BOOST_REQUIRE_EQUAL(treeset(j, i), dataset(j, newToOld[i])); - BOOST_REQUIRE_EQUAL(treeset(j, oldToNew[i]), dataset(j, i)); + REQUIRE(treeset(j, i) == dataset(j, newToOld[i])); + REQUIRE(treeset(j, oldToNew[i]) == dataset(j, i)); } } @@ -1665,7 +1668,7 @@ BOOST_AUTO_TEST_CASE(BallTreeTest) /** * Ensure that we can build a ball tree with a custom instantiated metric type. */ -BOOST_AUTO_TEST_CASE(MahalanobisBallTreeTest) +TEST_CASE("MahalanobisBallTreeTest", "[TreeTest]") { arma::mat dataset(10, 1000, arma::fill::randu); arma::mat cov = arma::eye(10, 10); @@ -1677,13 +1680,13 @@ BOOST_AUTO_TEST_CASE(MahalanobisBallTreeTest) TreeType tree(dataset); // As long as it built successfully, I am okay with that. - BOOST_REQUIRE_EQUAL(tree.NumDescendants(), 1000); + REQUIRE(tree.NumDescendants() == 1000); // Also test when we give oldFromNew, since this uses a different code path. std::vector oldFromNew; TreeType tree2(std::move(dataset), oldFromNew); - BOOST_REQUIRE_EQUAL(tree.NumDescendants(), 1000); + REQUIRE(tree.NumDescendants() == 1000); } template @@ -1719,7 +1722,7 @@ void GenerateVectorOfTree(TreeType* node, * * Then, we do that whole process a handful of times. */ -BOOST_AUTO_TEST_CASE(ExhaustiveSparseKDTreeTest) +TEST_CASE("ExhaustiveSparseKDTreeTest", "[TreeTest]") { typedef KDTree> TreeType; @@ -1750,15 +1753,15 @@ BOOST_AUTO_TEST_CASE(ExhaustiveSparseKDTreeTest) const arma::sp_mat& treeset = root.Dataset(); // Ensure the size of the tree is correct. - BOOST_REQUIRE_EQUAL(root.Count(), size); + REQUIRE(root.Count() == size); // Check the forward and backward mappings for correctness. for (size_t i = 0; i < size; ++i) { for (size_t j = 0; j < dimensions; ++j) { - BOOST_REQUIRE_EQUAL(treeset(j, i), dataset(j, newToOld[i])); - BOOST_REQUIRE_EQUAL(treeset(j, oldToNew[i]), dataset(j, i)); + REQUIRE(treeset(j, i) == dataset(j, newToOld[i])); + REQUIRE(treeset(j, oldToNew[i]) == dataset(j, i)); } } @@ -1777,7 +1780,7 @@ BOOST_AUTO_TEST_CASE(ExhaustiveSparseKDTreeTest) for (size_t i = depth; i < 2 * depth && i < v.size(); ++i) for (size_t j = i + 1; j < 2 * depth && j < v.size(); ++j) if (v[i] != NULL && v[j] != NULL) - BOOST_REQUIRE(!v[i]->Bound().Contains(v[j]->Bound())); + REQUIRE(!v[i]->Bound().Contains(v[j]->Bound())); depth *= 2; } @@ -1791,7 +1794,7 @@ BOOST_AUTO_TEST_CASE(ExhaustiveSparseKDTreeTest) TreeType root(dataset); } -BOOST_AUTO_TEST_CASE(BinarySpaceTreeMoveConstructorTest) +TEST_CASE("BinarySpaceTreeMoveConstructorTest", "[TreeTest]") { arma::mat dataset(5, 1000); dataset.randu(); @@ -1799,8 +1802,8 @@ BOOST_AUTO_TEST_CASE(BinarySpaceTreeMoveConstructorTest) BinarySpaceTree tree(dataset); BinarySpaceTree tree2(std::move(tree)); - BOOST_REQUIRE_EQUAL(tree.NumChildren(), 0); - BOOST_REQUIRE_EQUAL(tree2.NumChildren(), 2); + REQUIRE(tree.NumChildren() == 0); + REQUIRE(tree2.NumChildren() == 2); } template @@ -1832,7 +1835,7 @@ void CheckSelfChild(const TreeType& node) } // Ensure this has its own self-child. - BOOST_REQUIRE_EQUAL(found, true); + REQUIRE(found == true); } template @@ -1855,7 +1858,7 @@ void CheckCovering(const TreeType& node) double distance = MetricType::Evaluate(dataset.col(nodePoint), dataset.col(childPoint)); - BOOST_REQUIRE_LE(distance, maxDistance); + REQUIRE(distance <= maxDistance); // Check the child. CheckCovering(node.Child(i)); @@ -1865,7 +1868,7 @@ void CheckCovering(const TreeType& node) /** * Create a simple cover tree and then make sure it is valid. */ -BOOST_AUTO_TEST_CASE(SimpleCoverTreeConstructionTest) +TEST_CASE("SimpleCoverTreeConstructionTest", "[TreeTest]") { // 20-point dataset. arma::mat data = arma::trans(arma::mat("0.0 0.0;" @@ -1897,7 +1900,7 @@ BOOST_AUTO_TEST_CASE(SimpleCoverTreeConstructionTest) // The furthest point from the root will be (-5, -5), with a distance of // of sqrt(50). This means the scale of the root node should be 3 (because // 2^3 = 8). - BOOST_REQUIRE_EQUAL(tree.Scale(), 3); + REQUIRE(tree.Scale() == 3); // Now loop through the tree and ensure that each leaf is only created once. arma::vec counts; @@ -1906,7 +1909,7 @@ BOOST_AUTO_TEST_CASE(SimpleCoverTreeConstructionTest) // Each point should only have one leaf node representing it. for (size_t i = 0; i < 20; ++i) - BOOST_REQUIRE_EQUAL(counts[i], 1); + REQUIRE(counts[i] == 1); // Each non-leaf should have a self-child. CheckSelfChild(tree); @@ -1922,7 +1925,7 @@ BOOST_AUTO_TEST_CASE(SimpleCoverTreeConstructionTest) /** * Create a large cover tree and make sure it's accurate. */ -BOOST_AUTO_TEST_CASE(CoverTreeConstructionTest) +TEST_CASE("CoverTreeConstructionTest", "[TreeTest]") { arma::mat dataset; // 50-dimensional, 1000 point. @@ -1938,7 +1941,7 @@ BOOST_AUTO_TEST_CASE(CoverTreeConstructionTest) RecurseTreeCountLeaves(tree, counts); for (size_t i = 0; i < 1000; ++i) - BOOST_REQUIRE_EQUAL(counts[i], 1); + REQUIRE(counts[i] == 1); // Each non-leaf should have a self-child. CheckSelfChild(tree); @@ -1954,7 +1957,7 @@ BOOST_AUTO_TEST_CASE(CoverTreeConstructionTest) /** * Create a cover tree on sparse data and make sure it's accurate. */ -BOOST_AUTO_TEST_CASE(SparseCoverTreeConstructionTest) +TEST_CASE("SparseCoverTreeConstructionTest", "[TreeTest]") { arma::sp_mat dataset; // 50-dimensional, 1000 point. @@ -1970,7 +1973,7 @@ BOOST_AUTO_TEST_CASE(SparseCoverTreeConstructionTest) RecurseTreeCountLeaves(tree, counts); for (size_t i = 0; i < 1000; ++i) - BOOST_REQUIRE_EQUAL(counts[i], 1); + REQUIRE(counts[i] == 1); // Each non-leaf should have a self-child. CheckSelfChild(tree); @@ -1986,7 +1989,7 @@ BOOST_AUTO_TEST_CASE(SparseCoverTreeConstructionTest) /** * Test the manual constructor. */ -BOOST_AUTO_TEST_CASE(CoverTreeManualConstructorTest) +TEST_CASE("CoverTreeManualConstructorTest", "[TreeTest]") { arma::mat dataset; dataset.zeros(10, 10); @@ -1995,19 +1998,19 @@ BOOST_AUTO_TEST_CASE(CoverTreeManualConstructorTest) TreeType; TreeType node(dataset, 1.3, 3, 2, NULL, 1.5, 2.75); - BOOST_REQUIRE_EQUAL(&node.Dataset(), &dataset); - BOOST_REQUIRE_EQUAL(node.Base(), 1.3); - BOOST_REQUIRE_EQUAL(node.Point(), 3); - BOOST_REQUIRE_EQUAL(node.Scale(), 2); - BOOST_REQUIRE_EQUAL(node.Parent(), (CoverTree<>*) NULL); - BOOST_REQUIRE_EQUAL(node.ParentDistance(), 1.5); - BOOST_REQUIRE_EQUAL(node.FurthestDescendantDistance(), 2.75); + REQUIRE(&node.Dataset() == &dataset); + REQUIRE(node.Base() == 1.3); + REQUIRE(node.Point() == 3); + REQUIRE(node.Scale() == 2); + REQUIRE(node.Parent() == (CoverTree<>*) NULL); + REQUIRE(node.ParentDistance() == 1.5); + REQUIRE(node.FurthestDescendantDistance() == 2.75); } /** * Make sure cover trees work in different metric spaces. */ -BOOST_AUTO_TEST_CASE(CoverTreeAlternateMetricTest) +TEST_CASE("CoverTreeAlternateMetricTest", "[TreeTest]") { arma::mat dataset; // 5-dimensional, 300-point dataset. @@ -2023,7 +2026,7 @@ BOOST_AUTO_TEST_CASE(CoverTreeAlternateMetricTest) RecurseTreeCountLeaves(tree, counts); for (size_t i = 0; i < 300; ++i) - BOOST_REQUIRE_EQUAL(counts[i], 1); + REQUIRE(counts[i] == 1); // Each non-leaf should have a self-child. CheckSelfChild(tree); @@ -2039,7 +2042,7 @@ BOOST_AUTO_TEST_CASE(CoverTreeAlternateMetricTest) /** * Make sure copy constructor works for the cover tree. */ -BOOST_AUTO_TEST_CASE(CoverTreeCopyConstructor) +TEST_CASE("CoverTreeCopyConstructor", "[TreeTest]") { arma::mat dataset; dataset.randu(10, 10); // dataset is irrelevant. @@ -2054,51 +2057,51 @@ BOOST_AUTO_TEST_CASE(CoverTreeCopyConstructor) // Check that everything is the same. // As the tree being copied doesn't own the dataset, they must share the same // pointer. - BOOST_REQUIRE_EQUAL(c.Dataset().memptr(), d.Dataset().memptr()); - BOOST_REQUIRE_CLOSE(c.Base(), d.Base(), 1e-50); - BOOST_REQUIRE_EQUAL(c.Point(), d.Point()); - BOOST_REQUIRE_EQUAL(c.Scale(), d.Scale()); - BOOST_REQUIRE_EQUAL(c.Parent(), d.Parent()); - BOOST_REQUIRE_EQUAL(c.ParentDistance(), d.ParentDistance()); - BOOST_REQUIRE_EQUAL(c.FurthestDescendantDistance(), + REQUIRE(c.Dataset().memptr() == d.Dataset().memptr()); + REQUIRE(c.Base() == Approx(d.Base()).epsilon(1e-52)); + REQUIRE(c.Point() == d.Point()); + REQUIRE(c.Scale() == d.Scale()); + REQUIRE(c.Parent() == d.Parent()); + REQUIRE(c.ParentDistance() == d.ParentDistance()); + REQUIRE(c.FurthestDescendantDistance() == d.FurthestDescendantDistance()); - BOOST_REQUIRE_EQUAL(c.NumChildren(), d.NumChildren()); - BOOST_REQUIRE_NE(&c.Child(0), &d.Child(0)); - BOOST_REQUIRE_NE(&c.Child(1), &d.Child(1)); + REQUIRE(c.NumChildren() == d.NumChildren()); + REQUIRE(&c.Child(0) != &d.Child(0)); + REQUIRE(&c.Child(1) != &d.Child(1)); - BOOST_REQUIRE_EQUAL(c.Child(0).Parent(), &c); - BOOST_REQUIRE_EQUAL(c.Child(1).Parent(), &c); - BOOST_REQUIRE_EQUAL(d.Child(0).Parent(), &d); - BOOST_REQUIRE_EQUAL(d.Child(1).Parent(), &d); + REQUIRE(c.Child(0).Parent() == &c); + REQUIRE(c.Child(1).Parent() == &c); + REQUIRE(d.Child(0).Parent() == &d); + REQUIRE(d.Child(1).Parent() == &d); // Check that the children are okay. - BOOST_REQUIRE_EQUAL(c.Child(0).Dataset().memptr(), c.Dataset().memptr()); - BOOST_REQUIRE_CLOSE(c.Child(0).Base(), d.Child(0).Base(), 1e-50); - BOOST_REQUIRE_EQUAL(c.Child(0).Point(), d.Child(0).Point()); - BOOST_REQUIRE_EQUAL(c.Child(0).Scale(), d.Child(0).Scale()); - BOOST_REQUIRE_EQUAL(c.Child(0).ParentDistance(), d.Child(0).ParentDistance()); - BOOST_REQUIRE_EQUAL(c.Child(0).FurthestDescendantDistance(), + REQUIRE(c.Child(0).Dataset().memptr() == c.Dataset().memptr()); + REQUIRE(c.Child(0).Base() == Approx(d.Child(0).Base()).epsilon(1e-52)); + REQUIRE(c.Child(0).Point() == d.Child(0).Point()); + REQUIRE(c.Child(0).Scale() == d.Child(0).Scale()); + REQUIRE(c.Child(0).ParentDistance() == d.Child(0).ParentDistance()); + REQUIRE(c.Child(0).FurthestDescendantDistance() == d.Child(0).FurthestDescendantDistance()); - BOOST_REQUIRE_EQUAL(c.Child(0).NumChildren(), d.Child(0).NumChildren()); + REQUIRE(c.Child(0).NumChildren() == d.Child(0).NumChildren()); - BOOST_REQUIRE_EQUAL(c.Child(1).Dataset().memptr(), c.Dataset().memptr()); - BOOST_REQUIRE_CLOSE(c.Child(1).Base(), d.Child(1).Base(), 1e-50); - BOOST_REQUIRE_EQUAL(c.Child(1).Point(), d.Child(1).Point()); - BOOST_REQUIRE_EQUAL(c.Child(1).Scale(), d.Child(1).Scale()); - BOOST_REQUIRE_EQUAL(c.Child(1).ParentDistance(), d.Child(1).ParentDistance()); - BOOST_REQUIRE_EQUAL(c.Child(1).FurthestDescendantDistance(), + REQUIRE(c.Child(1).Dataset().memptr() == c.Dataset().memptr()); + REQUIRE(c.Child(1).Base() == Approx(d.Child(1).Base()).epsilon(1e-52)); + REQUIRE(c.Child(1).Point() == d.Child(1).Point()); + REQUIRE(c.Child(1).Scale() == d.Child(1).Scale()); + REQUIRE(c.Child(1).ParentDistance() == d.Child(1).ParentDistance()); + REQUIRE(c.Child(1).FurthestDescendantDistance() == d.Child(1).FurthestDescendantDistance()); - BOOST_REQUIRE_EQUAL(c.Child(1).NumChildren(), d.Child(1).NumChildren()); + REQUIRE(c.Child(1).NumChildren() == d.Child(1).NumChildren()); // Check copy constructor when the tree being copied owns the dataset. TreeType e(std::move(dataset), 1.3); TreeType f = e; // As the tree being copied owns the dataset, they must have different // instances. - BOOST_REQUIRE_NE(e.Dataset().memptr(), f.Dataset().memptr()); + REQUIRE(e.Dataset().memptr() != f.Dataset().memptr()); } -BOOST_AUTO_TEST_CASE(CoverTreeMoveDatasetTest) +TEST_CASE("CoverTreeMoveDatasetTest", "[TreeTest]") { arma::mat dataset = arma::randu(3, 1000); typedef StandardCoverTree @@ -2106,23 +2109,23 @@ BOOST_AUTO_TEST_CASE(CoverTreeMoveDatasetTest) TreeType t(std::move(dataset)); - BOOST_REQUIRE_EQUAL(dataset.n_elem, 0); - BOOST_REQUIRE_EQUAL(t.Dataset().n_rows, 3); - BOOST_REQUIRE_EQUAL(t.Dataset().n_cols, 1000); + REQUIRE(dataset.n_elem == 0); + REQUIRE(t.Dataset().n_rows == 3); + REQUIRE(t.Dataset().n_cols == 1000); EuclideanDistance ed; // Test the other constructor. dataset = arma::randu(3, 1000); TreeType t2(std::move(dataset), ed); - BOOST_REQUIRE_EQUAL(dataset.n_elem, 0); - BOOST_REQUIRE_EQUAL(t2.Dataset().n_rows, 3); - BOOST_REQUIRE_EQUAL(t2.Dataset().n_cols, 1000); + REQUIRE(dataset.n_elem == 0); + REQUIRE(t2.Dataset().n_rows == 3); + REQUIRE(t2.Dataset().n_cols == 1000); } /** * Make sure copy constructor works right for the binary space tree. */ -BOOST_AUTO_TEST_CASE(BinarySpaceTreeCopyConstructor) +TEST_CASE("BinarySpaceTreeCopyConstructor", "[TreeTest]") { arma::mat data("1"); typedef KDTree TreeType; @@ -2143,25 +2146,25 @@ BOOST_AUTO_TEST_CASE(BinarySpaceTreeCopyConstructor) TreeType c(b); // Ensure everything copied correctly. - BOOST_REQUIRE_EQUAL(b.Begin(), c.Begin()); - BOOST_REQUIRE_EQUAL(b.Count(), c.Count()); - BOOST_REQUIRE_NE(b.Left(), c.Left()); - BOOST_REQUIRE_NE(b.Right(), c.Right()); + REQUIRE(b.Begin() == c.Begin()); + REQUIRE(b.Count() == c.Count()); + REQUIRE(b.Left() != c.Left()); + REQUIRE(b.Right() != c.Right()); // Check the children. - BOOST_REQUIRE_EQUAL(b.Left()->Begin(), c.Left()->Begin()); - BOOST_REQUIRE_EQUAL(b.Left()->Count(), c.Left()->Count()); - BOOST_REQUIRE_EQUAL(b.Left()->Left(), (TreeType*) NULL); - BOOST_REQUIRE_EQUAL(b.Left()->Left(), c.Left()->Left()); - BOOST_REQUIRE_EQUAL(b.Left()->Right(), (TreeType*) NULL); - BOOST_REQUIRE_EQUAL(b.Left()->Right(), c.Left()->Right()); + REQUIRE(b.Left()->Begin() == c.Left()->Begin()); + REQUIRE(b.Left()->Count() == c.Left()->Count()); + REQUIRE(b.Left()->Left() == (TreeType*) NULL); + REQUIRE(b.Left()->Left() == c.Left()->Left()); + REQUIRE(b.Left()->Right() == (TreeType*) NULL); + REQUIRE(b.Left()->Right() == c.Left()->Right()); - BOOST_REQUIRE_EQUAL(b.Right()->Begin(), c.Right()->Begin()); - BOOST_REQUIRE_EQUAL(b.Right()->Count(), c.Right()->Count()); - BOOST_REQUIRE_EQUAL(b.Right()->Left(), (TreeType*) NULL); - BOOST_REQUIRE_EQUAL(b.Right()->Left(), c.Right()->Left()); - BOOST_REQUIRE_EQUAL(b.Right()->Right(), (TreeType*) NULL); - BOOST_REQUIRE_EQUAL(b.Right()->Right(), c.Right()->Right()); + REQUIRE(b.Right()->Begin() == c.Right()->Begin()); + REQUIRE(b.Right()->Count() == c.Right()->Count()); + REQUIRE(b.Right()->Left() == (TreeType*) NULL); + REQUIRE(b.Right()->Left() == c.Right()->Left()); + REQUIRE(b.Right()->Right() == (TreeType*) NULL); + REQUIRE(b.Right()->Right() == c.Right()->Right()); // Clean memory (we built the tree by hand, so this is what we have to do // since the destructor won't free the children's datasets). @@ -2237,19 +2240,19 @@ void CheckDescendants(TreeType* node) // In a cover tree, the number of leaves should be the number of descendant // points. const size_t numLeaves = NumLeaves(node); - BOOST_REQUIRE_EQUAL(numLeaves, node->NumDescendants()); + REQUIRE(numLeaves == node->NumDescendants()); // Now check that each descendant is somewhere in the tree. for (size_t i = 0; i < node->NumDescendants(); ++i) { Log::Debug << "Check for descendant " << node->Descendant(i) << " (i " << i << ").\n"; - BOOST_REQUIRE_EQUAL(FindIndex(node, node->Descendant(i)), true); + REQUIRE(FindIndex(node, node->Descendant(i)) == true); } // Now check that every actual descendant is accessible through the // Descendant() function. - BOOST_REQUIRE_EQUAL(CheckAccessibility(node, node), true); + REQUIRE(CheckAccessibility(node, node) == true); // Now check that there are no duplicates in the list of descendants. std::vector descendants; @@ -2262,7 +2265,7 @@ void CheckDescendants(TreeType* node) // Check that there are no duplicates (this is easy because it's sorted). for (size_t i = 1; i < descendants.size(); ++i) - BOOST_REQUIRE_NE(descendants[i], descendants[i - 1]); + REQUIRE(descendants[i] != descendants[i - 1]); // Now perform these same checks for the children. for (size_t i = 0; i < node->NumChildren(); ++i) @@ -2273,7 +2276,7 @@ void CheckDescendants(TreeType* node) * Make sure Descendant() and NumDescendants() works properly for the cover * tree. */ -BOOST_AUTO_TEST_CASE(CoverTreeDescendantTest) +TEST_CASE("CoverTreeDescendantTest", "[TreeTest]") { arma::mat dataset; dataset.randu(3, 100); @@ -2284,5 +2287,3 @@ BOOST_AUTO_TEST_CASE(CoverTreeDescendantTest) // using the recursive function above. CheckDescendants(&tree); } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/tree_traits_test.cpp b/src/mlpack/tests/tree_traits_test.cpp index fedf0ce1f1..caa642c71f 100644 --- a/src/mlpack/tests/tree_traits_test.cpp +++ b/src/mlpack/tests/tree_traits_test.cpp @@ -19,82 +19,78 @@ #include #include -#include -#include "test_tools.hpp" +#include "catch.hpp" +#include "test_catch_tools.hpp" using namespace mlpack; using namespace mlpack::tree; using namespace mlpack::metric; -BOOST_AUTO_TEST_SUITE(TreeTraitsTest); - // Be careful! When writing new tests, always get the boolean value of each // trait and store it in a temporary, because the Boost unit test macros do // weird things and will cause bizarre problems. // Test the defaults. -BOOST_AUTO_TEST_CASE(DefaultsTraitsTest) +TEST_CASE("DefaultsTraitsTest", "[TreeTraitsTestt]") { // An irrelevant non-tree type class is used here so that the default // implementation of TreeTraits is chosen. bool b = TreeTraits::HasOverlappingChildren; - BOOST_REQUIRE_EQUAL(b, true); + REQUIRE(b == true); b = TreeTraits::HasSelfChildren; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); b = TreeTraits::FirstPointIsCentroid; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); b = TreeTraits::RearrangesDataset; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); b = TreeTraits::BinaryTree; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); } // Test the binary space tree traits. -BOOST_AUTO_TEST_CASE(BinarySpaceTreeTraitsTest) +TEST_CASE("BinarySpaceTreeTraitsTest", "[TreeTraitsTestt]") { typedef BinarySpaceTree> TreeType; // Children are non-overlapping. bool b = TreeTraits::HasOverlappingChildren; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); // Points are not contained at multiple levels. b = TreeTraits::HasSelfChildren; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); // The first point is not the centroid. b = TreeTraits::FirstPointIsCentroid; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); // The dataset gets rearranged at build time. b = TreeTraits::RearrangesDataset; - BOOST_REQUIRE_EQUAL(b, true); + REQUIRE(b == true); // It is a binary tree. b = TreeTraits::BinaryTree; - BOOST_REQUIRE_EQUAL(b, true); + REQUIRE(b == true); } // Test the cover tree traits. -BOOST_AUTO_TEST_CASE(CoverTreeTraitsTest) +TEST_CASE("CoverTreeTraitsTest", "[TreeTraitsTestt]") { // Children may be overlapping. bool b = TreeTraits>::HasOverlappingChildren; - BOOST_REQUIRE_EQUAL(b, true); + REQUIRE(b == true); // The cover tree has self-children. b = TreeTraits>::HasSelfChildren; - BOOST_REQUIRE_EQUAL(b, true); + REQUIRE(b == true); // The first point is the center of the node. b = TreeTraits>::FirstPointIsCentroid; - BOOST_REQUIRE_EQUAL(b, true); + REQUIRE(b == true); b = TreeTraits>::RearrangesDataset; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); b = TreeTraits>::BinaryTree; - BOOST_REQUIRE_EQUAL(b, false); // Not necessarily binary. + REQUIRE(b == false); // Not necessarily binary. } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/ub_tree_test.cpp b/src/mlpack/tests/ub_tree_test.cpp index b1fb57b0bf..6df70e5627 100644 --- a/src/mlpack/tests/ub_tree_test.cpp +++ b/src/mlpack/tests/ub_tree_test.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include "catch.hpp" using namespace mlpack; using namespace mlpack::math; @@ -23,9 +23,7 @@ using namespace mlpack::metric; using namespace mlpack::bound; using namespace mlpack::neighbor; -BOOST_AUTO_TEST_SUITE(UBTreeTest); - -BOOST_AUTO_TEST_CASE(AddressTest) +TEST_CASE("AddressTest", "[UBTreeTest]") { typedef double ElemType; typedef typename std::conditional TreeType; arma::mat dataset(8, 1000); @@ -115,7 +113,7 @@ void CheckBound(const TreeType& tree) arma::Col point = tree.Dataset().col(tree.Descendant(i)); // Check that the point is contained in the bound. - BOOST_REQUIRE_EQUAL(true, tree.Bound().Contains(point)); + REQUIRE(true == tree.Bound().Contains(point)); const arma::Mat& loBound = tree.Bound().LoBound(); const arma::Mat& hiBound = tree.Bound().HiBound(); @@ -138,7 +136,7 @@ void CheckBound(const TreeType& tree) break; } - BOOST_REQUIRE_EQUAL(success, true); + REQUIRE(success == true); } if (!tree.IsLeaf()) @@ -148,7 +146,7 @@ void CheckBound(const TreeType& tree) } } -BOOST_AUTO_TEST_CASE(UBTreeBoundTest) +TEST_CASE("UBTreeBoundTest", "[UBTreeTest]") { typedef UBTree TreeType; arma::mat dataset(8, 1000); @@ -190,16 +188,16 @@ void CheckDistance(TreeType& tree, TreeType* node = NULL) minDist = dist; } - BOOST_REQUIRE_LE(tree.Bound().MinDistance(point), minDist * + REQUIRE(tree.Bound().MinDistance(point) <= minDist * (1.0 + 10 * std::numeric_limits::epsilon())); - BOOST_REQUIRE_LE(maxDist, tree.Bound().MaxDistance(point) * + REQUIRE(maxDist <= tree.Bound().MaxDistance(point) * (1.0 + 10 * std::numeric_limits::epsilon())); math::RangeType r = tree.Bound().RangeDistance(point); - BOOST_REQUIRE_LE(r.Lo(), minDist * + REQUIRE(r.Lo() <= minDist * (1.0 + 10 * std::numeric_limits::epsilon())); - BOOST_REQUIRE_LE(maxDist, r.Hi() * + REQUIRE(maxDist <= r.Hi() * (1.0 + 10 * std::numeric_limits::epsilon())); } @@ -228,16 +226,16 @@ void CheckDistance(TreeType& tree, TreeType* node = NULL) minDist = dist; } - BOOST_REQUIRE_LE(tree.Bound().MinDistance(node->Bound()), minDist * + REQUIRE(tree.Bound().MinDistance(node->Bound()) <= minDist * (1.0 + 10 * std::numeric_limits::epsilon())); - BOOST_REQUIRE_LE(maxDist, tree.Bound().MaxDistance(node->Bound()) * + REQUIRE(maxDist <= tree.Bound().MaxDistance(node->Bound()) * (1.0 + 10 * std::numeric_limits::epsilon())); math::RangeType r = tree.Bound().RangeDistance(node->Bound()); - BOOST_REQUIRE_LE(r.Lo(), minDist * + REQUIRE(r.Lo() <= minDist * (1.0 + 10 * std::numeric_limits::epsilon())); - BOOST_REQUIRE_LE(maxDist, r.Hi() * + REQUIRE(maxDist <= r.Hi() * (1.0 + 10 * std::numeric_limits::epsilon())); } if (!node->IsLeaf()) @@ -248,7 +246,7 @@ void CheckDistance(TreeType& tree, TreeType* node = NULL) } } -BOOST_AUTO_TEST_CASE(UBTreeDistanceTest) +TEST_CASE("UBTreeDistanceTest", "[UBTreeTest]") { typedef UBTree TreeType; arma::mat dataset(8, 200); @@ -260,7 +258,7 @@ BOOST_AUTO_TEST_CASE(UBTreeDistanceTest) } -BOOST_AUTO_TEST_CASE(UBTreeTest) +TEST_CASE("UBTreeTest", "[UBTreeTest]") { typedef UBTree TreeType; @@ -289,21 +287,21 @@ BOOST_AUTO_TEST_CASE(UBTreeTest) const arma::mat& treeset = root.Dataset(); // Ensure the size of the tree is correct. - BOOST_REQUIRE_EQUAL(root.NumDescendants(), size); + REQUIRE(root.NumDescendants() == size); // Check the forward and backward mappings for correctness. for (size_t i = 0; i < size; ++i) { for (size_t j = 0; j < dimensions; ++j) { - BOOST_REQUIRE_EQUAL(treeset(j, i), dataset(j, newToOld[i])); - BOOST_REQUIRE_EQUAL(treeset(j, oldToNew[i]), dataset(j, i)); + REQUIRE(treeset(j, i) == dataset(j, newToOld[i])); + REQUIRE(treeset(j, oldToNew[i]) == dataset(j, i)); } } } } -BOOST_AUTO_TEST_CASE(SingleTreeTraverserTest) +TEST_CASE("SingleUBTreeTraverserTest", "[UBTreeTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -325,12 +323,12 @@ BOOST_AUTO_TEST_CASE(SingleTreeTraverserTest) for (size_t i = 0; i < neighbors1.size(); ++i) { - BOOST_REQUIRE_EQUAL(neighbors1[i], neighbors2[i]); - BOOST_REQUIRE_EQUAL(distances1[i], distances2[i]); + REQUIRE(neighbors1[i] == neighbors2[i]); + REQUIRE(distances1[i] == distances2[i]); } } -BOOST_AUTO_TEST_CASE(DualTreeTraverserTest) +TEST_CASE("DualUBTreeTraverserTest", "[UBTreeTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -352,9 +350,7 @@ BOOST_AUTO_TEST_CASE(DualTreeTraverserTest) for (size_t i = 0; i < neighbors1.size(); ++i) { - BOOST_REQUIRE_EQUAL(neighbors1[i], neighbors2[i]); - BOOST_REQUIRE_EQUAL(distances1[i], distances2[i]); + REQUIRE(neighbors1[i] == neighbors2[i]); + REQUIRE(distances1[i] == distances2[i]); } } - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/vantage_point_tree_test.cpp b/src/mlpack/tests/vantage_point_tree_test.cpp index b31d679692..b531b49fd3 100644 --- a/src/mlpack/tests/vantage_point_tree_test.cpp +++ b/src/mlpack/tests/vantage_point_tree_test.cpp @@ -14,8 +14,8 @@ #include #include -#include -#include "test_tools.hpp" +#include "catch.hpp" +#include "test_catch_tools.hpp" using namespace mlpack; using namespace mlpack::math; @@ -24,112 +24,109 @@ using namespace mlpack::neighbor; using namespace mlpack::metric; using namespace mlpack::bound; -BOOST_AUTO_TEST_SUITE(VantagePointTreeTest); - -BOOST_AUTO_TEST_CASE(VPTreeTraitsTest) +TEST_CASE("VPTreeTraitsTest", "[VantagePointTreeTest]") { typedef VPTree TreeType; bool b = TreeTraits::HasOverlappingChildren; - BOOST_REQUIRE_EQUAL(b, true); + REQUIRE(b == true); b = TreeTraits::FirstPointIsCentroid; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); b = TreeTraits::HasSelfChildren; - BOOST_REQUIRE_EQUAL(b, false); + REQUIRE(b == false); b = TreeTraits::RearrangesDataset; - BOOST_REQUIRE_EQUAL(b, true); + REQUIRE(b == true); b = TreeTraits::BinaryTree; - BOOST_REQUIRE_EQUAL(b, true); + REQUIRE(b == true); } -BOOST_AUTO_TEST_CASE(HollowBallBoundTest) +TEST_CASE("HollowBallBoundTest", "[VantagePointTreeTest]") { HollowBallBound b(2, 4, arma::vec("1.0 2.0 3.0 4.0 5.0")); - BOOST_REQUIRE_EQUAL(b.Contains(arma::vec("1.0 2.0 3.0 7.0 5.0")), true); + REQUIRE(b.Contains(arma::vec("1.0 2.0 3.0 7.0 5.0")) == true); - BOOST_REQUIRE_EQUAL(b.Contains(arma::vec("1.0 2.0 3.0 9.0 5.0")), false); + REQUIRE(b.Contains(arma::vec("1.0 2.0 3.0 9.0 5.0")) == false); - BOOST_REQUIRE_EQUAL(b.Contains(arma::vec("1.0 2.0 3.0 5.0 5.0")), false); + REQUIRE(b.Contains(arma::vec("1.0 2.0 3.0 5.0 5.0")) == false); HollowBallBound b2(0.5, 1, arma::vec("1.0 2.0 3.0 7.0 5.0")); - BOOST_REQUIRE_EQUAL(b.Contains(b2), true); + REQUIRE(b.Contains(b2) == true); b2 = HollowBallBound(2.5, 3.5, arma::vec("1.0 2.0 3.0 4.5 5.0")); - BOOST_REQUIRE_EQUAL(b.Contains(b2), true); + REQUIRE(b.Contains(b2) == true); b2 = HollowBallBound(2.0, 3.5, arma::vec("1.0 2.0 3.0 4.5 5.0")); - BOOST_REQUIRE_EQUAL(b.Contains(b2), false); + REQUIRE(b.Contains(b2) == false); - BOOST_REQUIRE_CLOSE(b.MinDistance(arma::vec("1.0 2.0 8.0 4.0 5.0")), 1.0, - 1e-5); - BOOST_REQUIRE_CLOSE(b.MinDistance(arma::vec("1.0 2.0 4.0 4.0 5.0")), 1.0, - 1e-5); - BOOST_REQUIRE_CLOSE(b.MinDistance(arma::vec("1.0 2.0 3.0 4.0 5.0")), 2.0, - 1e-5); - BOOST_REQUIRE_CLOSE(b.MinDistance(arma::vec("1.0 2.0 5.0 4.0 5.0")), 0.0, - 1e-5); - BOOST_REQUIRE_CLOSE(b.MinDistance(arma::vec("5.0 2.0 3.0 4.0 5.0")), 0.0, - 1e-5); - BOOST_REQUIRE_CLOSE(b.MinDistance(arma::vec("3.0 2.0 3.0 4.0 5.0")), 0.0, - 1e-5); - - BOOST_REQUIRE_CLOSE(b.MaxDistance(arma::vec("1.0 2.0 4.0 4.0 5.0")), 5.0, - 1e-5); - BOOST_REQUIRE_CLOSE(b.MaxDistance(arma::vec("1.0 2.0 8.0 4.0 5.0")), 9.0, - 1e-5); - BOOST_REQUIRE_CLOSE(b.MaxDistance(arma::vec("1.0 2.0 3.0 4.0 5.0")), 4.0, - 1e-5); + REQUIRE(b.MinDistance(arma::vec("1.0 2.0 8.0 4.0 5.0")) == + Approx(1.0).epsilon(1e-7)); + REQUIRE(b.MinDistance(arma::vec("1.0 2.0 4.0 4.0 5.0")) == + Approx(1.0).epsilon(1e-7)); + REQUIRE(b.MinDistance(arma::vec("1.0 2.0 3.0 4.0 5.0")) == + Approx(2.0).epsilon(1e-7)); + REQUIRE(b.MinDistance(arma::vec("1.0 2.0 5.0 4.0 5.0")) == + Approx(0.0).epsilon(1e-7)); + REQUIRE(b.MinDistance(arma::vec("5.0 2.0 3.0 4.0 5.0")) == + Approx(0.0).epsilon(1e-7)); + REQUIRE(b.MinDistance(arma::vec("3.0 2.0 3.0 4.0 5.0")) == + Approx(0.0).epsilon(1e-7)); + REQUIRE(b.MaxDistance(arma::vec("1.0 2.0 4.0 4.0 5.0")) == + Approx(5.0).epsilon(1e-7)); + REQUIRE(b.MaxDistance(arma::vec("1.0 2.0 8.0 4.0 5.0")) == + Approx(9.0).epsilon(1e-7)); + REQUIRE(b.MaxDistance(arma::vec("1.0 2.0 3.0 4.0 5.0")) == + Approx(4.0).epsilon(1e-7)); b2 = HollowBallBound(3, 4, arma::vec("1.0 2.0 3.0 5.0 5.0")); - BOOST_REQUIRE_CLOSE(b.MinDistance(b2), 0.0, 1e-5); + REQUIRE(b.MinDistance(b2) == Approx(0.0).epsilon(1e-7)); b2 = HollowBallBound(1, 2, arma::vec("1.0 2.0 3.0 4.0 5.0")); - BOOST_REQUIRE_CLOSE(b.MinDistance(b2), 0.0, 1e-5); + REQUIRE(b.MinDistance(b2) == Approx(0.0).epsilon(1e-7)); b2 = HollowBallBound(0.5, 1.0, arma::vec("1.0 2.5 3.0 4.0 5.0")); - BOOST_REQUIRE_CLOSE(b.MinDistance(b2), 0.5, 1e-5); + REQUIRE(b.MinDistance(b2) == Approx(0.5).epsilon(1e-7)); b2 = HollowBallBound(0.5, 1.0, arma::vec("1.0 8.0 3.0 4.0 5.0")); - BOOST_REQUIRE_CLOSE(b.MinDistance(b2), 1.0, 1e-5); + REQUIRE(b.MinDistance(b2) == Approx(1.0).epsilon(1e-7)); b2 = HollowBallBound(0.5, 2.0, arma::vec("1.0 8.0 3.0 4.0 5.0")); - BOOST_REQUIRE_CLOSE(b.MinDistance(b2), 0.0, 1e-5); + REQUIRE(b.MinDistance(b2) == Approx(0.0).epsilon(1e-7)); b2 = HollowBallBound(0.5, 2.0, arma::vec("1.0 8.0 3.0 4.0 5.0")); - BOOST_REQUIRE_CLOSE(b.MaxDistance(b2), 12.0, 1e-5); + REQUIRE(b.MaxDistance(b2) == Approx(12.0).epsilon(1e-7)); b2 = HollowBallBound(0.5, 2.0, arma::vec("1.0 3.0 3.0 4.0 5.0")); - BOOST_REQUIRE_CLOSE(b.MaxDistance(b2), 7.0, 1e-5); + REQUIRE(b.MaxDistance(b2) == Approx(7.0).epsilon(1e-7)); HollowBallBound b1 = b; b2 = HollowBallBound(1.0, 2.0, arma::vec("1.0 2.5 3.0 4.0 5.0")); b1 |= b2; - BOOST_REQUIRE_CLOSE(b1.InnerRadius(), 0.5, 1e-5); + REQUIRE(b1.InnerRadius() == Approx(0.5).epsilon(1e-7)); b1 = b; b2 = HollowBallBound(0.5, 2.0, arma::vec("1.0 3.0 3.0 4.0 5.0")); b1 |= b2; - BOOST_REQUIRE_CLOSE(b1.InnerRadius(), 0.0, 1e-5); + REQUIRE(b1.InnerRadius() == Approx(0.0).epsilon(1e-7)); b1 = b; b2 = HollowBallBound(0.5, 4.0, arma::vec("1.0 3.0 3.0 4.0 5.0")); b1 |= b2; - BOOST_REQUIRE_CLOSE(b1.OuterRadius(), 5.0, 1e-5); + REQUIRE(b1.OuterRadius() == Approx(5.0).epsilon(1e-7)); } template @@ -147,10 +144,10 @@ void CheckBound(TreeType& tree) tree.Bound().HollowCenter(), tree.Dataset().col(tree.Point(i))); - BOOST_REQUIRE_LE(tree.Bound().InnerRadius(), hollowDist * + REQUIRE(tree.Bound().InnerRadius() <= hollowDist * (1.0 + 10.0 * std::numeric_limits::epsilon())); - BOOST_REQUIRE_LE(dist, tree.Bound().OuterRadius() * + REQUIRE(dist <= tree.Bound().OuterRadius() * (1.0 + 10.0 * std::numeric_limits::epsilon())); } } @@ -165,10 +162,10 @@ void CheckBound(TreeType& tree) tree.Bound().HollowCenter(), tree.Dataset().col(tree.Descendant(i))); - BOOST_REQUIRE_LE(tree.Bound().InnerRadius(), hollowDist * + REQUIRE(tree.Bound().InnerRadius() <= hollowDist * (1.0 + 10.0 * std::numeric_limits::epsilon())); - BOOST_REQUIRE_LE(dist, tree.Bound().OuterRadius() * + REQUIRE(dist <= tree.Bound().OuterRadius() * (1.0 + 10.0 * std::numeric_limits::epsilon())); } @@ -177,7 +174,7 @@ void CheckBound(TreeType& tree) } } -BOOST_AUTO_TEST_CASE(VPTreeBoundTest) +TEST_CASE("VPTreeBoundTest", "[VantagePointTreeTest]") { typedef VPTree TreeType; @@ -188,7 +185,7 @@ BOOST_AUTO_TEST_CASE(VPTreeBoundTest) CheckBound(tree); } -BOOST_AUTO_TEST_CASE(VPTreeTest) +TEST_CASE("VPTreeTest", "[VantagePointTreeTest]") { typedef VPTree TreeType; @@ -217,21 +214,21 @@ BOOST_AUTO_TEST_CASE(VPTreeTest) const arma::mat& treeset = root.Dataset(); // Ensure the size of the tree is correct. - BOOST_REQUIRE_EQUAL(root.NumDescendants(), size); + REQUIRE(root.NumDescendants() == size); // Check the forward and backward mappings for correctness. for (size_t i = 0; i < size; ++i) { for (size_t j = 0; j < dimensions; ++j) { - BOOST_REQUIRE_EQUAL(treeset(j, i), dataset(j, newToOld[i])); - BOOST_REQUIRE_EQUAL(treeset(j, oldToNew[i]), dataset(j, i)); + REQUIRE(treeset(j, i) == dataset(j, newToOld[i])); + REQUIRE(treeset(j, oldToNew[i]) == dataset(j, i)); } } } } -BOOST_AUTO_TEST_CASE(SingleTreeTraverserTest) +TEST_CASE("SingleVPTreeTraverserTest", "[VantagePointTreeTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -253,12 +250,12 @@ BOOST_AUTO_TEST_CASE(SingleTreeTraverserTest) for (size_t i = 0; i < neighbors1.size(); ++i) { - BOOST_REQUIRE_EQUAL(neighbors1[i], neighbors2[i]); - BOOST_REQUIRE_EQUAL(distances1[i], distances2[i]); + REQUIRE(neighbors1[i] == neighbors2[i]); + REQUIRE(distances1[i] == distances2[i]); } } -BOOST_AUTO_TEST_CASE(DualTreeTraverserTest) +TEST_CASE("DualVPTreeTraverserTest", "[VantagePointTreeTest]") { arma::mat dataset; dataset.randu(8, 1000); // 1000 points in 8 dimensions. @@ -280,9 +277,7 @@ BOOST_AUTO_TEST_CASE(DualTreeTraverserTest) for (size_t i = 0; i < neighbors1.size(); ++i) { - BOOST_REQUIRE_EQUAL(neighbors1[i], neighbors2[i]); - BOOST_REQUIRE_EQUAL(distances1[i], distances2[i]); + REQUIRE(neighbors1[i] == neighbors2[i]); + REQUIRE(distances1[i] == distances2[i]); } } - -BOOST_AUTO_TEST_SUITE_END();