Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Persistence Test/HeuristicLab.GP.StructureIdentification/3.3/HL2TreeEvaluator.cs @ 2594

Last change on this file since 2594 was 2328, checked in by gkronber, 15 years ago

this is the remaining part of changeset r2327.
Applied changes in modeling plugins that are necessary for the new model analyzer (#722)

  • predictor has properties for the lower and upper limit of the predicted value
  • added views for predictors that show the limits (also added a new view for GeneticProgrammingModel that shows the size and height of the model)
  • Reintroduced TreeEvaluatorInjectors that read a PunishmentFactor and calculate the lower and upper limits for estimated values (limits are set in the tree evaluators)
  • Added operators to create Predictors. Changed modeling algorithms to use the predictors for the calculation of final model qualities and variable impacts (to be compatible with the new model analyzer the predictors use a very large PunishmentFactor)
  • replaced all private implementations of double.IsAlmost and use HL.Commons instead (see #733 r2324)
  • Implemented operator SolutionExtractor and moved BestSolutionStorer from HL.Logging to HL.Modeling (fixes #734)
File size: 7.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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;
23
24namespace HeuristicLab.GP.StructureIdentification {
25  /// <summary>
26  /// Evaluates FunctionTrees recursively by interpretation of the function symbols in each node with HL2 semantics.
27  /// Not thread-safe!
28  /// </summary>
29  public class HL2TreeEvaluator : TreeEvaluatorBase {
30    public HL2TreeEvaluator() : base() { } // for persistence
31    public HL2TreeEvaluator(double minValue, double maxValue) : base(minValue, maxValue) { }
32
33    protected override double EvaluateBakedCode() {
34      Instr currInstr = codeArr[PC++];
35      switch (currInstr.symbol) {
36        case EvaluatorSymbolTable.VARIABLE: {
37            int row = sampleIndex + currInstr.i_arg1;
38            if (row < 0 || row >= dataset.Rows) return double.NaN;
39            else return currInstr.d_arg0 * dataset.GetValue(row, currInstr.i_arg0);
40          }
41        case EvaluatorSymbolTable.CONSTANT: {
42            return currInstr.d_arg0;
43          }
44        case EvaluatorSymbolTable.DIFFERENTIAL: {
45            int row = sampleIndex + currInstr.i_arg1;
46            if (row < 1 || row >= dataset.Rows) return double.NaN;
47            else {
48              double prevValue = dataset.GetValue(row - 1, currInstr.i_arg0);
49              return currInstr.d_arg0 * (dataset.GetValue(row, currInstr.i_arg0) - prevValue);
50            }
51          }
52        case EvaluatorSymbolTable.MULTIPLICATION: {
53            double result = EvaluateBakedCode();
54            for (int i = 1; i < currInstr.arity; i++) {
55              result *= EvaluateBakedCode();
56            }
57            return result;
58          }
59        case EvaluatorSymbolTable.ADDITION: {
60            double sum = EvaluateBakedCode();
61            for (int i = 1; i < currInstr.arity; i++) {
62              sum += EvaluateBakedCode();
63            }
64            return sum;
65          }
66        case EvaluatorSymbolTable.SUBTRACTION: {
67            return EvaluateBakedCode() - EvaluateBakedCode();
68          }
69        case EvaluatorSymbolTable.DIVISION: {
70            double arg0 = EvaluateBakedCode();
71            double arg1 = EvaluateBakedCode();
72            if (double.IsNaN(arg0) || double.IsNaN(arg1)) return double.NaN;
73            if (Math.Abs(arg1) < (10e-20)) return 0.0; else return (arg0 / arg1);
74          }
75        case EvaluatorSymbolTable.COSINUS: {
76            return Math.Cos(EvaluateBakedCode());
77          }
78        case EvaluatorSymbolTable.SINUS: {
79            return Math.Sin(EvaluateBakedCode());
80          }
81        case EvaluatorSymbolTable.EXP: {
82            return Math.Exp(EvaluateBakedCode());
83          }
84        case EvaluatorSymbolTable.LOG: {
85            return Math.Log(EvaluateBakedCode());
86          }
87        case EvaluatorSymbolTable.POWER: {
88            double x = EvaluateBakedCode();
89            double p = EvaluateBakedCode();
90            return Math.Pow(x, p);
91          }
92        case EvaluatorSymbolTable.SIGNUM: {
93            double value = EvaluateBakedCode();
94            if (double.IsNaN(value)) return double.NaN;
95            if (value < 0.0) return -1.0;
96            if (value > 0.0) return 1.0;
97            return 0.0;
98          }
99        case EvaluatorSymbolTable.SQRT: {
100            return Math.Sqrt(EvaluateBakedCode());
101          }
102        case EvaluatorSymbolTable.TANGENS: {
103            return Math.Tan(EvaluateBakedCode());
104          }
105        case EvaluatorSymbolTable.AND: { // only defined for inputs 1 and 0
106            double result = EvaluateBakedCode();
107            bool hasNaNBranch = false;
108            for (int i = 1; i < currInstr.arity; i++) {
109              if (result < 0.5 || double.IsNaN(result)) hasNaNBranch |= double.IsNaN(EvaluateBakedCode());
110              else {
111                result = EvaluateBakedCode();
112              }
113            }
114            if (hasNaNBranch || double.IsNaN(result)) return double.NaN;
115            if (result < 0.5) return 0.0;
116            return 1.0;
117          }
118        case EvaluatorSymbolTable.EQU: {
119            double x = EvaluateBakedCode();
120            double y = EvaluateBakedCode();
121            if (double.IsNaN(x) || double.IsNaN(y)) return double.NaN;
122            // direct comparison of double values is most likely incorrect but
123            // that's the way how it is implemented in the standard HL2 function library
124            if (x == y) return 1.0; else return 0.0;
125          }
126        case EvaluatorSymbolTable.GT: {
127            double x = EvaluateBakedCode();
128            double y = EvaluateBakedCode();
129            if (double.IsNaN(x) || double.IsNaN(y)) return double.NaN;
130            if (x > y) return 1.0;
131            return 0.0;
132          }
133        case EvaluatorSymbolTable.IFTE: { // only defined for condition 0 or 1
134            double condition = EvaluateBakedCode();
135            double result;
136            bool hasNaNBranch = false;
137            if (double.IsNaN(condition)) return double.NaN;
138            if (condition > 0.5) {
139              result = EvaluateBakedCode(); hasNaNBranch = double.IsNaN(EvaluateBakedCode());
140            } else {
141              hasNaNBranch = double.IsNaN(EvaluateBakedCode()); result = EvaluateBakedCode();
142            }
143            if (hasNaNBranch) return double.NaN;
144            return result;
145          }
146        case EvaluatorSymbolTable.LT: {
147            double x = EvaluateBakedCode();
148            double y = EvaluateBakedCode();
149            if (double.IsNaN(x) || double.IsNaN(y)) return double.NaN;
150            if (x < y) return 1.0;
151            return 0.0;
152          }
153        case EvaluatorSymbolTable.NOT: { // only defined for inputs 0 or 1
154            double result = EvaluateBakedCode();
155            if (double.IsNaN(result)) return double.NaN;
156            if (result < 0.5) return 1.0;
157            return 0.0;
158          }
159        case EvaluatorSymbolTable.OR: { // only defined for inputs 0 or 1
160            double result = EvaluateBakedCode();
161            bool hasNaNBranch = false;
162            for (int i = 1; i < currInstr.arity; i++) {
163              if (double.IsNaN(result) || result > 0.5) hasNaNBranch |= double.IsNaN(EvaluateBakedCode());
164              else
165                result = EvaluateBakedCode();
166            }
167            if (hasNaNBranch || double.IsNaN(result)) return double.NaN;
168            if (result > 0.5) return 1.0;
169            return 0.0;
170          }
171        default: {
172            throw new NotImplementedException();
173          }
174      }
175    }
176  }
177}
Note: See TracBrowser for help on using the repository browser.