Changeset 9758
- Timestamp:
- 07/25/13 17:04:27 (11 years ago)
- Location:
- branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/LinearInstruction.cs
r9738 r9758 23 23 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding { 24 24 // total size of this class should be small to improve cache access while executing the code 25 public class LinearInstruction { 26 // the tree node can hold additional data that is necessary for the execution of this instruction 27 public ISymbolicExpressionTreeNode dynamicNode; 28 // op code of the function that determines what operation should be executed 29 public byte opCode; 30 // number of arguments of the current instruction 31 public byte nArguments; 32 // an optional object value (addresses for calls, argument index for arguments) 33 public object iArg0; 34 25 public class LinearInstruction : Instruction { 35 26 public double value; 36 37 public int childIndex; 27 public byte childIndex; 38 28 } 39 29 } -
branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeLinearCompiler.cs
r9739 r9758 34 34 var nodes = root.IterateNodesBreadth().ToArray(); 35 35 for (int i = 0; i != nodes.Length; ++i) { 36 code[i].childIndex = code.Count; 37 code.AddRange(nodes[i].Subtrees.Select(s => new LinearInstruction { 38 dynamicNode = s, nArguments = (byte)s.SubtreeCount, opCode = opCodeMapper(s) 39 })); 36 code[i].childIndex = (byte)code.Count; 37 code.AddRange(nodes[i].Subtrees.Select(s => new LinearInstruction { dynamicNode = s, nArguments = (byte)s.SubtreeCount, opCode = opCodeMapper(s) })); 40 38 } 41 39 -
branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
r9739 r9758 32 32 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 33 33 [StorableClass] 34 [Item("SymbolicDataAnalysisExpressionTreeLinearInterpreter", "Linear (non-recursive) interpreter for symbolic expression trees (does not support ADFs).")]35 public class SymbolicDataAnalysisExpressionTreeLinearInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {34 [Item("SymbolicDataAnalysisExpressionTreeLinearInterpreter", "Linear (non-recursive) interpreter for symbolic expression trees. This interpreter is faster but does not support Integral, Derivative, TimeLag or ADF function nodes.")] 35 public sealed class SymbolicDataAnalysisExpressionTreeLinearInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter { 36 36 private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic"; 37 37 private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions"; … … 46 46 47 47 #region parameter properties 48 49 48 public IValueParameter<BoolValue> CheckExpressionsWithIntervalArithmeticParameter { 50 49 get { return (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; } … … 54 53 get { return (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; } 55 54 } 56 57 55 #endregion 58 56 59 57 #region properties 60 61 58 public BoolValue CheckExpressionsWithIntervalArithmetic { 62 59 get { return CheckExpressionsWithIntervalArithmeticParameter.Value; } 63 60 set { CheckExpressionsWithIntervalArithmeticParameter.Value = value; } 64 61 } 65 66 62 public IntValue EvaluatedSolutions { 67 63 get { return EvaluatedSolutionsParameter.Value; } 68 64 set { EvaluatedSolutionsParameter.Value = value; } 69 65 } 70 71 66 #endregion 72 67 73 68 [StorableConstructor] 74 pr otectedSymbolicDataAnalysisExpressionTreeLinearInterpreter(bool deserializing)69 private SymbolicDataAnalysisExpressionTreeLinearInterpreter(bool deserializing) 75 70 : base(deserializing) { 76 71 } 77 72 78 pr otectedSymbolicDataAnalysisExpressionTreeLinearInterpreter(73 private SymbolicDataAnalysisExpressionTreeLinearInterpreter( 79 74 SymbolicDataAnalysisExpressionTreeLinearInterpreter original, Cloner cloner) 80 75 : base(original, cloner) { … … 86 81 87 82 public SymbolicDataAnalysisExpressionTreeLinearInterpreter() 88 : base("SymbolicDataAnalysisExpressionTreeLinearInterpreter", " Interpreter for symbolic expression trees including automatically defined functions.") {83 : base("SymbolicDataAnalysisExpressionTreeLinearInterpreter", "Linear (non-recursive) interpreter for symbolic expression trees (does not support ADFs).") { 89 84 Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); 90 85 Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 91 86 } 92 87 93 pr otectedSymbolicDataAnalysisExpressionTreeLinearInterpreter(string name, string description)88 private SymbolicDataAnalysisExpressionTreeLinearInterpreter(string name, string description) 94 89 : base(name, description) { 95 90 Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false))); … … 123 118 124 119 var code = SymbolicExpressionTreeLinearCompiler.Compile(tree, OpCodes.MapSymbolToOpCode); 125 PrepareIn terpreterState(code, dataset);120 PrepareInstructions(code, dataset); 126 121 return rows.Select(row => Evaluate(dataset, ref row, code)); 127 122 } 128 123 129 private static void PrepareIn terpreterState(LinearInstruction[] code, Dataset dataset) {124 private static void PrepareInstructions(LinearInstruction[] code, Dataset dataset) { 130 125 for (int i = code.Length - 1; i >= 0; --i) { 131 126 var instr = code[i]; … … 159 154 private static double Evaluate(Dataset dataset, ref int row, LinearInstruction[] code) { 160 155 for (int i = code.Length - 1; i >= 0; --i) { 156 if (code[i].opCode == OpCodes.Constant) continue; 157 #region opcode switch 161 158 var instr = code[i]; 162 if (instr.opCode == OpCodes.Constant) continue;163 #region opcode switch164 159 switch (instr.opCode) { 165 160 case OpCodes.Variable: { … … 241 236 case OpCodes.Tan: { 242 237 instr.value = Math.Tan(code[instr.childIndex].value); 238 } 239 break; 240 case OpCodes.Square: { 241 instr.value = Math.Pow(code[instr.childIndex].value, 2); 242 } 243 break; 244 case OpCodes.Power: { 245 double x = code[instr.childIndex].value; 246 double y = Math.Round(code[instr.childIndex + 1].value); 247 instr.value = Math.Pow(x, y); 248 } 249 break; 250 case OpCodes.SquareRoot: { 251 instr.value = Math.Sqrt(code[instr.childIndex].value); 243 252 } 244 253 break; … … 422 431 } 423 432 break; 424 case OpCodes.TimeLag: {425 throw new NotSupportedException();426 }427 case OpCodes.Integral: {428 throw new NotSupportedException();429 }430 case OpCodes.Derivative: {431 throw new NotSupportedException();432 }433 case OpCodes.Arg: {434 throw new NotSupportedException();435 }436 433 default: 437 throw new NotSupportedException(); 434 var errorText = string.Format("The {0} symbol is not supported by the linear interpreter. To support this symbol, please use another interpreter.", instr.dynamicNode.Symbol.Name); 435 throw new NotSupportedException(errorText); 438 436 } 439 437 #endregion -
branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs
r9735 r9758 149 149 [TestMethod] 150 150 public void SymbolicDataAnalysisExpressionTreeInterpreterEvaluateTest() { 151 var interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter(); 151 152 Dataset ds = new Dataset(new string[] { "Y", "A", "B" }, new double[,] { 152 153 { 1.0, 1.0, 1.0 }, … … 164 165 }); 165 166 166 var interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();167 167 EvaluateTerminals(interpreter, ds); 168 168 EvaluateOperations(interpreter, ds); 169 EvaluateTimeSymbols(interpreter, ds); 169 170 EvaluateAdf(interpreter, ds); 171 } 172 173 [TestMethod] 174 public void SymbolicDataAnalysisExpressionTreeLinearInterpreterEvaluateTest() { 175 var interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter(); 176 Dataset ds = new Dataset(new string[] { "Y", "A", "B" }, new double[,] { 177 { 1.0, 1.0, 1.0 }, 178 { 2.0, 2.0, 2.0 }, 179 { 3.0, 1.0, 2.0 }, 180 { 4.0, 1.0, 1.0 }, 181 { 5.0, 2.0, 2.0 }, 182 { 6.0, 1.0, 2.0 }, 183 { 7.0, 1.0, 1.0 }, 184 { 8.0, 2.0, 2.0 }, 185 { 9.0, 1.0, 2.0 }, 186 { 10.0, 1.0, 1.0 }, 187 { 11.0, 2.0, 2.0 }, 188 { 12.0, 1.0, 2.0 } 189 }); 190 //time symbols and ADFs not supported by the linear interpreter 191 EvaluateTerminals(interpreter, ds); 192 EvaluateOperations(interpreter, ds); 170 193 } 171 194 … … 190 213 EvaluateTerminals(interpreter, ds); 191 214 EvaluateOperations(interpreter, ds); 215 } 216 217 private void EvaluateTimeSymbols(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds) { 218 // integral 219 Evaluate(interpreter, ds, "(integral -1.0 (variable 1.0 a)) ", 1, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1)); 220 Evaluate(interpreter, ds, "(integral -1.0 (lagVariable 1.0 a 1)) ", 1, ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2)); 221 Evaluate(interpreter, ds, "(integral -2.0 (variable 1.0 a)) ", 2, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2)); 222 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)); 223 Evaluate(interpreter, ds, "(integral -2.0 3.0)", 1, 9.0); 224 225 // derivative 226 // (f_0 + 2 * f_1 - 2 * f_3 - f_4) / 8; // h = 1 227 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); 228 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); 229 Evaluate(interpreter, ds, "(diff (* (variable 1.0 a) (variable 1.0 b)))", 5, + 230 (ds.GetDoubleValue("A", 5) * ds.GetDoubleValue("B", 5) + 231 2 * ds.GetDoubleValue("A", 4) * ds.GetDoubleValue("B", 4) - 232 2 * ds.GetDoubleValue("A", 2) * ds.GetDoubleValue("B", 2) - 233 ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1)) / 8.0); 234 Evaluate(interpreter, ds, "(diff -2.0 3.0)", 5, 0.0); 235 236 // timelag 237 Evaluate(interpreter, ds, "(lag -1.0 (lagVariable 1.0 a 2)) ", 1, ds.GetDoubleValue("A", 2)); 238 Evaluate(interpreter, ds, "(lag -2.0 (lagVariable 1.0 a 2)) ", 2, ds.GetDoubleValue("A", 2)); 239 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)); 240 Evaluate(interpreter, ds, "(lag -2.0 3.0)", 1, 3.0); 192 241 } 193 242 … … 358 407 Evaluate(interpreter, ds, "(lagVariable 1.0 a 1) ", 0, ds.GetDoubleValue("A", 1)); 359 408 360 // integral361 Evaluate(interpreter, ds, "(integral -1.0 (variable 1.0 a)) ", 1, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1));362 Evaluate(interpreter, ds, "(integral -1.0 (lagVariable 1.0 a 1)) ", 1, ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));363 Evaluate(interpreter, ds, "(integral -2.0 (variable 1.0 a)) ", 2, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));364 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));365 Evaluate(interpreter, ds, "(integral -2.0 3.0)", 1, 9.0);366 367 // derivative368 // (f_0 + 2 * f_1 - 2 * f_3 - f_4) / 8; // h = 1369 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);370 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);371 Evaluate(interpreter, ds, "(diff (* (variable 1.0 a) (variable 1.0 b)))", 5, +372 (ds.GetDoubleValue("A", 5) * ds.GetDoubleValue("B", 5) +373 2 * ds.GetDoubleValue("A", 4) * ds.GetDoubleValue("B", 4) -374 2 * ds.GetDoubleValue("A", 2) * ds.GetDoubleValue("B", 2) -375 ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1)) / 8.0);376 Evaluate(interpreter, ds, "(diff -2.0 3.0)", 5, 0.0);377 378 // timelag379 Evaluate(interpreter, ds, "(lag -1.0 (lagVariable 1.0 a 2)) ", 1, ds.GetDoubleValue("A", 2));380 Evaluate(interpreter, ds, "(lag -2.0 (lagVariable 1.0 a 2)) ", 2, ds.GetDoubleValue("A", 2));381 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));382 Evaluate(interpreter, ds, "(lag -2.0 3.0)", 1, 3.0);383 384 409 { 385 410 // special functions … … 434 459 Evaluate(interpreter, ds, "(expint " + x + ")", 0, alglib.exponentialintegralei(x)); 435 460 }; 436 437 438 461 439 462 foreach (var e in new[] { -2.0, -1.0, 0.0, 1.0, 2.0 }) {
Note: See TracChangeset
for help on using the changeset viewer.