Changeset 13139
 Timestamp:
 11/12/15 11:10:22 (6 years ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

branches/HeuristicLab.LinqExpressionTreeInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs
r13039 r13139 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; … … 62 61 #endregion 63 62 64 private static readonly Func<ReadOnlyCollection<double>, IList<double>> ReadOnlyCollectionRetrieveList = GetField<ReadOnlyCollection<double>, IList<double>>("list"); // retrieve underlying field of type List from a ReadOnlyCollection65 private static readonly Func<List<double>, double[]> ListRetrieveItems = GetField<List<double>, double[]>("_items"); // retrieve underlying field of type double[] from a List<double>63 private static readonly MethodInfo ListGetValue = typeof(IList<double>).GetProperty("Item", new Type[] { typeof(int) }).GetGetMethod(); 64 private static readonly MethodInfo DatasetGetReadOnlyDoubleValues = typeof(IDataset).GetMethod("GetReadOnlyDoubleValues", new[] { typeof(string) }); 66 65 67 66 public override bool CanChangeName { get { return false; } } … … 123 122 EvaluatedSolutions.Value++; // increment the evaluated solutions counter 124 123 } 125 126 var columns = dataset.DoubleVariables.Select(x => ListRetrieveItems((List<double>)ReadOnlyCollectionRetrieveList(dataset.GetReadOnlyDoubleValues(x)))).ToArray();127 124 var compiled = CompileTree(tree, dataset); 128 return rows.Select(x => compiled(x, columns));129 } 130 131 public static Func<int, double[][], double> CompileTree(ISymbolicExpressionTree tree, IDataset dataset) {125 return rows.Select(x => compiled(x, dataset)); 126 } 127 128 public static Func<int, IDataset, double> CompileTree(ISymbolicExpressionTree tree, IDataset dataset) { 132 129 var row = Expression.Parameter(typeof(int)); 133 var columns = Expression.Parameter(typeof(double[][])); 134 var variableIndices = dataset.DoubleVariables.Select((x, i) => new { x, i }).ToDictionary(e => e.x, e => e.i); 135 var expr = MakeExpr(tree, variableIndices, row, columns); 136 var lambda = Expression.Lambda<Func<int, double[][], double>>(expr, row, columns); 130 var ds = Expression.Parameter(typeof(IDataset)); 131 var expr = MakeExpr(tree, row, ds); 132 var lambda = Expression.Lambda<Func<int, IDataset, double>>(expr, row, ds); 137 133 return lambda.Compile(); 138 134 } 139 135 140 private static Expression MakeExpr(ISymbolicExpressionTree tree, Dictionary<string, int> variableIndices, ParameterExpression row, ParameterExpression columns) {136 private static Expression MakeExpr(ISymbolicExpressionTree tree, ParameterExpression row, ParameterExpression ds) { 141 137 var actualRoot = tree.Root.GetSubtree(0).GetSubtree(0); 142 return MakeExpr(actualRoot, variableIndices, row, columns);143 } 144 145 private static Expression MakeExpr(ISymbolicExpressionTreeNode node, Dictionary<string, int> variableIndices, ParameterExpression row, ParameterExpression columns) {138 return MakeExpr(actualRoot, row, ds); 139 } 140 141 private static Expression MakeExpr(ISymbolicExpressionTreeNode node, ParameterExpression row, ParameterExpression ds) { 146 142 var opcode = OpCodes.MapSymbolToOpCode(node); 147 143 switch (opcode) { … … 149 145 { 150 146 var functionSymbol = (FunctionSymbol)node.Symbol; 151 return Expression.Call(functionSymbol.MethodInfo, node.Subtrees.Select(x => MakeExpr(x, variableIndices, row, columns)));147 return Expression.Call(functionSymbol.MethodInfo, node.Subtrees.Select(x => MakeExpr(x, row, ds))); 152 148 } 153 149 case OpCodes.Constant: … … 160 156 var variableTreeNode = (VariableTreeNode)node; 161 157 var variableWeight = Expression.Constant(variableTreeNode.Weight); 162 var variableName = variableTreeNode.VariableName; 163 var indexExpr = Expression.Constant(variableIndices[variableName]); 164 var valuesExpr = Expression.ArrayIndex(columns, indexExpr); 165 var variableValue = Expression.ArrayIndex(valuesExpr, row); 158 var variableName = Expression.Constant(variableTreeNode.VariableName); 159 var valuesExpr = Expression.Call(ds, DatasetGetReadOnlyDoubleValues, variableName); 160 var variableValue = Expression.Call(valuesExpr, ListGetValue, row); 166 161 return Expression.Multiply(variableWeight, variableValue); 167 162 } 168 163 case OpCodes.Add: 169 164 { 170 Expression result = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);165 Expression result = MakeExpr(node.GetSubtree(0), row, ds); 171 166 for (int i = 1; i < node.SubtreeCount; ++i) { 172 result = Expression.Add(result, MakeExpr(node.GetSubtree(i), variableIndices, row, columns));167 result = Expression.Add(result, MakeExpr(node.GetSubtree(i), row, ds)); 173 168 } 174 169 return result; … … 176 171 case OpCodes.Sub: 177 172 { 178 Expression result = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);173 Expression result = MakeExpr(node.GetSubtree(0), row, ds); 179 174 if (node.SubtreeCount == 1) 180 175 return Expression.Negate(result); 181 176 for (int i = 1; i < node.SubtreeCount; ++i) { 182 result = Expression.Subtract(result, MakeExpr(node.GetSubtree(i), variableIndices, row, columns));177 result = Expression.Subtract(result, MakeExpr(node.GetSubtree(i), row, ds)); 183 178 } 184 179 return result; … … 186 181 case OpCodes.Mul: 187 182 { 188 Expression result = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);183 Expression result = MakeExpr(node.GetSubtree(0), row, ds); 189 184 for (int i = 1; i < node.SubtreeCount; ++i) { 190 result = Expression.Multiply(result, MakeExpr(node.GetSubtree(i), variableIndices, row, columns));185 result = Expression.Multiply(result, MakeExpr(node.GetSubtree(i), row, ds)); 191 186 } 192 187 return result; … … 194 189 case OpCodes.Div: 195 190 { 196 Expression result = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);191 Expression result = MakeExpr(node.GetSubtree(0), row, ds); 197 192 if (node.SubtreeCount == 1) 198 193 return Expression.Divide(Expression.Constant(1.0), result); 199 194 for (int i = 1; i < node.SubtreeCount; ++i) { 200 result = Expression.Divide(result, MakeExpr(node.GetSubtree(i), variableIndices, row, columns));195 result = Expression.Divide(result, MakeExpr(node.GetSubtree(i), row, ds)); 201 196 } 202 197 return result; … … 204 199 case OpCodes.Average: 205 200 { 206 Expression result = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);201 Expression result = MakeExpr(node.GetSubtree(0), row, ds); 207 202 for (int i = 1; i < node.SubtreeCount; ++i) { 208 result = Expression.Add(result, MakeExpr(node.GetSubtree(i), variableIndices, row, columns));203 result = Expression.Add(result, MakeExpr(node.GetSubtree(i), row, ds)); 209 204 } 210 205 return Expression.Divide(result, Expression.Constant((double)node.SubtreeCount)); … … 212 207 case OpCodes.Cos: 213 208 { 214 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);209 var arg = MakeExpr(node.GetSubtree(0), row, ds); 215 210 return Expression.Call(Cos, arg); 216 211 } 217 212 case OpCodes.Sin: 218 213 { 219 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);214 var arg = MakeExpr(node.GetSubtree(0), row, ds); 220 215 return Expression.Call(Sin, arg); 221 216 } 222 217 case OpCodes.Tan: 223 218 { 224 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);219 var arg = MakeExpr(node.GetSubtree(0), row, ds); 225 220 return Expression.Call(Tan, arg); 226 221 } 227 222 case OpCodes.Square: 228 223 { 229 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);224 var arg = MakeExpr(node.GetSubtree(0), row, ds); 230 225 return Expression.Power(arg, Expression.Constant(2)); 231 226 } 232 227 case OpCodes.Power: 233 228 { 234 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);235 var power = MakeExpr(node.GetSubtree(1), variableIndices, row, columns);229 var arg = MakeExpr(node.GetSubtree(0), row, ds); 230 var power = MakeExpr(node.GetSubtree(1), row, ds); 236 231 return Expression.Power(arg, Expression.Call(Floor, power)); 237 232 } 238 233 case OpCodes.SquareRoot: 239 234 { 240 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);235 var arg = MakeExpr(node.GetSubtree(0), row, ds); 241 236 return Expression.Call(Sqrt, arg); 242 237 } 243 238 case OpCodes.Root: 244 239 { 245 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);246 var power = MakeExpr(node.GetSubtree(1), variableIndices, row, columns);240 var arg = MakeExpr(node.GetSubtree(0), row, ds); 241 var power = MakeExpr(node.GetSubtree(1), row, ds); 247 242 return Expression.Power(arg, Expression.Divide(Expression.Constant(1.0), power)); 248 243 } 249 244 case OpCodes.Exp: 250 245 { 251 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);246 var arg = MakeExpr(node.GetSubtree(0), row, ds); 252 247 return Expression.Call(Exp, arg); 253 248 } 254 249 case OpCodes.Log: 255 250 { 256 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);251 var arg = MakeExpr(node.GetSubtree(0), row, ds); 257 252 return Expression.Call(Log, arg); 258 253 } 259 254 case OpCodes.Gamma: 260 255 { 261 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);256 var arg = MakeExpr(node.GetSubtree(0), row, ds); 262 257 var isNaN = Expression.Call(IsNaN, arg); 263 258 var gamma = Expression.Call(Gamma, arg); … … 277 272 case OpCodes.Psi: 278 273 { 279 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);274 var arg = MakeExpr(node.GetSubtree(0), row, ds); 280 275 var isNaN = Expression.Call(IsNaN, arg); 281 276 var psi = Expression.Call(Psi, arg); … … 300 295 case OpCodes.Dawson: 301 296 { 302 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);297 var arg = MakeExpr(node.GetSubtree(0), row, ds); 303 298 var isNaN = Expression.Call(IsNaN, arg); 304 299 var exprDawsonIntegral = Expression.Call(DawsonIntegral, arg); … … 317 312 case OpCodes.ExponentialIntegralEi: 318 313 { 319 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);314 var arg = MakeExpr(node.GetSubtree(0), row, ds); 320 315 var isNaN = Expression.Call(IsNaN, arg); 321 316 var expIntegrapEi = … … 334 329 case OpCodes.SineIntegral: 335 330 { 336 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);331 var arg = MakeExpr(node.GetSubtree(0), row, ds); 337 332 var isNaN = Expression.Call(IsNaN, arg); 338 333 var si = Expression.Variable(typeof(double)); … … 356 351 case OpCodes.CosineIntegral: 357 352 { 358 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);353 var arg = MakeExpr(node.GetSubtree(0), row, ds); 359 354 var isNaN = Expression.Call(IsNaN, arg); 360 355 var si = Expression.Variable(typeof(double)); … … 378 373 case OpCodes.HyperbolicSineIntegral: 379 374 { 380 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);375 var arg = MakeExpr(node.GetSubtree(0), row, ds); 381 376 var isNaN = Expression.Call(IsNaN, arg); 382 377 var shi = Expression.Variable(typeof(double)); … … 400 395 case OpCodes.HyperbolicCosineIntegral: 401 396 { 402 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);397 var arg = MakeExpr(node.GetSubtree(0), row, ds); 403 398 var isNaN = Expression.Call(IsNaN, arg); 404 399 var shi = Expression.Variable(typeof(double)); … … 422 417 case OpCodes.FresnelSineIntegral: 423 418 { 424 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);419 var arg = MakeExpr(node.GetSubtree(0), row, ds); 425 420 var isNaN = Expression.Call(IsNaN, arg); 426 421 var s = Expression.Variable(typeof(double)); … … 440 435 case OpCodes.FresnelCosineIntegral: 441 436 { 442 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);437 var arg = MakeExpr(node.GetSubtree(0), row, ds); 443 438 var isNaN = Expression.Call(IsNaN, arg); 444 439 var s = Expression.Variable(typeof(double)); … … 458 453 case OpCodes.AiryA: 459 454 { 460 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);455 var arg = MakeExpr(node.GetSubtree(0), row, ds); 461 456 var isNaN = Expression.Call(IsNaN, arg); 462 457 var ai = Expression.Variable(typeof(double)); … … 478 473 case OpCodes.AiryB: 479 474 { 480 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);475 var arg = MakeExpr(node.GetSubtree(0), row, ds); 481 476 var isNaN = Expression.Call(IsNaN, arg); 482 477 var ai = Expression.Variable(typeof(double)); … … 498 493 case OpCodes.Norm: 499 494 { 500 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);495 var arg = MakeExpr(node.GetSubtree(0), row, ds); 501 496 var isNaN = Expression.Call(IsNaN, arg); 502 497 var result = Expression.Variable(typeof(double)); … … 511 506 case OpCodes.Erf: 512 507 { 513 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);508 var arg = MakeExpr(node.GetSubtree(0), row, ds); 514 509 var isNaN = Expression.Call(IsNaN, arg); 515 510 var result = Expression.Variable(typeof(double)); … … 524 519 case OpCodes.Bessel: 525 520 { 526 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);521 var arg = MakeExpr(node.GetSubtree(0), row, ds); 527 522 var isNaN = Expression.Call(IsNaN, arg); 528 523 var result = Expression.Variable(typeof(double)); … … 540 535 case OpCodes.IfThenElse: 541 536 { 542 var test = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);537 var test = MakeExpr(node.GetSubtree(0), row, ds); 543 538 var result = Expression.Variable(typeof(double)); 544 539 var condition = Expression.IfThenElse(Expression.GreaterThan(test, Expression.Constant(0.0)), 545 Expression.Assign(result, MakeExpr(node.GetSubtree(1), variableIndices, row, columns)),546 Expression.Assign(result, MakeExpr(node.GetSubtree(2), variableIndices, row, columns)));540 Expression.Assign(result, MakeExpr(node.GetSubtree(1), row, ds)), 541 Expression.Assign(result, MakeExpr(node.GetSubtree(2), row, ds))); 547 542 return Expression.Block(new[] { result }, condition, result); 548 543 } … … 550 545 { 551 546 var result = Expression.Variable(typeof(double)); 552 var expr = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);547 var expr = MakeExpr(node.GetSubtree(0), row, ds); 553 548 554 549 for (int i = 1; i < node.SubtreeCount; ++i) { … … 556 551 Expression.IfThenElse( 557 552 Expression.GreaterThan(expr, Expression.Constant(0.0)), 558 Expression.Assign(result, MakeExpr(node.GetSubtree(i), variableIndices, row, columns)),553 Expression.Assign(result, MakeExpr(node.GetSubtree(i), row, ds)), 559 554 Expression.Assign(result, expr)), 560 555 result … … 576 571 { 577 572 var result = Expression.Variable(typeof(double)); 578 var expr = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);573 var expr = MakeExpr(node.GetSubtree(0), row, ds); 579 574 580 575 for (int i = 1; i < node.SubtreeCount; ++i) { … … 582 577 Expression.IfThenElse( 583 578 Expression.LessThanOrEqual(expr, Expression.Constant(0.0)), 584 Expression.Assign(result, MakeExpr(node.GetSubtree(i), variableIndices, row, columns)),579 Expression.Assign(result, MakeExpr(node.GetSubtree(i), row, ds)), 585 580 Expression.Assign(result, expr)), 586 581 result … … 601 596 case OpCodes.NOT: 602 597 { 603 var value = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);598 var value = MakeExpr(node.GetSubtree(0), row, ds); 604 599 var result = Expression.Variable(typeof(double)); 605 600 var condition = Expression.IfThenElse(Expression.GreaterThan(value, Expression.Constant(0.0)), … … 618 613 619 614 foreach (var subtree in node.Subtrees) { 620 var expr = MakeExpr(subtree, variableIndices, row, columns);615 var expr = MakeExpr(subtree, row, ds); 621 616 block = Expression.Block( 622 617 new[] { ps }, … … 642 637 case OpCodes.GT: 643 638 { 644 var left = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);645 var right = MakeExpr(node.GetSubtree(1), variableIndices, row, columns);639 var left = MakeExpr(node.GetSubtree(0), row, ds); 640 var right = MakeExpr(node.GetSubtree(1), row, ds); 646 641 var result = Expression.Variable(typeof(double)); 647 642 … … 655 650 case OpCodes.LT: 656 651 { 657 var left = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);658 var right = MakeExpr(node.GetSubtree(1), variableIndices, row, columns);652 var left = MakeExpr(node.GetSubtree(0), row, ds); 653 var right = MakeExpr(node.GetSubtree(1), row, ds); 659 654 var result = Expression.Variable(typeof(double)); 660 655 … … 666 661 { 667 662 var variableConditionTreeNode = (VariableConditionTreeNode)node; 668 var variableName = variableConditionTreeNode.VariableName; 669 var indexExpr = Expression.Constant(variableIndices[variableName]); 670 var valuesExpr = Expression.ArrayIndex(columns, indexExpr); 671 var variableValue = Expression.ArrayIndex(valuesExpr, row); 663 var variableName = Expression.Constant(variableConditionTreeNode.VariableName); 664 var valuesExpr = Expression.Call(ds, DatasetGetReadOnlyDoubleValues, variableName); 665 var variableValue = Expression.Call(valuesExpr, ListGetValue, row); 672 666 var variableThreshold = Expression.Constant(variableConditionTreeNode.Threshold); 673 667 var variableSlope = Expression.Constant(variableConditionTreeNode.Slope); … … 677 671 var xSlopeExp = Expression.Call(Exp, xSlope); 678 672 var p = Expression.Divide(Expression.Constant(1), Expression.Add(Expression.Constant(1), xSlopeExp)); 679 var trueBranch = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);680 var falseBranch = MakeExpr(node.GetSubtree(1), variableIndices, row, columns);673 var trueBranch = MakeExpr(node.GetSubtree(0), row, ds); 674 var falseBranch = MakeExpr(node.GetSubtree(1), row, ds); 681 675 return Expression.Add( 682 676 Expression.Multiply(trueBranch, p),
Note: See TracChangeset
for help on using the changeset viewer.