Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/HL3TreeEvaluator.cs @ 2318

Last change on this file since 2318 was 2226, checked in by gkronber, 15 years ago
  • Added extension method IsAlmost to type double
  • changed evaluation semantics of boolean operations in HL3TreeEvaluator

(#713)

File size: 6.9 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;
23using System.Diagnostics;
24using HeuristicLab.Modeling; // double.IsAlmost extension
25
26namespace HeuristicLab.GP.StructureIdentification {
27  /// <summary>
28  /// Evaluates FunctionTrees recursively by interpretation of the function symbols in each node.
29  /// Not thread-safe!
30  /// </summary>
31  public class HL3TreeEvaluator : TreeEvaluatorBase {
32    protected override double EvaluateBakedCode() {
33      Instr currInstr = codeArr[PC++];
34      switch (currInstr.symbol) {
35        case EvaluatorSymbolTable.VARIABLE: {
36            int row = sampleIndex + currInstr.i_arg1;
37            if (row < 0 || row >= dataset.Rows) throw new InvalidOperationException("Out of range access to dataset row: " + row);
38            else return currInstr.d_arg0 * dataset.GetValue(row, currInstr.i_arg0);
39          }
40        case EvaluatorSymbolTable.CONSTANT: {
41            return currInstr.d_arg0;
42          }
43        case EvaluatorSymbolTable.DIFFERENTIAL: {
44            int row = sampleIndex + currInstr.i_arg1;
45            if (row < 0 || row >= dataset.Rows) throw new InvalidOperationException("Out of range access to dataset row: " + row);
46            else if (row < 1) return 0.0;
47            else {
48              double prevValue = dataset.GetValue(row - 1, currInstr.i_arg0);
49              if (double.IsNaN(prevValue) || double.IsInfinity(prevValue)) return 0.0;
50              else 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            double result = EvaluateBakedCode();
69            for (int i = 1; i < currInstr.arity; i++) {
70              result -= EvaluateBakedCode();
71            }
72            return result;
73          }
74        case EvaluatorSymbolTable.DIVISION: {
75            double result;
76            result = EvaluateBakedCode();
77            for (int i = 1; i < currInstr.arity; i++) {
78              result /= EvaluateBakedCode();
79            }
80            if (double.IsInfinity(result)) return 0.0;
81            else return result;
82          }
83        case EvaluatorSymbolTable.AVERAGE: {
84            double sum = EvaluateBakedCode();
85            for (int i = 1; i < currInstr.arity; i++) {
86              sum += EvaluateBakedCode();
87            }
88            return sum / currInstr.arity;
89          }
90        case EvaluatorSymbolTable.COSINUS: {
91            return Math.Cos(EvaluateBakedCode());
92          }
93        case EvaluatorSymbolTable.SINUS: {
94            return Math.Sin(EvaluateBakedCode());
95          }
96        case EvaluatorSymbolTable.EXP: {
97            return Math.Exp(EvaluateBakedCode());
98          }
99        case EvaluatorSymbolTable.LOG: {
100            return Math.Log(EvaluateBakedCode());
101          }
102        case EvaluatorSymbolTable.POWER: {
103            double x = EvaluateBakedCode();
104            double p = EvaluateBakedCode();
105            return Math.Pow(x, p);
106          }
107        case EvaluatorSymbolTable.SIGNUM: {
108            double value = EvaluateBakedCode();
109            if (double.IsNaN(value)) return double.NaN;
110            else return Math.Sign(value);
111          }
112        case EvaluatorSymbolTable.SQRT: {
113            return Math.Sqrt(EvaluateBakedCode());
114          }
115        case EvaluatorSymbolTable.TANGENS: {
116            return Math.Tan(EvaluateBakedCode());
117          }
118        case EvaluatorSymbolTable.AND: {
119            double result = EvaluateBakedCode();
120            for (int i = 1; i < currInstr.arity; i++) {
121              if (result < 0.0) SkipBakedCode();
122              else {
123                result = EvaluateBakedCode();
124              }
125            }
126            return Math.Sign(result);
127          }
128        case EvaluatorSymbolTable.EQU: {
129            double x = EvaluateBakedCode();
130            double y = EvaluateBakedCode();
131            if (x.IsAlmost(y)) return 1.0; else return -1.0;
132          }
133        case EvaluatorSymbolTable.GT: {
134            double x = EvaluateBakedCode();
135            double y = EvaluateBakedCode();
136            if (x > y) return 1.0;
137            else return -1.0;
138          }
139        case EvaluatorSymbolTable.IFTE: {
140            double condition = EvaluateBakedCode();
141            double result;
142            if (condition < 0.0) {
143              result = EvaluateBakedCode(); SkipBakedCode();
144            } else {
145              SkipBakedCode(); result = EvaluateBakedCode();
146            }
147            return result;
148          }
149        case EvaluatorSymbolTable.LT: {
150            double x = EvaluateBakedCode();
151            double y = EvaluateBakedCode();
152            if (x < y) return 1.0;
153            else return -1.0;
154          }
155        case EvaluatorSymbolTable.NOT: {
156            return -EvaluateBakedCode();
157          }
158        case EvaluatorSymbolTable.OR: {
159            double result = EvaluateBakedCode();
160            for (int i = 1; i < currInstr.arity; i++) {
161              if (result >= 0.0) SkipBakedCode();
162              else {
163                result = EvaluateBakedCode();
164              }
165            }
166            return Math.Sign(result);
167          }
168        case EvaluatorSymbolTable.XOR: {
169            double x = EvaluateBakedCode();
170            double y = EvaluateBakedCode();
171            if (x > y) {
172              double tmp = x;
173              x = y;
174              y = tmp;
175            }
176            // invariant y >= x
177            if (y < 0.0 || x > 0.0) return -1.0;
178            else return 1.0;
179          }
180        default: {
181            throw new NotImplementedException();
182          }
183      }
184    }
185  }
186}
Note: See TracBrowser for help on using the repository browser.