Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3.2/sources/HeuristicLab.GP.StructureIdentification/3.3/HL2TreeEvaluator.cs @ 9426

Last change on this file since 9426 was 2578, checked in by gkronber, 15 years ago

Implemented #824 (Refactor: ITreeEvaluator interface to provide a method that evaluates a tree on a range of samples.)

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    [Obsolete]
34    protected override double EvaluateBakedCode() {
35      Instr currInstr = codeArr[PC++];
36      switch (currInstr.symbol) {
37        case EvaluatorSymbolTable.VARIABLE: {
38            int row = sampleIndex + currInstr.i_arg1;
39            if (row < 0 || row >= dataset.Rows) return double.NaN;
40            else return currInstr.d_arg0 * dataset.GetValue(row, currInstr.i_arg0);
41          }
42        case EvaluatorSymbolTable.CONSTANT: {
43            return currInstr.d_arg0;
44          }
45        case EvaluatorSymbolTable.DIFFERENTIAL: {
46            int row = sampleIndex + currInstr.i_arg1;
47            if (row < 1 || row >= dataset.Rows) return double.NaN;
48            else {
49              double prevValue = dataset.GetValue(row - 1, currInstr.i_arg0);
50              return currInstr.d_arg0 * (dataset.GetValue(row, currInstr.i_arg0) - prevValue);
51            }
52          }
53        case EvaluatorSymbolTable.MULTIPLICATION: {
54            double result = EvaluateBakedCode();
55            for (int i = 1; i < currInstr.arity; i++) {
56              result *= EvaluateBakedCode();
57            }
58            return result;
59          }
60        case EvaluatorSymbolTable.ADDITION: {
61            double sum = EvaluateBakedCode();
62            for (int i = 1; i < currInstr.arity; i++) {
63              sum += EvaluateBakedCode();
64            }
65            return sum;
66          }
67        case EvaluatorSymbolTable.SUBTRACTION: {
68            return EvaluateBakedCode() - EvaluateBakedCode();
69          }
70        case EvaluatorSymbolTable.DIVISION: {
71            double arg0 = EvaluateBakedCode();
72            double arg1 = EvaluateBakedCode();
73            if (double.IsNaN(arg0) || double.IsNaN(arg1)) return double.NaN;
74            if (Math.Abs(arg1) < (10e-20)) return 0.0; else return (arg0 / arg1);
75          }
76        case EvaluatorSymbolTable.COSINUS: {
77            return Math.Cos(EvaluateBakedCode());
78          }
79        case EvaluatorSymbolTable.SINUS: {
80            return Math.Sin(EvaluateBakedCode());
81          }
82        case EvaluatorSymbolTable.EXP: {
83            return Math.Exp(EvaluateBakedCode());
84          }
85        case EvaluatorSymbolTable.LOG: {
86            return Math.Log(EvaluateBakedCode());
87          }
88        case EvaluatorSymbolTable.POWER: {
89            double x = EvaluateBakedCode();
90            double p = EvaluateBakedCode();
91            return Math.Pow(x, p);
92          }
93        case EvaluatorSymbolTable.SIGNUM: {
94            double value = EvaluateBakedCode();
95            if (double.IsNaN(value)) return double.NaN;
96            if (value < 0.0) return -1.0;
97            if (value > 0.0) return 1.0;
98            return 0.0;
99          }
100        case EvaluatorSymbolTable.SQRT: {
101            return Math.Sqrt(EvaluateBakedCode());
102          }
103        case EvaluatorSymbolTable.TANGENS: {
104            return Math.Tan(EvaluateBakedCode());
105          }
106        case EvaluatorSymbolTable.AND: { // only defined for inputs 1 and 0
107            double result = EvaluateBakedCode();
108            bool hasNaNBranch = false;
109            for (int i = 1; i < currInstr.arity; i++) {
110              if (result < 0.5 || double.IsNaN(result)) hasNaNBranch |= double.IsNaN(EvaluateBakedCode());
111              else {
112                result = EvaluateBakedCode();
113              }
114            }
115            if (hasNaNBranch || double.IsNaN(result)) return double.NaN;
116            if (result < 0.5) return 0.0;
117            return 1.0;
118          }
119        case EvaluatorSymbolTable.EQU: {
120            double x = EvaluateBakedCode();
121            double y = EvaluateBakedCode();
122            if (double.IsNaN(x) || double.IsNaN(y)) return double.NaN;
123            // direct comparison of double values is most likely incorrect but
124            // that's the way how it is implemented in the standard HL2 function library
125            if (x == y) return 1.0; else return 0.0;
126          }
127        case EvaluatorSymbolTable.GT: {
128            double x = EvaluateBakedCode();
129            double y = EvaluateBakedCode();
130            if (double.IsNaN(x) || double.IsNaN(y)) return double.NaN;
131            if (x > y) return 1.0;
132            return 0.0;
133          }
134        case EvaluatorSymbolTable.IFTE: { // only defined for condition 0 or 1
135            double condition = EvaluateBakedCode();
136            double result;
137            bool hasNaNBranch = false;
138            if (double.IsNaN(condition)) return double.NaN;
139            if (condition > 0.5) {
140              result = EvaluateBakedCode(); hasNaNBranch = double.IsNaN(EvaluateBakedCode());
141            } else {
142              hasNaNBranch = double.IsNaN(EvaluateBakedCode()); result = EvaluateBakedCode();
143            }
144            if (hasNaNBranch) return double.NaN;
145            return result;
146          }
147        case EvaluatorSymbolTable.LT: {
148            double x = EvaluateBakedCode();
149            double y = EvaluateBakedCode();
150            if (double.IsNaN(x) || double.IsNaN(y)) return double.NaN;
151            if (x < y) return 1.0;
152            return 0.0;
153          }
154        case EvaluatorSymbolTable.NOT: { // only defined for inputs 0 or 1
155            double result = EvaluateBakedCode();
156            if (double.IsNaN(result)) return double.NaN;
157            if (result < 0.5) return 1.0;
158            return 0.0;
159          }
160        case EvaluatorSymbolTable.OR: { // only defined for inputs 0 or 1
161            double result = EvaluateBakedCode();
162            bool hasNaNBranch = false;
163            for (int i = 1; i < currInstr.arity; i++) {
164              if (double.IsNaN(result) || result > 0.5) hasNaNBranch |= double.IsNaN(EvaluateBakedCode());
165              else
166                result = EvaluateBakedCode();
167            }
168            if (hasNaNBranch || double.IsNaN(result)) return double.NaN;
169            if (result > 0.5) return 1.0;
170            return 0.0;
171          }
172        default: {
173            throw new NotImplementedException();
174          }
175      }
176    }
177  }
178}
Note: See TracBrowser for help on using the repository browser.