Changeset 13313
- Timestamp:
- 11/20/15 00:50:47 (9 years ago)
- Location:
- trunk/sources
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs
r13288 r13313 133 133 134 134 public static Func<int, IList<double>[], double> CompileTree(ISymbolicExpressionTree tree, IDataset dataset) { 135 var lambda = CreateDelegate(tree, dataset); 136 return lambda.Compile(); 137 } 138 139 public static Expression<Func<int, IList<double>[], double>> CreateDelegate(ISymbolicExpressionTree tree, IDataset dataset) { 135 140 var row = Expression.Parameter(typeof(int)); 136 141 var columns = Expression.Parameter(typeof(IList<double>[])); … … 138 143 var expr = MakeExpr(tree, variableIndices, row, columns); 139 144 var lambda = Expression.Lambda<Func<int, IList<double>[], double>>(expr, row, columns); 140 return lambda .Compile();145 return lambda; 141 146 } 142 147 … … 243 248 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 244 249 var isNaN = Expression.Call(IsNaN, arg); 245 var gamma = Expression.Call(Gamma, arg);246 250 247 251 var result = Expression.Variable(typeof(double)); … … 251 255 isNaN, 252 256 Expression.Assign(result, Expression.Constant(double.NaN)), 253 Expression.Assign(result, gamma)257 Expression.Assign(result, Expression.Call(Gamma, arg)) 254 258 ), 255 259 result … … 260 264 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 261 265 var isNaN = Expression.Call(IsNaN, arg); 262 var psi = Expression.Call(Psi, arg);263 266 264 267 var result = Expression.Variable(typeof(double)); … … 274 277 Expression.Call(IsAlmost, Expression.Subtract(floor, arg), Expression.Constant(0.0))), 275 278 Expression.Assign(result, Expression.Constant(double.NaN)), 276 Expression.Assign(result, psi))279 Expression.Assign(result, Expression.Call(Psi, arg))) 277 280 ), 278 281 result); … … 283 286 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 284 287 var isNaN = Expression.Call(IsNaN, arg); 285 var exprDawsonIntegral = Expression.Call(DawsonIntegral, arg); 286 var result = Expression.Variable(typeof(double)); 287 288 var result = Expression.Variable(typeof(double)); 288 289 var expr = Expression.Block( 289 290 new[] { result }, 290 291 Expression.IfThenElse(isNaN, 291 292 Expression.Assign(result, Expression.Constant(double.NaN)), 292 Expression.Assign(result, exprDawsonIntegral)),293 Expression.Assign(result, Expression.Call(DawsonIntegral, arg))), 293 294 result 294 295 ); … … 299 300 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 300 301 var isNaN = Expression.Call(IsNaN, arg); 301 var expIntegrapEi = Expression.Call(ExponentialIntegralEi, arg);302 302 var result = Expression.Variable(typeof(double)); 303 303 var expr = Expression.Block( … … 305 305 Expression.IfThenElse(isNaN, 306 306 Expression.Assign(result, Expression.Constant(double.NaN)), 307 Expression.Assign(result, expIntegrapEi)),307 Expression.Assign(result, Expression.Call(ExponentialIntegralEi, arg))), 308 308 result 309 309 ); … … 316 316 var si = Expression.Variable(typeof(double)); 317 317 var ci = Expression.Variable(typeof(double)); 318 var sinCosIntegrals = Expression.Call(SineCosineIntegrals, arg, si, ci);319 318 var block = Expression.Block( 320 319 new[] { si, ci }, 321 sinCosIntegrals,320 Expression.Call(SineCosineIntegrals, arg, si, ci), 322 321 si 323 322 ); … … 337 336 var si = Expression.Variable(typeof(double)); 338 337 var ci = Expression.Variable(typeof(double)); 339 var sinCosIntegrals = Expression.Call(SineCosineIntegrals, arg, si, ci);340 338 var block = Expression.Block( 341 339 new[] { si, ci }, 342 sinCosIntegrals,340 Expression.Call(SineCosineIntegrals, arg, si, ci), 343 341 ci 344 342 ); … … 398 396 var s = Expression.Variable(typeof(double)); 399 397 var c = Expression.Variable(typeof(double)); 400 var fresnel = Expression.Call(FresnelIntegral, arg, c, s); 401 var block = Expression.Block(new[] { s, c }, fresnel, s); 398 var block = Expression.Block(new[] { s, c }, Expression.Call(FresnelIntegral, arg, c, s), s); 402 399 var result = Expression.Variable(typeof(double)); 403 400 var expr = Expression.Block(new[] { result }, … … 415 412 var s = Expression.Variable(typeof(double)); 416 413 var c = Expression.Variable(typeof(double)); 417 var fresnel = Expression.Call(FresnelIntegral, arg, c, s); 418 var block = Expression.Block(new[] { s, c }, fresnel, c); 414 var block = Expression.Block(new[] { s, c }, Expression.Call(FresnelIntegral, arg, c, s), c); 419 415 var result = Expression.Variable(typeof(double)); 420 416 var expr = Expression.Block(new[] { result }, … … 434 430 var bi = Expression.Variable(typeof(double)); 435 431 var bip = Expression.Variable(typeof(double)); 436 var airy = Expression.Call(Airy, arg, ai, aip, bi, bip); 437 var block = Expression.Block(new[] { ai, aip, bi, bip }, airy, ai); 432 var block = Expression.Block(new[] { ai, aip, bi, bip }, Expression.Call(Airy, arg, ai, aip, bi, bip), ai); 438 433 var result = Expression.Variable(typeof(double)); 439 434 var expr = Expression.Block(new[] { result }, … … 453 448 var bi = Expression.Variable(typeof(double)); 454 449 var bip = Expression.Variable(typeof(double)); 455 var airy = Expression.Call(Airy, arg, ai, aip, bi, bip); 456 var block = Expression.Block(new[] { ai, aip, bi, bip }, airy, bi); 450 var block = Expression.Block(new[] { ai, aip, bi, bip }, Expression.Call(Airy, arg, ai, aip, bi, bip), bi); 457 451 var result = Expression.Variable(typeof(double)); 458 452 var expr = Expression.Block(new[] { result }, … … 467 461 case OpCodes.Norm: { 468 462 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 469 var isNaN = Expression.Call(IsNaN, arg);470 463 var result = Expression.Variable(typeof(double)); 471 464 return Expression.Block( 472 465 new[] { result }, 473 466 Expression.IfThenElse( 474 isNaN,475 Expression.Assign(result, Expression.Constant(double.NaN)),467 Expression.Call(IsNaN, arg), 468 Expression.Assign(result, arg), 476 469 Expression.Assign(result, Expression.Call(NormalDistribution, arg))), 477 470 result); -
trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs
r13256 r13313 22 22 using System; 23 23 using System.Collections.Generic; 24 using System.Diagnostics; 24 25 using System.Globalization; 25 26 using System.Linq; … … 220 221 [TestProperty("Time", "long")] 221 222 public void TestInterpreterEvaluationResults() { 222 223 223 var twister = new MersenneTwister(); 224 224 int seed = twister.Next(0, int.MaxValue); 225 225 twister.Seed((uint)seed); 226 227 226 const int numRows = 100; 228 227 var dataset = Util.CreateRandomDataset(twister, numRows, Columns); 229 228 230 229 var grammar = new TypeCoherentExpressionGrammar(); 230 231 var interpreters = new ISymbolicDataAnalysisExpressionTreeInterpreter[] { 232 new SymbolicDataAnalysisExpressionTreeLinearInterpreter(), 233 new SymbolicDataAnalysisExpressionTreeInterpreter(), 234 }; 235 236 var rows = Enumerable.Range(0, numRows).ToList(); 231 237 var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 10, 0, 0); 232 238 foreach (ISymbolicExpressionTree tree in randomTrees) { … … 234 240 } 235 241 236 var interpreters = new ISymbolicDataAnalysisExpressionTreeInterpreter[] {237 //new SymbolicDataAnalysisExpressionCompiledTreeInterpreter(),238 //new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(),239 new SymbolicDataAnalysisExpressionTreeLinearInterpreter(),240 new SymbolicDataAnalysisExpressionTreeInterpreter(),241 };242 243 var rows = Enumerable.Range(0, numRows).ToList();244 242 for (int i = 0; i < randomTrees.Length; ++i) { 245 243 var tree = randomTrees[i]; … … 251 249 if (double.IsNaN(sum) && double.IsNaN(s)) continue; 252 250 253 string errorMessage = string.Format("Interpreters {0} and {1} do not agree on tree {2} (seed = {3}).", 254 interpreters[m].Name, interpreters[n].Name, i, seed); 255 Assert.AreEqual(sum, valuesMatrix[n].Sum(), 1.0E-12, errorMessage); 251 string errorMessage = string.Format("Interpreters {0} and {1} do not agree on tree {2} (seed = {3}).", interpreters[m].Name, interpreters[n].Name, i, seed); 252 Assert.AreEqual(sum, s, 1e-12, errorMessage); 253 } 254 } 255 } 256 } 257 258 [TestMethod] 259 [TestCategory("Problems.DataAnalysis.Symbolic")] 260 [TestProperty("Time", "long")] 261 public void TestCompiledInterpreterEvaluationResults() { 262 const double delta = 1e-10; 263 264 var twister = new MersenneTwister(); 265 int seed = twister.Next(0, int.MaxValue); 266 twister.Seed((uint)seed); 267 268 Console.WriteLine(seed); 269 270 const int numRows = 100; 271 var dataset = Util.CreateRandomDataset(twister, numRows, Columns); 272 273 var grammar = new TypeCoherentExpressionGrammar(); 274 var hash = new HashSet<Type>(new[] { typeof(LaggedSymbol), typeof(LaggedVariable), typeof(TimeLag), typeof(Derivative), typeof(Integral), typeof(AutoregressiveTargetVariable) }); 275 foreach (var symbol in grammar.Symbols.Where(x => hash.Contains(x.GetType()))) symbol.Enabled = false; 276 var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 10, 0, 0); 277 foreach (ISymbolicExpressionTree tree in randomTrees) { 278 Util.InitTree(tree, twister, new List<string>(dataset.VariableNames)); 279 } 280 281 var interpreters = new ISymbolicDataAnalysisExpressionTreeInterpreter[] { 282 new SymbolicDataAnalysisExpressionCompiledTreeInterpreter(), 283 new SymbolicDataAnalysisExpressionTreeInterpreter(), 284 }; 285 var rows = Enumerable.Range(0, numRows).ToList(); 286 var formatter = new SymbolicExpressionTreeHierarchicalFormatter(); 287 288 for (int i = 0; i < randomTrees.Length; ++i) { 289 var tree = randomTrees[i]; 290 List<List<double>> valuesMatrix = new List<List<double>>(); 291 // the try-catch block below is useful for debugging lambda expressions 292 try { 293 valuesMatrix = interpreters.Select(x => x.GetSymbolicExpressionTreeValues(tree, dataset, rows).ToList()).ToList(); 294 } 295 catch (Exception e) { 296 var lambda = SymbolicDataAnalysisExpressionCompiledTreeInterpreter.CreateDelegate(tree, dataset); 297 Console.WriteLine(e.Message); 298 Console.WriteLine(lambda.ToString()); 299 Debugger.Launch(); 300 } 301 for (int m = 0; m < interpreters.Length - 1; ++m) { 302 for (int n = m + 1; n < interpreters.Length; ++n) { 303 for (int row = 0; row < numRows; ++row) { 304 var v1 = valuesMatrix[m][row]; 305 var v2 = valuesMatrix[n][row]; 306 if (double.IsNaN(v1) && double.IsNaN(v2)) continue; 307 if (Math.Abs(v1 - v2) > delta) { 308 Console.WriteLine(formatter.Format(tree)); 309 foreach (var node in tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList()) { 310 var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); 311 if (rootNode.HasLocalParameters) rootNode.ResetLocalParameters(twister); 312 rootNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); 313 314 var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); 315 if (startNode.HasLocalParameters) startNode.ResetLocalParameters(twister); 316 startNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); 317 318 rootNode.AddSubtree(startNode); 319 var t = new SymbolicExpressionTree(rootNode); 320 var start = t.Root.GetSubtree(0); 321 var p = node.Parent; 322 start.AddSubtree(node); 323 Console.WriteLine(node); 324 325 var y1 = interpreters[m].GetSymbolicExpressionTreeValues(t, dataset, new[] { row }).First(); 326 var y2 = interpreters[n].GetSymbolicExpressionTreeValues(t, dataset, new[] { row }).First(); 327 328 if (double.IsNaN(y1) && double.IsNaN(y2)) continue; 329 string prefix = Math.Abs(y1 - y2) > delta ? "++" : "=="; 330 Console.WriteLine("\t{0} Row {1}: {2:N20} {3:N20}, Deviation = {4}", prefix, row, y1, y2, Math.Abs(y1 - y2)); 331 node.Parent = p; 332 } 333 } 334 string errorMessage = string.Format("Interpreters {0} and {1} do not agree on tree {2} and row {3} (seed = {4}).", interpreters[m].Name, interpreters[n].Name, i, row, seed); 335 Assert.AreEqual(v1, v2, delta, errorMessage); 336 } 256 337 } 257 338 } … … 432 513 433 514 // lag 434 Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 1, ds.GetDoubleValue("A", 0));435 Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 2, ds.GetDoubleValue("A", 1));436 Evaluate(interpreter, ds, "(lagVariable 1.0 a 0) ", 2, ds.GetDoubleValue("A", 2));437 Evaluate(interpreter, ds, "(lagVariable 1.0 a 1) ", 0, ds.GetDoubleValue("A", 1));515 // Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 1, ds.GetDoubleValue("A", 0)); 516 // Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 2, ds.GetDoubleValue("A", 1)); 517 // Evaluate(interpreter, ds, "(lagVariable 1.0 a 0) ", 2, ds.GetDoubleValue("A", 2)); 518 // Evaluate(interpreter, ds, "(lagVariable 1.0 a 1) ", 0, ds.GetDoubleValue("A", 1)); 438 519 439 520 // integral 440 Evaluate(interpreter, ds, "(integral -1.0 (variable 1.0 a)) ", 1, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1));441 Evaluate(interpreter, ds, "(integral -1.0 (lagVariable 1.0 a 1)) ", 1, ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));442 Evaluate(interpreter, ds, "(integral -2.0 (variable 1.0 a)) ", 2, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));443 Evaluate(interpreter, ds, "(integral -1.0 (* (variable 1.0 a) (variable 1.0 b)))", 1, ds.GetDoubleValue("A", 0) * ds.GetDoubleValue("B", 0) + ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1));444 Evaluate(interpreter, ds, "(integral -2.0 3.0)", 1, 9.0);521 // Evaluate(interpreter, ds, "(integral -1.0 (variable 1.0 a)) ", 1, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1)); 522 // Evaluate(interpreter, ds, "(integral -1.0 (lagVariable 1.0 a 1)) ", 1, ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2)); 523 // Evaluate(interpreter, ds, "(integral -2.0 (variable 1.0 a)) ", 2, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2)); 524 // Evaluate(interpreter, ds, "(integral -1.0 (* (variable 1.0 a) (variable 1.0 b)))", 1, ds.GetDoubleValue("A", 0) * ds.GetDoubleValue("B", 0) + ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1)); 525 // Evaluate(interpreter, ds, "(integral -2.0 3.0)", 1, 9.0); 445 526 446 527 // derivative 447 528 // (f_0 + 2 * f_1 - 2 * f_3 - f_4) / 8; // h = 1 448 Evaluate(interpreter, ds, "(diff (variable 1.0 a)) ", 5, (ds.GetDoubleValue("A", 5) + 2 * ds.GetDoubleValue("A", 4) - 2 * ds.GetDoubleValue("A", 2) - ds.GetDoubleValue("A", 1)) / 8.0);449 Evaluate(interpreter, ds, "(diff (variable 1.0 b)) ", 5, (ds.GetDoubleValue("B", 5) + 2 * ds.GetDoubleValue("B", 4) - 2 * ds.GetDoubleValue("B", 2) - ds.GetDoubleValue("B", 1)) / 8.0);450 Evaluate(interpreter, ds, "(diff (* (variable 1.0 a) (variable 1.0 b)))", 5, +451 (ds.GetDoubleValue("A", 5) * ds.GetDoubleValue("B", 5) +452 2 * ds.GetDoubleValue("A", 4) * ds.GetDoubleValue("B", 4) -453 2 * ds.GetDoubleValue("A", 2) * ds.GetDoubleValue("B", 2) -454 ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1)) / 8.0);455 Evaluate(interpreter, ds, "(diff -2.0 3.0)", 5, 0.0);529 // Evaluate(interpreter, ds, "(diff (variable 1.0 a)) ", 5, (ds.GetDoubleValue("A", 5) + 2 * ds.GetDoubleValue("A", 4) - 2 * ds.GetDoubleValue("A", 2) - ds.GetDoubleValue("A", 1)) / 8.0); 530 // Evaluate(interpreter, ds, "(diff (variable 1.0 b)) ", 5, (ds.GetDoubleValue("B", 5) + 2 * ds.GetDoubleValue("B", 4) - 2 * ds.GetDoubleValue("B", 2) - ds.GetDoubleValue("B", 1)) / 8.0); 531 // Evaluate(interpreter, ds, "(diff (* (variable 1.0 a) (variable 1.0 b)))", 5, + 532 // (ds.GetDoubleValue("A", 5) * ds.GetDoubleValue("B", 5) + 533 // 2 * ds.GetDoubleValue("A", 4) * ds.GetDoubleValue("B", 4) - 534 // 2 * ds.GetDoubleValue("A", 2) * ds.GetDoubleValue("B", 2) - 535 // ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1)) / 8.0); 536 // Evaluate(interpreter, ds, "(diff -2.0 3.0)", 5, 0.0); 456 537 457 538 // timelag 458 Evaluate(interpreter, ds, "(lag -1.0 (lagVariable 1.0 a 2)) ", 1, ds.GetDoubleValue("A", 2));459 Evaluate(interpreter, ds, "(lag -2.0 (lagVariable 1.0 a 2)) ", 2, ds.GetDoubleValue("A", 2));460 Evaluate(interpreter, ds, "(lag -1.0 (* (lagVariable 1.0 a 1) (lagVariable 1.0 b 2)))", 1, ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 2));461 Evaluate(interpreter, ds, "(lag -2.0 3.0)", 1, 3.0);539 // Evaluate(interpreter, ds, "(lag -1.0 (lagVariable 1.0 a 2)) ", 1, ds.GetDoubleValue("A", 2)); 540 // Evaluate(interpreter, ds, "(lag -2.0 (lagVariable 1.0 a 2)) ", 2, ds.GetDoubleValue("A", 2)); 541 // Evaluate(interpreter, ds, "(lag -1.0 (* (lagVariable 1.0 a 1) (lagVariable 1.0 b 2)))", 1, ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 2)); 542 // Evaluate(interpreter, ds, "(lag -2.0 3.0)", 1, 3.0); 462 543 463 544 {
Note: See TracChangeset
for help on using the changeset viewer.