Changeset 3841 for trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs
- Timestamp:
- 05/18/10 11:40:02 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs
r3747 r3841 40 40 public const byte Mul = 3; 41 41 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 }; 48 93 private const int ARGUMENT_STACK_SIZE = 1024; 49 94 … … 81 126 var variableTreeNode = instr.dynamicNode as VariableTreeNode; 82 127 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 } 84 132 return instr; 85 133 } 86 134 87 135 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); 97 140 } 98 141 … … 133 176 return p; 134 177 } 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 } 135 245 case OpCodes.Call: { 136 246 // evaluate sub-trees … … 163 273 return dataset[row, currentInstr.iArg0] * variableTreeNode.Weight; 164 274 } 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 } 165 281 case OpCodes.Constant: { 166 282 var constTreeNode = currentInstr.dynamicNode as ConstantTreeNode; … … 170 286 } 171 287 } 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 } 172 297 } 173 298 }
Note: See TracChangeset
for help on using the changeset viewer.