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