Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/20/10 21:57:28 (14 years ago)
Author:
gkronber
Message:

Added constant folding to the symbolic simplifier for all data analysis symbols. #1227

Location:
branches/SymbolicSimplifier
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/SymbolicSimplifier/3.3/Symbolic/SymbolicSimplifier.cs

    r4477 r4878  
    3939    private Constant constSymbol = new Constant();
    4040    private Variable varSymbol = new Variable();
     41    private Logarithm logSymbol = new Logarithm();
     42    private Exponential expSymbol = new Exponential();
     43    private Sine sineSymbol = new Sine();
     44    private Cosine cosineSymbol = new Cosine();
     45    private Tangent tanSymbol = new Tangent();
     46    private IfThenElse ifThenElseSymbol = new IfThenElse();
     47    private And andSymbol = new And();
     48    private Or orSymbol = new Or();
     49    private Not notSymbol = new Not();
     50    private GreaterThan gtSymbol = new GreaterThan();
     51    private LessThan ltSymbol = new LessThan();
    4152
    4253    public SymbolicExpressionTree Simplify(SymbolicExpressionTree originalTree) {
     
    8495
    8596    #region symbol predicates
    86     private bool IsDivision(SymbolicExpressionTreeNode original) {
    87       return original.Symbol is Division;
    88     }
    89 
    90     private bool IsMultiplication(SymbolicExpressionTreeNode original) {
    91       return original.Symbol is Multiplication;
    92     }
    93 
    94     private bool IsSubtraction(SymbolicExpressionTreeNode original) {
    95       return original.Symbol is Subtraction;
    96     }
    97 
    98     private bool IsAddition(SymbolicExpressionTreeNode original) {
    99       return original.Symbol is Addition;
    100     }
    101 
    102     private bool IsVariable(SymbolicExpressionTreeNode original) {
    103       return original.Symbol is Variable;
    104     }
    105 
    106     private bool IsConstant(SymbolicExpressionTreeNode original) {
    107       return original.Symbol is Constant;
    108     }
    109 
    110     private bool IsAverage(SymbolicExpressionTreeNode original) {
    111       return original.Symbol is Average;
    112     }
    113     private bool IsLog(SymbolicExpressionTreeNode original) {
    114       return original.Symbol is Logarithm;
    115     }
    116     private bool IsIfThenElse(SymbolicExpressionTreeNode original) {
    117       return original.Symbol is IfThenElse;
    118     }
     97    // arithmetic
     98    private bool IsDivision(SymbolicExpressionTreeNode node) {
     99      return node.Symbol is Division;
     100    }
     101
     102    private bool IsMultiplication(SymbolicExpressionTreeNode node) {
     103      return node.Symbol is Multiplication;
     104    }
     105
     106    private bool IsSubtraction(SymbolicExpressionTreeNode node) {
     107      return node.Symbol is Subtraction;
     108    }
     109
     110    private bool IsAddition(SymbolicExpressionTreeNode node) {
     111      return node.Symbol is Addition;
     112    }
     113
     114    private bool IsAverage(SymbolicExpressionTreeNode node) {
     115      return node.Symbol is Average;
     116    }
     117    // exponential
     118    private bool IsLog(SymbolicExpressionTreeNode node) {
     119      return node.Symbol is Logarithm;
     120    }
     121    private bool IsExp(SymbolicExpressionTreeNode node) {
     122      return node.Symbol is Exponential;
     123    }
     124    // trigonometric
     125    private bool IsSine(SymbolicExpressionTreeNode node) {
     126      return node.Symbol is Sine;
     127    }
     128    private bool IsCosine(SymbolicExpressionTreeNode node) {
     129      return node.Symbol is Cosine;
     130    }
     131    private bool IsTangent(SymbolicExpressionTreeNode node) {
     132      return node.Symbol is Tangent;
     133    }
     134    // boolean
     135    private bool IsIfThenElse(SymbolicExpressionTreeNode node) {
     136      return node.Symbol is IfThenElse;
     137    }
     138    private bool IsAnd(SymbolicExpressionTreeNode node) {
     139      return node.Symbol is And;
     140    }
     141    private bool IsOr(SymbolicExpressionTreeNode node) {
     142      return node.Symbol is Or;
     143    }
     144    private bool IsNot(SymbolicExpressionTreeNode node) {
     145      return node.Symbol is Not;
     146    }
     147    // comparison
     148    private bool IsGreaterThan(SymbolicExpressionTreeNode node) {
     149      return node.Symbol is GreaterThan;
     150    }
     151    private bool IsLessThan(SymbolicExpressionTreeNode node) {
     152      return node.Symbol is LessThan;
     153    }
     154
     155    // terminals
     156    private bool IsVariable(SymbolicExpressionTreeNode node) {
     157      return node.Symbol is Variable;
     158    }
     159
     160    private bool IsConstant(SymbolicExpressionTreeNode node) {
     161      return node.Symbol is Constant;
     162    }
     163
    119164    #endregion
    120165
     
    138183        return SimplifyAverage(original);
    139184      } else if (IsLog(original)) {
    140         // TODO simplify logarithm
     185        return SimplifyLog(original);
     186      } else if (IsExp(original)) {
     187        return SimplifyExp(original);
     188      } else if (IsSine(original)) {
     189        return SimplifySine(original);
     190      } else if (IsCosine(original)) {
     191        return SimplifyCosine(original);
     192      } else if (IsTangent(original)) {
     193        return SimplifyTangent(original);
     194      } else if (IsIfThenElse(original)) {
     195        return SimplifyIfThenElse(original);
     196      } else if (IsGreaterThan(original)) {
     197        return SimplifyGreaterThan(original);
     198      } else if (IsLessThan(original)) {
     199        return SimplifyLessThan(original);
     200      } else if (IsAnd(original)) {
     201        return SimplifyAnd(original);
     202      } else if (IsOr(original)) {
     203        return SimplifyOr(original);
     204      } else if (IsNot(original)) {
     205        return SimplifyNot(original);
     206      } else {
    141207        return SimplifyAny(original);
    142       } else if (IsIfThenElse(original)) {
    143         // TODO simplify conditionals
    144         return SimplifyAny(original);
    145       } else if (IsAverage(original)) {
    146         return SimplifyAverage(original);
    147       } else {
    148         return SimplifyAny(original);
    149       }
    150     }
     208      }
     209    }
     210
    151211
    152212    #region specific simplification routines
     
    164224        clone.AddSubTree(simplifiedSubtree);
    165225      }
    166       if (simplifiedSubTrees.TrueForAll(t => IsConstant(t))) {
    167         SimplifyConstantExpression(clone);
    168       }
    169226      return clone;
    170     }
    171 
    172     private SymbolicExpressionTreeNode SimplifyConstantExpression(SymbolicExpressionTreeNode original) {
    173       // not yet implemented
    174       return original;
    175227    }
    176228
     
    239291      }
    240292    }
     293
     294    private SymbolicExpressionTreeNode SimplifyNot(SymbolicExpressionTreeNode original) {
     295      return MakeNot(GetSimplifiedTree(original.SubTrees[0]));
     296    }
     297    private SymbolicExpressionTreeNode SimplifyOr(SymbolicExpressionTreeNode original) {
     298      return original.SubTrees
     299        .Select(x => GetSimplifiedTree(x))
     300        .Aggregate((a, b) => MakeOr(a, b));
     301    }
     302    private SymbolicExpressionTreeNode SimplifyAnd(SymbolicExpressionTreeNode original) {
     303      return original.SubTrees
     304        .Select(x => GetSimplifiedTree(x))
     305        .Aggregate((a, b) => MakeAnd(a, b));
     306    }
     307    private SymbolicExpressionTreeNode SimplifyLessThan(SymbolicExpressionTreeNode original) {
     308      return MakeLessThan(GetSimplifiedTree(original.SubTrees[0]), GetSimplifiedTree(original.SubTrees[1]));
     309    }
     310    private SymbolicExpressionTreeNode SimplifyGreaterThan(SymbolicExpressionTreeNode original) {
     311      return MakeGreaterThan(GetSimplifiedTree(original.SubTrees[0]), GetSimplifiedTree(original.SubTrees[1]));
     312    }
     313    private SymbolicExpressionTreeNode SimplifyIfThenElse(SymbolicExpressionTreeNode original) {
     314      return MakeIfThenElse(GetSimplifiedTree(original.SubTrees[0]), GetSimplifiedTree(original.SubTrees[1]), GetSimplifiedTree(original.SubTrees[2]));
     315    }
     316    private SymbolicExpressionTreeNode SimplifyTangent(SymbolicExpressionTreeNode original) {
     317      return MakeTangent(GetSimplifiedTree(original.SubTrees[0]));
     318    }
     319    private SymbolicExpressionTreeNode SimplifyCosine(SymbolicExpressionTreeNode original) {
     320      return MakeCosine(GetSimplifiedTree(original.SubTrees[0]));
     321    }
     322    private SymbolicExpressionTreeNode SimplifySine(SymbolicExpressionTreeNode original) {
     323      return MakeSine(GetSimplifiedTree(original.SubTrees[0]));
     324    }
     325    private SymbolicExpressionTreeNode SimplifyExp(SymbolicExpressionTreeNode original) {
     326      return MakeExp(GetSimplifiedTree(original.SubTrees[0]));
     327    }
     328
     329    private SymbolicExpressionTreeNode SimplifyLog(SymbolicExpressionTreeNode original) {
     330      return MakeLog(GetSimplifiedTree(original.SubTrees[0]));
     331    }
     332
    241333    #endregion
    242334
     
    244336
    245337    #region low level tree restructuring
     338    private SymbolicExpressionTreeNode MakeNot(SymbolicExpressionTreeNode t) {
     339      return MakeProduct(t, MakeConstant(-1.0));
     340    }
     341
     342    private SymbolicExpressionTreeNode MakeOr(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) {
     343      if (IsConstant(a) && IsConstant(b)) {
     344        var constA = a as ConstantTreeNode;
     345        var constB = b as ConstantTreeNode;
     346        if (constA.Value > 0.0 || constB.Value > 0.0) {
     347          return MakeConstant(1.0);
     348        } else {
     349          return MakeConstant(-1.0);
     350        }
     351      } else if (IsConstant(a)) {
     352        return MakeOr(b, a);
     353      } else if (IsConstant(b)) {
     354        var constT = b as ConstantTreeNode;
     355        if (constT.Value > 0.0) {
     356          // boolean expression is necessarily true
     357          return MakeConstant(1.0);
     358        } else {
     359          // the constant value has no effect on the result of the boolean condition so we can drop the constant term
     360          var orNode = orSymbol.CreateTreeNode();
     361          orNode.AddSubTree(a);
     362          return orNode;
     363        }
     364      } else {
     365        var orNode = orSymbol.CreateTreeNode();
     366        orNode.AddSubTree(a);
     367        orNode.AddSubTree(b);
     368        return orNode;
     369      }
     370    }
     371    private SymbolicExpressionTreeNode MakeAnd(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) {
     372      if (IsConstant(a) && IsConstant(b)) {
     373        var constA = a as ConstantTreeNode;
     374        var constB = b as ConstantTreeNode;
     375        if (constA.Value > 0.0 && constB.Value > 0.0) {
     376          return MakeConstant(1.0);
     377        } else {
     378          return MakeConstant(-1.0);
     379        }
     380      } else if (IsConstant(a)) {
     381        return MakeAnd(b, a);
     382      } else if (IsConstant(b)) {
     383        var constB = b as ConstantTreeNode;
     384        if (constB.Value > 0.0) {
     385          // the constant value has no effect on the result of the boolean condition so we can drop the constant term
     386          var andNode = andSymbol.CreateTreeNode();
     387          andNode.AddSubTree(a);
     388          return andNode;
     389        } else {
     390          // boolean expression is necessarily false
     391          return MakeConstant(-1.0);
     392        }
     393      } else {
     394        var andNode = andSymbol.CreateTreeNode();
     395        andNode.AddSubTree(a);
     396        andNode.AddSubTree(b);
     397        return andNode;
     398      }
     399    }
     400    private SymbolicExpressionTreeNode MakeLessThan(SymbolicExpressionTreeNode leftSide, SymbolicExpressionTreeNode rightSide) {
     401      if (IsConstant(leftSide) && IsConstant(rightSide)) {
     402        var lsConst = leftSide as ConstantTreeNode;
     403        var rsConst = rightSide as ConstantTreeNode;
     404        if (lsConst.Value < rsConst.Value) return MakeConstant(1.0);
     405        else return MakeConstant(-1.0);
     406      } else {
     407        var ltNode = ltSymbol.CreateTreeNode();
     408        ltNode.AddSubTree(leftSide);
     409        ltNode.AddSubTree(rightSide);
     410        return ltNode;
     411      }
     412    }
     413    private SymbolicExpressionTreeNode MakeGreaterThan(SymbolicExpressionTreeNode leftSide, SymbolicExpressionTreeNode rightSide) {
     414      if (IsConstant(leftSide) && IsConstant(rightSide)) {
     415        var lsConst = leftSide as ConstantTreeNode;
     416        var rsConst = rightSide as ConstantTreeNode;
     417        if (lsConst.Value > rsConst.Value) return MakeConstant(1.0);
     418        else return MakeConstant(-1.0);
     419      } else {
     420        var gtNode = gtSymbol.CreateTreeNode();
     421        gtNode.AddSubTree(leftSide);
     422        gtNode.AddSubTree(rightSide);
     423        return gtNode;
     424      }
     425    }
     426    private SymbolicExpressionTreeNode MakeIfThenElse(SymbolicExpressionTreeNode condition, SymbolicExpressionTreeNode trueBranch, SymbolicExpressionTreeNode falseBranch) {
     427      if (IsConstant(condition)) {
     428        var constT = condition as ConstantTreeNode;
     429        if (constT.Value > 0.0) return trueBranch;
     430        else return falseBranch;
     431      } else {
     432        var ifNode = ifThenElseSymbol.CreateTreeNode();
     433        ifNode.AddSubTree(condition);
     434        ifNode.AddSubTree(trueBranch);
     435        ifNode.AddSubTree(falseBranch);
     436        return ifNode;
     437      }
     438    }
     439    private SymbolicExpressionTreeNode MakeSine(SymbolicExpressionTreeNode node) {
     440      // todo implement more transformation rules
     441      if (IsConstant(node)) {
     442        var constT = node as ConstantTreeNode;
     443        return MakeConstant(Math.Sin(constT.Value));
     444      } else {
     445        var sineNode = sineSymbol.CreateTreeNode();
     446        sineNode.AddSubTree(node);
     447        return sineNode;
     448      }
     449    }
     450    private SymbolicExpressionTreeNode MakeTangent(SymbolicExpressionTreeNode node) {
     451      // todo implement more transformation rules
     452      if (IsConstant(node)) {
     453        var constT = node as ConstantTreeNode;
     454        return MakeConstant(Math.Tan(constT.Value));
     455      } else {
     456        var tanNode = tanSymbol.CreateTreeNode();
     457        tanNode.AddSubTree(node);
     458        return tanNode;
     459      }
     460    }
     461    private SymbolicExpressionTreeNode MakeCosine(SymbolicExpressionTreeNode node) {
     462      // todo implement more transformation rules
     463      if (IsConstant(node)) {
     464        var constT = node as ConstantTreeNode;
     465        return MakeConstant(Math.Cos(constT.Value));
     466      } else {
     467        var cosNode = cosineSymbol.CreateTreeNode();
     468        cosNode.AddSubTree(node);
     469        return cosNode;
     470      }
     471    }
     472    private SymbolicExpressionTreeNode MakeExp(SymbolicExpressionTreeNode node) {
     473      // todo implement more transformation rules
     474      if (IsConstant(node)) {
     475        var constT = node as ConstantTreeNode;
     476        return MakeConstant(Math.Exp(constT.Value));
     477      } else {
     478        var expNode = expSymbol.CreateTreeNode();
     479        expNode.AddSubTree(node);
     480        return expNode;
     481      }
     482    }
     483    private SymbolicExpressionTreeNode MakeLog(SymbolicExpressionTreeNode node) {
     484      // todo implement more transformation rules
     485      if (IsConstant(node)) {
     486        var constT = node as ConstantTreeNode;
     487        return MakeConstant(Math.Log(constT.Value));
     488      } else {
     489        var logNode = logSymbol.CreateTreeNode();
     490        logNode.AddSubTree(node);
     491        return logNode;
     492      }
     493    }
     494
     495
    246496    // MakeFraction, MakeProduct and MakeSum take two already simplified trees and create a new simplified tree
    247497
Note: See TracChangeset for help on using the changeset viewer.