Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicSimplifierTest.cs @ 6774

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

#1227 implemented test cases and transformation rules for root and power symbols.

File size: 18.5 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 HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
27using HeuristicLab.Optimization;
28using HeuristicLab.Problems.DataAnalysis.Regression.Symbolic;
29using HeuristicLab.Problems.DataAnalysis.Symbolic;
30using Microsoft.VisualStudio.TestTools.UnitTesting;
31using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Formatters;
32namespace HeuristicLab.Problems.DataAnalysis.Tests {
33
34  [TestClass()]
35  public class SymbolicSimplifierTest {
36    [DeploymentItem(@"RegressionSolution01.hl")]
37    [DeploymentItem(@"RegressionSolution02.hl")]
38    [DeploymentItem(@"RegressionSolution03.hl")]
39    [DeploymentItem(@"RegressionSolution04.hl")]
40    [DeploymentItem(@"RegressionSolution05.hl")]
41    [DeploymentItem(@"RegressionSolution06.hl")]
42    [TestMethod]
43    public void SimplifyRegressionSolutionsTest() {
44      ContentManager.Initialize(new PersistenceContentManager());
45
46      {
47        SymbolicRegressionSolution solution = LoadSolution("RegressionSolution01.hl");
48        SymbolicRegressionSolution simplifiedSolution = SimplifySolution(solution);
49        AssertEqualEnumerations(solution.EstimatedValues, simplifiedSolution.EstimatedValues);
50      }
51      {
52        SymbolicRegressionSolution solution = LoadSolution("RegressionSolution02.hl");
53        SymbolicRegressionSolution simplifiedSolution = SimplifySolution(solution);
54        AssertEqualEnumerations(solution.EstimatedValues, simplifiedSolution.EstimatedValues);
55      }
56      {
57        SymbolicRegressionSolution solution = LoadSolution("RegressionSolution03.hl");
58        SymbolicRegressionSolution simplifiedSolution = SimplifySolution(solution);
59        AssertEqualEnumerations(solution.EstimatedValues, simplifiedSolution.EstimatedValues);
60      }
61      {
62        SymbolicRegressionSolution solution = LoadSolution("RegressionSolution04.hl");
63        SymbolicRegressionSolution simplifiedSolution = SimplifySolution(solution);
64        AssertEqualEnumerations(solution.EstimatedValues, simplifiedSolution.EstimatedValues);
65      }
66      {
67        SymbolicRegressionSolution solution = LoadSolution("RegressionSolution05.hl");
68        SymbolicRegressionSolution simplifiedSolution = SimplifySolution(solution);
69        AssertEqualEnumerations(solution.EstimatedValues, simplifiedSolution.EstimatedValues);
70      }
71      {
72        SymbolicRegressionSolution solution = LoadSolution("RegressionSolution06.hl");
73        SymbolicRegressionSolution simplifiedSolution = SimplifySolution(solution);
74        AssertEqualEnumerations(solution.EstimatedValues, simplifiedSolution.EstimatedValues);
75      }
76    }
77
78    [TestMethod]
79    public void SimplifierAxiomsTest() {
80      SymbolicExpressionImporter importer = new SymbolicExpressionImporter();
81      SymbolicSimplifier simplifier = new SymbolicSimplifier();
82      SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
83      #region single argument arithmetics
84      {
85        var actualTree = simplifier.Simplify(importer.Import("(+ 1.0)"));
86        var expectedTree = importer.Import("1.0");
87        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
88      }
89      {
90        var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a))"));
91        var expectedTree = importer.Import("(variable 2.0 a)");
92        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
93      }
94      {
95        var actualTree = simplifier.Simplify(importer.Import("(- 1.0)"));
96        var expectedTree = importer.Import("-1.0");
97        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
98      }
99      {
100        var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a))"));
101        var expectedTree = importer.Import("(variable -2.0 a)");
102        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
103      }
104      {
105        var actualTree = simplifier.Simplify(importer.Import("(* 2.0)"));
106        var expectedTree = importer.Import("2.0");
107        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
108      }
109      {
110        var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a))"));
111        var expectedTree = importer.Import("(variable 2.0 a)");
112        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
113      }
114      {
115        var actualTree = simplifier.Simplify(importer.Import("(/ 2.0)"));
116        var expectedTree = importer.Import("0.5");
117        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
118      }
119      {
120        var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a))"));
121        var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
122        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
123      }
124      #endregion
125      #region aggregation of constants into factors
126      {
127        var actualTree = simplifier.Simplify(importer.Import("(* 2.0 (variable 2.0 a))"));
128        var expectedTree = importer.Import("(variable 4.0 a)");
129        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
130      }
131      {
132        var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a) 2.0)"));
133        var expectedTree = importer.Import("(variable 1.0 a)");
134        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
135      }
136      {
137        var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a) (* 2.0 2.0))"));
138        var expectedTree = importer.Import("(variable 0.5 a)");
139        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
140      }
141      #endregion
142      #region constant and variable folding
143      {
144        var actualTree = simplifier.Simplify(importer.Import("(+ 1.0 2.0)"));
145        var expectedTree = importer.Import("3.0");
146        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
147      }
148      {
149        var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a) (variable 2.0 a))"));
150        var expectedTree = importer.Import("(variable 4.0 a)");
151        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
152      }
153      {
154        var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a) (variable 1.0 a))"));
155        var expectedTree = importer.Import("(variable 1.0 a)");
156        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
157      }
158      {
159        var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a) (variable 2.0 a))"));
160        var expectedTree = importer.Import("(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)");
161        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
162      }
163      {
164        var actualTree = simplifier.Simplify(importer.Import("(/ (variable 1.0 a) (variable 2.0 a))"));
165        var expectedTree = importer.Import("0.5");
166        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
167      }
168      #endregion
169      #region logarithm rules
170      {
171        // cancellation
172        var actualTree = simplifier.Simplify(importer.Import("(log (exp (variable 2.0 a)))"));
173        var expectedTree = importer.Import("(variable 2.0 a)");
174        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
175      }
176      {
177        // log transformation
178        var actualTree = simplifier.Simplify(importer.Import("(log (* (variable 2.0 a) (variable 3.0 b)))"));
179        var expectedTree = importer.Import("(+ (log (variable 1.0 a)) (log (variable 1.0 b)) 1.7918)");
180        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
181      }
182      {
183        // log transformation
184        var actualTree = simplifier.Simplify(importer.Import("(log (/ (variable 2.0 a) (variable 3.0 b)))"));
185        var expectedTree = importer.Import("(- (log (variable 2.0 a)) (log (variable 3.0 b)))");
186        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
187      }
188      #endregion
189      #region exponentiation rules
190      {
191        // cancellation
192        var actualTree = simplifier.Simplify(importer.Import("(exp (log (variable 2.0 a)))"));
193        var expectedTree = importer.Import("(variable 2.0 a)");
194        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
195      }
196      {
197        // exp transformation
198        var actualTree = simplifier.Simplify(importer.Import("(exp (+ (variable 2.0 a) (variable 3.0 b)))"));
199        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable 3.0 b)))");
200        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
201      }
202      {
203        // exp transformation
204        var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (variable 3.0 b)))"));
205        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable -3.0 b)))");
206        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
207      }
208      #endregion
209      #region power rules
210      {
211        // cancellation
212        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 0.0)"));
213        var expectedTree = importer.Import("1.0");
214        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
215      }
216      {
217        // fixed point
218        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 1.0)"));
219        var expectedTree = importer.Import("(variable 2.0 a)");
220        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
221      }
222      {
223        // inversion fixed point
224        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -1.0)"));
225        var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
226        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
227      }
228      {
229        // inversion
230        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -2.0)"));
231        var expectedTree = importer.Import("(/ 1.0 (pow (variable 2.0 a) 2.0))");
232        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
233      }
234      {
235        // constant folding
236        var actualTree = simplifier.Simplify(importer.Import("(pow 3.0 2.0)"));
237        var expectedTree = importer.Import("9.0");
238        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
239      }
240      #endregion
241      #region root rules
242      {
243        // cancellation
244        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 0.0)"));
245        var expectedTree = importer.Import("1.0");
246        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
247      }
248      {
249        // fixed point
250        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 1.0)"));
251        var expectedTree = importer.Import("(variable 2.0 a)");
252        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
253      }
254      {
255        // inversion fixed point
256        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -1.0)"));
257        var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
258        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
259      }
260      {
261        // inversion
262        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -2.0)"));
263        var expectedTree = importer.Import("(/ 1.0 (root (variable 2.0 a) 2.0))");
264        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
265      }
266      {
267        // constant folding
268        var actualTree = simplifier.Simplify(importer.Import("(root 9.0 2.0)"));
269        var expectedTree = importer.Import("3.0");
270        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
271      }
272      #endregion
273      #region boolean operations
274      {
275        // always true and
276        var actualTree = simplifier.Simplify(importer.Import("(and 1.0 2.0)"));
277        var expectedTree = importer.Import("1.0");
278        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
279      }
280      {
281        // always false and
282        var actualTree = simplifier.Simplify(importer.Import("(and 1.0 -2.0)"));
283        var expectedTree = importer.Import("-1.0");
284        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
285      }
286      {
287        // always true or
288        var actualTree = simplifier.Simplify(importer.Import("(or -1.0 2.0)"));
289        var expectedTree = importer.Import("1.0");
290        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
291      }
292      {
293        // always false or
294        var actualTree = simplifier.Simplify(importer.Import("(or -1.0 -2.0)"));
295        var expectedTree = importer.Import("-1.0");
296        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
297      }
298      {
299        // constant not
300        var actualTree = simplifier.Simplify(importer.Import("(not -2.0)"));
301        var expectedTree = importer.Import("2.0");
302        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
303      }
304      {
305        // constant not
306        var actualTree = simplifier.Simplify(importer.Import("(not 2.0)"));
307        var expectedTree = importer.Import("-2.0");
308        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
309      }
310      {
311        // constant not
312        var actualTree = simplifier.Simplify(importer.Import("(not 0.0)"));
313        var expectedTree = importer.Import("0.0");
314        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
315      }
316      #endregion
317      #region conditionals
318      {
319        // always false
320        var actualTree = simplifier.Simplify(importer.Import("(if -1.0 (variable 2.0 a) (variable 3.0 a))"));
321        var expectedTree = importer.Import("(variable 3.0 a)");
322        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
323      }
324      {
325        // always true
326        var actualTree = simplifier.Simplify(importer.Import("(if 1.0 (variable 2.0 a) (variable 3.0 a))"));
327        var expectedTree = importer.Import("(variable 2.0 a)");
328        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
329      }
330      {
331        // always false (0.0)
332        var actualTree = simplifier.Simplify(importer.Import("(if 0.0 (variable 2.0 a) (variable 3.0 a))"));
333        var expectedTree = importer.Import("(variable 3.0 a)");
334        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
335      }
336      {
337        // complex constant condition (always false)
338        var actualTree = simplifier.Simplify(importer.Import("(if (* 1.0 -2.0) (variable 2.0 a) (variable 3.0 a))"));
339        var expectedTree = importer.Import("(variable 3.0 a)");
340        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
341      }
342      {
343        // complex constant condition (always false)
344        var actualTree = simplifier.Simplify(importer.Import("(if (/ (variable 1.0 a) (variable -2.0 a)) (variable 2.0 a) (variable 3.0 a))"));
345        var expectedTree = importer.Import("(variable 3.0 a)");
346        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
347      }
348      {
349        // insertion of relational operator
350        var actualTree = simplifier.Simplify(importer.Import("(if (variable 1.0 a) (variable 2.0 a) (variable 3.0 a))"));
351        var expectedTree = importer.Import("(if (> (variable 1.0 a) 0.0) (variable 2.0 a) (variable 3.0 a))");
352        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
353      }
354      #endregion
355    }
356
357
358    private SymbolicRegressionSolution LoadSolution(string fileName) {
359      var doc = ContentManager.Load(fileName);
360      Result result = doc as Result;
361      if (result != null) {
362        return (SymbolicRegressionSolution)result.Value;
363      }
364      SymbolicRegressionSolution solution = doc as SymbolicRegressionSolution;
365      if (solution != null) {
366        return solution;
367      }
368      Assert.Fail("Cannot load file " + fileName);
369      throw new AssertFailedException();
370    }
371
372    private SymbolicRegressionSolution SimplifySolution(SymbolicRegressionSolution original) {
373      SymbolicSimplifier simplifier = new SymbolicSimplifier();
374      SymbolicExpressionTree simplifiedTree = simplifier.Simplify(original.Model.SymbolicExpressionTree);
375      SymbolicRegressionModel simplifiedModel = new SymbolicRegressionModel(original.Model.Interpreter, simplifiedTree);
376      return new SymbolicRegressionSolution(original.ProblemData, simplifiedModel, original.LowerEstimationLimit, original.UpperEstimationLimit);
377    }
378
379    private void AssertEqualEnumerations(IEnumerable<double> expected, IEnumerable<double> actual) {
380      var expectedEnumerator = expected.GetEnumerator();
381      var actualEnumerator = actual.GetEnumerator();
382      while (expectedEnumerator.MoveNext() & actualEnumerator.MoveNext()) {
383        Assert.AreEqual(expectedEnumerator.Current, actualEnumerator.Current, Math.Abs(1E-6 * expectedEnumerator.Current));
384      }
385      if (expectedEnumerator.MoveNext() | actualEnumerator.MoveNext())
386        Assert.Fail("Number of elements in enumerations do not match");
387    }
388  }
389}
Note: See TracBrowser for help on using the repository browser.