Changeset 13222 for branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs
- Timestamp:
- 11/17/15 16:21:29 (8 years ago)
- File:
-
- 1 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);
Note: See TracChangeset
for help on using the changeset viewer.