Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SimpleArithmeticExpressionInterpreterTest.cs @ 3841

Last change on this file since 3841 was 3841, checked in by gkronber, 14 years ago

Extended set of available functions for symbolic regression and added test cases for the extended function set. #1013

File size: 11.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.IO;
23using System;
24using HeuristicLab.Random;
25using System.Collections.Generic;
26using System.Diagnostics;
27using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
28using HeuristicLab.Problems.DataAnalysis.Symbolic;
29using Microsoft.VisualStudio.TestTools.UnitTesting;
30using System.Linq;
31using System.Globalization;
32namespace HeuristicLab.Problems.DataAnalysis.Tests {
33
34
35  /// <summary>
36  ///This is a test class for SimpleArithmeticExpressionInterpreter and is intended
37  ///to contain all SimpleArithmeticExpressionInterpreter Unit Tests
38  ///</summary>
39  [TestClass()]
40  public class SimpleArithmeticExpressionInterpreterTest {
41    private const int N = 1000;
42    private const int Rows = 1000;
43    private const int Columns = 50;
44    private static SymbolicExpressionTree[] randomTrees;
45    private static Dataset dataset;
46    private static MersenneTwister twister;
47    private TestContext testContextInstance;
48
49    /// <summary>
50    ///Gets or sets the test context which provides
51    ///information about and functionality for the current test run.
52    ///</summary>
53    public TestContext TestContext {
54      get {
55        return testContextInstance;
56      }
57      set {
58        testContextInstance = value;
59      }
60    }
61
62    [ClassInitialize()]
63    public static void CreateRandomTrees(TestContext testContext) {
64      twister = new MersenneTwister();
65      dataset = Util.CreateRandomDataset(twister, Rows, Columns);
66      var grammar = new GlobalSymbolicExpressionGrammar(new FullFunctionalExpressionGrammar());
67      grammar.MaxFunctionArguments = 0;
68      grammar.MaxFunctionDefinitions = 0;
69      grammar.MinFunctionArguments = 0;
70      grammar.MinFunctionDefinitions = 0;
71      randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
72    }
73
74
75    [TestMethod()]
76    public void SimpleArithmeticExpressionInterpreterPerformanceTest() {
77      double[] estimation = new double[Rows];
78      foreach (SymbolicExpressionTree tree in randomTrees) {
79        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
80      }
81      SimpleArithmeticExpressionInterpreter interpreter = new SimpleArithmeticExpressionInterpreter();
82      Util.EvaluateTrees(randomTrees, interpreter, dataset, 10);
83    }
84
85
86    /// <summary>
87    ///A test for Evaluate
88    ///</summary>
89    [TestMethod()]
90    public void SimpleArithmeticExpressionInterpreterEvaluateTest() {
91
92      Dataset ds = new Dataset(new string[] { "Y", "A", "B" }, new double[,] {
93        { 1.0, 1.0, 1.0 },
94        { 2.0, 2.0, 2.0 },
95        { 3.0, 1.0, 2.0 }
96      });
97
98      SimpleArithmeticExpressionInterpreter interpreter = new SimpleArithmeticExpressionInterpreter();
99
100      // constants
101      Evaluate(interpreter, ds, "(+ 1.5 3.5)", 0, 5.0);
102
103      // variables
104      Evaluate(interpreter, ds, "(variable 2.0 a)", 0, 2.0);
105      Evaluate(interpreter, ds, "(variable 2.0 a)", 1, 4.0);
106
107
108      // addition
109      Evaluate(interpreter, ds, "(+ (variable 2.0 a ))", 1, 4.0);
110      Evaluate(interpreter, ds, "(+ (variable 2.0 a ) (variable 3.0 b ))", 0, 5.0);
111      Evaluate(interpreter, ds, "(+ (variable 2.0 a ) (variable 3.0 b ))", 1, 10.0);
112      Evaluate(interpreter, ds, "(+ (variable 2.0 a) (variable 3.0 b ))", 2, 8.0);
113      Evaluate(interpreter, ds, "(+ 8.0 2.0 2.0)", 0, 12.0);
114
115      // subtraction
116      Evaluate(interpreter, ds, "(- (variable 2.0 a ))", 1, -4.0);
117      Evaluate(interpreter, ds, "(- (variable 2.0 a ) (variable 3.0 b))", 0, -1.0);
118      Evaluate(interpreter, ds, "(- (variable 2.0 a ) (variable 3.0 b ))", 1, -2.0);
119      Evaluate(interpreter, ds, "(- (variable 2.0 a ) (variable 3.0 b ))", 2, -4.0);
120      Evaluate(interpreter, ds, "(- 8.0 2.0 2.0)", 0, 4.0);
121
122      // multiplication
123      Evaluate(interpreter, ds, "(* (variable 2.0 a ))", 0, 2.0);
124      Evaluate(interpreter, ds, "(* (variable 2.0 a ) (variable 3.0 b ))", 0, 6.0);
125      Evaluate(interpreter, ds, "(* (variable 2.0 a ) (variable 3.0 b ))", 1, 24.0);
126      Evaluate(interpreter, ds, "(* (variable 2.0 a ) (variable 3.0 b ))", 2, 12.0);
127      Evaluate(interpreter, ds, "(* 8.0 2.0 2.0)", 0, 32.0);
128
129      // division
130      Evaluate(interpreter, ds, "(/ (variable 2.0 a ))", 1, 1.0 / 4.0);
131      Evaluate(interpreter, ds, "(/ (variable 2.0 a ) 2.0)", 0, 1.0);
132      Evaluate(interpreter, ds, "(/ (variable 2.0 a ) 2.0)", 1, 2.0);
133      Evaluate(interpreter, ds, "(/ (variable 3.0 b ) 2.0)", 2, 3.0);
134      Evaluate(interpreter, ds, "(/ 8.0 2.0 2.0)", 0, 2.0);
135
136      // gt
137      Evaluate(interpreter, ds, "(> (variable 2.0 a) 2.0)", 0, -1.0);
138      Evaluate(interpreter, ds, "(> 2.0 (variable 2.0 a))", 0, -1.0);
139      Evaluate(interpreter, ds, "(> (variable 2.0 a) 1.9)", 0, 1.0);
140      Evaluate(interpreter, ds, "(> 1.9 (variable 2.0 a))", 0, -1.0);
141      //Evaluate(interpreter, ds, "(> (sqrt -1.0) (log -1.0))", 0, -1.0); // (> nan nan) should be false
142
143      // lt
144      Evaluate(interpreter, ds, "(< (variable 2.0 a) 2.0)", 0, -1.0);
145      Evaluate(interpreter, ds, "(< 2.0 (variable 2.0 a))", 0, -1.0);
146      Evaluate(interpreter, ds, "(< (variable 2.0 a) 1.9)", 0, -1.0);
147      Evaluate(interpreter, ds, "(< 1.9 (variable 2.0 a))", 0, 1.0);
148      //Evaluate(interpreter, ds, "(< (sqrt -1,0) (log -1,0))", 0, -1.0); // (< nan nan) should be false
149
150      // If
151      Evaluate(interpreter, ds, "(if -10.0 2.0 3.0)", 0, 3.0);
152      Evaluate(interpreter, ds, "(if -1.0 2.0 3.0)", 0, 3.0);
153      Evaluate(interpreter, ds, "(if 0.0 2.0 3.0)", 0, 3.0);
154      Evaluate(interpreter, ds, "(if 1.0 2.0 3.0)", 0, 2.0);
155      Evaluate(interpreter, ds, "(if 10.0 2.0 3.0)", 0, 2.0);
156      // Evaluate(interpreter, ds, "(if (sqrt -1.0) 2.0 3.0)", 0, 3.0); // if(nan) should return the else branch
157
158      // NOT
159      Evaluate(interpreter, ds, "(not -1.0)", 0, 1.0);
160      Evaluate(interpreter, ds, "(not -2.0)", 0, 2.0);
161      Evaluate(interpreter, ds, "(not 1.0)", 0, -1.0);
162      Evaluate(interpreter, ds, "(not 2.0)", 0, -2.0);
163      Evaluate(interpreter, ds, "(not 0.0)", 0, 0.0);
164
165      // AND
166      Evaluate(interpreter, ds, "(and -1.0 -2.0)", 0, -1.0);
167      Evaluate(interpreter, ds, "(and -1.0 2.0)", 0, -1.0);
168      Evaluate(interpreter, ds, "(and 1.0 -2.0)", 0, -1.0);
169      Evaluate(interpreter, ds, "(and 1.0 0.0)", 0, -1.0);
170      Evaluate(interpreter, ds, "(and 0.0 0.0)", 0, -1.0);
171      Evaluate(interpreter, ds, "(and 1.0 2.0)", 0, 1.0);
172      Evaluate(interpreter, ds, "(and 1.0 2.0 3.0)", 0, 1.0);
173      Evaluate(interpreter, ds, "(and 1.0 -2.0 3.0)", 0, -1.0);
174
175      // OR
176      Evaluate(interpreter, ds, "(or -1.0 -2.0)", 0, -1.0);
177      Evaluate(interpreter, ds, "(or -1.0 2.0)", 0, 1.0);
178      Evaluate(interpreter, ds, "(or 1.0 -2.0)", 0, 1.0);
179      Evaluate(interpreter, ds, "(or 1.0 2.0)", 0, 1.0);
180      Evaluate(interpreter, ds, "(or 0.0 0.0)", 0, -1.0);
181      Evaluate(interpreter, ds, "(or -1.0 -2.0 -3.0)", 0, -1.0);
182      Evaluate(interpreter, ds, "(or -1.0 -2.0 3.0)", 0, 1.0);
183
184      // sin, cos, tan
185      Evaluate(interpreter, ds, "(sin " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, 0.0);
186      Evaluate(interpreter, ds, "(sin 0.0)", 0, 0.0);
187      Evaluate(interpreter, ds, "(cos " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, -1.0);
188      Evaluate(interpreter, ds, "(cos 0.0)", 0, 1.0);
189      Evaluate(interpreter, ds, "(tan " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, Math.Tan(Math.PI));
190      Evaluate(interpreter, ds, "(tan 0.0)", 0, Math.Tan(Math.PI));
191
192      // exp, log
193      Evaluate(interpreter, ds, "(log (exp 7.0))", 0, Math.Log(Math.Exp(7)));
194      Evaluate(interpreter, ds, "(exp (log 7.0))", 0, Math.Exp(Math.Log(7)));
195      Evaluate(interpreter, ds, "(log -3.0)", 0, Math.Log(-3));
196
197      // mean
198      Evaluate(interpreter, ds, "(mean -1.0 1.0 -1.0)", 0, -1.0 / 3.0);
199
200      // ADF     
201      Evaluate(interpreter, ds, @"(PROG
202                                    (MAIN
203                                      (CALL ADF0))
204                                    (defun ADF0 1.0))", 1, 1.0);
205      Evaluate(interpreter, ds, @"(PROG
206                                    (MAIN
207                                      (* (CALL ADF0) (CALL ADF0)))
208                                    (defun ADF0 2.0))", 1, 4.0);
209      Evaluate(interpreter, ds, @"(PROG
210                                    (MAIN
211                                      (CALL ADF0 2.0 3.0))
212                                    (defun ADF0
213                                      (+ (ARG 0) (ARG 1))))", 1, 5.0);
214      Evaluate(interpreter, ds, @"(PROG
215                                    (MAIN (CALL ADF1 2.0 3.0))
216                                    (defun ADF0
217                                      (- (ARG 1) (ARG 0)))
218                                    (defun ADF1
219                                      (+ (CALL ADF0 (ARG 1) (ARG 0))
220                                         (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
221      Evaluate(interpreter, ds, @"(PROG
222                                    (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
223                                    (defun ADF0
224                                      (- (ARG 1) (ARG 0)))
225                                    (defun ADF1                                                                             
226                                      (CALL ADF0 (ARG 1) (ARG 0))))", 1, 1.0);
227      Evaluate(interpreter, ds, @"(PROG
228                                    (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
229                                    (defun ADF0
230                                      (- (ARG 1) (ARG 0)))
231                                    (defun ADF1                                                                             
232                                      (+ (CALL ADF0 (ARG 1) (ARG 0))
233                                         (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
234    }
235
236    private void Evaluate(SimpleArithmeticExpressionInterpreter interpreter, Dataset ds, string expr, int index, double expected) {
237      var importer = new SymbolicExpressionImporter();
238      SymbolicExpressionTree tree = importer.Import(expr);
239
240      double actual = interpreter.GetSymbolicExpressionTreeValues(tree, ds, Enumerable.Range(index, 1)).First();
241
242      Assert.AreEqual(expected, actual, 1.0E-12, expr);
243    }
244  }
245}
Note: See TracBrowser for help on using the repository browser.