Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tests/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs @ 6832

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

#1645: fixed bug related to simplification of logarithmic expressions

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