Ignore:
Timestamp:
04/04/17 17:52:44 (6 months ago)
Author:
gkronber
Message:

#2650: merged the factors branch into trunk

Location:
trunk/sources
Files:
4 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/sources

  • trunk/sources/HeuristicLab.Tests

  • trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/InfixExpressionParserTest.cs

    r14350 r14826  
    3737      Console.WriteLine(formatter.Format(parser.Parse("3*3")));
    3838      Console.WriteLine(formatter.Format(parser.Parse("3 * 4")));
    39       Console.WriteLine(formatter.Format(parser.Parse("123E-03")  ));
     39      Console.WriteLine(formatter.Format(parser.Parse("123E-03")));
    4040      Console.WriteLine(formatter.Format(parser.Parse("123e-03")));
    4141      Console.WriteLine(formatter.Format(parser.Parse("123e+03")));
     
    106106      Console.WriteLine(formatter.Format(parser.Parse("x * LAG('x', +1)")));
    107107
     108      Console.WriteLine(formatter.Format(parser.Parse("x [1.0] * y")));
     109      Console.WriteLine(formatter.Format(parser.Parse("x [1.0, 2.0] * y [1.0, 2.0]")));
     110      Console.WriteLine(formatter.Format(parser.Parse("x[1] * y")));
     111      Console.WriteLine(formatter.Format(parser.Parse("x[1, 2] * y [1, 2]")));
     112
     113      Console.WriteLine(formatter.Format(parser.Parse("x [+1.0] * y")));
     114      Console.WriteLine(formatter.Format(parser.Parse("x [-1.0] * y")));
     115      Console.WriteLine(formatter.Format(parser.Parse("x [-1.0, -2.0] * y [+1.0, +2.0]")));
     116
     117      Console.WriteLine(formatter.Format(parser.Parse("x='bla' * y")));
     118      Console.WriteLine(formatter.Format(parser.Parse("x = 'bla'")));
     119      Console.WriteLine(formatter.Format(parser.Parse("x = \"bla\"")));
     120      Console.WriteLine(formatter.Format(parser.Parse("1.0 * x = bla")));
     121      Console.WriteLine(formatter.Format(parser.Parse("-1.0 * x = bla")));
     122      Console.WriteLine(formatter.Format(parser.Parse("+1.0 * \"x\" = bla + y = \"bla2\"")));
    108123    }
    109124  }
  • trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs

    r14400 r14826  
    1919 */
    2020#endregion
    21 
    2221using System;
    23 using System.Collections.Generic;
     22using System.Globalization;
    2423using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    25 using HeuristicLab.Problems.DataAnalysis.Symbolic;
    2624using Microsoft.VisualStudio.TestTools.UnitTesting;
    2725
     
    3937      SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
    4038      #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
     39
     40      AssertEqualAfterSimplification("(+ 1.0)", "1.0");
     41      AssertEqualAfterSimplification("(- 1.0)", "-1.0");
     42      AssertEqualAfterSimplification("(- (variable 2.0 a))", "(variable -2.0 a)");
     43      AssertEqualAfterSimplification("(* 2.0)", "2.0");
     44      AssertEqualAfterSimplification("(* (variable 2.0 a))", "(variable 2.0 a)");
     45      AssertEqualAfterSimplification("(/ 2.0)", "0.5");
     46      AssertEqualAfterSimplification("(/ (variable 2.0 a))", "(/ 1.0 (variable 2.0 a))");
     47      #endregion
     48
    8249      #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
     50      AssertEqualAfterSimplification("(* 2.0 (variable 2.0 a))", "(variable 4.0 a)");
     51      AssertEqualAfterSimplification("(/ (variable 2.0 a) 2.0)", "(variable 1.0 a)");
     52      AssertEqualAfterSimplification("(/ (variable 2.0 a) (* 2.0 2.0))", "(variable 0.5 a)");
     53      #endregion
     54
    9955      #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
     56      AssertEqualAfterSimplification("(+ 1.0 2.0)", "3.0");
     57      AssertEqualAfterSimplification("(+ (variable 2.0 a) (variable 2.0 a))", "(variable 4.0 a)");
     58      AssertEqualAfterSimplification("(- (variable 2.0 a) (variable 1.0 a))", "(variable 1.0 a)");
     59      AssertEqualAfterSimplification("(* (variable 2.0 a) (variable 2.0 a))", "(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)");
     60      AssertEqualAfterSimplification("(/ (variable 1.0 a) (variable 2.0 a))", "0.5");
     61      #endregion
     62
    12663      #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
     64
     65      // cancellation
     66      AssertEqualAfterSimplification("(log (exp (variable 2.0 a)))", "(variable 2.0 a)");
     67      // must not transform logs in this way as we do not know wether both variables are positive
     68      AssertEqualAfterSimplification("(log (* (variable 1.0 a) (variable 1.0 b)))", "(log (* (variable 1.0 a) (variable 1.0 b)))");
     69      // must not transform logs in this way as we do not know wether both variables are positive
     70      AssertEqualAfterSimplification("(log (/ (variable 1.0 a) (variable 1.0 b)))", "(log (/ (variable 1.0 a) (variable 1.0 b)))");
     71      #endregion
     72
    14673      #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
     74      // cancellation
     75      AssertEqualAfterSimplification("(exp (log (variable 2.0 a)))", "(variable 2.0 a)");
     76      // exp transformation
     77      AssertEqualAfterSimplification("(exp (+ (variable 2.0 a) (variable 3.0 b)))", "(* (exp (variable 2.0 a)) (exp (variable 3.0 b)))");
     78      // exp transformation
     79      AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (variable 3.0 b)))", "(* (exp (variable 2.0 a)) (exp (variable -3.0 b)))");
     80      // exp transformation
     81      AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (* (variable 3.0 b) (variable 4.0 c))))", "(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (variable 1.0 c) -12.0)))");
     82      // exp transformation
     83      AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (* (variable 3.0 b) (cos (variable 4.0 c)))))", "(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (cos (variable 4.0 c)) -3.0)))");
     84      #endregion
     85
    17886      #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
     87
     88      // cancellation
     89      AssertEqualAfterSimplification("(pow (variable 2.0 a) 0.0)", "1.0");
     90      // fixed point
     91      AssertEqualAfterSimplification("(pow (variable 2.0 a) 1.0)", "(variable 2.0 a)");
     92      // inversion fixed point
     93      AssertEqualAfterSimplification("(pow (variable 2.0 a) -1.0)", "(/ 1.0 (variable 2.0 a))");
     94      // inversion
     95      AssertEqualAfterSimplification("(pow (variable 2.0 a) -2.0)", "(/ 1.0 (pow (variable 2.0 a) 2.0))");
     96      // constant folding
     97      AssertEqualAfterSimplification("(pow 3.0 2.0)", "9.0");
     98      #endregion
     99
    210100      #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
     101      // cancellation
     102      AssertEqualAfterSimplification("(root (variable 2.0 a) 0.0)", "1.0");
     103      // fixed point
     104      AssertEqualAfterSimplification("(root (variable 2.0 a) 1.0)", "(variable 2.0 a)");
     105      // inversion fixed point
     106      AssertEqualAfterSimplification("(root (variable 2.0 a) -1.0)", "(/ 1.0 (variable 2.0 a))");
     107      // inversion
     108      AssertEqualAfterSimplification("(root (variable 2.0 a) -2.0)", "(/ 1.0 (root (variable 2.0 a) 2.0))");
     109      // constant folding
     110      AssertEqualAfterSimplification("(root 9.0 2.0)", "3.0");
     111      #endregion
     112
    242113      #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
     114      // always true and
     115      AssertEqualAfterSimplification("(and 1.0 2.0)", "1.0");
     116      // always false and
     117      AssertEqualAfterSimplification("(and 1.0 -2.0)", "-1.0");
     118      // always true or
     119      AssertEqualAfterSimplification("(or -1.0 2.0)", "1.0");
     120      // always false or
     121      AssertEqualAfterSimplification("(or -1.0 -2.0)", "-1.0");
     122      // constant not
     123      AssertEqualAfterSimplification("(not -2.0)", "1.0");
     124      // constant not
     125      AssertEqualAfterSimplification("(not 2.0)", "-1.0");
     126      // constant not
     127      AssertEqualAfterSimplification("(not 0.0)", "1.0");
     128      // nested nots
     129      AssertEqualAfterSimplification("(not (not 1.0))", "1.0");
     130      // not of non-Boolean argument
     131      AssertEqualAfterSimplification("(not (variable 1.0 a))", "(not (> (variable 1.0 a) 0.0))");
     132      // not Boolean argument
     133      AssertEqualAfterSimplification("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))", "(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))");
     134      #endregion
     135
    304136      #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       }
     137      // always false
     138      AssertEqualAfterSimplification("(if -1.0 (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
     139      // always true
     140      AssertEqualAfterSimplification("(if 1.0 (variable 2.0 a) (variable 3.0 a))", "(variable 2.0 a)");
     141      // always false (0.0)
     142      AssertEqualAfterSimplification("(if 0.0 (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
     143      // complex constant condition (always false)
     144      AssertEqualAfterSimplification("(if (* 1.0 -2.0) (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
     145      // complex constant condition (always false)
     146      AssertEqualAfterSimplification("(if (/ (variable 1.0 a) (variable -2.0 a)) (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)");
     147      // insertion of relational operator
     148      AssertEqualAfterSimplification("(if (variable 1.0 a) (variable 2.0 a) (variable 3.0 a))", "(if (> (variable 1.0 a) 0.0) (variable 2.0 a) (variable 3.0 a))");
     149      #endregion
     150
     151      #region factor variables
     152      AssertEqualAfterSimplification("(factor a 1.0)", "(factor a 1.0)");
     153      // factor folding
     154      AssertEqualAfterSimplification("(+ (factor a 1.0 1.0) (factor a 2.0 3.0))", "(factor a 3.0 4.0)");
     155      AssertEqualAfterSimplification("(- (factor a 1.0 1.0) (factor a 2.0 3.0))", "(factor a -1.0 -2.0)");
     156      AssertEqualAfterSimplification("(* (factor a 2.0 2.0) (factor a 2.0 3.0))", "(factor a 4.0 6.0)");
     157      AssertEqualAfterSimplification("(/ (factor a 2.0 5.0))", "(factor a 0.5 0.2)");
     158      AssertEqualAfterSimplification("(/ (factor a 4.0 6.0) (factor a 2.0 3.0))", "(factor a 2.0 2.0)");
     159      AssertEqualAfterSimplification("(+ 3.0 (factor a 4.0 6.0))", "(factor a 7.0 9.0)");
     160      AssertEqualAfterSimplification("(+ (factor a 4.0 6.0) 3.0)", "(factor a 7.0 9.0)");
     161      AssertEqualAfterSimplification("(- 3.0 (factor a 4.0 6.0))", "(factor a -1.0 -3.0)");
     162      AssertEqualAfterSimplification("(- (factor a 4.0 6.0) 3.0)", "(factor a 1.0 3.0)");
     163      AssertEqualAfterSimplification("(* 2.0 (factor a 4.0 6.0))", "(factor a 8.0 12.0)");
     164      AssertEqualAfterSimplification("(* (factor a 4.0 6.0) 2.0)", "(factor a 8.0 12.0)");
     165      AssertEqualAfterSimplification("(* (factor a 4.0 6.0) (variable 2.0 a))", "(* (factor a 8.0 12.0) (variable 1.0 a))"); // not possible (a is used as factor and double variable) interpreter will fail
     166      AssertEqualAfterSimplification(
     167        "(log (factor a 10.0 100.0))",
     168        string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1})", Math.Log(10.0), Math.Log(100.0)));
     169      AssertEqualAfterSimplification(
     170        "(exp (factor a 2.0 3.0))",
     171        string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1})", Math.Exp(2.0), Math.Exp(3.0)));
     172      AssertEqualAfterSimplification("(sqrt (factor a 9.0 16.0))", "(factor a 3.0 4.0))");
     173      AssertEqualAfterSimplification("(sqr (factor a 2.0 3.0))", "(factor a 4.0 9.0))");
     174      AssertEqualAfterSimplification("(root (factor a 8.0 27.0) 3)", "(factor a 2.0 3.0))");
     175      AssertEqualAfterSimplification("(pow (factor a 2.0 3.0) 3)", "(factor a 8.0 27.0))");
     176
     177      AssertEqualAfterSimplification("(sin (factor a 1.0 2.0) )",
     178        string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Sin(1.0), Math.Sin(2.0)));
     179      AssertEqualAfterSimplification("(cos (factor a 1.0 2.0) )",
     180        string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Cos(1.0), Math.Cos(2.0)));
     181      AssertEqualAfterSimplification("(tan (factor a 1.0 2.0) )",
     182        string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Tan(1.0), Math.Tan(2.0)));
     183
     184
     185      AssertEqualAfterSimplification("(binfactor a val 1.0)", "(binfactor a val 1.0)");
     186      // binfactor folding
     187      AssertEqualAfterSimplification("(+ (binfactor a val 1.0) (binfactor a val 2.0))", "(binfactor a val 3.0)");
     188      AssertEqualAfterSimplification("(+ (binfactor a val0 1.0) (binfactor a val1 2.0))", "(+ (binfactor a val0 1.0) (binfactor a val1 2.0))"); // cannot be simplified (different vals)
     189      AssertEqualAfterSimplification("(+ (binfactor a val 1.0) (binfactor b val 2.0))", "(+ (binfactor a val 1.0) (binfactor b val 2.0))"); // cannot be simplified (different vars)
     190      AssertEqualAfterSimplification("(- (binfactor a val 1.0) (binfactor a val 2.0))", "(binfactor a val -1.0)");
     191      AssertEqualAfterSimplification("(* (binfactor a val 2.0) (binfactor a val 3.0))", "(binfactor a val 6.0)");
     192      AssertEqualAfterSimplification("(/ (binfactor a val 6.0) (binfactor a val 3.0))", "(/ (binfactor a val 6.0) (binfactor a val 3.0))"); // not allowed! 0/0 for other values than 'val'
     193      AssertEqualAfterSimplification("(/ (binfactor a val 4.0))", "(/ 1.0 (binfactor a val 4.0))"); // not allowed!
     194
     195      AssertEqualAfterSimplification("(+ 3.0 (binfactor a val 4.0 ))", "(+ (binfactor a val 4.0 ) 3.0))"); // not allowed
     196      AssertEqualAfterSimplification("(- 3.0 (binfactor a val 4.0 ))", "(+ (binfactor a val -4.0 ) 3.0)");
     197      AssertEqualAfterSimplification("(+ (binfactor a val 4.0 ) 3.0)", "(+ (binfactor a val 4.0 ) 3.0)");  // not allowed
     198      AssertEqualAfterSimplification("(- (binfactor a val 4.0 ) 3.0)", "(+ (binfactor a val 4.0 ) -3.0)");
     199      AssertEqualAfterSimplification("(* 2.0 (binfactor a val 4.0))", "(binfactor a val 8.0 )");
     200      AssertEqualAfterSimplification("(* (binfactor a val 4.0) 2.0)", "(binfactor a val 8.0 )");
     201      AssertEqualAfterSimplification("(* (binfactor a val 4.0) (variable 2.0 a))", "(* (binfactor a val 1.0) (variable 1.0 a) 8.0)");   // not possible (a is used as factor and double variable) interpreter will fail
     202      AssertEqualAfterSimplification("(log (binfactor a val 10.0))", "(log (binfactor a val 10.0))"); // not allowed (log(0))
     203
     204      // exp( binfactor w val=a) = if(val=a) exp(w) else exp(0) = binfactor( (exp(w) - 1) val a) + 1
     205      AssertEqualAfterSimplification("(exp (binfactor a val 3.0))",
     206        string.Format(CultureInfo.InvariantCulture, "(+ (binfactor a val {0}) 1.0)", Math.Exp(3.0) - 1)
     207        );
     208      AssertEqualAfterSimplification("(sqrt (binfactor a val 16.0))", "(binfactor a val 4.0))"); // sqrt(0) = 0
     209      AssertEqualAfterSimplification("(sqr (binfactor a val 3.0))", "(binfactor a val 9.0))"); // 0*0 = 0
     210      AssertEqualAfterSimplification("(root (binfactor a val 27.0) 3)", "(binfactor a val 3.0))");
     211      AssertEqualAfterSimplification("(pow (binfactor a val 3.0) 3)", "(binfactor a val 27.0))");
     212
     213      AssertEqualAfterSimplification("(sin (binfactor a val 2.0) )",
     214        string.Format(CultureInfo.InvariantCulture, "(binfactor a val {0}))", Math.Sin(2.0))); // sin(0) = 0
     215      AssertEqualAfterSimplification("(cos (binfactor a val 2.0) )",
     216        string.Format(CultureInfo.InvariantCulture, "(+ (binfactor a val {0}) 1.0)", Math.Cos(2.0) - 1)); // cos(0) = 1
     217      AssertEqualAfterSimplification("(tan (binfactor a val 2.0) )",
     218        string.Format(CultureInfo.InvariantCulture, "(binfactor a val {0}))", Math.Tan(2.0))); // tan(0) = 0
     219
     220      // combination of factor and binfactor
     221      AssertEqualAfterSimplification("(+ (binfactor a x0 2.0) (factor a 2.0 3.0))", "(factor a 4.0 3.0)");
     222      AssertEqualAfterSimplification("(+ (factor a 2.0 3.0) (binfactor a x0 2.0))", "(factor a 4.0 3.0)");
     223      AssertEqualAfterSimplification("(* (binfactor a x1 2.0) (factor a 2.0 3.0))", "(binfactor a x1 6.0)"); // all other values have weight zero in binfactor
     224      AssertEqualAfterSimplification("(* (factor a 2.0 3.0) (binfactor a x1 2.0))", "(binfactor a x1 6.0)"); // all other values have weight zero in binfactor
     225      AssertEqualAfterSimplification("(/ (binfactor a x0 2.0) (factor a 2.0 3.0))", "(binfactor a x0 1.0)");
     226      AssertEqualAfterSimplification("(/ (factor a 2.0 3.0) (binfactor a x0 2.0))",
     227        string.Format(CultureInfo.InvariantCulture, "(factor a 1.0 {0})", 3.0 / 0.0));
     228      AssertEqualAfterSimplification("(- (binfactor a x0 2.0) (factor a 2.0 3.0))", "(factor a 0.0 -3.0)");
     229      AssertEqualAfterSimplification("(- (factor a 2.0 3.0) (binfactor a x0 2.0))", "(factor a 0.0 3.0)");
    341230      #endregion
    342231    }
    343232
    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");
     233
     234    private void AssertEqualAfterSimplification(string original, string expected) {
     235      var simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier();
     236      var formatter = new SymbolicExpressionTreeStringFormatter();
     237      var importer = new SymbolicExpressionImporter();
     238      var actualTree = simplifier.Simplify(importer.Import(original));
     239      var expectedTree = importer.Import(expected);
     240      Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     241
    352242    }
    353243  }
    354244}
     245
Note: See TracChangeset for help on using the changeset viewer.