Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/19/21 16:07:45 (3 years ago)
Author:
mkommend
Message:

#2521: Merged trunk changes into branch.

Location:
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4
Files:
15 edited
6 copied

Legend:

Unmodified
Added
Removed
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs

    r17226 r18086  
    149149        return Product(Product(CreateConstant(3.0), Square(f)), Derive(f, variableName));
    150150      }
     151      if (branch.Symbol is Power) {
     152        // HL evaluators handle power strangely (exponent is rounded to an integer)
     153        // here we only support the case when the exponent is a constant integer
     154        var exponent = branch.GetSubtree(1) as ConstantTreeNode;
     155        if (exponent != null && Math.Truncate(exponent.Value) == exponent.Value) {
     156          var newPower = (ISymbolicExpressionTreeNode)branch.Clone();
     157          var f = (ISymbolicExpressionTreeNode)newPower.GetSubtree(0).Clone();
     158          var newExponent = (ConstantTreeNode)newPower.GetSubtree(1);
     159          newExponent.Value -= 1;
     160          return Product(Product(CreateConstant(exponent.Value), newPower), Derive(f, variableName));
     161        } else throw new NotSupportedException("Cannot derive non-integer powers");
     162      }
    151163      if (branch.Symbol is Absolute) {
    152164        var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
     
    263275          !(n.Symbol is Cube) &&
    264276          !(n.Symbol is CubeRoot) &&
     277          !(n.Symbol is Power) &&
    265278          !(n.Symbol is Absolute) &&
    266279          !(n.Symbol is AnalyticQuotient) &&
     280          !(n.Symbol is HyperbolicTangent) &&
    267281          !(n.Symbol is Sine) &&
    268282          !(n.Symbol is Cosine) &&
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs

    r17226 r18086  
    784784      } else if (IsExp(node)) {
    785785        return MakeExp(MakeProduct(node.GetSubtree(0), MakeConstant(2.0))); // sqr(exp(x)) = exp(2x)
     786      } else if (IsSquare(node)) {
     787        return MakePower(node.GetSubtree(0), MakeConstant(4));
    786788      } else if (IsCube(node)) {
    787789        return MakePower(node.GetSubtree(0), MakeConstant(6));
     
    809811      } else if (IsSquare(node)) {
    810812        return MakePower(node.GetSubtree(0), MakeConstant(6));
     813      } else if (IsCube(node)) {
     814        return MakePower(node.GetSubtree(0), MakeConstant(9));
    811815      } else {
    812816        var cubeNode = cubeSymbol.CreateTreeNode();
     
    933937        var constB = b as ConstantTreeNode;
    934938        var constBValue = Math.Round(constB.Value);
    935         if (constBValue.IsAlmost(1.0)) {
     939        if (constBValue == 1.0) {
     940          // root(a, 1) => a
    936941          return a;
    937         } else if (constBValue.IsAlmost(0.0)) {
    938           return MakeConstant(1.0);
    939         } else if (constBValue.IsAlmost(-1.0)) {
     942        } else if (constBValue == 0.0) {
     943          // root(a, 0) is not defined
     944          //return MakeConstant(1.0);
     945          return MakeConstant(double.NaN);
     946        } else if (constBValue == -1.0) {
     947          // root(a, -1) => a^(-1/1) => 1/a
    940948          return MakeFraction(MakeConstant(1.0), a);
    941949        } else if (constBValue < 0) {
     950          // root(a, -b) => a^(-1/b) => (1/a)^(1/b) => root(1, b) / root(a, b) => 1 / root(a, b)
    942951          var rootNode = rootSymbol.CreateTreeNode();
    943952          rootNode.AddSubtree(a);
     
    987996        var constB = b as ConstantTreeNode;
    988997        double exponent = Math.Round(constB.Value);
    989         if (exponent.IsAlmost(0.0)) {
     998        if (exponent == 0.0) {
     999          // a^0 => 1
    9901000          return MakeConstant(1.0);
    991         } else if (exponent.IsAlmost(1.0)) {
     1001        } else if (exponent == 1.0) {
     1002          // a^1 => a
    9921003          return a;
    993         } else if (exponent.IsAlmost(-1.0)) {
     1004        } else if (exponent == -1.0) {
     1005          // a^-1 => 1/a
    9941006          return MakeFraction(MakeConstant(1.0), a);
    9951007        } else if (exponent < 0) {
     1008          // a^-b => (1/a)^b => 1/(a^b)
    9961009          var powNode = powSymbol.CreateTreeNode();
    9971010          powNode.AddSubtree(a);
     
    10181031        // fold constants
    10191032        return MakeConstant(((ConstantTreeNode)a).Value / ((ConstantTreeNode)b).Value);
    1020       } else if ((IsConstant(a) && !((ConstantTreeNode)a).Value.IsAlmost(1.0))) {
     1033      } else if ((IsConstant(a) && ((ConstantTreeNode)a).Value != 1.0)) {
     1034        // a / x => (a * 1/a) / (x * 1/a) => 1 / (x * 1/a)
    10211035        return MakeFraction(MakeConstant(1.0), MakeProduct(b, Invert(a)));
    10221036      } else if (IsVariableBase(a) && IsConstant(b)) {
     
    10941108        // b is not constant => make sure constant is on the right
    10951109        return MakeSum(b, a);
    1096       } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(0.0)) {
     1110      } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 0.0) {
    10971111        // x + 0 => x
    10981112        return a;
     
    12101224      foreach (var unchangedSubtree in unchangedSubtrees)
    12111225        sum.AddSubtree(unchangedSubtree);
    1212       if (!constant.IsAlmost(0.0)) {
     1226      if (constant != 0.0) {
    12131227        sum.AddSubtree(MakeConstant(constant));
    12141228      }
     
    12681282        if (wi < 0) throw new ArgumentException();
    12691283        return MakeBinFactor(node1.Symbol, node1.VariableName, node1.VariableValue, node1.Weight * node0.Weights[wi]);
    1270       } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(1.0)) {
     1284      } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 1.0) {
    12711285        // $ * 1.0 => $
    12721286        return a;
    1273       } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(0.0)) {
     1287      } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 0.0) {
    12741288        return MakeConstant(0);
    12751289      } else if (IsConstant(b) && IsVariableBase(a)) {
     
    14191433        prod.AddSubtree(unchangedSubtree);
    14201434
    1421       if (!constantProduct.IsAlmost(1.0)) {
     1435      if (constantProduct != 1.0) {
    14221436        prod.AddSubtree(MakeConstant(constantProduct));
    14231437      }
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs

    r17226 r18086  
    258258      if (node.Symbol is CubeRoot) {
    259259        return cbrt(ConvertToAutoDiff(node.GetSubtree(0)));
     260      }
     261      if (node.Symbol is Power) {
     262        var powerNode = node.GetSubtree(1) as ConstantTreeNode;
     263        if (powerNode == null)
     264          throw new NotSupportedException("Only integer powers are allowed in parameter optimization. Try to use exp() and log() instead of the power symbol.");
     265        var intPower = Math.Truncate(powerNode.Value);
     266        if (intPower != powerNode.Value)
     267          throw new NotSupportedException("Only integer powers are allowed in parameter optimization. Try to use exp() and log() instead of the power symbol.");
     268        return AutoDiff.TermBuilder.Power(ConvertToAutoDiff(node.GetSubtree(0)), intPower);
    260269      }
    261270      if (node.Symbol is Sine) {
     
    340349          !(n.Symbol is AnalyticQuotient) &&
    341350          !(n.Symbol is Cube) &&
    342           !(n.Symbol is CubeRoot)
     351          !(n.Symbol is CubeRoot) &&
     352          !(n.Symbol is Power)
    343353        select n).Any();
    344354      return !containsUnknownSymbol;
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Creators/MultiSymbolicDataAnalysisExpressionCreator.cs

    r17226 r18086  
    4444    private const string MaximumSymbolicExpressionTreeDepthParameterName = "MaximumSymbolicExpressionTreeDepth";
    4545    private const string SymbolicExpressionTreeGrammarParameterName = "SymbolicExpressionTreeGrammar";
    46     private const string ClonedSymbolicExpressionTreeGrammarParameterName = "ClonedSymbolicExpressionTreeGrammar";
    4746
    4847    public override bool CanChangeName {
     
    6665      get { return (IValueLookupParameter<ISymbolicExpressionGrammar>)Parameters[SymbolicExpressionTreeGrammarParameterName]; }
    6766    }
    68     public ILookupParameter<ISymbolicExpressionGrammar> ClonedSymbolicExpressionTreeGrammarParameter {
    69       get { return (ILookupParameter<ISymbolicExpressionGrammar>)Parameters[ClonedSymbolicExpressionTreeGrammarParameterName]; }
    70     }
    7167    #endregion
    7268
     
    8076      Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeLengthParameterName, "The maximal length (number of nodes) of the symbolic expression tree."));
    8177      Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeDepthParameterName, "The maximal depth of the symbolic expression tree (a tree with one node has depth = 0)."));
    82       Parameters.Add(new ValueLookupParameter<ISymbolicExpressionGrammar>(SymbolicExpressionTreeGrammarParameterName, "The tree grammar that defines the correct syntax of symbolic expression trees that should be created."));
    83       Parameters.Add(new LookupParameter<ISymbolicExpressionGrammar>(ClonedSymbolicExpressionTreeGrammarParameterName, "An immutable clone of the concrete grammar that is actually used to create and manipulate trees."));
     78      Parameters.Add(new ValueLookupParameter<ISymbolicExpressionGrammar>(SymbolicExpressionTreeGrammarParameterName, "The tree grammar that defines the correct syntax of symbolic expression trees that should be created."));     
    8479
    8580      List<ISymbolicDataAnalysisSolutionCreator> list = new List<ISymbolicDataAnalysisSolutionCreator>();
     
    9691    }
    9792
    98     public override IOperation InstrumentedApply() {
    99       if (ClonedSymbolicExpressionTreeGrammarParameter.ActualValue == null) {
    100         SymbolicExpressionTreeGrammarParameter.ActualValue.ReadOnly = true;
    101         IScope globalScope = ExecutionContext.Scope;
    102         while (globalScope.Parent != null)
    103           globalScope = globalScope.Parent;
    104 
    105         globalScope.Variables.Add(new Core.Variable(ClonedSymbolicExpressionTreeGrammarParameterName, (ISymbolicExpressionGrammar)SymbolicExpressionTreeGrammarParameter.ActualValue.Clone()));
    106       }
    107       return base.InstrumentedApply();
    108     }
    10993
    11094    public ISymbolicExpressionTree CreateTree(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeLength, int maxTreeDepth) {
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs

    r17586 r18086  
    3838        // operators
    3939        if (token == "+" || token == "-" || token == "OR" || token == "XOR" ||
    40             token == "*" || token == "/" || token == "AND" ||
    41             token == "^") {
     40            token == "*" || token == "/" || token == "AND") {
    4241          strBuilder.Append("(");
    4342          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants);
     
    4645            strBuilder.Append(" ").Append(token).Append(" ");
    4746            FormatRecursively(subtree, strBuilder, numberFormat, formatString, constants);
     47          }
     48
     49          strBuilder.Append(")");
     50        } else if (token == "^") {
     51          // handle integer powers directly
     52          strBuilder.Append("(");
     53          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants);
     54
     55          var power = node.GetSubtree(1);
     56          if(power is ConstantTreeNode constNode && Math.Truncate(constNode.Value) == constNode.Value) {
     57            strBuilder.Append(" ").Append(token).Append(" ").Append(constNode.Value.ToString(formatString, numberFormat));
     58          } else {
     59            strBuilder.Append(" ").Append(token).Append(" ");
     60            FormatRecursively(power, strBuilder, numberFormat, formatString, constants);
    4861          }
    4962
     
    8396          if (!varNode.Weight.IsAlmost(1.0)) {
    8497            strBuilder.Append("(");
    85             if (constants != null) {
    86               strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Weight);
    87             } else {
    88               strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat));
    89             }
     98            AppendConstant(strBuilder, constants, varNode.Weight, formatString, numberFormat);
    9099            strBuilder.Append("*");
    91100          }
    92101
    93102          strBuilder.Append("LAG(");
    94           if (varNode.VariableName.Contains("'"))
    95             strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
    96           else
    97             strBuilder.AppendFormat("'{0}'", varNode.VariableName);
    98 
     103          AppendVariableName(strBuilder, varNode.VariableName);
    99104          strBuilder.Append(", ")
    100105                    .AppendFormat(numberFormat, "{0}", varNode.Lag)
    101106                    .Append(")");
     107          if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
    102108        } else if (node.Symbol is Variable) {
    103109          var varNode = node as VariableTreeNode;
    104110          if (!varNode.Weight.IsAlmost(1.0)) {
    105111            strBuilder.Append("(");
    106             if (constants != null) {
    107               string constantKey = $"c_{constants.Count}";
    108               strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constantKey);
    109               constants.Add(new KeyValuePair<string, double>(constantKey, varNode.Weight));
    110             } else {
    111               strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat));
    112             }
    113 
     112            AppendConstant(strBuilder, constants, varNode.Weight, formatString, numberFormat);
    114113            strBuilder.Append("*");
    115114          }
    116115
    117           if (varNode.VariableName.Contains("'"))
    118             strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
    119           else
    120             strBuilder.AppendFormat("'{0}'", varNode.VariableName);
     116          AppendVariableName(strBuilder, varNode.VariableName);
    121117
    122118          if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
    123119        } else if (node.Symbol is FactorVariable) {
    124120          var factorNode = node as FactorVariableTreeNode;
    125           if (factorNode.VariableName.Contains("'"))
    126             strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName);
    127           else
    128             strBuilder.AppendFormat("'{0}'", factorNode.VariableName);
    129 
    130           strBuilder.AppendFormat("[{0}]",
    131             string.Join(", ", factorNode.Weights.Select(w => w.ToString(formatString, numberFormat))));
     121          AppendVariableName(strBuilder, factorNode.VariableName);
     122
     123          strBuilder.Append("[");
     124          for (int i = 0; i < factorNode.Weights.Length; i++) {
     125            if (i > 0) strBuilder.Append(", ");
     126            AppendConstant(strBuilder, constants, factorNode.Weights[i], formatString, numberFormat);
     127          }
     128          strBuilder.Append("]");
    132129        } else if (node.Symbol is BinaryFactorVariable) {
    133130          var factorNode = node as BinaryFactorVariableTreeNode;
    134131          if (!factorNode.Weight.IsAlmost(1.0)) {
    135132            strBuilder.Append("(");
    136             if (constants != null) {
    137               strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", factorNode.Weight);
    138             } else {
    139               strBuilder.Append(factorNode.Weight.ToString(formatString, numberFormat));
    140             }
     133            AppendConstant(strBuilder, constants, factorNode.Weight, formatString, numberFormat);
    141134
    142135            strBuilder.Append("*");
    143136          }
    144137
    145           if (factorNode.VariableName.Contains("'"))
    146             strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName);
    147           else
    148             strBuilder.AppendFormat("'{0}'", factorNode.VariableName);
    149 
     138          AppendVariableName(strBuilder, factorNode.VariableName);
    150139          strBuilder.Append(" = ");
    151           if (factorNode.VariableValue.Contains("'"))
    152             strBuilder.AppendFormat("\"{0}\"", factorNode.VariableValue);
    153           else
    154             strBuilder.AppendFormat("'{0}'", factorNode.VariableValue);
     140          AppendVariableName(strBuilder, factorNode.VariableValue);
    155141
    156142          if (!factorNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
    157143        } else if (node.Symbol is Constant) {
    158144          var constNode = node as ConstantTreeNode;
    159           if (constants != null) {
    160             string constantKey = $"c_{constants.Count}";
    161 
    162             strBuilder.AppendFormat(CultureInfo.InvariantCulture, constantKey);
    163             constants.Add(new KeyValuePair<string, double>(constantKey, constNode.Value));
     145          if (constants == null && constNode.Value < 0) {
     146            strBuilder.Append("(").Append(constNode.Value.ToString(formatString, numberFormat))
     147                      .Append(")"); // (-1
    164148          } else {
    165             if (constNode.Value >= 0.0)
    166               strBuilder.Append(constNode.Value.ToString(formatString, numberFormat));
    167             else
    168               strBuilder.Append("(").Append(constNode.Value.ToString(formatString, numberFormat))
    169                         .Append(")"); // (-1
     149            AppendConstant(strBuilder, constants, constNode.Value, formatString, numberFormat);
    170150          }
    171151        }
    172152      }
     153    }
     154
     155    private static void AppendConstant(StringBuilder strBuilder, List<KeyValuePair<string, double>> constants, double value, string formatString, NumberFormatInfo numberFormat) {
     156      if (constants != null) {
     157        string constantKey = $"c_{constants.Count}";
     158        strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constantKey);
     159        constants.Add(new KeyValuePair<string, double>(constantKey, value));
     160      } else {
     161        strBuilder.Append(value.ToString(formatString, numberFormat));
     162      }
     163    }
     164
     165    private static void AppendVariableName(StringBuilder strBuilder, string name) {
     166      if (name.Contains("'"))
     167        strBuilder.AppendFormat("\"{0}\"", name);
     168      else
     169        strBuilder.AppendFormat("'{0}'", name);
    173170    }
    174171
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionCSharpFormatter.cs

    r17226 r18086  
    154154          strBuilder.Append(" / Math.Sqrt(1 + Math.Pow(");
    155155          FormatRecursively(node.GetSubtree(1), strBuilder);
    156           strBuilder.Append(" , 2) )");
     156          strBuilder.Append(" , 2) ) )");
    157157        } else {
    158158          throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " not supported for C# symbolic expression tree formatter.");
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs

    r17226 r18086  
    517517
    518518    private void FormatStartSymbol(StringBuilder strBuilder) {
    519       strBuilder.Append(targetVariable ?? "target_" + (targetCount++));
     519      strBuilder.Append(targetVariable != null ? EscapeLatexString(targetVariable) : "\\text{target}_{" + targetCount++ + "}");
    520520      if (containsTimeSeriesSymbol)
    521521        strBuilder.Append("(t)");
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionPythonFormatter.cs

    r17922 r18086  
    5858    }
    5959
    60     private string GenerateHeader(ISymbolicExpressionTree symbolicExpressionTree) {
     60    private static string GenerateHeader(ISymbolicExpressionTree symbolicExpressionTree) {
    6161      StringBuilder strBuilder = new StringBuilder();
    6262
     
    102102    }
    103103
    104     private string GenerateNecessaryImports(int mathLibCounter, int statisticLibCounter) {
     104    private static string GenerateNecessaryImports(int mathLibCounter, int statisticLibCounter) {
    105105      StringBuilder strBuilder = new StringBuilder();
    106106      if (mathLibCounter > 0 || statisticLibCounter > 0) {
     
    115115    }
    116116
    117     private string GenerateIfThenElseSource(int evaluateIfCounter) {
     117    private static string GenerateIfThenElseSource(int evaluateIfCounter) {
    118118      StringBuilder strBuilder = new StringBuilder();
    119119      if (evaluateIfCounter > 0) {
     
    128128    }
    129129
    130     private string GenerateModelEvaluationFunction(ISet<string> variables) {
     130    private static string GenerateModelEvaluationFunction(ISet<string> variables) {
    131131      StringBuilder strBuilder = new StringBuilder();
    132132      strBuilder.Append("def evaluate(");
     
    142142    }
    143143
    144     private void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
     144    private static void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
    145145      ISymbol symbol = node.Symbol;
    146146      if (symbol is ProgramRootSymbol)
     
    208208    }
    209209
    210     private string VariableName2Identifier(string variableName) => variableName.Replace(" ", "_");
    211 
    212     private void FormatNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, string prefixSymbol = "", string openingSymbol = "(", string closingSymbol = ")", string infixSymbol = ",") {
     210    private static string VariableName2Identifier(string variableName) => variableName.Replace(" ", "_");
     211
     212    private static void FormatNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, string prefixSymbol = "", string openingSymbol = "(", string closingSymbol = ")", string infixSymbol = ",") {
    213213      strBuilder.Append($"{prefixSymbol}{openingSymbol}");
    214214      foreach (var child in node.Subtrees) {
     
    220220    }
    221221
    222     private void FormatVariableTreeNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
     222    private static void FormatVariableTreeNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
    223223      var varNode = node as VariableTreeNode;
    224224      var formattedVariable = VariableName2Identifier(varNode.VariableName);
     
    227227    }
    228228
    229     private void FormatConstantTreeNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
     229    private static void FormatConstantTreeNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
    230230      var constNode = node as ConstantTreeNode;
    231231      strBuilder.Append(constNode.Value.ToString("g17", CultureInfo.InvariantCulture));
    232232    }
    233233
    234     private void FormatPower(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, string exponent) {
     234    private static void FormatPower(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, string exponent) {
    235235      strBuilder.Append("math.pow(");
    236236      FormatRecursively(node.GetSubtree(0), strBuilder);
     
    238238    }
    239239
    240     private void FormatRoot(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
     240    private static void FormatRoot(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
    241241      strBuilder.Append("math.pow(");
    242242      FormatRecursively(node.GetSubtree(0), strBuilder);
     
    246246    }
    247247
    248     private void FormatSubtraction(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
     248    private static void FormatSubtraction(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
    249249      if (node.SubtreeCount == 1) {
    250250        strBuilder.Append("-");
     
    256256    }
    257257
    258     private void FormatDivision(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
     258    private static void FormatDivision(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
    259259      strBuilder.Append("(");
    260260      if (node.SubtreeCount == 1) {
     
    273273    }
    274274
    275     private void FormatAnalyticQuotient(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
     275    private static void FormatAnalyticQuotient(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
    276276      strBuilder.Append("(");
    277277      FormatRecursively(node.GetSubtree(0), strBuilder);
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj

    r17457 r18086  
    9999  </PropertyGroup>
    100100  <ItemGroup>
    101     <Reference Include="ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    102       <HintPath>..\..\bin\ALGLIB-3.7.0.dll</HintPath>
     101    <Reference Include="ALGLIB-3.17.0, Version=3.17.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     102      <SpecificVersion>False</SpecificVersion>
     103      <HintPath>..\..\bin\ALGLIB-3.17.0.dll</HintPath>
    103104      <Private>False</Private>
    104105    </Reference>
     
    107108      <Private>False</Private>
    108109    </Reference>
    109     <Reference Include="HEAL.Attic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     110    <Reference Include="HEAL.Attic, Version=1.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    110111      <SpecificVersion>False</SpecificVersion>
    111112      <HintPath>..\..\bin\HEAL.Attic.dll</HintPath>
     
    153154    <Compile Include="Crossovers\SymbolicDataAnalysisExpressionDiversityPreservingCrossover.cs" />
    154155    <Compile Include="Formatters\InfixExpressionFormatter.cs" />
     156    <Compile Include="Formatters\SymbolicDataAnalysisExpressionPythonFormatter.cs" />
    155157    <Compile Include="Formatters\TSQLExpressionFormatter.cs" />
    156158    <Compile Include="Formatters\SymbolicDataAnalysisExpressionMathematicaFormatter.cs" />
    157159    <Compile Include="Formatters\SymbolicDataAnalysisExpressionCSharpFormatter.cs" />
    158160    <Compile Include="Grammars\DataAnalysisGrammar.cs" />
     161    <Compile Include="Grammars\LinearScalingGrammar.cs" />
    159162    <Compile Include="Hashing\HashExtensions.cs" />
    160163    <Compile Include="Hashing\HashUtil.cs" />
     
    163166    <Compile Include="Importer\SymbolicExpressionImporter.cs" />
    164167    <Compile Include="Importer\Token.cs" />
     168    <Compile Include="Interfaces\IBoundsEstimator.cs" />
    165169    <Compile Include="Interfaces\IModelBacktransformator.cs" />
    166170    <Compile Include="Interfaces\IVariableTreeNode.cs" />
     
    168172    <Compile Include="Interpreter\BatchInstruction.cs" />
    169173    <Compile Include="Interpreter\BatchOperations.cs" />
     174    <Compile Include="Interpreter\IntervalArithBoundsEstimator.cs" />
     175    <Compile Include="Interpreter\IntervalArithCompiledExpressionBoundsEstimator.cs" />
    170176    <Compile Include="Interpreter\IntervalInterpreter.cs" />
    171177    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs" />
    172178    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs" />
    173179    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs" />
     180    <Compile Include="IntervalUtil.cs" />
    174181    <Compile Include="Selectors\DiversitySelector.cs" />
    175182    <Compile Include="SymbolicDataAnalysisExpressionTreeAverageSimilarityCalculator.cs" />
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs

    r17226 r18086  
    6464    }
    6565
    66     private class SymbolNameComparer : IEqualityComparer<ISymbol>, IComparer<ISymbol> {
     66    private class SymbolComparer : IEqualityComparer<ISymbol>, IComparer<ISymbol> {
    6767      public int Compare(ISymbol x, ISymbol y) {
    6868        return x.Name.CompareTo(y.Name);
     
    7070
    7171      public bool Equals(ISymbol x, ISymbol y) {
    72         return Compare(x, y) == 0;
     72        return x.GetType() == y.GetType();
    7373      }
    7474
    7575      public int GetHashCode(ISymbol obj) {
    76         return obj.Name.GetHashCode();
     76        return obj.GetType().GetHashCode();
    7777      }
    7878    }
     
    8080    // the lookup table is also used in the corresponding formatter
    8181    internal static readonly BidirectionalLookup<string, ISymbol>
    82       knownSymbols = new BidirectionalLookup<string, ISymbol>(StringComparer.InvariantCulture, new SymbolNameComparer());
     82      knownSymbols = new BidirectionalLookup<string, ISymbol>(StringComparer.InvariantCulture, new SymbolComparer());
    8383
    8484    private Constant constant = new Constant();
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalArithBoundsEstimator.cs

    r17903 r18086  
    5353    private IntervalArithBoundsEstimator(StorableConstructorFlag _) : base(_) { }
    5454
    55     private IntervalArithBoundsEstimator(IntervalArithBoundsEstimator original, Cloner cloner) : base(original, cloner) { }
     55    protected IntervalArithBoundsEstimator(IntervalArithBoundsEstimator original, Cloner cloner) : base(original, cloner) { }
    5656
    5757    public IntervalArithBoundsEstimator() : base("Interval Arithmetic Bounds Estimator",
     
    223223            break;
    224224          }
     225        case OpCodes.Power: {
     226          var a = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     227          var b = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     228          // support only integer powers
     229          if (b.LowerBound == b.UpperBound && Math.Truncate(b.LowerBound) == b.LowerBound) {
     230            result = Interval.Power(a, (int)b.LowerBound);
     231          } else {
     232            throw new NotSupportedException("Interval is only supported for integer powers");
     233          }
     234          break;
     235        }
    225236        case OpCodes.Absolute: {
    226237            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     
    232243            for (var i = 1; i < currentInstr.nArguments; i++) {
    233244              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    234               result = Interval.AnalyticalQuotient(result, argumentInterval);
     245              result = Interval.AnalyticQuotient(result, argumentInterval);
    235246            }
    236247
     
    329340          !(n.Symbol is Cube) &&
    330341          !(n.Symbol is CubeRoot) &&
     342          !(n.Symbol is Power) &&
    331343          !(n.Symbol is Absolute) &&
    332344          !(n.Symbol is AnalyticQuotient)
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalArithCompiledExpressionBoundsEstimator.cs

    r17903 r18086  
    7575
    7676    [StorableConstructor]
    77     private IntervalArithCompiledExpressionBoundsEstimator(StorableConstructorFlag _) : base(_) { }
    78 
    79     private IntervalArithCompiledExpressionBoundsEstimator(IntervalArithCompiledExpressionBoundsEstimator original, Cloner cloner) : base(original, cloner) { }
     77    protected IntervalArithCompiledExpressionBoundsEstimator(StorableConstructorFlag _) : base(_) { }
     78
     79    protected IntervalArithCompiledExpressionBoundsEstimator(IntervalArithCompiledExpressionBoundsEstimator original, Cloner cloner) : base(original, cloner) { }
    8080
    8181    public override IDeepCloneable Clone(Cloner cloner) {
     
    194194            return Expression.Divide(e1, e2);
    195195          }
     196        case OpCodes.AnalyticQuotient: {
     197            var a = expr(node.GetSubtree(0));
     198            var b = expr(node.GetSubtree(1));
     199            var fun = typeof(Interval).GetMethod(methodName[opCode], new[] { a.Type, b.Type });
     200            return Expression.Call(fun, a, b);
     201          }
    196202        // all these cases share the same code: get method info by name, emit call expression
    197203        case OpCodes.Exp:
     
    205211        case OpCodes.SquareRoot:
    206212        case OpCodes.CubeRoot:
    207         case OpCodes.Absolute:
    208         case OpCodes.AnalyticQuotient: {
     213        case OpCodes.Absolute: {
    209214            var arg = expr(node.GetSubtree(0));
    210215            var fun = typeof(Interval).GetMethod(methodName[opCode], new[] { arg.Type });
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs

    r17586 r18086  
    11#region License Information
     2
    23/* HeuristicLab
    34 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     
    1819 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
    1920 */
     21
    2022#endregion
    2123
     
    3234namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    3335  [StorableType("DE6C1E1E-D7C1-4070-847E-63B68562B10C")]
    34   [Item("IntervalInterpreter", "Intperter for calculation of intervals of symbolic models.")]
     36  [Item("IntervalInterpreter", "Interpreter for calculation of intervals of symbolic models.")]
    3537  public sealed class IntervalInterpreter : ParameterizedNamedItem, IStatefulItem {
    36 
    3738    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
    38 
    39     public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter {
    40       get { return (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
    41     }
     39    public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter =>
     40      (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName];
    4241
    4342    public int EvaluatedSolutions {
    44       get { return EvaluatedSolutionsParameter.Value.Value; }
    45       set { EvaluatedSolutionsParameter.Value.Value = value; }
     43      get => EvaluatedSolutionsParameter.Value.Value;
     44      set => EvaluatedSolutionsParameter.Value.Value = value;
    4645    }
    4746
    4847    [StorableConstructor]
    4948    private IntervalInterpreter(StorableConstructorFlag _) : base(_) { }
     49
    5050    private IntervalInterpreter(IntervalInterpreter original, Cloner cloner)
    51         : base(original, cloner) { }
     51      : base(original, cloner) { }
    5252
    5353    public IntervalInterpreter()
    54         : base("IntervalInterpreter", "Intperter for calculation of intervals of symbolic models.") {
    55       Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
     54      : base("IntervalInterpreter", "Interpreter for calculation of intervals of symbolic models.") {
     55      Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName,
     56        "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
    5657    }
    5758
     
    6364
    6465    #region IStatefulItem Members
     66
    6567    public void InitializeState() {
    6668      EvaluatedSolutions = 0;
    6769    }
     70
    6871    public void ClearState() { }
     72
    6973    #endregion
    7074
    71     public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows = null) {
     75    public Interval GetSymbolicExpressionTreeInterval(
     76      ISymbolicExpressionTree tree, IDataset dataset,
     77      IEnumerable<int> rows = null) {
    7278      var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
    7379      return GetSymbolicExpressionTreeInterval(tree, variableRanges);
    7480    }
    7581
    76     public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset,
    77       out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals, IEnumerable<int> rows = null) {
     82    public Interval GetSymbolicExpressionTreeIntervals(
     83      ISymbolicExpressionTree tree, IDataset dataset,
     84      out IDictionary<ISymbolicExpressionTreeNode, Interval>
     85        nodeIntervals, IEnumerable<int> rows = null) {
    7886      var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
    7987      return GetSymbolicExpressionTreeIntervals(tree, variableRanges, out nodeIntervals);
    8088    }
    8189
    82     public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges) {
     90    public Interval GetSymbolicExpressionTreeInterval(
     91      ISymbolicExpressionTree tree,
     92      IReadOnlyDictionary<string, Interval> variableRanges) {
    8393      lock (syncRoot) {
    8494        EvaluatedSolutions++;
    8595      }
    86       int instructionCount = 0;
     96
     97      Interval outputInterval;
     98
     99      var instructionCount = 0;
    87100      var instructions = PrepareInterpreterState(tree, variableRanges);
    88       var outputInterval = Evaluate(instructions, ref instructionCount);
    89 
    90       // because of numerical errors the bounds might be incorrect
    91       if (outputInterval.LowerBound <= outputInterval.UpperBound)
    92         return outputInterval;
    93       else
    94         return new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
    95     }
    96 
    97 
    98     public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree,
    99       IReadOnlyDictionary<string, Interval> variableRanges, out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals) {
     101      outputInterval = Evaluate(instructions, ref instructionCount);
     102
     103      return outputInterval.LowerBound <= outputInterval.UpperBound
     104        ? outputInterval
     105        : new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
     106    }
     107
     108
     109    public Interval GetSymbolicExpressionTreeIntervals(
     110      ISymbolicExpressionTree tree,
     111      IReadOnlyDictionary<string, Interval> variableRanges,
     112      out IDictionary<ISymbolicExpressionTreeNode, Interval>
     113        nodeIntervals) {
    100114      lock (syncRoot) {
    101115        EvaluatedSolutions++;
    102116      }
    103       int instructionCount = 0;
     117
    104118      var intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
    105119      var instructions = PrepareInterpreterState(tree, variableRanges);
    106       var outputInterval = Evaluate(instructions, ref instructionCount, intervals);
    107 
    108       // fix incorrect intervals if necessary (could occur because of numerical errors)
     120
     121      Interval outputInterval;
     122      var instructionCount = 0;
     123      outputInterval = Evaluate(instructions, ref instructionCount, intervals);
     124
    109125      nodeIntervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
    110126      foreach (var kvp in intervals) {
     
    119135      if (outputInterval.IsInfiniteOrUndefined || outputInterval.LowerBound <= outputInterval.UpperBound)
    120136        return outputInterval;
    121       else
    122         return new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
    123     }
    124 
    125 
    126     private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges) {
     137
     138      return new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
     139    }
     140
     141
     142    private static Instruction[] PrepareInterpreterState(
     143      ISymbolicExpressionTree tree,
     144      IReadOnlyDictionary<string, Interval> variableRanges) {
    127145      if (variableRanges == null)
    128146        throw new ArgumentNullException("No variablew ranges are present!", nameof(variableRanges));
    129147
    130       //Check if all variables used in the tree are present in the dataset
    131       foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName).Distinct()) {
    132         if (!variableRanges.ContainsKey(variable)) throw new InvalidOperationException($"No ranges for variable {variable} is present");
    133       }
    134 
    135       Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
    136       foreach (Instruction instr in code.Where(i => i.opCode == OpCodes.Variable)) {
     148      // Check if all variables used in the tree are present in the dataset
     149      foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName)
     150                                   .Distinct())
     151        if (!variableRanges.ContainsKey(variable))
     152          throw new InvalidOperationException($"No ranges for variable {variable} is present");
     153
     154      var code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
     155      foreach (var instr in code.Where(i => i.opCode == OpCodes.Variable)) {
    137156        var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
    138157        instr.data = variableRanges[variableTreeNode.VariableName];
    139158      }
     159
    140160      return code;
    141161    }
    142162
    143     private Interval Evaluate(Instruction[] instructions, ref int instructionCounter, IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null) {
    144       Instruction currentInstr = instructions[instructionCounter];
    145       //Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side
    146       //Update instructionCounter, whenever Evaluate is called
     163    // Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side
     164    // Update instructionCounter, whenever Evaluate is called
     165    public static Interval Evaluate(
     166    Instruction[] instructions, ref int instructionCounter,
     167      IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null,
     168      IReadOnlyDictionary<string, Interval> variableIntervals = null) {
     169      var currentInstr = instructions[instructionCounter];
     170
    147171      instructionCounter++;
    148       Interval result = null;
     172      Interval result;
    149173
    150174      switch (currentInstr.opCode) {
    151         //Variables, Constants, ...
    152175        case OpCodes.Variable: {
    153176            var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
    154177            var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight);
    155             var variableInterval = (Interval)currentInstr.data;
     178
     179            Interval variableInterval;
     180            if (variableIntervals != null && variableIntervals.ContainsKey(variableTreeNode.VariableName))
     181              variableInterval = variableIntervals[variableTreeNode.VariableName];
     182            else
     183              variableInterval = (Interval)currentInstr.data;
    156184
    157185            result = Interval.Multiply(variableInterval, weightInterval);
     
    163191            break;
    164192          }
    165         //Elementary arithmetic rules
    166193        case OpCodes.Add: {
    167             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    168             for (int i = 1; i < currentInstr.nArguments; i++) {
    169               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     194            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     195            for (var i = 1; i < currentInstr.nArguments; i++) {
     196              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    170197              result = Interval.Add(result, argumentInterval);
    171198            }
     199
    172200            break;
    173201          }
    174202        case OpCodes.Sub: {
    175             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     203            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    176204            if (currentInstr.nArguments == 1)
    177205              result = Interval.Multiply(new Interval(-1, -1), result);
    178206
    179             for (int i = 1; i < currentInstr.nArguments; i++) {
    180               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     207            for (var i = 1; i < currentInstr.nArguments; i++) {
     208              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    181209              result = Interval.Subtract(result, argumentInterval);
    182210            }
     211
    183212            break;
    184213          }
    185214        case OpCodes.Mul: {
    186             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    187             for (int i = 1; i < currentInstr.nArguments; i++) {
    188               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     215            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     216            for (var i = 1; i < currentInstr.nArguments; i++) {
     217              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    189218              result = Interval.Multiply(result, argumentInterval);
    190219            }
     220
    191221            break;
    192222          }
    193223        case OpCodes.Div: {
    194             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     224            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    195225            if (currentInstr.nArguments == 1)
    196226              result = Interval.Divide(new Interval(1, 1), result);
    197227
    198             for (int i = 1; i < currentInstr.nArguments; i++) {
    199               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     228            for (var i = 1; i < currentInstr.nArguments; i++) {
     229              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    200230              result = Interval.Divide(result, argumentInterval);
    201231            }
    202             break;
    203           }
    204         //Trigonometric functions
     232
     233            break;
     234          }
    205235        case OpCodes.Sin: {
    206             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     236            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    207237            result = Interval.Sine(argumentInterval);
    208238            break;
    209239          }
    210240        case OpCodes.Cos: {
    211             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     241            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    212242            result = Interval.Cosine(argumentInterval);
    213243            break;
    214244          }
    215245        case OpCodes.Tan: {
    216             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     246            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    217247            result = Interval.Tangens(argumentInterval);
    218248            break;
    219249          }
    220250        case OpCodes.Tanh: {
    221             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     251            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    222252            result = Interval.HyperbolicTangent(argumentInterval);
    223253            break;
    224254          }
    225         //Exponential functions
    226255        case OpCodes.Log: {
    227             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     256            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    228257            result = Interval.Logarithm(argumentInterval);
    229258            break;
    230259          }
    231260        case OpCodes.Exp: {
    232             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     261            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    233262            result = Interval.Exponential(argumentInterval);
    234263            break;
    235264          }
    236265        case OpCodes.Square: {
    237             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     266            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    238267            result = Interval.Square(argumentInterval);
    239268            break;
    240269          }
    241270        case OpCodes.SquareRoot: {
    242             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     271            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    243272            result = Interval.SquareRoot(argumentInterval);
    244273            break;
    245274          }
    246275        case OpCodes.Cube: {
    247             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     276            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    248277            result = Interval.Cube(argumentInterval);
    249278            break;
    250279          }
    251280        case OpCodes.CubeRoot: {
    252             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     281            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    253282            result = Interval.CubicRoot(argumentInterval);
    254283            break;
    255284          }
     285        case OpCodes.Power: {
     286            var a = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     287            var b = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     288            // support only integer powers
     289            if (b.LowerBound == b.UpperBound && Math.Truncate(b.LowerBound) == b.LowerBound) {
     290              result = Interval.Power(a, (int)b.LowerBound);
     291            } else {
     292              throw new NotSupportedException("Interval is only supported for integer powers");
     293            }
     294            break;
     295          }
     296
    256297        case OpCodes.Absolute: {
    257             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     298            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    258299            result = Interval.Absolute(argumentInterval);
    259300            break;
    260301          }
    261302        case OpCodes.AnalyticQuotient: {
    262             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    263             for (var i = 1; i < currentInstr.nArguments; i++) {
    264               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    265               result = Interval.AnalyticalQuotient(result, argumentInterval);
     303            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     304            for (var i = 1; i < currentInstr.nArguments; i++) {
     305              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     306              result = Interval.AnalyticQuotient(result, argumentInterval);
    266307            }
    267308
     
    272313      }
    273314
    274       if (nodeIntervals != null)
     315      if (!(nodeIntervals == null || nodeIntervals.ContainsKey(currentInstr.dynamicNode)))
    275316        nodeIntervals.Add(currentInstr.dynamicNode, result);
    276317
     
    278319    }
    279320
     321
    280322    public static bool IsCompatible(ISymbolicExpressionTree tree) {
    281       var containsUnknownSyumbol = (
    282         from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
    283         where
    284           !(n.Symbol is Problems.DataAnalysis.Symbolic.Variable) &&
     323      foreach (var n in tree.Root.GetSubtree(0).IterateNodesPrefix()) {
     324        if (
     325          !(n.Symbol is Variable) &&
    285326          !(n.Symbol is Constant) &&
    286327          !(n.Symbol is StartSymbol) &&
     
    292333          !(n.Symbol is Cosine) &&
    293334          !(n.Symbol is Tangent) &&
     335          !(n.Symbol is HyperbolicTangent) &&
    294336          !(n.Symbol is Logarithm) &&
    295337          !(n.Symbol is Exponential) &&
     
    298340          !(n.Symbol is Cube) &&
    299341          !(n.Symbol is CubeRoot) &&
     342          !(n.Symbol is Power) &&
    300343          !(n.Symbol is Absolute) &&
    301           !(n.Symbol is AnalyticQuotient)
    302         select n).Any();
    303       return !containsUnknownSyumbol;
     344          !(n.Symbol is AnalyticQuotient)) return false;
     345
     346        else if (n.Symbol is Power) {
     347          // only integer exponents are supported
     348          var exp = n.GetSubtree(1) as ConstantTreeNode;
     349          if (exp == null || exp.Value != Math.Truncate(exp.Value)) return false;
     350        }
     351      }
     352      return true;
    304353    }
    305354  }
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs

    r17226 r18086  
    144144      { typeof(Cosine), OpCodes.Cos },
    145145      { typeof(Tangent), OpCodes.Tan },
    146       { typeof (HyperbolicTangent), OpCodes.Tanh},
     146      { typeof(HyperbolicTangent), OpCodes.Tanh},
    147147      { typeof(Logarithm), OpCodes.Log },
    148148      { typeof(Exponential), OpCodes.Exp },
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs

    r17457 r18086  
    222222
    223223    private double[] GetValues(ISymbolicExpressionTree tree, IDataset dataset, int[] rows) {
    224       if (cachedData == null || cachedDataset != dataset) {
     224      if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) {
    225225        InitCache(dataset);
    226226      }
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs

    r17457 r18086  
    127127      if (!rows.Any()) return Enumerable.Empty<double>();
    128128
    129       if (cachedData == null || cachedDataset != dataset) {
     129      if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) {
    130130        InitCache(dataset);
    131131      }
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/IntervalUtil.cs

    r17903 r18086  
    3939      var varRanges = variableRanges.GetReadonlyDictionary();
    4040
    41       if (constraint.Variable != null && !varRanges.ContainsKey(constraint.Variable)) {
     41      if (!string.IsNullOrEmpty(constraint.Variable) && !varRanges.ContainsKey(constraint.Variable)) {
    4242        throw new ArgumentException(
    43           $"The given variable {constraint.Variable} in the constraint does not exist in the model.",
     43          $"No variable range found for variable {constraint.Variable} used in the constraints.",
    4444          nameof(constraint));
    4545      }
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame

    r17226 r18086  
    2828  [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic","Provides base classes for symbolic data analysis tasks.", "3.4.12.$WCREV$")]
    2929  [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll", PluginFileType.Assembly)]
    30   [PluginDependency("HeuristicLab.ALGLIB", "3.7.0")]
     30  [PluginDependency("HeuristicLab.ALGLIB", "3.17.0")]
    3131  [PluginDependency("HeuristicLab.AutoDiff", "1.0")]
    3232  [PluginDependency("HeuristicLab.Analysis", "3.3")]
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisMultiObjectiveProblem.cs

    r17695 r18086  
    2626using HeuristicLab.Core;
    2727using HeuristicLab.Data;
     28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2829using HeuristicLab.Optimization;
    2930using HeuristicLab.Parameters;
     
    3233  [StorableType("E9876DF8-ACFA-41C8-93B7-FA40C57CE459")]
    3334  public abstract class SymbolicDataAnalysisMultiObjectiveProblem<T, U> : SymbolicDataAnalysisProblem<T, U>, ISymbolicDataAnalysisMultiObjectiveProblem
    34     where T : class,IDataAnalysisProblemData
     35    where T : class, IDataAnalysisProblemData
    3536    where U : class, ISymbolicDataAnalysisMultiObjectiveEvaluator<T> {
    3637    private const string MaximizationParameterName = "Maximization";
     
    102103        op.MaximizationParameter.ActualName = MaximizationParameterName;
    103104      }
     105
     106      // these two crossover operators are compatible with single-objective problems only so we remove them from the operators collection
     107      bool pred(IItem x) {
     108        return x is SymbolicDataAnalysisExpressionDeterministicBestCrossover<T> || x is SymbolicDataAnalysisExpressionContextAwareCrossover<T>;
     109      };
     110      Operators.RemoveAll(pred);
     111      // if a multi crossover is present, remove them from its operator collection
     112      var cx = Operators.FirstOrDefault(x => x is MultiSymbolicDataAnalysisExpressionCrossover<T>);
     113      if (cx != null) {
     114        var multiCrossover = (MultiSymbolicDataAnalysisExpressionCrossover<T>)cx;
     115        var items = multiCrossover.Operators.Where(pred).Cast<ISymbolicExpressionTreeCrossover>().ToList();
     116        foreach (var item in items) {
     117          multiCrossover.Operators.Remove(item);
     118        }
     119      }
    104120    }
    105121
Note: See TracChangeset for help on using the changeset viewer.