Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/16/21 14:23:41 (4 years ago)
Author:
gkronber
Message:

#3073 merged reintegration branch to trunk

Location:
trunk/HeuristicLab.Problems.DataAnalysis.Symbolic
Files:
5 edited
5 copied

Legend:

Unmodified
Added
Removed
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic

  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs

    r17180 r17902  
    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) &&
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/IntervalArithmeticGrammar.cs

    r17884 r17902  
    1 using System.Collections.Generic;
     1#region License Information
     2
     3/* HeuristicLab
     4 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     5 *
     6 * This file is part of HeuristicLab.
     7 *
     8 * HeuristicLab is free software: you can redistribute it and/or modify
     9 * it under the terms of the GNU General Public License as published by
     10 * the Free Software Foundation, either version 3 of the License, or
     11 * (at your option) any later version.
     12 *
     13 * HeuristicLab is distributed in the hope that it will be useful,
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 * GNU General Public License for more details.
     17 *
     18 * You should have received a copy of the GNU General Public License
     19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     20 */
     21
     22#endregion
     23using System.Collections.Generic;
    224using System.Linq;
    325using HEAL.Attic;
     
    830namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    931  [StorableType("5A2300A0-D0FC-4F2D-B910-F86384FE9052")]
    10   [Item("IntervalArithmeticGrammar", "Represents a grammar for interval arithmetic")]
     32  [Item("IntervalArithmeticGrammar", "Represents a grammar for interval arithmetic which includes linear scaling parts implicitly.")]
    1133  public class IntervalArithmeticGrammar : DataAnalysisGrammar, ISymbolicDataAnalysisGrammar {
    1234    public IntervalArithmeticGrammar() : base(ItemAttribute.GetName(typeof(IntervalArithmeticGrammar)),
     
    3557      var cos = new Cosine();
    3658      var tan = new Tangent();
     59      var tanh = new HyperbolicTangent();
    3760      var log = new Logarithm();
    38       var pow = new Power();
     61      var exp = new Exponential();
    3962      var square = new Square();
    40       var root = new Root();
    4163      var sqrt = new SquareRoot();
    42       var exp = new Exponential();
    43       var tanh = new HyperbolicTangent();
     64      var cube = new Cube();
     65      var cbrt = new CubeRoot();
     66      var abs = new Absolute();
     67      var aq = new AnalyticQuotient();
    4468      var constant = new Constant();
    45       var aq = new AnalyticQuotient();
    4669      constant.MinValue = -20;
    4770      constant.MaxValue = 20;
     
    5174
    5275      //Special symbols
    53       var offset = new Addition {Name = "Offset"};
    54       var scaling = new Multiplication {Name = "Scaling"};
     76      var offset = new Addition { Name = "Offset" };
     77      var scaling = new Multiplication { Name = "Scaling" };
    5578      //all other symbols
    5679      var allSymbols = new List<Symbol> {
    57         add, sub, mul, div, constant, variableSymbol, sin, cos, tan, log, pow, square, root, sqrt, exp,
    58         tanh, aq
     80        add, sub, mul, div, constant, variableSymbol, sin, cos, tan, log, square, sqrt, cube, cbrt, exp,
     81        tanh, aq, abs
    5982      };
    6083
    61       var arithmeticSymbols = new List<Symbol> {add, sub, mul, div};
    62       var trigonometricSymbols = new List<Symbol> {sin, cos, tan, tanh};
    63       var exponentialAndLogarithmicSymbols = new List<Symbol> {exp, log};
    64       var powerSymbols = new List<Symbol> {square, pow, sqrt, root};
    65       var specialSymbols = new List<Symbol> {aq};
    66       var realValueSymbols = new List<Symbol>
    67         {add, sub, mul, div, sin, cos, tan, tanh, exp, log, variableSymbol, constant, aq};
     84      var bivariateFuncs = new List<Symbol> { add, sub, mul, div, aq };
     85      var univariateFuncs = new List<Symbol> { sin, cos, tan, tanh, exp, log, abs, square, cube, sqrt, cbrt };
     86      var realValueSymbols = new List<Symbol> {
     87         add, sub, mul, div, sin, cos, tan, tanh, exp, log, aq, abs, square, cube, sqrt, cbrt,
     88         variableSymbol, constant,
     89        };
    6890
    6991
     
    7698      #region define subtree count for special symbols
    7799
    78       foreach (var symb in arithmeticSymbols) SetSubtreeCount(symb, 2, 2);
     100      foreach (var symb in bivariateFuncs) SetSubtreeCount(symb, 2, 2);
    79101
    80       foreach (var symb in trigonometricSymbols) SetSubtreeCount(symb, 1, 1);
    81 
    82       foreach (var symb in exponentialAndLogarithmicSymbols) SetSubtreeCount(symb, 1, 1);
     102      foreach (var symb in univariateFuncs) SetSubtreeCount(symb, 1, 1);
    83103
    84104      SetSubtreeCount(offset, 2, 2);
    85105      SetSubtreeCount(scaling, 2, 2);
    86       SetSubtreeCount(pow, 2, 2);
    87       SetSubtreeCount(root, 2, 2);
    88       SetSubtreeCount(square, 1, 1);
    89       SetSubtreeCount(sqrt, 1, 1);
    90       SetSubtreeCount(aq, 2, 2);
    91106
    92107      #endregion
     
    109124      }
    110125
    111       //define childs for power symbols
    112       foreach (var symb in powerSymbols) {
    113         AddAllowedChildSymbol(symb, variableSymbol, 0);
    114         AddAllowedChildSymbol(symb, constant, 1);
    115       }
    116 
    117       //define child for sqrt and square
    118       foreach (var c in realValueSymbols) {
    119         AddAllowedChildSymbol(square, c, 0);
    120         AddAllowedChildSymbol(sqrt, c, 0);
    121       }
    122 
    123       //define child for aq
    124       foreach (var c in realValueSymbols) {
    125         AddAllowedChildSymbol(aq, c, 0);
    126         AddAllowedChildSymbol(aq, c, 1);
    127       }
    128 
    129126      #endregion
    130127
    131       Symbols.First(s => s is Power).Enabled = false;
    132       Symbols.First(s => s is Root).Enabled = false;
    133       Symbols.First(s => s is AnalyticQuotient).Enabled = false;
     128      Symbols.First(s => s is Cube).Enabled = false;
     129      Symbols.First(s => s is CubeRoot).Enabled = false;
     130      Symbols.First(s => s is Absolute).Enabled = false;
    134131    }
    135132  }
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj

    r17413 r17902  
    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>
     
    157157    <Compile Include="Formatters\SymbolicDataAnalysisExpressionCSharpFormatter.cs" />
    158158    <Compile Include="Grammars\DataAnalysisGrammar.cs" />
     159    <Compile Include="Grammars\IntervalArithmeticGrammar.cs" />
    159160    <Compile Include="Hashing\HashExtensions.cs" />
    160161    <Compile Include="Hashing\HashUtil.cs" />
     
    163164    <Compile Include="Importer\SymbolicExpressionImporter.cs" />
    164165    <Compile Include="Importer\Token.cs" />
     166    <Compile Include="Interfaces\IBoundsEstimator.cs" />
    165167    <Compile Include="Interfaces\IModelBacktransformator.cs" />
    166168    <Compile Include="Interfaces\IVariableTreeNode.cs" />
     
    168170    <Compile Include="Interpreter\BatchInstruction.cs" />
    169171    <Compile Include="Interpreter\BatchOperations.cs" />
     172    <Compile Include="Interpreter\IntervalArithBoundsEstimator.cs" />
     173    <Compile Include="Interpreter\IntervalArithCompiledExpressionBoundsEstimator.cs" />
    170174    <Compile Include="Interpreter\IntervalInterpreter.cs" />
    171175    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs" />
    172176    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs" />
    173177    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs" />
     178    <Compile Include="IntervalUtil.cs" />
    174179    <Compile Include="Selectors\DiversitySelector.cs" />
    175180    <Compile Include="SymbolicDataAnalysisExpressionTreeAverageSimilarityCalculator.cs" />
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs

    r17180 r17902  
    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();
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/IBoundsEstimator.cs

    r17884 r17902  
    1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5 using System.Threading.Tasks;
     1using System.Collections.Generic;
    62using HEAL.Attic;
    73using HeuristicLab.Core;
    84using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    95
    10 namespace HeuristicLab.Problems.DataAnalysis.Symbolic{
     6namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    117  [StorableType("C94A360D-5A9F-48A3-A6D3-CF920C77E50D")]
    128  public interface IBoundsEstimator : INamedItem, IStatefulItem {
    139    Interval GetModelBound(ISymbolicExpressionTree tree, IntervalCollection variableRanges);
    1410
    15     IDictionary<ISymbolicExpressionTreeNode, Interval> GetModelNodesBounds(
     11    IDictionary<ISymbolicExpressionTreeNode, Interval> GetModelNodeBounds(
    1612      ISymbolicExpressionTree tree, IntervalCollection variableRanges);
    1713
    18     double CheckConstraint(
    19       ISymbolicExpressionTree tree, IntervalCollection variableRanges, IntervalConstraint constraint);
     14    // returns the size of the violation which is the distance to one of the bounds
     15    double GetConstraintViolation(
     16      ISymbolicExpressionTree tree, IntervalCollection variableRanges, ShapeConstraint constraint);
    2017
    2118    bool IsCompatible(ISymbolicExpressionTree tree);
    2219
    2320    int EvaluatedSolutions { get; set; }
    24     }
     21  }
    2522}
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs

    r17579 r17902  
    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
    130148      //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)) {
     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);
     
    165193        //Elementary arithmetic rules
    166194        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);
     195            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     196            for (var i = 1; i < currentInstr.nArguments; i++) {
     197              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    170198              result = Interval.Add(result, argumentInterval);
    171199            }
     200
    172201            break;
    173202          }
    174203        case OpCodes.Sub: {
    175             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     204            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    176205            if (currentInstr.nArguments == 1)
    177206              result = Interval.Multiply(new Interval(-1, -1), result);
    178207
    179             for (int i = 1; i < currentInstr.nArguments; i++) {
    180               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     208            for (var i = 1; i < currentInstr.nArguments; i++) {
     209              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    181210              result = Interval.Subtract(result, argumentInterval);
    182211            }
     212
    183213            break;
    184214          }
    185215        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);
     216            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     217            for (var i = 1; i < currentInstr.nArguments; i++) {
     218              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    189219              result = Interval.Multiply(result, argumentInterval);
    190220            }
     221
    191222            break;
    192223          }
    193224        case OpCodes.Div: {
    194             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     225            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    195226            if (currentInstr.nArguments == 1)
    196227              result = Interval.Divide(new Interval(1, 1), result);
    197228
    198             for (int i = 1; i < currentInstr.nArguments; i++) {
    199               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     229            for (var i = 1; i < currentInstr.nArguments; i++) {
     230              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    200231              result = Interval.Divide(result, argumentInterval);
    201232            }
    202             break;
    203           }
    204         //Trigonometric functions
     233
     234            break;
     235          }
    205236        case OpCodes.Sin: {
    206             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     237            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    207238            result = Interval.Sine(argumentInterval);
    208239            break;
    209240          }
    210241        case OpCodes.Cos: {
    211             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     242            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    212243            result = Interval.Cosine(argumentInterval);
    213244            break;
    214245          }
    215246        case OpCodes.Tan: {
    216             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     247            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    217248            result = Interval.Tangens(argumentInterval);
    218249            break;
    219250          }
    220251        case OpCodes.Tanh: {
    221             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     252            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    222253            result = Interval.HyperbolicTangent(argumentInterval);
    223254            break;
    224255          }
    225         //Exponential functions
    226256        case OpCodes.Log: {
    227             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     257            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    228258            result = Interval.Logarithm(argumentInterval);
    229259            break;
    230260          }
    231261        case OpCodes.Exp: {
    232             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     262            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    233263            result = Interval.Exponential(argumentInterval);
    234264            break;
    235265          }
    236266        case OpCodes.Square: {
    237             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     267            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    238268            result = Interval.Square(argumentInterval);
    239269            break;
    240270          }
    241271        case OpCodes.SquareRoot: {
    242             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     272            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    243273            result = Interval.SquareRoot(argumentInterval);
    244274            break;
    245275          }
    246276        case OpCodes.Cube: {
    247             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     277            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    248278            result = Interval.Cube(argumentInterval);
    249279            break;
    250280          }
    251281        case OpCodes.CubeRoot: {
    252             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     282            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    253283            result = Interval.CubicRoot(argumentInterval);
    254284            break;
    255285          }
    256286        case OpCodes.Absolute: {
    257             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     287            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    258288            result = Interval.Absolute(argumentInterval);
    259289            break;
    260290          }
    261291        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);
     292            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     293            for (var i = 1; i < currentInstr.nArguments; i++) {
     294              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    265295              result = Interval.AnalyticalQuotient(result, argumentInterval);
    266296            }
     
    272302      }
    273303
    274       if (nodeIntervals != null)
     304      if (!(nodeIntervals == null || nodeIntervals.ContainsKey(currentInstr.dynamicNode)))
    275305        nodeIntervals.Add(currentInstr.dynamicNode, result);
    276306
     
    278308    }
    279309
     310
    280311    public static bool IsCompatible(ISymbolicExpressionTree tree) {
    281       var containsUnknownSyumbol = (
     312      var containsUnknownSymbols = (
    282313        from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
    283314        where
    284           !(n.Symbol is Problems.DataAnalysis.Symbolic.Variable) &&
     315          !(n.Symbol is Variable) &&
    285316          !(n.Symbol is Constant) &&
    286317          !(n.Symbol is StartSymbol) &&
     
    292323          !(n.Symbol is Cosine) &&
    293324          !(n.Symbol is Tangent) &&
     325          !(n.Symbol is HyperbolicTangent) &&
    294326          !(n.Symbol is Logarithm) &&
    295327          !(n.Symbol is Exponential) &&
     
    301333          !(n.Symbol is AnalyticQuotient)
    302334        select n).Any();
    303       return !containsUnknownSyumbol;
     335      return !containsUnknownSymbols;
    304336    }
    305337  }
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/IntervalUtil.cs

    r17884 r17902  
    1 using System;
     1#region License Information
     2
     3/* HeuristicLab
     4 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     5 *
     6 * This file is part of HeuristicLab.
     7 *
     8 * HeuristicLab is free software: you can redistribute it and/or modify
     9 * it under the terms of the GNU General Public License as published by
     10 * the Free Software Foundation, either version 3 of the License, or
     11 * (at your option) any later version.
     12 *
     13 * HeuristicLab is distributed in the hope that it will be useful,
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 * GNU General Public License for more details.
     17 *
     18 * You should have received a copy of the GNU General Public License
     19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
     20 */
     21
     22#endregion
     23using System;
    224using System.Collections.Generic;
    325using System.Linq;
     
    628namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    729  public static class IntervalUtil {
    8     public static double IntervalConstraintViolation(
    9       IntervalConstraint constraint, IBoundsEstimator estimator, IntervalCollection intervalCollection,
     30    public static IEnumerable<double> GetConstraintViolations(
     31      IEnumerable<ShapeConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection,
    1032      ISymbolicExpressionTree solution) {
    11       var variableRanges = intervalCollection.GetReadonlyDictionary();
     33      return constraints.Select(constraint => GetConstraintViolation(constraint, estimator, intervalCollection, solution)).ToList();
     34    }
    1235
    13       if (constraint.Variable != null && !variableRanges.ContainsKey(constraint.Variable)) {
     36    public static double GetConstraintViolation(
     37      ShapeConstraint constraint, IBoundsEstimator estimator, IntervalCollection variableRanges,
     38      ISymbolicExpressionTree tree) {
     39      var varRanges = variableRanges.GetReadonlyDictionary();
     40
     41      if (constraint.Variable != null && !varRanges.ContainsKey(constraint.Variable)) {
    1442        throw new ArgumentException(
    1543          $"The given variable {constraint.Variable} in the constraint does not exist in the model.",
    16           nameof(IntervalConstraintsParser));
     44          nameof(constraint));
    1745      }
    1846
    19       //Create new variable ranges for defined regions
     47      // Create new variable ranges for defined regions
    2048      var regionRanges = new IntervalCollection();
    21       foreach (var kvp in variableRanges) {
    22         if (kvp.Key != constraint.Target && constraint.Regions.GetReadonlyDictionary().TryGetValue(kvp.Key, out var val)) {
     49      foreach (var kvp in varRanges) {
     50        if (constraint.Regions.GetReadonlyDictionary().TryGetValue(kvp.Key, out var val)) {
    2351          regionRanges.AddInterval(kvp.Key, val);
    2452        } else {
     
    2755      }
    2856
    29       var error = 0.0;
    3057      if (!constraint.IsDerivative) {
    31         error = estimator.CheckConstraint(solution, regionRanges, constraint);
     58        return estimator.GetConstraintViolation(tree, regionRanges, constraint);
    3259      } else {
    33         var tree = solution;
    3460        for (var i = 0; i < constraint.NumberOfDerivations; ++i) {
    3561          if (!estimator.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree)) {
    36             throw new ArgumentException("Cube, Root, Power symbols are not supported.");
     62            throw new ArgumentException("The tree contains an unsupported symbol.");
    3763          }
    3864
     
    4066        }
    4167
    42         error = estimator.CheckConstraint(tree, regionRanges, constraint);
     68        return estimator.GetConstraintViolation(tree, regionRanges, constraint);
    4369      }
    44 
    45       return error;
    46     }
    47 
    48     public static IEnumerable<double> IntervalConstraintsViolation(
    49       IEnumerable<IntervalConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection,
    50       ISymbolicExpressionTree solution) {
    51       return constraints.Select(constraint => IntervalConstraintViolation(constraint, estimator, intervalCollection, solution)).ToList();
    5270    }
    5371  }
Note: See TracChangeset for help on using the changeset viewer.