Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 9764 was 9764, checked in by abeham, 9 years ago

#2088: Renamed namespaces (removed _33 and _34 postfixes)

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