Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/InfixExpressionParserTest.cs @ 18211

Last change on this file since 18211 was 18211, checked in by gkronber, 3 years ago

#3145: refactored infix formatter to improve output (less parenthesis) and added unit tests to test that the infix formatter works correclty.

File size: 22.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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
22
23using System;
24using System.Linq;
25using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
26using Microsoft.VisualStudio.TestTools.UnitTesting;
27namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Tests {
28
29
30  [TestClass]
31  public class InfixExpressionParserTest {
32    [TestMethod]
33    [TestCategory("Problems.DataAnalysis.Symbolic")]
34    [TestProperty("Time", "short")]
35    public void InfixExpressionParserTestFormatting() {
36      var formatter = new InfixExpressionFormatter();
37      var parser = new InfixExpressionParser();
38      Assert.AreEqual("3", formatter.Format(parser.Parse("3")));
39      Assert.AreEqual("3 * 3", formatter.Format(parser.Parse("3*3")));
40      Assert.AreEqual("3 * 4", formatter.Format(parser.Parse("3 * 4")));
41      Assert.AreEqual("0.123", formatter.Format(parser.Parse("123E-03")));
42      Assert.AreEqual("0.123", formatter.Format(parser.Parse("123e-03")));
43      Assert.AreEqual("123000", formatter.Format(parser.Parse("123e+03")));
44      Assert.AreEqual("123000", formatter.Format(parser.Parse("123E+03")));
45      Assert.AreEqual("0.123", formatter.Format(parser.Parse("123.0E-03")));
46      Assert.AreEqual("0.123", formatter.Format(parser.Parse("123.0e-03")));
47      Assert.AreEqual("123000", formatter.Format(parser.Parse("123.0e+03")));
48      Assert.AreEqual("123000", formatter.Format(parser.Parse("123.0E+03")));
49      Assert.AreEqual("0.123", formatter.Format(parser.Parse("123.0E-3")));
50      Assert.AreEqual("0.123", formatter.Format(parser.Parse("123.0e-3")));
51      Assert.AreEqual("123000", formatter.Format(parser.Parse("123.0e+3")));
52      Assert.AreEqual("123000", formatter.Format(parser.Parse("123.0E+3")));
53
54      Assert.AreEqual("3.1415 + 2", formatter.Format(parser.Parse("3.1415+2.0")));
55      Assert.AreEqual("3.1415 / 2", formatter.Format(parser.Parse("3.1415/2.0")));
56      Assert.AreEqual("3.1415 * 2", formatter.Format(parser.Parse("3.1415*2.0")));
57      Assert.AreEqual("3.1415 - 2", formatter.Format(parser.Parse("3.1415-2.0")));
58      // round-trip
59      Assert.AreEqual("3.1415 - 2", formatter.Format(parser.Parse(formatter.Format(parser.Parse("3.1415-2.0")))));
60      Assert.AreEqual("3.1415 + 2", formatter.Format(parser.Parse("3.1415+(2.0)")));
61      Assert.AreEqual("3.1415 + 2", formatter.Format(parser.Parse("(3.1415+(2.0))")));
62
63
64      Assert.AreEqual("LOG(3)", formatter.Format(parser.Parse("log(3)")));
65      Assert.AreEqual("LOG(-3)", formatter.Format(parser.Parse("log(-3)")));
66      Assert.AreEqual("EXP(3)", formatter.Format(parser.Parse("exp(3)")));
67      Assert.AreEqual("EXP(-3)", formatter.Format(parser.Parse("exp(-3)")));
68      Assert.AreEqual("SQRT(3)", formatter.Format(parser.Parse("sqrt(3)")));
69
70      Assert.AreEqual("SQR(-3)", formatter.Format(parser.Parse("sqr((-3))")));
71
72      Assert.AreEqual("3 / 3 + 2 / 2 + 1 / 1", formatter.Format(parser.Parse("3/3+2/2+1/1")));
73      Assert.AreEqual("-3 + 30 - 2 + 20 - 1 + 10", formatter.Format(parser.Parse("-3+30-2+20-1+10")));
74
75      // 'flattening' of nested addition, subtraction, multiplication, or division
76      Assert.AreEqual("1 + 2 + 3 + 4", formatter.Format(parser.Parse("1 + 2 + 3 + 4")));
77      Assert.AreEqual("1 - 2 - 3 - 4", formatter.Format(parser.Parse("1 - 2 - 3 - 4")));
78      Assert.AreEqual("1 * 2 * 3 * 4", formatter.Format(parser.Parse("1 * 2 * 3 * 4")));
79      Assert.AreEqual("1 / 2 / 3 / 4", formatter.Format(parser.Parse("1 / 2 / 3 / 4")));
80
81      // signed variables / constants
82      Assert.AreEqual("-1 * 'x1'", formatter.Format(parser.Parse("-x1")));
83      Assert.AreEqual("1", formatter.Format(parser.Parse("--1.0")));
84      Assert.AreEqual("1", formatter.Format(parser.Parse("----1.0")));
85      Assert.AreEqual("1", formatter.Format(parser.Parse("-+-1.0")));
86      Assert.AreEqual("1", formatter.Format(parser.Parse("+-+-1.0")));
87      Assert.AreEqual("-3 + -1", formatter.Format(parser.Parse("-3 + -1.0")));
88
89
90      Assert.AreEqual("'x1'", formatter.Format(parser.Parse("\"x1\"")));
91      Assert.AreEqual("'var name'", formatter.Format(parser.Parse("\'var name\'")));
92      Assert.AreEqual("'var name'", formatter.Format(parser.Parse("\"var name\"")));
93      Assert.AreEqual("'1'", formatter.Format(parser.Parse("\"1\"")));
94
95      Assert.AreEqual("'var \" name'", formatter.Format(parser.Parse("'var \" name\'")));
96      Assert.AreEqual("\"var ' name\"", formatter.Format(parser.Parse("\"var \' name\"")));
97
98
99      Assert.AreEqual("'x1' * 'x2'", formatter.Format(parser.Parse("\"x1\"*\"x2\"")));
100      Assert.AreEqual("'x1' * 'x2' + 'x3' * 'x4'", formatter.Format(parser.Parse("\"x1\"*\"x2\"+\"x3\"*\"x4\"")));
101      Assert.AreEqual("'x1' * 'x2' + 'x3' * 'x4'", formatter.Format(parser.Parse("x1*x2+x3*x4")));
102
103
104      Assert.AreEqual("3 ^ 2", formatter.Format(parser.Parse("POW(3, 2)")));
105      Assert.AreEqual("3.1 ^ 2.1", formatter.Format(parser.Parse("POW(3.1, 2.1)")));
106      Assert.AreEqual("3.1 ^ 2.1", formatter.Format(parser.Parse("POW(3.1 , 2.1)")));
107      Assert.AreEqual("3.1 ^ 2.1", formatter.Format(parser.Parse("POW(3.1 ,2.1)")));
108      Assert.AreEqual("-3.1 ^ -2.1", formatter.Format(parser.Parse("POW(-3.1 , - 2.1)")));
109      Assert.AreEqual("ROOT(3, 2)", formatter.Format(parser.Parse("ROOT(3, 2)")));
110      Assert.AreEqual("ROOT(3.1, 2.1)", formatter.Format(parser.Parse("ROOT(3.1, 2.1)")));
111      Assert.AreEqual("ROOT(3.1, 2.1)", formatter.Format(parser.Parse("ROOT(3.1 , 2.1)")));
112      Assert.AreEqual("ROOT(3.1, 2.1)", formatter.Format(parser.Parse("ROOT(3.1 ,2.1)")));
113      Assert.AreEqual("ROOT(-3.1, -2.1)", formatter.Format(parser.Parse("ROOT(-3.1 , -2.1)")));
114
115      Assert.AreEqual("IF(GT(0, 1), 1, 0)", formatter.Format(parser.Parse("IF(GT( 0, 1), 1, 0)")));
116      Assert.AreEqual("IF(LT(0, 1), 1, 0)", formatter.Format(parser.Parse("IF(LT(0,1), 1 , 0)")));
117      Assert.AreEqual("LAG('x', 1)", formatter.Format(parser.Parse("LAG(x, 1)")));
118      Assert.AreEqual("LAG('x', -1)", formatter.Format(parser.Parse("LAG(x, -1)")));
119      Assert.AreEqual("LAG('x', 1)", formatter.Format(parser.Parse("LAG(x, +1)")));
120      Assert.AreEqual("'x' * LAG('x', 1)", formatter.Format(parser.Parse("x * LAG('x', +1)")));
121
122      // factor variables
123      Assert.AreEqual("'x'[1] * 'y'", formatter.Format(parser.Parse("x [1.0] * y")));
124      Assert.AreEqual("'x'[1, 2] * 'y'[1, 2]", formatter.Format(parser.Parse("x [1.0, 2.0] * y [1.0, 2.0]")));
125      Assert.AreEqual("'x'[1] * 'y'", formatter.Format(parser.Parse("x[1] * y")));
126      Assert.AreEqual("'x'[1, 2] * 'y'[1, 2]", formatter.Format(parser.Parse("x[1, 2] * y [1, 2]")));
127      Assert.AreEqual("'x'[1] * 'y'", formatter.Format(parser.Parse("x [+1.0] * y")));
128      Assert.AreEqual("'x'[-1] * 'y'", formatter.Format(parser.Parse("x [-1.0] * y")));
129      Assert.AreEqual("'x'[-1, -2] * 'y'[1, 2]", formatter.Format(parser.Parse("x [-1.0, -2.0] * y [+1.0, +2.0]")));
130
131      // one-hot for factor
132      Assert.AreEqual("'x' = 'val' * 'y'", formatter.Format(parser.Parse("x='val' * y")));
133      Assert.AreEqual("'x' = 'val'", formatter.Format(parser.Parse("x = 'val'")));
134      Assert.AreEqual("'x' = 'val'", formatter.Format(parser.Parse("x = \"val\"")));
135      Assert.AreEqual("1 * 'x' = 'val'", formatter.Format(parser.Parse("1.0 * x = val")));
136      Assert.AreEqual("-1 * 'x' = 'val'", formatter.Format(parser.Parse("-1.0 * x = val")));
137      Assert.AreEqual("1 * 'x' = 'val1' + 'y' = 'val2'", formatter.Format(parser.Parse("+1.0 * \"x\" = val1 + y = \"val2\"")));
138
139      // numeric parameters
140      Assert.AreEqual("0", formatter.Format(parser.Parse("<num>"))); // default initial value is zero
141      Assert.AreEqual("0", formatter.Format(parser.Parse("< num >")));
142      Assert.AreEqual("1", formatter.Format(parser.Parse("< num=1.0>")));
143      Assert.AreEqual("1", formatter.Format(parser.Parse("< num = 1.0>")));
144      Assert.AreEqual("-1", formatter.Format(parser.Parse("< num =-1.0>")));
145      Assert.AreEqual("-1", formatter.Format(parser.Parse("< num = - 1.0>")));
146
147      // numeric parameter with sign
148      Assert.AreEqual("1", formatter.Format(parser.Parse("-<num=-1.0>")));
149
150      // nested functions
151      Assert.AreEqual("SIN(SIN(SIN('X1')))", formatter.Format(parser.Parse("SIN(SIN(SIN(X1)))")));
152
153      {
154        // a tree with single-argument multiplication and addition
155        //   ...
156        //    *
157        //    |
158        //    +
159        //   / \
160        //  v1 v2
161        //
162        // is still formatted as (v1 + v2) even though it is not strictly necessary
163        var root = new ProgramRootSymbol().CreateTreeNode();
164        var start = new StartSymbol().CreateTreeNode();
165        var mul = new Multiplication().CreateTreeNode();
166        var add = new Addition().CreateTreeNode();
167        var var1 = (VariableTreeNode)new Variable().CreateTreeNode(); var1.VariableName = "x1"; var1.Weight = 1.0;
168        var var2 = (VariableTreeNode)new Variable().CreateTreeNode(); var2.VariableName = "x2"; var2.Weight = 1.0;
169        add.AddSubtree(var1);
170        add.AddSubtree(var2);
171        mul.AddSubtree(add);
172        start.AddSubtree(mul);
173        root.AddSubtree(start);
174        var t = new SymbolicExpressionTree(root);
175
176        Assert.AreEqual("'x1' + 'x2'", formatter.Format(t));
177      }
178      {
179        //    *
180        //    |\
181        //    * v3
182        //    |
183        //    +
184        //   / \
185        //  v1 v2
186        //
187        // is still formatted as (v1 + v2) even though it is not strictly necessary
188        var root = new ProgramRootSymbol().CreateTreeNode();
189        var start = new StartSymbol().CreateTreeNode();
190        var mul1 = new Multiplication().CreateTreeNode();
191        var mul2 = new Multiplication().CreateTreeNode();
192        var add = new Addition().CreateTreeNode();
193        var var1 = (VariableTreeNode)new Variable().CreateTreeNode(); var1.VariableName = "x1"; var1.Weight = 1.0;
194        var var2 = (VariableTreeNode)new Variable().CreateTreeNode(); var2.VariableName = "x2"; var2.Weight = 1.0;
195        var var3 = (VariableTreeNode)new Variable().CreateTreeNode(); var3.VariableName = "x3"; var3.Weight = 1.0;
196        add.AddSubtree(var1);
197        add.AddSubtree(var2);
198        mul2.AddSubtree(add);
199        mul1.AddSubtree(mul2);
200        mul1.AddSubtree(var3);
201        start.AddSubtree(mul1);
202        root.AddSubtree(start);
203        var t = new SymbolicExpressionTree(root);
204
205        Assert.AreEqual("('x1' + 'x2') * 'x3'", formatter.Format(t));
206      }
207
208      {
209        //   sin
210        //    |
211        //    *
212        //    |
213        //    +
214        //   / \
215        //  v1 v2
216        //
217        // is still formatted as (v1 + v2) even though it is not strictly necessary
218        var root = new ProgramRootSymbol().CreateTreeNode();
219        var start = new StartSymbol().CreateTreeNode();
220        var sin = new Sine().CreateTreeNode();
221        var mul = new Multiplication().CreateTreeNode();
222        var add = new Addition().CreateTreeNode();
223        var var1 = (VariableTreeNode)new Variable().CreateTreeNode(); var1.VariableName = "x1"; var1.Weight = 1.0;
224        var var2 = (VariableTreeNode)new Variable().CreateTreeNode(); var2.VariableName = "x2"; var2.Weight = 1.0;
225        add.AddSubtree(var1);
226        add.AddSubtree(var2);
227        mul.AddSubtree(add);
228        sin.AddSubtree(mul);
229        start.AddSubtree(sin);
230        root.AddSubtree(start);
231        var t = new SymbolicExpressionTree(root);
232
233        Assert.AreEqual("SIN('x1' + 'x2')", formatter.Format(t));
234      }
235      {
236        // single-argument subtraction
237        //    -
238        //    |
239        //    v1
240        var root = new ProgramRootSymbol().CreateTreeNode();
241        var start = new StartSymbol().CreateTreeNode();
242        var sub = new Subtraction().CreateTreeNode();
243        var var1 = (VariableTreeNode)new Variable().CreateTreeNode(); var1.VariableName = "x1"; var1.Weight = -1.0;
244        sub.AddSubtree(var1);
245        start.AddSubtree(sub);
246        root.AddSubtree(start);
247        var t = new SymbolicExpressionTree(root);
248
249        Assert.AreEqual("-(-1 * 'x1')", formatter.Format(t));       // TODO: same as --1 * 'x1' and just 'x1'
250      }
251      {
252        // single-argument subtraction
253        //    -
254        //    |
255        //    +
256        //   / \
257        //  v1 v2
258        var root = new ProgramRootSymbol().CreateTreeNode();
259        var start = new StartSymbol().CreateTreeNode();
260        var sub = new Subtraction().CreateTreeNode();
261        var add = new Addition().CreateTreeNode();
262        var var1 = (VariableTreeNode)new Variable().CreateTreeNode(); var1.VariableName = "x1"; var1.Weight = 1.0;
263        var var2 = (VariableTreeNode)new Variable().CreateTreeNode(); var2.VariableName = "x2"; var2.Weight = 1.0;
264        add.AddSubtree(var1);
265        add.AddSubtree(var2);
266        sub.AddSubtree(add);
267        start.AddSubtree(sub);
268        root.AddSubtree(start);
269        var t = new SymbolicExpressionTree(root);
270
271        Assert.AreEqual("-('x1' + 'x2')", formatter.Format(t));
272      }
273      {
274        //     ^
275        //    / \
276        //    *  v3
277        //   / \
278        //  v1 v2
279        var root = new ProgramRootSymbol().CreateTreeNode();
280        var start = new StartSymbol().CreateTreeNode();
281        var pow = new Power().CreateTreeNode();
282        var mul = new Multiplication().CreateTreeNode();
283        var var1 = (VariableTreeNode)new Variable().CreateTreeNode(); var1.VariableName = "x1"; var1.Weight = 1.0;
284        var var2 = (VariableTreeNode)new Variable().CreateTreeNode(); var2.VariableName = "x2"; var2.Weight = 1.0;
285        var var3 = (VariableTreeNode)new Variable().CreateTreeNode(); var3.VariableName = "x3"; var3.Weight = 1.0;
286        mul.AddSubtree(var1);
287        mul.AddSubtree(var2);
288        pow.AddSubtree(mul);
289        pow.AddSubtree(var3);
290        start.AddSubtree(pow);
291        root.AddSubtree(start);
292        var t = new SymbolicExpressionTree(root);
293
294        Assert.AreEqual("('x1' * 'x2') ^ 'x3'", formatter.Format(t));
295      }
296      {
297        //       ^
298        //     /   \
299        //    *     *
300        //   / \   / \
301        //  v1 v2 v3 v4
302        var root = new ProgramRootSymbol().CreateTreeNode();
303        var start = new StartSymbol().CreateTreeNode();
304        var pow = new Power().CreateTreeNode();
305        var mul1 = new Multiplication().CreateTreeNode();
306        var mul2 = new Multiplication().CreateTreeNode();
307        var var1 = (VariableTreeNode)new Variable().CreateTreeNode(); var1.VariableName = "x1"; var1.Weight = 1.0;
308        var var2 = (VariableTreeNode)new Variable().CreateTreeNode(); var2.VariableName = "x2"; var2.Weight = 1.0;
309        var var3 = (VariableTreeNode)new Variable().CreateTreeNode(); var3.VariableName = "x3"; var3.Weight = 1.0;
310        var var4 = (VariableTreeNode)new Variable().CreateTreeNode(); var4.VariableName = "x4"; var4.Weight = 1.0;
311        mul1.AddSubtree(var1);
312        mul1.AddSubtree(var2);
313        mul2.AddSubtree(var3);
314        mul2.AddSubtree(var4);
315        pow.AddSubtree(mul1);
316        pow.AddSubtree(mul2);
317        start.AddSubtree(pow);
318        root.AddSubtree(start);
319        var t = new SymbolicExpressionTree(root);
320
321        Assert.AreEqual("('x1' * 'x2') ^ ('x3' * 'x4')", formatter.Format(t));
322      }
323      {
324        //       *
325        //     /   \
326        //    *     /
327        //   / \   / \
328        //  v1 v2 v3 v4
329        var root = new ProgramRootSymbol().CreateTreeNode();
330        var start = new StartSymbol().CreateTreeNode();
331        var mul1 = new Multiplication().CreateTreeNode();
332        var mul2 = new Multiplication().CreateTreeNode();
333        var div = new Division().CreateTreeNode();
334        var var1 = (VariableTreeNode)new Variable().CreateTreeNode(); var1.VariableName = "x1"; var1.Weight = 1.0;
335        var var2 = (VariableTreeNode)new Variable().CreateTreeNode(); var2.VariableName = "x2"; var2.Weight = 1.0;
336        var var3 = (VariableTreeNode)new Variable().CreateTreeNode(); var3.VariableName = "x3"; var3.Weight = 1.0;
337        var var4 = (VariableTreeNode)new Variable().CreateTreeNode(); var4.VariableName = "x4"; var4.Weight = 1.0;
338        mul2.AddSubtree(var1);
339        mul2.AddSubtree(var2);
340        div.AddSubtree(var3);
341        div.AddSubtree(var4);
342        mul1.AddSubtree(mul2);
343        mul1.AddSubtree(div);
344        start.AddSubtree(mul1);
345        root.AddSubtree(start);
346        var t = new SymbolicExpressionTree(root);
347
348        Assert.AreEqual("'x1' * 'x2' * 'x3' / 'x4'", formatter.Format(t));     // same as x1 * x2 * (x3 / x4)
349      }
350      {
351        //       *
352        //     /   \
353        //    div  div
354        //   / \   / \
355        //  v1 v2 v3 v4
356        var root = new ProgramRootSymbol().CreateTreeNode();
357        var start = new StartSymbol().CreateTreeNode();
358        var mul = new Multiplication().CreateTreeNode();
359        var div1 = new Division().CreateTreeNode();
360        var div2 = new Division().CreateTreeNode();
361        var var1 = (VariableTreeNode)new Variable().CreateTreeNode(); var1.VariableName = "x1"; var1.Weight = 1.0;
362        var var2 = (VariableTreeNode)new Variable().CreateTreeNode(); var2.VariableName = "x2"; var2.Weight = 1.0;
363        var var3 = (VariableTreeNode)new Variable().CreateTreeNode(); var3.VariableName = "x3"; var3.Weight = 1.0;
364        var var4 = (VariableTreeNode)new Variable().CreateTreeNode(); var4.VariableName = "x4"; var4.Weight = 1.0;
365        div1.AddSubtree(var1);
366        div1.AddSubtree(var2);
367        div2.AddSubtree(var3);
368        div2.AddSubtree(var4);
369        mul.AddSubtree(div1);
370        mul.AddSubtree(div2);
371        start.AddSubtree(mul);
372        root.AddSubtree(start);
373        var t = new SymbolicExpressionTree(root);
374
375        Assert.AreEqual("'x1' / 'x2' * 'x3' / 'x4'", formatter.Format(t)); // same as x1 / x2 * (x3 / x4)
376      }
377      {
378        //      div
379        //     /   \
380        //    div   *
381        //   / \   / \
382        //  v1 v2 v3 v4
383        //         
384        var root = new ProgramRootSymbol().CreateTreeNode();
385        var start = new StartSymbol().CreateTreeNode();
386        var mul = new Multiplication().CreateTreeNode();
387        var div2 = new Division().CreateTreeNode();
388        var div1 = new Division().CreateTreeNode();
389        var var1 = (VariableTreeNode)new Variable().CreateTreeNode(); var1.VariableName = "x1"; var1.Weight = 1.0;
390        var var2 = (VariableTreeNode)new Variable().CreateTreeNode(); var2.VariableName = "x2"; var2.Weight = 1.0;
391        var var3 = (VariableTreeNode)new Variable().CreateTreeNode(); var3.VariableName = "x3"; var3.Weight = 1.0;
392        var var4 = (VariableTreeNode)new Variable().CreateTreeNode(); var4.VariableName = "x4"; var4.Weight = 1.0;
393        div2.AddSubtree(var1);
394        div2.AddSubtree(var2);
395        mul.AddSubtree(var3);
396        mul.AddSubtree(var4);
397        div1.AddSubtree(div2);
398        div1.AddSubtree(mul);
399        start.AddSubtree(div1);
400        root.AddSubtree(start);
401        var t = new SymbolicExpressionTree(root);
402
403        Assert.AreEqual("'x1' / 'x2' / ('x3' * 'x4')", formatter.Format(t));
404      }
405
406      {
407        // check random trees after formatting & parsing again
408
409        var rand = new Random.MersenneTwister(1234);
410        var interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter(); // use an interpreter that supports boolean functions
411        var xy = new double[100, 4];
412        for (int i = 0; i < xy.GetLength(0); i++)
413          for (int j = 0; j < xy.GetLength(1); j++)
414            xy[i, j] = rand.NextDouble();
415
416        var ds = new Dataset(new string[] { "a", "b", "c", "y" }, xy);
417        var rows = Enumerable.Range(0, xy.GetLength(1)).ToArray();
418        var grammar = new TypeCoherentExpressionGrammar();
419        grammar.ConfigureAsDefaultRegressionGrammar();
420        grammar.Symbols.OfType<Logarithm>().First().Enabled = true; // enable a function
421        grammar.Symbols.OfType<Exponential>().First().Enabled = true; // enable a function
422        grammar.Symbols.OfType<AnalyticQuotient>().First().Enabled = true; // enable a function with two arguments
423        grammar.Symbols.OfType<Power>().First().Enabled = true; // another function with two arguments
424        grammar.Symbols.OfType<And>().First().Enabled = true; // enable Boolean operators
425        grammar.Symbols.OfType<Or>().First().Enabled = true;
426        grammar.Symbols.OfType<Xor>().First().Enabled = true;
427        grammar.Symbols.OfType<Not>().First().Enabled = true;
428        grammar.Symbols.OfType<IfThenElse>().First().Enabled = true; // enable if-then-else function
429        // test multi-argument versions of operators
430        grammar.SetSubtreeCount(grammar.Symbols.OfType<Division>().First(), 1, 4);
431        grammar.SetSubtreeCount(grammar.Symbols.OfType<Subtraction>().First(), 1, 2);
432        grammar.SetSubtreeCount(grammar.Symbols.OfType<Addition>().First(), 1, 4);
433        grammar.SetSubtreeCount(grammar.Symbols.OfType<Multiplication>().First(), 1, 4);
434        grammar.SetSubtreeCount(grammar.Symbols.OfType<And>().First(), 1, 4);
435        grammar.SetSubtreeCount(grammar.Symbols.OfType<Or>().First(), 1, 4);
436        grammar.SetSubtreeCount(grammar.Symbols.OfType<Xor>().First(), 1, 4);
437        grammar.ConfigureVariableSymbols(new RegressionProblemData(ds, new string[] { "a", "b", "c" }, "y"));
438        var fmt = new SymbolicExpressionTreeStringFormatter();
439        for (int i = 0; i < 100000; i++) {
440          var t = ProbabilisticTreeCreator.Create(rand, grammar, 15, 8);
441          var p1 = interpreter.GetSymbolicExpressionTreeValues(t, ds, rows).ToArray();
442          var p2 = interpreter.GetSymbolicExpressionTreeValues(parser.Parse(formatter.Format(t)), ds, rows).ToArray(); // test formatter, and that parser can read the expression again, and that the evaluation is the same
443          for (int j = 0; j < p1.Length; j++) {
444            if (double.IsNaN(p1[j]) && double.IsNaN(p2[j])) continue;
445            Assert.AreEqual(p1[j], p2[j], Math.Abs(p1[j] * 1e-6), $"Problem in formatted expression:\n{formatter.Format(t)}\n{fmt.Format(t)}");
446          }
447        }
448      }
449    }
450  }
451}
Note: See TracBrowser for help on using the repository browser.