public void FromDataTest() { Accord.Math.Random.Generator.Seed = 0; double[][] points = Vector.Interval(1.0, 7.0).ToJagged(); var tree = SPTree.FromData(points); Assert.IsTrue(tree.Root.IsCorrect()); var nodes = tree.ToList(); foreach (var p in points) { Assert.IsTrue(nodes.Where(x => x.IsLeaf) .Select(x => x.Position) .Contains(p, new ArrayComparer <double>())); } points = Vector.Shuffled(Vector.Range(1.0, 8.0)).ToJagged(); tree = SPTree.FromData(points); Assert.IsTrue(tree.Root.IsCorrect()); nodes = tree.ToList(); foreach (var p in points) { Assert.IsTrue(nodes.Select(x => x.Position).Contains(p)); } }
// Compute gradient of the t-SNE cost function (using Barnes-Hut algorithm) internal static void computeGradient(double[][] P, int[] inp_row_P, int[] inp_col_P, double[] inp_val_P, double[][] Y, int N, int D, double[][] dC, double theta) { // Construct space-partitioning tree on current map var tree = SPTree.FromData(Y); // Compute all terms required for t-SNE gradient var pos_f = Jagged.Create <double>(N, D); var neg_f = Jagged.Create <double>(N, D); tree.ComputeEdgeForces(Y, inp_row_P, inp_col_P, inp_val_P, pos_f); double sum_Q = 0.0; for (int n = 0; n < Y.Length; n++) { tree.ComputeNonEdgeForces(Y[n], theta, neg_f[n], ref sum_Q); } // Compute final t-SNE gradient for (int i = 0; i < dC.Length; i++) { for (int j = 0; j < dC[i].Length; j++) { dC[i][j] = pos_f[i][j] - (neg_f[i][j] / sum_Q); } } }
public void FromDataTest2() { Accord.Math.Random.Generator.Seed = 0; double[][] points = { new double[] { 2, 3 }, new double[] { 5, 4 }, new double[] { 9, 6 }, new double[] { 4, 7 }, new double[] { 8, 1 }, new double[] { 7, 2 }, }; var tree = SPTree.FromData(points); var nodes = tree.ToList(); Assert.IsTrue(tree.Root.IsCorrect()); foreach (var p in points) { Assert.IsTrue(nodes.Where(x => x.IsLeaf && !x.IsEmpty) .Select(x => x.Position) .Contains(p, new ArrayComparer <double>())); } Assert.IsTrue(tree.Root.IsCorrect()); Assert.IsFalse(tree.Root.IsLeaf); Assert.IsNull(tree.Root.Position); Assert.AreEqual(5.8333333333333339, tree.Root.CenterOfMass[0]); Assert.AreEqual(3.8333333333333339, tree.Root.CenterOfMass[1]); Assert.AreEqual(4, tree.Root.Children.Length); Assert.AreEqual(9, tree.Root.Children[0].Position[0]); Assert.AreEqual(6, tree.Root.Children[0].Position[1]); Assert.IsNull(tree.Root.Children[1].Position); Assert.AreEqual(4.5, tree.Root.Children[1].CenterOfMass[0]); Assert.AreEqual(5.5, tree.Root.Children[1].CenterOfMass[1]); }
// Evaluate t-SNE cost function (approximately) internal static double evaluateError(int[] row_P, int[] col_P, double[] val_P, double[][] Y, int N, int D, double theta) { // Get estimate of normalization term var tree = SPTree.FromData(Y); double[] buff = new double[D]; double sum_Q = 0.0; for (int n = 0; n < Y.Length; n++) { tree.ComputeNonEdgeForces(Y[n], theta, buff, ref sum_Q); } // Loop over all edges to compute t-SNE error double C = 0.0; for (int n = 0; n < N; n++) { for (int i = row_P[n]; i < row_P[n + 1]; i++) { int j = col_P[i]; for (int d = 0; d < buff.Length; d++) { buff[d] = Y[n][d]; } for (int d = 0; d < buff.Length; d++) { buff[d] -= Y[j][d]; } double Q = 0.0; for (int d = 0; d < buff.Length; d++) { Q += buff[d] * buff[d]; } Q = (1.0 / (1.0 + Q)) / sum_Q; C += val_P[i] * System.Math.Log((val_P[i] + FLT_MIN) / (Q + FLT_MIN)); } } return(C); }