Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/06/17 11:19:24 (7 years ago)
Author:
gkronber
Message:

#2697: merged r14938,r14949,r14950 from trunk to stable

Location:
stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs

    r14843 r15145  
    3333  /// </summary>
    3434  public class TreeSimplifier {
    35     private Addition addSymbol = new Addition();
    36     private Multiplication mulSymbol = new Multiplication();
    37     private Division divSymbol = new Division();
    38     private Constant constSymbol = new Constant();
    39     private Variable varSymbol = new Variable();
    40     private Logarithm logSymbol = new Logarithm();
    41     private Exponential expSymbol = new Exponential();
    42     private Root rootSymbol = new Root();
    43     private Square sqrSymbol = new Square();
    44     private SquareRoot sqrtSymbol = new SquareRoot();
    45     private Power powSymbol = new Power();
    46     private Sine sineSymbol = new Sine();
    47     private Cosine cosineSymbol = new Cosine();
    48     private Tangent tanSymbol = new Tangent();
    49     private IfThenElse ifThenElseSymbol = new IfThenElse();
    50     private And andSymbol = new And();
    51     private Or orSymbol = new Or();
    52     private Not notSymbol = new Not();
    53     private GreaterThan gtSymbol = new GreaterThan();
    54     private LessThan ltSymbol = new LessThan();
    55     private Integral integralSymbol = new Integral();
    56     private LaggedVariable laggedVariableSymbol = new LaggedVariable();
    57     private TimeLag timeLagSymbol = new TimeLag();
    58 
    59     public ISymbolicExpressionTree Simplify(ISymbolicExpressionTree originalTree) {
     35    private static readonly Addition addSymbol = new Addition();
     36    private static readonly Multiplication mulSymbol = new Multiplication();
     37    private static readonly Division divSymbol = new Division();
     38    private static readonly Constant constSymbol = new Constant();
     39    private static readonly Logarithm logSymbol = new Logarithm();
     40    private static readonly Exponential expSymbol = new Exponential();
     41    private static readonly Root rootSymbol = new Root();
     42    private static readonly Square sqrSymbol = new Square();
     43    private static readonly SquareRoot sqrtSymbol = new SquareRoot();
     44    private static readonly Power powSymbol = new Power();
     45    private static readonly Sine sineSymbol = new Sine();
     46    private static readonly Cosine cosineSymbol = new Cosine();
     47    private static readonly Tangent tanSymbol = new Tangent();
     48    private static readonly IfThenElse ifThenElseSymbol = new IfThenElse();
     49    private static readonly And andSymbol = new And();
     50    private static readonly Or orSymbol = new Or();
     51    private static readonly Not notSymbol = new Not();
     52    private static readonly GreaterThan gtSymbol = new GreaterThan();
     53    private static readonly LessThan ltSymbol = new LessThan();
     54    private static readonly Integral integralSymbol = new Integral();
     55    private static readonly LaggedVariable laggedVariableSymbol = new LaggedVariable();
     56    private static readonly TimeLag timeLagSymbol = new TimeLag();
     57
     58    [Obsolete("Use static method TreeSimplifier.Simplify instead")]
     59    public TreeSimplifier() { }
     60
     61    public static ISymbolicExpressionTree Simplify(ISymbolicExpressionTree originalTree) {
    6062      var clone = (ISymbolicExpressionTreeNode)originalTree.Root.Clone();
    6163      // macro expand (initially no argument trees)
     
    6769      // check that each node is only referenced once
    6870      var nodes = rootNode.IterateNodesPrefix().ToArray();
    69       foreach(var n in nodes) if(nodes.Count(ni => ni == n) > 1) throw new InvalidOperationException();
     71      foreach (var n in nodes) if (nodes.Count(ni => ni == n) > 1) throw new InvalidOperationException();
    7072#endif
    7173      return new SymbolicExpressionTree(rootNode);
     
    7375
    7476    // the argumentTrees list contains already expanded trees used as arguments for invocations
    75     private ISymbolicExpressionTreeNode MacroExpand(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode node,
     77    private static ISymbolicExpressionTreeNode MacroExpand(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode node,
    7678      IList<ISymbolicExpressionTreeNode> argumentTrees) {
    7779      List<ISymbolicExpressionTreeNode> subtrees = new List<ISymbolicExpressionTreeNode>(node.Subtrees);
     
    98100    }
    99101
    100     private ISymbolicExpressionTreeNode FindFunctionDefinition(ISymbolicExpressionTreeNode root, string functionName) {
     102    private static ISymbolicExpressionTreeNode FindFunctionDefinition(ISymbolicExpressionTreeNode root, string functionName) {
    101103      foreach (var subtree in root.Subtrees.OfType<DefunTreeNode>()) {
    102104        if (subtree.FunctionName == functionName) return subtree.GetSubtree(0);
     
    109111
    110112    // arithmetic
    111     private bool IsDivision(ISymbolicExpressionTreeNode node) {
     113    private static bool IsDivision(ISymbolicExpressionTreeNode node) {
    112114      return node.Symbol is Division;
    113115    }
    114116
    115     private bool IsMultiplication(ISymbolicExpressionTreeNode node) {
     117    private static bool IsMultiplication(ISymbolicExpressionTreeNode node) {
    116118      return node.Symbol is Multiplication;
    117119    }
    118120
    119     private bool IsSubtraction(ISymbolicExpressionTreeNode node) {
     121    private static bool IsSubtraction(ISymbolicExpressionTreeNode node) {
    120122      return node.Symbol is Subtraction;
    121123    }
    122124
    123     private bool IsAddition(ISymbolicExpressionTreeNode node) {
     125    private static bool IsAddition(ISymbolicExpressionTreeNode node) {
    124126      return node.Symbol is Addition;
    125127    }
    126128
    127     private bool IsAverage(ISymbolicExpressionTreeNode node) {
     129    private static bool IsAverage(ISymbolicExpressionTreeNode node) {
    128130      return node.Symbol is Average;
    129131    }
    130132
    131133    // exponential
    132     private bool IsLog(ISymbolicExpressionTreeNode node) {
     134    private static bool IsLog(ISymbolicExpressionTreeNode node) {
    133135      return node.Symbol is Logarithm;
    134136    }
    135137
    136     private bool IsExp(ISymbolicExpressionTreeNode node) {
     138    private static bool IsExp(ISymbolicExpressionTreeNode node) {
    137139      return node.Symbol is Exponential;
    138140    }
    139141
    140     private bool IsRoot(ISymbolicExpressionTreeNode node) {
     142    private static bool IsRoot(ISymbolicExpressionTreeNode node) {
    141143      return node.Symbol is Root;
    142144    }
    143145
    144     private bool IsSquare(ISymbolicExpressionTreeNode node) {
     146    private static bool IsSquare(ISymbolicExpressionTreeNode node) {
    145147      return node.Symbol is Square;
    146148    }
    147149
    148     private bool IsSquareRoot(ISymbolicExpressionTreeNode node) {
     150    private static bool IsSquareRoot(ISymbolicExpressionTreeNode node) {
    149151      return node.Symbol is SquareRoot;
    150152    }
    151153
    152     private bool IsPower(ISymbolicExpressionTreeNode node) {
     154    private static bool IsPower(ISymbolicExpressionTreeNode node) {
    153155      return node.Symbol is Power;
    154156    }
    155157
    156158    // trigonometric
    157     private bool IsSine(ISymbolicExpressionTreeNode node) {
     159    private static bool IsSine(ISymbolicExpressionTreeNode node) {
    158160      return node.Symbol is Sine;
    159161    }
    160162
    161     private bool IsCosine(ISymbolicExpressionTreeNode node) {
     163    private static bool IsCosine(ISymbolicExpressionTreeNode node) {
    162164      return node.Symbol is Cosine;
    163165    }
    164166
    165     private bool IsTangent(ISymbolicExpressionTreeNode node) {
     167    private static bool IsTangent(ISymbolicExpressionTreeNode node) {
    166168      return node.Symbol is Tangent;
    167169    }
    168170
    169171    // boolean
    170     private bool IsIfThenElse(ISymbolicExpressionTreeNode node) {
     172    private static bool IsIfThenElse(ISymbolicExpressionTreeNode node) {
    171173      return node.Symbol is IfThenElse;
    172174    }
    173175
    174     private bool IsAnd(ISymbolicExpressionTreeNode node) {
     176    private static bool IsAnd(ISymbolicExpressionTreeNode node) {
    175177      return node.Symbol is And;
    176178    }
    177179
    178     private bool IsOr(ISymbolicExpressionTreeNode node) {
     180    private static bool IsOr(ISymbolicExpressionTreeNode node) {
    179181      return node.Symbol is Or;
    180182    }
    181183
    182     private bool IsNot(ISymbolicExpressionTreeNode node) {
     184    private static bool IsNot(ISymbolicExpressionTreeNode node) {
    183185      return node.Symbol is Not;
    184186    }
    185187
    186188    // comparison
    187     private bool IsGreaterThan(ISymbolicExpressionTreeNode node) {
     189    private static bool IsGreaterThan(ISymbolicExpressionTreeNode node) {
    188190      return node.Symbol is GreaterThan;
    189191    }
    190192
    191     private bool IsLessThan(ISymbolicExpressionTreeNode node) {
     193    private static bool IsLessThan(ISymbolicExpressionTreeNode node) {
    192194      return node.Symbol is LessThan;
    193195    }
    194196
    195     private bool IsBoolean(ISymbolicExpressionTreeNode node) {
     197    private static bool IsBoolean(ISymbolicExpressionTreeNode node) {
    196198      return
    197199        node.Symbol is GreaterThan ||
     
    202204
    203205    // terminals
    204     private bool IsVariable(ISymbolicExpressionTreeNode node) {
     206    private static bool IsVariable(ISymbolicExpressionTreeNode node) {
    205207      return node.Symbol is Variable;
    206208    }
    207209
    208     private bool IsVariableBase(ISymbolicExpressionTreeNode node) {
     210    private static bool IsVariableBase(ISymbolicExpressionTreeNode node) {
    209211      return node is VariableTreeNodeBase;
    210212    }
    211213
    212     private bool IsFactor(ISymbolicExpressionTreeNode node) {
     214    private static bool IsFactor(ISymbolicExpressionTreeNode node) {
    213215      return node is FactorVariableTreeNode;
    214216    }
    215217
    216     private bool IsBinFactor(ISymbolicExpressionTreeNode node) {
     218    private static bool IsBinFactor(ISymbolicExpressionTreeNode node) {
    217219      return node is BinaryFactorVariableTreeNode;
    218220    }
    219221
    220     private bool IsConstant(ISymbolicExpressionTreeNode node) {
     222    private static bool IsConstant(ISymbolicExpressionTreeNode node) {
    221223      return node.Symbol is Constant;
    222224    }
    223225
    224226    // dynamic
    225     private bool IsTimeLag(ISymbolicExpressionTreeNode node) {
     227    private static bool IsTimeLag(ISymbolicExpressionTreeNode node) {
    226228      return node.Symbol is TimeLag;
    227229    }
    228230
    229     private bool IsIntegral(ISymbolicExpressionTreeNode node) {
     231    private static bool IsIntegral(ISymbolicExpressionTreeNode node) {
    230232      return node.Symbol is Integral;
    231233    }
     
    238240    /// <param name="original"></param>
    239241    /// <returns></returns>
    240     public ISymbolicExpressionTreeNode GetSimplifiedTree(ISymbolicExpressionTreeNode original) {
     242    public static ISymbolicExpressionTreeNode GetSimplifiedTree(ISymbolicExpressionTreeNode original) {
    241243      if (IsConstant(original) || IsVariableBase(original)) {
    242244        return (ISymbolicExpressionTreeNode)original.Clone();
     
    292294    #region specific simplification routines
    293295
    294     private ISymbolicExpressionTreeNode SimplifyAny(ISymbolicExpressionTreeNode original) {
     296    private static ISymbolicExpressionTreeNode SimplifyAny(ISymbolicExpressionTreeNode original) {
    295297      // can't simplify this function but simplify all subtrees
    296298      List<ISymbolicExpressionTreeNode> subtrees = new List<ISymbolicExpressionTreeNode>(original.Subtrees);
     
    311313    }
    312314
    313     private ISymbolicExpressionTreeNode SimplifyConstantExpression(ISymbolicExpressionTreeNode original) {
     315    private static ISymbolicExpressionTreeNode SimplifyConstantExpression(ISymbolicExpressionTreeNode original) {
    314316      // not yet implemented
    315317      return original;
    316318    }
    317319
    318     private ISymbolicExpressionTreeNode SimplifyAverage(ISymbolicExpressionTreeNode original) {
     320    private static ISymbolicExpressionTreeNode SimplifyAverage(ISymbolicExpressionTreeNode original) {
    319321      if (original.Subtrees.Count() == 1) {
    320322        return GetSimplifiedTree(original.GetSubtree(0));
     
    329331    }
    330332
    331     private ISymbolicExpressionTreeNode SimplifyDivision(ISymbolicExpressionTreeNode original) {
     333    private static ISymbolicExpressionTreeNode SimplifyDivision(ISymbolicExpressionTreeNode original) {
    332334      if (original.Subtrees.Count() == 1) {
    333335        return Invert(GetSimplifiedTree(original.GetSubtree(0)));
     
    344346    }
    345347
    346     private ISymbolicExpressionTreeNode SimplifyMultiplication(ISymbolicExpressionTreeNode original) {
     348    private static ISymbolicExpressionTreeNode SimplifyMultiplication(ISymbolicExpressionTreeNode original) {
    347349      if (original.Subtrees.Count() == 1) {
    348350        return GetSimplifiedTree(original.GetSubtree(0));
     
    354356    }
    355357
    356     private ISymbolicExpressionTreeNode SimplifySubtraction(ISymbolicExpressionTreeNode original) {
     358    private static ISymbolicExpressionTreeNode SimplifySubtraction(ISymbolicExpressionTreeNode original) {
    357359      if (original.Subtrees.Count() == 1) {
    358360        return Negate(GetSimplifiedTree(original.GetSubtree(0)));
     
    366368    }
    367369
    368     private ISymbolicExpressionTreeNode SimplifyAddition(ISymbolicExpressionTreeNode original) {
     370    private static ISymbolicExpressionTreeNode SimplifyAddition(ISymbolicExpressionTreeNode original) {
    369371      if (original.Subtrees.Count() == 1) {
    370372        return GetSimplifiedTree(original.GetSubtree(0));
     
    378380    }
    379381
    380     private ISymbolicExpressionTreeNode SimplifyNot(ISymbolicExpressionTreeNode original) {
     382    private static ISymbolicExpressionTreeNode SimplifyNot(ISymbolicExpressionTreeNode original) {
    381383      return MakeNot(GetSimplifiedTree(original.GetSubtree(0)));
    382384    }
    383385
    384     private ISymbolicExpressionTreeNode SimplifyOr(ISymbolicExpressionTreeNode original) {
     386    private static ISymbolicExpressionTreeNode SimplifyOr(ISymbolicExpressionTreeNode original) {
    385387      return original.Subtrees
    386388        .Select(GetSimplifiedTree)
     
    388390    }
    389391
    390     private ISymbolicExpressionTreeNode SimplifyAnd(ISymbolicExpressionTreeNode original) {
     392    private static ISymbolicExpressionTreeNode SimplifyAnd(ISymbolicExpressionTreeNode original) {
    391393      return original.Subtrees
    392394        .Select(GetSimplifiedTree)
     
    394396    }
    395397
    396     private ISymbolicExpressionTreeNode SimplifyLessThan(ISymbolicExpressionTreeNode original) {
     398    private static ISymbolicExpressionTreeNode SimplifyLessThan(ISymbolicExpressionTreeNode original) {
    397399      return MakeLessThan(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
    398400    }
    399401
    400     private ISymbolicExpressionTreeNode SimplifyGreaterThan(ISymbolicExpressionTreeNode original) {
     402    private static ISymbolicExpressionTreeNode SimplifyGreaterThan(ISymbolicExpressionTreeNode original) {
    401403      return MakeGreaterThan(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
    402404    }
    403405
    404     private ISymbolicExpressionTreeNode SimplifyIfThenElse(ISymbolicExpressionTreeNode original) {
     406    private static ISymbolicExpressionTreeNode SimplifyIfThenElse(ISymbolicExpressionTreeNode original) {
    405407      return MakeIfThenElse(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)),
    406408        GetSimplifiedTree(original.GetSubtree(2)));
    407409    }
    408410
    409     private ISymbolicExpressionTreeNode SimplifyTangent(ISymbolicExpressionTreeNode original) {
     411    private static ISymbolicExpressionTreeNode SimplifyTangent(ISymbolicExpressionTreeNode original) {
    410412      return MakeTangent(GetSimplifiedTree(original.GetSubtree(0)));
    411413    }
    412414
    413     private ISymbolicExpressionTreeNode SimplifyCosine(ISymbolicExpressionTreeNode original) {
     415    private static ISymbolicExpressionTreeNode SimplifyCosine(ISymbolicExpressionTreeNode original) {
    414416      return MakeCosine(GetSimplifiedTree(original.GetSubtree(0)));
    415417    }
    416418
    417     private ISymbolicExpressionTreeNode SimplifySine(ISymbolicExpressionTreeNode original) {
     419    private static ISymbolicExpressionTreeNode SimplifySine(ISymbolicExpressionTreeNode original) {
    418420      return MakeSine(GetSimplifiedTree(original.GetSubtree(0)));
    419421    }
    420422
    421     private ISymbolicExpressionTreeNode SimplifyExp(ISymbolicExpressionTreeNode original) {
     423    private static ISymbolicExpressionTreeNode SimplifyExp(ISymbolicExpressionTreeNode original) {
    422424      return MakeExp(GetSimplifiedTree(original.GetSubtree(0)));
    423425    }
    424426
    425     private ISymbolicExpressionTreeNode SimplifySquare(ISymbolicExpressionTreeNode original) {
     427    private static ISymbolicExpressionTreeNode SimplifySquare(ISymbolicExpressionTreeNode original) {
    426428      return MakeSquare(GetSimplifiedTree(original.GetSubtree(0)));
    427429    }
    428430
    429     private ISymbolicExpressionTreeNode SimplifySquareRoot(ISymbolicExpressionTreeNode original) {
     431    private static ISymbolicExpressionTreeNode SimplifySquareRoot(ISymbolicExpressionTreeNode original) {
    430432      return MakeSquareRoot(GetSimplifiedTree(original.GetSubtree(0)));
    431433    }
    432434
    433     private ISymbolicExpressionTreeNode SimplifyLog(ISymbolicExpressionTreeNode original) {
     435    private static ISymbolicExpressionTreeNode SimplifyLog(ISymbolicExpressionTreeNode original) {
    434436      return MakeLog(GetSimplifiedTree(original.GetSubtree(0)));
    435437    }
    436438
    437     private ISymbolicExpressionTreeNode SimplifyRoot(ISymbolicExpressionTreeNode original) {
     439    private static ISymbolicExpressionTreeNode SimplifyRoot(ISymbolicExpressionTreeNode original) {
    438440      return MakeRoot(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
    439441    }
    440442
    441     private ISymbolicExpressionTreeNode SimplifyPower(ISymbolicExpressionTreeNode original) {
     443    private static ISymbolicExpressionTreeNode SimplifyPower(ISymbolicExpressionTreeNode original) {
    442444      return MakePower(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
    443445    }
    444446
    445     private ISymbolicExpressionTreeNode SimplifyTimeLag(ISymbolicExpressionTreeNode original) {
     447    private static ISymbolicExpressionTreeNode SimplifyTimeLag(ISymbolicExpressionTreeNode original) {
    446448      var laggedTreeNode = original as ILaggedTreeNode;
    447449      var simplifiedSubtree = GetSimplifiedTree(original.GetSubtree(0));
     
    453455    }
    454456
    455     private ISymbolicExpressionTreeNode SimplifyIntegral(ISymbolicExpressionTreeNode original) {
     457    private static ISymbolicExpressionTreeNode SimplifyIntegral(ISymbolicExpressionTreeNode original) {
    456458      var laggedTreeNode = original as ILaggedTreeNode;
    457459      var simplifiedSubtree = GetSimplifiedTree(original.GetSubtree(0));
     
    467469    #region low level tree restructuring
    468470
    469     private ISymbolicExpressionTreeNode MakeTimeLag(ISymbolicExpressionTreeNode subtree, int lag) {
     471    private static ISymbolicExpressionTreeNode MakeTimeLag(ISymbolicExpressionTreeNode subtree, int lag) {
    470472      if (lag == 0) return subtree;
    471473      if (IsConstant(subtree)) return subtree;
     
    476478    }
    477479
    478     private ISymbolicExpressionTreeNode MakeIntegral(ISymbolicExpressionTreeNode subtree, int lag) {
     480    private static ISymbolicExpressionTreeNode MakeIntegral(ISymbolicExpressionTreeNode subtree, int lag) {
    479481      if (lag == 0) return subtree;
    480482      else if (lag == -1 || lag == 1) {
     
    488490    }
    489491
    490     private ISymbolicExpressionTreeNode MakeNot(ISymbolicExpressionTreeNode t) {
     492    private static ISymbolicExpressionTreeNode MakeNot(ISymbolicExpressionTreeNode t) {
    491493      if (IsConstant(t)) {
    492494        var constNode = t as ConstantTreeNode;
     
    509511    }
    510512
    511     private ISymbolicExpressionTreeNode MakeOr(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
     513    private static ISymbolicExpressionTreeNode MakeOr(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    512514      if (IsConstant(a) && IsConstant(b)) {
    513515        var constA = a as ConstantTreeNode;
     
    539541    }
    540542
    541     private ISymbolicExpressionTreeNode MakeAnd(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
     543    private static ISymbolicExpressionTreeNode MakeAnd(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    542544      if (IsConstant(a) && IsConstant(b)) {
    543545        var constA = a as ConstantTreeNode;
     
    569571    }
    570572
    571     private ISymbolicExpressionTreeNode MakeLessThan(ISymbolicExpressionTreeNode leftSide,
     573    private static ISymbolicExpressionTreeNode MakeLessThan(ISymbolicExpressionTreeNode leftSide,
    572574      ISymbolicExpressionTreeNode rightSide) {
    573575      if (IsConstant(leftSide) && IsConstant(rightSide)) {
     
    584586    }
    585587
    586     private ISymbolicExpressionTreeNode MakeGreaterThan(ISymbolicExpressionTreeNode leftSide,
     588    private static ISymbolicExpressionTreeNode MakeGreaterThan(ISymbolicExpressionTreeNode leftSide,
    587589      ISymbolicExpressionTreeNode rightSide) {
    588590      if (IsConstant(leftSide) && IsConstant(rightSide)) {
     
    599601    }
    600602
    601     private ISymbolicExpressionTreeNode MakeIfThenElse(ISymbolicExpressionTreeNode condition,
     603    private static ISymbolicExpressionTreeNode MakeIfThenElse(ISymbolicExpressionTreeNode condition,
    602604      ISymbolicExpressionTreeNode trueBranch, ISymbolicExpressionTreeNode falseBranch) {
    603605      if (IsConstant(condition)) {
     
    621623    }
    622624
    623     private ISymbolicExpressionTreeNode MakeSine(ISymbolicExpressionTreeNode node) {
     625    private static ISymbolicExpressionTreeNode MakeSine(ISymbolicExpressionTreeNode node) {
    624626      if (IsConstant(node)) {
    625627        var constT = node as ConstantTreeNode;
     
    638640    }
    639641
    640     private ISymbolicExpressionTreeNode MakeTangent(ISymbolicExpressionTreeNode node) {
     642    private static ISymbolicExpressionTreeNode MakeTangent(ISymbolicExpressionTreeNode node) {
    641643      if (IsConstant(node)) {
    642644        var constT = node as ConstantTreeNode;
     
    655657    }
    656658
    657     private ISymbolicExpressionTreeNode MakeCosine(ISymbolicExpressionTreeNode node) {
     659    private static ISymbolicExpressionTreeNode MakeCosine(ISymbolicExpressionTreeNode node) {
    658660      if (IsConstant(node)) {
    659661        var constT = node as ConstantTreeNode;
     
    674676    }
    675677
    676     private ISymbolicExpressionTreeNode MakeExp(ISymbolicExpressionTreeNode node) {
     678    private static ISymbolicExpressionTreeNode MakeExp(ISymbolicExpressionTreeNode node) {
    677679      if (IsConstant(node)) {
    678680        var constT = node as ConstantTreeNode;
     
    698700      }
    699701    }
    700     private ISymbolicExpressionTreeNode MakeLog(ISymbolicExpressionTreeNode node) {
     702    private static ISymbolicExpressionTreeNode MakeLog(ISymbolicExpressionTreeNode node) {
    701703      if (IsConstant(node)) {
    702704        var constT = node as ConstantTreeNode;
     
    716718    }
    717719
    718     private ISymbolicExpressionTreeNode MakeSquare(ISymbolicExpressionTreeNode node) {
     720    private static ISymbolicExpressionTreeNode MakeSquare(ISymbolicExpressionTreeNode node) {
    719721      if (IsConstant(node)) {
    720722        var constT = node as ConstantTreeNode;
     
    735737    }
    736738
    737     private ISymbolicExpressionTreeNode MakeSquareRoot(ISymbolicExpressionTreeNode node) {
     739    private static ISymbolicExpressionTreeNode MakeSquareRoot(ISymbolicExpressionTreeNode node) {
    738740      if (IsConstant(node)) {
    739741        var constT = node as ConstantTreeNode;
     
    754756    }
    755757
    756     private ISymbolicExpressionTreeNode MakeRoot(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
     758    private static ISymbolicExpressionTreeNode MakeRoot(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    757759      if (IsConstant(a) && IsConstant(b)) {
    758760        var constA = a as ConstantTreeNode;
     
    809811
    810812
    811     private ISymbolicExpressionTreeNode MakePower(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
     813    private static ISymbolicExpressionTreeNode MakePower(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    812814      if (IsConstant(a) && IsConstant(b)) {
    813815        var constA = a as ConstantTreeNode;
     
    864866
    865867    // MakeFraction, MakeProduct and MakeSum take two already simplified trees and create a new simplified tree
    866     private ISymbolicExpressionTreeNode MakeFraction(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
     868    private static ISymbolicExpressionTreeNode MakeFraction(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    867869      if (IsConstant(a) && IsConstant(b)) {
    868870        // fold constants
     
    933935    }
    934936
    935     private ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
     937    private static ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    936938      if (IsConstant(a) && IsConstant(b)) {
    937939        // fold constants
     
    10281030
    10291031    // makes sure variable symbols in sums are combined
    1030     private void MergeVariablesInSum(ISymbolicExpressionTreeNode sum) {
     1032    private static void MergeVariablesInSum(ISymbolicExpressionTreeNode sum) {
    10311033      var subtrees = new List<ISymbolicExpressionTreeNode>(sum.Subtrees);
    10321034      while (sum.Subtrees.Any()) sum.RemoveSubtree(0);
     
    10671069
    10681070    // nodes referencing variables can be grouped if they have
    1069     private string GroupId(IVariableTreeNode node) {
     1071    private static string GroupId(IVariableTreeNode node) {
    10701072      var binaryFactorNode = node as BinaryFactorVariableTreeNode;
    10711073      var factorNode = node as FactorVariableTreeNode;
     
    10861088
    10871089
    1088     private ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
     1090    private static ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    10891091      if (IsConstant(a) && IsConstant(b)) {
    10901092        // fold constants
     
    11671169    #region helper functions
    11681170
    1169     private bool ContainsVariableCondition(ISymbolicExpressionTreeNode node) {
     1171    private static bool ContainsVariableCondition(ISymbolicExpressionTreeNode node) {
    11701172      if (node.Symbol is VariableCondition) return true;
    11711173      foreach (var subtree in node.Subtrees)
     
    11741176    }
    11751177
    1176     private ISymbolicExpressionTreeNode AddLagToDynamicNodes(ISymbolicExpressionTreeNode node, int lag) {
     1178    private static ISymbolicExpressionTreeNode AddLagToDynamicNodes(ISymbolicExpressionTreeNode node, int lag) {
    11771179      var laggedTreeNode = node as ILaggedTreeNode;
    11781180      var variableNode = node as VariableTreeNode;
     
    11961198    }
    11971199
    1198     private bool AreSameTypeAndVariable(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
     1200    private static bool AreSameTypeAndVariable(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    11991201      return GroupId((IVariableTreeNode)a) == GroupId((IVariableTreeNode)b);
    12001202    }
    12011203
    12021204    // helper to combine the constant factors in products and to combine variables (powers of 2, 3...)
    1203     private void MergeVariablesAndConstantsInProduct(ISymbolicExpressionTreeNode prod) {
     1205    private static void MergeVariablesAndConstantsInProduct(ISymbolicExpressionTreeNode prod) {
    12041206      var subtrees = new List<ISymbolicExpressionTreeNode>(prod.Subtrees);
    12051207      while (prod.Subtrees.Any()) prod.RemoveSubtree(0);
     
    12651267    /// <param name="x"></param>
    12661268    /// <returns>-x</returns>
    1267     private ISymbolicExpressionTreeNode Negate(ISymbolicExpressionTreeNode x) {
     1269    private static ISymbolicExpressionTreeNode Negate(ISymbolicExpressionTreeNode x) {
    12681270      if (IsConstant(x)) {
    12691271        ((ConstantTreeNode)x).Value *= -1;
     
    13021304    /// <param name="x"></param>
    13031305    /// <returns></returns>
    1304     private ISymbolicExpressionTreeNode Invert(ISymbolicExpressionTreeNode x) {
     1306    private static ISymbolicExpressionTreeNode Invert(ISymbolicExpressionTreeNode x) {
    13051307      if (IsConstant(x)) {
    13061308        return MakeConstant(1.0 / ((ConstantTreeNode)x).Value);
     
    13161318    }
    13171319
    1318     private ISymbolicExpressionTreeNode MakeConstant(double value) {
     1320    private static ISymbolicExpressionTreeNode MakeConstant(double value) {
    13191321      ConstantTreeNode constantTreeNode = (ConstantTreeNode)(constSymbol.CreateTreeNode());
    13201322      constantTreeNode.Value = value;
     
    13221324    }
    13231325
    1324     private ISymbolicExpressionTreeNode MakeFactor(FactorVariable sy, string variableName, IEnumerable<double> weights) {
     1326    private static ISymbolicExpressionTreeNode MakeFactor(FactorVariable sy, string variableName, IEnumerable<double> weights) {
    13251327      var tree = (FactorVariableTreeNode)sy.CreateTreeNode();
    13261328      tree.VariableName = variableName;
     
    13281330      return tree;
    13291331    }
    1330     private ISymbolicExpressionTreeNode MakeBinFactor(BinaryFactorVariable sy, string variableName, string variableValue, double weight) {
     1332    private static ISymbolicExpressionTreeNode MakeBinFactor(BinaryFactorVariable sy, string variableName, string variableValue, double weight) {
    13311333      var tree = (BinaryFactorVariableTreeNode)sy.CreateTreeNode();
    13321334      tree.VariableName = variableName;
  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs

    r15143 r15145  
    2323using System.Collections.Generic;
    2424using System.Linq;
     25using System.Runtime.Serialization;
    2526using AutoDiff;
    2627using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     
    2930  public class TreeToAutoDiffTermConverter {
    3031    public delegate double ParametricFunction(double[] vars, double[] @params);
     32
    3133    public delegate Tuple<double[], double> ParametricFunctionGradient(double[] vars, double[] @params);
    3234
     
    6264      eval: Math.Atan,
    6365      diff: x => 1 / (1 + x * x));
     66
    6467    private static readonly Func<Term, UnaryFunc> sin = UnaryFunc.Factory(
    6568      eval: Math.Sin,
    6669      diff: Math.Cos);
     70
    6771    private static readonly Func<Term, UnaryFunc> cos = UnaryFunc.Factory(
    68        eval: Math.Cos,
    69        diff: x => -Math.Sin(x));
     72      eval: Math.Cos,
     73      diff: x => -Math.Sin(x));
     74
    7075    private static readonly Func<Term, UnaryFunc> tan = UnaryFunc.Factory(
    7176      eval: Math.Tan,
    7277      diff: x => 1 + Math.Tan(x) * Math.Tan(x));
     78
    7379    private static readonly Func<Term, UnaryFunc> erf = UnaryFunc.Factory(
    7480      eval: alglib.errorfunction,
    7581      diff: x => 2.0 * Math.Exp(-(x * x)) / Math.Sqrt(Math.PI));
     82
    7683    private static readonly Func<Term, UnaryFunc> norm = UnaryFunc.Factory(
    7784      eval: alglib.normaldistribution,
     
    8895      var transformator = new TreeToAutoDiffTermConverter(makeVariableWeightsVariable);
    8996      AutoDiff.Term term;
    90       var success = transformator.TryConvertToAutoDiff(tree.Root.GetSubtree(0), out term);
    91       if (success) {
     97      try {
     98        term = transformator.ConvertToAutoDiff(tree.Root.GetSubtree(0));
    9299        var parameterEntries = transformator.parameters.ToArray(); // guarantee same order for keys and values
    93         var compiledTerm = term.Compile(transformator.variables.ToArray(), parameterEntries.Select(kvp => kvp.Value).ToArray());
     100        var compiledTerm = term.Compile(transformator.variables.ToArray(),
     101          parameterEntries.Select(kvp => kvp.Value).ToArray());
    94102        parameters = new List<DataForVariable>(parameterEntries.Select(kvp => kvp.Key));
    95103        initialConstants = transformator.initialConstants.ToArray();
    96104        func = (vars, @params) => compiledTerm.Evaluate(vars, @params);
    97105        func_grad = (vars, @params) => compiledTerm.Differentiate(vars, @params);
    98       } else {
     106        return true;
     107      } catch (ConversionException) {
    99108        func = null;
    100109        func_grad = null;
     
    102111        initialConstants = null;
    103112      }
    104       return success;
     113      return false;
    105114    }
    106115
    107116    // state for recursive transformation of trees
    108     private readonly List<double> initialConstants;
     117    private readonly
     118    List<double> initialConstants;
    109119    private readonly Dictionary<DataForVariable, AutoDiff.Variable> parameters;
    110120    private readonly List<AutoDiff.Variable> variables;
     
    118128    }
    119129
    120     private bool TryConvertToAutoDiff(ISymbolicExpressionTreeNode node, out AutoDiff.Term term) {
     130    private AutoDiff.Term ConvertToAutoDiff(ISymbolicExpressionTreeNode node) {
    121131      if (node.Symbol is Constant) {
    122132        initialConstants.Add(((ConstantTreeNode)node).Value);
    123133        var var = new AutoDiff.Variable();
    124134        variables.Add(var);
    125         term = var;
    126         return true;
     135        return var;
    127136      }
    128137      if (node.Symbol is Variable || node.Symbol is BinaryFactorVariable) {
     
    137146          var w = new AutoDiff.Variable();
    138147          variables.Add(w);
    139           term = AutoDiff.TermBuilder.Product(w, par);
     148          return AutoDiff.TermBuilder.Product(w, par);
    140149        } else {
    141           term = varNode.Weight * par;
    142         }
    143         return true;
     150          return varNode.Weight * par;
     151        }
    144152      }
    145153      if (node.Symbol is FactorVariable) {
     
    155163          products.Add(AutoDiff.TermBuilder.Product(wVar, par));
    156164        }
    157         term = AutoDiff.TermBuilder.Sum(products);
    158         return true;
     165        return AutoDiff.TermBuilder.Sum(products);
    159166      }
    160167      if (node.Symbol is LaggedVariable) {
     
    166173          var w = new AutoDiff.Variable();
    167174          variables.Add(w);
    168           term = AutoDiff.TermBuilder.Product(w, par);
     175          return AutoDiff.TermBuilder.Product(w, par);
    169176        } else {
    170           term = varNode.Weight * par;
    171         }
    172         return true;
     177          return varNode.Weight * par;
     178        }
    173179      }
    174180      if (node.Symbol is Addition) {
    175181        List<AutoDiff.Term> terms = new List<Term>();
    176182        foreach (var subTree in node.Subtrees) {
    177           AutoDiff.Term t;
    178           if (!TryConvertToAutoDiff(subTree, out t)) {
    179             term = null;
    180             return false;
    181           }
    182           terms.Add(t);
    183         }
    184         term = AutoDiff.TermBuilder.Sum(terms);
    185         return true;
     183          terms.Add(ConvertToAutoDiff(subTree));
     184        }
     185        return AutoDiff.TermBuilder.Sum(terms);
    186186      }
    187187      if (node.Symbol is Subtraction) {
    188188        List<AutoDiff.Term> terms = new List<Term>();
    189189        for (int i = 0; i < node.SubtreeCount; i++) {
    190           AutoDiff.Term t;
    191           if (!TryConvertToAutoDiff(node.GetSubtree(i), out t)) {
    192             term = null;
    193             return false;
    194           }
     190          AutoDiff.Term t = ConvertToAutoDiff(node.GetSubtree(i));
    195191          if (i > 0) t = -t;
    196192          terms.Add(t);
    197193        }
    198         if (terms.Count == 1) term = -terms[0];
    199         else term = AutoDiff.TermBuilder.Sum(terms);
    200         return true;
     194        if (terms.Count == 1) return -terms[0];
     195        else return AutoDiff.TermBuilder.Sum(terms);
    201196      }
    202197      if (node.Symbol is Multiplication) {
    203198        List<AutoDiff.Term> terms = new List<Term>();
    204199        foreach (var subTree in node.Subtrees) {
    205           AutoDiff.Term t;
    206           if (!TryConvertToAutoDiff(subTree, out t)) {
    207             term = null;
    208             return false;
    209           }
    210           terms.Add(t);
    211         }
    212         if (terms.Count == 1) term = terms[0];
    213         else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, b));
    214         return true;
    215 
     200          terms.Add(ConvertToAutoDiff(subTree));
     201        }
     202        if (terms.Count == 1) return terms[0];
     203        else return terms.Aggregate((a, b) => new AutoDiff.Product(a, b));
    216204      }
    217205      if (node.Symbol is Division) {
    218206        List<AutoDiff.Term> terms = new List<Term>();
    219207        foreach (var subTree in node.Subtrees) {
    220           AutoDiff.Term t;
    221           if (!TryConvertToAutoDiff(subTree, out t)) {
    222             term = null;
    223             return false;
    224           }
    225           terms.Add(t);
    226         }
    227         if (terms.Count == 1) term = 1.0 / terms[0];
    228         else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b));
    229         return true;
     208          terms.Add(ConvertToAutoDiff(subTree));
     209        }
     210        if (terms.Count == 1) return 1.0 / terms[0];
     211        else return terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b));
    230212      }
    231213      if (node.Symbol is Logarithm) {
    232         AutoDiff.Term t;
    233         if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) {
    234           term = null;
    235           return false;
    236         } else {
    237           term = AutoDiff.TermBuilder.Log(t);
    238           return true;
    239         }
     214        return AutoDiff.TermBuilder.Log(
     215          ConvertToAutoDiff(node.GetSubtree(0)));
    240216      }
    241217      if (node.Symbol is Exponential) {
    242         AutoDiff.Term t;
    243         if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) {
    244           term = null;
    245           return false;
    246         } else {
    247           term = AutoDiff.TermBuilder.Exp(t);
    248           return true;
    249         }
     218        return AutoDiff.TermBuilder.Exp(
     219          ConvertToAutoDiff(node.GetSubtree(0)));
    250220      }
    251221      if (node.Symbol is Square) {
    252         AutoDiff.Term t;
    253         if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) {
    254           term = null;
    255           return false;
    256         } else {
    257           term = AutoDiff.TermBuilder.Power(t, 2.0);
    258           return true;
    259         }
     222        return AutoDiff.TermBuilder.Power(
     223          ConvertToAutoDiff(node.GetSubtree(0)), 2.0);
    260224      }
    261225      if (node.Symbol is SquareRoot) {
    262         AutoDiff.Term t;
    263         if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) {
    264           term = null;
    265           return false;
    266         } else {
    267           term = AutoDiff.TermBuilder.Power(t, 0.5);
    268           return true;
    269         }
     226        return AutoDiff.TermBuilder.Power(
     227          ConvertToAutoDiff(node.GetSubtree(0)), 0.5);
    270228      }
    271229      if (node.Symbol is Sine) {
    272         AutoDiff.Term t;
    273         if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) {
    274           term = null;
    275           return false;
    276         } else {
    277           term = sin(t);
    278           return true;
    279         }
     230        return sin(
     231          ConvertToAutoDiff(node.GetSubtree(0)));
    280232      }
    281233      if (node.Symbol is Cosine) {
    282         AutoDiff.Term t;
    283         if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) {
    284           term = null;
    285           return false;
    286         } else {
    287           term = cos(t);
    288           return true;
    289         }
     234        return cos(
     235          ConvertToAutoDiff(node.GetSubtree(0)));
    290236      }
    291237      if (node.Symbol is Tangent) {
    292         AutoDiff.Term t;
    293         if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) {
    294           term = null;
    295           return false;
    296         } else {
    297           term = tan(t);
    298           return true;
    299         }
     238        return tan(
     239          ConvertToAutoDiff(node.GetSubtree(0)));
    300240      }
    301241      if (node.Symbol is Erf) {
    302         AutoDiff.Term t;
    303         if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) {
    304           term = null;
    305           return false;
    306         } else {
    307           term = erf(t);
    308           return true;
    309         }
     242        return erf(
     243          ConvertToAutoDiff(node.GetSubtree(0)));
    310244      }
    311245      if (node.Symbol is Norm) {
    312         AutoDiff.Term t;
    313         if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) {
    314           term = null;
    315           return false;
    316         } else {
    317           term = norm(t);
    318           return true;
    319         }
     246        return norm(
     247          ConvertToAutoDiff(node.GetSubtree(0)));
    320248      }
    321249      if (node.Symbol is StartSymbol) {
     
    324252        variables.Add(beta);
    325253        variables.Add(alpha);
    326         AutoDiff.Term branchTerm;
    327         if (TryConvertToAutoDiff(node.GetSubtree(0), out branchTerm)) {
    328           term = branchTerm * alpha + beta;
    329           return true;
    330         } else {
    331           term = null;
    332           return false;
    333         }
    334       }
    335       term = null;
    336       return false;
     254        return ConvertToAutoDiff(node.GetSubtree(0)) * alpha + beta;
     255      }
     256      throw new ConversionException();
    337257    }
    338258
     
    357277        from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
    358278        where
    359         !(n.Symbol is Variable) &&
    360         !(n.Symbol is BinaryFactorVariable) &&
    361         !(n.Symbol is FactorVariable) &&
    362         !(n.Symbol is LaggedVariable) &&
    363         !(n.Symbol is Constant) &&
    364         !(n.Symbol is Addition) &&
    365         !(n.Symbol is Subtraction) &&
    366         !(n.Symbol is Multiplication) &&
    367         !(n.Symbol is Division) &&
    368         !(n.Symbol is Logarithm) &&
    369         !(n.Symbol is Exponential) &&
    370         !(n.Symbol is SquareRoot) &&
    371         !(n.Symbol is Square) &&
    372         !(n.Symbol is Sine) &&
    373         !(n.Symbol is Cosine) &&
    374         !(n.Symbol is Tangent) &&
    375         !(n.Symbol is Erf) &&
    376         !(n.Symbol is Norm) &&
    377         !(n.Symbol is StartSymbol)
     279          !(n.Symbol is Variable) &&
     280          !(n.Symbol is BinaryFactorVariable) &&
     281          !(n.Symbol is FactorVariable) &&
     282          !(n.Symbol is LaggedVariable) &&
     283          !(n.Symbol is Constant) &&
     284          !(n.Symbol is Addition) &&
     285          !(n.Symbol is Subtraction) &&
     286          !(n.Symbol is Multiplication) &&
     287          !(n.Symbol is Division) &&
     288          !(n.Symbol is Logarithm) &&
     289          !(n.Symbol is Exponential) &&
     290          !(n.Symbol is SquareRoot) &&
     291          !(n.Symbol is Square) &&
     292          !(n.Symbol is Sine) &&
     293          !(n.Symbol is Cosine) &&
     294          !(n.Symbol is Tangent) &&
     295          !(n.Symbol is Erf) &&
     296          !(n.Symbol is Norm) &&
     297          !(n.Symbol is StartSymbol)
    378298        select n).Any();
    379299      return !containsUnknownSymbol;
    380300    }
     301    #region exception class
     302    [Serializable]
     303    public class ConversionException : Exception {
     304
     305      public ConversionException() {
     306      }
     307
     308      public ConversionException(string message) : base(message) {
     309      }
     310
     311      public ConversionException(string message, Exception inner) : base(message, inner) {
     312      }
     313
     314      protected ConversionException(
     315        SerializationInfo info,
     316        StreamingContext context) : base(info, context) {
     317      }
     318    }
     319    #endregion
    381320  }
    382321}
Note: See TracChangeset for help on using the changeset viewer.