Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
05/18/10 11:40:02 (14 years ago)
Author:
gkronber
Message:

Extended set of available functions for symbolic regression and added test cases for the extended function set. #1013

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs

    r3747 r3841  
    4040      public const byte Mul = 3;
    4141      public const byte Div = 4;
    42       public const byte Variable = 5;
    43       public const byte Constant = 6;
    44       public const byte Call = 100;
    45       public const byte Arg = 101;
    46     }
    47 
     42
     43      public const byte Sin = 5;
     44      public const byte Cos = 6;
     45      public const byte Tan = 7;
     46
     47      public const byte Log = 8;
     48      public const byte Exp = 9;
     49
     50      public const byte IfThenElse = 10;
     51
     52      public const byte GT = 11;
     53      public const byte LT = 12;
     54
     55      public const byte AND = 13;
     56      public const byte OR = 14;
     57      public const byte NOT = 15;
     58
     59
     60      public const byte Average = 16;
     61
     62      public const byte Call = 17;
     63
     64      public const byte Variable = 18;
     65      public const byte LagVariable = 19;
     66      public const byte Constant = 20;
     67      public const byte Arg = 21;
     68    }
     69
     70    private Dictionary<Type, byte> symbolToOpcode = new Dictionary<Type, byte>() {
     71      { typeof(Addition), OpCodes.Add },
     72      { typeof(Subtraction), OpCodes.Sub },
     73      { typeof(Multiplication), OpCodes.Mul },
     74      { typeof(Division), OpCodes.Div },
     75      { typeof(Sine), OpCodes.Sin },
     76      { typeof(Cosine), OpCodes.Cos },
     77      { typeof(Tangent), OpCodes.Tan },
     78      { typeof(Logarithm), OpCodes.Log },
     79      { typeof(Exponential), OpCodes.Exp },
     80      { typeof(IfThenElse), OpCodes.IfThenElse },
     81      { typeof(GreaterThan), OpCodes.GT },
     82      { typeof(LessThan), OpCodes.LT },
     83      { typeof(And), OpCodes.AND },
     84      { typeof(Or), OpCodes.OR },
     85      { typeof(Not), OpCodes.NOT},
     86      { typeof(Average), OpCodes.Average},
     87      { typeof(InvokeFunction), OpCodes.Call },
     88      { typeof(HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols.Variable), OpCodes.Variable },
     89      { typeof(LaggedVariable), OpCodes.LagVariable },
     90      { typeof(Constant), OpCodes.Constant },
     91      { typeof(Argument), OpCodes.Arg },
     92    };
    4893    private const int ARGUMENT_STACK_SIZE = 1024;
    4994
     
    81126        var variableTreeNode = instr.dynamicNode as VariableTreeNode;
    82127        instr.iArg0 = (ushort)dataset.GetVariableIndex(variableTreeNode.VariableName);
    83       }
     128      } else if (instr.opCode == OpCodes.LagVariable) {
     129        var variableTreeNode = instr.dynamicNode as LaggedVariableTreeNode;
     130        instr.iArg0 = (ushort)dataset.GetVariableIndex(variableTreeNode.VariableName);
     131      }
    84132      return instr;
    85133    }
    86134
    87135    private byte MapSymbolToOpCode(SymbolicExpressionTreeNode treeNode) {
    88       if (treeNode.Symbol is Addition) return OpCodes.Add;
    89       if (treeNode.Symbol is Subtraction) return OpCodes.Sub;
    90       if (treeNode.Symbol is Multiplication) return OpCodes.Mul;
    91       if (treeNode.Symbol is Division) return OpCodes.Div;
    92       if (treeNode.Symbol is HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols.Variable) return OpCodes.Variable;
    93       if (treeNode.Symbol is Constant) return OpCodes.Constant;
    94       if (treeNode.Symbol is InvokeFunction) return OpCodes.Call;
    95       if (treeNode.Symbol is Argument) return OpCodes.Arg;
    96       throw new NotSupportedException("Symbol: " + treeNode.Symbol);
     136      if (symbolToOpcode.ContainsKey(treeNode.Symbol.GetType()))
     137        return symbolToOpcode[treeNode.Symbol.GetType()];
     138      else
     139        throw new NotSupportedException("Symbol: " + treeNode.Symbol);
    97140    }
    98141
     
    133176            return p;
    134177          }
     178        case OpCodes.Average: {
     179            double sum = Evaluate();
     180            for (int i = 1; i < currentInstr.nArguments; i++) {
     181              sum += Evaluate();
     182            }
     183            return sum / currentInstr.nArguments;
     184          }
     185        case OpCodes.Cos: {
     186            return Math.Cos(Evaluate());
     187          }
     188        case OpCodes.Sin: {
     189            return Math.Sin(Evaluate());
     190          }
     191        case OpCodes.Tan: {
     192            return Math.Tan(Evaluate());
     193          }
     194        case OpCodes.Exp: {
     195            return Math.Exp(Evaluate());
     196          }
     197        case OpCodes.Log: {
     198            return Math.Log(Evaluate());
     199          }
     200        case OpCodes.IfThenElse: {
     201            double condition = Evaluate();
     202            double result;
     203            if (condition > 0.0) {
     204              result = Evaluate(); SkipBakedCode();
     205            } else {
     206              SkipBakedCode(); result = Evaluate();
     207            }
     208            return result;
     209          }
     210        case OpCodes.AND: {
     211            double result = Evaluate();
     212            for (int i = 1; i < currentInstr.nArguments; i++) {
     213              if (result <= 0.0) SkipBakedCode();
     214              else {
     215                result = Evaluate();
     216              }
     217            }
     218            return result <= 0.0 ? -1.0 : 1.0;
     219          }
     220        case OpCodes.OR: {
     221            double result = Evaluate();
     222            for (int i = 1; i < currentInstr.nArguments; i++) {
     223              if (result > 0.0) SkipBakedCode();
     224              else {
     225                result = Evaluate();
     226              }
     227            }
     228            return result > 0.0 ? 1.0 : -1.0;
     229          }
     230        case OpCodes.NOT: {
     231            return -Evaluate();
     232          }
     233        case OpCodes.GT: {
     234            double x = Evaluate();
     235            double y = Evaluate();
     236            if (x > y) return 1.0;
     237            else return -1.0;
     238          }
     239        case OpCodes.LT: {
     240            double x = Evaluate();
     241            double y = Evaluate();
     242            if (x < y) return 1.0;
     243            else return -1.0;
     244          }
    135245        case OpCodes.Call: {
    136246            // evaluate sub-trees
     
    163273            return dataset[row, currentInstr.iArg0] * variableTreeNode.Weight;
    164274          }
     275        case OpCodes.LagVariable: {
     276            var lagVariableTreeNode = currentInstr.dynamicNode as LaggedVariableTreeNode;
     277            int actualRow = row + lagVariableTreeNode.Lag;
     278            if (actualRow < 0 || actualRow >= dataset.Rows) throw new ArgumentException("Out of range access to dataset row: " + row);
     279            return dataset[actualRow, currentInstr.iArg0] * lagVariableTreeNode.Weight;
     280          }
    165281        case OpCodes.Constant: {
    166282            var constTreeNode = currentInstr.dynamicNode as ConstantTreeNode;
     
    170286      }
    171287    }
     288
     289    // skips a whole branch
     290    protected void SkipBakedCode() {
     291      int i = 1;
     292      while (i > 0) {
     293        i += code[pc++].nArguments;
     294        i--;
     295      }
     296    }
    172297  }
    173298}
Note: See TracChangeset for help on using the changeset viewer.