Java tutorial
/******************************************************************************* * Copyright 2015, 2016 Taylor G Smith * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ package com.clust4j.algo; import static org.junit.Assert.*; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Map; import java.util.TreeMap; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.linear.Array2DRowRealMatrix; import org.apache.commons.math3.linear.RealMatrix; import org.apache.commons.math3.util.FastMath; import org.apache.commons.math3.util.Precision; import org.junit.Test; import com.clust4j.TestSuite; import com.clust4j.algo.HDBSCAN.HDBSCAN_Algorithm; import com.clust4j.algo.HDBSCAN.CompQuadTup; import com.clust4j.algo.HDBSCANParameters; import com.clust4j.algo.HDBSCAN.LinkageTreeUtils; import com.clust4j.algo.HDBSCAN.TreeUnionFind; import com.clust4j.algo.HDBSCAN.UnionFind; import com.clust4j.algo.preprocess.StandardScaler; import com.clust4j.algo.Neighborhood; import com.clust4j.data.DataSet; import com.clust4j.except.ModelNotFitException; import com.clust4j.kernel.GaussianKernel; import com.clust4j.kernel.Kernel; import com.clust4j.kernel.KernelTestCases; import com.clust4j.metrics.pairwise.Distance; import com.clust4j.metrics.pairwise.DistanceMetric; import com.clust4j.metrics.pairwise.MinkowskiDistance; import com.clust4j.metrics.pairwise.Pairwise; import com.clust4j.metrics.pairwise.Similarity; import com.clust4j.utils.EntryPair; import com.clust4j.utils.Series.Inequality; import com.clust4j.utils.MatUtils; import com.clust4j.utils.VecUtils; import com.clust4j.utils.MatUtils.MatSeries; import com.clust4j.utils.MatrixFormatter; import com.clust4j.utils.QuadTup; public class HDBSCANTests implements ClusterTest, ClassifierTest, BaseModelTest { final Array2DRowRealMatrix DATA = TestSuite.IRIS_DATASET.getData(); final Array2DRowRealMatrix iris = DATA; final static MatrixFormatter formatter = TestSuite.formatter; final static double[][] dist_mat = new double[][] { new double[] { 1, 2, 3 }, new double[] { 4, 5, 6 }, new double[] { 7, 8, 9 } }; final int[] expected_iris_labs = new LabelEncoder(new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }).fit() .getEncodedLabels(); @Test public void testHDBSCANGenericMutualReachability() { final int m = dist_mat.length, minPts = 3; final int min_points = FastMath.min(m - 1, minPts); final double[] core_distances = MatUtils.sortColsAsc(dist_mat)[min_points]; final MatSeries ser1 = new MatSeries(core_distances, Inequality.GREATER_THAN, dist_mat); double[][] stage1 = MatUtils.where(ser1, core_distances, dist_mat); stage1 = MatUtils.transpose(stage1); final MatSeries ser2 = new MatSeries(core_distances, Inequality.GREATER_THAN, stage1); final double[][] result = MatUtils.where(ser2, core_distances, stage1); final double[][] res = MatUtils.transpose(result); assertTrue(MatUtils.equalsExactly(res, new double[][] { new double[] { 7, 8, 9 }, new double[] { 8, 8, 9 }, new double[] { 9, 9, 9 } })); } @Test public void testHDBSCANGenericMstLinkageCore() { double[][] X = new double[][] { new double[] { 0.1, 0.6, 0.3 }, new double[] { 0.6, 0.6, 0.6 }, new double[] { 12.1, 13.1, 11.8 } }; final int m = X.length; double[][] result = HDBSCAN.LinkageTreeUtils.minSpanTreeLinkageCore(X, m); final double[][] expected = new double[][] { new double[] { 0.0, 2.0, 0.3 }, new double[] { 2.0, 1.0, 0.6 } }; assertTrue(MatUtils.equalsExactly(result, expected)); } @Test public void testArgSorting() { double[][] m = new double[][] { new double[] { 0.0, 2.0, 0.3 }, new double[] { 2.0, 1.0, 0.6 } }; double[][] exp = MatUtils.copy(m); int[] sortedArgs = VecUtils.argSort(MatUtils.transpose(m)[2]); m = MatUtils.reorder(m, sortedArgs); assertTrue(MatUtils.equalsExactly(exp, m)); } @Test public void testLabeling() { double[][] x = new double[][] { new double[] { 0.0, 2.0, 0.3 }, new double[] { 2.0, 1.0, 0.6 }, }; double[][] y = new double[][] { new double[] { 0.0, 2.0, 0.3, 2.0 }, new double[] { 3.0, 1.0, 0.6, 3.0 } }; assertTrue(MatUtils.equalsExactly(HDBSCAN.label(x), y)); // More complex assertTrue(MatUtils.equalsExactly( HDBSCAN.label(new double[][] { new double[] { 0.0, 2.0, 0.3, 1.9 }, new double[] { 2.0, 1.0, 0.6, 6.7 }, new double[] { 1.0, 4.3, 0.9, 0.1 } }), new double[][] { new double[] { 0.0, 2.0, 0.3, 2.0, 0.0 }, new double[] { 4.0, 1.0, 0.6, 3.0, 0.0 }, new double[] { 5.0, 5.0, 0.9, 6.0, 0. } })); } @Test public void testCondenseAndComputeStability() { double[][] slt = new double[][] { new double[] { 0.0, 2.0, 0.3, 2.0 }, new double[] { 3.0, 1.0, 0.6, 3.0 } }; ArrayList<CompQuadTup<Integer, Integer, Double, Integer>> h = HDBSCAN.LinkageTreeUtils.condenseTree(slt, 5); QuadTup<Integer, Integer, Double, Integer> q = h.get(0); assertTrue(q.getFirst() == 3); assertTrue(q.getSecond() == 0); // Three is a repeating decimal... assertTrue(q.getFourth() == 1); TreeMap<Integer, Double> computedStability = HDBSCAN.LinkageTreeUtils.computeStability(h); assertTrue(computedStability.size() == 1); assertTrue(computedStability.get(3) == 5); int[] labels = HDBSCAN.getLabels(h, computedStability); assertTrue(labels.length == 3); assertTrue(labels[0] == -1); assertTrue(labels[1] == -1); assertTrue(labels[2] == -1); } @Test public void testUnionFindClass() { UnionFind u = new UnionFind(5); int val = 2; // Test finds assertTrue(VecUtils.equalsExactly(new int[] { 1, 1, 1, 1, 1, 0, 0, 0, 0 }, u.size)); assertTrue(u.fastFind(val) == val); assertTrue(u.parent[u.parent.length - 1] == val); assertFalse(u.parent[val] == val); // Should look like [-1, -1, -1, -1, -1, -1, -1, -1, 2] assertTrue(u.fastFind(-1) == val); assertTrue(VecUtils.equalsExactly(u.parent, new int[] { -1, -1, -1, -1, -1, -1, -1, -1, 2 })); assertTrue(u.fastFind(3) == 3); assertTrue(VecUtils.equalsExactly(u.parent, new int[] { -1, -1, -1, -1, -1, -1, -1, -1, 3 })); // Test unions u.union(3, 4); assertTrue(VecUtils.equalsExactly(u.parent, new int[] { -1, -1, -1, 5, 5, -1, -1, -1, 3 })); assertTrue(VecUtils.equalsExactly(u.size, new int[] { 1, 1, 1, 1, 1, 2, 0, 0, 0 })); u.union(-1, -2); assertTrue(VecUtils.equalsExactly(u.parent, new int[] { -1, -1, -1, 5, 5, -1, -1, 6, 6 })); assertTrue(u.find(6) == 6); assertTrue(VecUtils.equalsExactly(u.parent, new int[] { -1, -1, -1, 5, 5, -1, -1, 6, 6 })); } @Test public void testTreeUnionFindClass() { TreeUnionFind t = new TreeUnionFind(5); int[][] parent = new int[][] { new int[] { 0, 0 }, new int[] { 1, 0 }, new int[] { 2, 0 }, new int[] { 3, 0 }, new int[] { 4, 0 } }; assertTrue(MatUtils.equalsExactly(t.dataArr, parent)); assertTrue(t.find(3) == 3); assertTrue(MatUtils.equalsExactly(t.dataArr, parent)); assertTrue(t.find(-1) == 4); assertTrue(MatUtils.equalsExactly(t.dataArr, parent)); // Test union t.union(3, -1); assertTrue(MatUtils.equalsExactly(t.dataArr, new int[][] { new int[] { 0, 0 }, new int[] { 1, 0 }, new int[] { 2, 0 }, new int[] { 3, 1 }, new int[] { 3, 0 } })); t.union(-3, 4); assertTrue(MatUtils.equalsExactly(t.dataArr, new int[][] { new int[] { 0, 0 }, new int[] { 1, 0 }, new int[] { 3, 0 }, new int[] { 3, 1 }, new int[] { 3, 0 } })); assertTrue(VecUtils.equalsExactly(t.components(), new int[] { 0, 1, 3 })); } @Test public void testGenericRun() { final double[][] x = new double[][] { new double[] { 0, 1, 0, 2 }, new double[] { 0, 0, 1, 2 }, new double[] { 5, 6, 7, 4 } }; HDBSCAN model = new HDBSCAN(new Array2DRowRealMatrix(x), new HDBSCANParameters(1).setVerbose(true)).fit(); int[] labels = model.getLabels(); assertTrue(VecUtils.equalsExactly(labels, new int[] { -1, -1, -1 })); System.out.println(); } @Test public void testFindNodeSplitDim() { final double[][] a = new double[][] { new double[] { 0, 1, 0, 2 }, new double[] { 0, 0, 1, 2 }, new double[] { 5, 6, 7, 4 } }; assertTrue(NearestNeighborHeapSearch.findNodeSplitDim(a, new int[] { 0, 1, 2 }) == 2); } @Test public void testPrimKD() { double m = dist_mat.length; int min_points = (int) FastMath.min(m - 1, 5); Array2DRowRealMatrix X = new Array2DRowRealMatrix(dist_mat); KDTree tree = new KDTree(X, HDBSCAN.DEF_LEAF_SIZE, Distance.EUCLIDEAN); Neighborhood query = tree.query(dist_mat, min_points, true, true); double[][] dists = query.getDistances(); double[] coreDistances = MatUtils.getColumn(dists, dists[0].length - 1); // Needs to equal this: // [ 5.19615242, 5.19615242, 5.19615242] assertTrue(VecUtils.equalsExactly(coreDistances, new double[] { 5.196152422706632, 5.196152422706632, 5.196152422706632 })); assertTrue(MatUtils.equalsExactly(query.getValue(), new int[][] { new int[] { 0, 1 }, new int[] { 1, 0 }, new int[] { 2, 1 } })); double[][] minSpanningTree = LinkageTreeUtils.minSpanTreeLinkageCore_cdist(dist_mat, coreDistances, Distance.EUCLIDEAN, HDBSCAN.DEF_ALPHA); double[][] expected = new double[][] { new double[] { 0.0, 1.0, 5.196152422706632 }, new double[] { 1.0, 2.0, 5.196152422706632 } }; assertTrue(MatUtils.equalsExactly(minSpanningTree, expected)); } @Test public void testPrimKDRun() { final double[][] x = new double[][] { new double[] { 0, 1, 0, 2 }, new double[] { 0, 0, 1, 2 }, new double[] { 5, 6, 7, 4 } }; HDBSCAN model = new HDBSCAN(new Array2DRowRealMatrix(x), new HDBSCANParameters(1).setAlgo(HDBSCAN_Algorithm.PRIMS_KDTREE).setVerbose(true)).fit(); int[] labels = model.getLabels(); assertTrue(VecUtils.equalsExactly(labels, new int[] { -1, -1, -1 })); System.out.println(); } @Test public void testPrimBall() { double m = dist_mat.length; int min_points = (int) FastMath.min(m - 1, 5); Array2DRowRealMatrix X = new Array2DRowRealMatrix(dist_mat); BallTree tree = new BallTree(X, HDBSCAN.DEF_LEAF_SIZE, Distance.EUCLIDEAN); Neighborhood query = tree.query(dist_mat, min_points, true, true); double[][] dists = query.getDistances(); double[] coreDistances = MatUtils.getColumn(dists, dists[0].length - 1); // Needs to equal this: // [ 5.19615242, 5.19615242, 5.19615242] assertTrue(VecUtils.equalsExactly(coreDistances, new double[] { 5.196152422706632, 5.196152422706632, 5.196152422706632 })); assertTrue(MatUtils.equalsExactly(query.getValue(), new int[][] { new int[] { 0, 1 }, new int[] { 1, 0 }, new int[] { 2, 1 } })); double[][] minSpanningTree = LinkageTreeUtils.minSpanTreeLinkageCore_cdist(dist_mat, coreDistances, Distance.EUCLIDEAN, HDBSCAN.DEF_ALPHA); double[][] expected = new double[][] { new double[] { 0.0, 1.0, 5.196152422706632 }, new double[] { 1.0, 2.0, 5.196152422706632 } }; assertTrue(MatUtils.equalsExactly(minSpanningTree, expected)); } @Test public void testMoreBFS() { double[][] x = new double[][] { new double[] { 0, 1, 1.414, 2 }, new double[] { 3, 2, 10.05, 3 } }; ArrayList<Integer> result; int root; // Test with root == 0 root = 0; result = HDBSCAN.LinkageTreeUtils.breadthFirstSearch(x, root); assertTrue(result.size() == 1); assertTrue(result.get(0) == root); // Test with root == 1 root = 1; result = HDBSCAN.LinkageTreeUtils.breadthFirstSearch(x, root); assertTrue(result.size() == 1); assertTrue(result.get(0) == root); // Test with root == 2 root = 2; result = HDBSCAN.LinkageTreeUtils.breadthFirstSearch(x, root); assertTrue(result.size() == 1); assertTrue(result.get(0) == root); // Test with root == -1 root = -1; result = HDBSCAN.LinkageTreeUtils.breadthFirstSearch(x, root); assertTrue(result.size() == 1); assertTrue(result.get(0) == root); // Test with root == -2 root = -2; result = HDBSCAN.LinkageTreeUtils.breadthFirstSearch(x, root); assertTrue(result.size() == 1); assertTrue(result.get(0) == root); } @Test public void testPrimBallRun() { final double[][] x = new double[][] { new double[] { 0, 1, 0, 2 }, new double[] { 0, 0, 1, 2 }, new double[] { 5, 6, 7, 4 } }; HDBSCAN model = new HDBSCAN(new Array2DRowRealMatrix(x), new HDBSCANParameters(1).setAlgo(HDBSCAN_Algorithm.PRIMS_BALLTREE).setVerbose(true)).fit(); int[] labels = model.getLabels(); assertTrue(VecUtils.equalsExactly(labels, new int[] { -1, -1, -1 })); System.out.println(); } @Test public void testDescKeySet() { TreeMap<Integer, Double> stability = new TreeMap<>(); stability.put(1, 456.0); stability.put(9, 23.0); stability.put(-5, 89.0); ArrayList<Integer> nodes = HDBSCAN.GetLabelUtils.descSortedKeySet(stability); assertTrue(nodes.size() == 2); assertTrue(nodes.get(0) == 9); assertTrue(nodes.get(1) == 1); // It should trim the last one } @Test public void testSizeOverOne() { ArrayList<CompQuadTup<Integer, Integer, Double, Integer>> tup = new ArrayList<>(); tup.add(new CompQuadTup<Integer, Integer, Double, Integer>(1, 2, 1.0, 1)); tup.add(new CompQuadTup<Integer, Integer, Double, Integer>(1, 1, 1.0, 2)); tup.add(new CompQuadTup<Integer, Integer, Double, Integer>(1, 1, 1.0, 2)); tup.add(new CompQuadTup<Integer, Integer, Double, Integer>(1, 1, 1.0, 2)); EntryPair<ArrayList<double[]>, Integer> entry = HDBSCAN.GetLabelUtils.childSizeGtOneAndMaxChild(tup); assertTrue(entry.getKey().size() == 3); assertTrue(entry.getValue() == 3); } @Test public void testDataSet() { // See if the iris dataset works... new HDBSCAN(iris, new HDBSCANParameters(1).setVerbose(true)).fit(); } @Test @Override public void testScoring() { new HDBSCAN(DATA).fit().silhouetteScore(); } @Test @Override public void testDefConst() { new HDBSCAN(DATA); } @Test @Override public void testArgConst() { new HDBSCAN(DATA, 3); } @Test @Override public void testPlannerConst() { new HDBSCAN(DATA, new HDBSCANParameters()); } @Test @Override public void testFit() { new HDBSCAN(DATA, 1).fit(); } @Test @Override public void testFromPlanner() { new HDBSCANParameters().fitNewModel(DATA); new HDBSCANParameters(3).fitNewModel(DATA); } @Test @Override public void testSerialization() throws IOException, ClassNotFoundException { HDBSCAN hd = new HDBSCAN(DATA, new HDBSCANParameters(1).setVerbose(true)).fit(); System.out.println(); final int[] labels = hd.getLabels(); hd.saveObject(new FileOutputStream(TestSuite.tmpSerPath)); assertTrue(TestSuite.file.exists()); HDBSCAN hd2 = (HDBSCAN) HDBSCAN.loadObject(new FileInputStream(TestSuite.tmpSerPath)); assertTrue(VecUtils.equalsExactly(hd2.getLabels(), labels)); assertTrue(hd.equals(hd2)); Files.delete(TestSuite.path); } @Test(expected = IllegalArgumentException.class) public void testAlphaIAE() { new HDBSCAN(TestSuite.getRandom(5, 5), new HDBSCANParameters().setAlpha(0.0)); } @Test public void testSepWarn() { HDBSCAN h = new HDBSCAN(TestSuite.getRandom(5, 5), new HDBSCANParameters().setAlgo(HDBSCAN_Algorithm.PRIMS_KDTREE).setMetric(new GaussianKernel())); assertTrue(h.hasWarnings()); } @Test public void compareToPckg() { Array2DRowRealMatrix X = new Array2DRowRealMatrix(MatUtils.reshape(new double[] { 0.58459246, 0.2411591, 0.54266953, 0.80298748, 0.7108317, 0.77419375, 0.19460038, 0.51769224, 0.80581355, 0.06109043, 0.57755264, 0.48690635, 0.4698578, 0.68256655, 0.35583625, 0.33956817, 0.46084149, 0.2266772, 0.78013553, 0.84169725, 0.45929076, 0.5763663, 0.85034392, 0.42344478, 0.08823549 }, 5, 5), false); HDBSCAN h = new HDBSCAN(X).fit(); assertTrue(VecUtils.equalsExactly(h.getLabels(), VecUtils.repInt(-1, 5))); h = new HDBSCAN(X, new HDBSCANParameters().setAlgo(HDBSCAN_Algorithm.PRIMS_KDTREE)).fit(); assertTrue(VecUtils.equalsExactly(h.getLabels(), VecUtils.repInt(-1, 5))); h = new HDBSCAN(X, new HDBSCANParameters().setAlgo(HDBSCAN_Algorithm.PRIMS_BALLTREE)).fit(); assertTrue(VecUtils.equalsExactly(h.getLabels(), VecUtils.repInt(-1, 5))); // Test on IRIS h = new HDBSCAN(iris, new HDBSCANParameters().setAlgo(HDBSCAN_Algorithm.GENERIC)).fit(); int[] expectedLabels = new NoiseyLabelEncoder(expected_iris_labs).fit().getEncodedLabels(); assertTrue(VecUtils.equalsExactly(expectedLabels, h.getLabels())); h = new HDBSCAN(X, new HDBSCANParameters().setAlgo(HDBSCAN_Algorithm.PRIMS_KDTREE)).fit(); System.out.println(Arrays.toString(h.getLabels())); } @Test public void testMutualReachability() { Array2DRowRealMatrix X = new Array2DRowRealMatrix( MatUtils.reshape(new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 3, 3), false); final double[][] dist = Pairwise.getDistance(X, Distance.EUCLIDEAN, false, false); // first test the partition by row final int minPts = FastMath.min(X.getRowDimension() - 1, 5); final double[] core_distances = MatUtils.sortColsAsc(dist)[minPts]; assertTrue(VecUtils.equalsExactly(core_distances, new double[] { 10.392304845413264, 5.196152422706632, 10.392304845413264 })); final double[][] expected = new double[][] { new double[] { 10.392304845413264, 10.392304845413264, 10.392304845413264 }, new double[] { 10.392304845413264, 5.196152422706632, 10.392304845413264 }, new double[] { 10.392304845413264, 10.392304845413264, 10.392304845413264 }, }; double[][] mr = HDBSCAN.LinkageTreeUtils.mutualReachability(dist, minPts, 1.0); assertTrue(MatUtils.equalsExactly(mr, expected)); } @Test public void testGenericAlgo() { HDBSCAN h = new HDBSCAN(iris, new HDBSCANParameters().setAlgo(HDBSCAN_Algorithm.GENERIC)).fit(); assertTrue(Precision.equals(h.indexAffinityScore(expected_iris_labs), 1.0, 0.05)); assertTrue(h.getNumberOfIdentifiedClusters() == 2); } @Test public void testPrimsKD() { HDBSCAN h = new HDBSCAN(iris, new HDBSCANParameters().setAlgo(HDBSCAN_Algorithm.PRIMS_KDTREE)).fit(); assertTrue(Precision.equals(h.indexAffinityScore(expected_iris_labs), 1.0, 0.05)); } @Test public void testPrimsBall() { HDBSCAN h = new HDBSCAN(iris, new HDBSCANParameters().setAlgo(HDBSCAN_Algorithm.PRIMS_BALLTREE)).fit(); assertTrue(Precision.equals(h.indexAffinityScore(expected_iris_labs), 1.0, 0.05)); } @Test public void testBoruvkaKDTree() { HDBSCAN h = new HDBSCAN(iris, new HDBSCANParameters().setAlgo(HDBSCAN_Algorithm.BORUVKA_KDTREE)).fit(); assertTrue(Precision.equals(h.indexAffinityScore(expected_iris_labs), 1.0, 0.05)); } @Test public void testBoruvkaBallTree() { HDBSCAN h = new HDBSCAN(iris, new HDBSCANParameters().setAlgo(HDBSCAN_Algorithm.BORUVKA_BALLTREE)).fit(); assertTrue(Precision.equals(h.indexAffinityScore(expected_iris_labs), 1.0, 0.05)); } @Test public void testPrimLinkage() { KDTree k = new KDTree(iris); double[] core_dists = MatUtils.getColumn(k.query(iris.getDataRef(), 5, true, true).getDistances(), 4); double[][] X = iris.getData(); DistanceMetric metric = Distance.EUCLIDEAN; double alpha = 1.0; double[][] cdist = HDBSCAN.LinkageTreeUtils.minSpanTreeLinkageCore_cdist(X, core_dists, metric, alpha); double[][] expected_cdists = new double[][] { new double[] { 0.00000000e+00, 3.90000000e+01, 1.41421356e-01 }, new double[] { 3.90000000e+01, 1.70000000e+01, 1.73205081e-01 }, new double[] { 1.70000000e+01, 2.70000000e+01, 1.73205081e-01 }, new double[] { 2.70000000e+01, 2.80000000e+01, 1.73205081e-01 }, new double[] { 2.80000000e+01, 7.00000000e+00, 2.00000000e-01 }, new double[] { 7.00000000e+00, 4.90000000e+01, 2.23606798e-01 }, new double[] { 4.90000000e+01, 4.00000000e+00, 2.23606798e-01 }, new double[] { 4.00000000e+00, 2.60000000e+01, 2.44948974e-01 }, new double[] { 2.60000000e+01, 4.00000000e+01, 2.44948974e-01 }, new double[] { 4.00000000e+01, 4.80000000e+01, 2.44948974e-01 }, new double[] { 4.80000000e+01, 9.00000000e+00, 2.64575131e-01 }, new double[] { 9.00000000e+00, 1.00000000e+00, 1.73205081e-01 }, new double[] { 1.00000000e+00, 3.00000000e+01, 1.73205081e-01 }, new double[] { 3.00000000e+01, 3.40000000e+01, 1.73205081e-01 }, new double[] { 3.40000000e+01, 3.70000000e+01, 1.73205081e-01 }, new double[] { 3.70000000e+01, 1.20000000e+01, 1.73205081e-01 }, new double[] { 1.20000000e+01, 2.50000000e+01, 2.23606798e-01 }, new double[] { 2.50000000e+01, 2.90000000e+01, 2.23606798e-01 }, new double[] { 2.90000000e+01, 4.70000000e+01, 2.23606798e-01 }, new double[] { 4.70000000e+01, 3.00000000e+00, 2.44948974e-01 }, new double[] { 3.00000000e+00, 1.90000000e+01, 2.64575131e-01 }, new double[] { 1.90000000e+01, 2.00000000e+00, 2.64575131e-01 }, new double[] { 2.00000000e+00, 2.10000000e+01, 2.64575131e-01 }, new double[] { 2.10000000e+01, 4.50000000e+01, 2.64575131e-01 }, new double[] { 4.50000000e+01, 3.80000000e+01, 3.00000000e-01 }, new double[] { 3.80000000e+01, 1.10000000e+01, 3.00000000e-01 }, new double[] { 1.10000000e+01, 4.20000000e+01, 3.00000000e-01 }, new double[] { 4.20000000e+01, 4.60000000e+01, 3.00000000e-01 }, new double[] { 4.60000000e+01, 6.00000000e+00, 3.16227766e-01 }, new double[] { 6.00000000e+00, 3.10000000e+01, 3.16227766e-01 }, new double[] { 3.10000000e+01, 3.50000000e+01, 3.31662479e-01 }, new double[] { 3.50000000e+01, 1.00000000e+01, 3.31662479e-01 }, new double[] { 1.00000000e+01, 8.00000000e+00, 3.46410162e-01 }, new double[] { 8.00000000e+00, 3.60000000e+01, 3.46410162e-01 }, new double[] { 3.60000000e+01, 2.00000000e+01, 3.60555128e-01 }, new double[] { 2.00000000e+01, 4.30000000e+01, 3.74165739e-01 }, new double[] { 4.30000000e+01, 5.00000000e+00, 3.74165739e-01 }, new double[] { 5.00000000e+00, 2.30000000e+01, 3.87298335e-01 }, new double[] { 2.30000000e+01, 1.60000000e+01, 3.87298335e-01 }, new double[] { 1.60000000e+01, 4.40000000e+01, 4.12310563e-01 }, new double[] { 4.40000000e+01, 3.30000000e+01, 4.12310563e-01 }, new double[] { 3.30000000e+01, 3.20000000e+01, 4.24264069e-01 }, new double[] { 3.20000000e+01, 2.40000000e+01, 4.24264069e-01 }, new double[] { 2.40000000e+01, 1.30000000e+01, 4.79583152e-01 }, new double[] { 1.30000000e+01, 1.80000000e+01, 5.09901951e-01 }, new double[] { 1.80000000e+01, 2.20000000e+01, 5.38516481e-01 }, new double[] { 2.20000000e+01, 1.40000000e+01, 5.56776436e-01 }, new double[] { 1.40000000e+01, 1.50000000e+01, 6.16441400e-01 }, new double[] { 1.50000000e+01, 4.10000000e+01, 7.81024968e-01 }, new double[] { 4.10000000e+01, 9.80000000e+01, 1.64012195e+00 }, new double[] { 9.80000000e+01, 5.70000000e+01, 7.93725393e-01 }, new double[] { 5.70000000e+01, 6.00000000e+01, 7.21110255e-01 }, new double[] { 6.00000000e+01, 8.00000000e+01, 7.14142843e-01 }, new double[] { 8.00000000e+01, 6.90000000e+01, 3.00000000e-01 }, new double[] { 6.90000000e+01, 9.20000000e+01, 2.64575131e-01 }, new double[] { 9.20000000e+01, 9.90000000e+01, 2.64575131e-01 }, new double[] { 9.90000000e+01, 9.60000000e+01, 2.44948974e-01 }, new double[] { 9.60000000e+01, 8.20000000e+01, 3.00000000e-01 }, new double[] { 8.20000000e+01, 8.90000000e+01, 3.00000000e-01 }, new double[] { 8.90000000e+01, 9.40000000e+01, 3.00000000e-01 }, new double[] { 9.40000000e+01, 8.80000000e+01, 3.16227766e-01 }, new double[] { 8.80000000e+01, 5.50000000e+01, 3.31662479e-01 }, new double[] { 5.50000000e+01, 9.50000000e+01, 3.31662479e-01 }, new double[] { 9.50000000e+01, 6.70000000e+01, 3.60555128e-01 }, new double[] { 6.70000000e+01, 6.10000000e+01, 3.60555128e-01 }, new double[] { 6.10000000e+01, 7.80000000e+01, 3.60555128e-01 }, new double[] { 7.80000000e+01, 9.10000000e+01, 3.46410162e-01 }, new double[] { 9.10000000e+01, 9.70000000e+01, 3.46410162e-01 }, new double[] { 9.70000000e+01, 7.40000000e+01, 3.87298335e-01 }, new double[] { 7.40000000e+01, 5.40000000e+01, 3.87298335e-01 }, new double[] { 5.40000000e+01, 5.80000000e+01, 3.74165739e-01 }, new double[] { 5.80000000e+01, 7.50000000e+01, 3.16227766e-01 }, new double[] { 7.50000000e+01, 8.60000000e+01, 3.31662479e-01 }, new double[] { 8.60000000e+01, 6.50000000e+01, 3.46410162e-01 }, new double[] { 6.50000000e+01, 5.20000000e+01, 3.46410162e-01 }, new double[] { 5.20000000e+01, 5.10000000e+01, 3.74165739e-01 }, new double[] { 5.10000000e+01, 7.60000000e+01, 3.74165739e-01 }, new double[] { 7.60000000e+01, 7.10000000e+01, 4.00000000e-01 }, new double[] { 7.10000000e+01, 6.60000000e+01, 4.12310563e-01 }, new double[] { 6.60000000e+01, 7.70000000e+01, 4.24264069e-01 }, new double[] { 7.70000000e+01, 1.47000000e+02, 4.24264069e-01 }, new double[] { 1.47000000e+02, 1.45000000e+02, 3.74165739e-01 }, new double[] { 1.45000000e+02, 1.12000000e+02, 3.74165739e-01 }, new double[] { 1.12000000e+02, 1.20000000e+02, 3.74165739e-01 }, new double[] { 1.20000000e+02, 1.40000000e+02, 3.46410162e-01 }, new double[] { 1.40000000e+02, 1.43000000e+02, 3.46410162e-01 }, new double[] { 1.43000000e+02, 1.39000000e+02, 3.74165739e-01 }, new double[] { 1.39000000e+02, 1.24000000e+02, 3.74165739e-01 }, new double[] { 1.24000000e+02, 1.15000000e+02, 3.87298335e-01 }, new double[] { 1.15000000e+02, 1.11000000e+02, 3.87298335e-01 }, new double[] { 1.11000000e+02, 1.03000000e+02, 3.87298335e-01 }, new double[] { 1.03000000e+02, 1.16000000e+02, 3.87298335e-01 }, new double[] { 1.16000000e+02, 1.28000000e+02, 3.87298335e-01 }, new double[] { 1.28000000e+02, 1.04000000e+02, 3.87298335e-01 }, new double[] { 1.04000000e+02, 1.44000000e+02, 4.00000000e-01 }, new double[] { 1.44000000e+02, 1.46000000e+02, 4.12310563e-01 }, new double[] { 1.46000000e+02, 1.23000000e+02, 4.12310563e-01 }, new double[] { 1.23000000e+02, 1.27000000e+02, 3.60555128e-01 }, new double[] { 1.27000000e+02, 1.38000000e+02, 3.16227766e-01 }, new double[] { 1.38000000e+02, 1.49000000e+02, 3.31662479e-01 }, new double[] { 1.49000000e+02, 1.01000000e+02, 3.31662479e-01 }, new double[] { 1.01000000e+02, 1.42000000e+02, 3.31662479e-01 }, new double[] { 1.42000000e+02, 8.30000000e+01, 3.74165739e-01 }, new double[] { 8.30000000e+01, 1.26000000e+02, 3.87298335e-01 }, new double[] { 1.26000000e+02, 7.00000000e+01, 4.24264069e-01 }, new double[] { 7.00000000e+01, 7.20000000e+01, 4.24264069e-01 }, new double[] { 7.20000000e+01, 1.10000000e+02, 4.24264069e-01 }, new double[] { 1.10000000e+02, 9.00000000e+01, 4.24264069e-01 }, new double[] { 9.00000000e+01, 6.30000000e+01, 4.24264069e-01 }, new double[] { 6.30000000e+01, 1.33000000e+02, 4.35889894e-01 }, new double[] { 1.33000000e+02, 5.30000000e+01, 4.35889894e-01 }, new double[] { 5.30000000e+01, 8.10000000e+01, 4.35889894e-01 }, new double[] { 8.10000000e+01, 1.32000000e+02, 4.35889894e-01 }, new double[] { 1.32000000e+02, 1.37000000e+02, 4.35889894e-01 }, new double[] { 1.37000000e+02, 7.30000000e+01, 4.35889894e-01 }, new double[] { 7.30000000e+01, 1.36000000e+02, 4.35889894e-01 }, new double[] { 1.36000000e+02, 7.90000000e+01, 4.47213595e-01 }, new double[] { 7.90000000e+01, 5.60000000e+01, 4.58257569e-01 }, new double[] { 5.60000000e+01, 1.21000000e+02, 4.58257569e-01 }, new double[] { 1.21000000e+02, 5.00000000e+01, 4.58257569e-01 }, new double[] { 5.00000000e+01, 1.02000000e+02, 4.58257569e-01 }, new double[] { 1.02000000e+02, 8.50000000e+01, 4.69041576e-01 }, new double[] { 8.50000000e+01, 1.25000000e+02, 4.69041576e-01 }, new double[] { 1.25000000e+02, 8.40000000e+01, 4.89897949e-01 }, new double[] { 8.40000000e+01, 1.30000000e+02, 5.09901951e-01 }, new double[] { 1.30000000e+02, 1.41000000e+02, 5.09901951e-01 }, new double[] { 1.41000000e+02, 6.40000000e+01, 5.19615242e-01 }, new double[] { 6.40000000e+01, 1.13000000e+02, 5.19615242e-01 }, new double[] { 1.13000000e+02, 1.14000000e+02, 5.19615242e-01 }, new double[] { 1.14000000e+02, 5.90000000e+01, 5.29150262e-01 }, new double[] { 5.90000000e+01, 1.07000000e+02, 5.47722558e-01 }, new double[] { 1.07000000e+02, 1.05000000e+02, 5.47722558e-01 }, new double[] { 1.05000000e+02, 1.29000000e+02, 5.56776436e-01 }, new double[] { 1.29000000e+02, 1.00000000e+02, 5.56776436e-01 }, new double[] { 1.00000000e+02, 1.19000000e+02, 5.83095189e-01 }, new double[] { 1.19000000e+02, 6.20000000e+01, 5.83095189e-01 }, new double[] { 6.20000000e+01, 8.70000000e+01, 6.08276253e-01 }, new double[] { 8.70000000e+01, 1.48000000e+02, 6.16441400e-01 }, new double[] { 1.48000000e+02, 1.08000000e+02, 6.16441400e-01 }, new double[] { 1.08000000e+02, 9.30000000e+01, 6.48074070e-01 }, new double[] { 9.30000000e+01, 1.34000000e+02, 6.63324958e-01 }, new double[] { 1.34000000e+02, 6.80000000e+01, 6.78232998e-01 }, new double[] { 6.80000000e+01, 1.35000000e+02, 6.78232998e-01 }, new double[] { 1.35000000e+02, 1.22000000e+02, 6.78232998e-01 }, new double[] { 1.22000000e+02, 1.09000000e+02, 7.54983444e-01 }, new double[] { 1.09000000e+02, 1.06000000e+02, 8.77496439e-01 }, new double[] { 1.06000000e+02, 1.18000000e+02, 9.27361850e-01 }, new double[] { 1.18000000e+02, 1.31000000e+02, 9.32737905e-01 }, new double[] { 1.31000000e+02, 1.17000000e+02, 1.00498756e+00 } }; assertTrue(MatUtils.equalsWithTolerance(cdist, expected_cdists, 1e-8)); double[][] srtd_cdists = MatUtils.sortAscByCol(cdist, 2); double[][] expected_srted = new double[][] { new double[] { 0.00000000e+00, 3.90000000e+01, 1.41421356e-01 }, new double[] { 3.90000000e+01, 1.70000000e+01, 1.73205081e-01 }, new double[] { 1.70000000e+01, 2.70000000e+01, 1.73205081e-01 }, new double[] { 2.70000000e+01, 2.80000000e+01, 1.73205081e-01 }, new double[] { 3.40000000e+01, 3.70000000e+01, 1.73205081e-01 }, new double[] { 3.00000000e+01, 3.40000000e+01, 1.73205081e-01 }, new double[] { 9.00000000e+00, 1.00000000e+00, 1.73205081e-01 }, new double[] { 1.00000000e+00, 3.00000000e+01, 1.73205081e-01 }, new double[] { 3.70000000e+01, 1.20000000e+01, 1.73205081e-01 }, new double[] { 2.80000000e+01, 7.00000000e+00, 2.00000000e-01 }, new double[] { 1.20000000e+01, 2.50000000e+01, 2.23606798e-01 }, new double[] { 7.00000000e+00, 4.90000000e+01, 2.23606798e-01 }, new double[] { 4.90000000e+01, 4.00000000e+00, 2.23606798e-01 }, new double[] { 2.90000000e+01, 4.70000000e+01, 2.23606798e-01 }, new double[] { 2.50000000e+01, 2.90000000e+01, 2.23606798e-01 }, new double[] { 4.00000000e+00, 2.60000000e+01, 2.44948974e-01 }, new double[] { 2.60000000e+01, 4.00000000e+01, 2.44948974e-01 }, new double[] { 4.00000000e+01, 4.80000000e+01, 2.44948974e-01 }, new double[] { 4.70000000e+01, 3.00000000e+00, 2.44948974e-01 }, new double[] { 9.90000000e+01, 9.60000000e+01, 2.44948974e-01 }, new double[] { 4.80000000e+01, 9.00000000e+00, 2.64575131e-01 }, new double[] { 3.00000000e+00, 1.90000000e+01, 2.64575131e-01 }, new double[] { 1.90000000e+01, 2.00000000e+00, 2.64575131e-01 }, new double[] { 2.00000000e+00, 2.10000000e+01, 2.64575131e-01 }, new double[] { 2.10000000e+01, 4.50000000e+01, 2.64575131e-01 }, new double[] { 9.20000000e+01, 9.90000000e+01, 2.64575131e-01 }, new double[] { 6.90000000e+01, 9.20000000e+01, 2.64575131e-01 }, new double[] { 4.50000000e+01, 3.80000000e+01, 3.00000000e-01 }, new double[] { 4.20000000e+01, 4.60000000e+01, 3.00000000e-01 }, new double[] { 3.80000000e+01, 1.10000000e+01, 3.00000000e-01 }, new double[] { 1.10000000e+01, 4.20000000e+01, 3.00000000e-01 }, new double[] { 8.00000000e+01, 6.90000000e+01, 3.00000000e-01 }, new double[] { 8.90000000e+01, 9.40000000e+01, 3.00000000e-01 }, new double[] { 8.20000000e+01, 8.90000000e+01, 3.00000000e-01 }, new double[] { 9.60000000e+01, 8.20000000e+01, 3.00000000e-01 }, new double[] { 4.60000000e+01, 6.00000000e+00, 3.16227766e-01 }, new double[] { 1.27000000e+02, 1.38000000e+02, 3.16227766e-01 }, new double[] { 6.00000000e+00, 3.10000000e+01, 3.16227766e-01 }, new double[] { 9.40000000e+01, 8.80000000e+01, 3.16227766e-01 }, new double[] { 5.80000000e+01, 7.50000000e+01, 3.16227766e-01 }, new double[] { 8.80000000e+01, 5.50000000e+01, 3.31662479e-01 }, new double[] { 3.10000000e+01, 3.50000000e+01, 3.31662479e-01 }, new double[] { 7.50000000e+01, 8.60000000e+01, 3.31662479e-01 }, new double[] { 1.38000000e+02, 1.49000000e+02, 3.31662479e-01 }, new double[] { 1.49000000e+02, 1.01000000e+02, 3.31662479e-01 }, new double[] { 1.01000000e+02, 1.42000000e+02, 3.31662479e-01 }, new double[] { 5.50000000e+01, 9.50000000e+01, 3.31662479e-01 }, new double[] { 3.50000000e+01, 1.00000000e+01, 3.31662479e-01 }, new double[] { 8.60000000e+01, 6.50000000e+01, 3.46410162e-01 }, new double[] { 1.00000000e+01, 8.00000000e+00, 3.46410162e-01 }, new double[] { 8.00000000e+00, 3.60000000e+01, 3.46410162e-01 }, new double[] { 7.80000000e+01, 9.10000000e+01, 3.46410162e-01 }, new double[] { 9.10000000e+01, 9.70000000e+01, 3.46410162e-01 }, new double[] { 1.20000000e+02, 1.40000000e+02, 3.46410162e-01 }, new double[] { 1.40000000e+02, 1.43000000e+02, 3.46410162e-01 }, new double[] { 6.50000000e+01, 5.20000000e+01, 3.46410162e-01 }, new double[] { 9.50000000e+01, 6.70000000e+01, 3.60555128e-01 }, new double[] { 1.23000000e+02, 1.27000000e+02, 3.60555128e-01 }, new double[] { 3.60000000e+01, 2.00000000e+01, 3.60555128e-01 }, new double[] { 6.10000000e+01, 7.80000000e+01, 3.60555128e-01 }, new double[] { 6.70000000e+01, 6.10000000e+01, 3.60555128e-01 }, new double[] { 1.12000000e+02, 1.20000000e+02, 3.74165739e-01 }, new double[] { 1.45000000e+02, 1.12000000e+02, 3.74165739e-01 }, new double[] { 1.47000000e+02, 1.45000000e+02, 3.74165739e-01 }, new double[] { 1.42000000e+02, 8.30000000e+01, 3.74165739e-01 }, new double[] { 1.43000000e+02, 1.39000000e+02, 3.74165739e-01 }, new double[] { 1.39000000e+02, 1.24000000e+02, 3.74165739e-01 }, new double[] { 5.20000000e+01, 5.10000000e+01, 3.74165739e-01 }, new double[] { 5.10000000e+01, 7.60000000e+01, 3.74165739e-01 }, new double[] { 2.00000000e+01, 4.30000000e+01, 3.74165739e-01 }, new double[] { 5.40000000e+01, 5.80000000e+01, 3.74165739e-01 }, new double[] { 4.30000000e+01, 5.00000000e+00, 3.74165739e-01 }, new double[] { 7.40000000e+01, 5.40000000e+01, 3.87298335e-01 }, new double[] { 9.70000000e+01, 7.40000000e+01, 3.87298335e-01 }, new double[] { 1.24000000e+02, 1.15000000e+02, 3.87298335e-01 }, new double[] { 1.16000000e+02, 1.28000000e+02, 3.87298335e-01 }, new double[] { 1.03000000e+02, 1.16000000e+02, 3.87298335e-01 }, new double[] { 1.11000000e+02, 1.03000000e+02, 3.87298335e-01 }, new double[] { 1.15000000e+02, 1.11000000e+02, 3.87298335e-01 }, new double[] { 8.30000000e+01, 1.26000000e+02, 3.87298335e-01 }, new double[] { 1.28000000e+02, 1.04000000e+02, 3.87298335e-01 }, new double[] { 5.00000000e+00, 2.30000000e+01, 3.87298335e-01 }, new double[] { 2.30000000e+01, 1.60000000e+01, 3.87298335e-01 }, new double[] { 7.60000000e+01, 7.10000000e+01, 4.00000000e-01 }, new double[] { 1.04000000e+02, 1.44000000e+02, 4.00000000e-01 }, new double[] { 1.46000000e+02, 1.23000000e+02, 4.12310563e-01 }, new double[] { 1.44000000e+02, 1.46000000e+02, 4.12310563e-01 }, new double[] { 1.60000000e+01, 4.40000000e+01, 4.12310563e-01 }, new double[] { 4.40000000e+01, 3.30000000e+01, 4.12310563e-01 }, new double[] { 7.10000000e+01, 6.60000000e+01, 4.12310563e-01 }, new double[] { 3.30000000e+01, 3.20000000e+01, 4.24264069e-01 }, new double[] { 1.26000000e+02, 7.00000000e+01, 4.24264069e-01 }, new double[] { 7.00000000e+01, 7.20000000e+01, 4.24264069e-01 }, new double[] { 3.20000000e+01, 2.40000000e+01, 4.24264069e-01 }, new double[] { 7.70000000e+01, 1.47000000e+02, 4.24264069e-01 }, new double[] { 6.60000000e+01, 7.70000000e+01, 4.24264069e-01 }, new double[] { 7.20000000e+01, 1.10000000e+02, 4.24264069e-01 }, new double[] { 1.10000000e+02, 9.00000000e+01, 4.24264069e-01 }, new double[] { 9.00000000e+01, 6.30000000e+01, 4.24264069e-01 }, new double[] { 6.30000000e+01, 1.33000000e+02, 4.35889894e-01 }, new double[] { 5.30000000e+01, 8.10000000e+01, 4.35889894e-01 }, new double[] { 1.33000000e+02, 5.30000000e+01, 4.35889894e-01 }, new double[] { 8.10000000e+01, 1.32000000e+02, 4.35889894e-01 }, new double[] { 1.32000000e+02, 1.37000000e+02, 4.35889894e-01 }, new double[] { 7.30000000e+01, 1.36000000e+02, 4.35889894e-01 }, new double[] { 1.37000000e+02, 7.30000000e+01, 4.35889894e-01 }, new double[] { 1.36000000e+02, 7.90000000e+01, 4.47213595e-01 }, new double[] { 7.90000000e+01, 5.60000000e+01, 4.58257569e-01 }, new double[] { 5.60000000e+01, 1.21000000e+02, 4.58257569e-01 }, new double[] { 1.21000000e+02, 5.00000000e+01, 4.58257569e-01 }, new double[] { 5.00000000e+01, 1.02000000e+02, 4.58257569e-01 }, new double[] { 1.02000000e+02, 8.50000000e+01, 4.69041576e-01 }, new double[] { 8.50000000e+01, 1.25000000e+02, 4.69041576e-01 }, new double[] { 2.40000000e+01, 1.30000000e+01, 4.79583152e-01 }, new double[] { 1.25000000e+02, 8.40000000e+01, 4.89897949e-01 }, new double[] { 1.30000000e+01, 1.80000000e+01, 5.09901951e-01 }, new double[] { 8.40000000e+01, 1.30000000e+02, 5.09901951e-01 }, new double[] { 1.30000000e+02, 1.41000000e+02, 5.09901951e-01 }, new double[] { 1.41000000e+02, 6.40000000e+01, 5.19615242e-01 }, new double[] { 6.40000000e+01, 1.13000000e+02, 5.19615242e-01 }, new double[] { 1.13000000e+02, 1.14000000e+02, 5.19615242e-01 }, new double[] { 1.14000000e+02, 5.90000000e+01, 5.29150262e-01 }, new double[] { 1.80000000e+01, 2.20000000e+01, 5.38516481e-01 }, new double[] { 5.90000000e+01, 1.07000000e+02, 5.47722558e-01 }, new double[] { 1.07000000e+02, 1.05000000e+02, 5.47722558e-01 }, new double[] { 1.05000000e+02, 1.29000000e+02, 5.56776436e-01 }, new double[] { 2.20000000e+01, 1.40000000e+01, 5.56776436e-01 }, new double[] { 1.29000000e+02, 1.00000000e+02, 5.56776436e-01 }, new double[] { 1.00000000e+02, 1.19000000e+02, 5.83095189e-01 }, new double[] { 1.19000000e+02, 6.20000000e+01, 5.83095189e-01 }, new double[] { 6.20000000e+01, 8.70000000e+01, 6.08276253e-01 }, new double[] { 8.70000000e+01, 1.48000000e+02, 6.16441400e-01 }, new double[] { 1.48000000e+02, 1.08000000e+02, 6.16441400e-01 }, new double[] { 1.40000000e+01, 1.50000000e+01, 6.16441400e-01 }, new double[] { 1.08000000e+02, 9.30000000e+01, 6.48074070e-01 }, new double[] { 9.30000000e+01, 1.34000000e+02, 6.63324958e-01 }, new double[] { 1.34000000e+02, 6.80000000e+01, 6.78232998e-01 }, new double[] { 6.80000000e+01, 1.35000000e+02, 6.78232998e-01 }, new double[] { 1.35000000e+02, 1.22000000e+02, 6.78232998e-01 }, new double[] { 6.00000000e+01, 8.00000000e+01, 7.14142843e-01 }, new double[] { 5.70000000e+01, 6.00000000e+01, 7.21110255e-01 }, new double[] { 1.22000000e+02, 1.09000000e+02, 7.54983444e-01 }, new double[] { 1.50000000e+01, 4.10000000e+01, 7.81024968e-01 }, new double[] { 9.80000000e+01, 5.70000000e+01, 7.93725393e-01 }, new double[] { 1.09000000e+02, 1.06000000e+02, 8.77496439e-01 }, new double[] { 1.06000000e+02, 1.18000000e+02, 9.27361850e-01 }, new double[] { 1.18000000e+02, 1.31000000e+02, 9.32737905e-01 }, new double[] { 1.31000000e+02, 1.17000000e+02, 1.00498756e+00 }, new double[] { 4.10000000e+01, 9.80000000e+01, 1.64012195e+00 } }; //System.out.println(Arrays.toString(VecUtils.argSort(MatUtils.getColumn(cdist, 2)))); //fail(); /* * In comparison to sklearn, this can get off by 1 or 2 due to * rounding errors in the sort. So lets just make sure there is a * discrepancy less than one or two. */ int wrong_ct = 0; for (int i = 0; i < srtd_cdists.length; i++) { if (!VecUtils.equalsWithTolerance(srtd_cdists[i], expected_srted[i], 1e-8)) { if (!Precision.equals(srtd_cdists[i][2], expected_srted[i][2], 1e-8)) wrong_ct++; } } assertTrue(wrong_ct < 2); // Do labeling double[][] labMat = HDBSCAN.label(srtd_cdists); double[][] expected_labMat = new double[][] { new double[] { 0.00000000e+00, 3.90000000e+01, 1.41421356e-01, 2.00000000e+00 }, new double[] { 1.50000000e+02, 1.70000000e+01, 1.73205081e-01, 3.00000000e+00 }, new double[] { 1.51000000e+02, 2.70000000e+01, 1.73205081e-01, 4.00000000e+00 }, new double[] { 1.52000000e+02, 2.80000000e+01, 1.73205081e-01, 5.00000000e+00 }, new double[] { 3.40000000e+01, 3.70000000e+01, 1.73205081e-01, 2.00000000e+00 }, new double[] { 3.00000000e+01, 1.54000000e+02, 1.73205081e-01, 3.00000000e+00 }, new double[] { 9.00000000e+00, 1.00000000e+00, 1.73205081e-01, 2.00000000e+00 }, new double[] { 1.56000000e+02, 1.55000000e+02, 1.73205081e-01, 5.00000000e+00 }, new double[] { 1.57000000e+02, 1.20000000e+01, 1.73205081e-01, 6.00000000e+00 }, new double[] { 1.53000000e+02, 7.00000000e+00, 2.00000000e-01, 6.00000000e+00 }, new double[] { 1.58000000e+02, 2.50000000e+01, 2.23606798e-01, 7.00000000e+00 }, new double[] { 1.59000000e+02, 4.90000000e+01, 2.23606798e-01, 7.00000000e+00 }, new double[] { 1.61000000e+02, 4.00000000e+00, 2.23606798e-01, 8.00000000e+00 }, new double[] { 2.90000000e+01, 4.70000000e+01, 2.23606798e-01, 2.00000000e+00 }, new double[] { 1.60000000e+02, 1.63000000e+02, 2.23606798e-01, 9.00000000e+00 }, new double[] { 1.62000000e+02, 2.60000000e+01, 2.44948974e-01, 9.00000000e+00 }, new double[] { 1.65000000e+02, 4.00000000e+01, 2.44948974e-01, 1.00000000e+01 }, new double[] { 1.66000000e+02, 4.80000000e+01, 2.44948974e-01, 1.10000000e+01 }, new double[] { 1.64000000e+02, 3.00000000e+00, 2.44948974e-01, 1.00000000e+01 }, new double[] { 9.90000000e+01, 9.60000000e+01, 2.44948974e-01, 2.00000000e+00 }, new double[] { 1.67000000e+02, 1.68000000e+02, 2.64575131e-01, 2.10000000e+01 }, new double[] { 1.70000000e+02, 1.90000000e+01, 2.64575131e-01, 2.20000000e+01 }, new double[] { 1.71000000e+02, 2.00000000e+00, 2.64575131e-01, 2.30000000e+01 }, new double[] { 1.72000000e+02, 2.10000000e+01, 2.64575131e-01, 2.40000000e+01 }, new double[] { 1.73000000e+02, 4.50000000e+01, 2.64575131e-01, 2.50000000e+01 }, new double[] { 9.20000000e+01, 1.69000000e+02, 2.64575131e-01, 3.00000000e+00 }, new double[] { 6.90000000e+01, 1.75000000e+02, 2.64575131e-01, 4.00000000e+00 }, new double[] { 1.74000000e+02, 3.80000000e+01, 3.00000000e-01, 2.60000000e+01 }, new double[] { 4.20000000e+01, 4.60000000e+01, 3.00000000e-01, 2.00000000e+00 }, new double[] { 1.77000000e+02, 1.10000000e+01, 3.00000000e-01, 2.70000000e+01 }, new double[] { 1.79000000e+02, 1.78000000e+02, 3.00000000e-01, 2.90000000e+01 }, new double[] { 8.00000000e+01, 1.76000000e+02, 3.00000000e-01, 5.00000000e+00 }, new double[] { 8.90000000e+01, 9.40000000e+01, 3.00000000e-01, 2.00000000e+00 }, new double[] { 8.20000000e+01, 1.82000000e+02, 3.00000000e-01, 3.00000000e+00 }, new double[] { 1.81000000e+02, 1.83000000e+02, 3.00000000e-01, 8.00000000e+00 }, new double[] { 1.80000000e+02, 6.00000000e+00, 3.16227766e-01, 3.00000000e+01 }, new double[] { 1.27000000e+02, 1.38000000e+02, 3.16227766e-01, 2.00000000e+00 }, new double[] { 1.85000000e+02, 3.10000000e+01, 3.16227766e-01, 3.10000000e+01 }, new double[] { 1.84000000e+02, 8.80000000e+01, 3.16227766e-01, 9.00000000e+00 }, new double[] { 5.80000000e+01, 7.50000000e+01, 3.16227766e-01, 2.00000000e+00 }, new double[] { 1.88000000e+02, 5.50000000e+01, 3.31662479e-01, 1.00000000e+01 }, new double[] { 1.87000000e+02, 3.50000000e+01, 3.31662479e-01, 3.20000000e+01 }, new double[] { 1.89000000e+02, 8.60000000e+01, 3.31662479e-01, 3.00000000e+00 }, new double[] { 1.86000000e+02, 1.49000000e+02, 3.31662479e-01, 3.00000000e+00 }, new double[] { 1.93000000e+02, 1.01000000e+02, 3.31662479e-01, 4.00000000e+00 }, new double[] { 1.94000000e+02, 1.42000000e+02, 3.31662479e-01, 5.00000000e+00 }, new double[] { 1.90000000e+02, 9.50000000e+01, 3.31662479e-01, 1.10000000e+01 }, new double[] { 1.91000000e+02, 1.00000000e+01, 3.31662479e-01, 3.30000000e+01 }, new double[] { 1.92000000e+02, 6.50000000e+01, 3.46410162e-01, 4.00000000e+00 }, new double[] { 1.97000000e+02, 8.00000000e+00, 3.46410162e-01, 3.40000000e+01 }, new double[] { 1.99000000e+02, 3.60000000e+01, 3.46410162e-01, 3.50000000e+01 }, new double[] { 7.80000000e+01, 9.10000000e+01, 3.46410162e-01, 2.00000000e+00 }, new double[] { 2.01000000e+02, 9.70000000e+01, 3.46410162e-01, 3.00000000e+00 }, new double[] { 1.20000000e+02, 1.40000000e+02, 3.46410162e-01, 2.00000000e+00 }, new double[] { 2.03000000e+02, 1.43000000e+02, 3.46410162e-01, 3.00000000e+00 }, new double[] { 1.98000000e+02, 5.20000000e+01, 3.46410162e-01, 5.00000000e+00 }, new double[] { 1.96000000e+02, 6.70000000e+01, 3.60555128e-01, 1.20000000e+01 }, new double[] { 1.23000000e+02, 1.95000000e+02, 3.60555128e-01, 6.00000000e+00 }, new double[] { 2.00000000e+02, 2.00000000e+01, 3.60555128e-01, 3.60000000e+01 }, new double[] { 6.10000000e+01, 2.02000000e+02, 3.60555128e-01, 4.00000000e+00 }, new double[] { 2.06000000e+02, 2.09000000e+02, 3.60555128e-01, 1.60000000e+01 }, new double[] { 1.12000000e+02, 2.04000000e+02, 3.74165739e-01, 4.00000000e+00 }, new double[] { 1.45000000e+02, 2.11000000e+02, 3.74165739e-01, 5.00000000e+00 }, new double[] { 1.47000000e+02, 2.12000000e+02, 3.74165739e-01, 6.00000000e+00 }, new double[] { 2.07000000e+02, 8.30000000e+01, 3.74165739e-01, 7.00000000e+00 }, new double[] { 2.13000000e+02, 1.39000000e+02, 3.74165739e-01, 7.00000000e+00 }, new double[] { 2.15000000e+02, 1.24000000e+02, 3.74165739e-01, 8.00000000e+00 }, new double[] { 2.05000000e+02, 5.10000000e+01, 3.74165739e-01, 6.00000000e+00 }, new double[] { 2.17000000e+02, 7.60000000e+01, 3.74165739e-01, 7.00000000e+00 }, new double[] { 2.08000000e+02, 4.30000000e+01, 3.74165739e-01, 3.70000000e+01 }, new double[] { 5.40000000e+01, 2.18000000e+02, 3.74165739e-01, 8.00000000e+00 }, new double[] { 2.19000000e+02, 5.00000000e+00, 3.74165739e-01, 3.80000000e+01 }, new double[] { 7.40000000e+01, 2.20000000e+02, 3.87298335e-01, 9.00000000e+00 }, new double[] { 2.10000000e+02, 2.22000000e+02, 3.87298335e-01, 2.50000000e+01 }, new double[] { 2.16000000e+02, 1.15000000e+02, 3.87298335e-01, 9.00000000e+00 }, new double[] { 1.16000000e+02, 1.28000000e+02, 3.87298335e-01, 2.00000000e+00 }, new double[] { 1.03000000e+02, 2.25000000e+02, 3.87298335e-01, 3.00000000e+00 }, new double[] { 1.11000000e+02, 2.26000000e+02, 3.87298335e-01, 4.00000000e+00 }, new double[] { 2.24000000e+02, 2.27000000e+02, 3.87298335e-01, 1.30000000e+01 }, new double[] { 2.14000000e+02, 1.26000000e+02, 3.87298335e-01, 8.00000000e+00 }, new double[] { 2.28000000e+02, 1.04000000e+02, 3.87298335e-01, 1.40000000e+01 }, new double[] { 2.21000000e+02, 2.30000000e+01, 3.87298335e-01, 3.90000000e+01 }, new double[] { 2.31000000e+02, 1.60000000e+01, 3.87298335e-01, 4.00000000e+01 }, new double[] { 2.23000000e+02, 7.10000000e+01, 4.00000000e-01, 2.60000000e+01 }, new double[] { 2.30000000e+02, 1.44000000e+02, 4.00000000e-01, 1.50000000e+01 }, new double[] { 1.46000000e+02, 2.29000000e+02, 4.12310563e-01, 9.00000000e+00 }, new double[] { 2.34000000e+02, 2.35000000e+02, 4.12310563e-01, 2.40000000e+01 }, new double[] { 2.32000000e+02, 4.40000000e+01, 4.12310563e-01, 4.10000000e+01 }, new double[] { 2.37000000e+02, 3.30000000e+01, 4.12310563e-01, 4.20000000e+01 }, new double[] { 2.33000000e+02, 6.60000000e+01, 4.12310563e-01, 2.70000000e+01 }, new double[] { 2.38000000e+02, 3.20000000e+01, 4.24264069e-01, 4.30000000e+01 }, new double[] { 2.36000000e+02, 7.00000000e+01, 4.24264069e-01, 2.50000000e+01 }, new double[] { 2.41000000e+02, 7.20000000e+01, 4.24264069e-01, 2.60000000e+01 }, new double[] { 2.40000000e+02, 2.40000000e+01, 4.24264069e-01, 4.40000000e+01 }, new double[] { 7.70000000e+01, 2.42000000e+02, 4.24264069e-01, 2.70000000e+01 }, new double[] { 2.39000000e+02, 2.44000000e+02, 4.24264069e-01, 5.40000000e+01 }, new double[] { 2.45000000e+02, 1.10000000e+02, 4.24264069e-01, 5.50000000e+01 }, new double[] { 2.46000000e+02, 9.00000000e+01, 4.24264069e-01, 5.60000000e+01 }, new double[] { 2.47000000e+02, 6.30000000e+01, 4.24264069e-01, 5.70000000e+01 }, new double[] { 2.48000000e+02, 1.33000000e+02, 4.35889894e-01, 5.80000000e+01 }, new double[] { 5.30000000e+01, 8.10000000e+01, 4.35889894e-01, 2.00000000e+00 }, new double[] { 2.49000000e+02, 2.50000000e+02, 4.35889894e-01, 6.00000000e+01 }, new double[] { 2.51000000e+02, 1.32000000e+02, 4.35889894e-01, 6.10000000e+01 }, new double[] { 2.52000000e+02, 1.37000000e+02, 4.35889894e-01, 6.20000000e+01 }, new double[] { 7.30000000e+01, 1.36000000e+02, 4.35889894e-01, 2.00000000e+00 }, new double[] { 2.53000000e+02, 2.54000000e+02, 4.35889894e-01, 6.40000000e+01 }, new double[] { 2.55000000e+02, 7.90000000e+01, 4.47213595e-01, 6.50000000e+01 }, new double[] { 2.56000000e+02, 5.60000000e+01, 4.58257569e-01, 6.60000000e+01 }, new double[] { 2.57000000e+02, 1.21000000e+02, 4.58257569e-01, 6.70000000e+01 }, new double[] { 2.58000000e+02, 5.00000000e+01, 4.58257569e-01, 6.80000000e+01 }, new double[] { 2.59000000e+02, 1.02000000e+02, 4.58257569e-01, 6.90000000e+01 }, new double[] { 2.60000000e+02, 8.50000000e+01, 4.69041576e-01, 7.00000000e+01 }, new double[] { 2.61000000e+02, 1.25000000e+02, 4.69041576e-01, 7.10000000e+01 }, new double[] { 2.43000000e+02, 1.30000000e+01, 4.79583152e-01, 4.50000000e+01 }, new double[] { 2.62000000e+02, 8.40000000e+01, 4.89897949e-01, 7.20000000e+01 }, new double[] { 2.63000000e+02, 1.80000000e+01, 5.09901951e-01, 4.60000000e+01 }, new double[] { 2.64000000e+02, 1.30000000e+02, 5.09901951e-01, 7.30000000e+01 }, new double[] { 2.66000000e+02, 1.41000000e+02, 5.09901951e-01, 7.40000000e+01 }, new double[] { 2.67000000e+02, 6.40000000e+01, 5.19615242e-01, 7.50000000e+01 }, new double[] { 2.68000000e+02, 1.13000000e+02, 5.19615242e-01, 7.60000000e+01 }, new double[] { 2.69000000e+02, 1.14000000e+02, 5.19615242e-01, 7.70000000e+01 }, new double[] { 2.70000000e+02, 5.90000000e+01, 5.29150262e-01, 7.80000000e+01 }, new double[] { 2.65000000e+02, 2.20000000e+01, 5.38516481e-01, 4.70000000e+01 }, new double[] { 2.71000000e+02, 1.07000000e+02, 5.47722558e-01, 7.90000000e+01 }, new double[] { 2.73000000e+02, 1.05000000e+02, 5.47722558e-01, 8.00000000e+01 }, new double[] { 2.74000000e+02, 1.29000000e+02, 5.56776436e-01, 8.10000000e+01 }, new double[] { 2.72000000e+02, 1.40000000e+01, 5.56776436e-01, 4.80000000e+01 }, new double[] { 2.75000000e+02, 1.00000000e+02, 5.56776436e-01, 8.20000000e+01 }, new double[] { 2.77000000e+02, 1.19000000e+02, 5.83095189e-01, 8.30000000e+01 }, new double[] { 2.78000000e+02, 6.20000000e+01, 5.83095189e-01, 8.40000000e+01 }, new double[] { 2.79000000e+02, 8.70000000e+01, 6.08276253e-01, 8.50000000e+01 }, new double[] { 2.80000000e+02, 1.48000000e+02, 6.16441400e-01, 8.60000000e+01 }, new double[] { 2.81000000e+02, 1.08000000e+02, 6.16441400e-01, 8.70000000e+01 }, new double[] { 2.76000000e+02, 1.50000000e+01, 6.16441400e-01, 4.90000000e+01 }, new double[] { 2.82000000e+02, 9.30000000e+01, 6.48074070e-01, 8.80000000e+01 }, new double[] { 2.84000000e+02, 1.34000000e+02, 6.63324958e-01, 8.90000000e+01 }, new double[] { 2.85000000e+02, 6.80000000e+01, 6.78232998e-01, 9.00000000e+01 }, new double[] { 2.86000000e+02, 1.35000000e+02, 6.78232998e-01, 9.10000000e+01 }, new double[] { 2.87000000e+02, 1.22000000e+02, 6.78232998e-01, 9.20000000e+01 }, new double[] { 6.00000000e+01, 2.88000000e+02, 7.14142843e-01, 9.30000000e+01 }, new double[] { 5.70000000e+01, 2.89000000e+02, 7.21110255e-01, 9.40000000e+01 }, new double[] { 2.90000000e+02, 1.09000000e+02, 7.54983444e-01, 9.50000000e+01 }, new double[] { 2.83000000e+02, 4.10000000e+01, 7.81024968e-01, 5.00000000e+01 }, new double[] { 9.80000000e+01, 2.91000000e+02, 7.93725393e-01, 9.60000000e+01 }, new double[] { 2.93000000e+02, 1.06000000e+02, 8.77496439e-01, 9.70000000e+01 }, new double[] { 2.94000000e+02, 1.18000000e+02, 9.27361850e-01, 9.80000000e+01 }, new double[] { 2.95000000e+02, 1.31000000e+02, 9.32737905e-01, 9.90000000e+01 }, new double[] { 2.96000000e+02, 1.17000000e+02, 1.00498756e+00, 1.00000000e+02 }, new double[] { 2.92000000e+02, 2.97000000e+02, 1.64012195e+00, 1.50000000e+02 } }; // ensure the labeling method works and gets what the sklearn method would... assertTrue(MatUtils.equalsExactly(expected_labMat, HDBSCAN.label(expected_srted))); // expected sorted... ArrayList<CompQuadTup<Integer, Integer, Double, Integer>> expected_hlist = new ArrayList<>(); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(150, 151, 0.6097107608496923, 50)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(150, 152, 0.6097107608496923, 100)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 2, 3.7796447300922726, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 5, 2.6726124191242397, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 6, 3.1622776601683857, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 8, 2.886751345948128, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 10, 3.015113445777631, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 11, 3.3333333333333353, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 13, 2.0851441405707485, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 14, 1.796053020267749, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 15, 1.6222142113076248, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 16, 2.5819888974716076, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 18, 1.9611613513818411, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 19, 3.7796447300922766, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 20, 2.773500981126144, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 21, 3.7796447300922726, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 22, 1.85695338177052, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 23, 2.581988897471612, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 24, 2.35702260395516, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 31, 3.1622776601683804, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 32, 2.3570226039551616, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 33, 2.42535625036333, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 35, 3.0151134457776374, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 36, 2.8867513459481273, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 38, 3.3333333333333384, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 41, 1.2803687993289594, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 42, 3.3333333333333353, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 43, 2.6726124191242437, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 44, 2.4253562503633304, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 45, 3.7796447300922726, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 46, 3.3333333333333353, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 153, 3.7796447300922766, 11)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(151, 154, 3.7796447300922766, 10)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 50, 2.1821789023599227, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 53, 2.294157338705618, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 56, 2.1821789023599236, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 57, 1.386750490563073, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 59, 1.8898223650461363, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 60, 1.4002800840280099, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 62, 1.7149858514250882, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 63, 2.357022603955156, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 64, 1.9245008972987536, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 68, 1.4744195615489724, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 73, 2.2941573387056153, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 79, 2.2360679774997894, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 81, 2.294157338705618, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 84, 2.041241452319315, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 85, 2.132007163556105, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 87, 1.6439898730535734, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 90, 2.3570226039551567, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 93, 1.5430334996209187, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 98, 1.2598815766974234, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 100, 1.796053020267749, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 102, 2.1821789023599227, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 105, 1.8257418583505527, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 106, 1.1396057645963797, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 107, 1.8257418583505547, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 108, 1.6222142113076254, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 109, 1.3245323570650438, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 110, 2.3570226039551576, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 113, 1.9245008972987536, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 114, 1.9245008972987536, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 117, 0.995037190209989, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 118, 1.0783277320343838, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 119, 1.7149858514250889, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 121, 2.1821789023599227, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 122, 1.4744195615489704, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 125, 2.132007163556103, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 129, 1.7960530202677494, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 130, 1.9611613513818407, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 131, 1.0721125348377945, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 132, 2.294157338705618, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 133, 2.2941573387056184, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 134, 1.5075567228888174, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 135, 1.474419561548971, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 136, 2.2941573387056153, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 137, 2.294157338705617, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 141, 1.9611613513818398, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 148, 1.6222142113076257, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 155, 2.3570226039551576, 27)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(152, 156, 2.3570226039551576, 27)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(153, 0, 5.773502691896247, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(153, 4, 4.472135954999576, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(153, 7, 5.000000000000003, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(153, 17, 5.773502691896247, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(153, 26, 4.082482904638632, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(153, 27, 5.773502691896247, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(153, 28, 5.773502691896247, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(153, 39, 5.773502691896247, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(153, 40, 4.08248290463863, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(153, 48, 4.0824829046386295, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(153, 49, 4.47213595499958, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(154, 1, 5.773502691896246, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(154, 3, 4.082482904638627, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(154, 9, 5.773502691896246, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(154, 12, 5.773502691896245, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(154, 25, 4.47213595499958, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(154, 29, 4.472135954999572, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(154, 30, 5.773502691896246, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(154, 34, 5.773502691896246, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(154, 37, 5.773502691896246, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(154, 47, 4.472135954999572, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(155, 66, 2.4253562503633277, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(155, 71, 2.5000000000000013, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(155, 157, 2.5819888974716125, 16)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(155, 158, 2.5819888974716125, 9)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(156, 70, 2.3570226039551603, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(156, 72, 2.3570226039551603, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(156, 77, 2.3570226039551576, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(156, 159, 2.425356250363331, 15)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(156, 160, 2.425356250363331, 9)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 55, 3.0151134457776374, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 61, 2.7735009811261433, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 67, 2.773500981126145, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 69, 3.333333333333332, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 78, 2.7735009811261433, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 80, 3.333333333333332, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 82, 3.3333333333333317, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 88, 3.162277660168379, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 89, 3.3333333333333317, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 91, 2.7735009811261433, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 92, 3.333333333333332, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 94, 3.3333333333333317, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 95, 3.015113445777636, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 96, 3.333333333333332, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 97, 2.7735009811261433, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(157, 99, 3.333333333333332, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(158, 51, 2.672612419124244, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(158, 52, 2.886751345948124, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(158, 54, 2.6726124191242406, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(158, 58, 2.886751345948124, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(158, 65, 2.886751345948124, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(158, 74, 2.5819888974716125, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(158, 75, 2.886751345948124, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(158, 76, 2.672612419124244, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(158, 86, 2.886751345948124, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 103, 2.581988897471612, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 104, 2.581988897471612, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 111, 2.581988897471612, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 112, 2.6726124191242464, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 115, 2.5819888974716125, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 116, 2.581988897471612, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 120, 2.6726124191242464, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 124, 2.6726124191242446, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 128, 2.581988897471612, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 139, 2.6726124191242455, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 140, 2.6726124191242464, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 143, 2.6726124191242464, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 144, 2.5000000000000004, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 145, 2.6726124191242464, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(159, 147, 2.6726124191242464, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(160, 83, 2.672612419124246, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(160, 101, 3.0151134457776365, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(160, 123, 2.7735009811261446, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(160, 126, 2.581988897471612, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(160, 127, 3.0151134457776365, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(160, 138, 3.0151134457776365, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(160, 142, 3.0151134457776365, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(160, 146, 2.425356250363331, 1)); expected_hlist.add(new CompQuadTup<Integer, Integer, Double, Integer>(160, 149, 3.0151134457776365, 1)); // test the condense tree label ArrayList<CompQuadTup<Integer, Integer, Double, Integer>> condensed = HDBSCAN.LinkageTreeUtils .condenseTree(expected_labMat, 5); // Now sort it for the sake of comparing to the sklearn res... Collections.sort(condensed, new Comparator<QuadTup<Integer, Integer, Double, Integer>>() { @Override public int compare(QuadTup<Integer, Integer, Double, Integer> q1, QuadTup<Integer, Integer, Double, Integer> q2) { int cmp = q1.getFirst().compareTo(q2.getFirst()); if (cmp == 0) { cmp = q1.getSecond().compareTo(q2.getSecond()); if (cmp == 0) { cmp = q1.getThird().compareTo(q2.getThird()); if (cmp == 0) { return q1.getFourth().compareTo(q2.getFourth()); } return cmp; } return cmp; } return cmp; } }); for (int i = 0; i < condensed.size(); i++) { if (!condensed.get(i).almostEquals(expected_hlist.get(i))) { System.out.println(condensed.get(i)); System.out.println(expected_hlist.get(i)); fail(); } } // If we get here, the condensed labels works!! TreeMap<Integer, Double> stability = HDBSCAN.LinkageTreeUtils.computeStability(condensed); TreeMap<Integer, Double> exp_stab = new TreeMap<>(); exp_stab.put(150, Double.NaN); exp_stab.put(151, 128.9165546745262); exp_stab.put(152, 150.98635723043549); exp_stab.put(153, 13.48314205238124); exp_stab.put(154, 14.343459620092055); exp_stab.put(155, 5.8354683803643868); exp_stab.put(156, 1.6400075137961618); exp_stab.put(157, 8.4148537644752253); exp_stab.put(158, 1.7956828073404498); exp_stab.put(159, 2.99248898237368); exp_stab.put(160, Double.NaN); /* * Assert near equality... */ for (Map.Entry<Integer, Double> entry : exp_stab.entrySet()) { int key = entry.getKey(); double stab = entry.getValue(); if (Double.isNaN(stab) && Double.isNaN(stability.get(key))) continue; if (!Precision.equals(stab, stability.get(key), 1e-6)) { System.out.println(key + ", " + stab); System.out.println(key + ", " + stability.get(key)); fail(); } } // test the treeToLabels method... final int[] labs = new NoiseyLabelEncoder(HDBSCAN.treeToLabels(iris.getData(), labMat, 5)).fit() .getEncodedLabels(); assertTrue(VecUtils.equalsExactly(labs, expected_iris_labs)); } /** * Asser that when all of the matrix entries are exactly the same, * the algorithm will still converge, yet produce one label: 0 */ @Override @Test public void testAllSame() { final double[][] x = MatUtils.rep(-1, 3, 3); final Array2DRowRealMatrix X = new Array2DRowRealMatrix(x, false); int[] labels = new HDBSCAN(X, new HDBSCANParameters(1).setVerbose(true)).fit().getLabels(); assertTrue(new VecUtils.IntSeries(labels, Inequality.EQUAL_TO, labels[0]).all()); // could be noise... labels = new HDBSCAN(X, new HDBSCANParameters().setVerbose(true)).fit().getLabels(); assertTrue(new VecUtils.IntSeries(labels, Inequality.EQUAL_TO, labels[0]).all()); // could be noise... } @Test public void testValidMetrics() { HDBSCAN model = null; HDBSCAN_Algorithm algo; StandardScaler scaler = new StandardScaler().fit(iris); RealMatrix X = scaler.transform(iris); /* * Generic first... should theoretically allow similarity metrics as well... */ algo = HDBSCAN_Algorithm.GENERIC; for (DistanceMetric d : Distance.values()) { model = new HDBSCAN(X, new HDBSCANParameters().setAlgo(algo).setMetric(d)).fit(); if (!model.isValidMetric(d)) { assertTrue(model.hasWarnings()); assertTrue(model.dist_metric.equals(Distance.EUCLIDEAN)); } } for (Kernel k : KernelTestCases.all_kernels) { model = new HDBSCAN(iris, new HDBSCANParameters().setAlgo(algo).setMetric(k)).fit(); if (!model.isValidMetric(k)) { assertTrue(model.hasWarnings()); assertTrue(model.dist_metric.equals(Distance.EUCLIDEAN)); } } /* * Prims/Boruvka KD tree now -- first assert no warnings for KD valid and then assert warnings for others. */ for (HDBSCAN_Algorithm al : new HDBSCAN_Algorithm[] { HDBSCAN_Algorithm.PRIMS_KDTREE, HDBSCAN_Algorithm.BORUVKA_KDTREE }) { algo = al; boolean warnings_thrown = false; for (DistanceMetric d : new DistanceMetric[] { Distance.EUCLIDEAN, Distance.MANHATTAN, Distance.CHEBYSHEV, new MinkowskiDistance(2.0) }) { model = new HDBSCAN(iris, new HDBSCANParameters().setAlgo(algo).setMetric(d)).fit(); if (model.hasWarnings()) { warnings_thrown = true; System.out.println(d + ", " + model.getWarnings()); } } assertFalse(warnings_thrown); model = new HDBSCAN(iris, new HDBSCANParameters().setAlgo(algo).setMetric(Distance.CANBERRA)).fit(); assertTrue(model.hasWarnings()); assertTrue(model.dist_metric.equals(Distance.EUCLIDEAN)); // try a few sim metrics to assert the same model = new HDBSCAN(iris, new HDBSCANParameters().setAlgo(algo).setMetric(Similarity.COSINE)).fit(); assertTrue(model.hasWarnings()); assertTrue(model.dist_metric.equals(Distance.EUCLIDEAN)); } /* * Prims/Boruvka ball tree */ for (HDBSCAN_Algorithm al : new HDBSCAN_Algorithm[] { HDBSCAN_Algorithm.PRIMS_BALLTREE, HDBSCAN_Algorithm.BORUVKA_BALLTREE }) { algo = al; // need to use a smaller dataset here because haversine is an option... DataSet irisSmall = TestSuite.IRIS_DATASET.copy(); irisSmall.dropCol(3); irisSmall.dropCol(2); final Array2DRowRealMatrix small = irisSmall.getData(); for (Distance d : Distance.values()) { model = new HDBSCAN(small, new HDBSCANParameters().setAlgo(algo).setMetric(d)).fit(); if (model.hasWarnings()) { assertTrue(!model.isValidMetric(d)); } } // Try minkowski and haversine... model = new HDBSCAN(small, new HDBSCANParameters().setAlgo(algo).setMetric(new MinkowskiDistance(1.5))) .fit(); assertFalse(model.hasWarnings()); model = new HDBSCAN(small, new HDBSCANParameters().setAlgo(algo).setMetric(Distance.HAVERSINE.MI)) .fit(); assertFalse(model.hasWarnings()); // assert sim doesn't fly for ball tree... model = new HDBSCAN(small, new HDBSCANParameters().setAlgo(algo).setMetric(Similarity.COSINE)).fit(); assertTrue(model.dist_metric.equals(Distance.EUCLIDEAN)); } } @Test public void testAutoGeneric() { HDBSCAN h = new HDBSCAN(DATA, new HDBSCANParameters().setMetric(Distance.YULE)).fit(); assertTrue(h.algo.equals(HDBSCAN.HDBSCAN_Algorithm.GENERIC)); /* * ensure unsupported operation exception here */ boolean a = false; try { HDBSCAN.HDBSCAN_Algorithm.AUTO.isValidMetric(null); } catch (UnsupportedOperationException u) { a = true; } finally { assertTrue(a); } } @Test public void testBadLeafSize() { boolean a = false; try { new HDBSCAN(DATA, new HDBSCANParameters().setLeafSize(0)); } catch (IllegalArgumentException i) { a = true; } finally { assertTrue(a); } } @Test public void testAlpha() { /* * Ensuring it actually fits it for all algos... */ for (HDBSCAN_Algorithm h : HDBSCAN.HDBSCAN_Algorithm.values()) new HDBSCAN(DATA, new HDBSCANParameters().setAlgo(h).setAlpha(1.5)).fit(); } @Test public void testWrapAroundWorks() { boolean b = false; try { HDBSCAN.LinkageTreeUtils.wraparoundIdxGet(4, 6); } catch (ArrayIndexOutOfBoundsException i) { b = true; } finally { assertTrue(b); } } @Test public void testUnionFindToStringNotNull() { assertNotNull(new HDBSCAN.UnionFind(4).toString()); } @Test public void testDoubleFit() { HDBSCAN h = new HDBSCAN(DATA); /* * First catch the MNFE */ boolean a = false; try { h.getLabels(); } catch (ModelNotFitException m) { a = true; } finally { assertTrue(a); } assertTrue(h.getNumberOfIdentifiedClusters() == -1); assertTrue(h.getNumberOfNoisePoints() == -1); h.fit(); assertTrue(h.equals(h.fit())); assertFalse(h.equals(new Object())); HDBSCAN i = new HDBSCAN(DATA).fit(); assertTrue(h.getKey().equals(i.getKey()) || !h.equals(i)); assertFalse(h.equals(new HDBSCAN(DATA))); } @Test public void testModelNotFit() { boolean a = false; try { new HDBSCAN(DATA).getLabels(); } catch (ModelNotFitException m) { a = true; } finally { assertTrue(a); } } @Test public void testPredict() { HDBSCAN d = new HDBSCANParameters().fitNewModel(iris); /* * Test for dim mismatch */ Array2DRowRealMatrix newData = new Array2DRowRealMatrix( new double[][] { new double[] { 150, 150, 150, 150, 150 } }, false); boolean a = false; try { d.predict(newData); } catch (DimensionMismatchException dim) { a = true; } finally { assertTrue(a); } /* * Ensure unsupportedOperation */ newData = new Array2DRowRealMatrix(new double[][] { new double[] { 150, 150, 150, 150 } }, false); a = false; try { d.predict(newData); } catch (UnsupportedOperationException u) { a = true; } finally { assertTrue(a); } } }