Changeset 16330


Ignore:
Timestamp:
11/27/18 10:20:59 (3 weeks ago)
Author:
chaider
Message:

#2966: Implemented review comments and added IsCompatible method.

Location:
branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj

    r16323 r16330  
    199199    <Compile Include="Interfaces\IVariableSymbol.cs" />
    200200    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs" />
    201     <Compile Include="Interpreter\Intervalnterpreter.cs" />
     201    <Compile Include="Interpreter\IntervalInterpreter.cs" />
    202202    <Compile Include="SymbolicDataAnalysisExpressionTreeSimplificationOperator.cs" />
    203203    <Compile Include="SymbolicDataAnalysisModelComplexityCalculator.cs" />
  • branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs

    r16329 r16330  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2018 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;
     
    1233namespace HeuristicLab.Algorithms.DataAnalysis.Symbolic {
    1334  [StorableClass]
    14   [Item("SymbolicDataAnalysisIntervalArithmeticInterpreter", "Interpreter for interval arithmetic within symbolic regression.")]
     35  [Item("IntervalInterpreter", "Intperter for calculation of intervals of symbolic models.")]
    1536  public sealed class IntervalInterpreter : ParameterizedNamedItem, IStatefulItem {
    1637
    1738    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
     39    private static int InstructionCount = 0;
     40
    1841    public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter {
    1942      get { return (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
     
    3053
    3154    public IntervalInterpreter()
    32         : base("SymbolicDataAnalysisIntervalArithmeticInterpreter", "Interpreter for interval arithmetic within symbolic regression.") { }
     55        : base("IntervalInterpreter", "Intperter for calculation of intervals of symbolic models.") { }
    3356
    3457    public override IDeepCloneable Clone(Cloner cloner) {
    3558      return new IntervalInterpreter(this, cloner);
    3659    }
     60
     61    private readonly object syncRoot = new object();
    3762
    3863    #region IStatefulItem Members
     
    4368    #endregion
    4469
    45 
    46     public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IEnumerable<int> rows, out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
     70    private static void ResetInstrucitonCount() {
     71      InstructionCount = 0;
     72    }
     73
     74
     75    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows = null) {
     76      lock (syncRoot) {
     77        EvaluatedSolutions++;
     78        ResetInstrucitonCount();
     79      }
     80      var instructions = PrepareInterpreterState(tree, rows, dataset);
     81      var x = Evaluate(instructions);
     82
     83      return x;
     84    }
     85
     86    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, Dictionary<string, Interval> customIntervals, IEnumerable<int> rows = null) {
     87      lock (syncRoot) {
     88        EvaluatedSolutions++;
     89        ResetInstrucitonCount();
     90      }
     91      var instructions = PrepareInterpreterState(tree, rows, null, customIntervals);
     92      var x = Evaluate(instructions);
     93
     94      return x;
     95    }
     96
     97    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset,
     98      Dictionary<string, Interval> customIntervals, out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals, IEnumerable<int> rows = null) {
     99      lock (syncRoot) {
     100        EvaluatedSolutions++;
     101        ResetInstrucitonCount();
     102      }
    47103      intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
    48       var state = PrepareInterpreterState(tree, rows);
    49       var x = Evaluate(state, intervals);
    50 
    51       return x;
    52     }
    53 
    54     public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows,
    55       Dictionary<string, Interval> customIntervals, out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
     104      var instructions = PrepareInterpreterState(tree, rows, dataset, customIntervals);
     105      var x = Evaluate(instructions, intervals);
     106
     107      return x;
     108    }
     109
     110    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset,
     111      out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals, IEnumerable<int> rows = null) {
     112      lock(syncRoot) {
     113        EvaluatedSolutions++;
     114        ResetInstrucitonCount();
     115      }
    56116      intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
    57       var state = PrepareInterpreterState(tree, rows, dataset, customIntervals);
    58       var x = Evaluate(state, intervals);
    59 
    60       return x;
    61     }
    62 
    63     public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows,
    64       out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
     117      var instructions = PrepareInterpreterState(tree, rows, dataset);
     118      var x = Evaluate(instructions, intervals);
     119
     120      return x;
     121    }
     122
     123    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, Dictionary<string, Interval> customIntervals,
     124      out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals, IEnumerable<int> rows = null) {
     125      lock (syncRoot) {
     126        EvaluatedSolutions++;
     127        ResetInstrucitonCount();
     128      }
    65129      intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
    66       var state = PrepareInterpreterState(tree, rows, dataset);
    67       var x = Evaluate(state, intervals);
    68 
    69       return x;
    70     }
    71 
    72     private readonly object syncRoot = new object();
    73 
    74     private static InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree,
    75       IEnumerable<int> rows, IDataset dataset = null, Dictionary<string, Interval> customIntervals = null) {
     130      var instructions = PrepareInterpreterState(tree, rows, null, customIntervals);
     131      var x = Evaluate(instructions, intervals);
     132
     133      return x;
     134    }
     135
     136    private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree,
     137      IEnumerable<int> rows = null, IDataset dataset = null, Dictionary<string, Interval> customIntervals = null) {
    76138      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
    77       int necessaryArgStackSize = 0;
     139
     140      if (dataset == null && customIntervals == null)
     141        throw new Exception("No dataset or ranges for intervals are given!");
     142
     143      if(rows == null)
     144        rows = Enumerable.Range(0, dataset.Rows);
    78145
    79146      foreach (Instruction instr in code) {
     
    82149          IList<double> values = new List<double>();
    83150
    84           if (dataset != null && customIntervals != null) {
     151          if (customIntervals != null) {
    85152            if (customIntervals.ContainsKey(variableTreeNode.VariableName)) {
    86153              instr.data = customIntervals[variableTreeNode.VariableName];
    87154            }
    88             else {
    89               foreach (var rowEnum in rows) {
    90                 values.Add(dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName)[rowEnum]);
    91               }
    92               instr.data = new Interval(values.Min(), values.Max());
    93             }
    94           }
    95           else if (dataset != null) {
     155          } else {
    96156            foreach (var rowEnum in rows) {
    97157              values.Add(dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName)[rowEnum]);
     
    99159            instr.data = new Interval(values.Min(), values.Max());
    100160          }
    101           else if (customIntervals != null) {
    102             if (customIntervals.ContainsKey(variableTreeNode.VariableName)) {
    103               instr.data = customIntervals[variableTreeNode.VariableName];
    104             }
    105           }
    106           else {
    107             throw new Exception("No valid input for variables!");
    108           }
    109161        }
    110162      }
    111 
    112       return new InterpreterState(code, necessaryArgStackSize);
    113     }
    114 
    115     private Interval Evaluate(InterpreterState state, Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
    116       Instruction currentInstr = state.NextInstruction();
     163      return code;
     164    }
     165
     166    private Interval Evaluate(Instruction[] instructions, Dictionary<ISymbolicExpressionTreeNode, Interval> intervals = null) {
     167      Instruction currentInstr = instructions[InstructionCount++];
    117168      switch (currentInstr.opCode) {
    118169        //Elementary arithmetic rules
    119170        case OpCodes.Add: {
    120             var s = Evaluate(state, intervals);
    121             for (int i = 1; i < currentInstr.nArguments; i++) {
    122               s = Interval.Add(s, Evaluate(state, intervals));
     171            var s = Evaluate(instructions, intervals);
     172            for (int i = 1; i < currentInstr.nArguments; i++) {
     173              s = Interval.Add(s, Evaluate(instructions, intervals));
    123174            }
    124175            intervals.Add(currentInstr.dynamicNode, s);
     
    126177          }
    127178        case OpCodes.Sub: {
    128             var s = Evaluate(state, intervals);
    129             for (int i = 1; i < currentInstr.nArguments; i++) {
    130               s = Interval.Subtract(s, Evaluate(state, intervals));
     179            var s = Evaluate(instructions, intervals);
     180            for (int i = 1; i < currentInstr.nArguments; i++) {
     181              s = Interval.Subtract(s, Evaluate(instructions, intervals));
    131182            }
    132183            intervals.Add(currentInstr.dynamicNode, s);
     
    134185          }
    135186        case OpCodes.Mul: {
    136             var s = Evaluate(state, intervals);
    137             for (int i = 1; i < currentInstr.nArguments; i++) {
    138               s = Interval.Multiply(s, Evaluate(state, intervals));
     187            var s = Evaluate(instructions, intervals);
     188            for (int i = 1; i < currentInstr.nArguments; i++) {
     189              s = Interval.Multiply(s, Evaluate(instructions, intervals));
    139190            }
    140191            intervals.Add(currentInstr.dynamicNode, s);
     
    142193          }
    143194        case OpCodes.Div: {
    144             var s = Evaluate(state, intervals);
    145             for (int i = 1; i < currentInstr.nArguments; i++) {
    146               s = Interval.Divide(s, Evaluate(state, intervals));
     195            var s = Evaluate(instructions, intervals);
     196            for (int i = 1; i < currentInstr.nArguments; i++) {
     197              s = Interval.Divide(s, Evaluate(instructions, intervals));
    147198            }
    148199            intervals.Add(currentInstr.dynamicNode, s);
     
    151202        //Trigonometric functions
    152203        case OpCodes.Sin: {
    153             var s = Interval.Sine(Evaluate(state, intervals));
     204            var s = Interval.Sine(Evaluate(instructions, intervals));
    154205            intervals.Add(currentInstr.dynamicNode, s);
    155206            return s;
    156207          }
    157208        case OpCodes.Cos: {
    158             var s = Interval.Cosine(Evaluate(state, intervals));
     209            var s = Interval.Cosine(Evaluate(instructions, intervals));
    159210            intervals.Add(currentInstr.dynamicNode, s);
    160211            return s;
    161212          }
    162213        case OpCodes.Tan: {
    163             var s = Interval.Tangens(Evaluate(state, intervals));
     214            var s = Interval.Tangens(Evaluate(instructions, intervals));
    164215            intervals.Add(currentInstr.dynamicNode, s);
    165216            return s;
     
    167218        //Exponential functions
    168219        case OpCodes.Log: {
    169             var s = Interval.Logarithm(Evaluate(state, intervals));
     220            var s = Interval.Logarithm(Evaluate(instructions, intervals));
    170221            intervals.Add(currentInstr.dynamicNode, s);
    171222            return s;
    172223          }
    173224        case OpCodes.Exp: {
    174             var s = Interval.Exponential(Evaluate(state, intervals));
     225            var s = Interval.Exponential(Evaluate(instructions, intervals));
    175226            intervals.Add(currentInstr.dynamicNode, s);
    176227            return s;
    177228          }
    178229        case OpCodes.Power: {
    179             var s = Evaluate(state, intervals);
    180             for (int i = 1; i < currentInstr.nArguments; i++) {
    181               s = Interval.Power(s, Evaluate(state, intervals));
     230            var s = Evaluate(instructions, intervals);
     231            for (int i = 1; i < currentInstr.nArguments; i++) {
     232              s = Interval.Power(s, Evaluate(instructions, intervals));
    182233            }
    183234            intervals.Add(currentInstr.dynamicNode, s);
     
    185236          }
    186237        case OpCodes.Square: {
    187             var s = Interval.Square(Evaluate(state, intervals));
     238            var s = Interval.Square(Evaluate(instructions, intervals));
    188239            intervals.Add(currentInstr.dynamicNode, s);
    189240            return s;
    190241          }
    191242        case OpCodes.Root: {
    192             var s = Evaluate(state, intervals);
    193             for (int i = 1; i < currentInstr.nArguments; i++) {
    194               s = Interval.Root(s, Evaluate(state, intervals));
     243            var s = Evaluate(instructions, intervals);
     244            for (int i = 1; i < currentInstr.nArguments; i++) {
     245              s = Interval.Root(s, Evaluate(instructions, intervals));
    195246            }
    196247            intervals.Add(currentInstr.dynamicNode, s);
     
    198249          }
    199250        case OpCodes.SquareRoot: {
    200             var s = Interval.SquareRoot(Evaluate(state, intervals));
     251            var s = Interval.SquareRoot(Evaluate(instructions, intervals));
    201252            intervals.Add(currentInstr.dynamicNode, s);
    202253            return s;
     
    214265          }
    215266        default:
    216           throw new NotSupportedException();
    217       }
     267          throw new NotSupportedException("Tree contains an unknown symbol.");
     268      }
     269    }
     270
     271    public static bool IsCompatible(ISymbolicExpressionTree tree) {
     272      var containsUnknownSyumbol = (
     273        from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
     274        where
     275          !(n.Symbol is StartSymbol) &&
     276          !(n.Symbol is Addition) &&
     277          !(n.Symbol is Subtraction) &&
     278          !(n.Symbol is Multiplication) &&
     279          !(n.Symbol is Division) &&
     280          !(n.Symbol is Sine) &&
     281          !(n.Symbol is Cosine) &&
     282          !(n.Symbol is Tangent) &&
     283          !(n.Symbol is Logarithm) &&
     284          !(n.Symbol is Exponential) &&
     285          !(n.Symbol is Power) &&
     286          !(n.Symbol is Square) &&
     287          !(n.Symbol is Root) &&
     288          !(n.Symbol is SquareRoot) &&
     289          !(n.Symbol is Problems.DataAnalysis.Symbolic.Variable) &&
     290          !(n.Symbol is Constant)
     291        select n).Any();
     292      return !containsUnknownSyumbol;
    218293    }
    219294  }
Note: See TracChangeset for help on using the changeset viewer.