Changeset 13222
- Timestamp:
- 11/17/15 16:21:29 (9 years ago)
- Location:
- branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs
r13141 r13222 22 22 using System; 23 23 using System.Collections.Generic; 24 using System.Collections.ObjectModel;25 24 using System.Linq; 26 25 using System.Linq.Expressions; … … 38 37 public sealed class SymbolicDataAnalysisExpressionCompiledTreeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter { 39 38 private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic"; 39 private const string CheckExpressionsWithIntervalArithmeticParameterDescription = "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression."; 40 40 private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions"; 41 41 … … 62 62 #endregion 63 63 64 private static readonly Func<ReadOnlyCollection<double>, IList<double>> ReadOnlyCollectionRetrieveList = GetField<ReadOnlyCollection<double>, IList<double>>("list"); // retrieve underlying field of type IList<double> from a ReadOnlyCollection<double>65 private static readonly Func<List<double>, double[]> ListRetrieveItems = GetField<List<double>, double[]>("_items"); // retrieve underlying field of type double[] from a List<double>66 private static MethodInfo listGetValue = typeof(IList<double>).GetProperty("Item", new Type[] { typeof(int) }).GetGetMethod();67 68 64 public override bool CanChangeName { get { return false; } } 69 70 65 public override bool CanChangeDescription { get { return false; } } 71 66 … … 106 101 public SymbolicDataAnalysisExpressionCompiledTreeInterpreter() : 107 102 base("SymbolicDataAnalysisExpressionCompiledTreeInterpreter", "Interpreter which compiles the tree into a lambda") { 108 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, 109 "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 103 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, CheckExpressionsWithIntervalArithmeticParameterDescription, new BoolValue(false))); 110 104 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 111 105 } … … 113 107 public SymbolicDataAnalysisExpressionCompiledTreeInterpreter(string name, string description) : 114 108 base(name, description) { 115 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, 116 "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 109 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, CheckExpressionsWithIntervalArithmeticParameterDescription, new BoolValue(false))); 117 110 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 118 }119 120 [StorableHook(HookType.AfterDeserialization)]121 private void AfterDeserialization() {122 Parameters.Remove(EvaluatedSolutionsParameterName);123 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));124 125 Parameters.Remove(CheckExpressionsWithIntervalArithmeticParameterName);126 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName,127 "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));128 111 } 129 112 … … 132 115 } 133 116 134 public void ClearState() { 135 } 117 public void ClearState() { } 136 118 137 119 public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) { … … 142 124 EvaluatedSolutions++; // increment the evaluated solutions counter 143 125 } 144 // var columns = dataset.DoubleVariables.Select(x => ListRetrieveItems((List<double>)ReadOnlyCollectionRetrieveList(dataset.GetReadOnlyDoubleValues(x)))).ToArray(); 145 var columns = dataset.DoubleVariables.Select(x => (List<double>)dataset.GetDoubleValues(x)).ToArray(); 126 var columns = dataset.DoubleVariables.Select(x => (IList<double>)dataset.GetReadOnlyDoubleValues(x)).ToArray(); 146 127 var compiled = CompileTree(tree, dataset); 147 128 return rows.Select(x => compiled(x, columns)); 148 129 } 149 130 150 public static Func<int, List<double>[], double> CompileTree(ISymbolicExpressionTree tree, IDataset dataset) {131 public static Func<int, IList<double>[], double> CompileTree(ISymbolicExpressionTree tree, IDataset dataset) { 151 132 var row = Expression.Parameter(typeof(int)); 152 var columns = Expression.Parameter(typeof( List<double>[]));133 var columns = Expression.Parameter(typeof(IList<double>[])); 153 134 var variableIndices = dataset.DoubleVariables.Select((x, i) => new { x, i }).ToDictionary(e => e.x, e => e.i); 154 135 var expr = MakeExpr(tree, variableIndices, row, columns); 155 var lambda = Expression.Lambda<Func<int, List<double>[], double>>(expr, row, columns);136 var lambda = Expression.Lambda<Func<int, IList<double>[], double>>(expr, row, columns); 156 137 return lambda.Compile(); 157 138 } … … 162 143 } 163 144 145 private static readonly PropertyInfo Indexer = typeof(IList<double>).GetProperty("Item"); 164 146 private static Expression MakeExpr(ISymbolicExpressionTreeNode node, Dictionary<string, int> variableIndices, Expression row, Expression columns) { 165 147 var opcode = OpCodes.MapSymbolToOpCode(node); 166 148 #region switch opcode 167 149 switch (opcode) { 168 case OpCodes.Constant: 169 { 150 case OpCodes.Constant: { 170 151 var constantTreeNode = (ConstantTreeNode)node; 171 152 return Expression.Constant(constantTreeNode.Value); 172 153 } 173 case OpCodes.Variable: 174 { 154 case OpCodes.Variable: { 175 155 var variableTreeNode = (VariableTreeNode)node; 176 156 var variableWeight = Expression.Constant(variableTreeNode.Weight); … … 178 158 var indexExpr = Expression.Constant(variableIndices[variableName]); 179 159 var valuesExpr = Expression.ArrayIndex(columns, indexExpr); 180 var variableValue = Expression.ArrayIndex(Expression.Field(valuesExpr, "_items"), row); 181 // var variableValue = Expression.Property(valuesExpr, Indexer, row); 160 var variableValue = Expression.Property(valuesExpr, Indexer, row); 182 161 return Expression.Multiply(variableWeight, variableValue); 183 162 } 184 case OpCodes.Add: 185 { 163 case OpCodes.Add: { 186 164 Expression result = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 187 165 for (int i = 1; i < node.SubtreeCount; ++i) { … … 190 168 return result; 191 169 } 192 case OpCodes.Sub: 193 { 170 case OpCodes.Sub: { 194 171 Expression result = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 195 172 if (node.SubtreeCount == 1) … … 200 177 return result; 201 178 } 202 case OpCodes.Mul: 203 { 179 case OpCodes.Mul: { 204 180 Expression result = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 205 181 for (int i = 1; i < node.SubtreeCount; ++i) { … … 208 184 return result; 209 185 } 210 case OpCodes.Div: 211 { 186 case OpCodes.Div: { 212 187 Expression result = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 213 188 if (node.SubtreeCount == 1) … … 218 193 return result; 219 194 } 220 case OpCodes.Average: 221 { 195 case OpCodes.Average: { 222 196 Expression result = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 223 197 for (int i = 1; i < node.SubtreeCount; ++i) { … … 226 200 return Expression.Divide(result, Expression.Constant((double)node.SubtreeCount)); 227 201 } 228 case OpCodes.Cos: 229 { 202 case OpCodes.Cos: { 230 203 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 231 204 return Expression.Call(Cos, arg); 232 205 } 233 case OpCodes.Sin: 234 { 206 case OpCodes.Sin: { 235 207 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 236 208 return Expression.Call(Sin, arg); 237 209 } 238 case OpCodes.Tan: 239 { 210 case OpCodes.Tan: { 240 211 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 241 212 return Expression.Call(Tan, arg); 242 213 } 243 case OpCodes.Square: 244 { 214 case OpCodes.Square: { 245 215 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 246 216 return Expression.Power(arg, Expression.Constant(2)); 247 217 } 248 case OpCodes.Power: 249 { 218 case OpCodes.Power: { 250 219 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 251 220 var power = MakeExpr(node.GetSubtree(1), variableIndices, row, columns); 252 221 return Expression.Power(arg, Expression.Call(Floor, power)); 253 222 } 254 case OpCodes.SquareRoot: 255 { 223 case OpCodes.SquareRoot: { 256 224 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 257 225 return Expression.Call(Sqrt, arg); 258 226 } 259 case OpCodes.Root: 260 { 227 case OpCodes.Root: { 261 228 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 262 229 var power = MakeExpr(node.GetSubtree(1), variableIndices, row, columns); 263 230 return Expression.Power(arg, Expression.Divide(Expression.Constant(1.0), power)); 264 231 } 265 case OpCodes.Exp: 266 { 232 case OpCodes.Exp: { 267 233 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 268 234 return Expression.Call(Exp, arg); 269 235 } 270 case OpCodes.Log: 271 { 236 case OpCodes.Log: { 272 237 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 273 238 return Expression.Call(Log, arg); 274 239 } 275 case OpCodes.Gamma: 276 { 240 case OpCodes.Gamma: { 277 241 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 278 242 var isNaN = Expression.Call(IsNaN, arg); … … 291 255 return expr; 292 256 } 293 case OpCodes.Psi: 294 { 257 case OpCodes.Psi: { 295 258 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 296 259 var isNaN = Expression.Call(IsNaN, arg); … … 314 277 return expr; 315 278 } 316 case OpCodes.Dawson: 317 { 279 case OpCodes.Dawson: { 318 280 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 319 281 var isNaN = Expression.Call(IsNaN, arg); … … 331 293 return expr; 332 294 } 333 case OpCodes.ExponentialIntegralEi: 334 { 295 case OpCodes.ExponentialIntegralEi: { 335 296 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 336 297 var isNaN = Expression.Call(IsNaN, arg); … … 348 309 return expr; 349 310 } 350 case OpCodes.SineIntegral: 351 { 311 case OpCodes.SineIntegral: { 352 312 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 353 313 var isNaN = Expression.Call(IsNaN, arg); … … 370 330 return expr; 371 331 } 372 case OpCodes.CosineIntegral: 373 { 332 case OpCodes.CosineIntegral: { 374 333 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 375 334 var isNaN = Expression.Call(IsNaN, arg); … … 392 351 return expr; 393 352 } 394 case OpCodes.HyperbolicSineIntegral: 395 { 353 case OpCodes.HyperbolicSineIntegral: { 396 354 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 397 355 var isNaN = Expression.Call(IsNaN, arg); … … 414 372 return expr; 415 373 } 416 case OpCodes.HyperbolicCosineIntegral: 417 { 374 case OpCodes.HyperbolicCosineIntegral: { 418 375 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 419 376 var isNaN = Expression.Call(IsNaN, arg); … … 436 393 return expr; 437 394 } 438 case OpCodes.FresnelSineIntegral: 439 { 395 case OpCodes.FresnelSineIntegral: { 440 396 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 441 397 var isNaN = Expression.Call(IsNaN, arg); … … 454 410 return expr; 455 411 } 456 case OpCodes.FresnelCosineIntegral: 457 { 412 case OpCodes.FresnelCosineIntegral: { 458 413 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 459 414 var isNaN = Expression.Call(IsNaN, arg); … … 472 427 return expr; 473 428 } 474 case OpCodes.AiryA: 475 { 429 case OpCodes.AiryA: { 476 430 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 477 431 var isNaN = Expression.Call(IsNaN, arg); … … 492 446 return expr; 493 447 } 494 case OpCodes.AiryB: 495 { 448 case OpCodes.AiryB: { 496 449 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 497 450 var isNaN = Expression.Call(IsNaN, arg); … … 512 465 return expr; 513 466 } 514 case OpCodes.Norm: 515 { 467 case OpCodes.Norm: { 516 468 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 517 469 var isNaN = Expression.Call(IsNaN, arg); … … 525 477 return expr; 526 478 } 527 case OpCodes.Erf: 528 { 479 case OpCodes.Erf: { 529 480 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 530 481 var isNaN = Expression.Call(IsNaN, arg); … … 538 489 return expr; 539 490 } 540 case OpCodes.Bessel: 541 { 491 case OpCodes.Bessel: { 542 492 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 543 493 var isNaN = Expression.Call(IsNaN, arg); … … 554 504 return expr; 555 505 } 556 case OpCodes.IfThenElse: 557 { 506 case OpCodes.IfThenElse: { 558 507 var test = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 559 508 var result = Expression.Variable(typeof(double)); … … 563 512 return Expression.Block(new[] { result }, condition, result); 564 513 } 565 case OpCodes.AND: 566 { 514 case OpCodes.AND: { 567 515 var result = Expression.Variable(typeof(double)); 568 516 var expr = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); … … 589 537 ); 590 538 } 591 case OpCodes.OR: 592 { 539 case OpCodes.OR: { 593 540 var result = Expression.Variable(typeof(double)); 594 541 var expr = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); … … 615 562 ); 616 563 } 617 case OpCodes.NOT: 618 { 564 case OpCodes.NOT: { 619 565 var value = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 620 566 var result = Expression.Variable(typeof(double)); … … 624 570 return Expression.Block(new[] { result }, condition, result); 625 571 } 626 case OpCodes.XOR: 627 { 572 case OpCodes.XOR: { 628 573 var ps = Expression.Variable(typeof(int)); 629 574 var block = Expression.Block( … … 656 601 return xorExpr; 657 602 } 658 case OpCodes.GT: 659 { 603 case OpCodes.GT: { 660 604 var left = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 661 605 var right = MakeExpr(node.GetSubtree(1), variableIndices, row, columns); … … 669 613 result); 670 614 } 671 case OpCodes.LT: 672 { 615 case OpCodes.LT: { 673 616 var left = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 674 617 var right = MakeExpr(node.GetSubtree(1), variableIndices, row, columns); … … 679 622 return Expression.Block(new[] { result }, condition, result); 680 623 } 681 case OpCodes.VariableCondition: 682 { 624 case OpCodes.VariableCondition: { 683 625 var variableConditionTreeNode = (VariableConditionTreeNode)node; 684 626 var variableName = variableConditionTreeNode.VariableName; … … 700 642 ); 701 643 } 702 case OpCodes.LagVariable: 703 { 644 case OpCodes.LagVariable: { 704 645 var laggedVariableTreeNode = (LaggedVariableTreeNode)node; 705 646 var lag = Expression.Constant(laggedVariableTreeNode.Lag); … … 708 649 var indexExpr = Expression.Constant(variableIndices[variableName]); 709 650 var valuesExpr = Expression.ArrayIndex(columns, indexExpr); 710 var variableValue = Expression. ArrayIndex(Expression.Field(valuesExpr, "_items"), Expression.Add(row, lag));651 var variableValue = Expression.Property(valuesExpr, Indexer, Expression.Add(row, lag)); 711 652 return Expression.Multiply(variableWeight, variableValue); 712 653 } 713 case OpCodes.TimeLag: 714 { 654 case OpCodes.TimeLag: { 715 655 var timeLagTreeNode = (LaggedTreeNode)node; 716 656 var lag = Expression.Constant(timeLagTreeNode.Lag); 717 657 return MakeExpr(timeLagTreeNode.GetSubtree(0), variableIndices, Expression.Add(row, lag), columns); 718 658 } 719 case OpCodes.Integral: 720 { 659 case OpCodes.Integral: { 721 660 var timeLagTreeNode = (LaggedTreeNode)node; 722 661 var subtree = node.GetSubtree(0); … … 730 669 return sum; 731 670 } 732 case OpCodes.Derivative: 733 { 671 case OpCodes.Derivative: { 734 672 var subtree = node.GetSubtree(0); 735 673 var f0 = MakeExpr(subtree, variableIndices, row, columns); -
branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs
r13141 r13222 69 69 70 70 private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic"; 71 private const string CheckExpressionsWithIntervalArithmeticParameterDescription = "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression."; 71 72 private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions"; 72 73 … … 124 125 [StorableHook(HookType.AfterDeserialization)] 125 126 private void AfterDeserialization() { 126 Parameters.Remove(EvaluatedSolutionsParameterName); 127 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 128 129 Parameters.Remove(CheckExpressionsWithIntervalArithmeticParameterName); 130 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, 131 "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 127 var evaluatedSolutions = new IntValue(0); 128 var checkExpressionsWithIntervalArithmetic = new BoolValue(false); 129 if (Parameters.ContainsKey(EvaluatedSolutionsParameterName)) { 130 var evaluatedSolutionsParameter = (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; 131 evaluatedSolutions = evaluatedSolutionsParameter.Value; 132 Parameters.Remove(EvaluatedSolutionsParameterName); 133 } 134 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", evaluatedSolutions)); 135 if (Parameters.ContainsKey(CheckExpressionsWithIntervalArithmeticParameterName)) { 136 var checkExpressionsWithIntervalArithmeticParameter = (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; 137 Parameters.Remove(CheckExpressionsWithIntervalArithmeticParameterName); 138 checkExpressionsWithIntervalArithmetic = checkExpressionsWithIntervalArithmeticParameter.Value; 139 } 140 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, CheckExpressionsWithIntervalArithmeticParameterDescription, checkExpressionsWithIntervalArithmetic)); 132 141 } 133 142 134 143 #region IStatefulItem 135 136 144 public void InitializeState() { 137 145 EvaluatedSolutions = 0; … … 140 148 public void ClearState() { 141 149 } 142 143 150 #endregion 144 151 … … 192 199 193 200 switch (currentInstr.opCode) { 194 case OpCodes.Add: 195 { 201 case OpCodes.Add: { 196 202 if (nArgs > 0) { 197 203 CompileInstructions(il, state, ds); … … 203 209 return; 204 210 } 205 case OpCodes.Sub: 206 { 211 case OpCodes.Sub: { 207 212 if (nArgs == 1) { 208 213 CompileInstructions(il, state, ds); … … 219 224 return; 220 225 } 221 case OpCodes.Mul: 222 { 226 case OpCodes.Mul: { 223 227 if (nArgs > 0) { 224 228 CompileInstructions(il, state, ds); … … 230 234 return; 231 235 } 232 case OpCodes.Div: 233 { 236 case OpCodes.Div: { 234 237 if (nArgs == 1) { 235 238 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); … … 247 250 return; 248 251 } 249 case OpCodes.Average: 250 { 252 case OpCodes.Average: { 251 253 CompileInstructions(il, state, ds); 252 254 for (int i = 1; i < nArgs; i++) { … … 258 260 return; 259 261 } 260 case OpCodes.Cos: 261 { 262 case OpCodes.Cos: { 262 263 CompileInstructions(il, state, ds); 263 264 il.Emit(System.Reflection.Emit.OpCodes.Call, cos); 264 265 return; 265 266 } 266 case OpCodes.Sin: 267 { 267 case OpCodes.Sin: { 268 268 CompileInstructions(il, state, ds); 269 269 il.Emit(System.Reflection.Emit.OpCodes.Call, sin); 270 270 return; 271 271 } 272 case OpCodes.Tan: 273 { 272 case OpCodes.Tan: { 274 273 CompileInstructions(il, state, ds); 275 274 il.Emit(System.Reflection.Emit.OpCodes.Call, tan); 276 275 return; 277 276 } 278 case OpCodes.Power: 279 { 277 case OpCodes.Power: { 280 278 CompileInstructions(il, state, ds); 281 279 CompileInstructions(il, state, ds); … … 284 282 return; 285 283 } 286 case OpCodes.Root: 287 { 284 case OpCodes.Root: { 288 285 CompileInstructions(il, state, ds); 289 286 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // 1 / round(...) … … 294 291 return; 295 292 } 296 case OpCodes.Exp: 297 { 293 case OpCodes.Exp: { 298 294 CompileInstructions(il, state, ds); 299 295 il.Emit(System.Reflection.Emit.OpCodes.Call, exp); 300 296 return; 301 297 } 302 case OpCodes.Log: 303 { 298 case OpCodes.Log: { 304 299 CompileInstructions(il, state, ds); 305 300 il.Emit(System.Reflection.Emit.OpCodes.Call, log); 306 301 return; 307 302 } 308 case OpCodes.Square: 309 { 303 case OpCodes.Square: { 310 304 CompileInstructions(il, state, ds); 311 305 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); … … 313 307 return; 314 308 } 315 case OpCodes.SquareRoot: 316 { 309 case OpCodes.SquareRoot: { 317 310 CompileInstructions(il, state, ds); 318 311 il.Emit(System.Reflection.Emit.OpCodes.Call, sqrt); 319 312 return; 320 313 } 321 case OpCodes.AiryA: 322 { 314 case OpCodes.AiryA: { 323 315 CompileInstructions(il, state, ds); 324 316 il.Emit(System.Reflection.Emit.OpCodes.Call, airyA); 325 317 return; 326 318 } 327 case OpCodes.AiryB: 328 { 319 case OpCodes.AiryB: { 329 320 CompileInstructions(il, state, ds); 330 321 il.Emit(System.Reflection.Emit.OpCodes.Call, airyB); 331 322 return; 332 323 } 333 case OpCodes.Bessel: 334 { 324 case OpCodes.Bessel: { 335 325 CompileInstructions(il, state, ds); 336 326 il.Emit(System.Reflection.Emit.OpCodes.Call, bessel); 337 327 return; 338 328 } 339 case OpCodes.CosineIntegral: 340 { 329 case OpCodes.CosineIntegral: { 341 330 CompileInstructions(il, state, ds); 342 331 il.Emit(System.Reflection.Emit.OpCodes.Call, cosIntegral); 343 332 return; 344 333 } 345 case OpCodes.Dawson: 346 { 334 case OpCodes.Dawson: { 347 335 CompileInstructions(il, state, ds); 348 336 il.Emit(System.Reflection.Emit.OpCodes.Call, dawson); 349 337 return; 350 338 } 351 case OpCodes.Erf: 352 { 339 case OpCodes.Erf: { 353 340 CompileInstructions(il, state, ds); 354 341 il.Emit(System.Reflection.Emit.OpCodes.Call, erf); 355 342 return; 356 343 } 357 case OpCodes.ExponentialIntegralEi: 358 { 344 case OpCodes.ExponentialIntegralEi: { 359 345 CompileInstructions(il, state, ds); 360 346 il.Emit(System.Reflection.Emit.OpCodes.Call, expIntegralEi); 361 347 return; 362 348 } 363 case OpCodes.FresnelCosineIntegral: 364 { 349 case OpCodes.FresnelCosineIntegral: { 365 350 CompileInstructions(il, state, ds); 366 351 il.Emit(System.Reflection.Emit.OpCodes.Call, fresnelCosIntegral); 367 352 return; 368 353 } 369 case OpCodes.FresnelSineIntegral: 370 { 354 case OpCodes.FresnelSineIntegral: { 371 355 CompileInstructions(il, state, ds); 372 356 il.Emit(System.Reflection.Emit.OpCodes.Call, fresnelSinIntegral); 373 357 return; 374 358 } 375 case OpCodes.Gamma: 376 { 359 case OpCodes.Gamma: { 377 360 CompileInstructions(il, state, ds); 378 361 il.Emit(System.Reflection.Emit.OpCodes.Call, gamma); 379 362 return; 380 363 } 381 case OpCodes.HyperbolicCosineIntegral: 382 { 364 case OpCodes.HyperbolicCosineIntegral: { 383 365 CompileInstructions(il, state, ds); 384 366 il.Emit(System.Reflection.Emit.OpCodes.Call, hypCosIntegral); 385 367 return; 386 368 } 387 case OpCodes.HyperbolicSineIntegral: 388 { 369 case OpCodes.HyperbolicSineIntegral: { 389 370 CompileInstructions(il, state, ds); 390 371 il.Emit(System.Reflection.Emit.OpCodes.Call, hypSinIntegral); 391 372 return; 392 373 } 393 case OpCodes.Norm: 394 { 374 case OpCodes.Norm: { 395 375 CompileInstructions(il, state, ds); 396 376 il.Emit(System.Reflection.Emit.OpCodes.Call, norm); 397 377 return; 398 378 } 399 case OpCodes.Psi: 400 { 379 case OpCodes.Psi: { 401 380 CompileInstructions(il, state, ds); 402 381 il.Emit(System.Reflection.Emit.OpCodes.Call, psi); 403 382 return; 404 383 } 405 case OpCodes.SineIntegral: 406 { 384 case OpCodes.SineIntegral: { 407 385 CompileInstructions(il, state, ds); 408 386 il.Emit(System.Reflection.Emit.OpCodes.Call, sinIntegral); 409 387 return; 410 388 } 411 case OpCodes.IfThenElse: 412 { 389 case OpCodes.IfThenElse: { 413 390 Label end = il.DefineLabel(); 414 391 Label c1 = il.DefineLabel(); … … 424 401 return; 425 402 } 426 case OpCodes.AND: 427 { 403 case OpCodes.AND: { 428 404 Label falseBranch = il.DefineLabel(); 429 405 Label end = il.DefineLabel(); … … 446 422 return; 447 423 } 448 case OpCodes.OR: 449 { 424 case OpCodes.OR: { 450 425 Label trueBranch = il.DefineLabel(); 451 426 Label end = il.DefineLabel(); … … 475 450 return; 476 451 } 477 case OpCodes.NOT: 478 { 452 case OpCodes.NOT: { 479 453 CompileInstructions(il, state, ds); 480 454 il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0 … … 487 461 return; 488 462 } 489 case OpCodes.XOR: 490 { 463 case OpCodes.XOR: { 491 464 CompileInstructions(il, state, ds); 492 465 il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); … … 505 478 return; 506 479 } 507 case OpCodes.GT: 508 { 480 case OpCodes.GT: { 509 481 CompileInstructions(il, state, ds); 510 482 CompileInstructions(il, state, ds); … … 517 489 return; 518 490 } 519 case OpCodes.LT: 520 { 491 case OpCodes.LT: { 521 492 CompileInstructions(il, state, ds); 522 493 CompileInstructions(il, state, ds); … … 528 499 return; 529 500 } 530 case OpCodes.TimeLag: 531 { 501 case OpCodes.TimeLag: { 532 502 LaggedTreeNode laggedTreeNode = (LaggedTreeNode)currentInstr.dynamicNode; 533 503 il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row -= lag … … 545 515 return; 546 516 } 547 case OpCodes.Integral: 548 { 517 case OpCodes.Integral: { 549 518 int savedPc = state.ProgramCounter; 550 519 LaggedTreeNode laggedTreeNode = (LaggedTreeNode)currentInstr.dynamicNode; … … 573 542 //one sided smooth differentiatior, N = 4 574 543 // y' = 1/8h (f_i + 2f_i-1, -2 f_i-3 - f_i-4) 575 case OpCodes.Derivative: 576 { 544 case OpCodes.Derivative: { 577 545 int savedPc = state.ProgramCounter; 578 546 CompileInstructions(il, state, ds); … … 616 584 return; 617 585 } 618 case OpCodes.Call: 619 { 586 case OpCodes.Call: { 620 587 throw new NotSupportedException( 621 588 "Automatically defined functions are not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter. Either turn of ADFs or change the interpeter."); 622 589 } 623 case OpCodes.Arg: 624 { 590 case OpCodes.Arg: { 625 591 throw new NotSupportedException( 626 592 "Automatically defined functions are not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter. Either turn of ADFs or change the interpeter."); 627 593 } 628 case OpCodes.Variable: 629 { 594 case OpCodes.Variable: { 630 595 VariableTreeNode varNode = (VariableTreeNode)currentInstr.dynamicNode; 631 596 il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); // load columns array … … 659 624 return; 660 625 } 661 case OpCodes.LagVariable: 662 { 626 case OpCodes.LagVariable: { 663 627 var nanResult = il.DefineLabel(); 664 628 var normalResult = il.DefineLabel(); … … 688 652 return; 689 653 } 690 case OpCodes.Constant: 691 { 654 case OpCodes.Constant: { 692 655 ConstantTreeNode constNode = (ConstantTreeNode)currentInstr.dynamicNode; 693 656 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, constNode.Value); … … 697 660 //mkommend: this symbol uses the logistic function f(x) = 1 / (1 + e^(-alpha * x) ) 698 661 //to determine the relative amounts of the true and false branch see http://en.wikipedia.org/wiki/Logistic_function 699 case OpCodes.VariableCondition: 700 { 662 case OpCodes.VariableCondition: { 701 663 throw new NotSupportedException("Interpretation of symbol " + currentInstr.dynamicNode.Symbol.Name + 702 664 " is not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter"); -
branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs
r13141 r13222 32 32 [StorableClass] 33 33 [Item("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")] 34 public class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter { 34 public class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem, 35 ISymbolicDataAnalysisExpressionTreeInterpreter { 35 36 private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic"; 37 private const string CheckExpressionsWithIntervalArithmeticParameterDescription = "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression."; 36 38 private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions"; 37 39 38 public override bool CanChangeName { get { return false; } } 39 public override bool CanChangeDescription { get { return false; } } 40 public override bool CanChangeName { 41 get { return false; } 42 } 43 44 public override bool CanChangeDescription { 45 get { return false; } 46 } 40 47 41 48 #region parameter properties … … 54 61 set { CheckExpressionsWithIntervalArithmeticParameter.Value.Value = value; } 55 62 } 63 56 64 public int EvaluatedSolutions { 57 65 get { return EvaluatedSolutionsParameter.Value.Value; } … … 62 70 [StorableConstructor] 63 71 protected SymbolicDataAnalysisExpressionTreeInterpreter(bool deserializing) : base(deserializing) { } 64 protected SymbolicDataAnalysisExpressionTreeInterpreter(SymbolicDataAnalysisExpressionTreeInterpreter original, Cloner cloner) : base(original, cloner) { } 72 73 protected SymbolicDataAnalysisExpressionTreeInterpreter(SymbolicDataAnalysisExpressionTreeInterpreter original, 74 Cloner cloner) : base(original, cloner) { } 75 65 76 public override IDeepCloneable Clone(Cloner cloner) { 66 77 return new SymbolicDataAnalysisExpressionTreeInterpreter(this, cloner); … … 69 80 public SymbolicDataAnalysisExpressionTreeInterpreter() 70 81 : base("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.") { 71 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, 72 "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 82 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 73 83 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 74 84 } … … 76 86 protected SymbolicDataAnalysisExpressionTreeInterpreter(string name, string description) 77 87 : base(name, description) { 78 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, 79 "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 88 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 80 89 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 81 90 } … … 83 92 [StorableHook(HookType.AfterDeserialization)] 84 93 private void AfterDeserialization() { 85 Parameters.Remove(EvaluatedSolutionsParameterName); 86 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 87 88 Parameters.Remove(CheckExpressionsWithIntervalArithmeticParameterName); 89 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, 90 "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 94 var evaluatedSolutions = new IntValue(0); 95 var checkExpressionsWithIntervalArithmetic = new BoolValue(false); 96 if (Parameters.ContainsKey(EvaluatedSolutionsParameterName)) { 97 var evaluatedSolutionsParameter = (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; 98 evaluatedSolutions = evaluatedSolutionsParameter.Value; 99 Parameters.Remove(EvaluatedSolutionsParameterName); 100 } 101 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", evaluatedSolutions)); 102 if (Parameters.ContainsKey(CheckExpressionsWithIntervalArithmeticParameterName)) { 103 var checkExpressionsWithIntervalArithmeticParameter = (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; 104 Parameters.Remove(CheckExpressionsWithIntervalArithmeticParameterName); 105 checkExpressionsWithIntervalArithmetic = checkExpressionsWithIntervalArithmeticParameter.Value; 106 } 107 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, CheckExpressionsWithIntervalArithmeticParameterDescription, checkExpressionsWithIntervalArithmetic)); 91 108 } 92 109 … … 96 113 } 97 114 98 public void ClearState() { 99 } 115 public void ClearState() { } 100 116 #endregion 101 117 102 public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) { 103 if (CheckExpressionsWithIntervalArithmetic) 118 public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, 119 IEnumerable<int> rows) { 120 if (CheckExpressionsWithIntervalArithmetic) { 104 121 throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter."); 122 } 105 123 106 124 lock (EvaluatedSolutionsParameter.Value) { … … 136 154 } 137 155 138 139 156 public virtual double Evaluate(IDataset dataset, ref int row, InterpreterState state) { 140 157 Instruction currentInstr = state.NextInstruction(); 141 158 switch (currentInstr.opCode) { 142 case OpCodes.Add: 143 { 159 case OpCodes.Add: { 144 160 double s = Evaluate(dataset, ref row, state); 145 161 for (int i = 1; i < currentInstr.nArguments; i++) { … … 148 164 return s; 149 165 } 150 case OpCodes.Sub: 151 { 166 case OpCodes.Sub: { 152 167 double s = Evaluate(dataset, ref row, state); 153 168 for (int i = 1; i < currentInstr.nArguments; i++) { 154 169 s -= Evaluate(dataset, ref row, state); 155 170 } 156 if (currentInstr.nArguments == 1) s = -s;171 if (currentInstr.nArguments == 1) { s = -s; } 157 172 return s; 158 173 } 159 case OpCodes.Mul: 160 { 174 case OpCodes.Mul: { 161 175 double p = Evaluate(dataset, ref row, state); 162 176 for (int i = 1; i < currentInstr.nArguments; i++) { … … 165 179 return p; 166 180 } 167 case OpCodes.Div: 168 { 181 case OpCodes.Div: { 169 182 double p = Evaluate(dataset, ref row, state); 170 183 for (int i = 1; i < currentInstr.nArguments; i++) { 171 184 p /= Evaluate(dataset, ref row, state); 172 185 } 173 if (currentInstr.nArguments == 1) p = 1.0 / p;186 if (currentInstr.nArguments == 1) { p = 1.0 / p; } 174 187 return p; 175 188 } 176 case OpCodes.Average: 177 { 189 case OpCodes.Average: { 178 190 double sum = Evaluate(dataset, ref row, state); 179 191 for (int i = 1; i < currentInstr.nArguments; i++) { … … 182 194 return sum / currentInstr.nArguments; 183 195 } 184 case OpCodes.Cos: 185 { 196 case OpCodes.Cos: { 186 197 return Math.Cos(Evaluate(dataset, ref row, state)); 187 198 } 188 case OpCodes.Sin: 189 { 199 case OpCodes.Sin: { 190 200 return Math.Sin(Evaluate(dataset, ref row, state)); 191 201 } 192 case OpCodes.Tan: 193 { 202 case OpCodes.Tan: { 194 203 return Math.Tan(Evaluate(dataset, ref row, state)); 195 204 } 196 case OpCodes.Square: 197 { 205 case OpCodes.Square: { 198 206 return Math.Pow(Evaluate(dataset, ref row, state), 2); 199 207 } 200 case OpCodes.Power: 201 { 208 case OpCodes.Power: { 202 209 double x = Evaluate(dataset, ref row, state); 203 210 double y = Math.Round(Evaluate(dataset, ref row, state)); 204 211 return Math.Pow(x, y); 205 212 } 206 case OpCodes.SquareRoot: 207 { 213 case OpCodes.SquareRoot: { 208 214 return Math.Sqrt(Evaluate(dataset, ref row, state)); 209 215 } 210 case OpCodes.Root: 211 { 216 case OpCodes.Root: { 212 217 double x = Evaluate(dataset, ref row, state); 213 218 double y = Math.Round(Evaluate(dataset, ref row, state)); 214 219 return Math.Pow(x, 1 / y); 215 220 } 216 case OpCodes.Exp: 217 { 221 case OpCodes.Exp: { 218 222 return Math.Exp(Evaluate(dataset, ref row, state)); 219 223 } 220 case OpCodes.Log: 221 { 224 case OpCodes.Log: { 222 225 return Math.Log(Evaluate(dataset, ref row, state)); 223 226 } 224 case OpCodes.Gamma: 225 { 226 var x = Evaluate(dataset, ref row, state); 227 if (double.IsNaN(x)) return double.NaN; 228 else return alglib.gammafunction(x); 229 } 230 case OpCodes.Psi: 231 { 227 case OpCodes.Gamma: { 228 var x = Evaluate(dataset, ref row, state); 229 if (double.IsNaN(x)) { return double.NaN; } else { return alglib.gammafunction(x); } 230 } 231 case OpCodes.Psi: { 232 232 var x = Evaluate(dataset, ref row, state); 233 233 if (double.IsNaN(x)) return double.NaN; … … 235 235 return alglib.psi(x); 236 236 } 237 case OpCodes.Dawson: 238 { 239 var x = Evaluate(dataset, ref row, state); 240 if (double.IsNaN(x)) return double.NaN; 237 case OpCodes.Dawson: { 238 var x = Evaluate(dataset, ref row, state); 239 if (double.IsNaN(x)) { return double.NaN; } 241 240 return alglib.dawsonintegral(x); 242 241 } 243 case OpCodes.ExponentialIntegralEi: 244 { 245 var x = Evaluate(dataset, ref row, state); 246 if (double.IsNaN(x)) return double.NaN; 242 case OpCodes.ExponentialIntegralEi: { 243 var x = Evaluate(dataset, ref row, state); 244 if (double.IsNaN(x)) { return double.NaN; } 247 245 return alglib.exponentialintegralei(x); 248 246 } 249 case OpCodes.SineIntegral: 250 { 247 case OpCodes.SineIntegral: { 251 248 double si, ci; 252 249 var x = Evaluate(dataset, ref row, state); … … 257 254 } 258 255 } 259 case OpCodes.CosineIntegral: 260 { 256 case OpCodes.CosineIntegral: { 261 257 double si, ci; 262 258 var x = Evaluate(dataset, ref row, state); … … 267 263 } 268 264 } 269 case OpCodes.HyperbolicSineIntegral: 270 { 265 case OpCodes.HyperbolicSineIntegral: { 271 266 double shi, chi; 272 267 var x = Evaluate(dataset, ref row, state); … … 277 272 } 278 273 } 279 case OpCodes.HyperbolicCosineIntegral: 280 { 274 case OpCodes.HyperbolicCosineIntegral: { 281 275 double shi, chi; 282 276 var x = Evaluate(dataset, ref row, state); … … 287 281 } 288 282 } 289 case OpCodes.FresnelCosineIntegral: 290 { 283 case OpCodes.FresnelCosineIntegral: { 291 284 double c = 0, s = 0; 292 285 var x = Evaluate(dataset, ref row, state); … … 297 290 } 298 291 } 299 case OpCodes.FresnelSineIntegral: 300 { 292 case OpCodes.FresnelSineIntegral: { 301 293 double c = 0, s = 0; 302 294 var x = Evaluate(dataset, ref row, state); … … 307 299 } 308 300 } 309 case OpCodes.AiryA: 310 { 301 case OpCodes.AiryA: { 311 302 double ai, aip, bi, bip; 312 303 var x = Evaluate(dataset, ref row, state); … … 317 308 } 318 309 } 319 case OpCodes.AiryB: 320 { 310 case OpCodes.AiryB: { 321 311 double ai, aip, bi, bip; 322 312 var x = Evaluate(dataset, ref row, state); … … 327 317 } 328 318 } 329 case OpCodes.Norm: 330 { 319 case OpCodes.Norm: { 331 320 var x = Evaluate(dataset, ref row, state); 332 321 if (double.IsNaN(x)) return double.NaN; 333 322 else return alglib.normaldistribution(x); 334 323 } 335 case OpCodes.Erf: 336 { 324 case OpCodes.Erf: { 337 325 var x = Evaluate(dataset, ref row, state); 338 326 if (double.IsNaN(x)) return double.NaN; 339 327 else return alglib.errorfunction(x); 340 328 } 341 case OpCodes.Bessel: 342 { 329 case OpCodes.Bessel: { 343 330 var x = Evaluate(dataset, ref row, state); 344 331 if (double.IsNaN(x)) return double.NaN; 345 332 else return alglib.besseli0(x); 346 333 } 347 case OpCodes.IfThenElse: 348 { 334 case OpCodes.IfThenElse: { 349 335 double condition = Evaluate(dataset, ref row, state); 350 336 double result; … … 356 342 return result; 357 343 } 358 case OpCodes.AND: 359 { 344 case OpCodes.AND: { 360 345 double result = Evaluate(dataset, ref row, state); 361 346 for (int i = 1; i < currentInstr.nArguments; i++) { … … 367 352 return result > 0.0 ? 1.0 : -1.0; 368 353 } 369 case OpCodes.OR: 370 { 354 case OpCodes.OR: { 371 355 double result = Evaluate(dataset, ref row, state); 372 356 for (int i = 1; i < currentInstr.nArguments; i++) { … … 378 362 return result > 0.0 ? 1.0 : -1.0; 379 363 } 380 case OpCodes.NOT: 381 { 364 case OpCodes.NOT: { 382 365 return Evaluate(dataset, ref row, state) > 0.0 ? -1.0 : 1.0; 383 366 } 384 case OpCodes.XOR: 385 { 367 case OpCodes.XOR: { 386 368 //mkommend: XOR on multiple inputs is defined as true if the number of positive signals is odd 387 369 // this is equal to a consecutive execution of binary XOR operations. 388 370 int positiveSignals = 0; 389 371 for (int i = 0; i < currentInstr.nArguments; i++) { 390 if (Evaluate(dataset, ref row, state) > 0.0) positiveSignals++;372 if (Evaluate(dataset, ref row, state) > 0.0) { positiveSignals++; } 391 373 } 392 374 return positiveSignals % 2 != 0 ? 1.0 : -1.0; 393 375 } 394 case OpCodes.GT: 395 { 376 case OpCodes.GT: { 396 377 double x = Evaluate(dataset, ref row, state); 397 378 double y = Evaluate(dataset, ref row, state); 398 if (x > y) return 1.0; 399 else return -1.0; 400 } 401 case OpCodes.LT: 402 { 379 if (x > y) { return 1.0; } else { return -1.0; } 380 } 381 case OpCodes.LT: { 403 382 double x = Evaluate(dataset, ref row, state); 404 383 double y = Evaluate(dataset, ref row, state); 405 if (x < y) return 1.0; 406 else return -1.0; 407 } 408 case OpCodes.TimeLag: 409 { 384 if (x < y) { return 1.0; } else { return -1.0; } 385 } 386 case OpCodes.TimeLag: { 410 387 var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode; 411 388 row += timeLagTreeNode.Lag; … … 414 391 return result; 415 392 } 416 case OpCodes.Integral: 417 { 393 case OpCodes.Integral: { 418 394 int savedPc = state.ProgramCounter; 419 395 var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode; … … 433 409 //one sided smooth differentiatior, N = 4 434 410 // y' = 1/8h (f_i + 2f_i-1, -2 f_i-3 - f_i-4) 435 case OpCodes.Derivative: 436 { 411 case OpCodes.Derivative: { 437 412 int savedPc = state.ProgramCounter; 438 413 double f_0 = Evaluate(dataset, ref row, state); row--; … … 447 422 return (f_0 + 2 * f_1 - 2 * f_3 - f_4) / 8; // h = 1 448 423 } 449 case OpCodes.Call: 450 { 424 case OpCodes.Call: { 451 425 // evaluate sub-trees 452 426 double[] argValues = new double[currentInstr.nArguments]; … … 471 445 return v; 472 446 } 473 case OpCodes.Arg: 474 { 447 case OpCodes.Arg: { 475 448 return state.GetStackFrameValue((ushort)currentInstr.data); 476 449 } 477 case OpCodes.Variable: 478 { 450 case OpCodes.Variable: { 479 451 if (row < 0 || row >= dataset.Rows) return double.NaN; 480 452 var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode; 481 453 return ((IList<double>)currentInstr.data)[row] * variableTreeNode.Weight; 482 454 } 483 case OpCodes.LagVariable: 484 { 455 case OpCodes.LagVariable: { 485 456 var laggedVariableTreeNode = (LaggedVariableTreeNode)currentInstr.dynamicNode; 486 457 int actualRow = row + laggedVariableTreeNode.Lag; 487 if (actualRow < 0 || actualRow >= dataset.Rows) return double.NaN;458 if (actualRow < 0 || actualRow >= dataset.Rows) { return double.NaN; } 488 459 return ((IList<double>)currentInstr.data)[actualRow] * laggedVariableTreeNode.Weight; 489 460 } 490 case OpCodes.Constant: 491 { 461 case OpCodes.Constant: { 492 462 var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode; 493 463 return constTreeNode.Value; … … 496 466 //mkommend: this symbol uses the logistic function f(x) = 1 / (1 + e^(-alpha * x) ) 497 467 //to determine the relative amounts of the true and false branch see http://en.wikipedia.org/wiki/Logistic_function 498 case OpCodes.VariableCondition: 499 { 468 case OpCodes.VariableCondition: { 500 469 if (row < 0 || row >= dataset.Rows) return double.NaN; 501 470 var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode; … … 509 478 return trueBranch * p + falseBranch * (1 - p); 510 479 } 511 default: throw new NotSupportedException(); 480 default: 481 throw new NotSupportedException(); 512 482 } 513 483 } -
branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
r13141 r13222 35 35 public sealed class SymbolicDataAnalysisExpressionTreeLinearInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter { 36 36 private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic"; 37 private const string CheckExpressionsWithIntervalArithmeticParameterDescription = "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression."; 37 38 private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions"; 38 39 … … 84 85 public SymbolicDataAnalysisExpressionTreeLinearInterpreter() 85 86 : base("SymbolicDataAnalysisExpressionTreeLinearInterpreter", "Linear (non-recursive) interpreter for symbolic expression trees (does not support ADFs).") { 86 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, 87 "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 87 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, CheckExpressionsWithIntervalArithmeticParameterDescription, new BoolValue(false))); 88 88 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 89 89 interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter(); … … 92 92 public SymbolicDataAnalysisExpressionTreeLinearInterpreter(string name, string description) 93 93 : base(name, description) { 94 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, 95 "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 94 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, CheckExpressionsWithIntervalArithmeticParameterDescription, new BoolValue(false))); 96 95 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 97 96 interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter(); … … 100 99 [StorableHook(HookType.AfterDeserialization)] 101 100 private void AfterDeserialization() { 102 if (interpreter == null) interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter(); 103 Parameters.Remove(EvaluatedSolutionsParameterName); 104 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 105 106 Parameters.Remove(CheckExpressionsWithIntervalArithmeticParameterName); 107 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, 108 "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 101 var evaluatedSolutions = new IntValue(0); 102 var checkExpressionsWithIntervalArithmetic = new BoolValue(false); 103 if (Parameters.ContainsKey(EvaluatedSolutionsParameterName)) { 104 var evaluatedSolutionsParameter = (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; 105 evaluatedSolutions = evaluatedSolutionsParameter.Value; 106 Parameters.Remove(EvaluatedSolutionsParameterName); 107 } 108 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", evaluatedSolutions)); 109 if (Parameters.ContainsKey(CheckExpressionsWithIntervalArithmeticParameterName)) { 110 var checkExpressionsWithIntervalArithmeticParameter = (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; 111 Parameters.Remove(CheckExpressionsWithIntervalArithmeticParameterName); 112 checkExpressionsWithIntervalArithmetic = checkExpressionsWithIntervalArithmeticParameter.Value; 113 } 114 Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, CheckExpressionsWithIntervalArithmeticParameterDescription, checkExpressionsWithIntervalArithmetic)); 109 115 } 110 116 … … 372 378 #region opcode switch 373 379 switch (instr.opCode) { 374 case OpCodes.Constant: 375 { 380 case OpCodes.Constant: { 376 381 var constTreeNode = (ConstantTreeNode)instr.dynamicNode; 377 382 instr.value = constTreeNode.Value; … … 379 384 } 380 385 break; 381 case OpCodes.Variable: 382 { 386 case OpCodes.Variable: { 383 387 var variableTreeNode = (VariableTreeNode)instr.dynamicNode; 384 388 instr.data = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName); 385 389 } 386 390 break; 387 case OpCodes.LagVariable: 388 { 391 case OpCodes.LagVariable: { 389 392 var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode; 390 393 instr.data = dataset.GetReadOnlyDoubleValues(laggedVariableTreeNode.VariableName); 391 394 } 392 395 break; 393 case OpCodes.VariableCondition: 394 { 396 case OpCodes.VariableCondition: { 395 397 var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode; 396 398 instr.data = dataset.GetReadOnlyDoubleValues(variableConditionTreeNode.VariableName); … … 399 401 case OpCodes.TimeLag: 400 402 case OpCodes.Integral: 401 case OpCodes.Derivative: 402 { 403 case OpCodes.Derivative: { 403 404 var seq = GetPrefixSequence(code, i); 404 405 var interpreterState = new InterpreterState(seq, 0);
Note: See TracChangeset
for help on using the changeset viewer.