Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/06/21 13:13:32 (4 years ago)
Author:
dpiringe
Message:

#3026

  • merged trunk into branch
Location:
branches/3026_IntegrationIntoSymSpace
Files:
20 edited
8 copied

Legend:

Unmodified
Added
Removed
  • branches/3026_IntegrationIntoSymSpace

  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic

  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs

    r17180 r17928  
    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/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs

    r17180 r17928  
    933933        var constB = b as ConstantTreeNode;
    934934        var constBValue = Math.Round(constB.Value);
    935         if (constBValue.IsAlmost(1.0)) {
     935        if (constBValue == 1.0) {
     936          // root(a, 1) => a
    936937          return a;
    937         } else if (constBValue.IsAlmost(0.0)) {
    938           return MakeConstant(1.0);
    939         } else if (constBValue.IsAlmost(-1.0)) {
     938        } else if (constBValue == 0.0) {
     939          // root(a, 0) is not defined
     940          //return MakeConstant(1.0);
     941          return MakeConstant(double.NaN);
     942        } else if (constBValue == -1.0) {
     943          // root(a, -1) => a^(-1/1) => 1/a
    940944          return MakeFraction(MakeConstant(1.0), a);
    941945        } else if (constBValue < 0) {
     946          // root(a, -b) => a^(-1/b) => (1/a)^(1/b) => root(1, b) / root(a, b) => 1 / root(a, b)
    942947          var rootNode = rootSymbol.CreateTreeNode();
    943948          rootNode.AddSubtree(a);
     
    987992        var constB = b as ConstantTreeNode;
    988993        double exponent = Math.Round(constB.Value);
    989         if (exponent.IsAlmost(0.0)) {
     994        if (exponent == 0.0) {
     995          // a^0 => 1
    990996          return MakeConstant(1.0);
    991         } else if (exponent.IsAlmost(1.0)) {
     997        } else if (exponent == 1.0) {
     998          // a^1 => a
    992999          return a;
    993         } else if (exponent.IsAlmost(-1.0)) {
     1000        } else if (exponent == -1.0) {
     1001          // a^-1 => 1/a
    9941002          return MakeFraction(MakeConstant(1.0), a);
    9951003        } else if (exponent < 0) {
     1004          // a^-b => (1/a)^b => 1/(a^b)
    9961005          var powNode = powSymbol.CreateTreeNode();
    9971006          powNode.AddSubtree(a);
     
    10181027        // fold constants
    10191028        return MakeConstant(((ConstantTreeNode)a).Value / ((ConstantTreeNode)b).Value);
    1020       } else if ((IsConstant(a) && !((ConstantTreeNode)a).Value.IsAlmost(1.0))) {
     1029      } else if ((IsConstant(a) && ((ConstantTreeNode)a).Value != 1.0)) {
     1030        // a / x => (a * 1/a) / (x * 1/a) => 1 / (x * 1/a)
    10211031        return MakeFraction(MakeConstant(1.0), MakeProduct(b, Invert(a)));
    10221032      } else if (IsVariableBase(a) && IsConstant(b)) {
     
    10941104        // b is not constant => make sure constant is on the right
    10951105        return MakeSum(b, a);
    1096       } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(0.0)) {
     1106      } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 0.0) {
    10971107        // x + 0 => x
    10981108        return a;
     
    12101220      foreach (var unchangedSubtree in unchangedSubtrees)
    12111221        sum.AddSubtree(unchangedSubtree);
    1212       if (!constant.IsAlmost(0.0)) {
     1222      if (constant != 0.0) {
    12131223        sum.AddSubtree(MakeConstant(constant));
    12141224      }
     
    12681278        if (wi < 0) throw new ArgumentException();
    12691279        return MakeBinFactor(node1.Symbol, node1.VariableName, node1.VariableValue, node1.Weight * node0.Weights[wi]);
    1270       } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(1.0)) {
     1280      } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 1.0) {
    12711281        // $ * 1.0 => $
    12721282        return a;
    1273       } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(0.0)) {
     1283      } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 0.0) {
    12741284        return MakeConstant(0);
    12751285      } else if (IsConstant(b) && IsVariableBase(a)) {
     
    14191429        prod.AddSubtree(unchangedSubtree);
    14201430
    1421       if (!constantProduct.IsAlmost(1.0)) {
     1431      if (constantProduct != 1.0) {
    14221432        prod.AddSubtree(MakeConstant(constantProduct));
    14231433      }
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs

    r17180 r17928  
    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/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs

    r17180 r17928  
    2121
    2222using System;
     23using System.Collections.Generic;
    2324using System.Globalization;
    2425using System.Linq;
    2526using System.Text;
     27using HEAL.Attic;
    2628using HeuristicLab.Common;
    2729using HeuristicLab.Core;
    2830using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    29 using HEAL.Attic;
    3031
    3132namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
     33  public static class BaseInfixExpressionFormatter {
     34    public static void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder,
     35                                          NumberFormatInfo numberFormat, string formatString, List<KeyValuePair<string, double>> constants = null) {
     36      if (node.SubtreeCount > 1) {
     37        var token = GetToken(node.Symbol);
     38        // operators
     39        if (token == "+" || token == "-" || token == "OR" || token == "XOR" ||
     40            token == "*" || token == "/" || token == "AND") {
     41          strBuilder.Append("(");
     42          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants);
     43
     44          foreach (var subtree in node.Subtrees.Skip(1)) {
     45            strBuilder.Append(" ").Append(token).Append(" ");
     46            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);
     61          }
     62
     63          strBuilder.Append(")");
     64        } else {
     65          // function with multiple arguments
     66          strBuilder.Append(token).Append("(");
     67          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants);
     68          foreach (var subtree in node.Subtrees.Skip(1)) {
     69            strBuilder.Append(", ");
     70            FormatRecursively(subtree, strBuilder, numberFormat, formatString, constants);
     71          }
     72
     73          strBuilder.Append(")");
     74        }
     75      } else if (node.SubtreeCount == 1) {
     76        var token = GetToken(node.Symbol);
     77        if (token == "-" || token == "NOT") {
     78          strBuilder.Append("(").Append(token).Append("(");
     79          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
     80          strBuilder.Append("))");
     81        } else if (token == "/") {
     82          strBuilder.Append("1/");
     83          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
     84        } else if (token == "+" || token == "*") {
     85          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
     86        } else {
     87          // function with only one argument
     88          strBuilder.Append(token).Append("(");
     89          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
     90          strBuilder.Append(")");
     91        }
     92      } else {
     93        // no subtrees
     94        if (node.Symbol is LaggedVariable) {
     95          var varNode = node as LaggedVariableTreeNode;
     96          if (!varNode.Weight.IsAlmost(1.0)) {
     97            strBuilder.Append("(");
     98            AppendConstant(strBuilder, constants, varNode.Weight, formatString, numberFormat);
     99            strBuilder.Append("*");
     100          }
     101
     102          strBuilder.Append("LAG(");
     103          AppendVariableName(strBuilder, varNode.VariableName);
     104          strBuilder.Append(", ")
     105                    .AppendFormat(numberFormat, "{0}", varNode.Lag)
     106                    .Append(")");
     107          if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
     108        } else if (node.Symbol is Variable) {
     109          var varNode = node as VariableTreeNode;
     110          if (!varNode.Weight.IsAlmost(1.0)) {
     111            strBuilder.Append("(");
     112            AppendConstant(strBuilder, constants, varNode.Weight, formatString, numberFormat);
     113            strBuilder.Append("*");
     114          }
     115
     116          AppendVariableName(strBuilder, varNode.VariableName);
     117
     118          if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
     119        } else if (node.Symbol is FactorVariable) {
     120          var factorNode = node as FactorVariableTreeNode;
     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("]");
     129        } else if (node.Symbol is BinaryFactorVariable) {
     130          var factorNode = node as BinaryFactorVariableTreeNode;
     131          if (!factorNode.Weight.IsAlmost(1.0)) {
     132            strBuilder.Append("(");
     133            AppendConstant(strBuilder, constants, factorNode.Weight, formatString, numberFormat);
     134
     135            strBuilder.Append("*");
     136          }
     137
     138          AppendVariableName(strBuilder, factorNode.VariableName);
     139          strBuilder.Append(" = ");
     140          AppendVariableName(strBuilder, factorNode.VariableValue);
     141
     142          if (!factorNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
     143        } else if (node.Symbol is Constant) {
     144          var constNode = node as ConstantTreeNode;
     145          if (constants == null && constNode.Value < 0) {
     146            strBuilder.Append("(").Append(constNode.Value.ToString(formatString, numberFormat))
     147                      .Append(")"); // (-1
     148          } else {
     149            AppendConstant(strBuilder, constants, constNode.Value, formatString, numberFormat);
     150          }
     151        }
     152      }
     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);
     170    }
     171
     172    private static string GetToken(ISymbol symbol) {
     173      var tok = InfixExpressionParser.knownSymbols.GetBySecond(symbol).FirstOrDefault();
     174      if (tok == null)
     175        throw new ArgumentException(string.Format("Unknown symbol {0} found.", symbol.Name));
     176      return tok;
     177    }
     178  }
     179
    32180  /// <summary>
    33181  /// Formats mathematical expressions in infix form. E.g. x1 * (3.0 * x2 + x3)
    34182  /// </summary>
    35183  [StorableType("6FE2C83D-A594-4ABF-B101-5AEAEA6D3E3D")]
    36   [Item("Infix Symbolic Expression Tree Formatter", "A string formatter that converts symbolic expression trees to infix expressions.")]
    37 
     184  [Item("Infix Symbolic Expression Tree Formatter",
     185    "A string formatter that converts symbolic expression trees to infix expressions.")]
    38186  public sealed class InfixExpressionFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
    39 
    40 
    41187    [StorableConstructor]
    42188    private InfixExpressionFormatter(StorableConstructorFlag _) : base(_) { }
     189
    43190    private InfixExpressionFormatter(InfixExpressionFormatter original, Cloner cloner) : base(original, cloner) { }
     191
    44192    public InfixExpressionFormatter()
    45193      : base() {
     
    47195      Description = ItemDescription;
    48196    }
     197
    49198    public override IDeepCloneable Clone(Cloner cloner) {
    50199      return new InfixExpressionFormatter(this, cloner);
     
    58207    /// <param name="formatString">The format string for numeric parameters (e.g. \"G4\" to limit to 4 digits, default is \"G\")</param>
    59208    /// <returns>Infix expression</returns>
    60     public string Format(ISymbolicExpressionTree symbolicExpressionTree, NumberFormatInfo numberFormat, string formatString="G") {
     209    public string Format(ISymbolicExpressionTree symbolicExpressionTree, NumberFormatInfo numberFormat,
     210                         string formatString = "G") {
    61211      // skip root and start symbols
    62212      StringBuilder strBuilder = new StringBuilder();
    63       FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0), strBuilder, numberFormat, formatString);
     213      BaseInfixExpressionFormatter.FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0),
     214        strBuilder, numberFormat, formatString);
    64215      return strBuilder.ToString();
    65216    }
     
    68219      return Format(symbolicExpressionTree, NumberFormatInfo.InvariantInfo);
    69220    }
    70 
    71     private static void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, NumberFormatInfo numberFormat, string formatString) {
    72       if (node.SubtreeCount > 1) {
    73         var token = GetToken(node.Symbol);
    74         // operators
    75         if (token == "+" || token == "-" || token == "OR" || token == "XOR" ||
    76             token == "*" || token == "/" || token == "AND" ||
    77             token == "^") {
    78           strBuilder.Append("(");
    79           FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString);
    80 
    81           foreach (var subtree in node.Subtrees.Skip(1)) {
    82             strBuilder.Append(" ").Append(token).Append(" ");
    83             FormatRecursively(subtree, strBuilder, numberFormat, formatString);
    84           }
    85           strBuilder.Append(")");
    86         } else {
    87           // function with multiple arguments
    88           strBuilder.Append(token).Append("(");
    89           FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString);
    90           foreach (var subtree in node.Subtrees.Skip(1)) {
    91             strBuilder.Append(", ");
    92             FormatRecursively(subtree, strBuilder, numberFormat, formatString);
    93           }
    94           strBuilder.Append(")");
    95         }
    96       } else if (node.SubtreeCount == 1) {
    97         var token = GetToken(node.Symbol);
    98         if (token == "-" || token == "NOT") {
    99           strBuilder.Append("(").Append(token).Append("(");
    100           FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString);
    101           strBuilder.Append("))");
    102         } else if (token == "/") {
    103           strBuilder.Append("1/");
    104           FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString);
    105         } else if (token == "+" || token == "*") {
    106           FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString);
    107         } else {
    108           // function with only one argument
    109           strBuilder.Append(token).Append("(");
    110           FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString);
    111           strBuilder.Append(")");
    112         }
    113       } else {
    114         // no subtrees
    115         if (node.Symbol is LaggedVariable) {
    116           var varNode = node as LaggedVariableTreeNode;
    117           if (!varNode.Weight.IsAlmost(1.0)) {
    118             strBuilder.Append("(");
    119             strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat));
    120             strBuilder.Append("*");
    121           }
    122           strBuilder.Append("LAG(");
    123           if (varNode.VariableName.Contains("'")) {
    124             strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
    125           } else {
    126             strBuilder.AppendFormat("'{0}'", varNode.VariableName);
    127           }
    128           strBuilder.Append(", ")
    129             .AppendFormat(numberFormat, "{0}", varNode.Lag)
    130             .Append(")");
    131         } else if (node.Symbol is Variable) {
    132           var varNode = node as VariableTreeNode;
    133           if (!varNode.Weight.IsAlmost(1.0)) {
    134             strBuilder.Append("(");
    135             strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat));
    136             strBuilder.Append("*");
    137           }
    138           if (varNode.VariableName.Contains("'")) {
    139             strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
    140           } else {
    141             strBuilder.AppendFormat("'{0}'", varNode.VariableName);
    142           }
    143           if (!varNode.Weight.IsAlmost(1.0)) {
    144             strBuilder.Append(")");
    145           }
    146         } else if (node.Symbol is FactorVariable) {
    147           var factorNode = node as FactorVariableTreeNode;
    148           if (factorNode.VariableName.Contains("'")) {
    149             strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName);
    150           } else {
    151             strBuilder.AppendFormat("'{0}'", factorNode.VariableName);
    152           }
    153           strBuilder.AppendFormat("[{0}]",
    154             string.Join(", ", factorNode.Weights.Select(w => w.ToString(formatString, numberFormat))));
    155         } else if (node.Symbol is BinaryFactorVariable) {
    156           var factorNode = node as BinaryFactorVariableTreeNode;
    157           if (!factorNode.Weight.IsAlmost(1.0)) {
    158             strBuilder.Append("(");
    159             strBuilder.Append(factorNode.Weight.ToString(formatString, numberFormat));
    160             strBuilder.Append("*");
    161           }
    162           if (factorNode.VariableName.Contains("'")) {
    163             strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName);
    164           } else {
    165             strBuilder.AppendFormat("'{0}'", factorNode.VariableName);
    166           }
    167           strBuilder.Append(" = ");
    168           if (factorNode.VariableValue.Contains("'")) {
    169             strBuilder.AppendFormat("\"{0}\"", factorNode.VariableValue);
    170           } else {
    171             strBuilder.AppendFormat("'{0}'", factorNode.VariableValue);
    172           }
    173 
    174           if (!factorNode.Weight.IsAlmost(1.0)) {
    175             strBuilder.Append(")");
    176           }
    177 
    178         } else if (node.Symbol is Constant) {
    179           var constNode = node as ConstantTreeNode;
    180           if (constNode.Value >= 0.0)
    181             strBuilder.Append(constNode.Value.ToString(formatString, numberFormat));
    182           else
    183             strBuilder.Append("(").Append(constNode.Value.ToString(formatString, numberFormat)).Append(")"); // (-1
    184         }
     221  }
     222
     223  [StorableType("54D917E8-134E-4066-9A60-2737C12D81DC")]
     224  [Item("Infix String Formater", "Formatter for symbolic expressions, which produces an infix expression " +
     225                                 "as well as a list of all coefficient values")]
     226  public sealed class InfixExpressionStringFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
     227    [StorableConstructor]
     228    private InfixExpressionStringFormatter(StorableConstructorFlag _) : base(_) { }
     229
     230    private InfixExpressionStringFormatter(InfixExpressionStringFormatter original, Cloner cloner) : base(original, cloner) { }
     231
     232    public InfixExpressionStringFormatter() : base() {
     233      Name = ItemName;
     234      Description = ItemDescription;
     235    }
     236
     237    public override IDeepCloneable Clone(Cloner cloner) {
     238      return new InfixExpressionStringFormatter(this, cloner);
     239    }
     240
     241    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
     242      StringBuilder strBuilder = new StringBuilder();
     243      var constants = new List<KeyValuePair<string, double>>();
     244      BaseInfixExpressionFormatter.FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0),
     245        strBuilder, NumberFormatInfo.InvariantInfo, "G", constants);
     246      strBuilder.Append($"{Environment.NewLine}{Environment.NewLine}");
     247
     248      int maxDigits = GetDigits(constants.Count);
     249      int padding = constants.Max(x => x.Value.ToString("F12", CultureInfo.InvariantCulture).Length);
     250      foreach (var constant in constants) {
     251        int digits = GetDigits(Int32.Parse(constant.Key.Substring(2)));
     252        strBuilder.Append($"{constant.Key}{new String(' ', maxDigits - digits)} = " +
     253                          string.Format($"{{0,{padding}:F12}}", constant.Value, CultureInfo.InvariantCulture) +
     254                          Environment.NewLine);
    185255      }
    186     }
    187 
    188     private static string GetToken(ISymbol symbol) {
    189       var tok = InfixExpressionParser.knownSymbols.GetBySecond(symbol).FirstOrDefault();
    190       if (tok == null)
    191         throw new ArgumentException(string.Format("Unknown symbol {0} found.", symbol.Name));
    192       return tok;
     256
     257      return strBuilder.ToString();
     258    }
     259
     260    private int GetDigits(int x) {
     261      if (x == 0) return 1;
     262      return (int)Math.Floor(Math.Log10(x) + 1);
    193263    }
    194264  }
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionCSharpFormatter.cs

    r17180 r17928  
    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/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs

    r17180 r17928  
    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/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/ArithmeticExpressionGrammar.cs

    r17180 r17928  
    2121
    2222using System.Collections.Generic;
     23using HEAL.Attic;
    2324using HeuristicLab.Common;
    2425using HeuristicLab.Core;
    2526using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    26 using HEAL.Attic;
    2727using HeuristicLab.PluginInfrastructure;
    2828
     
    3131  [StorableType("FCBA02B7-5D29-42F5-A64C-A60AD8EA475D")]
    3232  [Item("ArithmeticExpressionGrammar", "Represents a grammar for functional expressions using only arithmetic operations.")]
    33   public class ArithmeticExpressionGrammar : SymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {
     33  public class ArithmeticExpressionGrammar : DataAnalysisGrammar, ISymbolicDataAnalysisGrammar {
    3434
    3535    [StorableConstructor]
     
    5656      var factorVariableSymbol = new FactorVariable();
    5757
    58       var allSymbols = new List<Symbol>() { add, sub, mul, div, constant, variableSymbol, binFactorVariableSymbol, factorVariableSymbol};
     58      var allSymbols = new List<Symbol>() { add, sub, mul, div, constant, variableSymbol, binFactorVariableSymbol, factorVariableSymbol };
    5959      var functionSymbols = new List<Symbol>() { add, sub, mul, div };
    6060
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs

    r17180 r17928  
    2222using System.Collections.Generic;
    2323using System.Linq;
     24using HEAL.Attic;
    2425using HeuristicLab.Common;
    2526using HeuristicLab.Core;
    2627using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    27 using HEAL.Attic;
    2828
    2929namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    3030  [StorableType("44B0829C-1CB5-4BE9-9514-BBA54FAB2912")]
    3131  [Item("FullFunctionalExpressionGrammar", "Represents a grammar for functional expressions using all available functions.")]
    32   public class FullFunctionalExpressionGrammar : SymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {
     32  public class FullFunctionalExpressionGrammar : DataAnalysisGrammar, ISymbolicDataAnalysisGrammar {
    3333    [StorableConstructor]
    3434    protected FullFunctionalExpressionGrammar(StorableConstructorFlag _) : base(_) { }
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs

    r17180 r17928  
    2222using System.Collections.Generic;
    2323using System.Linq;
     24using HEAL.Attic;
    2425using HeuristicLab.Common;
    2526using HeuristicLab.Core;
    2627using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    27 using HEAL.Attic;
    2828namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    2929  [StorableType("36A22322-0627-4E25-A468-F2A788AF6D46")]
    3030  [Item("TypeCoherentExpressionGrammar", "Represents a grammar for functional expressions in which special syntactic constraints are enforced so that boolean and real-valued expressions are not mixed.")]
    31   public class TypeCoherentExpressionGrammar : SymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {
     31  public class TypeCoherentExpressionGrammar : DataAnalysisGrammar, ISymbolicDataAnalysisGrammar {
    3232    private const string ArithmeticFunctionsName = "Arithmetic Functions";
    3333    private const string TrigonometricFunctionsName = "Trigonometric Functions";
     
    117117      #region group symbol declaration
    118118      var arithmeticSymbols = new GroupSymbol(ArithmeticFunctionsName, new List<ISymbol>() { add, sub, mul, div, mean });
    119       var trigonometricSymbols = new GroupSymbol(TrigonometricFunctionsName, new List<ISymbol>() { sin, cos, tan, tanh});
    120       var exponentialAndLogarithmicSymbols = new GroupSymbol(ExponentialFunctionsName, new List<ISymbol> { exp, log});
     119      var trigonometricSymbols = new GroupSymbol(TrigonometricFunctionsName, new List<ISymbol>() { sin, cos, tan, tanh });
     120      var exponentialAndLogarithmicSymbols = new GroupSymbol(ExponentialFunctionsName, new List<ISymbol> { exp, log });
    121121      var specialFunctions = new GroupSymbol(SpecialFunctionsName, new List<ISymbol> { abs, airyA, airyB, bessel, cosineIntegral, dawson, erf, expIntegralEi,
    122122        fresnelCosineIntegral,fresnelSineIntegral,gamma,hypCosineIntegral,hypSineIntegral,norm, psi, sineIntegral, analyticalQuotient});
     
    149149      SetSubtreeCount(cubeRoot, 1, 1);
    150150      SetSubtreeCount(exponentialAndLogarithmicSymbols, 1, 1);
    151       foreach(var sy in specialFunctions.Symbols.Except(new[] { analyticalQuotient})) {
     151      foreach (var sy in specialFunctions.Symbols.Except(new[] { analyticalQuotient })) {
    152152        SetSubtreeCount(sy, 1, 1);
    153153      }
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj

    r16980 r17928  
    107107      <Private>False</Private>
    108108    </Reference>
    109     <Reference Include="HEAL.Attic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     109    <Reference Include="HEAL.Attic, Version=1.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    110110      <SpecificVersion>False</SpecificVersion>
    111111      <HintPath>..\..\bin\HEAL.Attic.dll</HintPath>
     
    150150    <Compile Include="Converters\DerivativeCalculator.cs" />
    151151    <Compile Include="Converters\TreeToAutoDiffTermConverter.cs" />
     152    <Compile Include="Creators\SymbolicDataAnalysisExpressionBalancedTreeCreator.cs" />
    152153    <Compile Include="Crossovers\SymbolicDataAnalysisExpressionDiversityPreservingCrossover.cs" />
    153154    <Compile Include="Formatters\InfixExpressionFormatter.cs" />
     155    <Compile Include="Formatters\SymbolicDataAnalysisExpressionPythonFormatter.cs" />
    154156    <Compile Include="Formatters\TSQLExpressionFormatter.cs" />
    155157    <Compile Include="Formatters\SymbolicDataAnalysisExpressionMathematicaFormatter.cs" />
    156158    <Compile Include="Formatters\SymbolicDataAnalysisExpressionCSharpFormatter.cs" />
     159    <Compile Include="Grammars\DataAnalysisGrammar.cs" />
     160    <Compile Include="Grammars\IntervalArithmeticGrammar.cs" />
    157161    <Compile Include="Hashing\HashExtensions.cs" />
    158162    <Compile Include="Hashing\HashUtil.cs" />
     
    161165    <Compile Include="Importer\SymbolicExpressionImporter.cs" />
    162166    <Compile Include="Importer\Token.cs" />
     167    <Compile Include="Interfaces\IBoundsEstimator.cs" />
    163168    <Compile Include="Interfaces\IModelBacktransformator.cs" />
    164169    <Compile Include="Interfaces\IVariableTreeNode.cs" />
     
    166171    <Compile Include="Interpreter\BatchInstruction.cs" />
    167172    <Compile Include="Interpreter\BatchOperations.cs" />
     173    <Compile Include="Interpreter\IntervalArithBoundsEstimator.cs" />
     174    <Compile Include="Interpreter\IntervalArithCompiledExpressionBoundsEstimator.cs" />
    168175    <Compile Include="Interpreter\IntervalInterpreter.cs" />
    169176    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs" />
    170177    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs" />
    171178    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs" />
     179    <Compile Include="IntervalUtil.cs" />
    172180    <Compile Include="Selectors\DiversitySelector.cs" />
    173181    <Compile Include="SymbolicDataAnalysisExpressionTreeAverageSimilarityCalculator.cs" />
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs

    r17180 r17928  
    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/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisGrammar.cs

    r17180 r17928  
    2020#endregion
    2121
     22using HEAL.Attic;
    2223using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    23 using HEAL.Attic;
    2424
    2525namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    2626  [StorableType("5b0720d7-b1f0-4c2f-893e-cd2549e20e9e")]
    2727  public interface ISymbolicDataAnalysisGrammar : ISymbolicExpressionGrammar {
     28    void ConfigureVariableSymbols(IDataAnalysisProblemData problemData);
    2829  }
    2930}
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs

    r17180 r17928  
    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
     
    2325using System.Collections.Generic;
    2426using System.Linq;
     27using HEAL.Attic;
    2528using HeuristicLab.Common;
    2629using HeuristicLab.Core;
    2730using HeuristicLab.Data;
    2831using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    29 using HEAL.Attic;
    3032using HeuristicLab.Parameters;
    3133
    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, IDictionary<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       IDictionary<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, IDictionary<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          }
    236         case OpCodes.Power: {
    237             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    238             for (int i = 1; i < currentInstr.nArguments; i++) {
    239               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    240               result = Interval.Power(result, argumentInterval);
    241             }
    242             break;
    243           }
    244265        case OpCodes.Square: {
    245             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     266            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    246267            result = Interval.Square(argumentInterval);
    247268            break;
    248269          }
    249         case OpCodes.Root: {
    250             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    251             for (int i = 1; i < currentInstr.nArguments; i++) {
    252               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    253               result = Interval.Root(result, argumentInterval);
    254             }
    255             break;
    256           }
    257270        case OpCodes.SquareRoot: {
    258             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     271            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    259272            result = Interval.SquareRoot(argumentInterval);
     273            break;
     274          }
     275        case OpCodes.Cube: {
     276            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     277            result = Interval.Cube(argumentInterval);
     278            break;
     279          }
     280        case OpCodes.CubeRoot: {
     281            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     282            result = Interval.CubicRoot(argumentInterval);
     283            break;
     284          }
     285        case OpCodes.Absolute: {
     286            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     287            result = Interval.Absolute(argumentInterval);
     288            break;
     289          }
     290        case OpCodes.AnalyticQuotient: {
     291            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     292            for (var i = 1; i < currentInstr.nArguments; i++) {
     293              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     294              result = Interval.AnalyticQuotient(result, argumentInterval);
     295            }
     296
    260297            break;
    261298          }
     
    264301      }
    265302
    266       if (nodeIntervals != null)
     303      if (!(nodeIntervals == null || nodeIntervals.ContainsKey(currentInstr.dynamicNode)))
    267304        nodeIntervals.Add(currentInstr.dynamicNode, result);
    268305
     
    270307    }
    271308
     309
    272310    public static bool IsCompatible(ISymbolicExpressionTree tree) {
    273       var containsUnknownSyumbol = (
     311      var containsUnknownSymbols = (
    274312        from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
    275313        where
     314          !(n.Symbol is Variable) &&
     315          !(n.Symbol is Constant) &&
    276316          !(n.Symbol is StartSymbol) &&
    277317          !(n.Symbol is Addition) &&
     
    282322          !(n.Symbol is Cosine) &&
    283323          !(n.Symbol is Tangent) &&
     324          !(n.Symbol is HyperbolicTangent) &&
    284325          !(n.Symbol is Logarithm) &&
    285326          !(n.Symbol is Exponential) &&
    286           !(n.Symbol is Power) &&
    287327          !(n.Symbol is Square) &&
    288           !(n.Symbol is Root) &&
    289328          !(n.Symbol is SquareRoot) &&
    290           !(n.Symbol is Problems.DataAnalysis.Symbolic.Variable) &&
    291           !(n.Symbol is Constant)
     329          !(n.Symbol is Cube) &&
     330          !(n.Symbol is CubeRoot) &&
     331          !(n.Symbol is Absolute) &&
     332          !(n.Symbol is AnalyticQuotient)
    292333        select n).Any();
    293       return !containsUnknownSyumbol;
     334      return !containsUnknownSymbols;
    294335    }
    295336  }
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs

    r17180 r17928  
    5252    private static readonly MethodInfo Log = typeof(Math).GetMethod("Log", new[] { typeof(double) });
    5353    private static readonly MethodInfo IsNaN = typeof(double).GetMethod("IsNaN");
    54     private static readonly MethodInfo IsAlmost = typeof(DoubleExtensions).GetMethod("IsAlmost");
     54    private static readonly MethodInfo IsAlmost = typeof(DoubleExtensions).GetMethod("IsAlmost", new Type[] { typeof(double), typeof(double)});
    5555    private static readonly MethodInfo Gamma = typeof(alglib).GetMethod("gammafunction", new[] { typeof(double) });
    5656    private static readonly MethodInfo Psi = typeof(alglib).GetMethod("psi", new[] { typeof(double) });
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs

    r16768 r17928  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     4 *
     5 * This file is part of HeuristicLab.
     6 *
     7 * HeuristicLab is free software: you can redistribute it and/or modify
     8 * it under the terms of the GNU General Public License as published by
     9 * the Free Software Foundation, either version 3 of the License, or
     10 * (at your option) any later version.
     11 *
     12 * HeuristicLab is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     19 */
     20#endregion
     21
     22using System;
    223using System.Collections.Generic;
    324using System.Linq;
     
    181202
    182203    [ThreadStatic]
    183     private Dictionary<string, double[]> cachedData;
     204    private static Dictionary<string, double[]> cachedData;
    184205
    185206    [ThreadStatic]
    186     private IDataset dataset;
     207    private static IDataset cachedDataset;
    187208
    188209    private void InitCache(IDataset dataset) {
    189       this.dataset = dataset;
     210      cachedDataset = dataset;
    190211      cachedData = new Dictionary<string, double[]>();
    191212      foreach (var v in dataset.DoubleVariables) {
     
    196217    public void InitializeState() {
    197218      cachedData = null;
    198       dataset = null;
     219      cachedDataset = null;
    199220      EvaluatedSolutions = 0;
    200221    }
    201222
    202223    private double[] GetValues(ISymbolicExpressionTree tree, IDataset dataset, int[] rows) {
    203       if (cachedData == null || this.dataset != dataset) {
     224      if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) {
    204225        InitCache(dataset);
    205226      }
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs

    r17180 r17928  
    9999
    100100    [ThreadStatic]
    101     private IDataset dataset;
     101    private static IDataset cachedDataset;
    102102
    103103    private static readonly HashSet<byte> supportedOpCodes = new HashSet<byte>() {
     
    127127      if (!rows.Any()) return Enumerable.Empty<double>();
    128128
    129       if (cachedData == null || this.dataset != dataset) {
     129      if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) {
    130130        InitCache(dataset);
    131131      }
     
    152152
    153153    private void InitCache(IDataset dataset) {
    154       this.dataset = dataset;
     154      cachedDataset = dataset;
    155155
    156156      // free handles to old data
     
    178178        cachedData = null;
    179179      }
    180       dataset = null;
     180      cachedDataset = null;
    181181      EvaluatedSolutions = 0;
    182182    }
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisMultiObjectiveProblem.cs

    r17180 r17928  
    2121
    2222using System.Linq;
     23using HEAL.Attic;
    2324using HeuristicLab.Common;
    2425using HeuristicLab.Core;
    2526using HeuristicLab.Data;
     27using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2628using HeuristicLab.Optimization;
    2729using HeuristicLab.Parameters;
    28 using HEAL.Attic;
    2930
    3031namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    3132  [StorableType("E9876DF8-ACFA-41C8-93B7-FA40C57CE459")]
    3233  public abstract class SymbolicDataAnalysisMultiObjectiveProblem<T, U, V> : SymbolicDataAnalysisProblem<T, U, V>, ISymbolicDataAnalysisMultiObjectiveProblem
    33     where T : class,IDataAnalysisProblemData
     34    where T : class, IDataAnalysisProblemData
    3435    where U : class, ISymbolicDataAnalysisMultiObjectiveEvaluator<T>
    3536    where V : class, ISymbolicDataAnalysisSolutionCreator {
     
    9798        op.MaximizationParameter.ActualName = MaximizationParameterName;
    9899      }
     100
     101      // these two crossover operators are compatible with single-objective problems only so we remove them from the operators collection
     102      bool pred(IItem x) {
     103        return x is SymbolicDataAnalysisExpressionDeterministicBestCrossover<T> || x is SymbolicDataAnalysisExpressionContextAwareCrossover<T>;
     104      };
     105      Operators.RemoveAll(pred);
     106      // if a multi crossover is present, remove them from its operator collection
     107      var cx = Operators.FirstOrDefault(x => x is MultiSymbolicDataAnalysisExpressionCrossover<T>);
     108      if (cx != null) {
     109        var multiCrossover = (MultiSymbolicDataAnalysisExpressionCrossover<T>)cx;
     110        var items = multiCrossover.Operators.Where(pred).Cast<ISymbolicExpressionTreeCrossover>().ToList();
     111        foreach (var item in items) {
     112          multiCrossover.Operators.Remove(item);
     113        }
     114      }
    99115    }
    100116  }
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs

    r17180 r17928  
    2424using System.Drawing;
    2525using System.Linq;
     26using HEAL.Attic;
    2627using HeuristicLab.Common;
    2728using HeuristicLab.Common.Resources;
     
    3132using HeuristicLab.Optimization;
    3233using HeuristicLab.Parameters;
    33 using HEAL.Attic;
    3434using HeuristicLab.PluginInfrastructure;
    3535using HeuristicLab.Problems.Instances;
     
    210210    protected virtual void UpdateGrammar() {
    211211      var problemData = ProblemData;
    212       var ds = problemData.Dataset;
    213212      var grammar = SymbolicExpressionTreeGrammar;
     213
    214214      grammar.MaximumFunctionArguments = MaximumFunctionArguments.Value;
    215215      grammar.MaximumFunctionDefinitions = MaximumFunctionDefinitions.Value;
    216       foreach (var varSymbol in grammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.VariableBase>()) {
    217         if (!varSymbol.Fixed) {
    218           varSymbol.AllVariableNames = problemData.InputVariables.Select(x => x.Value).Where(x => ds.VariableHasType<double>(x));
    219           varSymbol.VariableNames = problemData.AllowedInputVariables.Where(x => ds.VariableHasType<double>(x));
    220         }
    221       }
    222       foreach (var factorSymbol in grammar.Symbols.OfType<BinaryFactorVariable>()) {
    223         if (!factorSymbol.Fixed) {
    224           factorSymbol.AllVariableNames = problemData.InputVariables.Select(x => x.Value).Where(x => ds.VariableHasType<string>(x));
    225           factorSymbol.VariableNames = problemData.AllowedInputVariables.Where(x => ds.VariableHasType<string>(x));
    226           factorSymbol.VariableValues = factorSymbol.VariableNames
    227             .ToDictionary(varName => varName, varName => ds.GetStringValues(varName).Distinct().ToList());
    228         }
    229       }
    230       foreach (var factorSymbol in grammar.Symbols.OfType<FactorVariable>()) {
    231         if (!factorSymbol.Fixed) {
    232           factorSymbol.AllVariableNames = problemData.InputVariables.Select(x => x.Value).Where(x => ds.VariableHasType<string>(x));
    233           factorSymbol.VariableNames = problemData.AllowedInputVariables.Where(x => ds.VariableHasType<string>(x));
    234           factorSymbol.VariableValues = factorSymbol.VariableNames
    235             .ToDictionary(varName => varName,
    236             varName => ds.GetStringValues(varName).Distinct()
    237             .Select((n, i) => Tuple.Create(n, i))
    238             .ToDictionary(tup => tup.Item1, tup => tup.Item2));
    239         }
    240       }
     216
     217      grammar.ConfigureVariableSymbols(problemData);
    241218    }
    242219
Note: See TracChangeset for help on using the changeset viewer.