1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022008 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 


22  using System;


23  using System.Diagnostics;


24  using HeuristicLab.Common; // double.IsAlmost extension


25 


26  namespace HeuristicLab.GP.StructureIdentification {


27  /// <summary>


28  /// Evaluates FunctionTrees recursively by interpretation of the function symbols in each node.


29  /// Not threadsafe!


30  /// </summary>


31  public class HL3TreeEvaluator : TreeEvaluatorBase {


32  public HL3TreeEvaluator() : base() { } // for persistence


33  public HL3TreeEvaluator(double minValue, double maxValue) : base(minValue, maxValue) { }


34 


35  protected override double EvaluateBakedCode() {


36  Instr currInstr = codeArr[PC++];


37  switch (currInstr.symbol) {


38  case EvaluatorSymbolTable.VARIABLE: {


39  int row = sampleIndex + currInstr.i_arg1;


40  if (row < 0  row >= dataset.Rows) throw new ArgumentException("Out of range access to dataset row: " + row);


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;


48  if (row < 0  row >= dataset.Rows) throw new ArgumentException("Out of range access to dataset row: " + row);


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  }


55  }


56  case EvaluatorSymbolTable.MULTIPLICATION: {


57  double result = EvaluateBakedCode();


58  for (int i = 1; i < currInstr.arity; i++) {


59  result *= EvaluateBakedCode();


60  }


61  return result;


62  }


63  case EvaluatorSymbolTable.ADDITION: {


64  double sum = EvaluateBakedCode();


65  for (int i = 1; i < currInstr.arity; i++) {


66  sum += EvaluateBakedCode();


67  }


68  return sum;


69  }


70  case EvaluatorSymbolTable.SUBTRACTION: {


71  double result = EvaluateBakedCode();


72  for (int i = 1; i < currInstr.arity; i++) {


73  result = EvaluateBakedCode();


74  }


75  return result;


76  }


77  case EvaluatorSymbolTable.DIVISION: {


78  double result;


79  result = EvaluateBakedCode();


80  for (int i = 1; i < currInstr.arity; i++) {


81  result /= EvaluateBakedCode();


82  }


83  if (double.IsInfinity(result)) return 0.0;


84  else return result;


85  }


86  case EvaluatorSymbolTable.AVERAGE: {


87  double sum = EvaluateBakedCode();


88  for (int i = 1; i < currInstr.arity; i++) {


89  sum += EvaluateBakedCode();


90  }


91  return sum / currInstr.arity;


92  }


93  case EvaluatorSymbolTable.COSINUS: {


94  return Math.Cos(EvaluateBakedCode());


95  }


96  case EvaluatorSymbolTable.SINUS: {


97  return Math.Sin(EvaluateBakedCode());


98  }


99  case EvaluatorSymbolTable.EXP: {


100  return Math.Exp(EvaluateBakedCode());


101  }


102  case EvaluatorSymbolTable.LOG: {


103  return Math.Log(EvaluateBakedCode());


104  }


105  case EvaluatorSymbolTable.POWER: {


106  double x = EvaluateBakedCode();


107  double p = EvaluateBakedCode();


108  return Math.Pow(x, p);


109  }


110  case EvaluatorSymbolTable.SIGNUM: {


111  double value = EvaluateBakedCode();


112  if (double.IsNaN(value)) return double.NaN;


113  else return Math.Sign(value);


114  }


115  case EvaluatorSymbolTable.SQRT: {


116  return Math.Sqrt(EvaluateBakedCode());


117  }


118  case EvaluatorSymbolTable.TANGENS: {


119  return Math.Tan(EvaluateBakedCode());


120  }


121  case EvaluatorSymbolTable.AND: {


122  double result = EvaluateBakedCode();


123  for (int i = 1; i < currInstr.arity; i++) {


124  if (result < 0.0) SkipBakedCode();


125  else {


126  result = EvaluateBakedCode();


127  }


128  }


129  return Math.Sign(result);


130  }


131  case EvaluatorSymbolTable.EQU: {


132  double x = EvaluateBakedCode();


133  double y = EvaluateBakedCode();


134  if (x.IsAlmost(y)) return 1.0; else return 1.0;


135  }


136  case EvaluatorSymbolTable.GT: {


137  double x = EvaluateBakedCode();


138  double y = EvaluateBakedCode();


139  if (x > y) return 1.0;


140  else return 1.0;


141  }


142  case EvaluatorSymbolTable.IFTE: {


143  double condition = EvaluateBakedCode();


144  double result;


145  if (condition < 0.0) {


146  result = EvaluateBakedCode(); SkipBakedCode();


147  } else {


148  SkipBakedCode(); result = EvaluateBakedCode();


149  }


150  return result;


151  }


152  case EvaluatorSymbolTable.LT: {


153  double x = EvaluateBakedCode();


154  double y = EvaluateBakedCode();


155  if (x < y) return 1.0;


156  else return 1.0;


157  }


158  case EvaluatorSymbolTable.NOT: {


159  return EvaluateBakedCode();


160  }


161  case EvaluatorSymbolTable.OR: {


162  double result = EvaluateBakedCode();


163  for (int i = 1; i < currInstr.arity; i++) {


164  if (result >= 0.0) SkipBakedCode();


165  else {


166  result = EvaluateBakedCode();


167  }


168  }


169  return Math.Sign(result);


170  }


171  case EvaluatorSymbolTable.XOR: {


172  double x = EvaluateBakedCode();


173  double y = EvaluateBakedCode();


174  if (x > y) {


175  double tmp = x;


176  x = y;


177  y = tmp;


178  }


179  // invariant y >= x


180  if (y < 0.0  x > 0.0) return 1.0;


181  else return 1.0;


182  }


183  default: {


184  throw new NotImplementedException();


185  }


186  }


187  }


188  }


189  }

