Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
12/11/21 12:26:27 (2 years ago)
Author:
chaider
Message:

#3140

  • Refactored ConstantOptimization ==> ParameterOptimization
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3140_NumberSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs

    r17963 r18113  
    3636    private static readonly Multiplication mulSymbol = new Multiplication();
    3737    private static readonly Division divSymbol = new Division();
     38    private static readonly Number numberSymbol = new Number();
    3839    private static readonly Constant constSymbol = new Constant();
    3940    private static readonly Absolute absSymbol = new Absolute();
     
    240241    }
    241242
     243    private static bool IsNumber(ISymbolicExpressionTreeNode node) {
     244      return node.Symbol is Number;
     245    }
     246
    242247    private static bool IsConstant(ISymbolicExpressionTreeNode node) {
    243248      return node.Symbol is Constant;
    244249    }
    245 
    246250    // dynamic
    247251    private static bool IsTimeLag(ISymbolicExpressionTreeNode node) {
     
    261265    /// <returns></returns>
    262266    public static ISymbolicExpressionTreeNode GetSimplifiedTree(ISymbolicExpressionTreeNode original) {
    263       if (IsConstant(original) || IsVariableBase(original)) {
     267      if (IsNumber(original) || IsConstant(original) || IsVariableBase(original)) {
    264268        return (ISymbolicExpressionTreeNode)original.Clone();
    265269      } else if (IsAbsolute(original)) {
     
    335339        clone.AddSubtree(simplifiedSubtree);
    336340      }
    337       if (simplifiedSubtrees.TrueForAll(t => IsConstant(t))) {
     341      if (simplifiedSubtrees.TrueForAll(IsNumber)) {
    338342        SimplifyConstantExpression(clone);
    339343      }
     
    501505      var laggedTreeNode = original as ILaggedTreeNode;
    502506      var simplifiedSubtree = GetSimplifiedTree(original.GetSubtree(0));
    503       if (IsConstant(simplifiedSubtree)) {
     507      if (IsNumber(simplifiedSubtree)) {
    504508        return GetSimplifiedTree(MakeProduct(simplifiedSubtree, MakeConstant(-laggedTreeNode.Lag)));
    505509      } else {
     
    514518    private static ISymbolicExpressionTreeNode MakeTimeLag(ISymbolicExpressionTreeNode subtree, int lag) {
    515519      if (lag == 0) return subtree;
    516       if (IsConstant(subtree)) return subtree;
     520      if (IsNumber(subtree)) return subtree;
    517521      var lagNode = (LaggedTreeNode)timeLagSymbol.CreateTreeNode();
    518522      lagNode.Lag = lag;
     
    534538
    535539    private static ISymbolicExpressionTreeNode MakeNot(ISymbolicExpressionTreeNode t) {
    536       if (IsConstant(t)) {
    537         var constNode = t as ConstantTreeNode;
     540      if (IsNumber(t)) {
     541        var constNode = t as NumberTreeNode;
    538542        if (constNode.Value > 0) return MakeConstant(-1.0);
    539543        else return MakeConstant(1.0);
     
    555559
    556560    private static ISymbolicExpressionTreeNode MakeOr(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    557       if (IsConstant(a) && IsConstant(b)) {
    558         var constA = a as ConstantTreeNode;
    559         var constB = b as ConstantTreeNode;
     561      if (IsNumber(a) && IsNumber(b)) {
     562        var constA = a as NumberTreeNode;
     563        var constB = b as NumberTreeNode;
    560564        if (constA.Value > 0.0 || constB.Value > 0.0) {
    561565          return MakeConstant(1.0);
     
    563567          return MakeConstant(-1.0);
    564568        }
    565       } else if (IsConstant(a)) {
     569      } else if (IsNumber(a)) {
    566570        return MakeOr(b, a);
    567       } else if (IsConstant(b)) {
    568         var constT = b as ConstantTreeNode;
     571      } else if (IsNumber(b)) {
     572        var constT = b as NumberTreeNode;
    569573        if (constT.Value > 0.0) {
    570574          // boolean expression is necessarily true
     
    585589
    586590    private static ISymbolicExpressionTreeNode MakeAnd(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    587       if (IsConstant(a) && IsConstant(b)) {
    588         var constA = a as ConstantTreeNode;
    589         var constB = b as ConstantTreeNode;
     591      if (IsNumber(a) && IsNumber(b)) {
     592        var constA = a as NumberTreeNode;
     593        var constB = b as NumberTreeNode;
    590594        if (constA.Value > 0.0 && constB.Value > 0.0) {
    591595          return MakeConstant(1.0);
     
    593597          return MakeConstant(-1.0);
    594598        }
    595       } else if (IsConstant(a)) {
     599      } else if (IsNumber(a)) {
    596600        return MakeAnd(b, a);
    597       } else if (IsConstant(b)) {
    598         var constB = b as ConstantTreeNode;
     601      } else if (IsNumber(b)) {
     602        var constB = b as NumberTreeNode;
    599603        if (constB.Value > 0.0) {
    600604          // the constant value has no effect on the result of the boolean condition so we can drop the constant term
     
    616620    private static ISymbolicExpressionTreeNode MakeLessThan(ISymbolicExpressionTreeNode leftSide,
    617621      ISymbolicExpressionTreeNode rightSide) {
    618       if (IsConstant(leftSide) && IsConstant(rightSide)) {
    619         var lsConst = leftSide as ConstantTreeNode;
    620         var rsConst = rightSide as ConstantTreeNode;
     622      if (IsNumber(leftSide) && IsNumber(rightSide)) {
     623        var lsConst = leftSide as NumberTreeNode;
     624        var rsConst = rightSide as NumberTreeNode;
    621625        if (lsConst.Value < rsConst.Value) return MakeConstant(1.0);
    622626        else return MakeConstant(-1.0);
     
    631635    private static ISymbolicExpressionTreeNode MakeGreaterThan(ISymbolicExpressionTreeNode leftSide,
    632636      ISymbolicExpressionTreeNode rightSide) {
    633       if (IsConstant(leftSide) && IsConstant(rightSide)) {
    634         var lsConst = leftSide as ConstantTreeNode;
    635         var rsConst = rightSide as ConstantTreeNode;
     637      if (IsNumber(leftSide) && IsNumber(rightSide)) {
     638        var lsConst = leftSide as NumberTreeNode;
     639        var rsConst = rightSide as NumberTreeNode;
    636640        if (lsConst.Value > rsConst.Value) return MakeConstant(1.0);
    637641        else return MakeConstant(-1.0);
     
    646650    private static ISymbolicExpressionTreeNode MakeIfThenElse(ISymbolicExpressionTreeNode condition,
    647651      ISymbolicExpressionTreeNode trueBranch, ISymbolicExpressionTreeNode falseBranch) {
    648       if (IsConstant(condition)) {
    649         var constT = condition as ConstantTreeNode;
     652      if (IsNumber(condition)) {
     653        var constT = condition as NumberTreeNode;
    650654        if (constT.Value > 0.0) return trueBranch;
    651655        else return falseBranch;
     
    667671
    668672    private static ISymbolicExpressionTreeNode MakeSine(ISymbolicExpressionTreeNode node) {
    669       if (IsConstant(node)) {
    670         var constT = node as ConstantTreeNode;
     673      if (IsNumber(node)) {
     674        var constT = node as NumberTreeNode;
    671675        return MakeConstant(Math.Sin(constT.Value));
    672676      } else if (IsFactor(node)) {
     
    684688
    685689    private static ISymbolicExpressionTreeNode MakeTangent(ISymbolicExpressionTreeNode node) {
    686       if (IsConstant(node)) {
    687         var constT = node as ConstantTreeNode;
     690      if (IsNumber(node)) {
     691        var constT = node as NumberTreeNode;
    688692        return MakeConstant(Math.Tan(constT.Value));
    689693      } else if (IsFactor(node)) {
     
    701705
    702706    private static ISymbolicExpressionTreeNode MakeCosine(ISymbolicExpressionTreeNode node) {
    703       if (IsConstant(node)) {
    704         var constT = node as ConstantTreeNode;
     707      if (IsNumber(node)) {
     708        var constT = node as NumberTreeNode;
    705709        return MakeConstant(Math.Cos(constT.Value));
    706710      } else if (IsFactor(node)) {
     
    720724
    721725    private static ISymbolicExpressionTreeNode MakeExp(ISymbolicExpressionTreeNode node) {
    722       if (IsConstant(node)) {
    723         var constT = node as ConstantTreeNode;
     726      if (IsNumber(node)) {
     727        var constT = node as NumberTreeNode;
    724728        return MakeConstant(Math.Exp(constT.Value));
    725729      } else if (IsFactor(node)) {
     
    744748    }
    745749    private static ISymbolicExpressionTreeNode MakeLog(ISymbolicExpressionTreeNode node) {
    746       if (IsConstant(node)) {
    747         var constT = node as ConstantTreeNode;
     750      if (IsNumber(node)) {
     751        var constT = node as NumberTreeNode;
    748752        return MakeConstant(Math.Log(constT.Value));
    749753      } else if (IsFactor(node)) {
     
    762766
    763767    private static ISymbolicExpressionTreeNode MakeSquare(ISymbolicExpressionTreeNode node) {
    764       if (IsConstant(node)) {
    765         var constT = node as ConstantTreeNode;
     768      if (IsNumber(node)) {
     769        var constT = node as NumberTreeNode;
    766770        return MakeConstant(constT.Value * constT.Value);
    767771      } else if (IsFactor(node)) {
     
    796800
    797801    private static ISymbolicExpressionTreeNode MakeCube(ISymbolicExpressionTreeNode node) {
    798       if (IsConstant(node)) {
    799         var constT = node as ConstantTreeNode;
     802      if (IsNumber(node)) {
     803        var constT = node as NumberTreeNode;
    800804        return MakeConstant(constT.Value * constT.Value * constT.Value);
    801805      } else if (IsFactor(node)) {
     
    821825
    822826    private static ISymbolicExpressionTreeNode MakeAbs(ISymbolicExpressionTreeNode node) {
    823       if (IsConstant(node)) {
    824         var constT = node as ConstantTreeNode;
     827      if (IsNumber(node)) {
     828        var constT = node as NumberTreeNode;
    825829        return MakeConstant(Math.Abs(constT.Value));
    826830      } else if (IsFactor(node)) {
     
    853857    // constant folding only
    854858    private static ISymbolicExpressionTreeNode MakeAnalyticalQuotient(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    855       if (IsConstant(b)) {
    856         var c = b as ConstantTreeNode;
     859      if (IsNumber(b)) {
     860        var c = b as NumberTreeNode;
    857861        return MakeFraction(a, MakeConstant(Math.Sqrt(1.0 + c.Value * c.Value)));
    858862      } else if (IsFactor(b)) {
     
    871875
    872876    private static ISymbolicExpressionTreeNode MakeSquareRoot(ISymbolicExpressionTreeNode node) {
    873       if (IsConstant(node)) {
    874         var constT = node as ConstantTreeNode;
     877      if (IsNumber(node)) {
     878        var constT = node as NumberTreeNode;
    875879        return MakeConstant(Math.Sqrt(constT.Value));
    876880      } else if (IsFactor(node)) {
     
    890894
    891895    private static ISymbolicExpressionTreeNode MakeCubeRoot(ISymbolicExpressionTreeNode node) {
    892       if (IsConstant(node)) {
    893         var constT = node as ConstantTreeNode;
     896      if (IsNumber(node)) {
     897        var constT = node as NumberTreeNode;
    894898        return MakeConstant(Math.Pow(constT.Value, 1.0 / 3.0));
    895899      } else if (IsFactor(node)) {
     
    909913
    910914    private static ISymbolicExpressionTreeNode MakeRoot(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    911       if (IsConstant(a) && IsConstant(b)) {
    912         var constA = a as ConstantTreeNode;
    913         var constB = b as ConstantTreeNode;
     915      if (IsNumber(a) && IsNumber(b)) {
     916        var constA = a as NumberTreeNode;
     917        var constB = b as NumberTreeNode;
    914918        return MakeConstant(Math.Pow(constA.Value, 1.0 / Math.Round(constB.Value)));
    915       } else if (IsFactor(a) && IsConstant(b)) {
     919      } else if (IsFactor(a) && IsNumber(b)) {
    916920        var factNode = a as FactorVariableTreeNode;
    917         var constNode = b as ConstantTreeNode;
     921        var constNode = b as NumberTreeNode;
    918922        return MakeFactor(factNode.Symbol, factNode.VariableName,
    919923          factNode.Weights.Select(w => Math.Pow(w, 1.0 / Math.Round(constNode.Value))));
    920       } else if (IsBinFactor(a) && IsConstant(b)) {
     924      } else if (IsBinFactor(a) && IsNumber(b)) {
    921925        var binFactor = a as BinaryFactorVariableTreeNode;
    922         var constNode = b as ConstantTreeNode;
     926        var constNode = b as NumberTreeNode;
    923927        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Pow(binFactor.Weight, 1.0 / Math.Round(constNode.Value)));
    924       } else if (IsConstant(a) && IsFactor(b)) {
    925         var constNode = a as ConstantTreeNode;
     928      } else if (IsNumber(a) && IsFactor(b)) {
     929        var constNode = a as NumberTreeNode;
    926930        var factNode = b as FactorVariableTreeNode;
    927931        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(constNode.Value, 1.0 / Math.Round(w))));
    928       } else if (IsConstant(a) && IsBinFactor(b)) {
    929         var constNode = a as ConstantTreeNode;
     932      } else if (IsNumber(a) && IsBinFactor(b)) {
     933        var constNode = a as NumberTreeNode;
    930934        var factNode = b as BinaryFactorVariableTreeNode;
    931935        return MakeBinFactor(factNode.Symbol, factNode.VariableName, factNode.VariableValue, Math.Pow(constNode.Value, 1.0 / Math.Round(factNode.Weight)));
     
    934938        var node1 = b as FactorVariableTreeNode;
    935939        return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Zip(node1.Weights, (u, v) => Math.Pow(u, 1.0 / Math.Round(v))));
    936       } else if (IsConstant(b)) {
    937         var constB = b as ConstantTreeNode;
     940      } else if (IsNumber(b)) {
     941        var constB = b as NumberTreeNode;
    938942        var constBValue = Math.Round(constB.Value);
    939943        if (constBValue == 1.0) {
     
    969973
    970974    private static ISymbolicExpressionTreeNode MakePower(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    971       if (IsConstant(a) && IsConstant(b)) {
    972         var constA = a as ConstantTreeNode;
    973         var constB = b as ConstantTreeNode;
     975      if (IsNumber(a) && IsNumber(b)) {
     976        var constA = a as NumberTreeNode;
     977        var constB = b as NumberTreeNode;
    974978        return MakeConstant(Math.Pow(constA.Value, Math.Round(constB.Value)));
    975       } else if (IsFactor(a) && IsConstant(b)) {
     979      } else if (IsFactor(a) && IsNumber(b)) {
    976980        var factNode = a as FactorVariableTreeNode;
    977         var constNode = b as ConstantTreeNode;
     981        var constNode = b as NumberTreeNode;
    978982        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(w, Math.Round(constNode.Value))));
    979       } else if (IsBinFactor(a) && IsConstant(b)) {
     983      } else if (IsBinFactor(a) && IsNumber(b)) {
    980984        var binFactor = a as BinaryFactorVariableTreeNode;
    981         var constNode = b as ConstantTreeNode;
     985        var constNode = b as NumberTreeNode;
    982986        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Pow(binFactor.Weight, Math.Round(constNode.Value)));
    983       } else if (IsConstant(a) && IsFactor(b)) {
    984         var constNode = a as ConstantTreeNode;
     987      } else if (IsNumber(a) && IsFactor(b)) {
     988        var constNode = a as NumberTreeNode;
    985989        var factNode = b as FactorVariableTreeNode;
    986990        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(constNode.Value, Math.Round(w))));
    987       } else if (IsConstant(a) && IsBinFactor(b)) {
    988         var constNode = a as ConstantTreeNode;
     991      } else if (IsNumber(a) && IsBinFactor(b)) {
     992        var constNode = a as NumberTreeNode;
    989993        var factNode = b as BinaryFactorVariableTreeNode;
    990994        return MakeBinFactor(factNode.Symbol, factNode.VariableName, factNode.VariableValue, Math.Pow(constNode.Value, Math.Round(factNode.Weight)));
     
    993997        var node1 = b as FactorVariableTreeNode;
    994998        return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Zip(node1.Weights, (u, v) => Math.Pow(u, Math.Round(v))));
    995       } else if (IsConstant(b)) {
    996         var constB = b as ConstantTreeNode;
     999      } else if (IsNumber(b)) {
     1000        var constB = b as NumberTreeNode;
    9971001        double exponent = Math.Round(constB.Value);
    9981002        if (exponent == 0.0) {
     
    10281032    // MakeFraction, MakeProduct and MakeSum take two already simplified trees and create a new simplified tree
    10291033    private static ISymbolicExpressionTreeNode MakeFraction(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    1030       if (IsConstant(a) && IsConstant(b)) {
     1034      if (IsNumber(a) && IsNumber(b)) {
    10311035        // fold constants
    1032         return MakeConstant(((ConstantTreeNode)a).Value / ((ConstantTreeNode)b).Value);
    1033       } else if ((IsConstant(a) && ((ConstantTreeNode)a).Value != 1.0)) {
     1036        return MakeConstant(((NumberTreeNode)a).Value / ((NumberTreeNode)b).Value);
     1037      } else if ((IsNumber(a) && ((NumberTreeNode)a).Value != 1.0)) {
    10341038        // a / x => (a * 1/a) / (x * 1/a) => 1 / (x * 1/a)
    10351039        return MakeFraction(MakeConstant(1.0), MakeProduct(b, Invert(a)));
    1036       } else if (IsVariableBase(a) && IsConstant(b)) {
     1040      } else if (IsVariableBase(a) && IsNumber(b)) {
    10371041        // merge constant values into variable weights
    1038         var constB = ((ConstantTreeNode)b).Value;
     1042        var constB = ((NumberTreeNode)b).Value;
    10391043        ((VariableTreeNodeBase)a).Weight /= constB;
    10401044        return a;
    1041       } else if (IsFactor(a) && IsConstant(b)) {
     1045      } else if (IsFactor(a) && IsNumber(b)) {
    10421046        var factNode = a as FactorVariableTreeNode;
    1043         var constNode = b as ConstantTreeNode;
     1047        var constNode = b as NumberTreeNode;
    10441048        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => w / constNode.Value));
    1045       } else if (IsBinFactor(a) && IsConstant(b)) {
     1049      } else if (IsBinFactor(a) && IsNumber(b)) {
    10461050        var factNode = a as BinaryFactorVariableTreeNode;
    1047         var constNode = b as ConstantTreeNode;
     1051        var constNode = b as NumberTreeNode;
    10481052        return MakeBinFactor(factNode.Symbol, factNode.VariableName, factNode.VariableValue, factNode.Weight / constNode.Value);
    10491053      } else if (IsFactor(a) && IsFactor(b) && AreSameTypeAndVariable(a, b)) {
     
    10701074        var bVar = b as VariableTreeNode;
    10711075        return MakeConstant(aVar.Weight / bVar.Weight);
    1072       } else if (IsAddition(a) && IsConstant(b)) {
     1076      } else if (IsAddition(a) && IsNumber(b)) {
    10731077        return a.Subtrees
    10741078          .Select(x => GetSimplifiedTree(x))
    10751079          .Select(x => MakeFraction(x, GetSimplifiedTree(b)))
    10761080          .Aggregate((c, d) => MakeSum(c, d));
    1077       } else if (IsMultiplication(a) && IsConstant(b)) {
     1081      } else if (IsMultiplication(a) && IsNumber(b)) {
    10781082        return MakeProduct(a, Invert(b));
    1079       } else if (IsDivision(a) && IsConstant(b)) {
     1083      } else if (IsDivision(a) && IsNumber(b)) {
    10801084        // (a1 / a2) / c => (a1 / (a2 * c))
    10811085        return MakeFraction(a.GetSubtree(0), MakeProduct(a.GetSubtree(1), b));
     
    11001104
    11011105    private static ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    1102       if (IsConstant(a) && IsConstant(b)) {
     1106      if (IsNumber(a) && IsNumber(b)) {
    11031107        // fold constants
    1104         ((ConstantTreeNode)a).Value += ((ConstantTreeNode)b).Value;
     1108        ((NumberTreeNode)a).Value += ((NumberTreeNode)b).Value;
    11051109        return a;
    1106       } else if (IsConstant(a)) {
     1110      } else if (IsNumber(a)) {
    11071111        // c + x => x + c
    11081112        // b is not constant => make sure constant is on the right
    11091113        return MakeSum(b, a);
    1110       } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 0.0) {
     1114      } else if (IsNumber(b) && ((NumberTreeNode)b).Value == 0.0) {
    11111115        // x + 0 => x
    11121116        return a;
    1113       } else if (IsFactor(a) && IsConstant(b)) {
     1117      } else if (IsFactor(a) && IsNumber(b)) {
    11141118        var factNode = a as FactorVariableTreeNode;
    1115         var constNode = b as ConstantTreeNode;
     1119        var constNode = b as NumberTreeNode;
    11161120        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select((w) => w + constNode.Value));
    11171121      } else if (IsFactor(a) && IsFactor(b) && AreSameTypeAndVariable(a, b)) {
     
    11381142        for (int i = 0; i < a.Subtrees.Count() - 1; i++) add.AddSubtree(a.GetSubtree(i));
    11391143        for (int i = 0; i < b.Subtrees.Count() - 1; i++) add.AddSubtree(b.GetSubtree(i));
    1140         if (IsConstant(a.Subtrees.Last()) && IsConstant(b.Subtrees.Last())) {
     1144        if (IsNumber(a.Subtrees.Last()) && IsNumber(b.Subtrees.Last())) {
    11411145          add.AddSubtree(MakeSum(a.Subtrees.Last(), b.Subtrees.Last()));
    1142         } else if (IsConstant(a.Subtrees.Last())) {
     1146        } else if (IsNumber(a.Subtrees.Last())) {
    11431147          add.AddSubtree(b.Subtrees.Last());
    11441148          add.AddSubtree(a.Subtrees.Last());
     
    11551159      } else if (IsAddition(b)) {
    11561160        return MakeSum(b, a);
    1157       } else if (IsAddition(a) && IsConstant(b)) {
     1161      } else if (IsAddition(a) && IsNumber(b)) {
    11581162        // a is an addition and b is a constant => append b to a and make sure the constants are merged
    11591163        var add = addSymbol.CreateTreeNode();
    11601164        // add all sub trees except for the last
    11611165        for (int i = 0; i < a.Subtrees.Count() - 1; i++) add.AddSubtree(a.GetSubtree(i));
    1162         if (IsConstant(a.Subtrees.Last()))
     1166        if (IsNumber(a.Subtrees.Last()))
    11631167          add.AddSubtree(MakeSum(a.Subtrees.Last(), b));
    11641168        else {
     
    12011205                            group node by GroupId(node) into g
    12021206                            select g;
    1203       var constant = (from node in subtrees.OfType<ConstantTreeNode>()
     1207      var constant = (from node in subtrees.OfType<NumberTreeNode>()
    12041208                      select node.Value).DefaultIfEmpty(0.0).Sum();
    1205       var unchangedSubtrees = subtrees.Where(t => t.SubtreeCount > 0 || !(t is IVariableTreeNode) && !(t is ConstantTreeNode));
     1209      var unchangedSubtrees = subtrees.Where(t => t.SubtreeCount > 0 || !(t is IVariableTreeNode) && !(t is NumberTreeNode));
    12061210
    12071211      foreach (var variableNodeGroup in groupedVarNodes) {
     
    12501254
    12511255    private static ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
    1252       if (IsConstant(a) && IsConstant(b)) {
     1256      if (IsNumber(a) && IsNumber(b)) {
    12531257        // fold constants
    1254         return MakeConstant(((ConstantTreeNode)a).Value * ((ConstantTreeNode)b).Value);
    1255       } else if (IsConstant(a)) {
     1258        return MakeConstant(((NumberTreeNode)a).Value * ((NumberTreeNode)b).Value);
     1259      } else if (IsNumber(a)) {
    12561260        // a * $ => $ * a
    12571261        return MakeProduct(b, a);
     
    12641268        var node1 = b as BinaryFactorVariableTreeNode;
    12651269        return MakeBinFactor(node0.Symbol, node0.VariableName, node0.VariableValue, node0.Weight * node1.Weight);
    1266       } else if (IsFactor(a) && IsConstant(b)) {
     1270      } else if (IsFactor(a) && IsNumber(b)) {
    12671271        var node0 = a as FactorVariableTreeNode;
    1268         var node1 = b as ConstantTreeNode;
     1272        var node1 = b as NumberTreeNode;
    12691273        return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Select(w => w * node1.Value));
    1270       } else if (IsBinFactor(a) && IsConstant(b)) {
     1274      } else if (IsBinFactor(a) && IsNumber(b)) {
    12711275        var node0 = a as BinaryFactorVariableTreeNode;
    1272         var node1 = b as ConstantTreeNode;
     1276        var node1 = b as NumberTreeNode;
    12731277        return MakeBinFactor(node0.Symbol, node0.VariableName, node0.VariableValue, node0.Weight * node1.Value);
    12741278      } else if (IsBinFactor(a) && IsFactor(b)) {
     
    12821286        if (wi < 0) throw new ArgumentException();
    12831287        return MakeBinFactor(node1.Symbol, node1.VariableName, node1.VariableValue, node1.Weight * node0.Weights[wi]);
    1284       } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 1.0) {
     1288      } else if (IsNumber(b) && ((NumberTreeNode)b).Value == 1.0) {
    12851289        // $ * 1.0 => $
    12861290        return a;
    1287       } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 0.0) {
     1291      } else if (IsNumber(b) && ((NumberTreeNode)b).Value == 0.0) {
    12881292        return MakeConstant(0);
    1289       } else if (IsConstant(b) && IsVariableBase(a)) {
     1293      } else if (IsNumber(b) && IsVariableBase(a)) {
    12901294        // multiply constants into variables weights
    1291         ((VariableTreeNodeBase)a).Weight *= ((ConstantTreeNode)b).Value;
     1295        ((VariableTreeNodeBase)a).Weight *= ((NumberTreeNode)b).Value;
    12921296        return a;
    1293       } else if (IsConstant(b) && IsAddition(a) ||
     1297      } else if (IsNumber(b) && IsAddition(a) ||
    12941298          IsFactor(b) && IsAddition(a) ||
    12951299          IsBinFactor(b) && IsAddition(a)) {
     
    13211325      } else if (IsAbsolute(a) && IsAbsolute(b)) {
    13221326        return MakeAbs(MakeProduct(a.GetSubtree(0), b.GetSubtree(0)));
    1323       } else if (IsAbsolute(a) && IsConstant(b)) {
    1324         var constNode = b as ConstantTreeNode;
     1327      } else if (IsAbsolute(a) && IsNumber(b)) {
     1328        var constNode = b as NumberTreeNode;
    13251329        var posF = Math.Abs(constNode.Value);
    13261330        if (constNode.Value > 0) {
     
    13911395      var constantProduct = (from node in subtrees.OfType<VariableTreeNodeBase>()
    13921396                             select node.Weight)
    1393         .Concat(from node in subtrees.OfType<ConstantTreeNode>()
     1397        .Concat(from node in subtrees.OfType<NumberTreeNode>()
    13941398                select node.Value)
    13951399        .DefaultIfEmpty(1.0)
     
    13971401
    13981402      var unchangedSubtrees = from tree in subtrees
    1399                               where tree.SubtreeCount > 0 || !(tree is IVariableTreeNode) && !(tree is ConstantTreeNode)
     1403                              where tree.SubtreeCount > 0 || !(tree is IVariableTreeNode) && !(tree is NumberTreeNode)
    14001404                              select tree;
    14011405
     
    14461450    /// <returns>-x</returns>
    14471451    private static ISymbolicExpressionTreeNode Negate(ISymbolicExpressionTreeNode x) {
    1448       if (IsConstant(x)) {
    1449         ((ConstantTreeNode)x).Value *= -1;
     1452      if (IsNumber(x)) {
     1453        ((NumberTreeNode)x).Value *= -1;
    14501454      } else if (IsVariableBase(x)) {
    14511455        var variableTree = (VariableTreeNodeBase)x;
     
    14831487    /// <returns></returns>
    14841488    private static ISymbolicExpressionTreeNode Invert(ISymbolicExpressionTreeNode x) {
    1485       if (IsConstant(x)) {
    1486         return MakeConstant(1.0 / ((ConstantTreeNode)x).Value);
     1489      if (IsNumber(x)) {
     1490        return MakeConstant(1.0 / ((NumberTreeNode)x).Value);
    14871491      } else if (IsFactor(x)) {
    14881492        var factorNode = (FactorVariableTreeNode)x;
     
    14971501
    14981502    private static ISymbolicExpressionTreeNode MakeConstant(double value) {
    1499       ConstantTreeNode constantTreeNode = (ConstantTreeNode)(constSymbol.CreateTreeNode());
    1500       constantTreeNode.Value = value;
    1501       return constantTreeNode;
     1503      NumberTreeNode numberTreeNode = (NumberTreeNode)(numberSymbol.CreateTreeNode());
     1504      numberTreeNode.Value = value;
     1505      return numberTreeNode;
    15021506    }
    15031507
Note: See TracChangeset for help on using the changeset viewer.