source: branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Intervalnterpreter.cs @ 16326

Last change on this file since 16326 was 16326, checked in by mkommend, 3 years ago

#2966: Corrected namespace of intervals.

File size: 8.8 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using HeuristicLab.Common;
5using HeuristicLab.Core;
6using HeuristicLab.Data;
7using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
8using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
9using HeuristicLab.Problems.DataAnalysis;
10using HeuristicLab.Problems.DataAnalysis.Symbolic;
11
12namespace HeuristicLab.Algorithms.DataAnalysis.KnowledgeIntegration.Interpreter {
13  [StorableClass]
14  [Item("SymbolicDataAnalysisIntervalArithmeticInterpreter", "Interpreter for interval arithmetic within symbolic regression.")]
15  public class IntervalInterpreter : ParameterizedNamedItem{
16    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
17    public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter {
18      get { return (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
19    }
20
21    public int EvaluatedSolutions {
22      get { return EvaluatedSolutionsParameter.Value.Value; }
23      set { EvaluatedSolutionsParameter.Value.Value = value; }
24    }
25
26    public void ClearState() { }
27
28    protected IntervalInterpreter(bool deserializing) : base(deserializing) { }
29
30    protected IntervalInterpreter(IntervalInterpreter original,
31        Cloner cloner)
32        : base(original, cloner) { }
33
34    public IntervalInterpreter()
35        : base("SymbolicDataAnalysisIntervalArithmeticInterpreter", "Interpreter for interval arithmetic within symbolic regression.") { }
36
37    public override IDeepCloneable Clone(Cloner cloner) {
38      return new IntervalInterpreter(this, cloner);
39    }
40
41    private readonly object syncRoot = new object();
42
43    private static InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree,
44      IEnumerable<int> rows, IDataset dataset = null, Dictionary<string, Interval> customIntervals = null) {
45      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
46      int necessaryArgStackSize = 0;
47     
48      foreach(Instruction instr in code) {
49        if (instr.opCode == OpCodes.Variable) {
50          var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
51          IList<double> values = new List<double>();
52
53          if (dataset != null && customIntervals != null) {
54            if (customIntervals.ContainsKey(variableTreeNode.VariableName)) {
55              instr.data = customIntervals[variableTreeNode.VariableName];
56            } else {
57              foreach (var rowEnum in rows) {
58                values.Add(dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName)[rowEnum]);
59              }
60              instr.data = new Interval(values.Min(), values.Max());
61            }
62          } else if (dataset != null) {
63             foreach (var rowEnum in rows) {
64              values.Add(dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName)[rowEnum]);
65            }
66            instr.data = new Interval(values.Min(), values.Max());
67          } else if (customIntervals != null) {
68            if (customIntervals.ContainsKey(variableTreeNode.VariableName)) {
69              instr.data = customIntervals[variableTreeNode.VariableName];
70            }
71          } else {
72            throw new Exception("No valid input for variables!");
73          }
74        }
75      }
76
77      return new InterpreterState(code, necessaryArgStackSize);
78    }
79
80    private Interval Evaluate(InterpreterState state, Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
81      Instruction currentInstr = state.NextInstruction();
82      switch (currentInstr.opCode) {
83        //Elementary arithmetic rules
84        case OpCodes.Add: {
85            var s = Evaluate(state, intervals);
86            for (int i = 1; i < currentInstr.nArguments; i++) {
87              s = Interval.Add(s, Evaluate(state, intervals));
88            }
89            intervals.Add(currentInstr.dynamicNode, s);
90            return s;
91          }
92        case OpCodes.Sub: {
93            var s = Evaluate(state, intervals);
94            for (int i = 1; i < currentInstr.nArguments; i++) {
95              s = Interval.Subtract(s, Evaluate(state, intervals));
96            }
97            intervals.Add(currentInstr.dynamicNode, s);
98            return s;
99          }
100        case OpCodes.Mul: {
101            var s = Evaluate(state, intervals);
102            for (int i = 1; i < currentInstr.nArguments; i++) {
103              s = Interval.Multiply(s, Evaluate(state, intervals));
104            }
105            intervals.Add(currentInstr.dynamicNode, s);
106            return s;
107          }
108        case OpCodes.Div: {
109            var s = Evaluate(state, intervals);
110            for (int i = 1; i < currentInstr.nArguments; i++) {
111              s = Interval.Divide(s, Evaluate(state, intervals));
112            }
113            intervals.Add(currentInstr.dynamicNode, s);
114            return s;
115          }
116        //Trigonometric functions
117        case OpCodes.Sin: {
118            var s = Interval.Sine(Evaluate(state, intervals));
119            intervals.Add(currentInstr.dynamicNode, s);
120            return s;
121          }
122        case OpCodes.Cos: {
123            var s = Interval.Cosine(Evaluate(state, intervals));
124            intervals.Add(currentInstr.dynamicNode, s);
125            return s;
126          }
127        case OpCodes.Tan: {
128            var s = Interval.Tangens(Evaluate(state, intervals));
129            intervals.Add(currentInstr.dynamicNode, s);
130            return s;
131          }
132        //Exponential functions
133        case OpCodes.Log: {
134            var s = Interval.Logarithm(Evaluate(state, intervals));
135            intervals.Add(currentInstr.dynamicNode, s);
136            return s;
137          }
138        case OpCodes.Exp: {
139            var s = Interval.Exponential(Evaluate(state, intervals));
140            intervals.Add(currentInstr.dynamicNode, s);
141            return s;
142          }
143        case OpCodes.Power: {
144            var s = Evaluate(state, intervals);
145            for (int i = 1; i < currentInstr.nArguments; i++) {
146              s = Interval.Power(s, Evaluate(state, intervals));
147            }
148            intervals.Add(currentInstr.dynamicNode, s);
149            return s;
150          }
151        case OpCodes.Square: {
152            var s = Interval.Square(Evaluate(state, intervals));
153            intervals.Add(currentInstr.dynamicNode, s);
154            return s;
155          }
156        case OpCodes.Root: {
157            var s = Evaluate(state, intervals);
158            for (int i = 1; i < currentInstr.nArguments; i++) {
159              s = Interval.Root(s, Evaluate(state, intervals));
160            }
161            intervals.Add(currentInstr.dynamicNode, s);
162            return s;
163          }
164        case OpCodes.SquareRoot: {
165            var s = Interval.SquareRoot(Evaluate(state, intervals));
166            intervals.Add(currentInstr.dynamicNode, s);
167            return s;
168          }
169        //Variables, Constants, ...
170        case OpCodes.Variable: {
171            intervals.Add(currentInstr.dynamicNode, (Interval)currentInstr.data);
172            return (Interval)currentInstr.data;
173          }
174        case OpCodes.Constant: {
175            var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode;
176            var inter = new Interval(constTreeNode.Value, constTreeNode.Value);
177            intervals.Add(currentInstr.dynamicNode, inter);
178            return inter;
179          }
180        default:
181          throw new NotSupportedException();
182      }
183    }
184
185    public void InitializeState() {
186      EvaluatedSolutions = 0;
187    }
188
189    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IEnumerable<int> rows, out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
190      intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
191      var state = PrepareInterpreterState(tree, rows);
192      var x = Evaluate(state, intervals);
193
194      return x;
195    }
196
197    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows,
198      Dictionary<string, Interval> customIntervals, out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
199      intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
200      var state = PrepareInterpreterState(tree, rows, dataset, customIntervals);
201      var x = Evaluate(state, intervals);
202
203      return x;
204    }
205
206    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows,
207      out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
208      intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
209      var state = PrepareInterpreterState(tree, rows, dataset);
210      var x = Evaluate(state, intervals);
211     
212      return x;
213    }
214  }
215}
Note: See TracBrowser for help on using the repository browser.