Changeset 17434 for branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter
- Timestamp:
- 02/11/20 13:36:02 (5 years ago)
- Location:
- branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic
- Files:
-
- 7 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic
- Property svn:mergeinfo changed
-
branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/InterpreterState.cs
r16130 r17434 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-2018Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. -
branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs
r16130 r17434 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-2018Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 22 22 using System; 23 23 using System.Collections.Generic; 24 using System.Linq; 24 25 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 25 26 26 27 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 28 public enum OpCode : byte { 29 Add = 1, 30 Sub = 2, 31 Mul = 3, 32 Div = 4, 33 Sin = 5, 34 Cos = 6, 35 Tan = 7, 36 Log = 8, 37 Exp = 9, 38 IfThenElse = 10, 39 GT = 11, 40 LT = 12, 41 AND = 13, 42 OR = 14, 43 NOT = 15, 44 Average = 16, 45 Call = 17, 46 Variable = 18, 47 LagVariable = 19, 48 Constant = 20, 49 Arg = 21, 50 Power = 22, 51 Root = 23, 52 TimeLag = 24, 53 Integral = 25, 54 Derivative = 26, 55 VariableCondition = 27, 56 Square = 28, 57 SquareRoot = 29, 58 Gamma = 30, 59 Psi = 31, 60 Dawson = 32, 61 ExponentialIntegralEi = 33, 62 CosineIntegral = 34, 63 SineIntegral = 35, 64 HyperbolicCosineIntegral = 36, 65 HyperbolicSineIntegral = 37, 66 FresnelCosineIntegral = 38, 67 FresnelSineIntegral = 39, 68 AiryA = 40, 69 AiryB = 41, 70 Norm = 42, 71 Erf = 43, 72 Bessel = 44, 73 XOR = 45, 74 FactorVariable = 46, 75 BinaryFactorVariable = 47, 76 Absolute = 48, 77 AnalyticQuotient = 49, 78 Cube = 50, 79 CubeRoot = 51, 80 Tanh = 52, 81 }; 27 82 public static class OpCodes { 28 public const byte Add = 1; 29 public const byte Sub = 2; 30 public const byte Mul = 3; 31 public const byte Div = 4; 32 33 public const byte Sin = 5; 34 public const byte Cos = 6; 35 public const byte Tan = 7; 36 37 public const byte Log = 8; 38 public const byte Exp = 9; 39 40 public const byte IfThenElse = 10; 41 42 public const byte GT = 11; 43 public const byte LT = 12; 44 45 public const byte AND = 13; 46 public const byte OR = 14; 47 public const byte NOT = 15; 48 public const byte XOR = 45; 49 50 51 public const byte Average = 16; 52 53 public const byte Call = 17; 54 55 public const byte Variable = 18; 56 public const byte LagVariable = 19; 57 public const byte Constant = 20; 58 public const byte Arg = 21; 59 60 public const byte Power = 22; 61 public const byte Root = 23; 62 public const byte TimeLag = 24; 63 public const byte Integral = 25; 64 public const byte Derivative = 26; 65 66 public const byte VariableCondition = 27; 67 68 public const byte Square = 28; 69 public const byte SquareRoot = 29; 70 public const byte Gamma = 30; 71 public const byte Psi = 31; 72 public const byte Dawson = 32; 73 public const byte ExponentialIntegralEi = 33; 74 public const byte CosineIntegral = 34; 75 public const byte SineIntegral = 35; 76 public const byte HyperbolicCosineIntegral = 36; 77 public const byte HyperbolicSineIntegral = 37; 78 public const byte FresnelCosineIntegral = 38; 79 public const byte FresnelSineIntegral = 39; 80 public const byte AiryA = 40; 81 public const byte AiryB = 41; 82 public const byte Norm = 42; 83 public const byte Erf = 43; 84 public const byte Bessel = 44; 85 public const byte FactorVariable = 46; 86 public const byte BinaryFactorVariable = 47; 83 // constants for API compatibility only 84 public const byte Add = (byte)OpCode.Add; 85 public const byte Sub =(byte)OpCode.Sub; 86 public const byte Mul =(byte)OpCode.Mul; 87 public const byte Div =(byte)OpCode.Div; 88 public const byte Sin =(byte)OpCode.Sin; 89 public const byte Cos =(byte)OpCode.Cos; 90 public const byte Tan =(byte)OpCode.Tan; 91 public const byte Log =(byte)OpCode.Log; 92 public const byte Exp = (byte)OpCode.Exp; 93 public const byte IfThenElse = (byte)OpCode.IfThenElse; 94 public const byte GT = (byte)OpCode.GT; 95 public const byte LT = (byte)OpCode.LT; 96 public const byte AND = (byte)OpCode.AND; 97 public const byte OR = (byte)OpCode.OR; 98 public const byte NOT = (byte)OpCode.NOT; 99 public const byte Average = (byte)OpCode.Average; 100 public const byte Call = (byte)OpCode.Call; 101 public const byte Variable = (byte)OpCode.Variable; 102 public const byte LagVariable = (byte)OpCode.LagVariable; 103 public const byte Constant = (byte)OpCode.Constant; 104 public const byte Arg = (byte)OpCode.Arg; 105 public const byte Power = (byte)OpCode.Power; 106 public const byte Root = (byte)OpCode.Root; 107 public const byte TimeLag = (byte)OpCode.TimeLag; 108 public const byte Integral = (byte)OpCode.Integral; 109 public const byte Derivative = (byte)OpCode.Derivative; 110 public const byte VariableCondition = (byte)OpCode.VariableCondition; 111 public const byte Square = (byte)OpCode.Square; 112 public const byte SquareRoot = (byte)OpCode.SquareRoot; 113 public const byte Gamma = (byte)OpCode.Gamma; 114 public const byte Psi = (byte)OpCode.Psi; 115 public const byte Dawson = (byte)OpCode.Dawson; 116 public const byte ExponentialIntegralEi = (byte)OpCode.ExponentialIntegralEi; 117 public const byte CosineIntegral = (byte)OpCode.CosineIntegral; 118 public const byte SineIntegral = (byte)OpCode.SineIntegral; 119 public const byte HyperbolicCosineIntegral = (byte)OpCode.HyperbolicCosineIntegral; 120 public const byte HyperbolicSineIntegral = (byte)OpCode.HyperbolicSineIntegral; 121 public const byte FresnelCosineIntegral = (byte)OpCode.FresnelCosineIntegral; 122 public const byte FresnelSineIntegral = (byte)OpCode.FresnelSineIntegral; 123 public const byte AiryA = (byte)OpCode.AiryA; 124 public const byte AiryB = (byte)OpCode.AiryB; 125 public const byte Norm = (byte)OpCode.Norm; 126 public const byte Erf = (byte)OpCode.Erf; 127 public const byte Bessel = (byte)OpCode.Bessel; 128 public const byte XOR = (byte)OpCode.XOR; 129 public const byte FactorVariable = (byte)OpCode.FactorVariable; 130 public const byte BinaryFactorVariable = (byte)OpCode.BinaryFactorVariable; 131 public const byte Absolute = (byte)OpCode.Absolute; 132 public const byte AnalyticQuotient = (byte)OpCode.AnalyticQuotient; 133 public const byte Cube = (byte)OpCode.Cube; 134 public const byte CubeRoot = (byte)OpCode.CubeRoot; 135 public const byte Tanh = (byte)OpCode.Tanh; 87 136 88 137 … … 95 144 { typeof(Cosine), OpCodes.Cos }, 96 145 { typeof(Tangent), OpCodes.Tan }, 146 { typeof (HyperbolicTangent), OpCodes.Tanh}, 97 147 { typeof(Logarithm), OpCodes.Log }, 98 148 { typeof(Exponential), OpCodes.Exp }, … … 113 163 { typeof(Power),OpCodes.Power}, 114 164 { typeof(Root),OpCodes.Root}, 115 { typeof(TimeLag), OpCodes.TimeLag}, 165 { typeof(TimeLag), OpCodes.TimeLag}, 116 166 { typeof(Integral), OpCodes.Integral}, 117 167 { typeof(Derivative), OpCodes.Derivative}, … … 135 185 { typeof(Bessel), OpCodes.Bessel}, 136 186 { typeof(FactorVariable), OpCodes.FactorVariable }, 137 { typeof(BinaryFactorVariable), OpCodes.BinaryFactorVariable } 187 { typeof(BinaryFactorVariable), OpCodes.BinaryFactorVariable }, 188 { typeof(Absolute), OpCodes.Absolute }, 189 { typeof(AnalyticQuotient), OpCodes.AnalyticQuotient }, 190 { typeof(Cube), OpCodes.Cube }, 191 { typeof(CubeRoot), OpCodes.CubeRoot } 138 192 }; 139 193 140 194 public static byte MapSymbolToOpCode(ISymbolicExpressionTreeNode treeNode) { 141 byte opCode; 142 if (symbolToOpcode.TryGetValue(treeNode.Symbol.GetType(), out opCode)) return opCode; 195 if (symbolToOpcode.TryGetValue(treeNode.Symbol.GetType(), out byte opCode)) return opCode; 143 196 else throw new NotSupportedException("Symbol: " + treeNode.Symbol); 144 197 } -
branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs
r16130 r17434 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-2018Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 30 30 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 31 31 using HeuristicLab.Parameters; 32 using H euristicLab.Persistence.Default.CompositeSerializers.Storable;32 using HEAL.Attic; 33 33 34 34 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 35 [Storable Class]35 [StorableType("DFA06F28-E224-4D93-9907-69792D24D1F9")] 36 36 [Item("SymbolicDataAnalysisExpressionCompiledTreeInterpreter", "Interpreter that converts the tree into a Linq.Expression then compiles it.")] 37 37 public sealed class SymbolicDataAnalysisExpressionCompiledTreeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter { … … 41 41 42 42 #region method info for the commonly called functions 43 private static readonly MethodInfo Abs = typeof(Math).GetMethod("Abs", new[] { typeof(double) }); 43 44 private static readonly MethodInfo Sin = typeof(Math).GetMethod("Sin", new[] { typeof(double) }); 44 45 private static readonly MethodInfo Cos = typeof(Math).GetMethod("Cos", new[] { typeof(double) }); 45 46 private static readonly MethodInfo Tan = typeof(Math).GetMethod("Tan", new[] { typeof(double) }); 47 private static readonly MethodInfo Tanh = typeof(Math).GetMethod("Tanh", new[] { typeof(double) }); 46 48 private static readonly MethodInfo Sqrt = typeof(Math).GetMethod("Sqrt", new[] { typeof(double) }); 47 49 private static readonly MethodInfo Floor = typeof(Math).GetMethod("Floor", new[] { typeof(double) }); … … 50 52 private static readonly MethodInfo Log = typeof(Math).GetMethod("Log", new[] { typeof(double) }); 51 53 private static readonly MethodInfo IsNaN = typeof(double).GetMethod("IsNaN"); 52 private static readonly MethodInfo IsAlmost = typeof(DoubleExtensions).GetMethod("IsAlmost" );54 private static readonly MethodInfo IsAlmost = typeof(DoubleExtensions).GetMethod("IsAlmost", new Type[] { typeof(double), typeof(double)}); 53 55 private static readonly MethodInfo Gamma = typeof(alglib).GetMethod("gammafunction", new[] { typeof(double) }); 54 56 private static readonly MethodInfo Psi = typeof(alglib).GetMethod("psi", new[] { typeof(double) }); … … 97 99 98 100 [StorableConstructor] 99 private SymbolicDataAnalysisExpressionCompiledTreeInterpreter(bool deserializing) 100 : base(deserializing) { 101 private SymbolicDataAnalysisExpressionCompiledTreeInterpreter(StorableConstructorFlag _) : base(_) { 101 102 } 102 103 … … 207 208 return Expression.Divide(result, Expression.Constant((double)node.SubtreeCount)); 208 209 } 210 case OpCodes.Absolute: { 211 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 212 return Expression.Call(Abs, arg); 213 } 209 214 case OpCodes.Cos: { 210 215 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); … … 219 224 return Expression.Call(Tan, arg); 220 225 } 226 case OpCodes.Tanh: { 227 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 228 return Expression.Call(Tanh, arg); 229 } 221 230 case OpCodes.Square: { 222 231 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 223 232 return Expression.Power(arg, Expression.Constant(2.0)); 233 } 234 case OpCodes.Cube: { 235 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 236 return Expression.Power(arg, Expression.Constant(3.0)); 224 237 } 225 238 case OpCodes.Power: { … … 231 244 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 232 245 return Expression.Call(Sqrt, arg); 246 } 247 case OpCodes.CubeRoot: { 248 var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 249 return Expression.Condition(Expression.LessThan(arg, Expression.Constant(0.0)), 250 Expression.Negate(Expression.Power(Expression.Negate(arg), Expression.Constant(1.0 / 3.0))), 251 Expression.Power(arg, Expression.Constant(1.0 / 3.0))); 233 252 } 234 253 case OpCodes.Root: { … … 493 512 Expression.Assign(result, Expression.Call(Bessel, arg))), 494 513 result); 514 } 515 case OpCodes.AnalyticQuotient: { 516 var x1 = MakeExpr(node.GetSubtree(0), variableIndices, row, columns); 517 var x2 = MakeExpr(node.GetSubtree(1), variableIndices, row, columns); 518 return Expression.Divide(x1, 519 Expression.Call(Sqrt, 520 Expression.Add( 521 Expression.Constant(1.0), 522 Expression.Multiply(x2, x2)))); 495 523 } 496 524 case OpCodes.IfThenElse: { -
branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs
r16130 r17434 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-2018Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 30 30 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 31 31 using HeuristicLab.Parameters; 32 using H euristicLab.Persistence.Default.CompositeSerializers.Storable;32 using HEAL.Attic; 33 33 34 34 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 35 [Storable Class]35 [StorableType("426718E3-2A57-4CA4-98A1-65EDD0B0BDBF")] 36 36 [Item("SymbolicDataAnalysisExpressionTreeILEmittingInterpreter", "Interpreter for symbolic expression trees.")] 37 37 public sealed class SymbolicDataAnalysisExpressionTreeILEmittingInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter { … … 45 45 private static MethodInfo sin = typeof(Math).GetMethod("Sin", new Type[] { typeof(double) }); 46 46 private static MethodInfo tan = typeof(Math).GetMethod("Tan", new Type[] { typeof(double) }); 47 private static MethodInfo tanh = typeof(Math).GetMethod("Tanh", new Type[] { typeof(double) }); 47 48 private static MethodInfo exp = typeof(Math).GetMethod("Exp", new Type[] { typeof(double) }); 48 49 private static MethodInfo log = typeof(Math).GetMethod("Log", new Type[] { typeof(double) }); … … 50 51 private static MethodInfo round = typeof(Math).GetMethod("Round", new Type[] { typeof(double) }); 51 52 private static MethodInfo sqrt = typeof(Math).GetMethod("Sqrt", new Type[] { typeof(double) }); 53 private static MethodInfo abs = typeof(Math).GetMethod("Abs", new Type[] { typeof(double) }); 52 54 53 55 private static MethodInfo airyA = thisType.GetMethod("AiryA", new Type[] { typeof(double) }); … … 103 105 104 106 [StorableConstructor] 105 private SymbolicDataAnalysisExpressionTreeILEmittingInterpreter( bool deserializing) : base(deserializing) { }107 private SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(StorableConstructorFlag _) : base(_) { } 106 108 107 109 private SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(SymbolicDataAnalysisExpressionTreeILEmittingInterpreter original, Cloner cloner) : base(original, cloner) { } … … 264 266 return; 265 267 } 268 case OpCodes.Absolute: { 269 CompileInstructions(il, state, ds); 270 il.Emit(System.Reflection.Emit.OpCodes.Call, abs); 271 return; 272 } 266 273 case OpCodes.Cos: { 267 274 CompileInstructions(il, state, ds); … … 277 284 CompileInstructions(il, state, ds); 278 285 il.Emit(System.Reflection.Emit.OpCodes.Call, tan); 286 return; 287 } 288 case OpCodes.Tanh: { 289 CompileInstructions(il, state, ds); 290 il.Emit(System.Reflection.Emit.OpCodes.Call, tanh); 279 291 return; 280 292 } … … 311 323 return; 312 324 } 325 case OpCodes.Cube: { 326 CompileInstructions(il, state, ds); 327 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 3.0); 328 il.Emit(System.Reflection.Emit.OpCodes.Call, power); 329 return; 330 } 313 331 case OpCodes.SquareRoot: { 314 332 CompileInstructions(il, state, ds); … … 316 334 return; 317 335 } 336 case OpCodes.CubeRoot: { 337 CompileInstructions(il, state, ds); 338 var c1 = il.DefineLabel(); 339 var end = il.DefineLabel(); 340 341 il.Emit(System.Reflection.Emit.OpCodes.Dup); // x 342 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 0.0); 343 il.Emit(System.Reflection.Emit.OpCodes.Clt); // x < 0? 344 il.Emit(System.Reflection.Emit.OpCodes.Brfalse, c1); 345 il.Emit(System.Reflection.Emit.OpCodes.Neg); // x = -x 346 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0 / 3.0); 347 il.Emit(System.Reflection.Emit.OpCodes.Call, power); 348 il.Emit(System.Reflection.Emit.OpCodes.Neg); // -Math.Pow(-x, 1/3) 349 il.Emit(System.Reflection.Emit.OpCodes.Br, end); 350 il.MarkLabel(c1); 351 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0 / 3.0); 352 il.Emit(System.Reflection.Emit.OpCodes.Call, power); 353 il.MarkLabel(end); 354 return; 355 } 318 356 case OpCodes.AiryA: { 319 357 CompileInstructions(il, state, ds); … … 389 427 CompileInstructions(il, state, ds); 390 428 il.Emit(System.Reflection.Emit.OpCodes.Call, sinIntegral); 429 return; 430 } 431 case OpCodes.AnalyticQuotient: { 432 CompileInstructions(il, state, ds); // x1 433 CompileInstructions(il, state, ds); // x2 434 435 il.Emit(System.Reflection.Emit.OpCodes.Dup); 436 il.Emit(System.Reflection.Emit.OpCodes.Mul); // x2*x2 437 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); 438 il.Emit(System.Reflection.Emit.OpCodes.Add); // 1+x2*x2 439 il.Emit(System.Reflection.Emit.OpCodes.Call, sqrt); 440 il.Emit(System.Reflection.Emit.OpCodes.Div); 391 441 return; 392 442 } … … 395 445 Label c1 = il.DefineLabel(); 396 446 CompileInstructions(il, state, ds); 397 il.Emit(System.Reflection.Emit.OpCodes.Ldc_ I4_0); // > 0447 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 0.0); // > 0 398 448 il.Emit(System.Reflection.Emit.OpCodes.Cgt); 399 449 il.Emit(System.Reflection.Emit.OpCodes.Brfalse, c1); … … 410 460 CompileInstructions(il, state, ds); 411 461 for (int i = 1; i < nArgs; i++) { 412 il.Emit(System.Reflection.Emit.OpCodes.Ldc_ I4_0); // > 0462 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 0.0); // > 0 413 463 il.Emit(System.Reflection.Emit.OpCodes.Cgt); 414 464 il.Emit(System.Reflection.Emit.OpCodes.Brfalse, falseBranch); 415 465 CompileInstructions(il, state, ds); 416 466 } 417 il.Emit(System.Reflection.Emit.OpCodes.Ldc_ I4_0); // > 0467 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 0.0); // > 0 418 468 il.Emit(System.Reflection.Emit.OpCodes.Cgt); 419 469 il.Emit(System.Reflection.Emit.OpCodes.Brfalse, falseBranch); … … 435 485 // complex definition because of special properties of NaN 436 486 il.Emit(System.Reflection.Emit.OpCodes.Dup); 437 il.Emit(System.Reflection.Emit.OpCodes.Ldc_ I4_0); // <= 0487 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 0.0); // <= 0 438 488 il.Emit(System.Reflection.Emit.OpCodes.Ble, nextArgBranch); 439 489 il.Emit(System.Reflection.Emit.OpCodes.Br, resultBranch); … … 443 493 } 444 494 il.MarkLabel(resultBranch); 445 il.Emit(System.Reflection.Emit.OpCodes.Ldc_ I4_0); // > 0495 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 0.0); // > 0 446 496 il.Emit(System.Reflection.Emit.OpCodes.Cgt); 447 497 il.Emit(System.Reflection.Emit.OpCodes.Brtrue, trueBranch); … … 456 506 case OpCodes.NOT: { 457 507 CompileInstructions(il, state, ds); 458 il.Emit(System.Reflection.Emit.OpCodes.Ldc_ I4_0); // > 0508 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 0.0); // > 0 459 509 il.Emit(System.Reflection.Emit.OpCodes.Cgt); 460 510 il.Emit(System.Reflection.Emit.OpCodes.Conv_R8); // convert to float64 … … 468 518 case OpCodes.XOR: { 469 519 CompileInstructions(il, state, ds); 470 il.Emit(System.Reflection.Emit.OpCodes.Ldc_ I4_0);520 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 0.0); 471 521 il.Emit(System.Reflection.Emit.OpCodes.Cgt);// > 0 472 522 473 523 for (int i = 1; i < nArgs; i++) { 474 524 CompileInstructions(il, state, ds); 475 il.Emit(System.Reflection.Emit.OpCodes.Ldc_ I4_0);525 il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 0.0); 476 526 il.Emit(System.Reflection.Emit.OpCodes.Cgt);// > 0 477 527 il.Emit(System.Reflection.Emit.OpCodes.Xor); -
branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs
r16130 r17434 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-2018Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 22 22 using System; 23 23 using System.Collections.Generic; 24 using System.Linq;25 24 using HeuristicLab.Common; 26 25 using HeuristicLab.Core; … … 28 27 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 29 28 using HeuristicLab.Parameters; 30 using H euristicLab.Persistence.Default.CompositeSerializers.Storable;29 using HEAL.Attic; 31 30 32 31 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 33 [Storable Class]32 [StorableType("FB94F333-B32A-44FB-A561-CBDE76693D20")] 34 33 [Item("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")] 35 34 public class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem, … … 70 69 71 70 [StorableConstructor] 72 protected SymbolicDataAnalysisExpressionTreeInterpreter( bool deserializing) : base(deserializing) { }71 protected SymbolicDataAnalysisExpressionTreeInterpreter(StorableConstructorFlag _) : base(_) { } 73 72 74 73 protected SymbolicDataAnalysisExpressionTreeInterpreter(SymbolicDataAnalysisExpressionTreeInterpreter original, … … 203 202 return sum / currentInstr.nArguments; 204 203 } 204 case OpCodes.Absolute: { 205 return Math.Abs(Evaluate(dataset, ref row, state)); 206 } 207 case OpCodes.Tanh: { 208 return Math.Tanh(Evaluate(dataset, ref row, state)); 209 } 205 210 case OpCodes.Cos: { 206 211 return Math.Cos(Evaluate(dataset, ref row, state)); … … 214 219 case OpCodes.Square: { 215 220 return Math.Pow(Evaluate(dataset, ref row, state), 2); 221 } 222 case OpCodes.Cube: { 223 return Math.Pow(Evaluate(dataset, ref row, state), 3); 216 224 } 217 225 case OpCodes.Power: { … … 223 231 return Math.Sqrt(Evaluate(dataset, ref row, state)); 224 232 } 233 case OpCodes.CubeRoot: { 234 var arg = Evaluate(dataset, ref row, state); 235 return arg < 0 ? -Math.Pow(-arg, 1.0 / 3.0) : Math.Pow(arg, 1.0 / 3.0); 236 } 225 237 case OpCodes.Root: { 226 238 double x = Evaluate(dataset, ref row, state); … … 340 352 if (double.IsNaN(x)) return double.NaN; 341 353 else return alglib.besseli0(x); 354 } 355 356 case OpCodes.AnalyticQuotient: { 357 var x1 = Evaluate(dataset, ref row, state); 358 var x2 = Evaluate(dataset, ref row, state); 359 return x1 / Math.Pow(1 + x2 * x2, 0.5); 342 360 } 343 361 case OpCodes.IfThenElse: { -
branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
r16130 r17434 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-2018Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 28 28 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 29 29 using HeuristicLab.Parameters; 30 using H euristicLab.Persistence.Default.CompositeSerializers.Storable;30 using HEAL.Attic; 31 31 32 32 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 33 [Storable Class]33 [StorableType("EF325166-E03A-44C4-83CE-7F07B836285E")] 34 34 [Item("SymbolicDataAnalysisExpressionTreeLinearInterpreter", "Fast linear (non-recursive) interpreter for symbolic expression trees. Does not support ADFs.")] 35 35 public sealed class SymbolicDataAnalysisExpressionTreeLinearInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter { … … 70 70 71 71 [StorableConstructor] 72 private SymbolicDataAnalysisExpressionTreeLinearInterpreter(bool deserializing) 73 : base(deserializing) { 72 private SymbolicDataAnalysisExpressionTreeLinearInterpreter(StorableConstructorFlag _) : base(_) { 74 73 interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter(); 75 74 } … … 222 221 if (instr.nArguments == 1) p = 1.0 / p; 223 222 instr.value = p; 223 } else if (instr.opCode == OpCodes.AnalyticQuotient) { 224 var x1 = code[instr.childIndex].value; 225 var x2 = code[instr.childIndex + 1].value; 226 instr.value = x1 / Math.Sqrt(1 + x2 * x2); 224 227 } else if (instr.opCode == OpCodes.Average) { 225 228 double s = code[instr.childIndex].value; … … 228 231 } 229 232 instr.value = s / instr.nArguments; 233 } else if (instr.opCode == OpCodes.Absolute) { 234 instr.value = Math.Abs(code[instr.childIndex].value); 235 } else if (instr.opCode == OpCodes.Tanh) { 236 instr.value = Math.Tanh(code[instr.childIndex].value); 230 237 } else if (instr.opCode == OpCodes.Cos) { 231 238 instr.value = Math.Cos(code[instr.childIndex].value); … … 236 243 } else if (instr.opCode == OpCodes.Square) { 237 244 instr.value = Math.Pow(code[instr.childIndex].value, 2); 245 } else if (instr.opCode == OpCodes.Cube) { 246 instr.value = Math.Pow(code[instr.childIndex].value, 3); 238 247 } else if (instr.opCode == OpCodes.Power) { 239 248 double x = code[instr.childIndex].value; … … 242 251 } else if (instr.opCode == OpCodes.SquareRoot) { 243 252 instr.value = Math.Sqrt(code[instr.childIndex].value); 253 } else if (instr.opCode == OpCodes.CubeRoot) { 254 var arg = code[instr.childIndex].value; 255 instr.value = arg < 0 ? -Math.Pow(-arg, 1.0 / 3.0) : Math.Pow(arg, 1.0 / 3.0); 244 256 } else if (instr.opCode == OpCodes.Root) { 245 257 double x = code[instr.childIndex].value; -
branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs
r17433 r17434 24 24 using System.Linq; 25 25 using System.Runtime.InteropServices; 26 using HEAL.Attic; 26 27 using HeuristicLab.Common; 27 28 using HeuristicLab.Core; … … 29 30 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 30 31 using HeuristicLab.Parameters; 31 using HEAL.Attic;32 32 33 33 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 34 34 [StorableType("91723319-8F15-4D33-B277-40AC7C7CF9AE")] 35 [Item("SymbolicDataAnalysisExpressionTreeNativeInterpreter", " An interpreter that wraps a native dll")]35 [Item("SymbolicDataAnalysisExpressionTreeNativeInterpreter", "Operator calling into native C++ code for tree interpretation.")] 36 36 public class SymbolicDataAnalysisExpressionTreeNativeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter { 37 37 private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions"; … … 50 50 #endregion 51 51 52 public void ClearState() { }53 54 52 public SymbolicDataAnalysisExpressionTreeNativeInterpreter() { 55 53 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); … … 66 64 } 67 65 68 private NativeInstruction[] Compile(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper) { 66 public static NativeInstruction[] Compile(ISymbolicExpressionTree tree, IDataset dataset, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper, out List<ISymbolicExpressionTreeNode> nodes) { 67 if (cachedData == null || cachedDataset != dataset) { 68 InitCache(dataset); 69 } 70 69 71 var root = tree.Root.GetSubtree(0).GetSubtree(0); 70 72 var code = new NativeInstruction[root.GetLength()]; 71 73 if (root.SubtreeCount > ushort.MaxValue) throw new ArgumentException("Number of subtrees is too big (>65.535)"); 72 74 code[0] = new NativeInstruction { narg = (ushort)root.SubtreeCount, opcode = opCodeMapper(root) }; 73 int c = 1, i = 0; 74 foreach (var node in root.IterateNodesBreadth()) { 75 int c = 1; 76 nodes = (List<ISymbolicExpressionTreeNode>)root.IterateNodesBreadth(); 77 for (int i = 0; i < nodes.Count; ++i) { 78 var node = nodes[i]; 75 79 for (int j = 0; j < node.SubtreeCount; ++j) { 76 80 var s = node.GetSubtree(j); … … 80 84 81 85 if (node is VariableTreeNode variable) { 82 code[i]. weight= variable.Weight;86 code[i].value = variable.Weight; 83 87 code[i].data = cachedData[variable.VariableName].AddrOfPinnedObject(); 84 88 } else if (node is ConstantTreeNode constant) { … … 88 92 code[i].childIndex = c; 89 93 c += node.SubtreeCount; 90 ++i;91 94 } 92 95 return code; … … 127 130 if (!rows.Any()) return Enumerable.Empty<double>(); 128 131 129 if (cachedData == null || cachedDataset != dataset) { 130 InitCache(dataset); 131 } 132 133 byte mapSupportedSymbols(ISymbolicExpressionTreeNode node) { 132 byte mapSupportedSymbols(ISymbolicExpressionTreeNode node) { 134 133 var opCode = OpCodes.MapSymbolToOpCode(node); 135 134 if (supportedOpCodes.Contains(opCode)) return opCode; 136 135 else throw new NotSupportedException($"The native interpreter does not support {node.Symbol.Name}"); 137 136 }; 138 var code = Compile(tree, mapSupportedSymbols);137 var code = Compile(tree, dataset, mapSupportedSymbols, out List<ISymbolicExpressionTreeNode> nodes); 139 138 140 139 var rowsArray = rows.ToArray(); 141 140 var result = new double[rowsArray.Length]; 142 143 NativeWrapper.GetValuesVectorized(code, code.Length, rowsArray, rowsArray.Length, result); 141 NativeWrapper.GetValues(code, code.Length, rowsArray, rowsArray.Length, result); 144 142 145 143 // when evaluation took place without any error, we can increment the counter … … 151 149 } 152 150 153 private void InitCache(IDataset dataset) { 151 public static Dictionary<ISymbolicExpressionTreeNode, double> OptimizeConstants(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows, string targetVariable, int iterations) { 152 byte mapSupportedSymbols(ISymbolicExpressionTreeNode node) { 153 var opCode = OpCodes.MapSymbolToOpCode(node); 154 if (supportedOpCodes.Contains(opCode)) return opCode; 155 else throw new NotSupportedException($"The native interpreter does not support {node.Symbol.Name}"); 156 }; 157 var code = Compile(tree, dataset, mapSupportedSymbols, out List<ISymbolicExpressionTreeNode> nodes); 158 if (iterations > 0) { 159 var target = dataset.GetDoubleValues(targetVariable, rows).ToArray(); 160 var rowsArray = rows.ToArray(); 161 var result = new double[rowsArray.Length]; 162 NativeWrapper.GetValues(code, code.Length, rowsArray, rowsArray.Length, result, target, iterations); 163 } 164 return Enumerable.Range(0, code.Length).Where(i => nodes[i] is SymbolicExpressionTreeTerminalNode).ToDictionary(i => nodes[i], i => code[i].value); 165 } 166 167 private static void InitCache(IDataset dataset) { 154 168 cachedDataset = dataset; 155 156 // free handles to old data157 if (cachedData != null) {158 foreach (var gch in cachedData.Values) {159 gch.Free();160 }161 cachedData = null;162 }163 164 // cache new data165 169 cachedData = new Dictionary<string, GCHandle>(); 166 170 foreach (var v in dataset.DoubleVariables) { … … 171 175 } 172 176 173 public void InitializeState() {177 public void ClearState() { 174 178 if (cachedData != null) { 175 179 foreach (var gch in cachedData.Values) { … … 181 185 EvaluatedSolutions = 0; 182 186 } 187 188 public void InitializeState() { 189 ClearState(); 190 } 183 191 } 184 192 }
Note: See TracChangeset
for help on using the changeset viewer.