merge master
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 ..
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<string, ParamData>::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<string, ParamData>::iterator it = parameters.begin();
|
||||
it != parameters.end(); ++it)
|
||||
{
|
||||
|
||||
@@ -28,12 +28,12 @@ Softmax<InputDataType, OutputDataType>::Softmax()
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename InputType, typename OutputType>
|
||||
void Softmax<InputDataType, OutputDataType>::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<typename InputDataType, typename OutputDataType>
|
||||
|
||||
@@ -30,10 +30,9 @@ void Softmin<InputDataType, OutputDataType>::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<typename InputDataType, typename OutputDataType>
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -24,17 +24,15 @@
|
||||
|
||||
#include <ensmallen.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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();
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
#include <mlpack/methods/ann/augmented/tasks/add.hpp>
|
||||
#include <mlpack/methods/ann/augmented/tasks/score.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<arma::mat> predResponse;
|
||||
model.Predict(testPredictor, predResponse);
|
||||
// A single failure is a failure.
|
||||
BOOST_REQUIRE_GE(SequencePrecision<arma::mat>(testResponse, predResponse),
|
||||
0.99);
|
||||
REQUIRE(SequencePrecision<arma::mat>(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<arma::mat> predResponse;
|
||||
model.Predict(testPredictor, predResponse);
|
||||
// A single failure is a failure.
|
||||
BOOST_REQUIRE_GE(SequencePrecision<arma::mat>(testResponse, predResponse),
|
||||
0.99);
|
||||
REQUIRE(SequencePrecision<arma::mat>(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<arma::mat> predResponse;
|
||||
model.Predict(testPredictor, predResponse);
|
||||
// A single failure is a failure.
|
||||
BOOST_REQUIRE_GE(SequencePrecision<arma::mat>(testResponse, predResponse),
|
||||
0.99);
|
||||
REQUIRE(SequencePrecision<arma::mat>(testResponse, predResponse) >= 0.99);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
#include <mlpack/bindings/cli/cli_option.hpp>
|
||||
#include <mlpack/core/kernels/gaussian_kernel.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<double> 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<arma::mat> 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<double>((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<arma::mat>((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<arma::mat>((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<arma::Mat<size_t>>((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<arma::Mat<size_t>>((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<tuple<data::DatasetInfo, arma::mat>>((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<GaussianKernel*>((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<double>((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<arma::mat>((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<tuple<GaussianKernel*, string>>((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<tuple<data::DatasetInfo, arma::mat>>((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<size_t> 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<double>((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<bool>((util::ParamData&) d, (const void*) &a, (void*) NULL);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(boost::any_cast<bool>(d.value), true);
|
||||
REQUIRE(boost::any_cast<bool>(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<arma::mat, string>& t =
|
||||
*boost::any_cast<tuple<arma::mat, string>>(&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<GaussianKernel*, string>& t =
|
||||
*boost::any_cast<tuple<GaussianKernel*, string>>(&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<tuple<DatasetInfo, arma::mat>, string>& t3 =
|
||||
*boost::any_cast<tuple<tuple<DatasetInfo, arma::mat>, 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<bool>((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<arma::mat>((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<GaussianKernel*>((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<GaussianKernel*>((util::ParamData&) d,
|
||||
(const void*) NULL, (void*) NULL);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -13,10 +13,8 @@
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/tree/cosine_tree/cosine_tree.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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();
|
||||
|
||||
+236
-233
@@ -11,8 +11,7 @@
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
#include <mlpack/core.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<arma::mat> 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<arma::mat> 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<arma::mat> 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<double>::max(), 1e-10);
|
||||
BOOST_REQUIRE(testDTree.SubtreeLeaves() == 1);
|
||||
REQUIRE(alpha == Approx(numeric_limits<double>::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<double>::max(), 1e-10);
|
||||
BOOST_REQUIRE(testDTree.SubtreeLeaves() == 1);
|
||||
REQUIRE(alpha == Approx(numeric_limits<double>::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<arma::mat> testDTree2(std::move(*testDTree));
|
||||
|
||||
// Check default values of the original tree.
|
||||
BOOST_REQUIRE_EQUAL(testDTree->LogNegError(), -DBL_MAX);
|
||||
BOOST_REQUIRE(testDTree->Left() == (DTree<arma::mat>*) NULL);
|
||||
BOOST_REQUIRE(testDTree->Right() == (DTree<arma::mat>*) NULL);
|
||||
REQUIRE(testDTree->LogNegError() == -DBL_MAX);
|
||||
REQUIRE(testDTree->Left() == (DTree<arma::mat>*) NULL);
|
||||
REQUIRE(testDTree->Right() == (DTree<arma::mat>*) 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<arma::mat> testDTree2 = std::move(*testDTree);
|
||||
|
||||
// Check default values of the original tree.
|
||||
BOOST_REQUIRE_EQUAL(testDTree->LogNegError(), -DBL_MAX);
|
||||
BOOST_REQUIRE(testDTree->Left() == (DTree<arma::mat>*) NULL);
|
||||
BOOST_REQUIRE(testDTree->Right() == (DTree<arma::mat>*) NULL);
|
||||
REQUIRE(testDTree->LogNegError() == -DBL_MAX);
|
||||
REQUIRE(testDTree->Left() == (DTree<arma::mat>*) NULL);
|
||||
REQUIRE(testDTree->Right() == (DTree<arma::mat>*) 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();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,9 +17,9 @@
|
||||
#include <mlpack/methods/hoeffding_trees/binary_numeric_split.hpp>
|
||||
#include <mlpack/methods/hoeffding_trees/hoeffding_tree_model.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "test_tools.hpp"
|
||||
#include "serialization.hpp"
|
||||
#include "catch.hpp"
|
||||
#include "test_catch_tools.hpp"
|
||||
#include "serialization_catch.hpp"
|
||||
|
||||
#include <stack>
|
||||
|
||||
@@ -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<size_t> 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<size_t> 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<size_t> 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<size_t> counts = arma::zeros<arma::Mat<size_t>>(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<size_t> 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<size_t> 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<size_t> 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<size_t> counts = arma::zeros<arma::Mat<size_t>>(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<GiniImpurity> 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<GiniImpurity> 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<GiniImpurity> 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<GiniImpurity> 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<GiniImpurity> split(3, 3); // 3 categories.
|
||||
|
||||
@@ -334,17 +336,17 @@ BOOST_AUTO_TEST_CASE(HoeffdingCategoricalSplitSplitTest)
|
||||
arma::Col<size_t> 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<FitnessFunction,
|
||||
* that it can properly classify all of the training points. (The dataset is
|
||||
* perfectly separable.)
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(HoeffdingTreeSimpleDatasetTest)
|
||||
TEST_CASE("HoeffdingTreeSimpleDatasetTest", "[HoeffdingTreeTest]")
|
||||
{
|
||||
DatasetInfo info(3);
|
||||
info.MapString<size_t>("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<size_t> 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<size_t>("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<GiniImpurity> 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<GiniImpurity> 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<GiniImpurity> 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<size_t> 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<GiniImpurity> 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<GiniImpurity> 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<size_t> 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<size_t> 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();
|
||||
|
||||
+204
-186
@@ -29,8 +29,7 @@ static const std::string testName = "";
|
||||
#include <mlpack/bindings/cli/parse_command_line.hpp>
|
||||
#include <mlpack/bindings/cli/end_program.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<bool> 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<bool>("global/bool"),
|
||||
IO::GetParam<bool>("a"));
|
||||
REQUIRE(IO::HasParam("global/bool") == IO::HasParam("a"));
|
||||
REQUIRE(IO::GetParam<bool>("global/bool") == IO::GetParam<bool>("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<int>("test_parent/test"), 42);
|
||||
REQUIRE(IO::GetParam<int>("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<char**>(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<char**>(argv)),
|
||||
REQUIRE_THROWS_AS(ParseCommandLine(argc, const_cast<char**>(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<bool>("flag_test"), false);
|
||||
REQUIRE(IO::GetParam<bool>("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<char**>(argv));
|
||||
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<bool>("flag_test"), true);
|
||||
BOOST_REQUIRE_EQUAL(IO::HasParam("flag_test"), true);
|
||||
REQUIRE(IO::GetParam<bool>("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<char**>(argv));
|
||||
|
||||
BOOST_REQUIRE(IO::HasParam("test_vec"));
|
||||
REQUIRE(IO::HasParam("test_vec"));
|
||||
|
||||
vector<size_t> v = IO::GetParam<vector<size_t>>("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<char**>(argv));
|
||||
|
||||
BOOST_REQUIRE(IO::HasParam("test2_vec"));
|
||||
REQUIRE(IO::HasParam("test2_vec"));
|
||||
|
||||
vector<size_t> v = IO::GetParam<vector<size_t>>("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<char**>(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<arma::vec>("vector");
|
||||
arma::vec vec2 = IO::GetParam<arma::vec>("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<char**>(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<size_t> vec1 = IO::GetParam<arma::Col<size_t>>("vector");
|
||||
arma::Col<size_t> vec2 = IO::GetParam<arma::Col<size_t>>("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<char**>(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<arma::rowvec>("row");
|
||||
arma::rowvec vec2 = IO::GetParam<arma::rowvec>("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<char**>(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<size_t> vec1 = IO::GetParam<arma::Row<size_t>>("row");
|
||||
arma::Row<size_t> vec2 = IO::GetParam<arma::Row<size_t>>("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<char**>(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<char**>(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<size_t> 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<char**>(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<char**>(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<size_t> 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<char**>(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<arma::mat>("matrix");
|
||||
arma::mat dataset2 = IO::GetParam<arma::mat>("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<char**>(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<arma::mat>("matrix");
|
||||
arma::mat dataset2 = IO::GetParam<arma::mat>("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<char**>(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<arma::mat>("matrix");
|
||||
arma::mat dataset2 = IO::GetParam<arma::mat>("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<char**>(argv)),
|
||||
REQUIRE_THROWS_AS(ParseCommandLine(argc, const_cast<char**>(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<char**>(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<arma::mat>("matrix");
|
||||
arma::mat dataset2 = IO::GetParam<arma::mat>("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<char**>(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<char**>(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<char**>(argv));
|
||||
|
||||
BOOST_REQUIRE(IO::HasParam("int"));
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<int>("int"), 3);
|
||||
REQUIRE(IO::HasParam("int"));
|
||||
REQUIRE(IO::GetParam<int>("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<char**>(argv));
|
||||
|
||||
BOOST_REQUIRE(IO::HasParam("string"));
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<string>("string"), string("3"));
|
||||
REQUIRE(IO::HasParam("string"));
|
||||
REQUIRE(IO::GetParam<string>("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<char**>(argv));
|
||||
|
||||
BOOST_REQUIRE(IO::HasParam("double"));
|
||||
BOOST_REQUIRE_CLOSE(IO::GetParam<double>("double"), 3.12, 1e-10);
|
||||
REQUIRE(IO::HasParam("double"));
|
||||
REQUIRE(IO::GetParam<double>("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<char**>(argv)),
|
||||
REQUIRE_THROWS_AS(ParseCommandLine(argc, const_cast<char**>(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<char**>(argv)),
|
||||
REQUIRE_THROWS_AS(ParseCommandLine(argc, const_cast<char**>(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<char**>(argv));
|
||||
|
||||
// Now check that we can get unmapped parameters.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetPrintableParam<arma::mat>("matrix"),
|
||||
REQUIRE(IO::GetPrintableParam<arma::mat>("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<arma::mat>("matrix2"),
|
||||
REQUIRE(IO::GetPrintableParam<arma::mat>("matrix2") ==
|
||||
"'file2.csv' (0x0 matrix)");
|
||||
BOOST_REQUIRE_EQUAL(IO::GetPrintableParam<GaussianKernel*>("kernel"),
|
||||
REQUIRE(IO::GetPrintableParam<GaussianKernel*>("kernel") ==
|
||||
"kernel.txt");
|
||||
BOOST_REQUIRE_EQUAL(IO::GetPrintableParam<GaussianKernel*>("kernel2"),
|
||||
REQUIRE(IO::GetPrintableParam<GaussianKernel*>("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<GaussianKernel*>("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<char**>(argv)),
|
||||
REQUIRE_THROWS_AS(ParseCommandLine(argc, const_cast<char**>(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<TupleType>("dataset")));
|
||||
arma::mat dataset = move(get<1>(IO::GetParam<TupleType>("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>("double") = 3.0;
|
||||
|
||||
// Now when we get it, it should be what we just set it to.
|
||||
BOOST_REQUIRE_CLOSE(IO::GetParam<double>("double"), 3.0, 1e-5);
|
||||
REQUIRE(IO::GetParam<double>("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<DatasetInfo, arma::mat>>("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();
|
||||
|
||||
@@ -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 <mlpack/methods/lars/lars.hpp>
|
||||
#include <mlpack/core/data/load.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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();
|
||||
|
||||
@@ -15,18 +15,15 @@
|
||||
#include <mlpack/methods/ann/layer/layer_types.hpp>
|
||||
#include <mlpack/methods/ann/layer_names.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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();
|
||||
|
||||
@@ -14,20 +14,18 @@
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/math/lin_alg.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<arma::mat>(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();
|
||||
|
||||
@@ -18,8 +18,8 @@ static const std::string testName = "HoeffdingTree";
|
||||
#include <mlpack/methods/hoeffding_trees/hoeffding_tree_main.cpp>
|
||||
#include "test_helper.hpp"
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<size_t> 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<arma::Row<size_t>>("predictions").n_cols, testSize);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("probabilities").n_cols,
|
||||
testSize);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_cols == testSize);
|
||||
REQUIRE(IO::GetParam<arma::mat>("probabilities").n_cols == testSize);
|
||||
|
||||
// Check number of output rows equals 1 for probabilities and predictions.
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::Row<size_t>>("predictions").n_rows, 1);
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::mat>("probabilities").n_rows, 1);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_rows == 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("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<size_t> 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<arma::Row<size_t>>
|
||||
("predictions").n_cols, testSize);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("probabilities").n_cols,
|
||||
testSize);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_cols == testSize);
|
||||
REQUIRE(IO::GetParam<arma::mat>("probabilities").n_cols == testSize);
|
||||
|
||||
// Check number of output rows equals 1 for probabilities and predictions.
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::Row<size_t>>("predictions").n_rows, 1);
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::mat>("probabilities").n_rows, 1);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_rows == 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("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<size_t> 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<arma::Row<size_t>>("predictions").n_cols, testSize);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("probabilities").n_cols,
|
||||
testSize);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_cols == testSize);
|
||||
REQUIRE(IO::GetParam<arma::mat>("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<arma::Row<size_t>>("predictions").n_rows, 1);
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::mat>("probabilities").n_rows, 1);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_rows == 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("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<arma::Row<size_t>>("predictions").n_cols, testSize);
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::mat>("probabilities").n_cols, testSize);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_cols == testSize);
|
||||
REQUIRE(IO::GetParam<arma::mat>("probabilities").n_cols == testSize);
|
||||
|
||||
// Check number of output rows equals 1 for probabilities and predictions.
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::Row<size_t>>("predictions").n_rows, 1);
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::mat>("probabilities").n_rows, 1);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_rows == 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("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<size_t> 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<arma::Row<size_t>>("predictions").n_cols, testSize);
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::mat>("probabilities").n_cols, testSize);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_cols == testSize);
|
||||
REQUIRE(IO::GetParam<arma::mat>("probabilities").n_cols == testSize);
|
||||
|
||||
// Check number of output rows equals 1 for probabilities and predictions.
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::Row<size_t>>("predictions").n_rows, 1);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("probabilities").n_rows, 1);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_rows == 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("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<size_t> 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<arma::mat>("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<arma::Row<size_t>>("predictions").n_cols, testSize);
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::mat>("probabilities").n_cols, testSize);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_cols == testSize);
|
||||
REQUIRE(IO::GetParam<arma::mat>("probabilities").n_cols == testSize);
|
||||
|
||||
// Check number of output rows equals 1 for probabilities and predictions.
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::Row<size_t>>("predictions").n_rows, 1);
|
||||
BOOST_REQUIRE_EQUAL(
|
||||
IO::GetParam<arma::mat>("probabilities").n_rows, 1);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_rows == 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("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<size_t> 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<HoeffdingTreeModel*>("output_model"))->NumNodes(),
|
||||
REQUIRE((IO::GetParam<HoeffdingTreeModel*>("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<size_t> 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<HoeffdingTreeModel*>("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<size_t> 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<HoeffdingTreeModel*>("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<size_t> 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<HoeffdingTreeModel*>("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<size_t> 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<HoeffdingTreeModel*>("output_model"))->NumNodes()-1, 2);
|
||||
REQUIRE(
|
||||
(IO::GetParam<HoeffdingTreeModel*>("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<size_t> 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<HoeffdingTreeModel*>("output_model"))->NumNodes(), nodes);
|
||||
CHECK((IO::GetParam<HoeffdingTreeModel*>("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<size_t> 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<size_t> 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<HoeffdingTreeModel*>("output_model"))->NumNodes(), 1);
|
||||
REQUIRE((IO::GetParam<HoeffdingTreeModel*>("output_model"))->NumNodes()
|
||||
== 1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -17,7 +17,7 @@ static const std::string testName = "RangeSearchMain";
|
||||
#include "test_helper.hpp"
|
||||
#include <mlpack/methods/range_search/range_search_main.cpp>
|
||||
#include "range_search_utils.hpp"
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<RSModel*>("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<vector<double>> 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<RSModel*>("output_model")));
|
||||
REQUIRE(ModelToString(outputModel) ==
|
||||
ModelToString(IO::GetParam<RSModel*>("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<RSModel*>("output_model")));
|
||||
REQUIRE(ModelToString(outputModel1) !=
|
||||
ModelToString(IO::GetParam<RSModel*>("output_model")));
|
||||
|
||||
if (i != leafSizes.size() - 1)
|
||||
delete IO::GetParam<RSModel*>("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<RSModel*>("output_model")));
|
||||
REQUIRE(ModelToString(outputModel1) !=
|
||||
ModelToString(IO::GetParam<RSModel*>("output_model")));
|
||||
|
||||
if (i != trees.size() - 1)
|
||||
delete IO::GetParam<RSModel*>("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<RSModel*>("output_model")));
|
||||
REQUIRE(ModelToString(outputModel) !=
|
||||
ModelToString(IO::GetParam<RSModel*>("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<vector<double>> 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<RSModel*>("output_model")));
|
||||
REQUIRE(ModelToString(outputModel) !=
|
||||
ModelToString(IO::GetParam<RSModel*>("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<vector<double>> 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<RSModel*>("output_model")));
|
||||
REQUIRE(ModelToString(outputModel) !=
|
||||
ModelToString(IO::GetParam<RSModel*>("output_model")));
|
||||
|
||||
delete outputModel;
|
||||
|
||||
remove(neighborsFile.c_str());
|
||||
remove(distanceFile.c_str());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -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 <boost/test/unit_test.hpp>
|
||||
#include <mlpack/methods/range_search/rs_model.hpp>
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
#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<std::vector<double>>& vec1,
|
||||
std::vector<std::vector<double>>& 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<std::vector<double>>& vec1,
|
||||
inline void CheckMatrices(std::vector<std::vector<size_t>>& vec1,
|
||||
std::vector<std::vector<size_t>>& 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,21 +10,19 @@
|
||||
*/
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "catch.hpp"
|
||||
#include <mlpack/core/metrics/iou_metric.hpp>
|
||||
#include <mlpack/core/metrics/non_maximal_supression.hpp>
|
||||
#include <mlpack/core/metrics/bleu.hpp>
|
||||
#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<true>::Evaluate(bbox1, bbox2), 0.7980093, 1e-4);
|
||||
REQUIRE(IoU<true>::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<true>::Evaluate(bbox1, bbox2), 0.612479577, 1e-4);
|
||||
REQUIRE(IoU<true>::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<std::string> WordVector;
|
||||
std::vector<std::vector<WordVector>> 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<float> 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();
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/tree/octree.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<typename TreeType>
|
||||
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<typename TreeType>
|
||||
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();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,35 +16,33 @@
|
||||
#include <mlpack/core/tree/rectangle_tree.hpp>
|
||||
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<RTree<EuclideanDistance, EmptyStatistic,
|
||||
arma::mat>>::HasOverlappingChildren;
|
||||
BOOST_REQUIRE_EQUAL(b, true);
|
||||
REQUIRE(b == true);
|
||||
|
||||
// Points are not contained in multiple levels.
|
||||
b = TreeTraits<RTree<EuclideanDistance, EmptyStatistic,
|
||||
arma::mat>>::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<arma::vec*> 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<typename TreeType::ElemType>::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<NearestNeighborSort>, 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<double>::ComparePoints(point01,
|
||||
point02), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::ComparePoints(point01, point02) == -1);
|
||||
|
||||
point01[0] = -DBL_MAX;
|
||||
point02[0] = -100;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(DiscreteHilbertValue<double>::ComparePoints(point01,
|
||||
point02), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::ComparePoints(point01, point02) == -1);
|
||||
|
||||
point01[0] = -100;
|
||||
point02[0] = -1;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(DiscreteHilbertValue<double>::ComparePoints(point01,
|
||||
point02), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::ComparePoints(point01, point02) == -1);
|
||||
|
||||
point01[0] = -1;
|
||||
point02[0] = -std::numeric_limits<double>::min();
|
||||
|
||||
BOOST_REQUIRE_EQUAL(DiscreteHilbertValue<double>::ComparePoints(point01,
|
||||
point02), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::ComparePoints(point01, point02) == -1);
|
||||
|
||||
point01[0] = -std::numeric_limits<double>::min();
|
||||
point02[0] = 0;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(DiscreteHilbertValue<double>::ComparePoints(point01,
|
||||
point02), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::ComparePoints(point01, point02) == -1);
|
||||
|
||||
point01[0] = 0;
|
||||
point02[0] = std::numeric_limits<double>::min();
|
||||
|
||||
BOOST_REQUIRE_EQUAL(DiscreteHilbertValue<double>::ComparePoints(point01,
|
||||
point02), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::ComparePoints(point01, point02) == -1);
|
||||
|
||||
point01[0] = std::numeric_limits<double>::min();
|
||||
point02[0] = 1;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(DiscreteHilbertValue<double>::ComparePoints(point01,
|
||||
point02), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::ComparePoints(point01, point02) == -1);
|
||||
|
||||
point01[0] = 1;
|
||||
point02[0] = 100;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(DiscreteHilbertValue<double>::ComparePoints(point01,
|
||||
point02), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::ComparePoints(point01, point02) == -1);
|
||||
|
||||
point01[0] = 100;
|
||||
point02[0] = DBL_MAX;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(DiscreteHilbertValue<double>::ComparePoints(point01,
|
||||
point02), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::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<double>::ComparePoints(point1,
|
||||
point2), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::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<double>::ComparePoints(point1,
|
||||
point2), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::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<double>::ComparePoints(point1,
|
||||
point2), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::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<double>::ComparePoints(point1,
|
||||
point2), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::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<double>::ComparePoints(point1,
|
||||
point2), 1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::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<double>::ComparePoints(point3,
|
||||
point4), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::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<double>::ComparePoints(point3,
|
||||
point4), -1);
|
||||
REQUIRE(DiscreteHilbertValue<double>::ComparePoints(point3, point4) == -1);
|
||||
}
|
||||
|
||||
template<typename TreeType>
|
||||
@@ -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<EuclideanDistance,
|
||||
NeighborSearchStat<NearestNeighborSort>, 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<EuclideanDistance,
|
||||
NeighborSearchStat<NearestNeighborSort>, 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<TreeType>::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<TreeType>::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<EuclideanDistance,
|
||||
@@ -1125,11 +1112,11 @@ BOOST_AUTO_TEST_CASE(RPlusPlusTreeBoundTest)
|
||||
|
||||
CheckRPlusPlusTreeBound(rPlusPlusTree2);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(GetMinLevel(rPlusPlusTree2), GetMaxLevel(rPlusPlusTree2));
|
||||
BOOST_REQUIRE_EQUAL(rPlusPlusTree2.TreeDepth(), GetMinLevel(rPlusPlusTree2));
|
||||
REQUIRE(GetMinLevel(rPlusPlusTree2) == GetMaxLevel(rPlusPlusTree2));
|
||||
REQUIRE(rPlusPlusTree2.TreeDepth() == GetMinLevel(rPlusPlusTree2));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(RPlusPlusTreeTraverserTest)
|
||||
TEST_CASE("RPlusPlusTreeTraverserTest", "[RectangleTreeTraitsTest]")
|
||||
{
|
||||
arma::mat dataset;
|
||||
|
||||
@@ -1145,7 +1132,7 @@ BOOST_AUTO_TEST_CASE(RPlusPlusTreeTraverserTest)
|
||||
NeighborSearchStat<NearestNeighborSort>, 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<arma::mat>(3, 1000);
|
||||
typedef RTree<EuclideanDistance, EmptyStatistic, arma::mat> 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();
|
||||
|
||||
@@ -13,9 +13,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/util/sfinae_utility.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
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<A, MForm1>::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<A, MForm1>::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<WithOutFunctionModel>::value,
|
||||
"value should be false");
|
||||
@@ -176,5 +174,3 @@ BOOST_AUTO_TEST_CASE(HasMethodNameTest)
|
||||
static_assert(HasModel<WithFunctionModelB>::value, "value should be true");
|
||||
static_assert(HasModel<WithInheritedModelA>::value, "value should be true");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
#include <mlpack/methods/neighbor_search/sort_policies/nearest_neighbor_sort.hpp>
|
||||
#include <mlpack/methods/neighbor_search/sort_policies/furthest_neighbor_sort.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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();
|
||||
|
||||
@@ -13,21 +13,19 @@
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/tree/spill_tree.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "catch.hpp"
|
||||
#include <stack>
|
||||
|
||||
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<EuclideanDistance, EmptyStatistic, arma::mat> SpillType1;
|
||||
typedef NonOrtSPTree<EuclideanDistance, EmptyStatistic, arma::mat> 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<arma::mat>(3, 1000);
|
||||
typedef SPTree<EuclideanDistance, EmptyStatistic, arma::mat> 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<arma::mat>(3, 1000);
|
||||
typedef SPTree<EuclideanDistance, EmptyStatistic, arma::mat> 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<arma::mat>(3, 1000);
|
||||
typedef SPTree<EuclideanDistance, EmptyStatistic, arma::mat> 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();
|
||||
|
||||
@@ -20,15 +20,14 @@
|
||||
#include <mlpack/core/data/string_encoding_policies/tf_idf_encoding_policy.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <memory>
|
||||
#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<string> stringEncodingInput = {
|
||||
"mlpack is an intuitive, fast, and flexible C++ machine learning library "
|
||||
@@ -64,21 +63,21 @@ void CheckVectors(const vector<vector<ValueType>>& a,
|
||||
const vector<vector<ValueType>>& 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<boost::string_view>;
|
||||
|
||||
@@ -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<boost::string_view>;
|
||||
|
||||
@@ -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<boost::string_view>;
|
||||
|
||||
@@ -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<vector<size_t>> 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<boost::string_view> 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<string> 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<string> 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<string> 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<boost::string_view>;
|
||||
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<string, size_t>& 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<boost::string_view>;
|
||||
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<string, size_t>& 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<TokenType>& 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<int>& 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<int>& expected,
|
||||
* Serialization test for the general template of the StringEncodingDictionary
|
||||
* class.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(StringEncodingDictionarySerialization)
|
||||
TEST_CASE("StringEncodingDictionarySerialization", "[StringEncodingTest]")
|
||||
{
|
||||
using DictionaryType = StringEncodingDictionary<string>;
|
||||
|
||||
@@ -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<SplitByAnyOf::TokenType>;
|
||||
|
||||
@@ -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<CharExtract::TokenType>;
|
||||
|
||||
@@ -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<boost::string_view>;
|
||||
|
||||
@@ -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<boost::string_view>;
|
||||
|
||||
@@ -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<string> 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<vector<size_t>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorBagOfWordsEncodingIndividualCharactersTest)
|
||||
TEST_CASE("VectorBagOfWordsEncodingIndividualCharactersTest", "[StringEncodingTest]")
|
||||
{
|
||||
std::vector<string> 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<boost::string_view>;
|
||||
|
||||
@@ -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<vector<double>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorRawCountSmoothIdfEncodingTest)
|
||||
TEST_CASE("VectorRawCountSmoothIdfEncodingTest", "[StringEncodingTest]")
|
||||
{
|
||||
using DictionaryType = StringEncodingDictionary<boost::string_view>;
|
||||
|
||||
@@ -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<string> input = {
|
||||
"GACCA",
|
||||
@@ -943,7 +942,7 @@ BOOST_AUTO_TEST_CASE(RawCountSmoothIdfEncodingIndividualCharactersTest)
|
||||
* These parameters are the default ones. The output type is
|
||||
* vector<vector<double>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorRawCountSmoothIdfEncodingIndividualCharactersTest)
|
||||
TEST_CASE("VectorRawCountSmoothIdfEncodingIndividualCharactersTest", "[StringEncodingTest]")
|
||||
{
|
||||
std::vector<string> 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<boost::string_view>;
|
||||
|
||||
@@ -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<vector<double>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorTfIdfRawCountEncodingTest)
|
||||
TEST_CASE("VectorTfIdfRawCountEncodingTest", "[StringEncodingTest]")
|
||||
{
|
||||
using DictionaryType = StringEncodingDictionary<boost::string_view>;
|
||||
|
||||
@@ -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<string> 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<vector<double>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorRawCountTfIdfEncodingIndividualCharactersTest)
|
||||
TEST_CASE("VectorRawCountTfIdfEncodingIndividualCharactersTest", "[StringEncodingTest]")
|
||||
{
|
||||
std::vector<string> 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<string> 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<vector<double>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorBinarySmoothIdfEncodingIndividualCharactersTest)
|
||||
TEST_CASE("VectorBinarySmoothIdfEncodingIndividualCharactersTest", "[StringEncodingTest]")
|
||||
{
|
||||
std::vector<string> 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<string> 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<string> 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<string> 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<string> 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<string> 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<SplitByAnyOf::TokenType>;
|
||||
|
||||
@@ -1424,6 +1423,3 @@ BOOST_AUTO_TEST_CASE(SplitByAnyOfTfIdfEncodingSerialization)
|
||||
|
||||
CheckMatrices(output, xmlOutput, textOutput, binaryOutput);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
|
||||
@@ -13,18 +13,16 @@
|
||||
|
||||
#include <mlpack/methods/reinforcement_learning/replay/sumtree.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<double> 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<double> 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<double> 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<double> 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();
|
||||
|
||||
+390
-389
File diff suppressed because it is too large
Load Diff
@@ -19,82 +19,78 @@
|
||||
#include <mlpack/core/tree/cover_tree.hpp>
|
||||
#include <mlpack/core/tree/rectangle_tree.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<int>::HasOverlappingChildren;
|
||||
BOOST_REQUIRE_EQUAL(b, true);
|
||||
REQUIRE(b == true);
|
||||
b = TreeTraits<int>::HasSelfChildren;
|
||||
BOOST_REQUIRE_EQUAL(b, false);
|
||||
REQUIRE(b == false);
|
||||
b = TreeTraits<int>::FirstPointIsCentroid;
|
||||
BOOST_REQUIRE_EQUAL(b, false);
|
||||
REQUIRE(b == false);
|
||||
b = TreeTraits<int>::RearrangesDataset;
|
||||
BOOST_REQUIRE_EQUAL(b, false);
|
||||
REQUIRE(b == false);
|
||||
b = TreeTraits<int>::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<LMetric<2, false>> TreeType;
|
||||
|
||||
// Children are non-overlapping.
|
||||
bool b = TreeTraits<TreeType>::HasOverlappingChildren;
|
||||
BOOST_REQUIRE_EQUAL(b, false);
|
||||
REQUIRE(b == false);
|
||||
|
||||
// Points are not contained at multiple levels.
|
||||
b = TreeTraits<TreeType>::HasSelfChildren;
|
||||
BOOST_REQUIRE_EQUAL(b, false);
|
||||
REQUIRE(b == false);
|
||||
|
||||
// The first point is not the centroid.
|
||||
b = TreeTraits<TreeType>::FirstPointIsCentroid;
|
||||
BOOST_REQUIRE_EQUAL(b, false);
|
||||
REQUIRE(b == false);
|
||||
|
||||
// The dataset gets rearranged at build time.
|
||||
b = TreeTraits<TreeType>::RearrangesDataset;
|
||||
BOOST_REQUIRE_EQUAL(b, true);
|
||||
REQUIRE(b == true);
|
||||
|
||||
// It is a binary tree.
|
||||
b = TreeTraits<TreeType>::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<CoverTree<>>::HasOverlappingChildren;
|
||||
BOOST_REQUIRE_EQUAL(b, true);
|
||||
REQUIRE(b == true);
|
||||
|
||||
// The cover tree has self-children.
|
||||
b = TreeTraits<CoverTree<>>::HasSelfChildren;
|
||||
BOOST_REQUIRE_EQUAL(b, true);
|
||||
REQUIRE(b == true);
|
||||
|
||||
// The first point is the center of the node.
|
||||
b = TreeTraits<CoverTree<>>::FirstPointIsCentroid;
|
||||
BOOST_REQUIRE_EQUAL(b, true);
|
||||
REQUIRE(b == true);
|
||||
|
||||
b = TreeTraits<CoverTree<>>::RearrangesDataset;
|
||||
BOOST_REQUIRE_EQUAL(b, false);
|
||||
REQUIRE(b == false);
|
||||
|
||||
b = TreeTraits<CoverTree<>>::BinaryTree;
|
||||
BOOST_REQUIRE_EQUAL(b, false); // Not necessarily binary.
|
||||
REQUIRE(b == false); // Not necessarily binary.
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
|
||||
#include <mlpack/core/tree/binary_space_tree.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<sizeof(ElemType) * CHAR_BIT <= 32,
|
||||
@@ -45,7 +43,7 @@ BOOST_AUTO_TEST_CASE(AddressTest)
|
||||
addr::AddressToPoint(point, address);
|
||||
|
||||
for (size_t k = 0; k < dataset.n_rows; ++k)
|
||||
BOOST_REQUIRE_CLOSE(dataset(k, i), point[k], 1e-13);
|
||||
REQUIRE(dataset(k, i) == Approx(point[k]).epsilon(1e-15));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,13 +87,13 @@ void CheckSplit(const TreeType& tree)
|
||||
}
|
||||
|
||||
// Addresses in the left node should be less than addresses in the right node.
|
||||
BOOST_REQUIRE_LE(addr::CompareAddresses(hi, lo), 0);
|
||||
REQUIRE(addr::CompareAddresses(hi, lo) <= 0);
|
||||
|
||||
CheckSplit(*tree.Left());
|
||||
CheckSplit(*tree.Right());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UBTreeSplitTest)
|
||||
TEST_CASE("UBTreeSplitTest", "[UBTreeTest]")
|
||||
{
|
||||
typedef UBTree<EuclideanDistance, EmptyStatistic, arma::mat> TreeType;
|
||||
arma::mat dataset(8, 1000);
|
||||
@@ -115,7 +113,7 @@ void CheckBound(const TreeType& tree)
|
||||
arma::Col<ElemType> 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<ElemType>& loBound = tree.Bound().LoBound();
|
||||
const arma::Mat<ElemType>& 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<EuclideanDistance, EmptyStatistic, arma::mat> 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<ElemType>::epsilon()));
|
||||
BOOST_REQUIRE_LE(maxDist, tree.Bound().MaxDistance(point) *
|
||||
REQUIRE(maxDist <= tree.Bound().MaxDistance(point) *
|
||||
(1.0 + 10 * std::numeric_limits<ElemType>::epsilon()));
|
||||
|
||||
math::RangeType<ElemType> r = tree.Bound().RangeDistance(point);
|
||||
|
||||
BOOST_REQUIRE_LE(r.Lo(), minDist *
|
||||
REQUIRE(r.Lo() <= minDist *
|
||||
(1.0 + 10 * std::numeric_limits<ElemType>::epsilon()));
|
||||
BOOST_REQUIRE_LE(maxDist, r.Hi() *
|
||||
REQUIRE(maxDist <= r.Hi() *
|
||||
(1.0 + 10 * std::numeric_limits<ElemType>::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<ElemType>::epsilon()));
|
||||
BOOST_REQUIRE_LE(maxDist, tree.Bound().MaxDistance(node->Bound()) *
|
||||
REQUIRE(maxDist <= tree.Bound().MaxDistance(node->Bound()) *
|
||||
(1.0 + 10 * std::numeric_limits<ElemType>::epsilon()));
|
||||
|
||||
math::RangeType<ElemType> r = tree.Bound().RangeDistance(node->Bound());
|
||||
|
||||
BOOST_REQUIRE_LE(r.Lo(), minDist *
|
||||
REQUIRE(r.Lo() <= minDist *
|
||||
(1.0 + 10 * std::numeric_limits<ElemType>::epsilon()));
|
||||
BOOST_REQUIRE_LE(maxDist, r.Hi() *
|
||||
REQUIRE(maxDist <= r.Hi() *
|
||||
(1.0 + 10 * std::numeric_limits<ElemType>::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<EuclideanDistance, EmptyStatistic, arma::mat> 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<EuclideanDistance, EmptyStatistic, arma::mat> 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();
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
|
||||
#include <mlpack/core/tree/binary_space_tree.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#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<EuclideanDistance, EmptyStatistic, arma::mat> TreeType;
|
||||
|
||||
bool b = TreeTraits<TreeType>::HasOverlappingChildren;
|
||||
BOOST_REQUIRE_EQUAL(b, true);
|
||||
REQUIRE(b == true);
|
||||
b = TreeTraits<TreeType>::FirstPointIsCentroid;
|
||||
BOOST_REQUIRE_EQUAL(b, false);
|
||||
REQUIRE(b == false);
|
||||
b = TreeTraits<TreeType>::HasSelfChildren;
|
||||
BOOST_REQUIRE_EQUAL(b, false);
|
||||
REQUIRE(b == false);
|
||||
b = TreeTraits<TreeType>::RearrangesDataset;
|
||||
BOOST_REQUIRE_EQUAL(b, true);
|
||||
REQUIRE(b == true);
|
||||
b = TreeTraits<TreeType>::BinaryTree;
|
||||
BOOST_REQUIRE_EQUAL(b, true);
|
||||
REQUIRE(b == true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(HollowBallBoundTest)
|
||||
TEST_CASE("HollowBallBoundTest", "[VantagePointTreeTest]")
|
||||
{
|
||||
HollowBallBound<EuclideanDistance> 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<EuclideanDistance> 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<EuclideanDistance>(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<EuclideanDistance>(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<EuclideanDistance>(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<EuclideanDistance>(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<EuclideanDistance>(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<EuclideanDistance>(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<EuclideanDistance>(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<EuclideanDistance>(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<EuclideanDistance>(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<EuclideanDistance> b1 = b;
|
||||
b2 = HollowBallBound<EuclideanDistance>(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<EuclideanDistance>(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<EuclideanDistance>(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<typename TreeType>
|
||||
@@ -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<ElemType>::epsilon()));
|
||||
|
||||
BOOST_REQUIRE_LE(dist, tree.Bound().OuterRadius() *
|
||||
REQUIRE(dist <= tree.Bound().OuterRadius() *
|
||||
(1.0 + 10.0 * std::numeric_limits<ElemType>::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<ElemType>::epsilon()));
|
||||
|
||||
BOOST_REQUIRE_LE(dist, tree.Bound().OuterRadius() *
|
||||
REQUIRE(dist <= tree.Bound().OuterRadius() *
|
||||
(1.0 + 10.0 * std::numeric_limits<ElemType>::epsilon()));
|
||||
}
|
||||
|
||||
@@ -177,7 +174,7 @@ void CheckBound(TreeType& tree)
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(VPTreeBoundTest)
|
||||
TEST_CASE("VPTreeBoundTest", "[VantagePointTreeTest]")
|
||||
{
|
||||
typedef VPTree<EuclideanDistance, EmptyStatistic, arma::mat> TreeType;
|
||||
|
||||
@@ -188,7 +185,7 @@ BOOST_AUTO_TEST_CASE(VPTreeBoundTest)
|
||||
CheckBound(tree);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(VPTreeTest)
|
||||
TEST_CASE("VPTreeTest", "[VantagePointTreeTest]")
|
||||
{
|
||||
typedef VPTree<EuclideanDistance, EmptyStatistic, arma::mat> 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();
|
||||
|
||||
Reference in New Issue
Block a user