Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 2449 was 2449, checked in by gkronber, 14 years ago

Fixed minor evaluation inconsistencies in HL3 tree evaluator. #791

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