Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tests/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs @ 5574

Last change on this file since 5574 was 5574, checked in by gkronber, 13 years ago

#1418 Added test projects for data-analysis and symbolic data-analysis plugin. Moved grammars to version 3.4. Fixed bugs in interpretation and simplification of 'not' symbols.

File size: 12.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Globalization;
25using System.Linq;
26using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
27using HeuristicLab.Problems.DataAnalysis.Symbolic;
28using HeuristicLab.Random;
29using Microsoft.VisualStudio.TestTools.UnitTesting;
30namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Tests {
31
32
33  /// <summary>
34  ///This is a test class for SimpleArithmeticExpressionInterpreter and is intended
35  ///to contain all SimpleArithmeticExpressionInterpreter Unit Tests
36  ///</summary>
37  [TestClass()]
38  public class SymbolicDataAnalysisExpressionTreeInterpreterTest {
39    private const int N = 1000;
40    private const int Rows = 1000;
41    private const int Columns = 50;
42    private TestContext testContextInstance;
43
44    /// <summary>
45    ///Gets or sets the test context which provides
46    ///information about and functionality for the current test run.
47    ///</summary>
48    public TestContext TestContext {
49      get {
50        return testContextInstance;
51      }
52      set {
53        testContextInstance = value;
54      }
55    }
56
57    [TestMethod]
58    public void FullGrammarSimpleArithmeticExpressionInterpreterPerformanceTest() {
59      var twister = new MersenneTwister(31415);
60      var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
61      var grammar = new GlobalSymbolicExpressionGrammar(new FullFunctionalExpressionGrammar());
62      grammar.MaxFunctionArguments = 0;
63      grammar.MaxFunctionDefinitions = 0;
64      grammar.MinFunctionArguments = 0;
65      grammar.MinFunctionDefinitions = 0;
66      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
67      double[] estimation = new double[Rows];
68      foreach (ISymbolicExpressionTree tree in randomTrees) {
69        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
70      }
71      SymbolicDataAnalysisExpressionTreeInterpreter interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
72      double nodesPerSec = Util.CalculateEvaluatedNodesPerSec(randomTrees, interpreter, dataset, 3);
73      Assert.IsTrue(nodesPerSec > 15.0e6); // evaluated nodes per seconds must be larger than 15mNodes/sec
74    }
75
76    [TestMethod]
77    public void ArithmeticGrammarSimpleArithmeticExpressionInterpreterPerformanceTest() {
78      var twister = new MersenneTwister(31415);
79      var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
80      var grammar = new GlobalSymbolicExpressionGrammar(new ArithmeticExpressionGrammar());
81      grammar.MaxFunctionArguments = 0;
82      grammar.MaxFunctionDefinitions = 0;
83      grammar.MinFunctionArguments = 0;
84      grammar.MinFunctionDefinitions = 0;
85      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
86      double[] estimation = new double[Rows];
87      foreach (SymbolicExpressionTree tree in randomTrees) {
88        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
89      }
90      SymbolicDataAnalysisExpressionTreeInterpreter interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
91      double nodesPerSec = Util.CalculateEvaluatedNodesPerSec(randomTrees, interpreter, dataset, 3);
92      Assert.IsTrue(nodesPerSec > 15.0e6); // evaluated nodes per seconds must be larger than 15mNodes/sec
93    }
94
95
96    /// <summary>
97    ///A test for Evaluate
98    ///</summary>
99    [TestMethod]
100    public void SimpleArithmeticExpressionInterpreterEvaluateTest() {
101
102      Dataset ds = new Dataset(new string[] { "Y", "A", "B" }, new double[,] {
103        { 1.0, 1.0, 1.0 },
104        { 2.0, 2.0, 2.0 },
105        { 3.0, 1.0, 2.0 }
106      });
107
108      SymbolicDataAnalysisExpressionTreeInterpreter interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
109
110      // constants
111      Evaluate(interpreter, ds, "(+ 1.5 3.5)", 0, 5.0);
112
113      // variables
114      Evaluate(interpreter, ds, "(variable 2.0 a)", 0, 2.0);
115      Evaluate(interpreter, ds, "(variable 2.0 a)", 1, 4.0);
116
117
118      // addition
119      Evaluate(interpreter, ds, "(+ (variable 2.0 a ))", 1, 4.0);
120      Evaluate(interpreter, ds, "(+ (variable 2.0 a ) (variable 3.0 b ))", 0, 5.0);
121      Evaluate(interpreter, ds, "(+ (variable 2.0 a ) (variable 3.0 b ))", 1, 10.0);
122      Evaluate(interpreter, ds, "(+ (variable 2.0 a) (variable 3.0 b ))", 2, 8.0);
123      Evaluate(interpreter, ds, "(+ 8.0 2.0 2.0)", 0, 12.0);
124
125      // subtraction
126      Evaluate(interpreter, ds, "(- (variable 2.0 a ))", 1, -4.0);
127      Evaluate(interpreter, ds, "(- (variable 2.0 a ) (variable 3.0 b))", 0, -1.0);
128      Evaluate(interpreter, ds, "(- (variable 2.0 a ) (variable 3.0 b ))", 1, -2.0);
129      Evaluate(interpreter, ds, "(- (variable 2.0 a ) (variable 3.0 b ))", 2, -4.0);
130      Evaluate(interpreter, ds, "(- 8.0 2.0 2.0)", 0, 4.0);
131
132      // multiplication
133      Evaluate(interpreter, ds, "(* (variable 2.0 a ))", 0, 2.0);
134      Evaluate(interpreter, ds, "(* (variable 2.0 a ) (variable 3.0 b ))", 0, 6.0);
135      Evaluate(interpreter, ds, "(* (variable 2.0 a ) (variable 3.0 b ))", 1, 24.0);
136      Evaluate(interpreter, ds, "(* (variable 2.0 a ) (variable 3.0 b ))", 2, 12.0);
137      Evaluate(interpreter, ds, "(* 8.0 2.0 2.0)", 0, 32.0);
138
139      // division
140      Evaluate(interpreter, ds, "(/ (variable 2.0 a ))", 1, 1.0 / 4.0);
141      Evaluate(interpreter, ds, "(/ (variable 2.0 a ) 2.0)", 0, 1.0);
142      Evaluate(interpreter, ds, "(/ (variable 2.0 a ) 2.0)", 1, 2.0);
143      Evaluate(interpreter, ds, "(/ (variable 3.0 b ) 2.0)", 2, 3.0);
144      Evaluate(interpreter, ds, "(/ 8.0 2.0 2.0)", 0, 2.0);
145
146      // gt
147      Evaluate(interpreter, ds, "(> (variable 2.0 a) 2.0)", 0, -1.0);
148      Evaluate(interpreter, ds, "(> 2.0 (variable 2.0 a))", 0, -1.0);
149      Evaluate(interpreter, ds, "(> (variable 2.0 a) 1.9)", 0, 1.0);
150      Evaluate(interpreter, ds, "(> 1.9 (variable 2.0 a))", 0, -1.0);
151      //Evaluate(interpreter, ds, "(> (sqrt -1.0) (log -1.0))", 0, -1.0); // (> nan nan) should be false
152
153      // lt
154      Evaluate(interpreter, ds, "(< (variable 2.0 a) 2.0)", 0, -1.0);
155      Evaluate(interpreter, ds, "(< 2.0 (variable 2.0 a))", 0, -1.0);
156      Evaluate(interpreter, ds, "(< (variable 2.0 a) 1.9)", 0, -1.0);
157      Evaluate(interpreter, ds, "(< 1.9 (variable 2.0 a))", 0, 1.0);
158      //Evaluate(interpreter, ds, "(< (sqrt -1,0) (log -1,0))", 0, -1.0); // (< nan nan) should be false
159
160      // If
161      Evaluate(interpreter, ds, "(if -10.0 2.0 3.0)", 0, 3.0);
162      Evaluate(interpreter, ds, "(if -1.0 2.0 3.0)", 0, 3.0);
163      Evaluate(interpreter, ds, "(if 0.0 2.0 3.0)", 0, 3.0);
164      Evaluate(interpreter, ds, "(if 1.0 2.0 3.0)", 0, 2.0);
165      Evaluate(interpreter, ds, "(if 10.0 2.0 3.0)", 0, 2.0);
166      // Evaluate(interpreter, ds, "(if (sqrt -1.0) 2.0 3.0)", 0, 3.0); // if(nan) should return the else branch
167
168      // NOT
169      Evaluate(interpreter, ds, "(not -1.0)", 0, 1.0);
170      Evaluate(interpreter, ds, "(not -2.0)", 0, 1.0);
171      Evaluate(interpreter, ds, "(not 1.0)", 0, -1.0);
172      Evaluate(interpreter, ds, "(not 2.0)", 0, -1.0);
173      Evaluate(interpreter, ds, "(not 0.0)", 0, 1.0);
174
175      // AND
176      Evaluate(interpreter, ds, "(and -1.0 -2.0)", 0, -1.0);
177      Evaluate(interpreter, ds, "(and -1.0 2.0)", 0, -1.0);
178      Evaluate(interpreter, ds, "(and 1.0 -2.0)", 0, -1.0);
179      Evaluate(interpreter, ds, "(and 1.0 0.0)", 0, -1.0);
180      Evaluate(interpreter, ds, "(and 0.0 0.0)", 0, -1.0);
181      Evaluate(interpreter, ds, "(and 1.0 2.0)", 0, 1.0);
182      Evaluate(interpreter, ds, "(and 1.0 2.0 3.0)", 0, 1.0);
183      Evaluate(interpreter, ds, "(and 1.0 -2.0 3.0)", 0, -1.0);
184
185      // OR
186      Evaluate(interpreter, ds, "(or -1.0 -2.0)", 0, -1.0);
187      Evaluate(interpreter, ds, "(or -1.0 2.0)", 0, 1.0);
188      Evaluate(interpreter, ds, "(or 1.0 -2.0)", 0, 1.0);
189      Evaluate(interpreter, ds, "(or 1.0 2.0)", 0, 1.0);
190      Evaluate(interpreter, ds, "(or 0.0 0.0)", 0, -1.0);
191      Evaluate(interpreter, ds, "(or -1.0 -2.0 -3.0)", 0, -1.0);
192      Evaluate(interpreter, ds, "(or -1.0 -2.0 3.0)", 0, 1.0);
193
194      // sin, cos, tan
195      Evaluate(interpreter, ds, "(sin " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, 0.0);
196      Evaluate(interpreter, ds, "(sin 0.0)", 0, 0.0);
197      Evaluate(interpreter, ds, "(cos " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, -1.0);
198      Evaluate(interpreter, ds, "(cos 0.0)", 0, 1.0);
199      Evaluate(interpreter, ds, "(tan " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, Math.Tan(Math.PI));
200      Evaluate(interpreter, ds, "(tan 0.0)", 0, Math.Tan(Math.PI));
201
202      // exp, log
203      Evaluate(interpreter, ds, "(log (exp 7.0))", 0, Math.Log(Math.Exp(7)));
204      Evaluate(interpreter, ds, "(exp (log 7.0))", 0, Math.Exp(Math.Log(7)));
205      Evaluate(interpreter, ds, "(log -3.0)", 0, Math.Log(-3));
206
207      // mean
208      Evaluate(interpreter, ds, "(mean -1.0 1.0 -1.0)", 0, -1.0 / 3.0);
209
210      // ADF     
211      Evaluate(interpreter, ds, @"(PROG
212                                    (MAIN
213                                      (CALL ADF0))
214                                    (defun ADF0 1.0))", 1, 1.0);
215      Evaluate(interpreter, ds, @"(PROG
216                                    (MAIN
217                                      (* (CALL ADF0) (CALL ADF0)))
218                                    (defun ADF0 2.0))", 1, 4.0);
219      Evaluate(interpreter, ds, @"(PROG
220                                    (MAIN
221                                      (CALL ADF0 2.0 3.0))
222                                    (defun ADF0
223                                      (+ (ARG 0) (ARG 1))))", 1, 5.0);
224      Evaluate(interpreter, ds, @"(PROG
225                                    (MAIN (CALL ADF1 2.0 3.0))
226                                    (defun ADF0
227                                      (- (ARG 1) (ARG 0)))
228                                    (defun ADF1
229                                      (+ (CALL ADF0 (ARG 1) (ARG 0))
230                                         (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
231      Evaluate(interpreter, ds, @"(PROG
232                                    (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
233                                    (defun ADF0
234                                      (- (ARG 1) (ARG 0)))
235                                    (defun ADF1                                                                             
236                                      (CALL ADF0 (ARG 1) (ARG 0))))", 1, 1.0);
237      Evaluate(interpreter, ds, @"(PROG
238                                    (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
239                                    (defun ADF0
240                                      (- (ARG 1) (ARG 0)))
241                                    (defun ADF1                                                                             
242                                      (+ (CALL ADF0 (ARG 1) (ARG 0))
243                                         (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
244    }
245
246    private void Evaluate(SymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds, string expr, int index, double expected) {
247      var importer = new SymbolicExpressionImporter();
248      ISymbolicExpressionTree tree = importer.Import(expr);
249
250      double actual = interpreter.GetSymbolicExpressionTreeValues(tree, ds, Enumerable.Range(index, 1)).First();
251
252      Assert.AreEqual(expected, actual, 1.0E-12, expr);
253    }
254  }
255}
Note: See TracBrowser for help on using the repository browser.