[mlpack-svn] r10139 - in mlpack/trunk/src/mlpack: . tests tests/data

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Fri Nov 4 11:43:11 EDT 2011


Author: vlad321
Date: 2011-11-04 11:43:10 -0400 (Fri, 04 Nov 2011)
New Revision: 10139

Added:
   mlpack/trunk/src/mlpack/tests/
   mlpack/trunk/src/mlpack/tests/CMakeLists.txt
   mlpack/trunk/src/mlpack/tests/allkfn_test.cc
   mlpack/trunk/src/mlpack/tests/allknn_test.cc
   mlpack/trunk/src/mlpack/tests/aug_lagrangian_test.cpp
   mlpack/trunk/src/mlpack/tests/cli_test.cpp
   mlpack/trunk/src/mlpack/tests/data/
   mlpack/trunk/src/mlpack/tests/data/fake.csv
   mlpack/trunk/src/mlpack/tests/data/testRes.csv
   mlpack/trunk/src/mlpack/tests/data/testSet.csv
   mlpack/trunk/src/mlpack/tests/data/test_data_3_1000.csv
   mlpack/trunk/src/mlpack/tests/data/trainSet.csv
   mlpack/trunk/src/mlpack/tests/emst_test.cc
   mlpack/trunk/src/mlpack/tests/infomax_ica_test.cc
   mlpack/trunk/src/mlpack/tests/kernel_pca_test.cc
   mlpack/trunk/src/mlpack/tests/kernel_test.cc
   mlpack/trunk/src/mlpack/tests/lbfgs_test.cpp
   mlpack/trunk/src/mlpack/tests/lin_alg_test.cpp
   mlpack/trunk/src/mlpack/tests/linear_regression_test.cpp
   mlpack/trunk/src/mlpack/tests/load_save_test.cpp
   mlpack/trunk/src/mlpack/tests/math_test.cpp
   mlpack/trunk/src/mlpack/tests/mlpack_test.cpp
   mlpack/trunk/src/mlpack/tests/nbc_test.cc
   mlpack/trunk/src/mlpack/tests/nca_test.cc
   mlpack/trunk/src/mlpack/tests/nnsvm_test.cpp
   mlpack/trunk/src/mlpack/tests/ridge_regression_test.cc
   mlpack/trunk/src/mlpack/tests/save_restore_utility_test.cpp
   mlpack/trunk/src/mlpack/tests/svm_test.cc
   mlpack/trunk/src/mlpack/tests/tree_test.cpp
   mlpack/trunk/src/mlpack/tests/union_find_test.cpp
Modified:
   mlpack/trunk/src/mlpack/CMakeLists.txt
Log:
The all encompasing test, it should be just names mlpack_test in the bit directory. All required dataset files are in a folder as well.


Modified: mlpack/trunk/src/mlpack/CMakeLists.txt
===================================================================
--- mlpack/trunk/src/mlpack/CMakeLists.txt	2011-11-04 05:04:36 UTC (rev 10138)
+++ mlpack/trunk/src/mlpack/CMakeLists.txt	2011-11-04 15:43:10 UTC (rev 10139)
@@ -4,6 +4,7 @@
 set(DIRS
   core
   methods
+  tests
 )
 
 foreach(dir ${DIRS})

Added: mlpack/trunk/src/mlpack/tests/CMakeLists.txt
===================================================================
--- mlpack/trunk/src/mlpack/tests/CMakeLists.txt	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/CMakeLists.txt	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,38 @@
+cmake_minimum_required(VERSION 2.8)
+
+# add directory name to sources
+set(DIR_SRCS)
+foreach(file ${SOURCES})
+  set(DIR_SRCS ${DIR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${file})
+endforeach()
+# Append sources (with directory name) to list of all MLPACK sources (used at
+# the parent scope).
+set(MLPACK_SRCS ${MLPACK_SRCS} ${DIR_SRCS} PARENT_SCOPE)
+
+# test executable
+add_executable(mlpack_test
+  mlpack_test.cpp
+  allkfn_test.cc
+  allknn_test.cc
+  cli_test.cpp
+  emst_test.cc
+  infomax_ica_test.cc
+  kernel_test.cc
+  lin_alg_test.cpp
+  linear_regression_test.cpp
+  load_save_test.cpp
+  math_test.cpp
+  nbc_test.cc
+  nca_test.cc
+  nnsvm_test.cpp
+  ridge_regression_test.cc
+  save_restore_utility_test.cpp
+  svm_test.cc
+  tree_test.cpp
+  union_find_test.cpp
+)
+# link dependencies of test executable
+target_link_libraries(mlpack_test
+  mlpack
+  boost_unit_test_framework
+)

Added: mlpack/trunk/src/mlpack/tests/allkfn_test.cc
===================================================================
--- mlpack/trunk/src/mlpack/tests/allkfn_test.cc	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/allkfn_test.cc	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,434 @@
+/**
+ * @file allkfn_test.cc
+ *
+ * Test file for AllkFN class
+ */
+#include <mlpack/core.h>
+#include <mlpack/methods/neighbor_search/neighbor_search.h>
+#include <boost/test/unit_test.hpp>
+
+
+using namespace mlpack;
+using namespace mlpack::neighbor;
+
+BOOST_AUTO_TEST_SUITE(AllKfnTest);
+  /***
+   * Simple furthest-neighbors test with small, synthetic dataset.  This is an
+   * exhaustive test, which checks that each method for performing the calculation
+   * (dual-tree, single-tree, naive) produces the correct results.  An
+   * eleven-point dataset and the ten furthest neighbors are taken.  The dataset
+   * is in one dimension for simplicity -- the correct functionality of distance
+   * functions is not tested here.
+   */
+  BOOST_AUTO_TEST_CASE(exhaustive_synthetic_test) {
+    // Set up our data.
+    arma::mat data(1, 11);
+    data[0] = 0.05; // Row addressing is unnecessary (they are all 0).
+    data[1] = 0.35;
+    data[2] = 0.15;
+    data[3] = 1.25;
+    data[4] = 5.05;
+    data[5] = -0.22;
+    data[6] = -2.00;
+    data[7] = -1.30;
+    data[8] = 0.45;
+    data[9] = 0.90;
+    data[10] = 1.00;
+
+    // We will loop through three times, one for each method of performing the
+    // calculation.  We'll always use 10 neighbors, so set that parameter.
+    CLI::GetParam<int>("neighbor_search/k") = 10;
+    for (int i = 0; i < 3; i++) {
+      AllkFN* allkfn;
+      arma::mat data_mutable = data;
+      switch(i) {
+        case 0: // Use the dual-tree method.
+          allkfn = new AllkFN(data_mutable);
+          break;
+        case 1: // Use the single-tree method.
+          CLI::GetParam<bool>("neighbor_search/single_mode") = true;
+          allkfn = new AllkFN(data_mutable);
+          break;
+        case 2: // Use the naive method.
+          CLI::GetParam<bool>("neighbor_search/single_mode") = false;
+          CLI::GetParam<bool>("neighbor_search/naive_mode") = true;
+          allkfn = new AllkFN(data_mutable);
+          break;
+      }
+
+      // Now perform the actual calculation.
+      arma::Mat<size_t> neighbors;
+      arma::mat distances;
+      allkfn->ComputeNeighbors(neighbors, distances);
+
+      // Now the exhaustive check for correctness.  This will be long.  We must
+      // also remember that the distances returned are squared distances.  As a
+      // result, distance comparisons are written out as (distance * distance) for
+      // readability.
+
+      // Neighbors of point 0.
+      BOOST_REQUIRE(neighbors(9, 0) == 2);
+      BOOST_REQUIRE_CLOSE(distances(9, 0), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 0) == 5);
+      BOOST_REQUIRE_CLOSE(distances(8, 0), (0.27 * 0.27), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 0) == 1);
+      BOOST_REQUIRE_CLOSE(distances(7, 0), (0.30 * 0.30), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 0) == 8);
+      BOOST_REQUIRE_CLOSE(distances(6, 0), (0.40 * 0.40), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 0) == 9);
+      BOOST_REQUIRE_CLOSE(distances(5, 0), (0.85 * 0.85), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 0) == 10);
+      BOOST_REQUIRE_CLOSE(distances(4, 0), (0.95 * 0.95), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 0) == 3);
+      BOOST_REQUIRE_CLOSE(distances(3, 0), (1.20 * 1.20), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 0) == 7);
+      BOOST_REQUIRE_CLOSE(distances(2, 0), (1.35 * 1.35), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 0) == 6);
+      BOOST_REQUIRE_CLOSE(distances(1, 0), (2.05 * 2.05), 1e-5);
+      BOOST_REQUIRE(neighbors(0, 0) == 4);
+      BOOST_REQUIRE_CLOSE(distances(0, 0), (5.00 * 5.00), 1e-5);
+
+      // Neighbors of point 1.
+      BOOST_REQUIRE(neighbors(9, 1) == 8);
+      BOOST_REQUIRE_CLOSE(distances(9, 1), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 1) == 2);
+      BOOST_REQUIRE_CLOSE(distances(8, 1), (0.20 * 0.20), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 1) == 0);
+      BOOST_REQUIRE_CLOSE(distances(7, 1), (0.30 * 0.30), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 1) == 9);
+      BOOST_REQUIRE_CLOSE(distances(6, 1), (0.55 * 0.55), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 1) == 5);
+      BOOST_REQUIRE_CLOSE(distances(5, 1), (0.57 * 0.57), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 1) == 10);
+      BOOST_REQUIRE_CLOSE(distances(4, 1), (0.65 * 0.65), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 1) == 3);
+      BOOST_REQUIRE_CLOSE(distances(3, 1), (0.90 * 0.90), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 1) == 7);
+      BOOST_REQUIRE_CLOSE(distances(2, 1), (1.65 * 1.65), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 1) == 6);
+      BOOST_REQUIRE_CLOSE(distances(1, 1), (2.35 * 2.35), 1e-5);
+      BOOST_REQUIRE(neighbors(0, 1) == 4);
+      BOOST_REQUIRE_CLOSE(distances(0, 1), (4.70 * 4.70), 1e-5);
+
+      // Neighbors of point 2.
+      BOOST_REQUIRE(neighbors(9, 2) == 0);
+      BOOST_REQUIRE_CLOSE(distances(9, 2), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 2) == 1);
+      BOOST_REQUIRE_CLOSE(distances(8, 2), (0.20 * 0.20), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 2) == 8);
+      BOOST_REQUIRE_CLOSE(distances(7, 2), (0.30 * 0.30), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 2) == 5);
+      BOOST_REQUIRE_CLOSE(distances(6, 2), (0.37 * 0.37), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 2) == 9);
+      BOOST_REQUIRE_CLOSE(distances(5, 2), (0.75 * 0.75), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 2) == 10);
+      BOOST_REQUIRE_CLOSE(distances(4, 2), (0.85 * 0.85), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 2) == 3);
+      BOOST_REQUIRE_CLOSE(distances(3, 2), (1.10 * 1.10), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 2) == 7);
+      BOOST_REQUIRE_CLOSE(distances(2, 2), (1.45 * 1.45), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 2) == 6);
+      BOOST_REQUIRE_CLOSE(distances(1, 2), (2.15 * 2.15), 1e-5);
+      BOOST_REQUIRE(neighbors(0, 2) == 4);
+      BOOST_REQUIRE_CLOSE(distances(0, 2), (4.90 * 4.90), 1e-5);
+
+      // Neighbors of point 3.
+      BOOST_REQUIRE(neighbors(9, 3) == 10);
+      BOOST_REQUIRE_CLOSE(distances(9, 3), (0.25 * 0.25), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 3) == 9);
+      BOOST_REQUIRE_CLOSE(distances(8, 3), (0.35 * 0.35), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 3) == 8);
+      BOOST_REQUIRE_CLOSE(distances(7, 3), (0.80 * 0.80), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 3) == 1);
+      BOOST_REQUIRE_CLOSE(distances(6, 3), (0.90 * 0.90), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 3) == 2);
+      BOOST_REQUIRE_CLOSE(distances(5, 3), (1.10 * 1.10), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 3) == 0);
+      BOOST_REQUIRE_CLOSE(distances(4, 3), (1.20 * 1.20), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 3) == 5);
+      BOOST_REQUIRE_CLOSE(distances(3, 3), (1.47 * 1.47), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 3) == 7);
+      BOOST_REQUIRE_CLOSE(distances(2, 3), (2.55 * 2.55), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 3) == 6);
+      BOOST_REQUIRE_CLOSE(distances(1, 3), (3.25 * 3.25), 1e-5);
+      BOOST_REQUIRE(neighbors(0, 3) == 4);
+      BOOST_REQUIRE_CLOSE(distances(0, 3), (3.80 * 3.80), 1e-5);
+
+      // Neighbors of point 4.
+      BOOST_REQUIRE(neighbors(9, 4) == 3);
+      BOOST_REQUIRE_CLOSE(distances(9, 4), (3.80 * 3.80), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 4) == 10);
+      BOOST_REQUIRE_CLOSE(distances(8, 4), (4.05 * 4.05), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 4) == 9);
+      BOOST_REQUIRE_CLOSE(distances(7, 4), (4.15 * 4.15), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 4) == 8);
+      BOOST_REQUIRE_CLOSE(distances(6, 4), (4.60 * 4.60), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 4) == 1);
+      BOOST_REQUIRE_CLOSE(distances(5, 4), (4.70 * 4.70), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 4) == 2);
+      BOOST_REQUIRE_CLOSE(distances(4, 4), (4.90 * 4.90), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 4) == 0);
+      BOOST_REQUIRE_CLOSE(distances(3, 4), (5.00 * 5.00), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 4) == 5);
+      BOOST_REQUIRE_CLOSE(distances(2, 4), (5.27 * 5.27), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 4) == 7);
+      BOOST_REQUIRE_CLOSE(distances(1, 4), (6.35 * 6.35), 1e-5);
+      BOOST_REQUIRE(neighbors(0, 4) == 6);
+      BOOST_REQUIRE_CLOSE(distances(0, 4), (7.05 * 7.05), 1e-5);
+
+      // Neighbors of point 5.
+      BOOST_REQUIRE(neighbors(9, 5) == 0);
+      BOOST_REQUIRE_CLOSE(distances(9, 5), (0.27 * 0.27), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 5) == 2);
+      BOOST_REQUIRE_CLOSE(distances(8, 5), (0.37 * 0.37), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 5) == 1);
+      BOOST_REQUIRE_CLOSE(distances(7, 5), (0.57 * 0.57), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 5) == 8);
+      BOOST_REQUIRE_CLOSE(distances(6, 5), (0.67 * 0.67), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 5) == 7);
+      BOOST_REQUIRE_CLOSE(distances(5, 5), (1.08 * 1.08), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 5) == 9);
+      BOOST_REQUIRE_CLOSE(distances(4, 5), (1.12 * 1.12), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 5) == 10);
+      BOOST_REQUIRE_CLOSE(distances(3, 5), (1.22 * 1.22), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 5) == 3);
+      BOOST_REQUIRE_CLOSE(distances(2, 5), (1.47 * 1.47), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 5) == 6);
+      BOOST_REQUIRE_CLOSE(distances(1, 5), (1.78 * 1.78), 1e-5);
+      BOOST_REQUIRE(neighbors(0, 5) == 4);
+      BOOST_REQUIRE_CLOSE(distances(0, 5), (5.27 * 5.27), 1e-5);
+
+      // Neighbors of point 6.
+      BOOST_REQUIRE(neighbors(9, 6) == 7);
+      BOOST_REQUIRE_CLOSE(distances(9, 6), (0.70 * 0.70), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 6) == 5);
+      BOOST_REQUIRE_CLOSE(distances(8, 6), (1.78 * 1.78), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 6) == 0);
+      BOOST_REQUIRE_CLOSE(distances(7, 6), (2.05 * 2.05), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 6) == 2);
+      BOOST_REQUIRE_CLOSE(distances(6, 6), (2.15 * 2.15), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 6) == 1);
+      BOOST_REQUIRE_CLOSE(distances(5, 6), (2.35 * 2.35), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 6) == 8);
+      BOOST_REQUIRE_CLOSE(distances(4, 6), (2.45 * 2.45), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 6) == 9);
+      BOOST_REQUIRE_CLOSE(distances(3, 6), (2.90 * 2.90), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 6) == 10);
+      BOOST_REQUIRE_CLOSE(distances(2, 6), (3.00 * 3.00), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 6) == 3);
+      BOOST_REQUIRE_CLOSE(distances(1, 6), (3.25 * 3.25), 1e-5);
+      BOOST_REQUIRE(neighbors(0, 6) == 4);
+      BOOST_REQUIRE_CLOSE(distances(0, 6), (7.05 * 7.05), 1e-5);
+
+      // Neighbors of point 7.
+      BOOST_REQUIRE(neighbors(9, 7) == 6);
+      BOOST_REQUIRE_CLOSE(distances(9, 7), (0.70 * 0.70), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 7) == 5);
+      BOOST_REQUIRE_CLOSE(distances(8, 7), (1.08 * 1.08), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 7) == 0);
+      BOOST_REQUIRE_CLOSE(distances(7, 7), (1.35 * 1.35), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 7) == 2);
+      BOOST_REQUIRE_CLOSE(distances(6, 7), (1.45 * 1.45), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 7) == 1);
+      BOOST_REQUIRE_CLOSE(distances(5, 7), (1.65 * 1.65), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 7) == 8);
+      BOOST_REQUIRE_CLOSE(distances(4, 7), (1.75 * 1.75), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 7) == 9);
+      BOOST_REQUIRE_CLOSE(distances(3, 7), (2.20 * 2.20), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 7) == 10);
+      BOOST_REQUIRE_CLOSE(distances(2, 7), (2.30 * 2.30), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 7) == 3);
+      BOOST_REQUIRE_CLOSE(distances(1, 7), (2.55 * 2.55), 1e-5);
+      BOOST_REQUIRE(neighbors(0, 7) == 4);
+      BOOST_REQUIRE_CLOSE(distances(0, 7), (6.35 * 6.35), 1e-5);
+
+      // Neighbors of point 8.
+      BOOST_REQUIRE(neighbors(9, 8) == 1);
+      BOOST_REQUIRE_CLOSE(distances(9, 8), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 8) == 2);
+      BOOST_REQUIRE_CLOSE(distances(8, 8), (0.30 * 0.30), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 8) == 0);
+      BOOST_REQUIRE_CLOSE(distances(7, 8), (0.40 * 0.40), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 8) == 9);
+      BOOST_REQUIRE_CLOSE(distances(6, 8), (0.45 * 0.45), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 8) == 10);
+      BOOST_REQUIRE_CLOSE(distances(5, 8), (0.55 * 0.55), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 8) == 5);
+      BOOST_REQUIRE_CLOSE(distances(4, 8), (0.67 * 0.67), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 8) == 3);
+      BOOST_REQUIRE_CLOSE(distances(3, 8), (0.80 * 0.80), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 8) == 7);
+      BOOST_REQUIRE_CLOSE(distances(2, 8), (1.75 * 1.75), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 8) == 6);
+      BOOST_REQUIRE_CLOSE(distances(1, 8), (2.45 * 2.45), 1e-5);
+      BOOST_REQUIRE(neighbors(0, 8) == 4);
+      BOOST_REQUIRE_CLOSE(distances(0, 8), (4.60 * 4.60), 1e-5);
+
+      // Neighbors of point 9.
+      BOOST_REQUIRE(neighbors(9, 9) == 10);
+      BOOST_REQUIRE_CLOSE(distances(9, 9), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 9) == 3);
+      BOOST_REQUIRE_CLOSE(distances(8, 9), (0.35 * 0.35), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 9) == 8);
+      BOOST_REQUIRE_CLOSE(distances(7, 9), (0.45 * 0.45), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 9) == 1);
+      BOOST_REQUIRE_CLOSE(distances(6, 9), (0.55 * 0.55), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 9) == 2);
+      BOOST_REQUIRE_CLOSE(distances(5, 9), (0.75 * 0.75), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 9) == 0);
+      BOOST_REQUIRE_CLOSE(distances(4, 9), (0.85 * 0.85), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 9) == 5);
+      BOOST_REQUIRE_CLOSE(distances(3, 9), (1.12 * 1.12), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 9) == 7);
+      BOOST_REQUIRE_CLOSE(distances(2, 9), (2.20 * 2.20), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 9) == 6);
+      BOOST_REQUIRE_CLOSE(distances(1, 9), (2.90 * 2.90), 1e-5);
+      BOOST_REQUIRE(neighbors(0, 9) == 4);
+      BOOST_REQUIRE_CLOSE(distances(0, 9), (4.15 * 4.15), 1e-5);
+
+      // Neighbors of point 10.
+      BOOST_REQUIRE(neighbors(9, 10) == 9);
+      BOOST_REQUIRE_CLOSE(distances(9, 10), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 10) == 3);
+      BOOST_REQUIRE_CLOSE(distances(8, 10), (0.25 * 0.25), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 10) == 8);
+      BOOST_REQUIRE_CLOSE(distances(7, 10), (0.55 * 0.55), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 10) == 1);
+      BOOST_REQUIRE_CLOSE(distances(6, 10), (0.65 * 0.65), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 10) == 2);
+      BOOST_REQUIRE_CLOSE(distances(5, 10), (0.85 * 0.85), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 10) == 0);
+      BOOST_REQUIRE_CLOSE(distances(4, 10), (0.95 * 0.95), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 10) == 5);
+      BOOST_REQUIRE_CLOSE(distances(3, 10), (1.22 * 1.22), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 10) == 7);
+      BOOST_REQUIRE_CLOSE(distances(2, 10), (2.30 * 2.30), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 10) == 6);
+      BOOST_REQUIRE_CLOSE(distances(1, 10), (3.00 * 3.00), 1e-5);
+      BOOST_REQUIRE(neighbors(0, 10) == 4);
+      BOOST_REQUIRE_CLOSE(distances(0, 10), (4.05 * 4.05), 1e-5);
+
+      // Clean the memory.
+      delete allkfn;
+    }
+  }
+
+  /***
+   * Test the dual-tree furthest-neighbors method with the naive method.  This
+   * uses both a query and reference dataset.
+   *
+   * Errors are produced if the results are not identical.
+   */
+  BOOST_AUTO_TEST_CASE(dual_tree_vs_naive_1) {
+    arma::mat data_for_tree_;
+
+    // Hard-coded filename: bad!
+    if (!data::Load("test_data_3_1000.csv", data_for_tree_))
+      BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
+
+    // Set up matrices to work with.
+    arma::mat dual_query(data_for_tree_);
+    arma::mat dual_references(data_for_tree_);
+    arma::mat naive_query(data_for_tree_);
+    arma::mat naive_references(data_for_tree_);
+
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = false;
+    CLI::GetParam<bool>("neighbor_search/single_mode") = false;
+    AllkFN allkfn_(dual_query, dual_references);
+
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = true;
+    AllkFN naive_(naive_query, naive_references);
+
+    arma::Mat<size_t> resulting_neighbors_tree;
+    arma::mat distances_tree;
+    allkfn_.ComputeNeighbors(resulting_neighbors_tree, distances_tree);
+
+    arma::Mat<size_t> resulting_neighbors_naive;
+    arma::mat distances_naive;
+    naive_.ComputeNeighbors(resulting_neighbors_naive, distances_naive);
+
+    for (size_t i = 0; i < resulting_neighbors_tree.n_elem; i++) {
+      BOOST_REQUIRE(resulting_neighbors_tree[i] == resulting_neighbors_naive[i]);
+      BOOST_REQUIRE_CLOSE(distances_tree[i], distances_naive[i], 1e-5);
+    }
+  }
+
+  /**
+   * Test the dual-tree furthest-neighbors method with the naive method.  This
+   * uses only a reference dataset.
+   *
+   * Errors are produced if the results are not identical.
+   */
+  BOOST_AUTO_TEST_CASE(dual_tree_vs_naive_2) {
+    arma::mat data_for_tree_;
+
+    // Hard-coded filename: bad!
+    // Code duplication: also bad!
+    if (!data::Load("test_data_3_1000.csv", data_for_tree_))
+      BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
+
+    // Set up matrices to work with (may not be necessary with no ALIAS_MATRIX?).
+    arma::mat dual_references(data_for_tree_);
+    arma::mat naive_references(data_for_tree_);
+
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = false;
+    CLI::GetParam<bool>("neighbor_search/single_mode") = false;
+    AllkFN allkfn_(dual_references);
+
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = true;
+    AllkFN naive_(naive_references);
+
+    arma::Mat<size_t> resulting_neighbors_tree;
+    arma::mat distances_tree;
+    allkfn_.ComputeNeighbors(resulting_neighbors_tree, distances_tree);
+
+    arma::Mat<size_t> resulting_neighbors_naive;
+    arma::mat distances_naive;
+    naive_.ComputeNeighbors(resulting_neighbors_naive, distances_naive);
+
+    for (size_t i = 0; i < resulting_neighbors_tree.n_elem; i++) {
+      BOOST_REQUIRE(resulting_neighbors_tree[i] == resulting_neighbors_naive[i]);
+      BOOST_REQUIRE_CLOSE(distances_tree[i], distances_naive[i], 1e-5);
+    }
+  }
+
+  /**
+   * Test the single-tree furthest-neighbors method with the naive method.  This
+   * uses only a reference dataset.
+   *
+   * Errors are produced if the results are not identical.
+   */
+  BOOST_AUTO_TEST_CASE(single_tree_vs_naive) {
+    arma::mat data_for_tree_;
+
+    // Hard-coded filename: bad!
+    // Code duplication: also bad!
+    if (!data::Load("test_data_3_1000.csv", data_for_tree_))
+      BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
+
+    arma::mat single_query(data_for_tree_);
+    arma::mat naive_query(data_for_tree_);
+
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = false;
+    CLI::GetParam<bool>("neighbor_search/single_mode") = true;
+    AllkFN allkfn_(single_query);
+
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = true;
+    CLI::GetParam<bool>("neighbor_search/single_mode") = false;
+    AllkFN naive_(naive_query);
+
+    arma::Mat<size_t> resulting_neighbors_tree;
+    arma::mat distances_tree;
+    allkfn_.ComputeNeighbors(resulting_neighbors_tree, distances_tree);
+
+    arma::Mat<size_t> resulting_neighbors_naive;
+    arma::mat distances_naive;
+    naive_.ComputeNeighbors(resulting_neighbors_naive, distances_naive);
+
+    for (size_t i = 0; i < resulting_neighbors_tree.n_elem; i++) {
+      BOOST_REQUIRE(resulting_neighbors_tree[i] == resulting_neighbors_naive[i]);
+      BOOST_REQUIRE_CLOSE(distances_tree[i], distances_naive[i], 1e-5);
+    }
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/allknn_test.cc
===================================================================
--- mlpack/trunk/src/mlpack/tests/allknn_test.cc	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/allknn_test.cc	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,442 @@
+/**
+ * @file allknn_test.cc
+ *
+ * Test file for AllkNN class
+ */
+#include <mlpack/core.h>
+#include <mlpack/methods/neighbor_search/neighbor_search.h>
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+using namespace mlpack::neighbor;
+
+BOOST_AUTO_TEST_SUITE(AllKnnTest);
+
+  /***
+   * Simple nearest-neighbors test with small, synthetic dataset.  This is an
+   * exhaustive test, which checks that each method for performing the calculation
+   * (dual-tree, single-tree, naive) produces the correct results.  An
+   * eleven-point dataset and the ten nearest neighbors are taken.  The dataset is
+   * in one dimension for simplicity -- the correct functionality of distance
+   * functions is not tested here.
+   */
+  BOOST_AUTO_TEST_CASE(exhaustive_synthetic_test) {
+    // Set up our data.
+    arma::mat data(1, 11);
+    data[0] = 0.05; // Row addressing is unnecessary (they are all 0).
+    data[1] = 0.35;
+    data[2] = 0.15;
+    data[3] = 1.25;
+    data[4] = 5.05;
+    data[5] = -0.22;
+    data[6] = -2.00;
+    data[7] = -1.30;
+    data[8] = 0.45;
+    data[9] = 0.90;
+    data[10] = 1.00;
+
+    // We will loop through three times, one for each method of performing the
+    // calculation.  We'll always use 10 neighbors, so set that parameter.
+    CLI::GetParam<int>("neighbor_search/k") = 10;
+    for (int i = 0; i < 3; i++) {
+      AllkNN* allknn;
+      arma::mat data_mutable = data;
+      switch(i) {
+        case 0: // Use the dual-tree method.
+          allknn = new AllkNN(data_mutable);
+          break;
+        case 1: // Use the single-tree method.
+          CLI::GetParam<bool>("neighbor_search/single_mode") = true;
+          allknn = new AllkNN(data_mutable);
+          break;
+        case 2: // Use the naive method.
+          CLI::GetParam<bool>("neighbor_search/single_mode") = false;
+          CLI::GetParam<bool>("neighbor_search/naive_mode") = true;
+          allknn = new AllkNN(data_mutable);
+          break;
+      }
+
+      // Now perform the actual calculation.
+      arma::Mat<size_t> neighbors;
+      arma::mat distances;
+      allknn->ComputeNeighbors(neighbors, distances);
+
+      // Now the exhaustive check for correctness.  This will be long.  We must
+      // also remember that the distances returned are squared distances.  As a
+      // result, distance comparisons are written out as (distance * distance) for
+      // readability.
+
+      // Neighbors of point 0.
+      BOOST_REQUIRE(neighbors(0, 0) == 2);
+      BOOST_REQUIRE_CLOSE(distances(0, 0), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 0) == 5);
+      BOOST_REQUIRE_CLOSE(distances(1, 0), (0.27 * 0.27), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 0) == 1);
+      BOOST_REQUIRE_CLOSE(distances(2, 0), (0.30 * 0.30), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 0) == 8);
+      BOOST_REQUIRE_CLOSE(distances(3, 0), (0.40 * 0.40), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 0) == 9);
+      BOOST_REQUIRE_CLOSE(distances(4, 0), (0.85 * 0.85), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 0) == 10);
+      BOOST_REQUIRE_CLOSE(distances(5, 0), (0.95 * 0.95), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 0) == 3);
+      BOOST_REQUIRE_CLOSE(distances(6, 0), (1.20 * 1.20), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 0) == 7);
+      BOOST_REQUIRE_CLOSE(distances(7, 0), (1.35 * 1.35), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 0) == 6);
+      BOOST_REQUIRE_CLOSE(distances(8, 0), (2.05 * 2.05), 1e-5);
+      BOOST_REQUIRE(neighbors(9, 0) == 4);
+      BOOST_REQUIRE_CLOSE(distances(9, 0), (5.00 * 5.00), 1e-5);
+
+      // Neighbors of point 1.
+      BOOST_REQUIRE(neighbors(0, 1) == 8);
+      BOOST_REQUIRE_CLOSE(distances(0, 1), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 1) == 2);
+      BOOST_REQUIRE_CLOSE(distances(1, 1), (0.20 * 0.20), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 1) == 0);
+      BOOST_REQUIRE_CLOSE(distances(2, 1), (0.30 * 0.30), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 1) == 9);
+      BOOST_REQUIRE_CLOSE(distances(3, 1), (0.55 * 0.55), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 1) == 5);
+      BOOST_REQUIRE_CLOSE(distances(4, 1), (0.57 * 0.57), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 1) == 10);
+      BOOST_REQUIRE_CLOSE(distances(5, 1), (0.65 * 0.65), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 1) == 3);
+      BOOST_REQUIRE_CLOSE(distances(6, 1), (0.90 * 0.90), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 1) == 7);
+      BOOST_REQUIRE_CLOSE(distances(7, 1), (1.65 * 1.65), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 1) == 6);
+      BOOST_REQUIRE_CLOSE(distances(8, 1), (2.35 * 2.35), 1e-5);
+      BOOST_REQUIRE(neighbors(9, 1) == 4);
+      BOOST_REQUIRE_CLOSE(distances(9, 1), (4.70 * 4.70), 1e-5);
+
+      // Neighbors of point 2.
+      BOOST_REQUIRE(neighbors(0, 2) == 0);
+      BOOST_REQUIRE_CLOSE(distances(0, 2), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 2) == 1);
+      BOOST_REQUIRE_CLOSE(distances(1, 2), (0.20 * 0.20), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 2) == 8);
+      BOOST_REQUIRE_CLOSE(distances(2, 2), (0.30 * 0.30), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 2) == 5);
+      BOOST_REQUIRE_CLOSE(distances(3, 2), (0.37 * 0.37), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 2) == 9);
+      BOOST_REQUIRE_CLOSE(distances(4, 2), (0.75 * 0.75), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 2) == 10);
+      BOOST_REQUIRE_CLOSE(distances(5, 2), (0.85 * 0.85), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 2) == 3);
+      BOOST_REQUIRE_CLOSE(distances(6, 2), (1.10 * 1.10), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 2) == 7);
+      BOOST_REQUIRE_CLOSE(distances(7, 2), (1.45 * 1.45), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 2) == 6);
+      BOOST_REQUIRE_CLOSE(distances(8, 2), (2.15 * 2.15), 1e-5);
+      BOOST_REQUIRE(neighbors(9, 2) == 4);
+      BOOST_REQUIRE_CLOSE(distances(9, 2), (4.90 * 4.90), 1e-5);
+
+      // Neighbors of point 3.
+      BOOST_REQUIRE(neighbors(0, 3) == 10);
+      BOOST_REQUIRE_CLOSE(distances(0, 3), (0.25 * 0.25), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 3) == 9);
+      BOOST_REQUIRE_CLOSE(distances(1, 3), (0.35 * 0.35), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 3) == 8);
+      BOOST_REQUIRE_CLOSE(distances(2, 3), (0.80 * 0.80), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 3) == 1);
+      BOOST_REQUIRE_CLOSE(distances(3, 3), (0.90 * 0.90), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 3) == 2);
+      BOOST_REQUIRE_CLOSE(distances(4, 3), (1.10 * 1.10), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 3) == 0);
+      BOOST_REQUIRE_CLOSE(distances(5, 3), (1.20 * 1.20), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 3) == 5);
+      BOOST_REQUIRE_CLOSE(distances(6, 3), (1.47 * 1.47), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 3) == 7);
+      BOOST_REQUIRE_CLOSE(distances(7, 3), (2.55 * 2.55), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 3) == 6);
+      BOOST_REQUIRE_CLOSE(distances(8, 3), (3.25 * 3.25), 1e-5);
+      BOOST_REQUIRE(neighbors(9, 3) == 4);
+      BOOST_REQUIRE_CLOSE(distances(9, 3), (3.80 * 3.80), 1e-5);
+
+      // Neighbors of point 4.
+      BOOST_REQUIRE(neighbors(0, 4) == 3);
+      BOOST_REQUIRE_CLOSE(distances(0, 4), (3.80 * 3.80), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 4) == 10);
+      BOOST_REQUIRE_CLOSE(distances(1, 4), (4.05 * 4.05), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 4) == 9);
+      BOOST_REQUIRE_CLOSE(distances(2, 4), (4.15 * 4.15), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 4) == 8);
+      BOOST_REQUIRE_CLOSE(distances(3, 4), (4.60 * 4.60), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 4) == 1);
+      BOOST_REQUIRE_CLOSE(distances(4, 4), (4.70 * 4.70), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 4) == 2);
+      BOOST_REQUIRE_CLOSE(distances(5, 4), (4.90 * 4.90), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 4) == 0);
+      BOOST_REQUIRE_CLOSE(distances(6, 4), (5.00 * 5.00), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 4) == 5);
+      BOOST_REQUIRE_CLOSE(distances(7, 4), (5.27 * 5.27), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 4) == 7);
+      BOOST_REQUIRE_CLOSE(distances(8, 4), (6.35 * 6.35), 1e-5);
+      BOOST_REQUIRE(neighbors(9, 4) == 6);
+      BOOST_REQUIRE_CLOSE(distances(9, 4), (7.05 * 7.05), 1e-5);
+
+      // Neighbors of point 5.
+      BOOST_REQUIRE(neighbors(0, 5) == 0);
+      BOOST_REQUIRE_CLOSE(distances(0, 5), (0.27 * 0.27), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 5) == 2);
+      BOOST_REQUIRE_CLOSE(distances(1, 5), (0.37 * 0.37), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 5) == 1);
+      BOOST_REQUIRE_CLOSE(distances(2, 5), (0.57 * 0.57), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 5) == 8);
+      BOOST_REQUIRE_CLOSE(distances(3, 5), (0.67 * 0.67), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 5) == 7);
+      BOOST_REQUIRE_CLOSE(distances(4, 5), (1.08 * 1.08), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 5) == 9);
+      BOOST_REQUIRE_CLOSE(distances(5, 5), (1.12 * 1.12), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 5) == 10);
+      BOOST_REQUIRE_CLOSE(distances(6, 5), (1.22 * 1.22), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 5) == 3);
+      BOOST_REQUIRE_CLOSE(distances(7, 5), (1.47 * 1.47), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 5) == 6);
+      BOOST_REQUIRE_CLOSE(distances(8, 5), (1.78 * 1.78), 1e-5);
+      BOOST_REQUIRE(neighbors(9, 5) == 4);
+      BOOST_REQUIRE_CLOSE(distances(9, 5), (5.27 * 5.27), 1e-5);
+
+      // Neighbors of point 6.
+      BOOST_REQUIRE(neighbors(0, 6) == 7);
+      BOOST_REQUIRE_CLOSE(distances(0, 6), (0.70 * 0.70), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 6) == 5);
+      BOOST_REQUIRE_CLOSE(distances(1, 6), (1.78 * 1.78), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 6) == 0);
+      BOOST_REQUIRE_CLOSE(distances(2, 6), (2.05 * 2.05), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 6) == 2);
+      BOOST_REQUIRE_CLOSE(distances(3, 6), (2.15 * 2.15), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 6) == 1);
+      BOOST_REQUIRE_CLOSE(distances(4, 6), (2.35 * 2.35), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 6) == 8);
+      BOOST_REQUIRE_CLOSE(distances(5, 6), (2.45 * 2.45), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 6) == 9);
+      BOOST_REQUIRE_CLOSE(distances(6, 6), (2.90 * 2.90), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 6) == 10);
+      BOOST_REQUIRE_CLOSE(distances(7, 6), (3.00 * 3.00), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 6) == 3);
+      BOOST_REQUIRE_CLOSE(distances(8, 6), (3.25 * 3.25), 1e-5);
+      BOOST_REQUIRE(neighbors(9, 6) == 4);
+      BOOST_REQUIRE_CLOSE(distances(9, 6), (7.05 * 7.05), 1e-5);
+
+      // Neighbors of point 7.
+      BOOST_REQUIRE(neighbors(0, 7) == 6);
+      BOOST_REQUIRE_CLOSE(distances(0, 7), (0.70 * 0.70), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 7) == 5);
+      BOOST_REQUIRE_CLOSE(distances(1, 7), (1.08 * 1.08), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 7) == 0);
+      BOOST_REQUIRE_CLOSE(distances(2, 7), (1.35 * 1.35), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 7) == 2);
+      BOOST_REQUIRE_CLOSE(distances(3, 7), (1.45 * 1.45), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 7) == 1);
+      BOOST_REQUIRE_CLOSE(distances(4, 7), (1.65 * 1.65), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 7) == 8);
+      BOOST_REQUIRE_CLOSE(distances(5, 7), (1.75 * 1.75), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 7) == 9);
+      BOOST_REQUIRE_CLOSE(distances(6, 7), (2.20 * 2.20), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 7) == 10);
+      BOOST_REQUIRE_CLOSE(distances(7, 7), (2.30 * 2.30), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 7) == 3);
+      BOOST_REQUIRE_CLOSE(distances(8, 7), (2.55 * 2.55), 1e-5);
+      BOOST_REQUIRE(neighbors(9, 7) == 4);
+      BOOST_REQUIRE_CLOSE(distances(9, 7), (6.35 * 6.35), 1e-5);
+
+      // Neighbors of point 8.
+      BOOST_REQUIRE(neighbors(0, 8) == 1);
+      BOOST_REQUIRE_CLOSE(distances(0, 8), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 8) == 2);
+      BOOST_REQUIRE_CLOSE(distances(1, 8), (0.30 * 0.30), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 8) == 0);
+      BOOST_REQUIRE_CLOSE(distances(2, 8), (0.40 * 0.40), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 8) == 9);
+      BOOST_REQUIRE_CLOSE(distances(3, 8), (0.45 * 0.45), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 8) == 10);
+      BOOST_REQUIRE_CLOSE(distances(4, 8), (0.55 * 0.55), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 8) == 5);
+      BOOST_REQUIRE_CLOSE(distances(5, 8), (0.67 * 0.67), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 8) == 3);
+      BOOST_REQUIRE_CLOSE(distances(6, 8), (0.80 * 0.80), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 8) == 7);
+      BOOST_REQUIRE_CLOSE(distances(7, 8), (1.75 * 1.75), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 8) == 6);
+      BOOST_REQUIRE_CLOSE(distances(8, 8), (2.45 * 2.45), 1e-5);
+      BOOST_REQUIRE(neighbors(9, 8) == 4);
+      BOOST_REQUIRE_CLOSE(distances(9, 8), (4.60 * 4.60), 1e-5);
+
+      // Neighbors of point 9.
+      BOOST_REQUIRE(neighbors(0, 9) == 10);
+      BOOST_REQUIRE_CLOSE(distances(0, 9), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 9) == 3);
+      BOOST_REQUIRE_CLOSE(distances(1, 9), (0.35 * 0.35), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 9) == 8);
+      BOOST_REQUIRE_CLOSE(distances(2, 9), (0.45 * 0.45), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 9) == 1);
+      BOOST_REQUIRE_CLOSE(distances(3, 9), (0.55 * 0.55), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 9) == 2);
+      BOOST_REQUIRE_CLOSE(distances(4, 9), (0.75 * 0.75), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 9) == 0);
+      BOOST_REQUIRE_CLOSE(distances(5, 9), (0.85 * 0.85), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 9) == 5);
+      BOOST_REQUIRE_CLOSE(distances(6, 9), (1.12 * 1.12), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 9) == 7);
+      BOOST_REQUIRE_CLOSE(distances(7, 9), (2.20 * 2.20), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 9) == 6);
+      BOOST_REQUIRE_CLOSE(distances(8, 9), (2.90 * 2.90), 1e-5);
+      BOOST_REQUIRE(neighbors(9, 9) == 4);
+      BOOST_REQUIRE_CLOSE(distances(9, 9), (4.15 * 4.15), 1e-5);
+
+      // Neighbors of point 10.
+      BOOST_REQUIRE(neighbors(0, 10) == 9);
+      BOOST_REQUIRE_CLOSE(distances(0, 10), (0.10 * 0.10), 1e-5);
+      BOOST_REQUIRE(neighbors(1, 10) == 3);
+      BOOST_REQUIRE_CLOSE(distances(1, 10), (0.25 * 0.25), 1e-5);
+      BOOST_REQUIRE(neighbors(2, 10) == 8);
+      BOOST_REQUIRE_CLOSE(distances(2, 10), (0.55 * 0.55), 1e-5);
+      BOOST_REQUIRE(neighbors(3, 10) == 1);
+      BOOST_REQUIRE_CLOSE(distances(3, 10), (0.65 * 0.65), 1e-5);
+      BOOST_REQUIRE(neighbors(4, 10) == 2);
+      BOOST_REQUIRE_CLOSE(distances(4, 10), (0.85 * 0.85), 1e-5);
+      BOOST_REQUIRE(neighbors(5, 10) == 0);
+      BOOST_REQUIRE_CLOSE(distances(5, 10), (0.95 * 0.95), 1e-5);
+      BOOST_REQUIRE(neighbors(6, 10) == 5);
+      BOOST_REQUIRE_CLOSE(distances(6, 10), (1.22 * 1.22), 1e-5);
+      BOOST_REQUIRE(neighbors(7, 10) == 7);
+      BOOST_REQUIRE_CLOSE(distances(7, 10), (2.30 * 2.30), 1e-5);
+      BOOST_REQUIRE(neighbors(8, 10) == 6);
+      BOOST_REQUIRE_CLOSE(distances(8, 10), (3.00 * 3.00), 1e-5);
+      BOOST_REQUIRE(neighbors(9, 10) == 4);
+      BOOST_REQUIRE_CLOSE(distances(9, 10), (4.05 * 4.05), 1e-5);
+
+      // Clean the memory.
+      delete allknn;
+    }
+  }
+
+  /**
+   * Test the dual-tree nearest-neighbors method with the naive method.  This
+   * uses both a query and reference dataset.
+   *
+   * Errors are produced if the results are not identical.
+   */
+  BOOST_AUTO_TEST_CASE(dual_tree_vs_naive_1) {
+    arma::mat data_for_tree_;
+
+    // Hard-coded filename: bad!
+    if (!data::Load("test_data_3_1000.csv", data_for_tree_))
+      BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
+
+    // Set up matrices to work with.
+    arma::mat dual_query(data_for_tree_);
+    arma::mat dual_references(data_for_tree_);
+    arma::mat naive_query(data_for_tree_);
+    arma::mat naive_references(data_for_tree_);
+
+    // Reset parameters from last test.
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = false;
+    CLI::GetParam<bool>("neighbor_search/single_mode") = false;
+
+    AllkNN allknn_(dual_query, dual_references);
+
+    // Set parameters right for naive run.
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = true;
+    AllkNN naive_(naive_query, naive_references);
+
+    arma::Mat<size_t> resulting_neighbors_tree;
+    arma::mat distances_tree;
+    allknn_.ComputeNeighbors(resulting_neighbors_tree, distances_tree);
+
+    arma::Mat<size_t> resulting_neighbors_naive;
+    arma::mat distances_naive;
+    naive_.ComputeNeighbors(resulting_neighbors_naive, distances_naive);
+
+    for (size_t i = 0; i < resulting_neighbors_tree.n_elem; i++) {
+      BOOST_REQUIRE(resulting_neighbors_tree[i] == resulting_neighbors_naive[i]);
+      BOOST_REQUIRE_CLOSE(distances_tree[i], distances_naive[i], 1e-5);
+    }
+  }
+
+  /**
+   * Test the dual-tree nearest-neighbors method with the naive method.  This uses
+   * only a reference dataset.
+   *
+   * Errors are produced if the results are not identical.
+   */
+  BOOST_AUTO_TEST_CASE(dual_tree_vs_naive_2) {
+    arma::mat data_for_tree_;
+
+    // Hard-coded filename: bad!
+    // Code duplication: also bad!
+    if (!data::Load("test_data_3_1000.csv", data_for_tree_))
+      BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
+
+    // Set up matrices to work with (may not be necessary with no ALIAS_MATRIX?).
+    arma::mat dual_query(data_for_tree_);
+    arma::mat naive_query(data_for_tree_);
+
+    // Reset parameters from last test.
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = false;
+    CLI::GetParam<bool>("neighbor_search/single_mode") = false;
+    AllkNN allknn_(dual_query);
+
+    // Set naive mode.
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = true;
+    AllkNN naive_(naive_query);
+
+    arma::Mat<size_t> resulting_neighbors_tree;
+    arma::mat distances_tree;
+    allknn_.ComputeNeighbors(resulting_neighbors_tree, distances_tree);
+
+    arma::Mat<size_t> resulting_neighbors_naive;
+    arma::mat distances_naive;
+    naive_.ComputeNeighbors(resulting_neighbors_naive, distances_naive);
+
+    for (size_t i = 0; i < resulting_neighbors_tree.n_elem; i++) {
+      BOOST_REQUIRE(resulting_neighbors_tree[i] == resulting_neighbors_naive[i]);
+      BOOST_REQUIRE_CLOSE(distances_tree[i], distances_naive[i], 1e-5);
+    }
+  }
+
+  /**
+   * Test the single-tree nearest-neighbors method with the naive method.  This
+   * uses only a reference dataset.
+   *
+   * Errors are produced if the results are not identical.
+   */
+  BOOST_AUTO_TEST_CASE(single_tree_vs_naive) {
+    arma::mat data_for_tree_;
+
+    // Hard-coded filename: bad!
+    // Code duplication: also bad!
+    if (!data::Load("test_data_3_1000.csv", data_for_tree_))
+      BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
+
+    // Set up matrices to work with (may not be necessary with no ALIAS_MATRIX?).
+    arma::mat single_query(data_for_tree_);
+    arma::mat naive_query(data_for_tree_);
+
+    // Reset parameters from last test.
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = false;
+    CLI::GetParam<bool>("neighbor_search/single_mode") = true;
+    AllkNN allknn_(single_query);
+
+    // Set up computation for naive mode.
+    CLI::GetParam<bool>("neighbor_search/single_mode") = false;
+    CLI::GetParam<bool>("neighbor_search/naive_mode") = true;
+    AllkNN naive_(naive_query);
+
+    arma::Mat<size_t> resulting_neighbors_tree;
+    arma::mat distances_tree;
+    allknn_.ComputeNeighbors(resulting_neighbors_tree, distances_tree);
+
+    arma::Mat<size_t> resulting_neighbors_naive;
+    arma::mat distances_naive;
+    naive_.ComputeNeighbors(resulting_neighbors_naive, distances_naive);
+
+    for (size_t i = 0; i < resulting_neighbors_tree.n_elem; i++) {
+      BOOST_REQUIRE(resulting_neighbors_tree[i] == resulting_neighbors_naive[i]);
+      BOOST_REQUIRE_CLOSE(distances_tree[i], distances_naive[i], 1e-5);
+    }
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/aug_lagrangian_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/aug_lagrangian_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/aug_lagrangian_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,108 @@
+/***
+ * @file aug_lagrangian_test.cc
+ * @author Ryan Curtin
+ *
+ * Test of the AugmentedLagrangian class using the test functions defined in
+ * aug_lagrangian_test_functions.h.
+ */
+
+#include <mlpack/core.h>
+#include <mlpack/core/optimizers/aug_lagrangian/aug_lagrangian.hpp>
+#include <mlpack/core/optimizers/aug_lagrangian/aug_lagrangian_test_functions.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+using namespace mlpack::optimization;
+
+BOOST_AUTO_TEST_SUITE(AugLagrangianTest);
+
+  /***
+   * Tests the Augmented Lagrangian optimizer using the
+   * AugmentedLagrangianTestFunction class.
+   */
+  BOOST_AUTO_TEST_CASE(aug_lagrangian_test_function) {
+    // The choice of 10 memory slots is arbitrary.
+    AugLagrangianTestFunction f;
+    AugLagrangian<AugLagrangianTestFunction> aug(f, 10);
+
+    arma::vec coords = f.GetInitialPoint();
+
+    if(!aug.Optimize(0, coords))
+      BOOST_FAIL("Optimization reported failure.");
+
+    double final_value = f.Evaluate(coords);
+
+    BOOST_REQUIRE_CLOSE(final_value, 70, 1e-5);
+    BOOST_REQUIRE_CLOSE(coords[0], 1, 1e-5);
+    BOOST_REQUIRE_CLOSE(coords[1], 4, 1e-5);
+  }
+
+  /***
+   * Tests the Augmented Lagrangian optimizer using the Gockenbach function.
+   */
+  BOOST_AUTO_TEST_CASE(gockenbach_function) {
+    GockenbachFunction f;
+    AugLagrangian<GockenbachFunction> aug(f, 10);
+
+    arma::vec coords = f.GetInitialPoint();
+
+    if(!aug.Optimize(0, coords))
+      BOOST_FAIL("Optimization reported failure.");
+
+    double final_value = f.Evaluate(coords);
+
+    BOOST_REQUIRE_CLOSE(final_value, 29.633926, 1e-5);
+    BOOST_REQUIRE_CLOSE(coords[0], 0.12288178, 1e-5);
+    BOOST_REQUIRE_CLOSE(coords[1], -1.10778185, 1e-5);
+    BOOST_REQUIRE_CLOSE(coords[2], 0.015099932, 1e-5);
+  }
+
+  /***
+   * Extremely simple test case for the Lovasz theta SDP.
+   */
+  BOOST_AUTO_TEST_CASE(extremely_simple_lovasz_theta_sdp) {
+    // Manually input the single edge.
+    arma::mat edges = "0; 1";
+
+    LovaszThetaSDP ltsdp(edges);
+    AugLagrangian<LovaszThetaSDP> aug(ltsdp, 10);
+
+    arma::mat coords = ltsdp.GetInitialPoint();
+
+    if (!aug.Optimize(0, coords))
+      BOOST_FAIL("Optimization reported failure.");
+
+    double final_value = ltsdp.Evaluate(coords);
+
+    arma::mat X = trans(coords) * coords;
+
+    BOOST_CHECK_CLOSE(final_value, -1.0, 1e-5);
+
+    BOOST_CHECK_CLOSE(X(0, 0) + X(1, 1), 1.0, 1e-5);
+    BOOST_CHECK_SMALL(X(0, 1), 1e-8);
+    BOOST_CHECK_SMALL(X(1, 0), 1e-8);
+  }
+
+  /***
+   * Tests the Augmented Lagrangian optimizer on the Lovasz theta SDP, using the
+   * hamming_10_2 dataset, just like in the paper by Monteiro and Burer.
+   *
+  BOOST_AUTO_TEST_CASE(lovasz_theta_johnson8_4_4) {
+    arma::mat edges;
+    // Hardcoded filename: bad!
+    data::Load("MANN-a27.csv", edges);
+
+    LovaszThetaSDP ltsdp(edges);
+    AugLagrangian<LovaszThetaSDP> aug(ltsdp, 10);
+
+    arma::mat coords = ltsdp.GetInitialPoint();
+
+    if(!aug.Optimize(0, coords))
+      BOOST_FAIL("Optimization reported failure.");
+
+    double final_value = ltsdp.Evaluate(coords);
+
+    BOOST_REQUIRE_CLOSE(final_value, -14.0, 1e-5);
+  }
+  */
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/cli_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/cli_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/cli_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,239 @@
+/***
+ * @file io_test.cc
+ * @author Matthew Amidon, Ryan Curtin
+ *
+ * Test for the CLI input parameter system.
+ */
+
+#include <iostream>
+#include <sstream>
+#include <sys/time.h>
+
+#include <mlpack/core/io/optionshierarchy.hpp>
+#include <mlpack/core/io/cli.hpp>
+#include <mlpack/core/io/log.hpp>
+#include <mlpack/core.h>
+
+#define DEFAULT_INT 42
+
+//Include unit tests down here since we just have to
+#include <boost/test/unit_test.hpp>
+
+#define BASH_RED "\033[0;31m"
+#define BASH_GREEN "\033[0;32m"
+#define BASH_YELLOW "\033[0;33m"
+#define BASH_CYAN "\033[0;36m"
+#define BASH_CLEAR "\033[0m"
+
+using namespace mlpack;
+using namespace mlpack::io;
+
+BOOST_AUTO_TEST_SUITE(CLITest);
+
+  /***
+   * @brief Tests that inserting elements into an OptionsHierarchy
+   *   properly updates the tree.
+   *
+   * @return True indicating all is well with OptionsHierarchy
+   */
+  BOOST_AUTO_TEST_CASE(TestHierarchy) {
+    OptionsHierarchy tmp = OptionsHierarchy("UTest");
+    std::string testName = std::string("UTest/test");
+    std::string testDesc = std::string("Test description.");
+    std::string testTID = TYPENAME(int);
+
+    // Check that the hierarchy is properly named.
+    std::string str = std::string("UTest");
+    OptionsData node = tmp.GetNodeData();
+
+    BOOST_REQUIRE_EQUAL(str.compare(node.node), 0);
+    // Check that inserting a node actually inserts the node.
+    // Note, that since all versions of append simply call the most qualified
+    //    overload, we will only test that one.
+    tmp.AppendNode(testName, testTID, testDesc);
+    BOOST_REQUIRE(tmp.FindNode(testName) != NULL);
+
+    // Now check that the inserted node has the correct data.
+    OptionsHierarchy* testHierarchy = tmp.FindNode(testName);
+    OptionsData testData;
+    if (testHierarchy != NULL) {
+      node = testHierarchy->GetNodeData();
+
+      BOOST_REQUIRE(testName.compare(node.node) == 0);
+      BOOST_REQUIRE(testDesc.compare(node.desc) == 0);
+      BOOST_REQUIRE(testTID.compare(node.tname) == 0);
+    }
+  }
+
+  /***
+   * @brief Tests that CLI works as intended, namely that CLI::Add
+   *   propagates successfully.
+   *
+   * @return True indicating all is well with CLI::Add, false otherwise.
+   */
+  BOOST_AUTO_TEST_CASE(TestCLIAdd) {
+    // Check that the CLI::HasParam returns false if no value has been specified
+    // on the commandline and ignores any programmatical assignments.
+    CLI::Add<bool>("bool", "True or False", "global");
+    BOOST_REQUIRE_EQUAL(CLI::HasParam("global/bool"), false);
+    CLI::GetParam<bool>("global/bool") = true;
+    // CLI::HasParam should return true.
+    BOOST_REQUIRE_EQUAL(CLI::HasParam("global/bool"), true);
+
+    //Check the description of our variable.
+    BOOST_REQUIRE_EQUAL(CLI::GetDescription("global/bool").compare(
+        std::string("True or False")) , 0);
+    // Check that SanitizeString is sanitary.
+    std::string tmp = CLI::SanitizeString("/foo/bar/fizz");
+    BOOST_REQUIRE_EQUAL(tmp.compare(std::string("foo/bar/fizz/")),0);
+  }
+
+  /***
+   * Test the output of CLI.  We will pass bogus input to a stringstream so that
+   * none of it gets to the screen.
+   */
+  BOOST_AUTO_TEST_CASE(TestPrefixedOutStreamBasic) {
+    std::stringstream ss;
+    PrefixedOutStream pss(ss, BASH_GREEN "[INFO ] " BASH_CLEAR);
+
+    pss << "This shouldn't break anything" << std::endl;
+    BOOST_REQUIRE_EQUAL(ss.str(),
+        BASH_GREEN "[INFO ] " BASH_CLEAR "This shouldn't break anything\n");
+
+    ss.str("");
+    pss << "Test the new lines...";
+    pss << "shouldn't get 'Info' here." << std::endl;
+    BOOST_REQUIRE_EQUAL(ss.str(),
+        BASH_GREEN "[INFO ] " BASH_CLEAR
+        "Test the new lines...shouldn't get 'Info' here.\n");
+
+    pss << "But now I should." << std::endl << std::endl;
+    pss << "";
+    BOOST_REQUIRE_EQUAL(ss.str(),
+        BASH_GREEN "[INFO ] " BASH_CLEAR
+        "Test the new lines...shouldn't get 'Info' here.\n"
+        BASH_GREEN "[INFO ] " BASH_CLEAR "But now I should.\n"
+        BASH_GREEN "[INFO ] " BASH_CLEAR "\n"
+        BASH_GREEN "[INFO ] " BASH_CLEAR "");
+  }
+
+  /**
+   * @brief Tests that the various PARAM_* macros work properly
+   * @return True indicating that all is well with CLI & Options.
+   */
+  BOOST_AUTO_TEST_CASE(TestOption) {
+    // This test will involve creating an option, and making sure CLI reflects
+    // this.
+    PARAM(int, "test", "test desc", "test_parent", DEFAULT_INT, false);
+
+    // Does CLI reflect this?
+    BOOST_REQUIRE_EQUAL(CLI::HasParam("test_parent/test"), true);
+
+    std::string desc = std::string("test desc");
+
+    BOOST_REQUIRE_EQUAL(CLI::GetDescription("test_parent/test"), "test desc");
+    BOOST_REQUIRE_EQUAL(CLI::GetParam<int>("test_parent/test"), DEFAULT_INT);
+  }
+
+  /***
+   * Ensure that a Boolean option which we define is set correctly.
+   */
+  BOOST_AUTO_TEST_CASE(TestBooleanOption) {
+    PARAM_FLAG("flag_test", "flag test description", "test_parent");
+
+    BOOST_REQUIRE_EQUAL(CLI::HasParam("test_parent/flag_test"), false);
+
+    BOOST_REQUIRE_EQUAL(CLI::GetDescription("test_parent/flag_test"),
+        "flag test description");
+
+    // Now check that CLI reflects that it is false by default.
+    BOOST_REQUIRE_EQUAL(CLI::GetParam<bool>("test_parent/flag_test"), false);
+  }
+
+
+  /***
+   * Test that we can correctly output Armadillo objects to PrefixedOutStream
+   * objects.
+   */
+  BOOST_AUTO_TEST_CASE(TestArmadilloPrefixedOutStream) {
+    // We will test this with both a vector and a matrix.
+    arma::vec test("1.0 1.5 2.0 2.5 3.0 3.5 4.0");
+
+    std::stringstream ss;
+    PrefixedOutStream pss(ss, BASH_GREEN "[INFO ] " BASH_CLEAR);
+
+    pss << test;
+    // This should result in nothing being on the current line (since it clears
+    // it).
+    BOOST_REQUIRE_EQUAL(ss.str(), BASH_GREEN "[INFO ] " BASH_CLEAR "   1.0000\n"
+                                  BASH_GREEN "[INFO ] " BASH_CLEAR "   1.5000\n"
+                                  BASH_GREEN "[INFO ] " BASH_CLEAR "   2.0000\n"
+                                  BASH_GREEN "[INFO ] " BASH_CLEAR "   2.5000\n"
+                                  BASH_GREEN "[INFO ] " BASH_CLEAR "   3.0000\n"
+                                  BASH_GREEN "[INFO ] " BASH_CLEAR "   3.5000\n"
+                                  BASH_GREEN "[INFO ] " BASH_CLEAR "   4.0000\n");
+
+    ss.str("");
+    pss << trans(test);
+    // This should result in there being stuff on the line.
+    BOOST_REQUIRE_EQUAL(ss.str(), BASH_GREEN "[INFO ] " BASH_CLEAR
+        "   1.0000   1.5000   2.0000   2.5000   3.0000   3.5000   4.0000\n");
+
+    arma::mat test2("1.0 1.5 2.0; 2.5 3.0 3.5; 4.0 4.5 4.99999");
+    ss.str("");
+    pss << test2;
+    BOOST_REQUIRE_EQUAL(ss.str(),
+        BASH_GREEN "[INFO ] " BASH_CLEAR "   1.0000   1.5000   2.0000\n"
+        BASH_GREEN "[INFO ] " BASH_CLEAR "   2.5000   3.0000   3.5000\n"
+        BASH_GREEN "[INFO ] " BASH_CLEAR "   4.0000   4.5000   5.0000\n");
+
+    // Try and throw a curveball by not clearing the line before outputting
+    // something else.  The PrefixedOutStream should not force Armadillo objects
+    // onto their own lines.
+    ss.str("");
+    pss << "hello" << test2;
+    BOOST_REQUIRE_EQUAL(ss.str(),
+        BASH_GREEN "[INFO ] " BASH_CLEAR "hello   1.0000   1.5000   2.0000\n"
+        BASH_GREEN "[INFO ] " BASH_CLEAR "   2.5000   3.0000   3.5000\n"
+        BASH_GREEN "[INFO ] " BASH_CLEAR "   4.0000   4.5000   5.0000\n");
+  }
+
+  /***
+   * Test that we can correctly output things in general.
+   */
+  BOOST_AUTO_TEST_CASE(TestPrefixedOutStream) {
+    std::stringstream ss;
+    PrefixedOutStream pss(ss, BASH_GREEN "[INFO ] " BASH_CLEAR);
+
+    pss << "hello world I am ";
+    pss << 7;
+
+    BOOST_REQUIRE_EQUAL(ss.str(),
+        BASH_GREEN "[INFO ] " BASH_CLEAR "hello world I am 7");
+
+    pss << std::endl;
+    BOOST_REQUIRE_EQUAL(ss.str(),
+        BASH_GREEN "[INFO ] " BASH_CLEAR "hello world I am 7\n");
+
+    ss.str("");
+    pss << std::endl;
+    BOOST_REQUIRE_EQUAL(ss.str(),
+        BASH_GREEN "[INFO ] " BASH_CLEAR "\n");
+  }
+
+  /***
+   * Test format modifiers.
+   */
+  BOOST_AUTO_TEST_CASE(TestPrefixedOutStreamModifiers) {
+    std::stringstream ss;
+    PrefixedOutStream pss(ss, BASH_GREEN "[INFO ] " BASH_CLEAR);
+
+    pss << "I have a precise number which is ";
+    pss << std::setw(6) << std::setfill('0') << 156;
+
+    BOOST_REQUIRE_EQUAL(ss.str(),
+        BASH_GREEN "[INFO ] " BASH_CLEAR
+        "I have a precise number which is 000156");
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/data/fake.csv
===================================================================
--- mlpack/trunk/src/mlpack/tests/data/fake.csv	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/data/fake.csv	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,100 @@
+-0.28992,-0.13173,-0.61575
+-1.2142,-1.1994,-0.4661
+0.031128,0.084721,-0.057328
+-0.86099,-0.79692,-0.35194
+-0.45353,-0.11696,-0.15629
+0.82319,0.31796,0.5654
+0.87603,0.62511,0.54203
+-1.8458,-1.2202,-1.6845
+1.3571,0.86032,0.95889
+-0.88157,-0.092799,-0.21391
+-1.7254,-0.80534,-1.2231
+-3.7444,-2.7681,-2.8587
+-1.9593,-1.9499,-1.6215
+0.036513,-0.65684,-0.16414
+-1.0091,-0.9538,-0.82084
+-2.6299,-2.4503,-2.0805
+1.4404,0.91235,1.0368
+2.3232,1.7905,1.3835
+-0.22953,0.29435,-0.55121
+0.52442,0.53273,0.29293
+1.9345,1.1211,1.5277
+-0.71909,-0.91217,-0.13798
+-1.0023,-0.31518,-0.83793
+0.88445,0.55393,0.63455
+-0.14286,0.75819,0.10212
+-0.57519,-0.41389,-0.16138
+-0.54536,-0.54785,0.19468
+0.18259,-0.038652,-0.11602
+1.5583,1.5063,1.1687
+0.67228,0.25056,0.28417
+1.8047,1.3339,1.8819
+1.6772,1.8611,1.5816
+0.30442,0.39109,0.31353
+-0.66552,-0.38255,-0.36366
+-0.99614,-0.31771,0.10233
+0.65813,0.72853,0.66725
+1.3433,0.87076,0.9503
+0.5952,0.54358,0.15799
+0.80337,0.48182,0.92845
+-1.0895,-0.77068,-0.43275
+-1.2246,-1.0886,-0.81559
+-3.2332,-2.2593,-1.8321
+2.36,1.5532,1.98
+-1.417,-0.72475,-1.6775
+0.48999,0.27822,0.63959
+1.7494,1.1849,1.2174
+0.098846,0.48884,0.58291
+-2.2389,-1.239,-1.5603
+-2.5684,-2.0838,-2.044
+1.833,1.9878,1.488
+-1.3408,-0.41722,-0.78372
+0.41603,-0.03137,-0.19393
+1.3308,0.97246,0.50187
+1.8763,1.4224,1.5111
+0.47414,0.35165,0.45279
+0.72983,0.62162,0.81429
+0.072535,-0.15613,0.19178
+0.24045,0.31484,0.73666
+-0.63399,-0.44661,0.16174
+-0.7575,-0.29941,-0.23175
+-0.22151,0.13724,-0.053466
+-0.61552,-0.30699,-0.18651
+0.13717,0.14514,-0.13645
+0.79648,1.0154,0.66609
+0.02903,0.11115,-0.027887
+1.2644,0.91254,0.91018
+-0.36039,-0.27273,-0.093994
+1.8088,1.6939,1.1004
+-1.4649,-1.1623,-1.3663
+0.16635,0.21012,-0.5929
+-1.9238,-0.92677,-1.2546
+-1.1433,-1.2331,-0.83555
+-1.3747,-1.2459,-0.9011
+0.66298,0.6126,0.17198
+-0.4638,-0.12425,-0.29331
+-1.1176,-0.7349,-0.67311
+0.13308,0.25935,0.25244
+-0.068732,-0.5169,-0.16423
+-0.56212,-0.51442,-0.3723
+-1.7361,-1.4933,-1.4681
+0.98691,0.45932,0.37285
+0.21825,-0.36061,-0.26815
+0.90569,0.70056,0.68695
+1.9013,1.2122,1.4488
+-1.7678,-1.0156,-1.173
+0.38102,-0.26481,0.1876
+-1.7408,-1.4657,-1.3288
+-0.40932,-0.036133,0.12221
+0.15014,0.23639,0.54873
+-1.9972,-1.75,-1.8577
+-1.8673,-1.0512,-1.2368
+0.33336,1.028,0.67552
+0.12516,0.33989,0.54363
+1.2947,1.1484,1.3026
+-2.6568,-1.9047,-1.6224
+0.80258,1.1538,0.43664
+0.68373,0.22631,-0.13506
+2.0724,1.9613,1.4781
+-0.057605,0.069219,0.048158
+0.25527,0.50668,-0.053834

Added: mlpack/trunk/src/mlpack/tests/data/testRes.csv
===================================================================
--- mlpack/trunk/src/mlpack/tests/data/testRes.csv	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/data/testRes.csv	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1 @@
+0,0,0,1,1,1,1

Added: mlpack/trunk/src/mlpack/tests/data/testSet.csv
===================================================================
--- mlpack/trunk/src/mlpack/tests/data/testSet.csv	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/data/testSet.csv	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,7 @@
+2,4,4,2,0
+2,5,4,2,0
+2,4,4,4,0
+8,4,4,2,1
+8,4,4,2,1
+8,5,4,2,1
+8,4,4,4,1

Added: mlpack/trunk/src/mlpack/tests/data/test_data_3_1000.csv
===================================================================
--- mlpack/trunk/src/mlpack/tests/data/test_data_3_1000.csv	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/data/test_data_3_1000.csv	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,1000 @@
+0.339406815,0.843176636,0.472701471
+0.212587646,0.351174901,0.81056695
+0.605649993,0.45338097,0.623370668
+0.269783539,0.482031883,0.36535861
+0.725254282,0.477113042,0.042100268
+0.529287901,0.776008587,0.303809928
+0.098778217,0.318454787,0.983422857
+0.685345453,0.837942768,0.540406673
+0.503220972,0.268813629,0.41488501
+0.160147626,0.255047893,0.04072469
+0.564535197,0.943435462,0.597070812
+0.663842864,0.276972185,0.02208704
+0.077321401,0.032366881,0.826784604
+0.794220519,0.319582218,0.266025433
+0.466815953,0.864683732,0.684380976
+0.680962499,0.009554527,0.484176898
+0.257862396,0.875068776,0.326253946
+0.695503778,0.695095604,0.955586038
+0.569205007,0.662786497,0.036489177
+0.604542917,0.250714055,0.232826165
+0.928175028,0.871769923,0.327107027
+0.362809806,0.270846833,0.917535106
+0.567471988,0.09223176,0.018232595
+0.30294,0.197331083,0.676067984
+0.136497436,0.991079028,0.640906359
+0.490191642,0.321877535,0.210121475
+0.886240693,0.124811844,0.109638108
+0.487537807,0.474289999,0.34183089
+0.038698268,0.515865087,0.984297254
+0.437309222,0.534489172,0.792665419
+0.898099395,0.461121197,0.785225662
+0.256850927,0.840446806,0.056158684
+0.335408063,0.806637161,0.913551388
+0.11329872,0.670392847,0.333361274
+0.954403847,0.024104509,0.325578493
+0.824152332,0.614355433,0.271931013
+0.729647547,0.666093053,0.579723184
+0.25675029,0.94037263,0.530553224
+0.799877963,0.555666351,0.056606945
+0.213120693,0.763046224,0.341926361
+0.975873714,0.554796483,0.049489218
+0.422782321,0.375502502,0.875514176
+0.732474122,0.920181004,0.273895723
+0.288070185,0.878065303,0.57017629
+0.269706239,0.854626516,0.607709975
+0.615118638,0.006748605,0.00278243
+0.655373608,0.348029869,0.909502319
+0.358287814,0.419322455,0.362741982
+0.152473842,0.659459939,0.497284571
+0.930791658,0.934132013,0.150924236
+0.792977546,0.953203388,0.465884431
+0.971953827,0.268751729,0.220474277
+0.244730747,0.056636753,0.088649766
+0.873554351,0.305649442,0.91790044
+0.26662478,0.221646762,0.310857157
+0.659541537,0.93018384,0.139339275
+0.833616742,0.833734413,0.551027856
+0.43405195,0.874582065,0.996443541
+0.442896336,0.118977275,0.03127628
+0.388886541,0.976070927,0.294801481
+0.14757794,0.195944854,0.129778502
+0.73209291,0.551685931,0.218866346
+0.85393572,0.675733762,0.501776114
+0.804291505,0.746786474,0.94053733
+0.199998362,0.403471102,0.614783956
+0.302029244,0.084831174,0.043490422
+0.458371115,0.076068613,0.940418665
+0.122287089,0.867270578,0.612001352
+0.423331474,0.370629389,0.407480574
+0.400056969,0.919523609,0.940521669
+0.74852813,0.872400563,0.915423635
+0.614934326,0.67621724,0.382278246
+0.0184522,0.545825352,0.74127138
+0.937453855,0.175662201,0.666301896
+0.504358818,0.251308945,0.849159677
+0.397410107,0.973000161,0.648601332
+0.398342217,0.110698975,0.916968596
+0.464980239,0.683124011,0.070633362
+0.787030874,0.393777381,0.731973049
+0.612845512,0.893440416,0.475331995
+0.241219407,0.792282417,0.389574277
+0.465756798,0.552685716,0.092092299
+0.908028882,0.837528446,0.794160948
+0.552741674,0.898614081,0.764312365
+0.607116253,0.958698621,0.334887326
+0.322583246,0.541387861,0.879874555
+0.124522558,0.229074642,0.510214096
+0.049900273,0.471371867,0.367698395
+0.261657863,0.105228571,0.748191349
+0.216818324,0.700885804,0.34479269
+0.896337659,0.634574468,0.203599217
+0.961150989,0.920563011,0.795999477
+0.120635447,0.744570376,0.107177572
+0.696406743,0.788342315,0.173664558
+0.577700329,0.493151732,0.989211395
+0.270346683,0.586765585,0.208832269
+0.171412097,0.116618251,0.53141933
+0.596260532,0.819973735,0.531503373
+0.120665467,0.556332466,0.643268746
+0.546751646,0.563896374,0.079856633
+0.637150933,0.126536213,0.823749724
+0.637940649,0.951567917,0.397777975
+0.344749598,0.517031469,0.48297473
+0.296545224,0.419944602,0.99985146
+0.707956343,0.985929306,0.942420811
+0.24734852,0.001808114,0.489512545
+0.29395388,0.751934338,0.924845167
+0.306350765,0.676837884,0.614397758
+0.387029257,0.668882644,0.316866608
+0.166701475,0.220250465,0.70788096
+0.666366134,0.343214579,0.063804166
+0.970614577,0.514452347,0.643280872
+0.084297811,0.906111319,0.590434434
+0.163302217,0.226212634,0.074753132
+0.20207705,0.197835179,0.217985026
+0.413236066,0.640190511,0.520645448
+0.807941459,0.463910044,0.996796367
+0.208875906,0.182468954,0.876826443
+0.743474185,0.840439019,0.143677671
+0.266758693,0.103719005,0.920995789
+0.030607849,0.973154392,0.814015083
+0.237753714,0.374336732,0.44138091
+0.83212984,0.547216604,0.371699647
+0.302411666,0.58054099,0.303141758
+0.949214871,0.783756542,0.457582838
+0.32776739,0.133095384,0.351183944
+0.673471065,0.432009028,0.761641303
+0.120361022,0.494421101,0.954699616
+0.049975694,0.857405242,0.133753572
+0.314326245,0.599784238,0.698931698
+0.10972582,0.994733888,0.603365409
+0.246939825,0.79385323,0.576049373
+0.420949269,0.55824091,0.684730016
+0.085903635,0.678776288,0.759533545
+0.221902971,0.606683148,0.183625782
+0.934582003,0.263106456,0.195228637
+0.276550653,0.563455012,0.477130256
+0.939865401,0.683543172,0.98694541
+0.090714119,0.155392084,0.183225576
+0.546170002,0.226065658,0.757518873
+0.635725491,0.259656977,0.803254796
+0.768135532,0.329687113,0.784471673
+0.67201594,0.69314804,0.216292884
+0.731388623,0.632648812,0.298465113
+0.030104188,0.531279626,0.68605789
+0.404907965,0.617707054,0.646985633
+0.38264213,0.522044947,0.606066308
+0.850778503,0.771072538,0.780038925
+0.333386945,0.62981651,0.838539888
+0.144526261,0.90723358,0.672092924
+0.803193149,0.545698586,0.740250704
+0.144775421,0.073065649,0.81327723
+0.800150626,0.077947117,0.498989131
+0.805355858,0.282274855,0.111520406
+0.432276345,0.614069782,0.04562788
+0.119740317,0.122788948,0.68461108
+0.188596378,0.666133286,0.753645204
+0.143050522,0.393902986,0.609633117
+0.754401856,0.84172035,0.387786256
+0.97549575,0.97044364,0.621482928
+0.735098473,0.96738673,0.239086021
+0.825090649,0.153687653,0.520111132
+0.720848546,0.211391499,0.513430909
+0.572411742,0.56579983,0.313933048
+0.766584951,0.704264072,0.103088529
+0.933914925,0.70795791,0.378434849
+0.232266382,0.864968616,0.664769493
+0.180748316,0.792633394,0.983236654
+0.320744207,0.073646797,0.915148464
+0.058415284,0.478244018,0.171213592
+0.613274471,0.423949271,0.899198164
+0.83818587,0.622457639,0.496368891
+0.547369341,0.5160996,0.318684775
+0.489079348,0.504840066,0.174865371
+0.133510366,0.873938618,0.95342181
+0.355477984,0.610358907,0.32242224
+0.32167355,0.132961802,0.381440702
+0.660257981,0.59386003,0.570704079
+0.519799486,0.220676336,0.85452965
+0.097125446,0.037837774,0.581579153
+0.801485909,0.741547848,0.06310355
+0.413142247,0.303102946,0.30224609
+0.07746447,0.555846316,0.750106689
+0.593760097,0.256631753,0.179035377
+0.819000445,0.86578977,0.797167379
+0.644052663,0.148335877,0.377067692
+0.02037784,0.835405997,0.192438566
+0.248506314,0.951214215,0.492923258
+0.387445752,0.862693509,0.11983047
+0.411437123,0.512831692,0.516380652
+0.481199694,0.970780992,0.565521666
+0.967908564,0.168755985,0.447517833
+0.280607962,0.670538365,0.548021587
+0.402044213,0.121532495,0.136718448
+0.83696286,0.739549154,0.495218329
+0.652215616,0.664877651,0.838254198
+0.846246408,0.411635906,0.96601722
+0.359827733,0.627436225,0.666295882
+0.522326573,0.496565812,0.404066784
+0.614406114,0.160072022,0.269439305
+0.221722954,0.558736063,0.890699947
+0.561777087,0.782270647,0.792345194
+0.385698506,0.295964873,0.697613223
+0.101162968,0.27600378,0.239798872
+0.075127486,0.14163579,0.728168103
+0.982440842,0.583109151,0.395072917
+0.69628067,0.26642599,0.283866713
+0.073093261,0.914332418,0.925554624
+0.01642578,0.927883834,0.248712685
+0.11636724,0.556067816,0.248282085
+0.487453151,0.058684617,0.294624957
+0.813726551,0.860917181,0.678149491
+0.492581545,0.501803813,0.193032429
+0.642766795,0.422421802,0.950458987
+0.662519175,0.950448071,0.157126432
+0.548815699,0.127905654,0.23337741
+0.159163516,0.345059322,0.586704542
+0.40029112,0.928563882,0.954476476
+0.587201396,0.44357769,0.797926632
+0.026827624,0.206281621,0.680220462
+0.884217164,0.266754666,0.652197582
+0.475019281,0.447732834,0.14299077
+0.193076354,0.317892868,0.976621856
+0.515208981,0.512331237,0.422351595
+0.336671812,0.870606258,0.364554196
+0.438596677,0.333836845,0.801388791
+0.194389409,0.929245672,0.589545825
+0.205377525,0.079938747,0.187363423
+0.426814991,0.823224852,0.707435026
+0.262972959,0.517545732,0.19872636
+0.720354434,0.847649202,0.709246477
+0.355306192,0.303943053,0.835051265
+0.949975427,0.106134411,0.204516092
+0.106374426,0.874129261,0.971439223
+0.14517828,0.371147898,0.695954142
+0.739099753,0.331888701,0.890413781
+0.627551297,0.9001009,0.177324543
+0.047488938,0.224289129,0.220822902
+0.912785118,0.79570392,0.838242455
+0.49717293,0.703176431,0.754883589
+0.090976094,0.502530756,0.657999889
+0.194042479,0.284561692,0.14516165
+0.409960603,0.285564554,0.097001811
+0.310205693,0.003434942,0.173823303
+0.233583043,0.118822434,0.816665508
+0.513843271,0.539640669,0.864405207
+0.40692643,0.436463418,0.369798489
+0.126544008,0.159580886,0.933714485
+0.286441339,0.872974675,0.04454198
+0.964565622,0.910027403,0.897861798
+0.203121728,0.899714292,0.085173744
+0.445639841,0.360999337,0.016645134
+0.307793993,0.117750087,0.562967352
+0.281587526,0.174834541,0.274581395
+0.119660773,0.099740072,0.484016211
+0.511583585,0.54938211,0.339766424
+0.188451695,0.073022292,0.006123739
+0.346586219,0.49567248,0.234826476
+0.225242461,0.587641331,0.725805817
+0.075409614,0.208266437,0.826377328
+0.204076002,0.04779427,0.040457828
+0.050861901,0.763043363,0.256073344
+0.972150662,0.792678045,0.909955027
+0.506115605,0.031837525,0.903340416
+0.804010111,0.955685921,0.175896939
+0.092926989,0.062223289,0.821308211
+0.363715968,0.726101463,0.79168981
+0.787381816,0.338102828,0.005758252
+0.484331698,0.495765424,0.891180155
+0.241982415,0.277129738,0.561477087
+0.484161267,0.286665154,0.03556541
+0.211600046,0.304292614,0.395789513
+0.372524976,0.202611617,0.166595985
+0.265124748,0.017345601,0.037686194
+0.701786714,0.420334817,0.714000487
+0.034048463,0.651290563,0.050634716
+0.802331316,0.558297752,0.291679579
+0.344037056,0.467477672,0.358504649
+0.639463582,0.425507582,0.954817361
+0.602885138,0.374751922,0.374607167
+0.993637385,0.955212301,0.16550343
+0.955669008,0.745723993,0.889786752
+0.365337348,0.19682491,0.506234866
+0.7457291,0.51831627,0.978818087
+0.92625289,0.631584997,0.443128894
+0.786168714,0.264993195,0.263960382
+0.316681591,0.61079768,0.089349247
+0.858371024,0.834969763,0.174819213
+0.525393487,0.243792169,0.955241627
+0.720242053,0.143419208,0.402799979
+0.749292304,0.217311863,0.799688479
+0.246462289,0.958943724,0.142358796
+0.528138907,0.590786754,0.948225902
+0.454799161,0.510565688,0.295103038
+0.953069085,0.021533141,0.116332423
+0.188120341,0.690529852,0.623168048
+0.318359731,0.758493036,0.91843922
+0.726077549,0.902046947,0.327147423
+0.386752461,0.338547997,0.651921958
+0.707225745,0.584329479,0.37703596
+0.060288975,0.494620757,0.075518168
+0.237652566,0.962903992,0.824801251
+0.535945075,0.958493881,0.754701994
+0.064404553,0.235151293,0.39448081
+0.979476468,0.347342952,0.99138709
+0.189166661,0.798328607,0.697048046
+0.180560013,0.342106481,0.174983336
+0.28337819,0.962425666,0.955845318
+0.593924663,0.66654314,0.570147835
+0.114749593,0.903677338,0.957687266
+0.151925114,0.716482401,0.637800283
+0.235669594,0.580788646,0.528893286
+0.778117587,0.250968708,0.684104646
+0.747849981,0.214563448,0.02984775
+0.720813243,0.066656345,0.737883757
+0.626964368,0.953760147,0.459809098
+0.469018562,0.720549931,0.518332767
+0.821461664,0.507041049,0.514946331
+0.384160041,0.953174654,0.443907617
+0.233220889,0.511502601,0.369065624
+0.434955659,0.150497671,0.76574469
+0.8958592,0.481635774,0.942994014
+0.979260732,0.445148596,0.323549157
+0.334878174,0.403760723,0.385124629
+0.460214884,0.33828675,0.592783427
+0.518346254,0.909618383,0.6009723
+0.338370801,0.317375424,0.337490389
+0.636668843,0.96449714,0.481975016
+0.025064304,0.923419227,0.119203699
+0.048318449,0.53489191,0.76133984
+0.491930784,0.016568024,0.112619998
+0.17743988,0.903969674,0.481918653
+0.981634317,0.513179093,0.316557669
+0.02560158,0.930375993,0.563316641
+0.017997936,0.890571459,0.4580491
+0.96277821,0.443025655,0.083145161
+0.419576578,0.112060055,0.531294103
+0.494454706,0.954168063,0.047922651
+0.800000835,0.673332473,0.064026809
+0.870702162,0.510095577,0.863030178
+0.851121904,0.916229763,0.781903614
+0.159726434,0.082081261,0.19548317
+0.362450326,0.788524336,0.826141196
+0.270846003,0.098989879,0.574494436
+0.406889772,0.838173717,0.436699777
+0.035503139,0.853255007,0.642800341
+0.083155666,0.952721164,0.708076056
+0.847697478,0.56519776,0.894660498
+0.037841045,0.984301359,0.365909559
+0.177721428,0.418447797,0.157612683
+0.429370039,0.508723836,0.767724035
+0.071851749,0.216253471,0.819600825
+0.578083664,0.212360494,0.627380646
+0.380746754,0.954034946,0.11483721
+0.211278539,0.560080096,0.685450354
+0.770737322,0.813954563,0.79322567
+0.318759117,0.06983,0.664250133
+0.059856737,0.06677071,0.26622355
+0.968241527,0.953861837,0.311894576
+0.504226431,0.06220937,0.289105117
+0.256406511,0.249902695,0.348997399
+0.674888311,0.860374,0.605942473
+0.246067727,0.048342783,0.343006159
+0.830735494,0.783740344,0.677522751
+0.99887952,0.341758368,0.229922444
+0.731699282,0.940258743,0.10886285
+0.541383735,0.910293019,0.381124662
+0.750868727,0.848911762,0.265718422
+0.425671591,0.626146239,0.622684142
+0.214013066,0.091251581,0.864057899
+0.545601885,0.310480085,0.046543211
+0.517244356,0.115819763,0.248517895
+0.872633121,0.50117097,0.12009094
+0.255496857,0.472006579,0.796438566
+0.468962035,0.26918685,0.131735945
+0.742353904,0.528441793,0.565922864
+0.85366711,0.2676075,0.914062206
+0.447698287,0.149534939,0.670156644
+0.445589481,0.6431063,0.225580433
+0.357872915,0.788565726,0.814611643
+0.580287142,0.506307991,0.527031912
+0.500500265,0.365277722,0.04677688
+0.141881394,0.926001483,0.86894952
+0.221717771,0.366035312,0.125658418
+0.600339909,0.684670388,0.826168927
+0.307898392,0.20966968,0.752966481
+0.959700077,0.899536378,0.491452813
+0.230433688,0.613941888,0.415683508
+0.495527265,0.634504412,0.370199526
+0.506575734,0.986633413,0.84941237
+0.761764339,0.963921599,0.828872018
+0.348601654,0.087553061,0.791174897
+0.104944192,0.102179531,0.905877926
+0.375324247,0.246387607,0.301420991
+0.875454272,0.118686164,0.988824311
+0.17698346,0.393647261,0.159870783
+0.917659703,0.583236755,0.630992101
+0.285048123,0.469986869,0.37272766
+0.011480822,0.597073945,0.904116141
+0.313259229,0.510005423,0.894823085
+0.795838324,0.911141124,0.928152818
+0.164974957,0.359128099,0.60236716
+0.983429159,0.003861397,0.083218217
+0.242529745,0.562773547,0.664077813
+0.765913188,0.194009625,0.286229668
+0.070781352,0.102661854,0.249285398
+0.511452125,0.418997177,0.284014634
+0.439472205,0.891870259,0.82363463
+0.580892549,0.466753672,0.140496383
+0.615517449,0.738921356,0.461546367
+0.824697707,0.698589656,0.941554339
+0.46610398,0.902958283,0.688012984
+0.523365471,0.691567649,0.547171487
+0.545929937,0.714552317,0.041938604
+0.32756288,0.701840615,0.927731162
+0.761874356,0.276228477,0.886668834
+0.979442228,0.298771691,0.591610911
+0.374731022,0.860510449,0.321638525
+0.8074911,0.097011746,0.930723417
+0.453431338,0.206882669,0.431005917
+0.910029309,0.03223923,0.493150704
+0.2897017,0.170401689,0.739971322
+0.024666309,0.777054677,0.769170439
+0.05624039,0.089983601,0.64642539
+0.149696037,0.539762835,0.702098143
+0.676100319,0.000479419,0.639516981
+0.967411256,0.893394783,0.958913773
+0.158669993,0.527294695,0.347808355
+0.181672491,0.532695548,0.988953142
+0.053598946,0.497693858,0.118111495
+0.132496571,0.985450674,0.753931807
+0.87586561,0.732063591,0.884137731
+0.419609591,0.012639269,0.645369169
+0.102047486,0.008854525,0.658344391
+0.123913855,0.210708056,0.499395878
+0.159685659,0.968477268,0.586268979
+0.834269522,0.369645239,0.245380904
+0.637297781,0.768550638,0.48870442
+0.778386961,0.376787501,0.03205647
+0.67713794,0.632054697,0.000672655
+0.860752189,0.140567399,0.326727043
+0.220600271,0.039797462,0.871431738
+0.373493897,0.910009286,0.043303147
+0.269453424,0.571833998,0.346704152
+0.919787568,0.373470212,0.873193468
+0.776952353,0.362003265,0.172733797
+0.575862615,0.900415576,0.599884308
+0.616882997,0.8845633,0.13177173
+0.366855251,0.729104299,0.950578149
+0.668847681,0.753527405,0.660832331
+0.264243456,0.308498641,0.912106098
+0.542527865,0.880831766,0.535728949
+0.460634645,0.013712653,0.152280892
+0.828209711,0.921304334,0.049084108
+0.874065663,0.473229025,0.545232499
+0.731220357,0.126627169,0.996060848
+0.943461868,0.033256065,0.992038738
+0.211193798,0.522810965,0.907780013
+0.767158364,0.967162642,0.888059793
+0.689583275,0.841550923,0.377520241
+0.147705388,0.959063909,0.031580823
+0.654707489,0.752912445,0.305046055
+0.628378168,0.075829853,0.719349441
+0.886468112,0.185491156,0.719710557
+0.749470564,0.448017109,0.897349202
+0.492693185,0.884164268,0.633427171
+0.44686733,0.7934547,0.773846432
+0.630683325,0.776592453,0.708944434
+0.814848973,0.845977344,0.643222219
+0.016975156,0.729138989,0.058020996
+0.511298247,0.07057554,0.733405098
+0.784480806,0.738595698,0.373688534
+0.530814843,0.44312087,0.691107945
+0.944091316,0.957332961,0.639542386
+0.771047017,0.811962024,0.977774991
+0.87020688,0.755962661,0.925248114
+0.458700988,0.334773333,0.095844508
+0.533831151,0.912609619,0.027149015
+0.524625598,0.652693277,0.497418106
+0.805674264,0.723021478,0.80073208
+0.113696528,0.650247192,0.344709776
+0.826900827,0.593783006,0.550936366
+0.940655423,0.740273144,0.630218018
+0.141520315,0.632429144,0.838610834
+0.39673597,0.503240828,0.590691376
+0.037602886,0.040815285,0.620639119
+0.716116291,0.506754028,0.253596249
+0.619782298,7.76626E-05,0.676065593
+0.496033457,0.98742451,0.984019601
+0.649314148,0.147470427,0.489967654
+0.691622038,0.161245902,0.647851723
+0.936526892,0.590442875,0.939555093
+0.604802621,0.838823011,0.251219058
+0.071190531,0.67647138,0.597666328
+0.019410183,0.495778133,0.44031324
+0.726411874,0.262687025,0.086312948
+0.830480537,0.135077568,0.079159787
+0.950841893,0.769723105,0.47873095
+0.611417896,0.84114966,0.395349789
+0.181347141,0.287776713,0.883076078
+0.200712222,0.873964629,0.571505353
+0.65202277,0.084117342,0.250545655
+0.342561024,0.202306216,0.079726003
+0.584301932,0.122693153,0.129858724
+0.591176502,0.051275102,0.876431468
+0.165946295,0.474087103,0.856717365
+0.839385948,0.763414504,0.961778868
+0.528260865,0.865453126,0.680673095
+0.076050301,0.71693581,0.15210816
+0.780443967,0.33197709,0.73242445
+0.363327494,0.164977224,0.185099911
+0.687912867,0.396104619,0.249748592
+0.88391393,0.554502064,0.089705278
+0.33788714,0.686247878,0.252660937
+0.19163616,0.441496434,0.513458703
+0.478908993,0.15156254,0.818829745
+0.918896553,0.899169945,0.780767514
+0.782967436,0.327693122,0.755050753
+0.32558364,0.492239506,0.12339517
+0.047070459,0.693552034,0.508452959
+0.109465204,0.821862145,0.632136838
+0.826253828,0.610682399,0.632137891
+0.162364171,0.5709024,0.027035072
+0.479768494,0.607203769,0.077566143
+0.897031412,0.795684932,0.974415558
+0.801002173,0.551618649,0.876984199
+0.123312093,0.411438516,0.901446561
+0.594677287,0.32833558,0.914104796
+0.741635419,0.14325589,0.115905361
+0.08993896,0.243272135,0.742401503
+0.116491314,0.690400792,0.020805328
+0.180855336,0.599454312,0.340688071
+0.087037755,0.006886539,0.952560809
+0.300603611,0.113658264,0.797478049
+0.832235841,0.05963984,0.771465426
+0.095194013,0.247650851,0.801344581
+0.300632189,0.150924198,0.086360387
+0.874625368,0.700861247,0.713919826
+0.863383564,0.57922769,0.870911826
+0.11913471,0.767551415,0.50918181
+0.556749667,0.691513618,0.782003681
+0.197331319,0.827247513,0.779623914
+0.987023902,0.734883462,0.623629089
+0.420615082,0.614082171,0.741891207
+0.312249031,0.014913149,0.070878868
+0.974642188,0.983123549,0.086275706
+0.783360774,0.814835668,0.67625897
+0.540478752,0.254940938,0.449867885
+0.048763621,0.290768213,0.625363258
+0.697965851,0.033892112,0.612844092
+0.724879255,0.708375839,0.525641059
+0.747562377,0.173208535,0.263779612
+0.867179342,0.213616814,0.754428508
+0.02226162,0.326141353,0.081963664
+0.627227744,0.116451144,0.409565408
+0.543129433,0.092850944,0.54072763
+0.281594806,0.709633472,0.876793176
+0.35647452,0.063874296,0.965050871
+0.045168661,0.497624359,0.186815072
+0.524949861,0.944601324,0.332059785
+0.126474627,0.02739514,0.246752374
+0.208604998,0.568408651,0.772918262
+0.125784169,0.514833609,0.514478954
+0.154512957,0.373291441,0.993402025
+0.233618131,0.572616698,0.016411005
+0.999890963,0.570275565,0.216853317
+0.486828361,0.379924401,0.696213866
+0.075314427,0.667395497,0.863855433
+0.86294927,0.812782874,0.997533964
+0.031445186,0.249022328,0.973324576
+0.326573891,0.118171329,0.965763005
+0.332020059,0.604459411,0.538268842
+0.706622108,0.694323961,0.209014536
+0.932949763,0.08165582,0.356510191
+0.75591714,0.880443277,0.240181713
+0.227219665,0.515538046,0.063202431
+0.069200681,0.150851636,0.361221939
+0.902427408,0.646942656,0.504832272
+0.262382978,0.180972368,0.403132445
+0.032506623,0.656194,0.257345113
+0.959652463,0.776117592,0.653289283
+0.778669537,0.171816058,0.383820737
+0.64856927,0.78342696,0.966231461
+0.638608998,0.323023815,0.667259556
+0.120265759,0.176019011,0.416173717
+0.275065523,0.921190579,0.324061946
+0.490137925,0.337844445,0.135339916
+0.724097632,0.992269402,0.410123181
+0.296958503,0.142356399,0.479483213
+0.092381103,0.57773093,0.290898447
+0.89183933,0.312149005,0.295126666
+0.669251799,0.071453982,0.955861716
+0.938378225,0.324238979,0.455589077
+0.762236627,0.048617283,0.120655973
+0.886194063,0.842136906,0.886167779
+0.420448588,0.826040453,0.209811195
+0.496120113,0.140244984,0.010275807
+0.291770734,0.089337397,0.940136172
+0.823744617,0.442752205,0.79506829
+0.86635257,0.308919721,0.929313191
+0.124187371,0.515507145,0.3952627
+0.515643261,0.514493405,0.592216269
+0.435577703,0.202265522,0.749380396
+0.851215206,0.581140662,0.909262689
+0.97276388,0.305964393,0.119556192
+0.833642983,0.44267292,0.574065373
+0.908658096,0.985442117,0.032891222
+0.120536868,0.898167052,0.754847347
+0.328480689,0.206500348,0.883388839
+0.584233318,0.127164736,0.934356548
+0.520904286,0.085542266,0.469645136
+0.118804512,0.276694477,0.255706174
+0.669152609,0.480169645,0.350044668
+0.784599588,0.030844507,0.672270616
+0.97462202,0.984822685,0.801402402
+0.09061512,0.20599842,0.288943446
+0.500630874,0.668012143,0.326107661
+0.243946646,0.885842685,0.356343047
+0.704519934,0.112411764,0.840776533
+0.064722176,0.148130565,0.724221405
+0.069998846,0.826917642,0.285248236
+0.463142105,0.129132053,0.071693121
+0.065672617,0.491471158,0.143248345
+0.345719852,0.550477283,0.417188691
+0.523811405,0.923188335,0.366706095
+0.57113315,0.798590349,0.465646081
+0.828359309,0.886833757,0.470994632
+0.649200809,0.422037446,0.338970547
+0.991959241,0.065292471,0.545926733
+0.402707667,0.892315167,0.157737898
+0.583371677,0.915247643,0.510882162
+0.286752954,0.119216908,0.422178531
+0.000574842,0.932477989,0.322762631
+0.521100182,0.182516345,0.799539149
+0.217552185,0.32460329,0.001286413
+0.129263953,0.832799191,0.746800354
+0.859133069,0.682500693,0.035727655
+0.081296267,0.499283963,0.851895509
+0.709384988,0.14985208,0.186521894
+0.247922963,0.253358356,0.872326832
+0.203028631,0.068652472,0.553487984
+0.292370767,0.925595124,0.401383438
+0.721522222,0.300176493,0.452098604
+0.622021123,0.308001842,0.51395483
+0.601298816,0.268135963,0.584441602
+0.207949629,0.407128704,0.699430418
+0.152216375,0.92660356,0.07049208
+0.997031345,0.789488864,0.194662825
+0.14170589,0.513011324,0.250918681
+0.979853004,0.246273698,0.732371057
+0.441466086,0.428787477,0.680856737
+0.513859379,0.668402062,0.50429415
+0.32103853,0.59436219,0.481843963
+0.466004374,0.019901121,0.225087815
+0.546731744,0.359957666,0.776590304
+0.088133727,0.021028123,0.579299556
+0.172044151,0.237278834,0.567876411
+0.576325796,0.86256513,0.487980769
+0.459957415,0.004052068,0.41344615
+0.72021758,0.906208873,0.049850195
+0.835505139,0.006504875,0.716129577
+0.974913096,0.06350265,0.945758998
+0.538076764,0.931252476,0.05429443
+0.921879308,0.750002283,0.120075272
+0.825790117,0.095295707,0.471769578
+0.667512779,0.726667248,0.68041055
+0.604774928,0.209313615,0.803678279
+0.058678158,0.457882119,0.491090679
+0.46503574,0.647148555,0.063745514
+0.268569925,0.07151649,0.354414339
+0.309997568,0.048651773,0.652050824
+0.852057231,0.800064591,0.378993288
+0.101844132,0.975250128,0.919521375
+0.879950774,0.012524944,0.243977924
+0.71298613,0.410784591,0.766666426
+0.253953963,0.18863912,0.353408633
+0.859540187,0.786140568,0.50468592
+0.885165537,0.182373738,0.365436093
+0.919226953,0.132590959,0.305319302
+0.794222067,0.325843691,0.81503301
+0.360472386,0.828503699,0.992751302
+0.568328182,0.596642015,0.166689456
+0.495797608,0.390533497,0.466894225
+0.497383703,0.057721092,0.136501948
+0.18770586,0.924785691,0.325442341
+0.693138587,0.351786889,0.499636742
+0.898980429,0.759285754,0.006488642
+0.203362481,0.362873482,0.576750046
+0.178651329,0.720602676,0.881219809
+0.176525065,0.325805008,0.029694687
+0.280908733,0.527522643,0.545345238
+0.370750152,0.138599939,0.044930538
+0.675097184,0.14761356,0.378589866
+0.735023127,0.793326142,0.751658301
+0.589712544,0.569527756,0.006401988
+0.528971516,0.297342992,0.454367414
+0.691477287,0.799565463,0.424110191
+0.261622015,0.848996059,0.848455301
+0.401014342,0.684428894,0.631646442
+0.16646465,0.252704215,0.907185556
+0.100875707,0.566947803,0.906685851
+0.434813596,0.104021401,0.167032575
+0.525475323,0.508926771,0.950312938
+0.159164103,0.298161029,0.813651341
+0.688364345,0.371765734,0.533450516
+0.712069354,0.849924822,0.351626269
+0.322500041,0.141195673,0.954104724
+0.146595062,0.93264431,0.190821916
+0.71991816,0.904994255,0.945180752
+0.025505056,0.369278227,0.225567491
+0.450884297,0.163076541,0.835655337
+0.666130325,0.52707414,0.82767262
+0.747584223,0.050899988,0.253442115
+0.525074918,0.930938393,0.27765909
+0.940041036,0.129750051,0.169526547
+0.976328221,0.406056506,0.156213454
+0.413206486,0.217043404,0.425652131
+0.108491931,0.963192763,0.498477601
+0.958709036,0.585116585,0.507265441
+0.048428848,0.713725414,0.728970388
+0.587791364,0.896305822,0.279922122
+0.086686919,0.740059232,0.914875869
+0.422027713,0.086096483,0.419750985
+0.767716034,0.871663257,0.103971292
+0.549835043,0.371430165,0.801009346
+0.557408598,0.341725364,0.279171927
+0.071240148,0.765613908,0.173767574
+0.713230298,0.779720404,0.253165546
+0.572322236,0.663937254,0.045664107
+0.428432377,0.161070991,0.891029544
+0.818292324,0.971164957,0.271696059
+0.269446053,0.962766931,0.051526478
+0.515277086,0.74833971,0.351491465
+0.796419252,0.556278732,0.361314209
+0.801556269,0.987424165,0.117197305
+0.782772261,0.05866778,0.982749779
+0.21806961,0.609256862,0.798461899
+0.699205142,0.038761394,0.271238908
+0.534754129,0.27476979,0.163606178
+0.003518131,0.437675965,0.388250875
+0.619198012,0.090710318,0.566559914
+0.178576562,0.885793567,0.022734794
+0.578539981,0.281190469,0.008260142
+0.177713211,0.393560621,0.052236228
+0.846158221,0.357695748,0.875170299
+0.127568308,0.638314871,0.946658268
+0.767138325,0.621405933,0.564104167
+0.798451074,0.40443786,0.599831193
+0.616223487,0.665752297,0.971012789
+0.267441096,0.388352985,0.430687937
+0.923867358,0.654582643,0.464037122
+0.492137227,0.706258913,0.378247168
+0.536642887,0.555595419,0.104998227
+0.992969717,0.688862613,0.896407883
+0.454975157,0.851727744,0.144297419
+0.317976254,0.620102227,0.416793119
+0.440632343,0.535615753,0.913356284
+0.791010869,0.962116708,0.627040144
+0.926826073,0.382456611,0.465806072
+0.568904993,0.514101455,0.724489494
+0.895517901,0.391005356,0.347893715
+0.289875186,0.830981849,0.92116788
+0.95185048,0.996829271,0.970163256
+0.079055453,0.999386589,0.528208258
+0.926932102,0.147799896,0.417138668
+0.244651465,0.832349744,0.221104338
+0.179560876,0.149581841,0.97827318
+0.869778794,0.116050413,0.930858226
+0.681347988,0.700100934,0.003010153
+0.688804753,0.087819887,0.217246073
+0.054919581,0.536206628,0.011960678
+0.640496257,0.193125181,0.654595034
+0.879605152,0.152112809,0.50946439
+0.336877078,0.352944356,0.032651908
+0.578287892,0.410740871,0.424981809
+0.655610763,0.370342392,0.021605292
+0.184746216,0.078627828,0.615262076
+0.335250916,0.744164606,0.7834867
+0.086006226,0.796624922,0.100735176
+0.278674471,0.483655368,0.117132599
+0.994681992,0.915583798,0.682419845
+0.077364925,0.488968443,0.762836001
+0.460939585,0.226843633,0.262301782
+0.998409563,0.464398025,0.918229672
+0.221191504,0.605272697,0.236818579
+0.305532514,0.107986913,0.285771959
+0.429457882,0.021852143,0.417044654
+0.4398254,0.904405397,0.587007492
+0.472361927,0.615492219,0.311474339
+0.4847793,0.830454499,0.692963217
+0.525054945,0.760690911,0.176296268
+0.117729529,0.425190139,0.763022992
+0.435815483,0.901034288,0.68353143
+0.310722347,0.711502874,0.050054312
+0.692557474,0.756865138,0.823601442
+0.748561397,0.302607431,0.404056776
+0.370478834,0.749199053,0.220199408
+0.686929375,0.172808164,0.22046762
+0.037511035,0.299597568,0.543432459
+0.513900441,0.892613907,0.740051648
+0.389543522,0.806516669,0.891439062
+0.053758187,0.367104684,0.356060944
+0.450039969,0.18662041,0.022226949
+0.481122219,0.376490604,0.455652341
+0.97009151,0.252002631,0.121449418
+0.322174741,0.359645571,0.785282495
+0.904310053,0.730301338,0.994210513
+0.450101531,0.92830086,0.086584177
+0.456948101,0.90305291,0.216589856
+0.430158828,0.574385535,0.812451667
+0.958800913,0.229029132,0.004822368
+0.641856333,0.757170989,0.097059421
+0.442276634,0.278413528,0.877655305
+0.036927777,0.425286999,0.92305997
+0.996003678,0.902465847,0.265142606
+0.306340939,0.260744837,0.528606261
+0.098272048,0.162476078,0.354882218
+0.658054373,0.890822429,0.9000076
+0.087284546,0.695167739,0.026293663
+0.667310433,0.902843368,0.248946207
+0.451887926,0.995052067,0.181712955
+0.721298527,0.006611482,0.727102995
+0.180137144,0.38951174,0.678305837
+0.420761331,0.419860176,0.010656383
+0.788488075,0.180473318,0.708019695
+0.662265015,0.757397169,0.348937464
+0.22732873,0.663301685,0.39923678
+0.716892599,0.552981067,0.089832495
+0.177215605,0.465175647,0.887666589
+0.4010009,0.597937203,0.09497585
+0.259096154,0.591668012,0.145793124
+0.7855796,0.541345166,0.383678057
+0.201753532,0.613603748,0.879697044
+0.825321851,0.452349759,0.192581377
+0.171266337,0.782789247,0.848185787
+0.989170718,0.575391852,0.643933271
+0.224216552,0.128615538,0.261286445
+0.355440689,0.629457955,0.902600249
+0.72784327,0.282293864,0.605943451
+0.210467186,0.748327916,0.269725684
+0.703080367,0.411052005,0.029450281
+0.611720264,0.653108765,0.115754888
+0.625714261,0.426502244,0.253625516
+0.080879639,0.231561531,0.000776511
+0.580765049,0.214103901,0.655333535
+0.411287343,0.079075761,0.794277642
+0.710073858,0.646863988,0.71074505
+0.335569397,0.900645276,0.683474835
+0.967747154,0.579773932,0.534024604
+0.766717973,0.582199309,0.533102234
+0.383468743,0.426721157,0.027251934
+0.490400205,0.117276739,0.92366954
+0.526437331,0.70107653,0.671085752
+0.889392656,0.764668251,0.594183178
+0.638642815,0.578480214,0.97861599
+0.87668719,0.16462794,0.216101311
+0.42672965,0.578827138,0.263549989
+0.811170473,0.093966938,0.225951223
+0.099089206,0.263591386,0.882393744
+0.38399777,0.327948679,0.494541301
+0.183583616,0.008025085,0.345896483
+0.584960878,0.5469813,0.968535684
+0.361345034,0.854037953,0.527327995
+0.984905322,0.997741532,0.876521812
+0.074758264,0.39928899,0.847634791
+0.78330323,0.392062416,0.024783838
+0.467728166,0.712167022,0.024533141
+0.587280899,0.398576247,0.573112113
+0.964829971,0.025982741,0.969019811
+0.9497508,0.659436309,0.204878206
+0.657359903,0.347373583,0.193308068
+0.186434557,0.521059421,0.070439079
+0.870109867,0.062761012,0.710077454
+0.217962469,0.288311322,0.190708548
+0.955539243,0.022311215,0.71590241
+0.625665814,0.76136552,0.988044588
+0.597252746,0.710748192,0.314068902
+0.516054372,0.327282916,0.54307302
+0.271367679,0.738701611,0.304169987
+0.933804469,0.580994455,0.210076964
+0.127919156,0.599299518,0.585857959
+0.676065679,0.558987708,0.958866142
+0.316141871,0.460898294,0.141769324
+0.471335921,0.089770919,0.358606362
+0.623875078,0.120949677,0.031070096
+0.279561054,0.756633154,0.523821594
+0.367638452,0.041473293,0.205100917
+0.194748444,0.554149226,0.891998106
+0.41189445,0.060780804,0.739908884
+0.463521747,0.175865472,0.535693142
+0.945971006,0.966028962,0.856940254
+0.183047078,0.337562524,0.181769865
+0.594627884,0.198176957,0.150059332
+0.843270928,0.530723522,0.928016742
+0.223830394,0.396224789,0.671524797
+0.660767374,0.651553136,0.816830801
+0.435601302,0.067504838,0.286367496
+0.118647364,0.597413606,0.736034901
+0.130876628,0.718657894,0.132667782
+0.512036173,0.807939768,0.573980493
+0.651567779,0.146952948,0.239972065
+0.288725439,0.224872447,0.043641949
+0.13707238,0.381109232,0.022199238
+0.754226814,0.167426623,0.961971718
+0.951586322,0.053557001,0.223348551
+0.618926676,0.885546611,0.123622882
+0.790423531,0.278666859,0.501354777
+0.038612914,0.868235102,0.288826116
+0.488859959,0.478054033,0.700027159
+0.862804894,0.011591559,0.750381881
+0.994070885,0.954113216,0.968886216
+0.452966461,0.985185262,0.402556559
+0.163204173,0.188199516,0.352205827
+0.15850908,0.505182571,0.583169832
+0.135779826,0.409087768,0.238200196
+0.643385144,0.86154063,0.14538336
+0.50233965,0.544662955,0.992305772
+0.208435385,0.031950832,0.061424365
+0.866478253,0.391456921,0.511463088
+0.4937369,0.216683838,0.68183869
+0.635277683,0.264963125,0.828569956
+0.57036797,0.199089208,0.947261901
+0.622849636,0.554898686,0.300444481
+0.148150252,0.793195105,0.95852649
+0.118643776,0.375521816,0.127817104
+0.758672306,0.928120507,0.147843091
+0.988902496,0.305378105,0.027460368
+0.101391422,0.187140233,0.666743757
+0.742622491,0.913697728,0.538923383
+0.093250323,0.083342814,0.253041857
+0.769590781,0.9991462,0.438612548
+0.729371479,0.304770086,0.732577389
+0.309854988,0.231328158,0.907015378
+0.357043464,0.291981607,0.210471606
+0.310867898,0.310831132,0.021305479
+0.099716251,0.743995352,0.892636908
+0.41508308,0.015438634,0.257251295
+0.53442204,0.552940574,0.911759333
+0.066875817,0.519643391,0.683239895
+0.960228558,0.637860456,0.564663828
+0.166667197,0.282113595,0.909573438
+0.400063729,0.629753113,0.314970443
+0.708945745,0.167807931,0.868195558
+0.371947838,0.749772529,0.913374887
+0.364252703,0.719347038,0.968988396
+0.565947998,0.47317603,0.848594323
+0.963005103,0.86347636,0.213376655
+0.010974265,0.115488107,0.918644935
+0.579274525,0.748172658,0.195517101
+0.054742886,0.089561473,0.35514667
+0.352904397,0.177453817,0.485671073
+0.86540568,0.455589491,0.325840682
+0.826269285,0.742045207,0.836774969
+0.075485913,0.446267336,0.134777488
+0.123130773,0.10695964,0.319080831
+0.353341713,0.250920125,0.94582804
+0.934151416,0.641155987,0.332526901
+0.183094596,0.975798892,0.512697523
+0.931523642,0.525759501,0.067066893
+0.171012136,0.581683693,0.603794825
+0.489763176,0.561915728,0.886623062
+0.427818728,0.227974683,0.462025302
+0.059325421,0.726266371,0.692412984
+0.770271664,0.743519141,0.117959307
+0.107862896,0.552555172,0.592259145
+0.445007388,0.046308389,0.69499137
+0.056486616,0.370154602,0.498507879
+0.347798483,0.541312622,0.44955603
+0.01637411,0.777726654,0.346640124
+0.918778501,0.247274577,0.931656904
+0.468325578,0.552066653,0.233304727
+0.558842714,0.30110019,0.237582706
+0.520406065,0.396600845,0.627623904
+0.42717615,0.55961213,0.312743984
+0.043819454,0.060632818,0.168267929
+0.151405047,0.276450913,0.385322692
+0.864539894,0.203199707,0.865006307
+0.866179018,0.649792248,0.369625823
+0.566181508,0.155001949,0.751738414
+0.022193506,0.262524266,0.378478591
+0.835870282,0.436869514,0.439857307
+0.54507765,0.825712044,0.425012638
+0.180124959,0.284189803,0.059324375
+0.91303517,0.659662103,0.021990781
+0.068890512,0.857174742,0.245915138
+0.146299591,0.2282098,0.992357695
+0.279495766,0.087424865,0.532747766
+0.095737503,0.107245868,0.190786801
+0.276947216,0.537071712,0.654100689
+0.010738646,0.40673838,0.479608479
+0.420307684,0.947352567,0.178277524
+0.108124774,0.127227634,0.278086371
+0.18958629,0.587262704,0.69187928
+0.814773727,0.220263054,0.007250506
+0.948149379,0.572617808,0.939774741
+0.150492895,0.970045889,0.979230909
+0.997567108,0.897085006,0.573132383
+0.039773611,0.517659257,0.317936584
+0.915778891,0.598912752,0.541405962
+0.081857212,0.994515385,0.261260636


Property changes on: mlpack/trunk/src/mlpack/tests/data/test_data_3_1000.csv
___________________________________________________________________
Added: svn:executable
   + *

Added: mlpack/trunk/src/mlpack/tests/data/trainSet.csv
===================================================================
--- mlpack/trunk/src/mlpack/tests/data/trainSet.csv	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/data/trainSet.csv	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,31 @@
+3,3,3,3,0
+3,4,4,3,0
+3,4,4,3,0
+3,3,4,3,0
+3,6,4,3,0
+2,4,4,3,0
+2,4,4,1,0
+3,3,3,2,0
+3,4,4,2,0
+3,4,4,2,0
+3,3,4,2,0
+3,6,4,2,0
+2,4,4,2,0
+2,4,4,3,0
+2,4,1,2,0
+4,4,4,2,0
+9,3,3,3,1
+9,4,4,3,1
+9,4,4,3,1
+9,3,4,3,1
+9,6,4,3,1
+9,4,4,3,1
+9,4,4,1,1
+9,3,3,2,1
+8,4,4,2,1
+8,4,4,2,1
+8,3,4,2,1
+8,6,4,2,1
+7,8,4,3,1
+6,9,1,2,1
+8,5,4,2,1

Added: mlpack/trunk/src/mlpack/tests/emst_test.cc
===================================================================
--- mlpack/trunk/src/mlpack/tests/emst_test.cc	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/emst_test.cc	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,136 @@
+/**
+ * @file emst_test.cc
+ *
+ * Test file for EMST methods
+ */
+#include <mlpack/core.h>
+#include <mlpack/methods/emst/dtb.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+using namespace mlpack::emst;
+
+BOOST_AUTO_TEST_SUITE(EmstTest);
+  /***
+   * Simple emst test with small, synthetic dataset.  This is an
+   * exhaustive test, which checks that each method for performing the calculation
+   * (dual-tree, single-tree, naive) produces the correct results.  The dataset is
+   * in one dimension for simplicity -- the correct functionality of distance
+   * functions is not tested here.
+   */
+  BOOST_AUTO_TEST_CASE(exhaustive_synthetic_test) {
+    // Set up our data.
+    arma::mat data(1, 11);
+    data[0] = 0.05; // Row addressing is unnecessary (they are all 0).
+    data[1] = 0.37;
+    data[2] = 0.15;
+    data[3] = 1.25;
+    data[4] = 5.05;
+    data[5] = -0.22;
+    data[6] = -2.00;
+    data[7] = -1.30;
+    data[8] = 0.45;
+    data[9] = 0.91;
+    data[10] = 1.00;
+
+
+    // Now perform the actual calculation.
+    arma::mat results;
+
+
+    DualTreeBoruvka dtb;
+    dtb.Init(data);
+    dtb.ComputeMST(results);
+
+    // Now the exhaustive check for correctness.
+
+    BOOST_REQUIRE(results(0, 0) == 1);
+    BOOST_REQUIRE(results(0, 1) == 8);
+    BOOST_REQUIRE_CLOSE(results(0, 2), 0.08, 1e-5);
+
+    BOOST_REQUIRE(results(1, 0) == 9);
+    BOOST_REQUIRE(results(1, 1) == 10);
+    BOOST_REQUIRE_CLOSE(results(1, 2), 0.09, 1e-5);
+
+    BOOST_REQUIRE(results(2, 0) == 0);
+    BOOST_REQUIRE(results(2, 1) == 2);
+    BOOST_REQUIRE_CLOSE(results(2, 2), 0.1, 1e-5);
+
+    BOOST_REQUIRE(results(3, 0) == 1);
+    BOOST_REQUIRE(results(3, 1) == 2);
+    BOOST_REQUIRE_CLOSE(results(3, 2), 0.22, 1e-5);
+
+    BOOST_REQUIRE(results(4, 0) == 3);
+    BOOST_REQUIRE(results(4, 1) == 10);
+    BOOST_REQUIRE_CLOSE(results(4, 2), 0.25, 1e-5);
+
+    BOOST_REQUIRE(results(5, 0) == 0);
+    BOOST_REQUIRE(results(5, 1) == 5);
+    BOOST_REQUIRE_CLOSE(results(5, 2), 0.27, 1e-5);
+
+    BOOST_REQUIRE(results(6, 0) == 8);
+    BOOST_REQUIRE(results(6, 1) == 9);
+    BOOST_REQUIRE_CLOSE(results(6, 2), 0.46, 1e-5);
+
+    BOOST_REQUIRE(results(7, 0) == 6);
+    BOOST_REQUIRE(results(7, 1) == 7);
+    BOOST_REQUIRE_CLOSE(results(7, 2), 0.7, 1e-5);
+
+    BOOST_REQUIRE(results(8, 0) == 5);
+    BOOST_REQUIRE(results(8, 1) == 7);
+    BOOST_REQUIRE_CLOSE(results(8, 2), 1.08, 1e-5);
+
+    BOOST_REQUIRE(results(9, 0) == 3);
+    BOOST_REQUIRE(results(9, 1) == 4);
+    BOOST_REQUIRE_CLOSE(results(9, 2), 3.8, 1e-5);
+
+
+  }
+
+  /**
+   * Test the dual tree method against the naive computation.
+   *
+   * Errors are produced if the results are not identical.
+   */
+  BOOST_AUTO_TEST_CASE(dual_tree_vs_naive) {
+    arma::mat input_data;
+
+    // Hard-coded filename: bad!
+    // Code duplication: also bad!
+    if (!input_data.load("test_data_3_1000.csv", arma::auto_detect, false,
+        true))
+      BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
+
+    // Set up matrices to work with (may not be necessary with no ALIAS_MATRIX?).
+    arma::mat dual_data = arma::trans(input_data);
+    arma::mat naive_data = arma::trans(input_data);
+
+    // Reset parameters from last test.
+    DualTreeBoruvka dtb;
+    dtb.Init(dual_data);
+
+    arma::mat dual_results;
+    dtb.ComputeMST(dual_results);
+
+    // Set naive mode.
+    CLI::GetParam<bool>("naive/do_naive") = true;
+
+    DualTreeBoruvka dtb_naive;
+    dtb_naive.Init(naive_data);
+
+    arma::mat naive_results;
+    dtb_naive.ComputeMST(naive_results);
+
+    BOOST_REQUIRE(dual_results.n_cols == naive_results.n_cols);
+    BOOST_REQUIRE(dual_results.n_rows == naive_results.n_rows);
+
+    for (size_t i = 0; i < dual_results.n_rows; i++) {
+
+      BOOST_REQUIRE(dual_results(i,0) == naive_results(i,0));
+      BOOST_REQUIRE(dual_results(i,1) == naive_results(i,1));
+      BOOST_REQUIRE_CLOSE(dual_results(i,2), naive_results(i,2), 1e-5);
+
+    }
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/infomax_ica_test.cc
===================================================================
--- mlpack/trunk/src/mlpack/tests/infomax_ica_test.cc	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/infomax_ica_test.cc	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,66 @@
+/**
+ * @file main.cc
+ *
+ * Test driver for our infomax ICA method.
+ */
+#include <mlpack/core.h>
+
+#include <mlpack/methods/infomax_ica/infomax_ica.h>
+
+using namespace mlpack;
+using namespace infomax_ica;
+
+#include <boost/test/unit_test.hpp>
+
+void testSQRTM(InfomaxICA& icab_, arma::mat& m) {
+  icab_.sqrtm(m);
+}
+
+BOOST_AUTO_TEST_SUITE(InfomaxIcaTest);
+
+  BOOST_AUTO_TEST_CASE(SqrtM) {
+    arma::mat testdatab_;
+    double lambdab_ = 0.001;
+    int bb_ = 5;
+    double epsilonb_ = 0.001;
+
+    data::Load("fake.csv", testdatab_);
+
+    InfomaxICA icab_(lambdab_, bb_, epsilonb_);
+
+    arma::mat intermediateb = icab_.sampleCovariance(testdatab_);
+    testSQRTM(icab_, intermediateb);
+  }
+
+  BOOST_AUTO_TEST_CASE(TestCov) {
+    arma::mat testdata_;
+
+    double lambda_ = 0.001;
+    int b_ = 5;
+    double epsilon_ = 0.001;
+
+    // load some test data that has been verified using the matlab
+    // implementation of infomax
+    data::Load("fake.csv", testdata_);
+
+    InfomaxICA ica_(lambda_, b_, epsilon_);
+    ica_.sampleCovariance(testdata_);
+  }
+
+  BOOST_AUTO_TEST_CASE(TestICA) {
+    arma::mat testdata_;
+    double lambda_ = 0.001;
+    int b_ = 5;
+    double epsilon_ = 0.001;
+
+    // load some test data that has been verified using the matlab
+    // implementation of infomax
+    data::Load("fake.csv", testdata_);
+
+    InfomaxICA ica_(lambda_, b_, epsilon_);
+    arma::mat unmixing;
+    ica_.applyICA(testdata_);
+    ica_.getUnmixing(unmixing);
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/kernel_pca_test.cc
===================================================================
--- mlpack/trunk/src/mlpack/tests/kernel_pca_test.cc	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/kernel_pca_test.cc	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,80 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  kernel_pca_test.cc
+ *
+ *    Description:
+ *
+ *        Version:  1.0
+ *        Created:  01/09/2008 11:26:48 AM EST
+ *       Revision:  none
+ *       Compiler:  gcc
+ *
+ *         Author:  Nikolaos Vasiloglou (NV), nvasil at ieee.org
+ *        Company:  Georgia Tech Fastlab-ESP Lab
+ *
+ * =====================================================================================
+ */
+#include <mlpack/methods/kernel_pca/kernel_pca.h>
+#include <vector>
+#include <mlpack/core.h>
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_SUITE(KernelPCATest);
+
+  BOOST_AUTO_TEST_CASE(TestGeneralKernelPCA) {
+     arma::mat eigen_vectors;
+     arma::vec eigen_values;
+
+     KernelPCA engine_;
+     KernelPCA::GaussianKernel kernel_;
+     engine_.Init("test_data_3_1000.csv", 5, 20);
+     engine_.ComputeNeighborhoods();
+     double bandwidth;
+     engine_.EstimateBandwidth(&bandwidth);
+     kernel_.set(bandwidth);
+     engine_.LoadAffinityMatrix();
+     engine_.ComputeGeneralKernelPCA(kernel_, 15,
+                                      &eigen_vectors,
+                                      &eigen_values);
+     engine_.SaveToTextFile("results", eigen_vectors, eigen_values);
+    }
+
+  BOOST_AUTO_TEST_CASE(TestLLE) {
+      arma::mat eigen_vectors;
+      arma::vec eigen_values;
+      KernelPCA engine_;
+      KernelPCA::GaussianKernel kernel_;
+      engine_.Init("test_data_3_1000.csv", 5, 20);
+      engine_.ComputeNeighborhoods();
+      engine_.LoadAffinityMatrix();
+      engine_.ComputeLLE(2,
+                           &eigen_vectors,
+                           &eigen_values);
+      engine_.SaveToTextFile("results", eigen_vectors, eigen_values);
+  }
+
+  BOOST_AUTO_TEST_CASE (TestSpectralRegression) {
+      KernelPCA engine_;
+      KernelPCA::GaussianKernel kernel_;
+      engine_.Init("test_data_3_1000.csv", 5, 20);
+      engine_.ComputeNeighborhoods();
+      double bandwidth;
+      engine_.EstimateBandwidth(&bandwidth);
+      kernel_.set(bandwidth);
+      engine_.LoadAffinityMatrix();
+      std::map<size_t, size_t> data_label;
+      for(size_t i=0; i<20; i++) {
+        data_label[math::RandInt(0, engine_->data_.n_cols())] =
+          math::RandInt(0 ,2);
+      }
+      arma::mat embedded_coordinates;
+      arma::vec eigenvalues;
+      engine_.ComputeSpectralRegression(kernel_,
+                                         data_label,
+                                         &embedded_coordinates,
+                                         &eigenvalues);
+      engine_.SaveToTextFile("results", embedded_coordinates, eigenvalues);
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/kernel_test.cc
===================================================================
--- mlpack/trunk/src/mlpack/tests/kernel_test.cc	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/kernel_test.cc	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,228 @@
+/***
+ * @file kernel_test.cc
+ * @author Ryan Curtin
+ *
+ * Tests for the various kernel classes.
+ */
+
+#include <mlpack/core/kernels/lmetric.hpp>
+#include <mlpack/core/kernels/mahalanobis_distance.hpp>
+#include <mlpack/core/kernels/cosine_distance.hpp>
+#include <mlpack/core/kernels/gaussian_kernel.hpp>
+#include <mlpack/core/kernels/linear_kernel.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+using namespace mlpack::kernel;
+
+BOOST_AUTO_TEST_SUITE(KernelTest);
+
+  /***
+   * Basic test of the Manhattan distance.
+   */
+  BOOST_AUTO_TEST_CASE(manhattan_distance) {
+    // A couple quick tests.
+    arma::vec a = "1.0 3.0 4.0";
+    arma::vec b = "3.0 3.0 5.0";
+
+    BOOST_REQUIRE_CLOSE(ManhattanDistance::Evaluate(a, b), 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(ManhattanDistance::Evaluate(b, a), 3.0, 1e-5);
+
+    // Check also for when the root is taken (should be the same).
+    BOOST_REQUIRE_CLOSE((LMetric<1, true>::Evaluate(a, b)), 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE((LMetric<1, true>::Evaluate(b, a)), 3.0, 1e-5);
+  }
+
+  /***
+   * Basic test of squared Euclidean distance.
+   */
+  BOOST_AUTO_TEST_CASE(squared_euclidean_distance) {
+    // Sample 2-dimensional vectors.
+    arma::vec a = "1.0  2.0";
+    arma::vec b = "0.0 -2.0";
+
+    BOOST_REQUIRE_CLOSE(SquaredEuclideanDistance::Evaluate(a, b), 17.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(SquaredEuclideanDistance::Evaluate(b, a), 17.0, 1e-5);
+  }
+
+  /***
+   * Basic test of Euclidean distance.
+   */
+  BOOST_AUTO_TEST_CASE(euclidean_distance) {
+    arma::vec a = "1.0 3.0 5.0 7.0";
+    arma::vec b = "4.0 0.0 2.0 0.0";
+
+    BOOST_REQUIRE_CLOSE(EuclideanDistance::Evaluate(a, b), sqrt(76.0), 1e-5);
+    BOOST_REQUIRE_CLOSE(EuclideanDistance::Evaluate(b, a), sqrt(76.0), 1e-5);
+  }
+
+  /***
+   * Arbitrary test case for coverage.
+   */
+  BOOST_AUTO_TEST_CASE(arbitrary_case) {
+    arma::vec a = "3.0 5.0 6.0 7.0";
+    arma::vec b = "1.0 2.0 1.0 0.0";
+
+    BOOST_REQUIRE_CLOSE(LMetric<3>::Evaluate(a, b), 503.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(LMetric<3>::Evaluate(b, a), 503.0, 1e-5);
+
+    BOOST_REQUIRE_CLOSE((LMetric<3, true>::Evaluate(a, b)), 7.95284762, 1e-5);
+    BOOST_REQUIRE_CLOSE((LMetric<3, true>::Evaluate(b, a)), 7.95284762, 1e-5);
+  }
+
+  /***
+   * Make sure two vectors of all zeros return zero distance, for a few different
+   * powers.
+   */
+  BOOST_AUTO_TEST_CASE(lmetric_zeros) {
+    arma::vec a(250);
+    a.fill(0.0);
+
+    // We cannot use a loop because compilers seem to be unable to unroll the loop
+    // and realize the variable actually is knowable at compile-time.
+    BOOST_REQUIRE((LMetric<1, false>::Evaluate(a, a)) == 0);
+    BOOST_REQUIRE((LMetric<1, true>::Evaluate(a, a)) == 0);
+    BOOST_REQUIRE((LMetric<2, false>::Evaluate(a, a)) == 0);
+    BOOST_REQUIRE((LMetric<2, true>::Evaluate(a, a)) == 0);
+    BOOST_REQUIRE((LMetric<3, false>::Evaluate(a, a)) == 0);
+    BOOST_REQUIRE((LMetric<3, true>::Evaluate(a, a)) == 0);
+    BOOST_REQUIRE((LMetric<4, false>::Evaluate(a, a)) == 0);
+    BOOST_REQUIRE((LMetric<4, true>::Evaluate(a, a)) == 0);
+    BOOST_REQUIRE((LMetric<5, false>::Evaluate(a, a)) == 0);
+    BOOST_REQUIRE((LMetric<5, true>::Evaluate(a, a)) == 0);
+  }
+
+  /***
+   * Simple test of Mahalanobis distance with unset covariance matrix.
+   */
+  BOOST_AUTO_TEST_CASE(md_unset_covariance) {
+    MahalanobisDistance<false> md;
+    arma::vec a = "1.0 2.0 2.0 3.0";
+    arma::vec b = "0.0 0.0 1.0 3.0";
+
+    BOOST_REQUIRE_CLOSE(md.Evaluate(a, b), 6.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(md.Evaluate(b, a), 6.0, 1e-5);
+  }
+
+  /***
+   * Simple test of Mahalanobis distance with unset covariance matrix and
+   * t_take_root set to true.
+   */
+  BOOST_AUTO_TEST_CASE(md_root_unset_covariance) {
+    MahalanobisDistance<true> md;
+    arma::vec a = "1.0 2.0 2.5 5.0";
+    arma::vec b = "0.0 2.0 0.5 8.0";
+
+    BOOST_REQUIRE_CLOSE(md.Evaluate(a, b), sqrt(14.0), 1e-5);
+    BOOST_REQUIRE_CLOSE(md.Evaluate(b, a), sqrt(14.0), 1e-5);
+  }
+
+  /***
+   * Simple test with diagonal covariance matrix.
+   */
+  BOOST_AUTO_TEST_CASE(md_diagonal_covariance) {
+    arma::mat cov = arma::eye<arma::mat>(5, 5);
+    cov(0, 0) = 2.0;
+    cov(1, 1) = 0.5;
+    cov(2, 2) = 3.0;
+    cov(3, 3) = 1.0;
+    cov(4, 4) = 1.5;
+    MahalanobisDistance<false> md(cov);
+
+    arma::vec a = "1.0 2.0 2.0 4.0 5.0";
+    arma::vec b = "2.0 3.0 1.0 1.0 0.0";
+
+    BOOST_REQUIRE_CLOSE(md.Evaluate(a, b), 52.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(md.Evaluate(b, a), 52.0, 1e-5);
+  }
+
+  /***
+   * More specific case with more difficult covariance matrix.
+   */
+  BOOST_AUTO_TEST_CASE(md_full_covariance) {
+    arma::mat cov = "1.0 2.0 3.0 4.0;"
+                    "0.5 0.6 0.7 0.1;"
+                    "3.4 4.3 5.0 6.1;"
+                    "1.0 2.0 4.0 1.0;";
+    MahalanobisDistance<false> md(cov);
+
+    arma::vec a = "1.0 2.0 2.0 4.0";
+    arma::vec b = "2.0 3.0 1.0 1.0";
+
+    BOOST_REQUIRE_CLOSE(md.Evaluate(a, b), 15.7, 1e-5);
+    BOOST_REQUIRE_CLOSE(md.Evaluate(b, a), 15.7, 1e-5);
+  }
+
+  /***
+   * Simple test case for the cosine distance.
+   */
+  BOOST_AUTO_TEST_CASE(cosine_distance_same_angle) {
+    arma::vec a = "1.0 2.0 3.0";
+    arma::vec b = "2.0 4.0 6.0";
+
+    BOOST_REQUIRE_SMALL(CosineDistance::Evaluate(a, b), 1e-5);
+    BOOST_REQUIRE_SMALL(CosineDistance::Evaluate(b, a), 1e-5);
+  }
+
+  /***
+   * Now let's have them be orthogonal.
+   */
+  BOOST_AUTO_TEST_CASE(cosine_distance_orthogonal) {
+    arma::vec a = "0.0 1.0";
+    arma::vec b = "1.0 0.0";
+
+    BOOST_REQUIRE_CLOSE(CosineDistance::Evaluate(a, b), 1.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(CosineDistance::Evaluate(b, a), 1.0, 1e-5);
+  }
+
+  /***
+   * Some random angle test.
+   */
+  BOOST_AUTO_TEST_CASE(cosine_distance_random_test) {
+    arma::vec a = "0.1 0.2 0.3 0.4 0.5";
+    arma::vec b = "1.2 1.0 0.8 -0.3 -0.5";
+
+    BOOST_REQUIRE_CLOSE(CosineDistance::Evaluate(a, b), 1 - 0.1385349024, 1e-5);
+    BOOST_REQUIRE_CLOSE(CosineDistance::Evaluate(b, a), 1 - 0.1385349024, 1e-5);
+  }
+
+  /***
+   * Linear Kernel test.
+   */
+  BOOST_AUTO_TEST_CASE(linear_kernel) {
+    arma::vec a = ".2 .3 .4 .1";
+    arma::vec b = ".56 .21 .623 .82";
+
+    LinearKernel lk;
+    BOOST_REQUIRE_CLOSE(lk.Evaluate(a,b), .5062, 1e-5);
+    BOOST_REQUIRE_CLOSE(lk.Evaluate(b,a), .5062, 1e-5);
+  }
+
+  /***
+   * Linear Kernel test, orthogonal vectors.
+   */
+  BOOST_AUTO_TEST_CASE(linear_kernel_orthogonal) {
+    arma::vec a = "1 0 0";
+    arma::vec b = "0 0 1";
+
+    LinearKernel lk;
+    BOOST_REQUIRE_SMALL(lk.Evaluate(a,b), 1e-5);
+    BOOST_REQUIRE_SMALL(lk.Evaluate(b,a), 1e-5);
+  }
+
+  BOOST_AUTO_TEST_CASE(gaussian_kernel) {
+    arma::vec a = "1 0 0";
+    arma::vec b = "0 1 0";
+    arma::vec c = "0 0 1";
+
+    GaussianKernel gk(.5);
+    BOOST_REQUIRE_CLOSE(gk.Evaluate(a,b), .018315638888734, 1e-5);
+    BOOST_REQUIRE_CLOSE(gk.Evaluate(b,a), .018315638888734, 1e-5);
+    BOOST_REQUIRE_CLOSE(gk.Evaluate(a,c), .018315638888734, 1e-5);
+    BOOST_REQUIRE_CLOSE(gk.Evaluate(c,a), .018315638888734, 1e-5);
+    BOOST_REQUIRE_CLOSE(gk.Evaluate(b,c), .018315638888734, 1e-5);
+    BOOST_REQUIRE_CLOSE(gk.Evaluate(c,b), .018315638888734, 1e-5);
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/lbfgs_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/lbfgs_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/lbfgs_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,104 @@
+/***
+ * @file lbfgs_test.cc
+ *
+ * Tests the L-BFGS optimizer on a couple test functions.
+ *
+ * @author Ryan Curtin (gth671b at mail.gatech.edu)
+ */
+
+#include <mlpack/core.h>
+#include <mlpack/core/optimizers/lbfgs/lbfgs.hpp>
+#include <mlpack/core/optimizers/lbfgs/test_functions.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack::optimization;
+using namespace mlpack::optimization::test;
+
+BOOST_AUTO_TEST_SUITE(LbfgsTest);
+
+  /***
+   * Tests the L-BFGS optimizer using the Rosenbrock Function.
+   */
+  BOOST_AUTO_TEST_CASE(rosenbrock_function) {
+    RosenbrockFunction f;
+    L_BFGS<RosenbrockFunction> lbfgs(f, 10);
+
+    arma::vec coords = f.GetInitialPoint();
+    if(!lbfgs.Optimize(0, coords))
+      BOOST_FAIL("L-BFGS optimization reported failure.");
+
+    double final_value = f.Evaluate(coords);
+
+    BOOST_REQUIRE_SMALL(final_value, 1e-5);
+    BOOST_REQUIRE_CLOSE(coords[0], 1, 1e-5);
+    BOOST_REQUIRE_CLOSE(coords[1], 1, 1e-5);
+  }
+
+  /***
+   * Tests the L-BFGS optimizer using the Wood Function.
+   */
+  BOOST_AUTO_TEST_CASE(wood_function) {
+    WoodFunction f;
+    L_BFGS<WoodFunction> lbfgs(f, 10);
+
+    arma::vec coords = f.GetInitialPoint();
+    if(!lbfgs.Optimize(0, coords))
+      BOOST_FAIL("L-BFGS optimization reported failure.");
+
+    double final_value = f.Evaluate(coords);
+
+    BOOST_REQUIRE_SMALL(final_value, 1e-5);
+    BOOST_REQUIRE_CLOSE(coords[0], 1, 1e-5);
+    BOOST_REQUIRE_CLOSE(coords[1], 1, 1e-5);
+    BOOST_REQUIRE_CLOSE(coords[2], 1, 1e-5);
+    BOOST_REQUIRE_CLOSE(coords[3], 1, 1e-5);
+  }
+
+  /***
+   * Tests the L-BFGS optimizer using the generalized Rosenbrock function.  This
+   * is actually multiple tests, increasing the dimension by powers of 2, from 4
+   * dimensions to 1024 dimensions.
+   */
+  BOOST_AUTO_TEST_CASE(generalized_rosenbrock_function) {
+    for (int i = 2; i < 10; i++) {
+      // Dimension: powers of 2
+      int dim = std::pow(2, i);
+
+      GeneralizedRosenbrockFunction f(dim);
+      L_BFGS<GeneralizedRosenbrockFunction> lbfgs(f, 20);
+
+      arma::vec coords = f.GetInitialPoint();
+      if(!lbfgs.Optimize(0, coords))
+        BOOST_FAIL("L-BFGS optimization reported failure.");
+
+      double final_value = f.Evaluate(coords);
+
+      // Test the output to make sure it is correct.
+      BOOST_REQUIRE_SMALL(final_value, 1e-5);
+      for (int j = 0; j < dim; j++)
+        BOOST_REQUIRE_CLOSE(coords[j], 1, 1e-5);
+    }
+  };
+
+  /***
+   * Tests the L-BFGS optimizer using the Rosenbrock-Wood combined function.  This
+   * is a test on optimizing a matrix of coordinates.
+   */
+  BOOST_AUTO_TEST_CASE(rosenbrock_wood_function) {
+    RosenbrockWoodFunction f;
+    L_BFGS<RosenbrockWoodFunction> lbfgs(f, 10);
+
+    arma::mat coords = f.GetInitialPoint();
+    if(!lbfgs.Optimize(0, coords))
+      BOOST_FAIL("L-BFGS optimization reported failure.");
+
+    double final_value = f.Evaluate(coords);
+
+    BOOST_REQUIRE_SMALL(final_value, 1e-5);
+    for (int row = 0; row < 4; row++) {
+      BOOST_REQUIRE_CLOSE((coords(row, 0)), 1, 1e-5);
+      BOOST_REQUIRE_CLOSE((coords(row, 1)), 1, 1e-5);
+    }
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/lin_alg_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/lin_alg_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/lin_alg_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,128 @@
+/***
+ * lin_alg_test.cc
+ *
+ * Simple tests for things in the linalg__private namespace.
+ * Partly so I can be sure that my changes are working.
+ * Move to boost unit testing framework at some point.
+ *
+ * @author Ryan Curtin
+ */
+#include <mlpack/core.h>
+
+#include <mlpack/methods/fastica/lin_alg.hpp>
+
+using namespace arma;
+using namespace mlpack;
+using namespace fastica;
+using namespace linalg__private;
+
+#include <boost/test/unit_test.hpp>
+
+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) {
+    mat tmp(5, 5);
+    // [[0  0  0  0  0]
+    //  [1  2  3  4  5]
+    //  [2  4  6  8  10]
+    //  [3  6  9  12 15]
+    //  [4  8  12 16 20]]
+    for (int row = 0; row < 5; row++) {
+      for (int col = 0; col < 5; col++)
+        tmp(row, col) = row * (col + 1);
+    }
+
+    mat tmp_out;
+    Center(tmp, tmp_out);
+
+    // average should be
+    // [[0 3 6 9 12]]'
+    // so result should be
+    // [[ 0  0  0  0  0]
+    //  [-2 -1  0  1  2 ]
+    //  [-4 -2  0  2  4 ]
+    //  [-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);
+      }
+    }
+  }
+
+  BOOST_AUTO_TEST_CASE(TestCenterB) {
+    mat tmp(5, 6);
+    for (int row = 0; row < 5; row++) {
+      for (int col = 0; col < 6; col++)
+        tmp(row, col) = row * (col + 1);
+    }
+
+    mat tmp_out;
+    Center(tmp, tmp_out);
+
+    // average should be
+    // [[0 3.5 7 10.5 14]]'
+    // so result should be
+    // [[ 0    0    0   0   0   0  ]
+    //  [-2.5 -1.5 -0.5 0.5 1.5 2.5]
+    //  [-5   -3   -1   1   3   5  ]
+    //  [-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);
+      }
+    }
+  }
+
+  BOOST_AUTO_TEST_CASE(TestWhitenUsingEig) {
+    // After whitening using eigendecomposition, the covariance of
+    // our matrix will be I (or something very close to that).
+    // We are loading a matrix from an external file... bad choice.
+    mat tmp, tmp_centered, whitened, whitening_matrix;
+
+    data::Load("trainSet.csv", tmp);
+    Center(tmp, tmp_centered);
+    WhitenUsingEig(tmp_centered, whitened, whitening_matrix);
+
+    mat newcov = ccov(whitened);
+    for (int row = 0; row < 5; row++) {
+      for (int col = 0; col < 5; col++) {
+        if (row == col) {
+          // diagonal will be 0 in the case of any zero-valued eigenvalues
+          // (rank-deficient covariance case)
+          if (std::abs(newcov(row, col)) > 1e-10)
+            BOOST_REQUIRE_CLOSE(newcov(row, col), 1.0, 1e-10);
+        } else {
+          BOOST_REQUIRE_SMALL(newcov(row, col), 1e-10);
+        }
+      }
+    }
+  }
+
+  BOOST_AUTO_TEST_CASE(TestOrthogonalize) {
+    // Generate a random matrix; then, orthogonalize it and test if it's
+    // orthogonal.
+    mat tmp, orth;
+    data::Load("fake.csv", tmp);
+    Orthogonalize(tmp, orth);
+
+    // test orthogonality
+    mat test = ccov(orth);
+    double ival = test(0, 0);
+    for (size_t row = 0; row < test.n_rows; row++) {
+      for (size_t col = 0; col < test.n_cols; col++) {
+        if (row == col) {
+          if (std::abs(test(row, col)) > 1e-10)
+            BOOST_REQUIRE_CLOSE(test(row, col), ival, 1e-10);
+        } else {
+          BOOST_REQUIRE_SMALL(test(row, col), 1e-10);
+        }
+      }
+    }
+  }
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/linear_regression_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/linear_regression_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/linear_regression_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,54 @@
+#include <mlpack/core.h>
+#include <mlpack/methods/linear_regression/linear_regression.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_SUITE(LinearRegressonTest);
+
+  /**
+   * Creates two 10x3 random matrices and one 10x1 "results" matrix.
+   * Finds B in y=BX with one matrix, then predicts against the other.
+   */
+  BOOST_AUTO_TEST_CASE(LinearRegressionTest)
+  {
+    // predictors, points are 10x3 matrices
+    arma::mat predictors, points;
+
+    // responses is the "correct" value for each point in predictors, poitns
+    arma::colvec responses;
+
+    // the values we get back when we predict for points
+    arma::rowvec predictions;
+
+    // Initialize randomly
+    predictors.randu(3,10);
+    points.randu(3,10);
+    // add 3 so that we have two clusters of points
+    predictors.cols(0,4) += 3;
+    points.cols(0,4) += 3;
+
+    // Create y
+    responses.zeros(10);
+    // Create a second "class" for the first cluster of points
+    for(size_t i = 0; i < 5; ++i)
+    {
+      responses(i) = 1;
+    }
+    responses += 1; // "classes" are 2,1
+
+    predictions.zeros(responses.n_rows);
+
+    // Initialize and predict
+    mlpack::linear_regression::LinearRegression lr(predictors, responses);
+    lr.predict(predictions, points);
+
+    // Output result and verify we have less than .5 error from "correct" value
+    // for each point
+    std::cout << points << '\n' << predictions << '\n';
+    for(size_t i = 0; i < predictions.n_cols; ++i)
+    {
+      assert( fabs(predictions(i) - responses(i)) < .5);
+    }
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/load_save_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/load_save_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/load_save_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,313 @@
+/**
+ * @file load_save_test.cpp
+ * @author Ryan Curtin
+ *
+ * Tests for data::Load() and data::Save().
+ */
+#include <sstream>
+
+#include <mlpack/core/data/load.hpp>
+#include <mlpack/core/data/save.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+
+BOOST_AUTO_TEST_SUITE(LoadSaveTests);
+
+  /**
+   * Make sure failure occurs when no extension given.
+   */
+  BOOST_AUTO_TEST_CASE(NoExtensionLoad) {
+    arma::mat out;
+    BOOST_REQUIRE(data::Load("noextension", out) == false);
+  }
+
+  /**
+   * Make sure failure occurs when no extension given.
+   */
+  BOOST_AUTO_TEST_CASE(NoExtensionSave) {
+    arma::mat out;
+    BOOST_REQUIRE(data::Save("noextension", out) == false);
+  }
+
+  /**
+   * Make sure load fails if the file does not exist.
+   */
+  BOOST_AUTO_TEST_CASE(NotExistLoad) {
+    arma::mat out;
+    BOOST_REQUIRE(data::Load("nonexistentfile_______________.csv", out) == false);
+  }
+
+  /**
+   * Make sure a CSV is loaded correctly.
+   */
+  BOOST_AUTO_TEST_CASE(LoadCSVTest) {
+    std::fstream f;
+    f.open("test_file.csv", std::fstream::out);
+
+    f << "1, 2, 3, 4" << std::endl;
+    f << "5, 6, 7, 8" << std::endl;
+
+    f.close();
+
+    arma::mat test;
+    BOOST_REQUIRE(data::Load("test_file.csv", test) == true);
+
+    BOOST_REQUIRE_EQUAL(test.n_rows, 4);
+    BOOST_REQUIRE_EQUAL(test.n_cols, 2);
+
+    for (int i = 0; i < 8; i++)
+      BOOST_REQUIRE_CLOSE(test[i], (double) (i + 1), 1e-5);
+
+    // Remove the file.
+    remove("test_file.csv");
+  }
+
+  /**
+   * Make sure a CSV is saved correctly.
+   */
+  BOOST_AUTO_TEST_CASE(SaveCSVTest) {
+    arma::mat test = "1 5;"
+                     "2 6;"
+                     "3 7;"
+                     "4 8;";
+
+    BOOST_REQUIRE(data::Save("test_file.csv", test) == true);
+
+    // Load it in and make sure it is the same.
+    BOOST_REQUIRE(data::Load("test_file.csv", test) == true);
+
+    BOOST_REQUIRE_EQUAL(test.n_rows, 4);
+    BOOST_REQUIRE_EQUAL(test.n_cols, 2);
+
+    for (int i = 0; i < 8; i++)
+      BOOST_REQUIRE_CLOSE(test[i], (double) (i + 1), 1e-5);
+
+    // Remove the file.
+    remove("test_file.csv");
+  }
+
+  /**
+   * Make sure arma_ascii is loaded correctly.
+   */
+  BOOST_AUTO_TEST_CASE(LoadArmaASCIITest) {
+    arma::mat test = "1 5;"
+                     "2 6;"
+                     "3 7;"
+                     "4 8;";
+
+    arma::mat testTrans = trans(test);
+    BOOST_REQUIRE(testTrans.save("test_file.txt", arma::arma_ascii));
+
+    BOOST_REQUIRE(data::Load("test_file.txt", test) == true);
+
+    BOOST_REQUIRE_EQUAL(test.n_rows, 4);
+    BOOST_REQUIRE_EQUAL(test.n_cols, 2);
+
+    for (int i = 0; i < 8; i++)
+      BOOST_REQUIRE_CLOSE(test[i], (double) (i + 1), 1e-5);
+
+    // Remove the file.
+    remove("test_file.txt");
+  }
+
+  /**
+   * Make sure a CSV is saved correctly.
+   */
+  BOOST_AUTO_TEST_CASE(SaveArmaASCIITest) {
+    arma::mat test = "1 5;"
+                     "2 6;"
+                     "3 7;"
+                     "4 8;";
+
+    BOOST_REQUIRE(data::Save("test_file.txt", test) == true);
+
+    // Load it in and make sure it is the same.
+    BOOST_REQUIRE(data::Load("test_file.txt", test) == true);
+
+    BOOST_REQUIRE_EQUAL(test.n_rows, 4);
+    BOOST_REQUIRE_EQUAL(test.n_cols, 2);
+
+    for (int i = 0; i < 8; i++)
+      BOOST_REQUIRE_CLOSE(test[i], (double) (i + 1), 1e-5);
+
+    // Remove the file.
+    remove("test_file.txt");
+  }
+
+  /**
+   * Make sure raw_ascii is loaded correctly.
+   */
+  BOOST_AUTO_TEST_CASE(LoadRawASCIITest) {
+    std::fstream f;
+    f.open("test_file.txt", std::fstream::out);
+
+    f << "1 2 3 4" << std::endl;
+    f << "5 6 7 8" << std::endl;
+
+    f.close();
+
+    arma::mat test;
+    BOOST_REQUIRE(data::Load("test_file.txt", test) == true);
+
+    BOOST_REQUIRE_EQUAL(test.n_rows, 4);
+    BOOST_REQUIRE_EQUAL(test.n_cols, 2);
+
+    for (int i = 0; i < 8; i++)
+      BOOST_REQUIRE_CLOSE(test[i], (double) (i + 1), 1e-5);
+
+    // Remove the file.
+    remove("test_file.txt");
+  }
+
+  /**
+   * Make sure CSV is loaded correctly as .txt.
+   */
+  BOOST_AUTO_TEST_CASE(LoadCSVTxtTest) {
+    std::fstream f;
+    f.open("test_file.txt", std::fstream::out);
+
+    f << "1, 2, 3, 4" << std::endl;
+    f << "5, 6, 7, 8" << std::endl;
+
+    f.close();
+
+    arma::mat test;
+    BOOST_REQUIRE(data::Load("test_file.txt", test) == true);
+
+    BOOST_REQUIRE_EQUAL(test.n_rows, 4);
+    BOOST_REQUIRE_EQUAL(test.n_cols, 2);
+
+    for (int i = 0; i < 8; i++)
+      BOOST_REQUIRE_CLOSE(test[i], (double) (i + 1), 1e-5);
+
+    // Remove the file.
+    remove("test_file.txt");
+  }
+
+  /**
+   * Make sure arma_binary is loaded correctly.
+   */
+  BOOST_AUTO_TEST_CASE(LoadArmaBinaryTest) {
+    arma::mat test = "1 5;"
+                     "2 6;"
+                     "3 7;"
+                     "4 8;";
+
+    arma::mat testTrans = trans(test);
+    BOOST_REQUIRE(testTrans.quiet_save("test_file.bin", arma::arma_binary)
+        == true);
+
+    // Now reload through our interface.
+    BOOST_REQUIRE(data::Load("test_file.bin", test) == true);
+
+    BOOST_REQUIRE_EQUAL(test.n_rows, 4);
+    BOOST_REQUIRE_EQUAL(test.n_cols, 2);
+
+    for (int i = 0; i < 8; i++)
+      BOOST_REQUIRE_CLOSE(test[i], (double) (i + 1), 1e-5);
+
+    // Remove the file.
+    remove("test_file.bin");
+  }
+
+  /**
+   * Make sure arma_binary is saved correctly.
+   */
+  BOOST_AUTO_TEST_CASE(SaveArmaBinaryTest) {
+    arma::mat test = "1 5;"
+                     "2 6;"
+                     "3 7;"
+                     "4 8;";
+
+    BOOST_REQUIRE(data::Save("test_file.bin", test) == true);
+
+    BOOST_REQUIRE(data::Load("test_file.bin", test) == true);
+
+    BOOST_REQUIRE_EQUAL(test.n_rows, 4);
+    BOOST_REQUIRE_EQUAL(test.n_cols, 2);
+
+    for (int i = 0; i < 8; i++)
+      BOOST_REQUIRE_CLOSE(test[i], (double) (i + 1), 1e-5);
+
+    // Remove the file.
+    remove("test_file.bin");
+  }
+
+  /**
+   * Make sure raw_binary is loaded correctly.
+   */
+  BOOST_AUTO_TEST_CASE(LoadRawBinaryTest) {
+    arma::mat test = "1 2;"
+                     "3 4;"
+                     "5 6;"
+                     "7 8;";
+
+    arma::mat testTrans = trans(test);
+    BOOST_REQUIRE(testTrans.quiet_save("test_file.bin", arma::raw_binary)
+        == true);
+
+    // Now reload through our interface.
+    BOOST_REQUIRE(data::Load("test_file.bin", test) == true);
+
+    BOOST_REQUIRE_EQUAL(test.n_rows, 1);
+    BOOST_REQUIRE_EQUAL(test.n_cols, 8);
+
+    for (int i = 0; i < 8; i++)
+      BOOST_REQUIRE_CLOSE(test[i], (double) (i + 1), 1e-5);
+
+    // Remove the file.
+    remove("test_file.bin");
+  }
+
+  /**
+   * Make sure load as PGM is successful.
+   */
+  BOOST_AUTO_TEST_CASE(LoadPGMBinaryTest) {
+    arma::mat test = "1 5;"
+                     "2 6;"
+                     "3 7;"
+                     "4 8;";
+
+    arma::mat testTrans = trans(test);
+    BOOST_REQUIRE(testTrans.quiet_save("test_file.pgm", arma::pgm_binary)
+        == true);
+
+    // Now reload through our interface.
+    BOOST_REQUIRE(data::Load("test_file.pgm", test) == true);
+
+    BOOST_REQUIRE_EQUAL(test.n_rows, 4);
+    BOOST_REQUIRE_EQUAL(test.n_cols, 2);
+
+    for (int i = 0; i < 8; i++)
+      BOOST_REQUIRE_CLOSE(test[i], (double) (i + 1), 1e-5);
+
+    // Remove the file.
+    remove("test_file.pgm");
+  }
+
+  /**
+   * Make sure save as PGM is successful.
+   */
+  BOOST_AUTO_TEST_CASE(SavePGMBinaryTest) {
+    arma::mat test = "1 5;"
+                     "2 6;"
+                     "3 7;"
+                     "4 8;";
+
+    BOOST_REQUIRE(data::Save("test_file.pgm", test) == true);
+
+    // Now reload through our interface.
+    BOOST_REQUIRE(data::Load("test_file.pgm", test) == true);
+
+    BOOST_REQUIRE_EQUAL(test.n_rows, 4);
+    BOOST_REQUIRE_EQUAL(test.n_cols, 2);
+
+    for (int i = 0; i < 8; i++)
+      BOOST_REQUIRE_CLOSE(test[i], (double) (i + 1), 1e-5);
+
+    // Remove the file.
+    remove("test_file.pgm");
+  }
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/math_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/math_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/math_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,523 @@
+/***
+ * @file math_test.cpp
+ * @author Ryan Curtin
+ *
+ * Tests for everything in the math:: namespace.
+ */
+#include <mlpack/core/math/range.hpp>
+#include <mlpack/core/math/math_misc.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+using namespace math;
+
+BOOST_AUTO_TEST_SUITE(MathTest);
+
+  /***
+   * Verify that the empty constructor creates an empty range.
+   */
+  BOOST_AUTO_TEST_CASE(RangeEmptyConstructor)
+  {
+    Range x = Range();
+
+    // Just verify that it is empty.
+    BOOST_REQUIRE_GT(x.lo, x.hi);
+  }
+
+  /***
+   * Verify that the point constructor correctly creates a range that is just a
+   * point.
+   */
+  BOOST_AUTO_TEST_CASE(RangePointConstructor)
+  {
+    Range x(10.0);
+
+    BOOST_REQUIRE_CLOSE(x.lo, x.hi, 1e-25);
+    BOOST_REQUIRE_SMALL(x.width(), 1e-5);
+    BOOST_REQUIRE_CLOSE(x.lo, 10.0, 1e-25);
+    BOOST_REQUIRE_CLOSE(x.hi, 10.0, 1e-25);
+  }
+
+  /***
+   * Verify that the range constructor correctly creates the range.
+   */
+  BOOST_AUTO_TEST_CASE(RangeConstructor)
+  {
+    Range x(0.5, 5.5);
+
+    BOOST_REQUIRE_CLOSE(x.lo, 0.5, 1e-25);
+    BOOST_REQUIRE_CLOSE(x.hi, 5.5, 1e-25);
+  }
+
+  /***
+   * Test that we get the width correct.
+   */
+  BOOST_AUTO_TEST_CASE(RangeWidth)
+  {
+    Range x(0.0, 10.0);
+
+    BOOST_REQUIRE_CLOSE(x.width(), 10.0, 1e-20);
+
+    // Make it empty.
+    x.hi = 0.0;
+
+    BOOST_REQUIRE_SMALL(x.width(), 1e-5);
+
+    // Make it negative.
+    x.hi = -2.0;
+
+    BOOST_REQUIRE_SMALL(x.width(), 1e-5);
+
+    // Just one more test.
+    x.lo = -5.2;
+    x.hi = 5.2;
+
+    BOOST_REQUIRE_CLOSE(x.width(), 10.4, 1e-5);
+  }
+
+  /**
+   * Test that we get the midpoint correct.
+   */
+  BOOST_AUTO_TEST_CASE(RangeMidpoint)
+  {
+    Range x(0.0, 10.0);
+
+    BOOST_REQUIRE_CLOSE(x.mid(), 5.0, 1e-5);
+
+    x.lo = -5.0;
+
+    BOOST_REQUIRE_CLOSE(x.mid(), 2.5, 1e-5);
+  }
+
+  /***
+   * Test that we can expand to include other ranges correctly.
+   */
+  BOOST_AUTO_TEST_CASE(RangeIncludeOther)
+  {
+    // We need to test both |= and |.
+    // We have three cases: non-overlapping; overlapping; equivalent, and then a
+    // couple permutations (switch left with right and make sure it still works).
+    Range x(0.0, 2.0);
+    Range y(3.0, 5.0);
+
+    Range z(0.0, 2.0); // Used for operator|=().
+    Range w;
+    z |= y;
+    w = x | y;
+
+    BOOST_REQUIRE_SMALL(z.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 5.0, 1e-5);
+    BOOST_REQUIRE_SMALL(w.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 5.0, 1e-5);
+
+    // Switch operator precedence.
+    z = y;
+    z |= x;
+    w = y | x;
+
+    BOOST_REQUIRE_SMALL(z.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 5.0, 1e-5);
+    BOOST_REQUIRE_SMALL(w.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 5.0, 1e-5);
+
+    // Now make them overlapping.
+    x = Range(0.0, 3.5);
+    y = Range(3.0, 4.0);
+
+    z = x;
+    z |= y;
+    w = x | y;
+
+    BOOST_REQUIRE_SMALL(z.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 4.0, 1e-5);
+    BOOST_REQUIRE_SMALL(w.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 4.0, 1e-5);
+
+    // Switch operator precedence.
+    z = y;
+    z |= x;
+    w = y | x;
+
+    BOOST_REQUIRE_SMALL(z.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 4.0, 1e-5);
+    BOOST_REQUIRE_SMALL(w.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 4.0, 1e-5);
+
+    // Now the equivalent case.
+    x = Range(0.0, 2.0);
+    y = Range(0.0, 2.0);
+
+    z = x;
+    z |= y;
+    w = x | y;
+
+    BOOST_REQUIRE_SMALL(z.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 2.0, 1e-5);
+    BOOST_REQUIRE_SMALL(w.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 2.0, 1e-5);
+
+    z = y;
+    z |= x;
+    w = y | x;
+
+    BOOST_REQUIRE_SMALL(z.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 2.0, 1e-5);
+    BOOST_REQUIRE_SMALL(w.lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 2.0, 1e-5);
+  }
+
+  /***
+   * Test that we can 'and' ranges correctly.
+   */
+  BOOST_AUTO_TEST_CASE(RangeIntersectOther)
+  {
+    // We need to test both &= and &.
+    // We have three cases: non-overlapping, overlapping; equivalent, and then a
+    // couple permutations (switch left with right and make sure it still works).
+    Range x(0.0, 2.0);
+    Range y(3.0, 5.0);
+
+    Range z(0.0, 2.0);
+    Range w;
+    z &= y;
+    w = x & y;
+
+    BOOST_REQUIRE_SMALL(z.width(), 1e-5);
+    BOOST_REQUIRE_SMALL(w.width(), 1e-5);
+
+    // Reverse operator precedence.
+    z = y;
+    z &= x;
+    w = y & x;
+
+    BOOST_REQUIRE_SMALL(z.width(), 1e-5);
+    BOOST_REQUIRE_SMALL(w.width(), 1e-5);
+
+    // Now make them overlapping.
+    x = Range(0.0, 3.5);
+    y = Range(3.0, 4.0);
+
+    z = x;
+    z &= y;
+    w = x & y;
+
+    BOOST_REQUIRE_CLOSE(z.lo, 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 3.5, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.lo, 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 3.5, 1e-5);
+
+    // Reverse operator precedence.
+    z = y;
+    z &= x;
+    w = y & x;
+
+    BOOST_REQUIRE_CLOSE(z.lo, 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 3.5, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.lo, 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 3.5, 1e-5);
+
+    // Now make them equivalent.
+    x = Range(2.0, 4.0);
+    y = Range(2.0, 4.0);
+
+    z = x;
+    z &= y;
+    w = x & y;
+
+    BOOST_REQUIRE_CLOSE(z.lo, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 4.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.lo, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 4.0, 1e-5);
+  }
+
+  /**
+   * Test multiplication of a range with a double.
+   */
+  BOOST_AUTO_TEST_CASE(RangeMultiply)
+  {
+    // We need to test both * and *=, as well as both cases of *.
+    // We'll try with a couple of numbers: -1, 0, 2.
+    // And we'll have a couple of cases for bounds: strictly less than zero;
+    // including zero; and strictly greater than zero.
+    //
+    // So, nine total cases.
+    Range x(-5.0, -3.0);
+    Range y(-5.0, -3.0);
+    Range z;
+    Range w;
+
+    y *= -1.0;
+    z = x * -1.0;
+    w = -1.0 * x;
+
+    BOOST_REQUIRE_CLOSE(y.lo, 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(y.hi, 5.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.lo, 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 5.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.lo, 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 5.0, 1e-5);
+
+    y = x;
+    y *= 0.0;
+    z = x * 0.0;
+    w = 0.0 * x;
+
+    BOOST_REQUIRE_SMALL(y.lo, 1e-5);
+    BOOST_REQUIRE_SMALL(y.hi, 1e-5);
+    BOOST_REQUIRE_SMALL(z.lo, 1e-5);
+    BOOST_REQUIRE_SMALL(z.hi, 1e-5);
+    BOOST_REQUIRE_SMALL(w.lo, 1e-5);
+    BOOST_REQUIRE_SMALL(w.hi, 1e-5);
+
+    y = x;
+    y *= 2.0;
+    z = x * 2.0;
+    w = 2.0 * x;
+
+    BOOST_REQUIRE_CLOSE(y.lo, -10.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(y.hi, -6.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.lo, -10.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, -6.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.lo, -10.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, -6.0, 1e-5);
+
+    x = Range(-2.0, 2.0);
+    y = x;
+
+    y *= -1.0;
+    z = x * -1.0;
+    w = -1.0 * x;
+
+    BOOST_REQUIRE_CLOSE(y.lo, -2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(y.hi, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.lo, -2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.lo, -2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 2.0, 1e-5);
+
+    y = x;
+    y *= 0.0;
+    z = x * 0.0;
+    w = 0.0 * x;
+
+    BOOST_REQUIRE_SMALL(y.lo, 1e-5);
+    BOOST_REQUIRE_SMALL(y.hi, 1e-5);
+    BOOST_REQUIRE_SMALL(z.lo, 1e-5);
+    BOOST_REQUIRE_SMALL(z.hi, 1e-5);
+    BOOST_REQUIRE_SMALL(w.lo, 1e-5);
+    BOOST_REQUIRE_SMALL(w.hi, 1e-5);
+
+    y = x;
+    y *= 2.0;
+    z = x * 2.0;
+    w = 2.0 * x;
+
+    BOOST_REQUIRE_CLOSE(y.lo, -4.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(y.hi, 4.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.lo, -4.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 4.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.lo, -4.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 4.0, 1e-5);
+
+    x = Range(3.0, 5.0);
+
+    y = x;
+    y *= -1.0;
+    z = x * -1.0;
+    w = -1.0 * x;
+
+    BOOST_REQUIRE_CLOSE(y.lo, -5.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(y.hi, -3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.lo, -5.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, -3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.lo, -5.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, -3.0, 1e-5);
+
+    y = x;
+    y *= 0.0;
+    z = x * 0.0;
+    w = 0.0 * x;
+
+    BOOST_REQUIRE_SMALL(y.lo, 1e-5);
+    BOOST_REQUIRE_SMALL(y.hi, 1e-5);
+    BOOST_REQUIRE_SMALL(z.lo, 1e-5);
+    BOOST_REQUIRE_SMALL(z.hi, 1e-5);
+    BOOST_REQUIRE_SMALL(w.lo, 1e-5);
+    BOOST_REQUIRE_SMALL(w.hi, 1e-5);
+
+    y = x;
+    y *= 2.0;
+    z = x * 2.0;
+    w = 2.0 * x;
+
+    BOOST_REQUIRE_CLOSE(y.lo, 6.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(y.hi, 10.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.lo, 6.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(z.hi, 10.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.lo, 6.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(w.hi, 10.0, 1e-5);
+  }
+
+  /**
+   * Test equality operator.
+   */
+  BOOST_AUTO_TEST_CASE(RangeEquality)
+  {
+    // Three cases: non-overlapping, overlapping, equivalent.  We should also
+    // consider empty ranges, which are not necessarily equal...
+    Range x(0.0, 2.0);
+    Range y(3.0, 5.0);
+
+    // These are odd calls, but we don't want to use operator!= here.
+    BOOST_REQUIRE_EQUAL((x == y), false);
+    BOOST_REQUIRE_EQUAL((y == x), false);
+
+    y = Range(1.0, 3.0);
+
+    BOOST_REQUIRE_EQUAL((x == y), false);
+    BOOST_REQUIRE_EQUAL((y == x), false);
+
+    y = Range(0.0, 2.0);
+
+    BOOST_REQUIRE_EQUAL((x == y), true);
+    BOOST_REQUIRE_EQUAL((y == x), true);
+
+    x = Range(1.0, -1.0); // Empty.
+    y = Range(1.0, -1.0); // Also empty.
+
+    BOOST_REQUIRE_EQUAL((x == y), true);
+    BOOST_REQUIRE_EQUAL((y == x), true);
+
+    // No need to test what it does if the empty ranges are different "ranges"
+    // because we are not forcing behavior for that.
+  }
+
+  /**
+   * Test inequality operator.
+   */
+  BOOST_AUTO_TEST_CASE(RangeInequality)
+  {
+    // We will use the same three cases as the RangeEquality test.
+    Range x(0.0, 2.0);
+    Range y(3.0, 5.0);
+
+    // Again, odd calls, but we want to force use of operator!=.
+    BOOST_REQUIRE_EQUAL((x != y), true);
+    BOOST_REQUIRE_EQUAL((y != x), true);
+
+    y = Range(1.0, 3.0);
+
+    BOOST_REQUIRE_EQUAL((x != y), true);
+    BOOST_REQUIRE_EQUAL((y != x), true);
+
+    y = Range(0.0, 2.0);
+
+    BOOST_REQUIRE_EQUAL((x != y), false);
+    BOOST_REQUIRE_EQUAL((y != x), false);
+
+    x = Range(1.0, -1.0); // Empty.
+    y = Range(1.0, -1.0); // Also empty.
+
+    BOOST_REQUIRE_EQUAL((x != y), false);
+    BOOST_REQUIRE_EQUAL((y != x), false);
+  }
+
+  /**
+   * Test strict less-than operator.
+   */
+  BOOST_AUTO_TEST_CASE(RangeStrictLessThan)
+  {
+    // Three cases: non-overlapping, overlapping, and equivalent.
+    Range x(0.0, 2.0);
+    Range y(3.0, 5.0);
+
+    BOOST_REQUIRE_EQUAL((x < y), true);
+    BOOST_REQUIRE_EQUAL((y < x), false);
+
+    y = Range(1.0, 3.0);
+
+    BOOST_REQUIRE_EQUAL((x < y), false);
+    BOOST_REQUIRE_EQUAL((y < x), false);
+
+    y = Range(0.0, 2.0);
+
+    BOOST_REQUIRE_EQUAL((x < y), false);
+    BOOST_REQUIRE_EQUAL((y < x), false);
+  }
+
+  /**
+   * Test strict greater-than operator.
+   */
+  BOOST_AUTO_TEST_CASE(RangeStrictGreaterThan)
+  {
+    // Three cases: non-overlapping, overlapping, and equivalent.
+    Range x(0.0, 2.0);
+    Range y(3.0, 5.0);
+
+    BOOST_REQUIRE_EQUAL((x > y), false);
+    BOOST_REQUIRE_EQUAL((y > x), true);
+
+    y = Range(1.0, 3.0);
+
+    BOOST_REQUIRE_EQUAL((x > y), false);
+    BOOST_REQUIRE_EQUAL((y > x), false);
+
+    y = Range(0.0, 2.0);
+
+    BOOST_REQUIRE_EQUAL((x > y), false);
+    BOOST_REQUIRE_EQUAL((y > x), false);
+  }
+
+  /**
+   * Test the Contains() operator.
+   */
+  BOOST_AUTO_TEST_CASE(RangeContains)
+  {
+    // We have three Range cases: strictly less than 0; overlapping 0; and
+    // strictly greater than 0.  Then the numbers we check can be the same three
+    // cases, including one greater than and one less than the range.  This should
+    // be about 15 total cases.
+    Range x(-2.0, -1.0);
+
+    BOOST_REQUIRE(!x.Contains(-3.0));
+    BOOST_REQUIRE(x.Contains(-2.0));
+    BOOST_REQUIRE(x.Contains(-1.5));
+    BOOST_REQUIRE(x.Contains(-1.0));
+    BOOST_REQUIRE(!x.Contains(-0.5));
+    BOOST_REQUIRE(!x.Contains(0.0));
+    BOOST_REQUIRE(!x.Contains(1.0));
+
+    x = Range(-1.0, 1.0);
+
+    BOOST_REQUIRE(!x.Contains(-2.0));
+    BOOST_REQUIRE(x.Contains(-1.0));
+    BOOST_REQUIRE(x.Contains(0.0));
+    BOOST_REQUIRE(x.Contains(1.0));
+    BOOST_REQUIRE(!x.Contains(2.0));
+
+    x = Range(1.0, 2.0);
+
+    BOOST_REQUIRE(!x.Contains(-1.0));
+    BOOST_REQUIRE(!x.Contains(0.0));
+    BOOST_REQUIRE(!x.Contains(0.5));
+    BOOST_REQUIRE(x.Contains(1.0));
+    BOOST_REQUIRE(x.Contains(1.5));
+    BOOST_REQUIRE(x.Contains(2.0));
+    BOOST_REQUIRE(!x.Contains(2.5));
+
+    // Now let's try it on an empty range.
+    x = Range();
+
+    BOOST_REQUIRE(!x.Contains(-10.0));
+    BOOST_REQUIRE(!x.Contains(0.0));
+    BOOST_REQUIRE(!x.Contains(10.0));
+
+    // And an infinite range.
+    x = Range(-DBL_MAX, DBL_MAX);
+
+    BOOST_REQUIRE(x.Contains(-10.0));
+    BOOST_REQUIRE(x.Contains(0.0));
+    BOOST_REQUIRE(x.Contains(10.0));
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/mlpack_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/mlpack_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/mlpack_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,3 @@
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE MLPACKTest
+#include <boost/test/unit_test.hpp>

Added: mlpack/trunk/src/mlpack/tests/nbc_test.cc
===================================================================
--- mlpack/trunk/src/mlpack/tests/nbc_test.cc	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/nbc_test.cc	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,56 @@
+#include <mlpack/core.h>
+#include <mlpack/methods/naive_bayes/simple_nbc.h>
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+using namespace naive_bayes;
+
+BOOST_AUTO_TEST_SUITE(NBCTest);
+
+  BOOST_AUTO_TEST_CASE(SimpleNBCTest) {
+    const char* filename_train_ = "trainSet.csv";
+    const char* filename_test_ = "testSet.csv";
+    const char* train_result_ = "trainRes.csv";
+    const char* test_result_ = "testRes.csv";
+    size_t number_of_classes_ = 2;
+
+    arma::mat train_data, train_res, calc_mat;
+    data::Load(filename_train_, train_data, true);
+    data::Load(train_result_, train_res, true);
+
+    CLI::GetParam<int>("nbc/classes") = number_of_classes_;
+    SimpleNaiveBayesClassifier nbc_test_(train_data);
+
+    size_t number_of_features = nbc_test_.means_.n_rows;
+    calc_mat.zeros(2 * number_of_features + 1, number_of_classes_);
+
+    for (size_t i = 0; i < number_of_features; i++) {
+      for (size_t j = 0; j < number_of_classes_; j++) {
+        calc_mat(i, j) = nbc_test_.means_(i, j);
+        calc_mat(i + number_of_features, j) = nbc_test_.variances_(i, j);
+      }
+    }
+    for (size_t i = 0; i < number_of_classes_; i++)
+      calc_mat(2 * number_of_features, i) = nbc_test_.class_probabilities_(i);
+
+    for(size_t i = 0; i < calc_mat.n_rows; i++) {
+      for(size_t j = 0; j < number_of_classes_; j++) {
+        BOOST_REQUIRE_CLOSE(train_res(i, j) + .00001, calc_mat(i, j), .01);
+      }
+    }
+
+    arma::mat test_data, test_res;
+    arma::vec test_res_vec, calc_vec;
+    data::Load(filename_test_, test_data, true);
+    data::Load(test_result_, test_res, true);
+
+    nbc_test_.Classify(test_data, calc_vec);
+
+    size_t number_of_datum = test_data.n_cols;
+    test_res_vec = test_res.col(0);
+
+    for(size_t i = 0; i < number_of_datum; i++)
+      BOOST_REQUIRE_EQUAL(test_res_vec(i), calc_vec(i));
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/nca_test.cc
===================================================================
--- mlpack/trunk/src/mlpack/tests/nca_test.cc	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/nca_test.cc	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,167 @@
+/**
+ * @file nca_test.cc
+ * @author Ryan Curtin
+ *
+ * Unit tests for Neighborhood Components Analysis and related code (including
+ * the softmax error function).
+ */
+#include <mlpack/core.h>
+#include <mlpack/core/kernels/lmetric.hpp>
+#include <mlpack/methods/nca/nca.h>
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+using namespace mlpack::kernel;
+using namespace mlpack::nca;
+
+//
+// Tests for the SoftmaxErrorFunction
+//
+
+BOOST_AUTO_TEST_SUITE(NcaTest);
+
+  /***
+   * The Softmax error function should return the identity matrix as its initial
+   * point.
+   */
+  BOOST_AUTO_TEST_CASE(softmax_initial_point) {
+    // Cheap fake dataset.
+    arma::mat data;
+    data.randu(5, 5);
+    arma::uvec labels;
+    labels.zeros(5);
+
+    SoftmaxErrorFunction<SquaredEuclideanDistance> sef(data, labels);
+
+    // Verify the initial point is the identity matrix.
+    arma::mat initial_point = sef.GetInitialPoint();
+    for (int row = 0; row < 5; row++) {
+      for (int col = 0; col < 5; col++) {
+        if (row == col)
+          BOOST_REQUIRE_CLOSE(initial_point(row, col), 1.0, 1e-5);
+        else
+          BOOST_REQUIRE(initial_point(row, col) == 0.0);
+      }
+    }
+  }
+
+  /***
+   * On a simple fake dataset, ensure that the initial function evaluation is
+   * correct.
+   */
+  BOOST_AUTO_TEST_CASE(softmax_initial_evaluation) {
+    // Useful but simple dataset with six points and two classes.
+    arma::mat data    = "-0.1 -0.1 -0.1  0.1  0.1  0.1;"
+                        " 1.0  0.0 -1.0  1.0  0.0 -1.0 ";
+    arma::uvec labels = " 0    0    0    1    1    1   ";
+
+    SoftmaxErrorFunction<SquaredEuclideanDistance> sef(data, labels);
+
+    double objective = sef.Evaluate(arma::eye<arma::mat>(2, 2));
+
+    // Result painstakingly calculated by hand by rcurtin (recorded forever in his
+    // notebook).  As a result of lack of precision of the by-hand result, the
+    // tolerance is fairly high.
+    BOOST_REQUIRE_CLOSE(objective, -1.5115, 0.01);
+  }
+
+  /***
+   * On a simple fake dataset, ensure that the initial gradient evaluation is
+   * correct.
+   */
+  BOOST_AUTO_TEST_CASE(softmax_initial_gradient) {
+    // Useful but simple dataset with six points and two classes.
+    arma::mat data    = "-0.1 -0.1 -0.1  0.1  0.1  0.1;"
+                        " 1.0  0.0 -1.0  1.0  0.0 -1.0 ";
+    arma::uvec labels = " 0    0    0    1    1    1   ";
+
+    SoftmaxErrorFunction<SquaredEuclideanDistance> sef(data, labels);
+
+    arma::mat gradient;
+    sef.Gradient(arma::eye<arma::mat>(2, 2), gradient);
+
+    // Results painstakingly calculated by hand by rcurtin (recorded forever in
+    // his notebook).  As a result of lack of precision of the by-hand result, the
+    // tolerance is fairly high.
+    BOOST_REQUIRE_CLOSE(gradient(0, 0), -0.089766, 0.05);
+    BOOST_REQUIRE(gradient(1, 0) == 0.0);
+    BOOST_REQUIRE(gradient(0, 1) == 0.0);
+    BOOST_REQUIRE_CLOSE(gradient(1, 1), 1.63823, 0.01);
+  }
+
+  /***
+   * On optimally separated datasets, ensure that the objective function is
+   * optimal (equal to the negative number of points).
+   */
+  BOOST_AUTO_TEST_CASE(softmax_optimal_evaluation) {
+    // Simple optimal dataset.
+    arma::mat data    = " 500  500 -500 -500;"
+                        "   1    0    1    0 ";
+    arma::uvec labels = "   0    0    1    1 ";
+
+    SoftmaxErrorFunction<SquaredEuclideanDistance> sef(data, labels);
+
+    double objective = sef.Evaluate(arma::eye<arma::mat>(2, 2));
+
+    // Use a very close tolerance for optimality; we need to be sure this function
+    // gives optimal results correctly.
+    BOOST_REQUIRE_CLOSE(objective, -4.0, 1e-10);
+  }
+
+  /***
+   * On optimally separated datasets, ensure that the gradient is zero.
+   */
+  BOOST_AUTO_TEST_CASE(softmax_optimal_gradient) {
+    // Simple optimal dataset.
+    arma::mat data    = " 500  500 -500 -500;"
+                        "   1    0    1    0 ";
+    arma::uvec labels = "   0    0    1    1 ";
+
+    SoftmaxErrorFunction<SquaredEuclideanDistance> sef(data, labels);
+
+    arma::mat gradient;
+    sef.Gradient(arma::eye<arma::mat>(2, 2), gradient);
+
+    BOOST_REQUIRE(gradient(0, 0) == 0.0);
+    BOOST_REQUIRE(gradient(0, 1) == 0.0);
+    BOOST_REQUIRE(gradient(1, 0) == 0.0);
+    BOOST_REQUIRE(gradient(1, 1) == 0.0);
+  }
+
+  //
+  // Tests for the NCA algorithm.
+  //
+
+  /***
+   * On our simple dataset, ensure that the NCA algorithm fully separates the
+   * points.
+   */
+  BOOST_AUTO_TEST_CASE(nca_simple_dataset) {
+    // Useful but simple dataset with six points and two classes.
+    arma::mat data    = "-0.1 -0.1 -0.1  0.1  0.1  0.1;"
+                        " 1.0  0.0 -1.0  1.0  0.0 -1.0 ";
+    arma::uvec labels = " 0    0    0    1    1    1   ";
+
+    NCA<SquaredEuclideanDistance> nca(data, labels);
+
+    arma::mat output_matrix;
+    nca.LearnDistance(output_matrix);
+
+    // Ensure that the objective function is better now.
+    SoftmaxErrorFunction<SquaredEuclideanDistance> sef(data, labels);
+
+    double init_obj = sef.Evaluate(arma::eye<arma::mat>(2, 2));
+    double final_obj = sef.Evaluate(output_matrix);
+    arma::mat final_gradient;
+    sef.Gradient(output_matrix, final_gradient);
+
+    // final_obj must be less than init_obj.
+    BOOST_REQUIRE_LT(final_obj, init_obj);
+    // Verify that final objective is optimal.
+    BOOST_REQUIRE_CLOSE(final_obj, -6.0, 1e-8);
+    // The solution is not unique, so the best we can do is ensure the gradient
+    // norm is close to 0.
+    BOOST_REQUIRE_LT(arma::norm(final_gradient, 2), 1e-10);
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/nnsvm_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/nnsvm_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/nnsvm_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,288 @@
+/**
+ * @file nnsvm_test.cc
+ *
+ * Test file for NNSVM class
+ */
+#include <iostream>
+#include <mlpack/methods/nnsvm/nnsvm.hpp>
+#include <mlpack/core/kernels/linear_kernel.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+using namespace mlpack::nnsvm;
+
+BOOST_AUTO_TEST_SUITE(NnsvmTest);
+
+  /***
+   * simple nonnegative SVM test with small, synthetic dataset
+   */
+  BOOST_AUTO_TEST_CASE(linear_kernel_test_1)
+  {
+    // initialize the matrix
+    arma::mat data;
+
+    data << -1.0 <<  1.0 << 1.0 << arma::endr
+         << -2.0 <<  2.0 << 1.0 << arma::endr
+         << -3.0 <<  3.0 << 1.0 << arma::endr
+         << -4.0 <<  4.0 << 1.0 << arma::endr
+         <<  1.0 << -1.0 << 0.0 << arma::endr
+         <<  2.0 << -2.0 << 0.0 << arma::endr
+         <<  3.0 << -3.0 << 0.0 << arma::endr
+         <<  4.0 << -4.0 << 0.0 << arma::endr;
+
+    // test the linear kernel
+    NNSVM<kernel::LinearKernel> nnsvm;
+
+    nnsvm.InitTrain(data, 2);
+    double calculatedThreshold = nnsvm.getThreshold();
+    size_t calculatedSupportVectorCount = nnsvm.getSupportVectorCount();
+    const arma::vec calculatedSupportVectorCoefficients =
+                      nnsvm.getSupportVectorCoefficients();
+    const arma::vec calculatedWeightVector = nnsvm.getWeightVector();
+
+    // check for correctness on the linear kernel
+    BOOST_REQUIRE(calculatedSupportVectorCount == 3);
+    BOOST_REQUIRE_CLOSE(calculatedThreshold, -1.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(calculatedSupportVectorCoefficients[0],
+                        3.7499785159728178, 1e-5);
+    BOOST_REQUIRE_CLOSE(calculatedSupportVectorCoefficients[1],
+                        6.2500214840271884, 1e-5);
+    BOOST_REQUIRE_CLOSE(calculatedSupportVectorCoefficients[2], -10.000, 1e-5);
+    BOOST_REQUIRE_CLOSE(calculatedWeightVector[0], 0.00000000, 1e-5);
+    BOOST_REQUIRE_CLOSE(calculatedWeightVector[1], 0.00000000, 1e-5);
+    BOOST_REQUIRE_CLOSE(calculatedWeightVector[2], 0.00000000, 1e-5);
+    BOOST_REQUIRE_CLOSE(calculatedWeightVector[3], 0.00017187221748210524, 1e-5);
+    BOOST_REQUIRE_CLOSE(calculatedWeightVector[4], 0.00000000, 1e-5);
+    BOOST_REQUIRE_CLOSE(calculatedWeightVector[5], 0.00000000, 1e-5);
+    BOOST_REQUIRE_CLOSE(calculatedWeightVector[6], 0.00000000, 1e-5);
+
+  }
+  //BOOST_AUTO_TEST_CASE(linear_kernel_test_2)
+  //{
+  //  // initialize the matrix
+  //  arma::mat data;
+  //
+  //  data << 2.8532 << 0.6808 << -18 << 6.5 << -26.23 << -273.67 << 3.1747
+  //          << 1.4824 << 2.0161 << -11.142 << -31.166 << 0 << -1.0324
+  //          << -8.2685 << 3.48 << 8.545 << 6.575 << -7.89 << 1.9919 << -7
+  //          << 1 << arma::endr
+  //       << 0.0578 << 1.3971 << -24 << -12.1 << -100.13 << -553.18 << 2.3804
+  //          << -0.5607 << 4.5496 << -24.574 << -24.968 << -1 << -13.534 << -31.45
+  //          << 1.54 << -13.05 << -11.725 << -2.55 << 1.8087 << 10 << 1
+  //          << arma::endr
+  //       << 0.1804 << 1.6302 << -26 << -6.4 << -81.28 << -529.73 << 2.0123
+  //          << 1.0011 << 2.1322 << -38.049 << -22.548 << -1 << -17.921
+  //          << -29.786 << -4.2 << -5.885 << -12.065 << -0.18 << 3.7498
+  //          << 8 << 1 << arma::endr
+  //       << 2.2685 << 0.77 << -26 << -5 << -63.74 << -619.41 << 3.79 << 1.4824
+  //          << 2.6626 << -11.553 << -10.084 << -1 << -23.293 << -24.595 << 5.06
+  //          << 1.81 << -6.8 << -2.74 << 1.4367 << 2 << 1 << arma::endr
+  //       << 1.1094 << 1.3512 << -27 << -5.9 << -97.98 << -888.82 << 4.7719
+  //          << -0.8833 << 7.0048 << -41.996 << -25.473 << 0 << -17.197 << -31.864
+  //          << 2.96 << -12.92 << -21.625 << -4.66 << 4.1161 << 14 << 1
+  //          << arma::endr
+  //       << -0.7448 << 0.639 << -33 << -4.3 << -121.87 << -1240.2 << 2.574
+  //          << -11.96 << -1.4605 << -23.163 << -41.738 << 0 << -26.078
+  //          << -65.459 << -3.46 << -43.665 << -47.125 << 0.36 << 1.5793
+  //          << 11 << 1 << arma::endr
+  //       << 2.1242 << 1.0001 << -27 << -1.5 << -85.01 << -753.81 << 5.8026
+  //          << 0.4733 << 7.3244 << -28.602 << -22.096 << -1 << -25.72 << -5.058
+  //          << 1.96 << -2.715 << -36.435 << 6.23 << 4.0664 << 4 << 1 << arma::endr
+  //       << 1.5147 << 1.5999 << -30 << 9.5 << -48.64 << -552.72 << 6.8646
+  //          << -2.7514 << 9.765 << -32.567 << -26.009 << -1 << -21.244 << -42.178
+  //          << -4.38 << -14.655 << -35.8 << -8.5 << 3.5578 << -3 << 1
+  //          << arma::endr
+  //       << 0.2762 << 0.4498 << -33 << -14.5 << -108.06 << -1848.7 << 3.3279
+  //          << -4.7404 << 8.3787 << -69.738 << -45.989 << -2 << -20.988 << -87.26
+  //          << 5.26 << -41.045 << -46.53 << 2.92 << 0.2006 << 17 << 1
+  //          << arma::endr
+  //       << -0.8361 << 0.5906 << -35 << -9.9 << -123.2 << -1535.6 << 1.7498
+  //          << -9.412 << 4.8324 << -61.991 << -45.081 << -1 << -28.325 << -85.874
+  //          << -10.38 << -36.53 << -51.315 << -4.12 << 1.5208 << 28 << 1
+  //          << arma::endr
+  //       << 3.4862 << 0.1746 << -8 << -12.6 << -48.05 << -74.518 << -5.3072 << 0
+  //          << -0.6322 << 14.706 << 4.6319 << -1 << -5.1945 << -10.268 << -13.8
+  //          << -18.11 << -2.625 << -9.7 << 0.0399 << -11 << 0 << arma::endr
+  //       << -1.332 << -0.5399 << 6 << -11.5 << -7.1 << -41.538 << -0.4827
+  //          << 0.1494 << 2.6331 << 13.711 << -20.669 << 1 << -2.307 << -16.457
+  //          << -5.3 << -21.65 << 3.57 << 6.82 << -1.4101 << -6 << 0
+  //          << arma::endr
+  //       << 0.6689 << 0.1837 << 2 << -1.9 << 10.22 << 176.41 << -1.2294 << 0
+  //          << -1.7885 << -16.553 << -2.9748 << 0 << 9.304 << 10.097 << -4.32
+  //          << -7.325 << -6.375 << 13.96 << -0.1116 << 25 << 0 << arma::endr
+  //       << -0.9639 << -0.6035 << 15 << 17.7 << 82.64 << 849.54 << 1.7272
+  //          << 2.3738 << -2.3887 << -4.4992 << 31.715 << -1 << 18.632 << -4.4991
+  //          << 13 << 8.955 << 12.725 << -19.04 << 0.218 << -24 << 0 << arma::endr
+  //       << -3.5669 << -0.4114 << 19 << 11.8 << 84.35 << 749.12 << -3.8668
+  //          << 1.9631 << 3.2414 << 25.695 << 28.835 << 1 << 30.208 << 34.002
+  //          << 14.78 << 46.875 << 24.84 << 8.1 << -1.7294 << -7 << 0 << arma::endr
+  //       << 1.5881 << -0.023 << 24 << 6.8 << 108.42 << 1255.7 << 2.0539 << 12.079
+  //          << 1.7954 << 21.008 << 33.312 << 0 << 27.819 << 22.083 << 15.94
+  //          << 71.565 << 49.805 << 3.94 << 0.3416 << -12 << 0 << arma::endr
+  //       << -1.5349 << -0.5047 << 10 << -12.2 << 12.26 << 476.02 << -4.4551 << 0
+  //          << -7.213 << 7.56 << 2.4955 << 0 << 18.81 << -13.185 << -11 << 9.86
+  //          << -12.555 << -3.63 << -2.4305 << -7 << 0 << arma::endr
+  //       << 1.9474 << -1.9588 << 26 << 29.8 << 156.44 << 1885.6 << 1.7485
+  //          << 12.592 << -4.1963 << 17.719 << 45.104 << 0 << 29.739 << 82.289
+  //          << 17 << 62.15 << 41.805 << -13.57 << 1.4464 << -48 << 0
+  //          << arma::endr
+  //       << 1.9065 << -0.1575 << 24 << -8.5 << 59.85 << 577 << -6.8442 << -0.4728
+  //          << -1.5632 << 19.76 << 13.641 << -2 << 32.432 << 34.894 << -0.9
+  //          << 52.775 << 23.125 << -24 << -8.2289 << -18 << 0 << arma::endr
+  //       << -0.6037 << -0.4235 << 21 << 18.6 << 137.71 << 1506.4 << -0.9627
+  //          << 11.03 << -2.7523 << 47.119 << 58.999 << 1 << 21.233 << 74.764
+  //          << 21.96 << 72.49 << 54.675 << -10.04 << 1.916 << -12 << 0
+  //          << arma::endr;
+  //
+  //  // test the linear kernel
+  //  NNSVM<SVMLinearKernel>* nnsvm = new NNSVM<SVMLinearKernel>();
+  //
+  //  nnsvm.InitTrain(data, 2);
+  //  double calculatedThreshold = nnsvm.getThreshold();
+  //  size_t calculatedSupportVectorCount = nnsvm.getSupportVectorCount();
+  //  const arma::vec calculatedSupportVectorCoefficients =
+  //                    nnsvm.getSupportVectorCoefficients();
+  //  const arma::vec calculatedWeightVector = nnsvm.getWeightVector();
+  //
+  //  // check for correctness on the linear kernel
+  //  BOOST_REQUIRE(calculatedSupportVectorCount == 6);
+  //  BOOST_REQUIRE_CLOSE(calculatedThreshold, -39.793784137999701, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedSupportVectorCoefficients[0],
+  //                      0.06875628588658407, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedSupportVectorCoefficients[1],
+  //                      3.1607079296638054, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedSupportVectorCoefficients[2],
+  //                      0.0039166013511236601, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedSupportVectorCoefficients[3],
+  //                      3.7130510722124139, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedSupportVectorCoefficients[4],
+  //                      0.43343566949350276, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedSupportVectorCoefficients[5],
+  //                      -10.000, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedWeightVector[0], 0.00000000, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedWeightVector[1], 0.00000000, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedWeightVector[2], 0.00000000, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedWeightVector[3], 0.00000000, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedWeightVector[4], 0.053222444790909262, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedWeightVector[5], 0.00000000, 1e-5);
+  //  BOOST_REQUIRE_CLOSE(calculatedWeightVector[6], 0.00000000, 1e-5);
+  //
+  //}
+  ///***
+  // * Test the dual-tree nearest-neighbors method with the naive method.  This
+  // * uses both a query and reference dataset.
+  // *
+  // * Errors are produced if the results are not identical.
+  // */
+  //BOOST_AUTO_TEST_CASE(dual_tree_vs_naive_1)
+  //{
+  //  arma::mat data_for_tree_;
+  //
+  //  // Hard-coded filename: bad!
+  //  if (data::Load("test_data_3_1000.csv", data_for_tree_) != true)
+  //  {
+  //    BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
+  //  }
+  //
+  //  // Set up matrices to work with.
+  //  arma::mat dual_query(data_for_tree_);
+  //  arma::mat dual_references(data_for_tree_);
+  //  arma::mat naive_query(data_for_tree_);
+  //  arma::mat naive_references(data_for_tree_);
+  //
+  //  AllkNN allknn_(dual_query, dual_references, 20, 5);
+  //  AllkNN naive_(naive_query, naive_references, 1 /* leaf_size ignored */, 5,
+  //      AllkNN::NAIVE);
+  //
+  //  arma::Col<size_t> resulting_neighbors_tree;
+  //  arma::vec distances_tree;
+  //  allknn_.ComputeNeighbors(resulting_neighbors_tree, distances_tree);
+  //
+  //  arma::Col<size_t> resulting_neighbors_naive;
+  //  arma::vec distances_naive;
+  //  naive_.ComputeNeighbors(resulting_neighbors_naive, distances_naive);
+  //
+  //  for (size_t i = 0; i < resulting_neighbors_tree.n_elem; i++)
+  //  {
+  //    BOOST_REQUIRE(resulting_neighbors_tree[i] == resulting_neighbors_naive[i]);
+  //    BOOST_REQUIRE_CLOSE(distances_tree[i], distances_naive[i], 1e-5);
+  //  }
+  //}
+  //
+  ///***
+  // * Test the dual-tree nearest-neighbors method with the naive method.  This uses
+  // * only a reference dataset.
+  // *
+  // * Errors are produced if the results are not identical.
+  // */
+  //BOOST_AUTO_TEST_CASE(dual_tree_vs_naive_2)
+  //{
+  //  arma::mat data_for_tree_;
+  //
+  //  // Hard-coded filename: bad!
+  //  // Code duplication: also bad!
+  //  if (data::Load("test_data_3_1000.csv", data_for_tree_) != true)
+  //  {
+  //    BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
+  //  }
+  //
+  //  // Set up matrices to work with (may not be necessary with no ALIAS_MATRIX?).
+  //  arma::mat dual_query(data_for_tree_);
+  //  arma::mat naive_query(data_for_tree_);
+  //
+  //  AllkNN allknn_(dual_query, 20, 1);
+  //  AllkNN naive_(naive_query, 1 /* leaf_size ignored with naive */, 1,
+  //      AllkNN::NAIVE);
+  //
+  //  arma::Col<size_t> resulting_neighbors_tree;
+  //  arma::vec distances_tree;
+  //  allknn_.ComputeNeighbors(resulting_neighbors_tree, distances_tree);
+  //
+  //  arma::Col<size_t> resulting_neighbors_naive;
+  //  arma::vec distances_naive;
+  //  naive_.ComputeNeighbors(resulting_neighbors_naive, distances_naive);
+  //
+  //  for (size_t i = 0; i < resulting_neighbors_tree.n_elem; i++) {
+  //    BOOST_REQUIRE(resulting_neighbors_tree[i] == resulting_neighbors_naive[i]);
+  //    BOOST_REQUIRE_CLOSE(distances_tree[i], distances_naive[i], 1e-5);
+  //  }
+  //}
+  //
+  ///***
+  // * Test the single-tree nearest-neighbors method with the naive method.  This
+  // * uses only a reference dataset.
+  // *
+  // * Errors are produced if the results are not identical.
+  // */
+  //BOOST_AUTO_TEST_CASE(single_tree_vs_naive)
+  //{
+  //  arma::mat data_for_tree_;
+  //
+  //  // Hard-coded filename: bad!
+  //  // Code duplication: also bad!
+  //  if (data::Load("test_data_3_1000.csv", data_for_tree_) != true)
+  //    BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
+  //
+  //  // Set up matrices to work with (may not be necessary with no ALIAS_MATRIX?).
+  //  arma::mat single_query(data_for_tree_);
+  //  arma::mat naive_query(data_for_tree_);
+  //
+  //  AllkNN allknn_(single_query, 20, 5, AllkNN::MODE_SINGLE);
+  //  AllkNN naive_(naive_query, 1 /* leaf_size ignored with naive */, 5,
+  //      AllkNN::NAIVE);
+  //
+  //  arma::Col<size_t> resulting_neighbors_tree;
+  //  arma::vec distances_tree;
+  //  allknn_.ComputeNeighbors(resulting_neighbors_tree, distances_tree);
+  //
+  //  arma::Col<size_t> resulting_neighbors_naive;
+  //  arma::vec distances_naive;
+  //  naive_.ComputeNeighbors(resulting_neighbors_naive, distances_naive);
+  //
+  //  for (size_t i = 0; i < resulting_neighbors_tree.n_elem; i++) {
+  //    BOOST_REQUIRE(resulting_neighbors_tree[i] == resulting_neighbors_naive[i]);
+  //    BOOST_REQUIRE_CLOSE(distances_tree[i], distances_naive[i], 1e-5);
+  //  }
+  //}
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/ridge_regression_test.cc
===================================================================
--- mlpack/trunk/src/mlpack/tests/ridge_regression_test.cc	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/ridge_regression_test.cc	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,91 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ridge_regression_test.cc
+ *
+ *    Description:
+ *
+ *        Version:  1.0
+ *        Created:  02/15/2009 01:34:25 PM EST
+ *       Revision:  none
+ *       Compiler:  gcc
+ *
+ *         Author:  Nikolaos Vasiloglou (NV), nvasil at ieee.org
+ *        Company:  Georgia Tech Fastlab-ESP Lab
+ *
+ * =====================================================================================
+ */
+#include <mlpack/core.h>
+#include <mlpack/methods/regression/ridge_regression.h>
+#include <mlpack/methods/regression/ridge_regression_util.h>
+
+#include <iostream>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+using namespace regression;
+
+BOOST_AUTO_TEST_SUITE(RidgeRegressoinTest);
+
+  /*
+  BOOST_AUTO_TEST_CASE(TestSVDNormalEquationRegressVersusSVDRegress) {
+
+    arma::mat predictors_ = "1.2 4.2 2.1 0.3 4.2;"
+                            "3.1 1.1 4.7 1.8 0.4;"
+                            "2.5 3.3 9.1 7.4 0.1";
+    arma::mat predictions_ = "0.4 0.33 0.8 1.4 3.3";
+    arma::mat true_factors_ = "0; 0; 0";
+
+    RidgeRegression engine_(predictors_, predictions_, true);
+    engine_.SVDRegress(0);
+    RidgeRegression svd_engine(predictors_, predictions_, false);
+    svd_engine.SVDRegress(0);
+    arma::mat factors, svd_factors;
+
+    engine_.factors(&factors);
+    svd_engine.factors(&svd_factors);
+
+    for(size_t i=0; i<factors.n_rows; i++) {
+      BOOST_REQUIRE_CLOSE(factors(i, 0), svd_factors(i, 0), 1e-5);
+    }
+  }
+  */
+
+  BOOST_AUTO_TEST_CASE(TestVIFBasedFeatureSelection) {
+    // Craft a synthetic dataset in which the third dimension is
+    // completely dependent on the first and the second.
+    arma::mat synthetic_data;
+    arma::mat synthetic_data_target_training_values;
+    synthetic_data.zeros(4, 5);
+    synthetic_data_target_training_values.zeros(1, 5);
+    for(size_t i = 0; i < 5; i++) {
+      synthetic_data(0, i) = i;
+      synthetic_data(1, i) = 3 * i + 1;
+      synthetic_data(2, i) = 4;
+      synthetic_data(3, i) = 5;
+      synthetic_data_target_training_values(0, i) = i;
+    }
+    arma::Col<size_t> predictor_indices;
+    arma::Col<size_t> prune_predictor_indices;
+    arma::Col<size_t> output_predictor_indices;
+    predictor_indices.zeros(4);
+    predictor_indices[0] = 0;
+    predictor_indices[1] = 1;
+    predictor_indices[2] = 2;
+    predictor_indices[3] = 3;
+    prune_predictor_indices = predictor_indices;
+    RidgeRegression engine_(synthetic_data, predictor_indices,
+                            synthetic_data_target_training_values);
+    engine_.FeatureSelectedRegression(predictor_indices,
+                                      prune_predictor_indices,
+                                      synthetic_data_target_training_values,
+                                      &output_predictor_indices);
+    std::cout << "Output indices: ";
+    for(size_t i = 0; i < output_predictor_indices.n_elem; i++) {
+      std::cout << output_predictor_indices[i] << ' ';
+    }
+    std::cout << std::endl;
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/save_restore_utility_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/save_restore_utility_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/save_restore_utility_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,151 @@
+/***
+ * @file save_restore_model_test.cpp
+ * @author Neil Slagle
+ *
+ * Here we have tests for the SaveRestoreModel class.
+ */
+
+#include <mlpack/core/utilities/save_restore_utility.hpp>
+
+#include <boost/test/unit_test.hpp>
+#define ARGSTR(a) a,#a
+
+BOOST_AUTO_TEST_SUITE(SaveRestoreUtilityTests);
+
+  /***
+   * Exhibit proper save restore utility usage
+   *  of child class proper usage
+   */
+  class SaveRestoreTest
+  {
+    private:
+      size_t anInt;
+      SaveRestoreUtility saveRestore;
+    public:
+      SaveRestoreTest()
+      {
+        saveRestore = SaveRestoreUtility();
+      }
+      bool SaveModel (std::string filename)
+      {
+        saveRestore.SaveParameter (anInt, "anInt");
+        return saveRestore.WriteFile (filename);
+      }
+      bool LoadModel (std::string filename)
+      {
+        bool success = saveRestore.ReadFile (filename);
+        if (success)
+        {
+          anInt = saveRestore.LoadParameter (anInt, "anInt");
+        }
+        return success;
+      }
+      const size_t AnInt () { return anInt; }
+      void AnInt (size_t s) { this->anInt = s; }
+  };
+
+  /***
+   * Perform a save and restore on basic types.
+   */
+  BOOST_AUTO_TEST_CASE(save_basic_types)
+  {
+    bool b = false;
+    char c = 67;
+    unsigned u = 34;
+    size_t s = 12;
+    short sh = 100;
+    int i = -23;
+    float f = -2.34f;
+    double d = 3.14159;
+    std::string cc = "Hello world!";
+
+    SaveRestoreUtility* sRM = new SaveRestoreUtility();
+
+    sRM->SaveParameter (ARGSTR(b));
+    sRM->SaveParameter (ARGSTR(c));
+    sRM->SaveParameter (ARGSTR(u));
+    sRM->SaveParameter (ARGSTR(s));
+    sRM->SaveParameter (ARGSTR(sh));
+    sRM->SaveParameter (ARGSTR(i));
+    sRM->SaveParameter (ARGSTR(f));
+    sRM->SaveParameter (ARGSTR(d));
+    sRM->SaveParameter (ARGSTR(cc));
+    sRM->WriteFile ("test_basic_types.xml");
+
+    sRM->ReadFile ("test_basic_types.xml");
+
+    bool b2 =         sRM->LoadParameter (ARGSTR(b));
+    char c2 =         sRM->LoadParameter (ARGSTR(c));
+    unsigned u2 =     sRM->LoadParameter (ARGSTR(u));
+    size_t s2 =       sRM->LoadParameter (ARGSTR(s));
+    short sh2 =       sRM->LoadParameter (ARGSTR(sh));
+    int i2 =          sRM->LoadParameter (ARGSTR(i));
+    float f2 =        sRM->LoadParameter (ARGSTR(f));
+    double d2 =       sRM->LoadParameter (ARGSTR(d));
+    std::string cc2 = sRM->LoadParameter (ARGSTR(cc));
+
+    BOOST_REQUIRE (b == b2);
+    BOOST_REQUIRE (c == c2);
+    BOOST_REQUIRE (u == u2);
+    BOOST_REQUIRE (s == s2);
+    BOOST_REQUIRE (sh == sh2);
+    BOOST_REQUIRE (i == i2);
+    BOOST_REQUIRE (cc == cc2);
+    BOOST_REQUIRE_CLOSE (f, f2, 1e-5);
+    BOOST_REQUIRE_CLOSE (d, d2, 1e-5);
+
+    delete sRM;
+  }
+
+  /***
+   * Test the arma::mat functionality.
+   */
+  BOOST_AUTO_TEST_CASE(save_arma_mat)
+  {
+    arma::mat matrix;
+    matrix <<  1.2 << 2.3 << -0.1 << arma::endr
+           <<  3.5 << 2.4 << -1.2 << arma::endr
+           << -0.1 << 3.4 << -7.8 << arma::endr;
+    SaveRestoreUtility* sRM = new SaveRestoreUtility();
+
+    sRM->SaveParameter (ARGSTR (matrix));
+
+    sRM->WriteFile ("test_arma_mat_type.xml");
+
+    sRM->ReadFile ("test_arma_mat_type.xml");
+
+    arma::mat matrix2 = sRM->LoadParameter (ARGSTR (matrix));
+
+    for (size_t row = 0; row < matrix.n_rows; ++row)
+    {
+      for (size_t column = 0; column < matrix.n_cols; ++column)
+      {
+        BOOST_REQUIRE_CLOSE(matrix(row,column), matrix2(row,column), 1e-5);
+      }
+    }
+
+    delete sRM;
+  }
+  /***
+   * Test SaveRestoreModel proper usage in child classes and loading from
+   *   separately defined objects
+   */
+  BOOST_AUTO_TEST_CASE(save_restore_model_child_class_usage)
+  {
+    SaveRestoreTest* saver = new SaveRestoreTest();
+    SaveRestoreTest* loader = new SaveRestoreTest();
+    size_t s = 1200;
+    const char* filename = "anInt.xml";
+
+    saver->AnInt (s);
+    saver->SaveModel (filename);
+    delete saver;
+
+    loader->LoadModel (filename);
+
+    BOOST_REQUIRE (loader->AnInt () == s);
+
+    delete loader;
+  }
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/svm_test.cc
===================================================================
--- mlpack/trunk/src/mlpack/tests/svm_test.cc	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/svm_test.cc	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,148 @@
+#include <mlpack/core.h>
+
+#include <mlpack/methods/svm/svm.h>
+
+#include <boost/test/unit_test.hpp>
+
+using std::string;
+using namespace mlpack;
+using namespace mlpack::svm;
+
+// Create test data
+arma::mat matrix(20,3);
+bool first = true;
+
+/***
+ *
+ */
+/*
+BOOST_AUTO_TEST_CASE(test_test) {
+  double x = 1.0, y = 1.0, z = 2.0;
+
+  // We need to make sure someValue is 1.
+  BOOST_REQUIRE_CLOSE(x, y, 1e-5);
+  BOOST_REQUIRE_CLOSE(z, y, 1e-5);
+}
+*/
+
+  //CLI::GetParam<>() = ;
+
+/**
+ *  Creates the data to train and test with and prints it to stdout.
+ *  Should only have any effect once.
+ */
+void setup() {
+  if(!first)
+    return;
+  first = false;
+
+  CLI::GetParam<bool>("svm/shrink") = true;
+  CLI::GetParam<double>("svm/epsilon") = .1;
+  CLI::GetParam<double>("svm/sigma") = 1;
+  // Protect the test from taking forever
+  CLI::GetParam<size_t>("svm/n_iter") = 10000;
+
+  matrix <<
+    7.19906628001437787e-01 << 1.83250823399634477e+00 << 0 << arma::endr <<
+    1.37899419263889733e+01 << 1.78198235122579263e+00 << 1 << arma::endr <<
+    6.68859485848275703e-01 << 2.14083320956715983e+00 << 0 << arma::endr <<
+    1.84729928795588165e+01 << 2.25024702760868101e+00 << 1 << arma::endr <<
+    9.22802773268335819e-01 << 1.61469358350834513e+00 << 0 << arma::endr <<
+    2.06209849662245204e-01 << 6.34699695340683490e-01 << 1 << arma::endr <<
+    4.01062068250524817e-01 << 1.65802752932441777e+00 << 0 << arma::endr <<
+    5.02985607135568635e+00 << 1.39976642741810831e+00 << 1 << arma::endr <<
+    3.66471199955079319e-01 << 1.62780588172739638e+00 << 0 << arma::endr <<
+    1.56912570240400999e+01 << 2.16941541650770953e+00 << 1 << arma::endr <<
+    9.98909584711729304e-01 << 2.00337906391517206e+00 << 0 << arma::endr <<
+    1.31430438780891912e+01 << 1.34410346059319719e+00 << 1 << arma::endr <<
+    3.41572957272442523e-01 << 1.16758463655951639e+00 << 0 << arma::endr <<
+    9.53941410851637528e-01 << 6.30271704462483373e-01 << 1 << arma::endr <<
+    7.07135529120981432e-01 << 2.17763537339756041e+00 << 0 << arma::endr <<
+    9.68899714280338742e+00 << 1.26922579378319256e+00 << 1 << arma::endr <<
+    9.82393905512240706e-01 << 2.36790583090293483e+00 << 0 << arma::endr <<
+    1.31583349281727973e+01 << 1.45115094722767868e+00 << 1 << arma::endr <<
+    3.80991188521027202e-01 << 9.05379134419085019e-01 << 0 << arma::endr <<
+    1.86057436180327755e+01 << 2.26941891469499968e+00 << 1 << arma::endr;
+  matrix = trans(matrix);
+
+  std::cout << matrix << std::endl;
+}
+
+/**
+ *  Compares predicted values with known values to see if the prediction/training works.
+ *
+ *  @param: learner_typeid Magic number for selecting between classification and
+ *     regression.
+ *  @param: data The dataset with the data to predict with.
+ *  @param: svm The SVM class instance that has been trained for this data, et al.
+ */
+template<typename T>
+void verify(size_t learner_typeid, arma::mat& data, SVM<T>& svm) {
+  for(size_t i = 0; i < data.n_cols; i++) {
+    arma::vec testvec = data.col(i);
+
+    double predictedvalue = svm.Predict(learner_typeid, testvec);
+    BOOST_REQUIRE_CLOSE(predictedvalue,
+	data(data.n_rows-1,i),1e-6);
+  }
+}
+
+BOOST_AUTO_TEST_SUITE(SvmTest);
+
+  /**
+   *  Trains a classifier with a linear kernel and checks predictions against
+   *  classes.
+   */
+  //BOOST_AUTO_TEST_CASE(svm_classification_linear_kernel_test) {
+  //  setup();
+  //
+  //  arma::mat trainingdata;
+  //  trainingdata = matrix;
+  //  SVM<SVMLinearKernel> svm;
+  //  svm.InitTrain(0,trainingdata); // 0 for classification
+  //  verify(0,trainingdata,svm);
+  //}
+  //
+  /**
+   *  Trains a classifier with a gaussian kernel and checks predictions against
+   *  classes.
+   */
+  BOOST_AUTO_TEST_CASE(svm_classification_gaussian_kernel_test) {
+    setup();
+
+    arma::mat trainingdata;
+    trainingdata = matrix;
+    SVM<SVMRBFKernel> svm;
+    svm.InitTrain(0,trainingdata); // 0 for classification
+    verify(0,trainingdata,svm);
+  }
+
+  /**
+   *  Trains a classifier with a linear kernel and checks predictions against
+   *  classes, using regression. TODO: BROKEN
+   */
+  //BOOST_AUTO_TEST_CASE(svm_regression_linear_kernel_test) {
+  //  setup();
+  //
+  //  arma::mat trainingdata;
+  //  trainingdata = matrix;
+  //  SVM<SVMLinearKernel> svm;
+  //  svm.InitTrain(1,trainingdata); // 0 for classification
+  //  //verify(1,trainingdata,svm);
+  //}
+
+  /**
+   *  Trains a classifier with a gaussian kernel and checks predictions against
+   *  classes, using regression. TODO: BROKEN
+   */
+  //BOOST_AUTO_TEST_CASE(svm_regression_gaussian_kernel_test) {
+  //  setup();
+  //
+  //  arma::mat trainingdata;
+  //  trainingdata = matrix;
+  //  SVM<SVMRBFKernel> svm;
+  //  svm.InitTrain(1,trainingdata); // 0 for classification
+  //  //verify(1,trainingdata,svm);
+  //}
+
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/tree_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/tree_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/tree_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,1038 @@
+/**
+ * @file uselapack_test.cc
+ *
+ * Tests for LAPACK integration.
+ */
+
+#include <mlpack/core/tree/bounds.hpp>
+#include <mlpack/core/tree/binary_space_tree.hpp>
+#include <mlpack/core/kernels/lmetric.hpp>
+#include <vector>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+using namespace mlpack::math;
+using namespace mlpack::tree;
+using namespace mlpack::kernel;
+using namespace mlpack::bound;
+
+BOOST_AUTO_TEST_SUITE(TreeTest);
+  /***
+   * Ensure that a bound, by default, is empty and has no dimensionality.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundEmptyConstructor) {
+    HRectBound<2> b;
+
+    BOOST_REQUIRE_EQUAL(b.dim(), 0);
+  }
+
+  /***
+   * Ensure that when we specify the dimensionality in the constructor, it is
+   * correct, and the bounds are all the empty set.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundDimConstructor) {
+    HRectBound<2> b(2); // We'll do this with 2 and 5 dimensions.
+
+    BOOST_REQUIRE_EQUAL(b.dim(), 2);
+    BOOST_REQUIRE_SMALL(b[0].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(b[1].width(), 1e-5);
+
+    b = HRectBound<2>(5);
+
+    BOOST_REQUIRE_EQUAL(b.dim(), 5);
+    BOOST_REQUIRE_SMALL(b[0].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(b[1].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(b[2].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(b[3].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(b[4].width(), 1e-5);
+  }
+
+  /***
+   * Test the copy constructor.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundCopyConstructor) {
+    HRectBound<2> b(2);
+    b[0] = Range(0.0, 2.0);
+    b[1] = Range(2.0, 3.0);
+
+    HRectBound<2> c(b);
+
+    BOOST_REQUIRE_EQUAL(c.dim(), 2);
+    BOOST_REQUIRE_SMALL(c[0].lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[0].hi, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[1].lo, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[1].hi, 3.0, 1e-5);
+  }
+
+  /***
+   * Test the assignment operator.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundAssignmentOperator) {
+    HRectBound<2> b(2);
+    b[0] = Range(0.0, 2.0);
+    b[1] = Range(2.0, 3.0);
+
+    HRectBound<2> c(4);
+
+    c = b;
+
+    BOOST_REQUIRE_EQUAL(c.dim(), 2);
+    BOOST_REQUIRE_SMALL(c[0].lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[0].hi, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[1].lo, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[1].hi, 3.0, 1e-5);
+  }
+
+  /***
+   * Test that clearing the dimensions resets the bound to empty.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundClear) {
+    HRectBound<2> b(2); // We'll do this with two dimensions only.
+
+    b[0] = Range(0.0, 2.0);
+    b[1] = Range(2.0, 4.0);
+
+    // Now we just need to make sure that we clear the range.
+    b.Clear();
+
+    BOOST_REQUIRE_SMALL(b[0].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(b[1].width(), 1e-5);
+  }
+
+  /***
+   * Ensure that we get the correct centroid for our bound.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundCentroid) {
+    // Create a simple 3-dimensional bound.
+    HRectBound<2> b(3);
+
+    b[0] = Range(0.0, 5.0);
+    b[1] = Range(-2.0, -1.0);
+    b[2] = Range(-10.0, 50.0);
+
+    arma::vec centroid;
+
+    b.Centroid(centroid);
+
+    BOOST_REQUIRE_EQUAL(centroid.n_elem, 3);
+    BOOST_REQUIRE_CLOSE(centroid[0], 2.5, 1e-5);
+    BOOST_REQUIRE_CLOSE(centroid[1], -1.5, 1e-5);
+    BOOST_REQUIRE_CLOSE(centroid[2], 20.0, 1e-5);
+  }
+
+  /***
+   * Ensure that we calculate the correct minimum distance between a point and a
+   * bound.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundMinDistancePoint) {
+    // We'll do the calculation in five dimensions, and we'll use three cases for
+    // the point: point is outside the bound; point is on the edge of the bound;
+    // point is inside the bound.  In the latter two cases, the distance should be
+    // zero.
+    HRectBound<2> b(5);
+
+    b[0] = Range(0.0, 2.0);
+    b[1] = Range(1.0, 5.0);
+    b[2] = Range(-2.0, 2.0);
+    b[3] = Range(-5.0, -2.0);
+    b[4] = Range(1.0, 2.0);
+
+    arma::vec point = "-2.0 0.0 10.0 3.0 3.0";
+
+    // This will be the Euclidean squared distance.
+    BOOST_REQUIRE_CLOSE(b.MinDistance(point), 95.0, 1e-5);
+
+    point = "2.0 5.0 2.0 -5.0 1.0";
+
+    BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5);
+
+    point = "1.0 2.0 0.0 -2.0 1.5";
+
+    BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5);
+  }
+
+  /***
+   * Ensure that we calculate the correct minimum distance between a bound and
+   * another bound.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundMinDistanceBound) {
+    // We'll do the calculation in five dimensions, and we can use six cases.
+    // The other bound is completely outside the bound; the other bound is on the
+    // edge of the bound; the other bound partially overlaps the bound; the other
+    // bound fully overlaps the bound; the other bound is entirely inside the
+    // bound; the other bound entirely envelops the bound.
+    HRectBound<2> b(5);
+
+    b[0] = Range(0.0, 2.0);
+    b[1] = Range(1.0, 5.0);
+    b[2] = Range(-2.0, 2.0);
+    b[3] = Range(-5.0, -2.0);
+    b[4] = Range(1.0, 2.0);
+
+    HRectBound<2> c(5);
+
+    // The other bound is completely outside the bound.
+    c[0] = Range(-5.0, -2.0);
+    c[1] = Range(6.0, 7.0);
+    c[2] = Range(-2.0, 2.0);
+    c[3] = Range(2.0, 5.0);
+    c[4] = Range(3.0, 4.0);
+
+    BOOST_REQUIRE_CLOSE(b.MinDistance(c), 22.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c.MinDistance(b), 22.0, 1e-5);
+
+    // The other bound is on the edge of the bound.
+    c[0] = Range(-2.0, 0.0);
+    c[1] = Range(0.0, 1.0);
+    c[2] = Range(-3.0, -2.0);
+    c[3] = Range(-10.0, -5.0);
+    c[4] = Range(2.0, 3.0);
+
+    BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5);
+    BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5);
+
+    // The other bound partially overlaps the bound.
+    c[0] = Range(-2.0, 1.0);
+    c[1] = Range(0.0, 2.0);
+    c[2] = Range(-2.0, 2.0);
+    c[3] = Range(-8.0, -4.0);
+    c[4] = Range(0.0, 4.0);
+
+    BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5);
+    BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5);
+
+    // The other bound fully overlaps the bound.
+    BOOST_REQUIRE_SMALL(b.MinDistance(b), 1e-5);
+    BOOST_REQUIRE_SMALL(c.MinDistance(c), 1e-5);
+
+    // The other bound is entirely inside the bound / the other bound entirely
+    // envelops the bound.
+    c[0] = Range(-1.0, 3.0);
+    c[1] = Range(0.0, 6.0);
+    c[2] = Range(-3.0, 3.0);
+    c[3] = Range(-7.0, 0.0);
+    c[4] = Range(0.0, 5.0);
+
+    BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5);
+    BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5);
+  }
+
+  /***
+   * Ensure that we calculate the correct maximum distance between a bound and a
+   * point.  This uses the same test cases as the MinDistance test.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundMaxDistancePoint) {
+    // We'll do the calculation in five dimensions, and we'll use three cases for
+    // the point: point is outside the bound; point is on the edge of the bound;
+    // point is inside the bound.  In the latter two cases, the distance should be
+    // zero.
+    HRectBound<2> b(5);
+
+    b[0] = Range(0.0, 2.0);
+    b[1] = Range(1.0, 5.0);
+    b[2] = Range(-2.0, 2.0);
+    b[3] = Range(-5.0, -2.0);
+    b[4] = Range(1.0, 2.0);
+
+    arma::vec point = "-2.0 0.0 10.0 3.0 3.0";
+
+    // This will be the Euclidean squared distance.
+    BOOST_REQUIRE_CLOSE(b.MaxDistance(point), 253.0, 1e-5);
+
+    point = "2.0 5.0 2.0 -5.0 1.0";
+
+    BOOST_REQUIRE_CLOSE(b.MaxDistance(point), 46.0, 1e-5);
+
+    point = "1.0 2.0 0.0 -2.0 1.5";
+
+    BOOST_REQUIRE_CLOSE(b.MaxDistance(point), 23.25, 1e-5);
+  }
+
+  /***
+   * Ensure that we calculate the correct maximum distance between a bound and
+   * another bound.  This uses the same test cases as the MinDistance test.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundMaxDistanceBound) {
+    // We'll do the calculation in five dimensions, and we can use six cases.
+    // The other bound is completely outside the bound; the other bound is on the
+    // edge of the bound; the other bound partially overlaps the bound; the other
+    // bound fully overlaps the bound; the other bound is entirely inside the
+    // bound; the other bound entirely envelops the bound.
+    HRectBound<2> b(5);
+
+    b[0] = Range(0.0, 2.0);
+    b[1] = Range(1.0, 5.0);
+    b[2] = Range(-2.0, 2.0);
+    b[3] = Range(-5.0, -2.0);
+    b[4] = Range(1.0, 2.0);
+
+    HRectBound<2> c(5);
+
+    // The other bound is completely outside the bound.
+    c[0] = Range(-5.0, -2.0);
+    c[1] = Range(6.0, 7.0);
+    c[2] = Range(-2.0, 2.0);
+    c[3] = Range(2.0, 5.0);
+    c[4] = Range(3.0, 4.0);
+
+    BOOST_REQUIRE_CLOSE(b.MaxDistance(c), 210.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c.MaxDistance(b), 210.0, 1e-5);
+
+    // The other bound is on the edge of the bound.
+    c[0] = Range(-2.0, 0.0);
+    c[1] = Range(0.0, 1.0);
+    c[2] = Range(-3.0, -2.0);
+    c[3] = Range(-10.0, -5.0);
+    c[4] = Range(2.0, 3.0);
+
+    BOOST_REQUIRE_CLOSE(b.MaxDistance(c), 134.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c.MaxDistance(b), 134.0, 1e-5);
+
+    // The other bound partially overlaps the bound.
+    c[0] = Range(-2.0, 1.0);
+    c[1] = Range(0.0, 2.0);
+    c[2] = Range(-2.0, 2.0);
+    c[3] = Range(-8.0, -4.0);
+    c[4] = Range(0.0, 4.0);
+
+    BOOST_REQUIRE_CLOSE(b.MaxDistance(c), 102.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c.MaxDistance(b), 102.0, 1e-5);
+
+    // The other bound fully overlaps the bound.
+    BOOST_REQUIRE_CLOSE(b.MaxDistance(b), 46.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c.MaxDistance(c), 61.0, 1e-5);
+
+    // The other bound is entirely inside the bound / the other bound entirely
+    // envelops the bound.
+    c[0] = Range(-1.0, 3.0);
+    c[1] = Range(0.0, 6.0);
+    c[2] = Range(-3.0, 3.0);
+    c[3] = Range(-7.0, 0.0);
+    c[4] = Range(0.0, 5.0);
+
+    BOOST_REQUIRE_CLOSE(b.MaxDistance(c), 100.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c.MaxDistance(b), 100.0, 1e-5);
+
+    // One last additional case.  If the bound encloses only one point, the
+    // maximum distance between it and itself is 0.
+    HRectBound<2> d(2);
+
+    d[0] = Range(2.0, 2.0);
+    d[1] = Range(3.0, 3.0);
+
+    BOOST_REQUIRE_SMALL(d.MaxDistance(d), 1e-5);
+  }
+
+  /***
+   * Ensure that the ranges returned by RangeDistance() are equal to the minimum
+   * and maximum distance.  We will perform this test by creating random bounds
+   * and comparing the behavior to MinDistance() and MaxDistance() -- so this test
+   * is assuming that those passed and operate correctly.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundRangeDistanceBound) {
+    srand(time(NULL));
+
+    for (int i = 0; i < 50; i++) {
+      size_t dim = rand() % 20;
+
+      HRectBound<2> a(dim);
+      HRectBound<2> b(dim);
+
+      // We will set the low randomly and the width randomly for each dimension of
+      // each bound.
+      arma::vec lo_a(dim);
+      arma::vec width_a(dim);
+
+      lo_a.randu();
+      width_a.randu();
+
+      arma::vec lo_b(dim);
+      arma::vec width_b(dim);
+
+      lo_b.randu();
+      width_b.randu();
+
+      for (size_t j = 0; j < dim; j++) {
+        a[j] = Range(lo_a[j], lo_a[j] + width_a[j]);
+        b[j] = Range(lo_b[j], lo_b[j] + width_b[j]);
+      }
+
+      // Now ensure that MinDistance and MaxDistance report the same.
+      Range r = a.RangeDistance(b);
+      Range s = b.RangeDistance(a);
+
+      BOOST_REQUIRE_CLOSE(r.lo, s.lo, 1e-5);
+      BOOST_REQUIRE_CLOSE(r.hi, s.hi, 1e-5);
+
+      BOOST_REQUIRE_CLOSE(r.lo, a.MinDistance(b), 1e-5);
+      BOOST_REQUIRE_CLOSE(r.hi, a.MaxDistance(b), 1e-5);
+
+      BOOST_REQUIRE_CLOSE(s.lo, b.MinDistance(a), 1e-5);
+      BOOST_REQUIRE_CLOSE(s.hi, b.MaxDistance(a), 1e-5);
+    }
+  }
+
+  /***
+   * Ensure that the ranges returned by RangeDistance() are equal to the minimum
+   * and maximum distance.  We will perform this test by creating random bounds
+   * and comparing the bheavior to MinDistance() and MaxDistance() -- so this test
+   * is assuming that those passed and operate correctly.  This is for the
+   * bound-to-point case.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundRangeDistancePoint) {
+    srand(time(NULL));
+
+    for (int i = 0; i < 20; i++) {
+      size_t dim = rand() % 20;
+
+      HRectBound<2> a(dim);
+
+      // We will set the low randomly and the width randomly for each dimension of
+      // each bound.
+      arma::vec lo_a(dim);
+      arma::vec width_a(dim);
+
+      lo_a.randu();
+      width_a.randu();
+
+      for (size_t j = 0; j < dim; j++)
+        a[j] = Range(lo_a[j], lo_a[j] + width_a[j]);
+
+      // Now run the test on a few points.
+      for (int j = 0; j < 10; j++) {
+        arma::vec point(dim);
+
+        point.randu();
+
+        Range r = a.RangeDistance(point);
+
+        BOOST_REQUIRE_CLOSE(r.lo, a.MinDistance(point), 1e-5);
+        BOOST_REQUIRE_CLOSE(r.hi, a.MaxDistance(point), 1e-5);
+      }
+    }
+  }
+
+  /***
+   * Test that we can expand the bound to include a new point.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundOrOperatorPoint) {
+    // Because this should be independent in each dimension, we can essentially
+    // run five test cases at once.
+    HRectBound<2> b(5);
+
+    b[0] = Range(1.0, 3.0);
+    b[1] = Range(2.0, 4.0);
+    b[2] = Range(-2.0, -1.0);
+    b[3] = Range(0.0, 0.0);
+    b[4] = Range(); // Empty range.
+
+    arma::vec point = "2.0 4.0 2.0 -1.0 6.0";
+
+    b |= point;
+
+    BOOST_REQUIRE_CLOSE(b[0].lo, 1.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[0].hi, 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[1].lo, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[1].hi, 4.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[2].lo, -2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[2].hi, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[3].lo, -1.0, 1e-5);
+    BOOST_REQUIRE_SMALL(b[3].hi, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[4].lo, 6.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[4].hi, 6.0, 1e-5);
+  }
+
+  /***
+   * Test that we can expand the bound to include another bound.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundOrOperatorBound) {
+    // Because this should be independent in each dimension, we can run many tests
+    // at once.
+    HRectBound<2> b(8);
+
+    b[0] = Range(1.0, 3.0);
+    b[1] = Range(2.0, 4.0);
+    b[2] = Range(-2.0, -1.0);
+    b[3] = Range(4.0, 5.0);
+    b[4] = Range(2.0, 4.0);
+    b[5] = Range(0.0, 0.0);
+    b[6] = Range();
+    b[7] = Range(1.0, 3.0);
+
+    HRectBound<2> c(8);
+
+    c[0] = Range(-3.0, -1.0); // Entirely less than the other bound.
+    c[1] = Range(0.0, 2.0); // Touching edges.
+    c[2] = Range(-3.0, -1.5); // Partially overlapping.
+    c[3] = Range(4.0, 5.0); // Identical.
+    c[4] = Range(1.0, 5.0); // Entirely enclosing.
+    c[5] = Range(2.0, 2.0); // A single point.
+    c[6] = Range(1.0, 3.0);
+    c[7] = Range(); // Empty set.
+
+    HRectBound<2> d = c;
+
+    b |= c;
+    d |= b;
+
+    BOOST_REQUIRE_CLOSE(b[0].lo, -3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[0].hi, 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[0].lo, -3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[0].hi, 3.0, 1e-5);
+
+    BOOST_REQUIRE_CLOSE(b[1].lo, 0.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[1].hi, 4.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[1].lo, 0.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[1].hi, 4.0, 1e-5);
+
+    BOOST_REQUIRE_CLOSE(b[2].lo, -3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[2].hi, -1.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[2].lo, -3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[2].hi, -1.0, 1e-5);
+
+    BOOST_REQUIRE_CLOSE(b[3].lo, 4.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[3].hi, 5.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[3].lo, 4.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[3].hi, 5.0, 1e-5);
+
+    BOOST_REQUIRE_CLOSE(b[4].lo, 1.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[4].hi, 5.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[4].lo, 1.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[4].hi, 5.0, 1e-5);
+
+    BOOST_REQUIRE_SMALL(b[5].lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[5].hi, 2.0, 1e-5);
+    BOOST_REQUIRE_SMALL(d[5].lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[5].hi, 2.0, 1e-5);
+
+    BOOST_REQUIRE_CLOSE(b[6].lo, 1.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[6].hi, 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[6].lo, 1.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[6].hi, 3.0, 1e-5);
+
+    BOOST_REQUIRE_CLOSE(b[7].lo, 1.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b[7].hi, 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[7].lo, 1.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d[7].hi, 3.0, 1e-5);
+  }
+
+  /***
+   * Test that the Contains() function correctly figures out whether or not a
+   * point is in a bound.
+   */
+  BOOST_AUTO_TEST_CASE(HRectBoundContains) {
+    // We can test a couple different points: completely outside the bound,
+    // adjacent in one dimension to the bound, adjacent in all dimensions to the
+    // bound, and inside the bound.
+    HRectBound<2> b(3);
+
+    b[0] = Range(0.0, 2.0);
+    b[1] = Range(0.0, 2.0);
+    b[2] = Range(0.0, 2.0);
+
+    // Completely outside the range.
+    arma::vec point = "-1.0 4.0 4.0";
+    BOOST_REQUIRE(!b.Contains(point));
+
+    // Completely outside, but one dimension is in the range.
+    point = "-1.0 4.0 1.0";
+    BOOST_REQUIRE(!b.Contains(point));
+
+    // Outside, but one dimension is on the edge.
+    point = "-1.0 0.0 3.0";
+    BOOST_REQUIRE(!b.Contains(point));
+
+    // Two dimensions are on the edge, but one is outside.
+    point = "0.0 0.0 3.0";
+    BOOST_REQUIRE(!b.Contains(point));
+
+    // Completely on the edge (should be contained).
+    point = "0.0 0.0 0.0";
+    BOOST_REQUIRE(b.Contains(point));
+
+    // Inside the range.
+    point = "0.3 1.0 0.4";
+    BOOST_REQUIRE(b.Contains(point));
+  }
+
+  BOOST_AUTO_TEST_CASE(TestBallBound) {
+    DBallBound<> b1;
+    DBallBound<> b2;
+
+    // Create two balls with a center distance of 1 from each other.
+    // Give the first one a radius of 0.3 and the second a radius of 0.4.
+
+    b1.center().set_size(3);
+    b1.center()[0] = 1;
+    b1.center()[1] = 2;
+    b1.center()[2] = 3;
+    b1.set_radius(0.3);
+
+    b2.center().set_size(3);
+    b2.center()[0] = 1;
+    b2.center()[1] = 2;
+    b2.center()[2] = 4;
+    b2.set_radius(0.4);
+
+    BOOST_REQUIRE_CLOSE(sqrt(b1.MinDistanceSq(b2)), 1-0.3-0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b1.RangeDistanceSq(b2).hi), 1+0.3+0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b1.RangeDistanceSq(b2).lo), 1-0.3-0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(b1.RangeDistance(b2).hi, 1+0.3+0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(b1.RangeDistance(b2).lo, 1-0.3-0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b1.MinToMidSq(b2)), 1-0.3, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b1.MinimaxDistanceSq(b2)), 1-0.3+0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b1.MidDistanceSq(b2)), 1.0, 1e-5);
+
+    BOOST_REQUIRE_CLOSE(sqrt(b2.MinDistanceSq(b1)), 1-0.3-0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b2.MaxDistanceSq(b1)), 1+0.3+0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b2.RangeDistanceSq(b1).hi), 1+0.3+0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b2.RangeDistanceSq(b1).lo), 1-0.3-0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b2.MinToMidSq(b1)), 1-0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b2.MinimaxDistanceSq(b1)), 1-0.4+0.3, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b2.MidDistanceSq(b1)), 1.0, 1e-5);
+
+    BOOST_REQUIRE(b1.Contains(b1.center()));
+    BOOST_REQUIRE(!b1.Contains(b2.center()));
+
+    BOOST_REQUIRE(!b2.Contains(b1.center()));
+    BOOST_REQUIRE(b2.Contains(b2.center()));
+    arma::vec b2point(3); // a point that's within the radius bot not the center
+    b2point[0] = 1.1;
+    b2point[1] = 2.1;
+    b2point[2] = 4.1;
+
+    BOOST_REQUIRE(b2.Contains(b2point));
+
+    BOOST_REQUIRE_SMALL(sqrt(b1.MinDistanceSq(b1.center())), 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b1.MinDistanceSq(b2.center())), 1 - 0.3, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b2.MinDistanceSq(b1.center())), 1 - 0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b2.MaxDistanceSq(b1.center())), 1 + 0.4, 1e-5);
+    BOOST_REQUIRE_CLOSE(sqrt(b1.MaxDistanceSq(b2.center())), 1 + 0.3, 1e-5);
+  }
+
+  /***
+   * Ensure that a bound, by default, is empty and has no dimensionality, and the
+   * box size vector is empty.
+   */
+  BOOST_AUTO_TEST_CASE(PeriodicHRectBoundEmptyConstructor) {
+    PeriodicHRectBound<2> b;
+
+    BOOST_REQUIRE_EQUAL(b.dim(), 0);
+    BOOST_REQUIRE_EQUAL(b.box().n_elem, 0);
+  }
+
+  /***
+   * Ensure that when we specify the dimensionality in the constructor, it is
+   * correct, and the bounds are all the empty set.
+   */
+  BOOST_AUTO_TEST_CASE(PeriodicHRectBoundBoxConstructor) {
+    PeriodicHRectBound<2> b(arma::vec("5 6"));
+
+    BOOST_REQUIRE_EQUAL(b.dim(), 2);
+    BOOST_REQUIRE_SMALL(b[0].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(b[1].width(), 1e-5);
+    BOOST_REQUIRE_EQUAL(b.box().n_elem, 2);
+    BOOST_REQUIRE_CLOSE(b.box()[0], 5.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b.box()[1], 6.0, 1e-5);
+
+    PeriodicHRectBound<2> d(arma::vec("2 3 4 5 6"));
+
+    BOOST_REQUIRE_EQUAL(d.dim(), 5);
+    BOOST_REQUIRE_SMALL(d[0].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(d[1].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(d[2].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(d[3].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(d[4].width(), 1e-5);
+    BOOST_REQUIRE_EQUAL(d.box().n_elem, 5);
+    BOOST_REQUIRE_CLOSE(d.box()[0], 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d.box()[1], 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d.box()[2], 4.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d.box()[3], 5.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(d.box()[4], 6.0, 1e-5);
+  }
+
+  /***
+   * Test the copy constructor.
+   *
+  BOOST_AUTO_TEST_CASE(PeriodicHRectBoundCopyConstructor) {
+    PeriodicHRectBound<2> b(arma::vec("3 4"));
+    b[0] = Range(0.0, 2.0);
+    b[1] = Range(2.0, 3.0);
+
+    PeriodicHRectBound<2> c(b);
+
+    BOOST_REQUIRE_EQUAL(c.dim(), 2);
+    BOOST_REQUIRE_SMALL(c[0].lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[0].hi, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[1].lo, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[1].hi, 3.0, 1e-5);
+    BOOST_REQUIRE_EQUAL(c.box().n_elem, 2);
+    BOOST_REQUIRE_CLOSE(c.box()[0], 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c.box()[1], 4.0, 1e-5);
+  }*/
+
+  /***
+   * Test the assignment operator.
+   *
+  BOOST_AUTO_TEST_CASE(PeriodicHRectBoundAssignmentOperator) {
+    PeriodicHRectBound<2> b(arma::vec("3 4"));
+    b[0] = Range(0.0, 2.0);
+    b[1] = Range(2.0, 3.0);
+
+    PeriodicHRectBound<2> c(arma::vec("3 4 5 6"));
+
+    c = b;
+
+    BOOST_REQUIRE_EQUAL(c.dim(), 2);
+    BOOST_REQUIRE_SMALL(c[0].lo, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[0].hi, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[1].lo, 2.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c[1].hi, 3.0, 1e-5);
+    BOOST_REQUIRE_EQUAL(c.box().n_elem, 2);
+    BOOST_REQUIRE_CLOSE(c.box()[0], 3.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(c.box()[1], 4.0, 1e-5);
+  }*/
+
+  /***
+   * Ensure that we can set the box size correctly.
+   *
+  BOOST_AUTO_TEST_CASE(PeriodicHRectBoundSetBoxSize) {
+    PeriodicHRectBound<2> b(arma::vec("1 2"));
+
+    b.SetBoxSize(arma::vec("10 12"));
+
+    BOOST_REQUIRE_EQUAL(b.box().n_elem, 2);
+    BOOST_REQUIRE_CLOSE(b.box()[0], 10.0, 1e-5);
+    BOOST_REQUIRE_CLOSE(b.box()[1], 12.0, 1e-5);
+  }*/
+
+  /***
+   * Ensure that we can clear the dimensions correctly.  This does not involve the
+   * box size at all, so the test can be identical to the HRectBound test.
+   *
+  BOOST_AUTO_TEST_CASE(PeriodicHRectBoundClear) {
+    // We'll do this with two dimensions only.
+    PeriodicHRectBound<2> b(arma::vec("5 5"));
+
+    b[0] = Range(0.0, 2.0);
+    b[1] = Range(2.0, 4.0);
+
+    // Now we just need to make sure that we clear the range.
+    b.Clear();
+
+    BOOST_REQUIRE_SMALL(b[0].width(), 1e-5);
+    BOOST_REQUIRE_SMALL(b[1].width(), 1e-5);
+  }*/
+
+  /***
+   * Ensure that we get the correct centroid for our bound.
+   *
+  BOOST_AUTO_TEST_CASE(PeriodicHRectBoundCentroid) {
+    // Create a simple 3-dimensional bound.  The centroid is not affected by the
+    // periodic coordinates.
+    PeriodicHRectBound<2> b(arma::vec("100 100 100"));
+
+    b[0] = Range(0.0, 5.0);
+    b[1] = Range(-2.0, -1.0);
+    b[2] = Range(-10.0, 50.0);
+
+    arma::vec centroid;
+
+    b.Centroid(centroid);
+
+    BOOST_REQUIRE_EQUAL(centroid.n_elem, 3);
+    BOOST_REQUIRE_CLOSE(centroid[0], 2.5, 1e-5);
+    BOOST_REQUIRE_CLOSE(centroid[1], -1.5, 1e-5);
+    BOOST_REQUIRE_CLOSE(centroid[2], 20.0, 1e-5);
+  }*/
+
+  /***
+   * Correctly calculate the minimum distance between the bound and a point in
+   * periodic coordinates.  We have to account for the shifts necessary in
+   * periodic coordinates too, so that makes testing this a little more difficult.
+   *
+  BOOST_AUTO_TEST_CASE(PeriodicHRectBoundMinDistancePoint) {
+    // First, we'll start with a simple 2-dimensional case where the point is
+    // inside the bound, then on the edge of the bound, then barely outside the
+    // bound.  The box size will be large enough that this is basically the
+    // HRectBound case.
+    PeriodicHRectBound<2> b(arma::vec("100 100"));
+
+    b[0] = Range(0.0, 5.0);
+    b[1] = Range(2.0, 4.0);
+
+    // Inside the bound.
+    arma::vec point = "2.5 3.0";
+
+    BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5);
+
+    // On the edge.
+    point = "5.0 4.0";
+
+    BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5);
+
+    // And just a little outside the bound.
+    point = "6.0 5.0";
+
+    BOOST_REQUIRE_CLOSE(b.MinDistance(point), 2.0, 1e-5);
+
+    // Now we start to invoke the periodicity.  This point will "alias" to (-1,
+    // -1).
+    point = "99.0 99.0";
+
+    BOOST_REQUIRE_CLOSE(b.MinDistance(point), 10.0, 1e-5);
+
+    // We will perform several tests on a one-dimensional bound.
+    b = PeriodicHRectBound<2>(arma::vec("5.0"));
+    point.set_size(1);
+
+    b[0] = Range("2.0 4.0"); // Entirely inside box.
+    point[0] = 7.5; // Inside first right image of the box.
+
+    BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5);
+
+    b[0] = Range("0.0 5.0"); // Fills box fully.
+    point[1] = 19.3; // Inside the box, which covers everything.
+
+    BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5);
+
+    b[0] = Range("-10.0 10.0"); // Larger than the box.
+    point[0] = -500.0; // Inside the box, which covers everything.
+
+    BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5);
+
+    b[0] = Range("-2.0 1.0"); // Crosses over an edge.
+    point[0] = 2.9; // The first right image of the bound starts at 3.0.
+
+    BOOST_REQUIRE_CLOSE(b.MinDistance(point), 0.01, 1e-5);
+
+    b[0] = Range("2.0 4.0"); // Inside box.
+    point[0] = 0.0; // Closest to the first left image of the bound.
+
+    BOOST_REQUIRE_CLOSE(b.MinDistance(point), 1.0, 1e-5);
+
+    b[0] = Range("0.0 2.0"); // On edge of box.
+    point[0] = 7.1; // 0.1 away from the first right image of the bound.
+
+    BOOST_REQUIRE_CLOSE(b.MinDistance(point), 0.01, 1e-5);
+
+    b[0] = Range("-10.0 10.0"); // Box is of infinite size.
+    point[0] = 810.0; // 800 away from the only image of the box.
+
+    BOOST_REQUIRE_CLOSE(b.MinDistance(point), 640000, 1e-5);
+
+    b[0] = Range("2.0 4.0"); // Box size of -5 should function the same as 5.
+    point[0] = -10.8; // Should alias to 4.2.
+
+    BOOST_REQUIRE_CLOSE(b.MinDistance(point), 0.04, 1e-5);
+
+    // Switch our bound to a higher dimensionality.  This should ensure that the
+    // dimensions are independent like they should be.
+    b = PeriodicHRectBound<2>(arma::vec("5.0 5.0 5.0 5.0 5.0 5.0 0.0 -5.0"));
+
+    b[0] = Range("2.0 4.0"); // Entirely inside box.
+    b[1] = Range("0.0 5.0"); // Fills box fully.
+    b[2] = Range("-10.0 10.0"); // Larger than the box.
+    b[3] = Range("-2.0 1.0"); // Crosses over an edge.
+    b[4] = Range("2.0 4.0"); // Inside box.
+    b[5] = Range("0.0 2.0"); // On edge of box.
+    b[6] = Range("-10.0 10.0"); // Box is of infinite size.
+    b[7] = Range("2.0 4.0"); // Box size of -5 should function the same as 5.
+
+    point.set_size(8);
+    point[0] = 7.5; // Inside first right image of the box.
+    point[1] = 19.3; // Inside the box, which covers everything.
+    point[2] = -500.0; // Inside the box, which covers everything.
+    point[3] = 2.9; // The first right image of the bound starts at 3.0.
+    point[4] = 0.0; // Closest to the first left image of the bound.
+    point[5] = 7.1; // 0.1 away from the first right image of the bound.
+    point[6] = 810.0; // 800 away from the only image of the box.
+    point[7] = -10.8; // Should alias to 4.2.
+
+    BOOST_REQUIRE_CLOSE(b.MinDistance(point), 640001.06, 1e-10);
+  }*/
+
+  /***
+   * It seems as though Bill has stumbled across a bug where
+   * BinarySpaceTree<>::count() returns something different than
+   * BinarySpaceTree<>::count_.  So, let's build a simple tree and make sure they
+   * are the same.
+   */
+  BOOST_AUTO_TEST_CASE(tree_count_mismatch) {
+    arma::mat dataset = "2.0 5.0 9.0 4.0 8.0 7.0;"
+                        "3.0 4.0 6.0 7.0 1.0 2.0 ";
+
+    // Leaf size of 1.
+    CLI::GetParam<int>("tree/leaf_size") = 1;
+    BinarySpaceTree<HRectBound<2> > root_node(dataset);
+
+    BOOST_REQUIRE(root_node.count() == 6);
+    BOOST_REQUIRE(root_node.left()->count() == 3);
+    BOOST_REQUIRE(root_node.left()->left()->count() == 2);
+    BOOST_REQUIRE(root_node.left()->left()->left()->count() == 1);
+    BOOST_REQUIRE(root_node.left()->left()->right()->count() == 1);
+    BOOST_REQUIRE(root_node.left()->right()->count() == 1);
+    BOOST_REQUIRE(root_node.right()->count() == 3);
+    BOOST_REQUIRE(root_node.right()->left()->count() == 2);
+    BOOST_REQUIRE(root_node.right()->left()->left()->count() == 1);
+    BOOST_REQUIRE(root_node.right()->left()->right()->count() == 1);
+    BOOST_REQUIRE(root_node.right()->right()->count() == 1);
+  }
+
+  // Forward declaration of methods we need for the next test.
+  template<typename TreeType>
+  bool CheckPointBounds(TreeType* node, const arma::mat& data);
+
+  template<typename TreeType>
+  void GenerateVectorOfTree(TreeType* node,
+                            size_t depth,
+                            std::vector<TreeType*>& v);
+
+  template<int t_pow>
+  bool DoBoundsIntersect(HRectBound<t_pow>& a,
+                         HRectBound<t_pow>& b,
+                         size_t ia,
+                         size_t ib);
+
+  /***
+   * Exhaustive kd-tree test based on #125.
+   *
+   * - Generate a random dataset of a random size.
+   * - Build a tree on that dataset.
+   * - Ensure all the permutation indices map back to the correct points.
+   * - Verify that each point is contained inside all of the bounds of its parent
+   *     nodes.
+   * - Verify that each bound at a particular level of the tree does not overlap
+   *     with any other bounds at that level.
+   *
+   * Then, we do that whole process a handful of times.
+   */
+  BOOST_AUTO_TEST_CASE(kd_tree_test) {
+    typedef BinarySpaceTree<HRectBound<2> > TreeType;
+
+    size_t max_runs = 10; // Ten total tests.
+    size_t point_increments = 1000; // Range is from 2000 points to 11000.
+
+    // Generate the dataset.
+    srand(time(NULL));
+
+    // Reset the leaf size as other tests have been naughty.
+    // Also, a leaf size of 20 makes the test take too long.
+    CLI::GetParam<int>("tree/leaf_size") = 20;
+
+    for(size_t run = 0; run < max_runs; run++) {
+      size_t dimensions = run + 2;
+      size_t max_points = (run + 1) * point_increments;
+
+      size_t size = max_points;
+      arma::mat dataset = arma::mat(dimensions, size);
+      arma::mat datacopy; // Used to test mappings.
+
+      // Mappings for post-sort verification of data.
+      std::vector<size_t> new_to_old;
+      std::vector<size_t> old_to_new;
+
+      // Generate data.
+      dataset.randu();
+      datacopy = dataset; // Save a copy.
+
+      // Build the tree itself.
+      TreeType root(dataset, new_to_old, old_to_new);
+
+      // Ensure the size of the tree is correct.
+      BOOST_REQUIRE_EQUAL(root.count(), size);
+
+      // Check the forward and backward mappings for correctness.
+      for(size_t i = 0; i < size; i++) {
+        for(size_t j = 0; j < dimensions; j++) {
+          BOOST_REQUIRE_EQUAL(dataset(j, i), datacopy(j, new_to_old[i]));
+          BOOST_REQUIRE_EQUAL(dataset(j, old_to_new[i]), datacopy(j, i));
+        }
+      }
+
+      // Now check that each point is contained inside of all bounds above it.
+      CheckPointBounds(&root, dataset);
+
+      // Now check that no peers overlap.
+      std::vector<TreeType*> v;
+      GenerateVectorOfTree(&root, 1, v);
+
+      // Start with the first pair.
+      size_t depth = 2;
+      // Compare each peer against every other peer.
+      while (depth < v.size()) {
+        for (size_t i = depth; i < 2 * depth && i < v.size(); i++)
+          for (size_t j = i + 1; j < 2 * depth && j < v.size(); j++)
+            if (v[i] != NULL && v[j] != NULL)
+              BOOST_REQUIRE(!DoBoundsIntersect(v[i]->bound(), v[j]->bound(),
+                  i, j));
+
+        depth *= 2;
+      }
+    }
+
+    // Reset it to the default value at the end of the test.
+    CLI::GetParam<int>("tree/leaf_size") = 20;
+  }
+
+  // Recursively checks that each node contains all points that it claims to have.
+  template<typename TreeType>
+  bool CheckPointBounds(TreeType* node, const arma::mat& data) {
+    if (node == NULL) // We have passed a leaf node.
+      return true;
+
+    TreeType* left = node->left();
+    TreeType* right = node->right();
+
+    size_t begin = node->begin();
+    size_t count = node->count();
+
+    // Check that each point which this tree claims is actually inside the tree.
+    for (size_t index = begin; index < begin+count; index++) {
+      if (!node->bound().Contains(data.col(index)))
+        return false;
+    }
+
+    return CheckPointBounds(left, data) && CheckPointBounds(right, data);
+  }
+
+  template<int t_pow>
+  bool DoBoundsIntersect(HRectBound<t_pow>& a,
+                         HRectBound<t_pow>& b,
+                         size_t ia,
+                         size_t ib) {
+    size_t dimensionality = a.dim();
+
+    Range r_a;
+    Range r_b;
+
+    for (size_t i = 0; i < dimensionality; i++) {
+      r_a = a[i];
+      r_b = b[i];
+      if (r_a < r_b || r_a > r_b) // If a does not overlap b at all.
+        return false;
+    }
+
+    return true;
+  }
+
+  template<typename TreeType>
+  void GenerateVectorOfTree(TreeType* node,
+                            size_t depth,
+                            std::vector<TreeType*>& v) {
+    if (node == NULL)
+      return;
+
+    if (depth >= v.size())
+      v.resize(2 * depth + 1, NULL); // Resize to right size; fill with NULL.
+
+    v[depth] = node;
+
+    // Recurse to the left and right children.
+    GenerateVectorOfTree(node->left(), depth * 2, v);
+    GenerateVectorOfTree(node->right(), depth * 2 + 1, v);
+
+    return;
+  }
+BOOST_AUTO_TEST_SUITE_END();

Added: mlpack/trunk/src/mlpack/tests/union_find_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/union_find_test.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/tests/union_find_test.cpp	2011-11-04 15:43:10 UTC (rev 10139)
@@ -0,0 +1,48 @@
+/**
+ * @file union_find_test.cc
+ *
+ * @author Bill March (march at gatech.edu)
+ *
+ * Unit tests for the Union-Find data structure.
+ */
+
+#include <mlpack/methods/emst/union_find.hpp>
+
+#include <mlpack/core.h>
+#include <boost/test/unit_test.hpp>
+
+using namespace mlpack;
+using namespace mlpack::emst;
+
+BOOST_AUTO_TEST_CASE(TestFind) {
+  static const size_t test_size_ = 10;
+  UnionFind test_union_find_;
+  test_union_find_.Init(test_size_);
+
+  for (size_t i = 0; i < test_size_; i++) {
+    BOOST_REQUIRE(test_union_find_.Find(i) == i);
+  }
+  test_union_find_.Union(0,1);
+  test_union_find_.Union(1, 2);
+
+  BOOST_REQUIRE(test_union_find_.Find(2) == test_union_find_.Find(0));
+
+}
+
+BOOST_AUTO_TEST_CASE(TestUnion) {
+  static const size_t test_size_ = 10;
+  UnionFind test_union_find_;
+  test_union_find_.Init(test_size_);
+
+  test_union_find_.Union(0, 1);
+  test_union_find_.Union(2, 3);
+  test_union_find_.Union(0, 2);
+  test_union_find_.Union(5, 0);
+  test_union_find_.Union(0, 6);
+
+  BOOST_REQUIRE(test_union_find_.Find(0) == test_union_find_.Find(1));
+  BOOST_REQUIRE(test_union_find_.Find(2) == test_union_find_.Find(3));
+  BOOST_REQUIRE(test_union_find_.Find(1) == test_union_find_.Find(5));
+  BOOST_REQUIRE(test_union_find_.Find(6) == test_union_find_.Find(3));
+}
+




More information about the mlpack-svn mailing list