Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
02/11/20 13:36:02 (5 years ago)
Author:
bburlacu
Message:

#1772: Merge trunk changes and fix all errors and compilation warnings.

Location:
branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic
Files:
4 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic

  • branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/LinearModelToTreeConverter.cs

    r16130 r17434  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    3838      double @const = 0) {
    3939
    40       if (factorCoefficients.Length == 0 && coefficients.Length == 0) throw new ArgumentException();
     40      if (factorCoefficients.Length == 0 && coefficients.Length == 0 && @const==0) throw new ArgumentException();
     41
     42      // Combine both trees
     43      ISymbolicExpressionTreeNode add = (new Addition()).CreateTreeNode();
    4144
    4245      // Create tree for double variables
    43       ISymbolicExpressionTree tree = null;     
    4446      if (coefficients.Length > 0) {
    45         tree = CreateTree(variableNames, new int[variableNames.Length], coefficients, @const);
    46         if (factorCoefficients.Length == 0) return tree;
     47        var varTree = CreateTree(variableNames, new int[variableNames.Length], coefficients);
     48        foreach (var varNode in varTree.IterateNodesPrefix().OfType<VariableTreeNode>())
     49          add.AddSubtree(varNode);
    4750      }
    4851
    4952      // Create tree for string variables
    50       ISymbolicExpressionTree factorTree = null;     
    5153      if (factorCoefficients.Length > 0) {
    52         factorTree = CreateTree(factors, factorCoefficients, @const);
    53         if (tree == null) return factorTree; 
     54        var factorTree = CreateTree(factors, factorCoefficients);
     55        foreach (var binFactorNode in factorTree.IterateNodesPrefix().OfType<BinaryFactorVariableTreeNode>())
     56          add.AddSubtree(binFactorNode);
    5457      }
    5558
    56       // Combine both trees
    57       ISymbolicExpressionTreeNode add = tree.Root.GetSubtree(0).GetSubtree(0);
    58       foreach (var binFactorNode in factorTree.IterateNodesPrefix().OfType<BinaryFactorVariableTreeNode>())
    59         add.InsertSubtree(add.SubtreeCount - 1, binFactorNode);
     59      if (@const!=0.0) {
     60        ConstantTreeNode cNode = (ConstantTreeNode)new Constant().CreateTreeNode();
     61        cNode.Value = @const;
     62        add.AddSubtree(cNode);
     63      }
     64
     65      ISymbolicExpressionTree tree = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
     66      ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();
     67      tree.Root.AddSubtree(startNode);
     68      startNode.AddSubtree(add);
    6069      return tree;
    61 
    62       throw new ArgumentException();
    6370    }
    6471
  • branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs

    r16130 r17434  
    22
    33/* HeuristicLab
    4  * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    55 *
    66 * This file is part of HeuristicLab.
     
    3737    private static readonly Division divSymbol = new Division();
    3838    private static readonly Constant constSymbol = new Constant();
     39    private static readonly Absolute absSymbol = new Absolute();
    3940    private static readonly Logarithm logSymbol = new Logarithm();
    4041    private static readonly Exponential expSymbol = new Exponential();
     
    4243    private static readonly Square sqrSymbol = new Square();
    4344    private static readonly SquareRoot sqrtSymbol = new SquareRoot();
     45    private static readonly AnalyticQuotient aqSymbol = new AnalyticQuotient();
     46    private static readonly Cube cubeSymbol = new Cube();
     47    private static readonly CubeRoot cubeRootSymbol = new CubeRoot();
    4448    private static readonly Power powSymbol = new Power();
    4549    private static readonly Sine sineSymbol = new Sine();
     
    131135    }
    132136
     137    private static bool IsAbsolute(ISymbolicExpressionTreeNode node) {
     138      return node.Symbol is Absolute;
     139    }
     140
    133141    // exponential
    134142    private static bool IsLog(ISymbolicExpressionTreeNode node) {
     
    152160    }
    153161
     162    private static bool IsCube(ISymbolicExpressionTreeNode node) {
     163      return node.Symbol is Cube;
     164    }
     165
     166    private static bool IsCubeRoot(ISymbolicExpressionTreeNode node) {
     167      return node.Symbol is CubeRoot;
     168    }
     169
    154170    private static bool IsPower(ISymbolicExpressionTreeNode node) {
    155171      return node.Symbol is Power;
     
    167183    private static bool IsTangent(ISymbolicExpressionTreeNode node) {
    168184      return node.Symbol is Tangent;
     185    }
     186
     187    private static bool IsAnalyticalQuotient(ISymbolicExpressionTreeNode node) {
     188      return node.Symbol is AnalyticQuotient;
    169189    }
    170190
     
    243263      if (IsConstant(original) || IsVariableBase(original)) {
    244264        return (ISymbolicExpressionTreeNode)original.Clone();
     265      } else if (IsAbsolute(original)) {
     266        return SimplifyAbsolute(original);
    245267      } else if (IsAddition(original)) {
    246268        return SimplifyAddition(original);
     
    261283      } else if (IsSquareRoot(original)) {
    262284        return SimplifySquareRoot(original);
     285      } else if (IsCube(original)) {
     286        return SimplifyCube(original);
     287      } else if (IsCubeRoot(original)) {
     288        return SimplifyCubeRoot(original);
    263289      } else if (IsPower(original)) {
    264290        return SimplifyPower(original);
     
    271297      } else if (IsTangent(original)) {
    272298        return SimplifyTangent(original);
     299      } else if (IsAnalyticalQuotient(original)) {
     300        return SimplifyAnalyticalQuotient(original);
    273301      } else if (IsIfThenElse(original)) {
    274302        return SimplifyIfThenElse(original);
     
    380408    }
    381409
     410    private static ISymbolicExpressionTreeNode SimplifyAbsolute(ISymbolicExpressionTreeNode original) {
     411      return MakeAbs(GetSimplifiedTree(original.GetSubtree(0)));
     412    }
     413
    382414    private static ISymbolicExpressionTreeNode SimplifyNot(ISymbolicExpressionTreeNode original) {
    383415      return MakeNot(GetSimplifiedTree(original.GetSubtree(0)));
     
    432464      return MakeSquareRoot(GetSimplifiedTree(original.GetSubtree(0)));
    433465    }
     466    private static ISymbolicExpressionTreeNode SimplifyCube(ISymbolicExpressionTreeNode original) {
     467      return MakeCube(GetSimplifiedTree(original.GetSubtree(0)));
     468    }
     469
     470    private static ISymbolicExpressionTreeNode SimplifyCubeRoot(ISymbolicExpressionTreeNode original) {
     471      return MakeCubeRoot(GetSimplifiedTree(original.GetSubtree(0)));
     472    }
    434473
    435474    private static ISymbolicExpressionTreeNode SimplifyLog(ISymbolicExpressionTreeNode original) {
     
    443482    private static ISymbolicExpressionTreeNode SimplifyPower(ISymbolicExpressionTreeNode original) {
    444483      return MakePower(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
     484    }
     485
     486    private static ISymbolicExpressionTreeNode SimplifyAnalyticalQuotient(ISymbolicExpressionTreeNode original) {
     487      return MakeAnalyticalQuotient(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
    445488    }
    446489
     
    730773      } else if (IsSquareRoot(node)) {
    731774        return node.GetSubtree(0);
     775      } else if (IsMultiplication(node)) {
     776        // sqr( x * y ) = sqr(x) * sqr(y)
     777        var mulNode = mulSymbol.CreateTreeNode();
     778        foreach (var subtree in node.Subtrees) {
     779          mulNode.AddSubtree(MakeSquare(subtree));
     780        }
     781        return mulNode;
     782      } else if (IsAbsolute(node)) {
     783        return MakeSquare(node.GetSubtree(0)); // sqr(abs(x)) = sqr(x)
     784      } else if (IsExp(node)) {
     785        return MakeExp(MakeProduct(node.GetSubtree(0), MakeConstant(2.0))); // sqr(exp(x)) = exp(2x)
     786      } else if (IsCube(node)) {
     787        return MakePower(node.GetSubtree(0), MakeConstant(6));
    732788      } else {
    733789        var sqrNode = sqrSymbol.CreateTreeNode();
    734790        sqrNode.AddSubtree(node);
    735791        return sqrNode;
     792      }
     793    }
     794
     795    private static ISymbolicExpressionTreeNode MakeCube(ISymbolicExpressionTreeNode node) {
     796      if (IsConstant(node)) {
     797        var constT = node as ConstantTreeNode;
     798        return MakeConstant(constT.Value * constT.Value * constT.Value);
     799      } else if (IsFactor(node)) {
     800        var factNode = node as FactorVariableTreeNode;
     801        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => w * w * w));
     802      } else if (IsBinFactor(node)) {
     803        var binFactor = node as BinaryFactorVariableTreeNode;
     804        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, binFactor.Weight * binFactor.Weight * binFactor.Weight);
     805      } else if (IsCubeRoot(node)) {
     806        return node.GetSubtree(0); // NOTE: not really accurate because cuberoot(x) with negative x is evaluated to NaN and after this simplification we evaluate as x
     807      } else if (IsExp(node)) {
     808        return MakeExp(MakeProduct(node.GetSubtree(0), MakeConstant(3)));
     809      } else if (IsSquare(node)) {
     810        return MakePower(node.GetSubtree(0), MakeConstant(6));
     811      } else {
     812        var cubeNode = cubeSymbol.CreateTreeNode();
     813        cubeNode.AddSubtree(node);
     814        return cubeNode;
     815      }
     816    }
     817
     818    private static ISymbolicExpressionTreeNode MakeAbs(ISymbolicExpressionTreeNode node) {
     819      if (IsConstant(node)) {
     820        var constT = node as ConstantTreeNode;
     821        return MakeConstant(Math.Abs(constT.Value));
     822      } else if (IsFactor(node)) {
     823        var factNode = node as FactorVariableTreeNode;
     824        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Abs(w)));
     825      } else if (IsBinFactor(node)) {
     826        var binFactor = node as BinaryFactorVariableTreeNode;
     827        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Abs(binFactor.Weight));
     828      } else if (IsSquare(node) || IsExp(node) || IsSquareRoot(node) || IsCubeRoot(node)) {
     829        return node; // abs(sqr(x)) = sqr(x), abs(exp(x)) = exp(x) ...
     830      } else if (IsMultiplication(node)) {
     831        var mul = mulSymbol.CreateTreeNode();
     832        foreach (var st in node.Subtrees) {
     833          mul.AddSubtree(MakeAbs(st));
     834        }
     835        return mul;
     836      } else if (IsDivision(node)) {
     837        var div = divSymbol.CreateTreeNode();
     838        foreach (var st in node.Subtrees) {
     839          div.AddSubtree(MakeAbs(st));
     840        }
     841        return div;
     842      } else {
     843        var absNode = absSymbol.CreateTreeNode();
     844        absNode.AddSubtree(node);
     845        return absNode;
     846      }
     847    }
     848
     849    // constant folding only
     850    private static ISymbolicExpressionTreeNode MakeAnalyticalQuotient(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
     851      if (IsConstant(b)) {
     852        var c = b as ConstantTreeNode;
     853        return MakeFraction(a, MakeConstant(Math.Sqrt(1.0 + c.Value * c.Value)));
     854      } else if (IsFactor(b)) {
     855        var factNode = b as FactorVariableTreeNode;
     856        return MakeFraction(a, MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Sqrt(1.0 + w * w))));
     857      } else if (IsBinFactor(b)) {
     858        var binFactor = b as BinaryFactorVariableTreeNode;
     859        return MakeFraction(a, MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(1.0 + binFactor.Weight * binFactor.Weight)));
     860      } else {
     861        var aqNode = aqSymbol.CreateTreeNode();
     862        aqNode.AddSubtree(a);
     863        aqNode.AddSubtree(b);
     864        return aqNode;
    736865      }
    737866    }
     
    748877        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(binFactor.Weight));
    749878      } else if (IsSquare(node)) {
    750         return node.GetSubtree(0);
     879        return node.GetSubtree(0); // NOTE: not really accurate because sqrt(x) with negative x is evaluated to NaN and after this simplification we evaluate as x
    751880      } else {
    752881        var sqrtNode = sqrtSymbol.CreateTreeNode();
    753882        sqrtNode.AddSubtree(node);
    754883        return sqrtNode;
     884      }
     885    }
     886
     887    private static ISymbolicExpressionTreeNode MakeCubeRoot(ISymbolicExpressionTreeNode node) {
     888      if (IsConstant(node)) {
     889        var constT = node as ConstantTreeNode;
     890        return MakeConstant(Math.Pow(constT.Value, 1.0 / 3.0));
     891      } else if (IsFactor(node)) {
     892        var factNode = node as FactorVariableTreeNode;
     893        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(w, 1.0 / 3.0)));
     894      } else if (IsBinFactor(node)) {
     895        var binFactor = node as BinaryFactorVariableTreeNode;
     896        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(Math.Pow(binFactor.Weight, 1.0 / 3.0)));
     897      } else if (IsCube(node)) {
     898        return node.GetSubtree(0);
     899      } else {
     900        var cubeRootNode = cubeRootSymbol.CreateTreeNode();
     901        cubeRootNode.AddSubtree(node);
     902        return cubeRootNode;
    755903      }
    756904    }
     
    9271075        // a / (b1 / b2) => (a * b2) / b1
    9281076        return MakeFraction(MakeProduct(a, b.GetSubtree(1)), b.GetSubtree(0));
     1077      } else if (IsAnalyticalQuotient(a)) {
     1078        return MakeAnalyticalQuotient(a.GetSubtree(0), MakeProduct(a.GetSubtree(1), b));
    9291079      } else {
    9301080        var div = divSymbol.CreateTreeNode();
     
    11211271        // $ * 1.0 => $
    11221272        return a;
     1273      } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(0.0)) {
     1274        return MakeConstant(0);
    11231275      } else if (IsConstant(b) && IsVariableBase(a)) {
    11241276        // multiply constants into variables weights
     
    11531305        MergeVariablesAndConstantsInProduct(a);
    11541306        return a;
     1307      } else if (IsAbsolute(a) && IsAbsolute(b)) {
     1308        return MakeAbs(MakeProduct(a.GetSubtree(0), b.GetSubtree(0)));
     1309      } else if (IsAbsolute(a) && IsConstant(b)) {
     1310        var constNode = b as ConstantTreeNode;
     1311        var posF = Math.Abs(constNode.Value);
     1312        if (constNode.Value > 0) {
     1313          return MakeAbs(MakeProduct(a.GetSubtree(0), MakeConstant(posF)));
     1314        } else {
     1315          var mul = mulSymbol.CreateTreeNode();
     1316          mul.AddSubtree(MakeAbs(MakeProduct(a.GetSubtree(0), MakeConstant(posF))));
     1317          mul.AddSubtree(MakeConstant(-1.0));
     1318          return mul;
     1319        }
     1320      } else if (IsAnalyticalQuotient(a)) {
     1321        return MakeAnalyticalQuotient(MakeProduct(a.GetSubtree(0), b), a.GetSubtree(1));
    11551322      } else {
    11561323        var mul = mulSymbol.CreateTreeNode();
  • branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs

    r16130 r17434  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    7676      eval: Math.Tan,
    7777      diff: x => 1 + Math.Tan(x) * Math.Tan(x));
    78 
     78    private static readonly Func<Term, UnaryFunc> tanh = UnaryFunc.Factory(
     79      eval: Math.Tanh,
     80      diff: x => 1 - Math.Tanh(x) * Math.Tanh(x));
    7981    private static readonly Func<Term, UnaryFunc> erf = UnaryFunc.Factory(
    8082      eval: alglib.errorfunction,
     
    8486      eval: alglib.normaldistribution,
    8587      diff: x => -(Math.Exp(-(x * x)) * Math.Sqrt(Math.Exp(x * x)) * x) / Math.Sqrt(2 * Math.PI));
     88
     89    private static readonly Func<Term, UnaryFunc> abs = UnaryFunc.Factory(
     90      eval: Math.Abs,
     91      diff: x => Math.Sign(x)
     92      );
     93
     94    private static readonly Func<Term, UnaryFunc> cbrt = UnaryFunc.Factory(
     95      eval: x => x < 0 ? -Math.Pow(-x, 1.0 / 3) : Math.Pow(x, 1.0 / 3),
     96      diff: x => { var cbrt_x = x < 0 ? -Math.Pow(-x, 1.0 / 3) : Math.Pow(x, 1.0 / 3); return 1.0 / (3 * cbrt_x * cbrt_x); }
     97      );
     98
     99
    86100
    87101    #endregion
     
    213227        else return terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b));
    214228      }
     229      if (node.Symbol is Absolute) {
     230        var x1 = ConvertToAutoDiff(node.GetSubtree(0));
     231        return abs(x1);
     232      }
     233      if (node.Symbol is AnalyticQuotient) {
     234        var x1 = ConvertToAutoDiff(node.GetSubtree(0));
     235        var x2 = ConvertToAutoDiff(node.GetSubtree(1));
     236        return x1 / (TermBuilder.Power(1 + x2 * x2, 0.5));
     237      }
    215238      if (node.Symbol is Logarithm) {
    216239        return AutoDiff.TermBuilder.Log(
     
    229252          ConvertToAutoDiff(node.GetSubtree(0)), 0.5);
    230253      }
     254      if (node.Symbol is Cube) {
     255        return AutoDiff.TermBuilder.Power(
     256          ConvertToAutoDiff(node.GetSubtree(0)), 3.0);
     257      }
     258      if (node.Symbol is CubeRoot) {
     259        return cbrt(ConvertToAutoDiff(node.GetSubtree(0)));
     260      }
    231261      if (node.Symbol is Sine) {
    232262        return sin(
     
    239269      if (node.Symbol is Tangent) {
    240270        return tan(
     271          ConvertToAutoDiff(node.GetSubtree(0)));
     272      }
     273      if (node.Symbol is HyperbolicTangent) {
     274        return tanh(
    241275          ConvertToAutoDiff(node.GetSubtree(0)));
    242276      }
     
    299333          !(n.Symbol is Cosine) &&
    300334          !(n.Symbol is Tangent) &&
     335          !(n.Symbol is HyperbolicTangent) &&
    301336          !(n.Symbol is Erf) &&
    302337          !(n.Symbol is Norm) &&
    303           !(n.Symbol is StartSymbol)
     338          !(n.Symbol is StartSymbol) &&
     339          !(n.Symbol is Absolute) &&
     340          !(n.Symbol is AnalyticQuotient) &&
     341          !(n.Symbol is Cube) &&
     342          !(n.Symbol is CubeRoot)
    304343        select n).Any();
    305344      return !containsUnknownSymbol;
Note: See TracChangeset for help on using the changeset viewer.