source: trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs @ 14185

Last change on this file since 14185 was 14185, checked in by swagner, 6 years ago

#2526: Updated year of copyrights in license headers

File size: 17.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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.Encodings.SymbolicExpressionTreeEncoding;
25using HeuristicLab.Problems.DataAnalysis.Symbolic;
26using Microsoft.VisualStudio.TestTools.UnitTesting;
27
28namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Tests {
29
30  [TestClass()]
31  public class SymbolicDataAnalysisExpressionTreeSimplifierTest {
32
33    [TestMethod]
34    [TestCategory("Problems.DataAnalysis")]
35    [TestProperty("Time", "short")]
36    public void SimplifierAxiomsTest() {
37      SymbolicExpressionImporter importer = new SymbolicExpressionImporter();
38      SymbolicDataAnalysisExpressionTreeSimplifier simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier();
39      SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
40      #region single argument arithmetics
41      {
42        var actualTree = simplifier.Simplify(importer.Import("(+ 1.0)"));
43        var expectedTree = importer.Import("1.0");
44        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
45      }
46      {
47        var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a))"));
48        var expectedTree = importer.Import("(variable 2.0 a)");
49        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
50      }
51      {
52        var actualTree = simplifier.Simplify(importer.Import("(- 1.0)"));
53        var expectedTree = importer.Import("-1.0");
54        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
55      }
56      {
57        var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a))"));
58        var expectedTree = importer.Import("(variable -2.0 a)");
59        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
60      }
61      {
62        var actualTree = simplifier.Simplify(importer.Import("(* 2.0)"));
63        var expectedTree = importer.Import("2.0");
64        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
65      }
66      {
67        var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a))"));
68        var expectedTree = importer.Import("(variable 2.0 a)");
69        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
70      }
71      {
72        var actualTree = simplifier.Simplify(importer.Import("(/ 2.0)"));
73        var expectedTree = importer.Import("0.5");
74        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
75      }
76      {
77        var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a))"));
78        var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
79        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
80      }
81      #endregion
82      #region aggregation of constants into factors
83      {
84        var actualTree = simplifier.Simplify(importer.Import("(* 2.0 (variable 2.0 a))"));
85        var expectedTree = importer.Import("(variable 4.0 a)");
86        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
87      }
88      {
89        var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a) 2.0)"));
90        var expectedTree = importer.Import("(variable 1.0 a)");
91        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
92      }
93      {
94        var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a) (* 2.0 2.0))"));
95        var expectedTree = importer.Import("(variable 0.5 a)");
96        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
97      }
98      #endregion
99      #region constant and variable folding
100      {
101        var actualTree = simplifier.Simplify(importer.Import("(+ 1.0 2.0)"));
102        var expectedTree = importer.Import("3.0");
103        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
104      }
105      {
106        var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a) (variable 2.0 a))"));
107        var expectedTree = importer.Import("(variable 4.0 a)");
108        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
109      }
110      {
111        var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a) (variable 1.0 a))"));
112        var expectedTree = importer.Import("(variable 1.0 a)");
113        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
114      }
115      {
116        var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a) (variable 2.0 a))"));
117        var expectedTree = importer.Import("(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)");
118        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
119      }
120      {
121        var actualTree = simplifier.Simplify(importer.Import("(/ (variable 1.0 a) (variable 2.0 a))"));
122        var expectedTree = importer.Import("0.5");
123        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
124      }
125      #endregion
126      #region logarithm rules
127      {
128        // cancellation
129        var actualTree = simplifier.Simplify(importer.Import("(log (exp (variable 2.0 a)))"));
130        var expectedTree = importer.Import("(variable 2.0 a)");
131        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
132      }
133      {
134        // must not transform logs in this way as we do not know wether both variables are positive
135        var actualTree = simplifier.Simplify(importer.Import("(log (* (variable 1.0 a) (variable 1.0 b)))"));
136        var expectedTree = importer.Import("(log (* (variable 1.0 a) (variable 1.0 b)))");
137        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
138      }
139      {
140        // must not transform logs in this way as we do not know wether both variables are positive
141        var actualTree = simplifier.Simplify(importer.Import("(log (/ (variable 1.0 a) (variable 1.0 b)))"));
142        var expectedTree = importer.Import("(log (/ (variable 1.0 a) (variable 1.0 b)))");
143        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
144      }
145      #endregion
146      #region exponentiation rules
147      {
148        // cancellation
149        var actualTree = simplifier.Simplify(importer.Import("(exp (log (variable 2.0 a)))"));
150        var expectedTree = importer.Import("(variable 2.0 a)");
151        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
152      }
153      {
154        // exp transformation
155        var actualTree = simplifier.Simplify(importer.Import("(exp (+ (variable 2.0 a) (variable 3.0 b)))"));
156        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable 3.0 b)))");
157        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
158      }
159      {
160        // exp transformation
161        var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (variable 3.0 b)))"));
162        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable -3.0 b)))");
163        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
164      }
165      {
166        // exp transformation
167        var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (* (variable 3.0 b) (variable 4.0 c))))"));
168        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (variable 1.0 c) -12.0)))");
169        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
170      }
171      {
172        // exp transformation
173        var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (* (variable 3.0 b) (cos (variable 4.0 c)))))"));
174        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (cos (variable 4.0 c)) -3.0)))");
175        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
176      }
177      #endregion
178      #region power rules
179      {
180        // cancellation
181        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 0.0)"));
182        var expectedTree = importer.Import("1.0");
183        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
184      }
185      {
186        // fixed point
187        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 1.0)"));
188        var expectedTree = importer.Import("(variable 2.0 a)");
189        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
190      }
191      {
192        // inversion fixed point
193        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -1.0)"));
194        var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
195        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
196      }
197      {
198        // inversion
199        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -2.0)"));
200        var expectedTree = importer.Import("(/ 1.0 (pow (variable 2.0 a) 2.0))");
201        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
202      }
203      {
204        // constant folding
205        var actualTree = simplifier.Simplify(importer.Import("(pow 3.0 2.0)"));
206        var expectedTree = importer.Import("9.0");
207        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
208      }
209      #endregion
210      #region root rules
211      {
212        // cancellation
213        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 0.0)"));
214        var expectedTree = importer.Import("1.0");
215        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
216      }
217      {
218        // fixed point
219        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 1.0)"));
220        var expectedTree = importer.Import("(variable 2.0 a)");
221        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
222      }
223      {
224        // inversion fixed point
225        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -1.0)"));
226        var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
227        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
228      }
229      {
230        // inversion
231        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -2.0)"));
232        var expectedTree = importer.Import("(/ 1.0 (root (variable 2.0 a) 2.0))");
233        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
234      }
235      {
236        // constant folding
237        var actualTree = simplifier.Simplify(importer.Import("(root 9.0 2.0)"));
238        var expectedTree = importer.Import("3.0");
239        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
240      }
241      #endregion
242      #region boolean operations
243      {
244        // always true and
245        var actualTree = simplifier.Simplify(importer.Import("(and 1.0 2.0)"));
246        var expectedTree = importer.Import("1.0");
247        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
248      }
249      {
250        // always false and
251        var actualTree = simplifier.Simplify(importer.Import("(and 1.0 -2.0)"));
252        var expectedTree = importer.Import("-1.0");
253        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
254      }
255      {
256        // always true or
257        var actualTree = simplifier.Simplify(importer.Import("(or -1.0 2.0)"));
258        var expectedTree = importer.Import("1.0");
259        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
260      }
261      {
262        // always false or
263        var actualTree = simplifier.Simplify(importer.Import("(or -1.0 -2.0)"));
264        var expectedTree = importer.Import("-1.0");
265        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
266      }
267      {
268        // constant not
269        var actualTree = simplifier.Simplify(importer.Import("(not -2.0)"));
270        var expectedTree = importer.Import("1.0");
271        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
272      }
273      {
274        // constant not
275        var actualTree = simplifier.Simplify(importer.Import("(not 2.0)"));
276        var expectedTree = importer.Import("-1.0");
277        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
278      }
279      {
280        // constant not
281        var actualTree = simplifier.Simplify(importer.Import("(not 0.0)"));
282        var expectedTree = importer.Import("1.0");
283        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
284      }
285      {
286        // nested nots
287        var actualTree = simplifier.Simplify(importer.Import("(not (not 1.0))"));
288        var expectedTree = importer.Import("1.0");
289        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
290      }
291      {
292        // not of non-Boolean argument
293        var actualTree = simplifier.Simplify(importer.Import("(not (variable 1.0 a))"));
294        var expectedTree = importer.Import("(not (> (variable 1.0 a) 0.0))");
295        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
296      }
297      {
298        // not Boolean argument
299        var actualTree = simplifier.Simplify(importer.Import("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))"));
300        var expectedTree = importer.Import("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))");
301        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
302      }
303      #endregion
304      #region conditionals
305      {
306        // always false
307        var actualTree = simplifier.Simplify(importer.Import("(if -1.0 (variable 2.0 a) (variable 3.0 a))"));
308        var expectedTree = importer.Import("(variable 3.0 a)");
309        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
310      }
311      {
312        // always true
313        var actualTree = simplifier.Simplify(importer.Import("(if 1.0 (variable 2.0 a) (variable 3.0 a))"));
314        var expectedTree = importer.Import("(variable 2.0 a)");
315        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
316      }
317      {
318        // always false (0.0)
319        var actualTree = simplifier.Simplify(importer.Import("(if 0.0 (variable 2.0 a) (variable 3.0 a))"));
320        var expectedTree = importer.Import("(variable 3.0 a)");
321        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
322      }
323      {
324        // complex constant condition (always false)
325        var actualTree = simplifier.Simplify(importer.Import("(if (* 1.0 -2.0) (variable 2.0 a) (variable 3.0 a))"));
326        var expectedTree = importer.Import("(variable 3.0 a)");
327        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
328      }
329      {
330        // complex constant condition (always false)
331        var actualTree = simplifier.Simplify(importer.Import("(if (/ (variable 1.0 a) (variable -2.0 a)) (variable 2.0 a) (variable 3.0 a))"));
332        var expectedTree = importer.Import("(variable 3.0 a)");
333        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
334      }
335      {
336        // insertion of relational operator
337        var actualTree = simplifier.Simplify(importer.Import("(if (variable 1.0 a) (variable 2.0 a) (variable 3.0 a))"));
338        var expectedTree = importer.Import("(if (> (variable 1.0 a) 0.0) (variable 2.0 a) (variable 3.0 a))");
339        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
340      }
341      #endregion
342    }
343
344    private void AssertEqualEnumerations(IEnumerable<double> expected, IEnumerable<double> actual) {
345      var expectedEnumerator = expected.GetEnumerator();
346      var actualEnumerator = actual.GetEnumerator();
347      while (expectedEnumerator.MoveNext() & actualEnumerator.MoveNext()) {
348        Assert.AreEqual(expectedEnumerator.Current, actualEnumerator.Current, Math.Abs(1E-6 * expectedEnumerator.Current));
349      }
350      if (expectedEnumerator.MoveNext() | actualEnumerator.MoveNext())
351        Assert.Fail("Number of elements in enumerations do not match");
352    }
353  }
354}
Note: See TracBrowser for help on using the repository browser.