/// <summary> /// Tests with the first formula /// </summary> private static void TestExample1(FunctionEvaluation addition, FunctionEvaluation multiplication, TerminalEvaluation variable) { Console.WriteLine("ADD([1.2*VAR_1], MULT([-2.9*VAR_0], [0.3*VAR_2]))"); Console.WriteLine("-------------------------------------------------"); const int variableCount = 3; const int sampleCount = 5; double[][] data = CreateTestData(variableCount, sampleCount); INode multNode = new FunctionalNode(multiplication, new List <INode>() { new TerminalNode(variable, 2, 0.3), new TerminalNode(variable, 0, -2.9) }); INode rootNode = new FunctionalNode(addition, new List <INode>() { multNode, new TerminalNode(variable, 1, 1.2) }); for (var sampleIdx = 0; sampleIdx < sampleCount; sampleIdx++) { double actual = rootNode.Evaluate(data, sampleIdx); double expected = ((1.2 * data[1][sampleIdx]) + (-2.9 * data[0][sampleIdx] * 0.3 * data[2][sampleIdx])); Console.WriteLine( $"ADD([1.2*{data[1][sampleIdx]}], " + $"MULT([-2.9*{data[0][sampleIdx]}], [0.3*{data[2][sampleIdx]}])) " + $"= {actual} " + $"= {expected} " + $"= {actual.AssertAlmostEqual(expected)} "); } }
/// <summary> /// Creates a terminal evaluation method /// </summary> /// <param name="arguments">the string[] representing the method arguments</param> /// <param name="resultType">the method result type</param> /// <param name="code">the source code of the method body</param> /// <returns>the created terminal evaluation method delegate</returns> private static TerminalEvaluation CreateTerminal(string[] arguments, Type resultType, string code) { CompilationResults compilationResults; TerminalEvaluation variable = FunctionalBasis.CompileTerminal <TerminalEvaluation>(code, arguments, resultType, out compilationResults); if (compilationResults.HasErrors) { throw new InvalidProgramException( $"Variable terminal evaluation creation failes: Error: {compilationResults.ErrorsExplanation}"); } return(variable); }
/// <summary> /// Tests with the second formula /// </summary> private static void TestExample2(FunctionEvaluation addition, FunctionEvaluation multiplication, TerminalEvaluation variable) { Console.WriteLine("ADD([2*VAR_0], MULT([4*VAR_1], ADD([-2*VAR_2], MULT([4*VAR_3], [-2*VAR_4]))))"); Console.WriteLine("-------------------------------------------------"); const int variableCount = 5; const int sampleCount = 5; double[][] data = CreateTestData(variableCount, sampleCount); INode mult0Node = new FunctionalNode(multiplication, new List <INode>() { new TerminalNode(variable, 4, -2), new TerminalNode(variable, 3, 4) }); INode add1Node = new FunctionalNode(addition, new List <INode>() { mult0Node, new TerminalNode(variable, 2, -2) }); INode mult2Node = new FunctionalNode(multiplication, new List <INode>() { add1Node, new TerminalNode(variable, 1, 4) }); INode rootNode = new FunctionalNode(addition, new List <INode>() { mult2Node, new TerminalNode(variable, 0, 2) }); for (var sampleIdx = 0; sampleIdx < sampleCount; sampleIdx++) { double actual = rootNode.Evaluate(data, sampleIdx); double expected = ((2 * data[0][sampleIdx]) + ((4 * data[1][sampleIdx]) * (((-2) * data[2][sampleIdx]) + (4 * data[3][sampleIdx] * (-2) * data[4][sampleIdx])))); Console.WriteLine( $"ADD([2*{data[0][sampleIdx]}], " + $"MULT([4*{data[1][sampleIdx]}], " + $"ADD([-2*{data[2][sampleIdx]}], " + $"MULT([4*{data[3][sampleIdx]}], [-2*{data[4][sampleIdx]}])))) " + $"= {actual} " + $"= {expected} " + $"= {actual.AssertAlmostEqual(expected)} "); } }
static void Main(string[] args) { // create varaible function TerminalEvaluation variable = CreateTerminal(new [] { "double[][] data", "int varIdx", "int sampleIdx", "double coefficient" }, typeof(double), "return data[varIdx][sampleIdx] * coefficient;"); // create addition function FunctionEvaluation addition = CreateFunctional("double[] data", typeof(double), "double result = 0.0; for (int i = 0; i < data.Length; i++) result += data[i]; return result;"); // create multiplication function FunctionEvaluation multiplication = CreateFunctional("double[] data", typeof(double), "double result = 1.0; for (int i = 0; i < data.Length; i++) result *= data[i]; return result;"); Console.WriteLine("-------------------------------------------------"); Console.WriteLine("Test functions:"); Console.WriteLine("-------------------------------------------------"); double[][] data = CreateTestData(4, 4); Console.WriteLine("TestEvaluation(() => addition([1,2,3]))"); Console.WriteLine("-------------------------------------------------"); TestEvaluation(() => addition(new double[] { 1, 2, 3 }), 6.0); Console.WriteLine("-------------------------------------------------"); Console.WriteLine("TestEvaluation(() => multiplication([1,2,3]))"); Console.WriteLine("-------------------------------------------------"); TestEvaluation(() => multiplication(new double[] { 1, 2, 3 }), 6.0); Console.WriteLine("-------------------------------------------------"); Console.WriteLine("TestEvaluation(() => varaible([1,2,3], 0, 2, 2))"); Console.WriteLine("-------------------------------------------------"); TestEvaluation(() => variable(data, 0, 2, 2.0), (data[0][2] * 2.0)); Console.WriteLine("-------------------------------------------------"); Console.WriteLine(); Console.WriteLine("-------------------------------------------------"); Console.WriteLine("Test evaluation trees:"); Console.WriteLine("-------------------------------------------------"); Console.WriteLine("TestExample1()"); Console.WriteLine("-------------------------------------------------"); TestExample1(addition, multiplication, variable); Console.WriteLine("-------------------------------------------------"); Console.WriteLine("TestExample2()"); Console.WriteLine("-------------------------------------------------"); TestExample2(addition, multiplication, variable); Console.WriteLine("-------------------------------------------------"); }