using System.Collections.Generic; using System.Linq; using HeuristicLab.Algorithms.DataAnalysis.FastFunctionExtraction; using HeuristicLab.Data; using HeuristicLab.Problems.DataAnalysis; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace UnitTests { [TestClass] public class BasisFunctionUtilsTests { private static readonly HashSet defaultExponents = new HashSet { 0.5, 1.0, 2.0 }; private static readonly HashSet defaultNonlinFuncs = new HashSet { NonlinearOperator.Abs, NonlinearOperator.Log, NonlinearOperator.Sin, NonlinearOperator.Cos }; private static readonly Approach defaultApproach = new Approach(false, false, false, false, false, defaultExponents, defaultNonlinFuncs, 10, 1, 0.2, 0.8, 5); private static readonly IDataset defaultDataset = new Dataset(new string[] { "x1", "x2", "x3", "y" }, new double[,] { { 1, 1, -3, 7 }, { 2, 3, -1, 12 }, { 3, -3, 0, 0 }, { 4, -2, 1, -8 }, { 15, -8, 5, 2 } }); [TestMethod] public void CreateBasisFunctions_ZeroFeatures_AllFalse() { var data = new RegressionProblemData(defaultDataset, new string[] { }, "y"); var basisFunctions = BFUtils.CreateBasisFunctions(data, defaultApproach); Assert.AreEqual(basisFunctions.Count(), 0); } [TestMethod] public void CreateBasisFunctions_TwoFeatures_All_False() { var data = new RegressionProblemData(defaultDataset, new string[] { "x1", "x2" }, "y"); var basisFunctions = BFUtils.CreateBasisFunctions(data, defaultApproach); Assert.AreEqual(basisFunctions.Count(), 2); var bf = basisFunctions.Last(); Assert.AreEqual(bf, new SimpleBasisFunction("x2")); } [TestMethod] public void CreateBasisFunctions_TwoFeatures_AllowExponents() { var appr = defaultApproach; appr.AllowExp = true; appr.Exponents = defaultExponents; var data = new RegressionProblemData(defaultDataset, new string[] { "x1", "x2" }, "y"); var basisFunctions = BFUtils.CreateBasisFunctions(data, appr); // -1 because you sqrt("x2") is not valid Assert.AreEqual(2 * appr.Exponents.Count - 1, basisFunctions.Count()); var bf = basisFunctions.Last(); Assert.AreEqual(bf, new SimpleBasisFunction("x2", exponent: defaultExponents.Last())); } [TestMethod] public void CreateSimpleBases_NoFeatures() { var data = new RegressionProblemData(defaultDataset, new string[] { }, "y"); var bfs = BFUtils.CreateSimpleBases(data, new HashSet { 1, 2, 0.5 }, new HashSet { NonlinearOperator.Abs }).ToArray(); // num_features * num_exponents * num_nonlinearOperators Assert.AreEqual(0 * 3 * 1, bfs.Length); } [TestMethod] public void CreateSimpleBases_NoExponents() { var data = new RegressionProblemData(defaultDataset, new string[] { "x1" }, "y"); var bfs = BFUtils.CreateSimpleBases(data, new HashSet { }, new HashSet { NonlinearOperator.None }).ToArray(); // num_features * num_exponents * num_nonlinearOperators Assert.AreEqual(1 * 0 * 1, bfs.Length); bfs = BFUtils.CreateSimpleBases(data, new HashSet { 1 }, new HashSet { }).ToArray(); Assert.AreEqual(1 * 1 * 0, bfs.Length); bfs = BFUtils.CreateSimpleBases(data, new HashSet { 1 }, new HashSet { NonlinearOperator.None }).ToArray(); Assert.AreEqual(1 * 1 * 1, bfs.Length); Assert.AreEqual(bfs.First(), new SimpleBasisFunction(feature: "x1", exponent: 1, op: NonlinearOperator.None, isNominator: true)); bfs = BFUtils.CreateSimpleBases(data, new HashSet { 2, 3 }, new HashSet { NonlinearOperator.None, NonlinearOperator.Log }).ToArray(); Assert.AreEqual(1 * 2 * 2, bfs.Length); Assert.AreEqual(bfs.First(), new SimpleBasisFunction(feature: "x1", exponent: 2, op: NonlinearOperator.None, isNominator: true)); } [TestMethod] public void CreateSimpleBases_NoNonlinearOperator() { var data = new RegressionProblemData(defaultDataset, new string[] { "x1", "x2" }, "y"); var bfs = BFUtils.CreateSimpleBases(data, new HashSet { 1, 2, 3 }, new HashSet { }).ToArray(); // num_features * num_exponents * num_nonlinearOperators Assert.AreEqual(2 * 3 * 0, bfs.Length); } [TestMethod] public void CreateSimpleBases_ManyFeatures() { var data = new RegressionProblemData(defaultDataset, new string[] { "x1", "x2" }, "y"); var bfs = BFUtils.CreateSimpleBases(data, new HashSet { 1, 2, 3 }, new HashSet { NonlinearOperator.None }).ToArray(); // num_features * num_exponents * (num_operators + 1) Assert.AreEqual(2 * 3 * 1, bfs.Length); } [TestMethod] public void CreateHingeBases() { var data = new RegressionProblemData(defaultDataset, new string[] { "x1", "x2" }, "y"); var bfs = BFUtils.CreateSimpleBases(data, new HashSet { 1, 2 }, new HashSet { NonlinearOperator.None, NonlinearOperator.Sin }).ToArray(); var numSimpleBasisFuncs = bfs.Length; int num_thrs = 2; var hingeBases = BFUtils.CreateHingeBases(data, bfs, 0, 1, num_thrs).ToArray(); Assert.AreEqual(2 * numSimpleBasisFuncs * num_thrs, hingeBases.Length); } [TestMethod] public void CreateHingeBases_CheckOtherBFValues() { var data = new RegressionProblemData(defaultDataset, new string[] { "x3" }, "y"); var bfs = BFUtils.CreateSimpleBases(data, new HashSet { 1 }, new HashSet { NonlinearOperator.None }).ToArray(); Assert.AreEqual(1, bfs.Length); int num_thrs = 2; var partition = new IntRange(0, data.Dataset.Rows); var hingeBases = BFUtils.CreateHingeBases(data, bfs, 0, 1, num_thrs, partition).ToArray(); Assert.AreEqual(2 * 1 * num_thrs, hingeBases.Length); foreach(var hingeBase in hingeBases) { Assert.AreEqual(hingeBase.Feature, "x3"); Assert.AreEqual(hingeBase.Exponent, 1); Assert.AreEqual(hingeBase.IsDenominator, true); } } [TestMethod] public void CreateHingeBases_CheckArbitraryStartThrAndEndThr() { var data = new RegressionProblemData(defaultDataset, new string[] { "x3" }, "y"); var bfs = BFUtils.CreateSimpleBases(data, new HashSet { 1 }, new HashSet { NonlinearOperator.None }).ToArray(); Assert.AreEqual(1, bfs.Length); int num_thrs = 2; var partition = new IntRange(0, data.Dataset.Rows); var hingeBases = BFUtils.CreateHingeBases(data, bfs, 0.5, 0.75, num_thrs, partition).ToArray(); Assert.AreEqual(2 * num_thrs, hingeBases.Length); Assert.AreEqual(hingeBases.Count(hingeBase => hingeBase.Threshold == 1), 2); Assert.AreEqual(hingeBases.Count(hingeBase => hingeBase.Threshold == 3), 2); } [TestMethod] public void CreateHingeBases_CheckManyThrs() { var data = new RegressionProblemData(defaultDataset, new string[] { "x3" }, "y"); var bfs = BFUtils.CreateSimpleBases(data, new HashSet { 1 }, new HashSet { NonlinearOperator.None }).ToArray(); Assert.AreEqual(1, bfs.Length); int num_thrs = 9; var partition = new IntRange(0, data.Dataset.Rows); // i.e. from -11 to 13 double start_thr = -1; double end_thr = 2; var hingeBases = BFUtils.CreateHingeBases(data, bfs, start_thr, end_thr, num_thrs, partition).ToArray(); Assert.AreEqual(2 * num_thrs, hingeBases.Length); Assert.AreEqual(hingeBases.Count(hingeBase => hingeBase.Threshold == -11), 2); Assert.AreEqual(hingeBases.Count(hingeBase => hingeBase.Threshold == -8), 2); Assert.AreEqual(hingeBases.Count(hingeBase => hingeBase.Threshold == 13), 2); } } }