Changeset 17756 for branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter
- Timestamp:
- 09/24/20 10:16:49 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs
r17742 r17756 43 43 44 44 public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter => 45 (IFixedValueParameter<IntValue>) 45 (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; 46 46 47 47 public IFixedValueParameter<IntValue> MinSplittingWithParameter => 48 (IFixedValueParameter<IntValue>) 48 (IFixedValueParameter<IntValue>)Parameters[MinSplittingWidthParameterName]; 49 49 50 50 public IFixedValueParameter<IntValue> MaxSplittingDepthParameter => 51 (IFixedValueParameter<IntValue>) 51 (IFixedValueParameter<IntValue>)Parameters[MaxSplittingDepthParameterName]; 52 52 53 53 public IFixedValueParameter<BoolValue> UseIntervalSplittingParameter => 54 (IFixedValueParameter<BoolValue>) 54 (IFixedValueParameter<BoolValue>)Parameters[UseIntervalSplittingParameterName]; 55 55 56 56 public int MinSplittingWidth { … … 109 109 public Interval GetSymbolicExpressionTreeInterval( 110 110 ISymbolicExpressionTree tree, IDataset dataset, 111 IEnumerable<int> rows = null , int splitDirection = 0) {111 IEnumerable<int> rows = null) { 112 112 var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows); 113 113 return GetSymbolicExpressionTreeInterval(tree, variableRanges); … … 117 117 ISymbolicExpressionTree tree, IDataset dataset, 118 118 out IDictionary<ISymbolicExpressionTreeNode, Interval> 119 nodeIntervals, IEnumerable<int> rows = null , int splitDirection = 0) {119 nodeIntervals, IEnumerable<int> rows = null) { 120 120 var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows); 121 121 return GetSymbolicExpressionTreeIntervals(tree, variableRanges, out nodeIntervals); … … 124 124 public Interval GetSymbolicExpressionTreeInterval( 125 125 ISymbolicExpressionTree tree, 126 IReadOnlyDictionary<string, Interval> variableRanges , int splitDirection = 0) {126 IReadOnlyDictionary<string, Interval> variableRanges) { 127 127 lock (syncRoot) { 128 128 EvaluatedSolutions++; … … 133 133 if (UseIntervalSplitting) { 134 134 outputInterval = GetSymbolicExpressionTreeIntervals(tree, variableRanges, 135 out var nodeIntervals);135 out var _); 136 136 } else { 137 137 var instructionCount = 0; … … 150 150 IReadOnlyDictionary<string, Interval> variableRanges, 151 151 out IDictionary<ISymbolicExpressionTreeNode, Interval> 152 nodeIntervals , int splitDirection = 0) {152 nodeIntervals) { 153 153 lock (syncRoot) { 154 154 EvaluatedSolutions++; … … 171 171 //outputInterval = EvaluateRecursive(instructions, intervals, writeableVariableRanges, variables, MinSplittingWidth, MaxSplittingDepth, 172 172 // ref currIndex, ref currDepth, tree); 173 outputInterval = EvaluateWithSplitting(instructions, intervals, writeableVariableRanges , splitDirection);173 outputInterval = EvaluateWithSplitting(instructions, intervals, writeableVariableRanges); 174 174 } else { 175 175 var instructionCount = 0; … … 212 212 var code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode); 213 213 foreach (var instr in code.Where(i => i.opCode == OpCodes.Variable)) { 214 var variableTreeNode = (VariableTreeNode) 214 var variableTreeNode = (VariableTreeNode)instr.dynamicNode; 215 215 instr.data = variableRanges[variableTreeNode.VariableName]; 216 216 } … … 221 221 public static Interval EvaluateWithSplitting(Instruction[] instructions, 222 222 IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals, 223 IDictionary<string, Interval> variableIntervals, 224 int splitDirection = 0) { 225 if (splitDirection == 0) { 226 var savedIntervals = variableIntervals.ToDictionary(entry => entry.Key, entry => entry.Value); 227 var minimization = PerformSplitting(instructions, nodeIntervals, variableIntervals, -1); 228 var maximization = PerformSplitting(instructions, nodeIntervals, savedIntervals, 1); 229 230 return new Interval(minimization.LowerBound, maximization.UpperBound); 231 } 232 233 return PerformSplitting(instructions, nodeIntervals, variableIntervals, splitDirection); 234 } 235 236 private static Interval PerformSplitting(Instruction[] instructions, 237 IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals, 238 IDictionary<string, Interval> variableIntervals, int splitDirection) { 239 SortedList<Tuple<double, List<Interval>>, Interval> priorityList = null; 240 priorityList = splitDirection == -1 ? new SortedList<Tuple<double, List<Interval>>, Interval>(new BoxMinimizer()) : new SortedList<Tuple<double, List<Interval>>, Interval>(new BoxMaximizer()); 223 IDictionary<string, Interval> variableIntervals) { 224 var savedIntervals = variableIntervals.ToDictionary(entry => entry.Key, entry => entry.Value); 225 var min = FindBound(instructions, nodeIntervals, variableIntervals, minimization: true); 226 var max = FindBound(instructions, nodeIntervals, savedIntervals, minimization: false); 227 228 return new Interval(min, max); 229 } 230 231 232 private static double FindBound(Instruction[] instructions, 233 IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals, 234 IDictionary<string, Interval> variableIntervals, bool minimization = true) { 235 SortedSet<BoxBound> prioQ = new SortedSet<BoxBound>(); 236 241 237 var ic = 0; 242 238 //Calculate full box 243 239 IReadOnlyDictionary<string, Interval> readonlyRanges = variableIntervals.ToDictionary(k => k.Key, k => k.Value); 244 var fullbox = Evaluate(instructions, ref ic, nodeIntervals, readonlyRanges); 245 var box = variableIntervals.Keys.Select(k => variableIntervals[k]).ToList(); 246 priorityList.Add( 247 splitDirection == -1 248 ? new Tuple<double, List<Interval>>(fullbox.LowerBound, box) 249 : new Tuple<double, List<Interval>>(fullbox.UpperBound, box), fullbox); 250 240 var interval = Evaluate(instructions, ref ic, nodeIntervals, readonlyRanges); 241 // the order of keys in a dictionary is guaranteed to be the same order as values in a dictionary 242 // https://docs.microsoft.com/en-us/dotnet/api/system.collections.idictionary.keys?view=netcore-3.1#remarks 243 var box = variableIntervals.Values; 244 if(minimization) { 245 prioQ.Add(new BoxBound(box, interval.LowerBound)); 246 } else { 247 prioQ.Add(new BoxBound(box, -interval.UpperBound)); 248 } 249 250 // TODO a fixed limit for depth?! 251 251 for (var depth = 0; depth < 200; ++depth) { 252 var firstBox = priorityList.First();253 prio rityList.RemoveAt(0);254 255 var boxes = Split(firstBox.Key.Item2);256 257 foreach (var b in boxes) {258 var i = 0;259 foreach (var k in readonlyRanges.Keys) {260 variableIntervals[k] = b.ToList()[i];261 ++i;252 var currentBound = prioQ.Min; 253 prioQ.Remove(currentBound); 254 255 var newBoxes = Split(currentBound.box); 256 257 foreach (var newBox in newBoxes) { 258 var intervalEnum = newBox.GetEnumerator(); 259 var keyEnum = readonlyRanges.Keys.GetEnumerator(); 260 while (intervalEnum.MoveNext() & keyEnum.MoveNext()) { 261 variableIntervals[keyEnum.Current] = intervalEnum.Current; 262 262 } 263 263 … … 265 265 var res = Evaluate(instructions, ref ic, nodeIntervals, 266 266 new ReadOnlyDictionary<string, Interval>(variableIntervals)); 267 priorityList.Add( 268 splitDirection == -1 269 ? new Tuple<double, List<Interval>>(res.LowerBound, b.ToList()) 270 : new Tuple<double, List<Interval>>(res.UpperBound, b.ToList()), res); 267 if (minimization) { 268 prioQ.Add(new BoxBound(newBox, interval.LowerBound)); 269 } else { 270 prioQ.Add(new BoxBound(newBox, -interval.UpperBound)); 271 } 271 272 } 272 273 } 273 274 274 //Calculate final interval 275 var final = new Interval(0, 0); 276 277 return priorityList.Aggregate(final, (current, b) => current | b.Value); 275 return minimization ? 276 prioQ.First().bound : 277 -prioQ.First().bound; 278 278 } 279 279 280 280 private static IEnumerable<IEnumerable<Interval>> Split(List<Interval> box) { 281 var boxes = box.Select(region => region.Split()).Select(split => new List<Interval> { split.Item1, split.Item2})281 var boxes = box.Select(region => region.Split()).Select(split => new List<Interval> { split.Item1, split.Item2 }) 282 282 .ToList(); 283 283 … … 285 285 } 286 286 287 private class BoxMinimizer : IComparer<Tuple<double, List<Interval>>> { 288 public int Compare(Tuple<double, List<Interval>> x, Tuple<double, List<Interval>> y) { 289 var result = x.Item1.CompareTo(y.Item1); 290 291 if (result == 0) { 292 var sizeBox2 = y.Item2.Aggregate(1.0, (current, region) => current * region.Width); 293 var sizeBox1 = x.Item2.Aggregate(1.0, (current, region) => current * region.Width); 294 295 if (sizeBox2 < sizeBox1) return -1; 296 297 return 1; 287 // a multi-dimensional box with an associated bound 288 // boxbounds are ordered first by bound (smaller first), then by size of box (smaller first) then by extent in each dimension 289 private class BoxBound : IComparable<BoxBound> { 290 public List<Interval> box; 291 public double bound; 292 public BoxBound(IEnumerable<Interval> box, double bound) { 293 this.box = new List<Interval>(box); 294 this.bound = bound; 295 } 296 public int CompareTo(BoxBound other) { 297 if (bound != other.bound) return bound.CompareTo(other.bound); 298 299 var thisSize = box.Aggregate(1.0, (current, dimExtent) => current * dimExtent.Width); 300 var otherSize = other.box.Aggregate(1.0, (current, dimExtent) => current * dimExtent.Width); 301 if (thisSize != otherSize) return thisSize.CompareTo(otherSize); 302 303 for(int i=0;i<box.Count;i++) { 304 if (box[i].Width != other.box[i].Width) return box[i].Width.CompareTo(other.box[i].Width); 298 305 } 299 300 return result; 301 } 302 } 303 304 private class BoxMaximizer : IComparer<Tuple<double, List<Interval>>> { 305 public int Compare(Tuple<double, List<Interval>> x, Tuple<double, List<Interval>> y) { 306 var result = y.Item1.CompareTo(x.Item1); 307 308 if (result == 0) { 309 var sizeBox2 = y.Item2.Aggregate(1.0, (current, region) => current * region.Width); 310 var sizeBox1 = x.Item2.Aggregate(1.0, (current, region) => current * region.Width); 311 312 if (sizeBox2 > sizeBox1) return -1; 313 314 return 1; 315 } 316 317 return result; 306 return 0; 318 307 } 319 308 } … … 379 368 //Variables, Constants, ... 380 369 case OpCodes.Variable: { 381 var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;382 var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight);383 //var variableInterval = (Interval)currentInstr.data;384 385 Interval variableInterval;386 if (variableIntervals != null && variableIntervals.ContainsKey(variableTreeNode.VariableName))387 variableInterval = variableIntervals[variableTreeNode.VariableName];388 else389 variableInterval = (Interval)currentInstr.data;390 391 result = Interval.Multiply(variableInterval, weightInterval);392 break;393 }370 var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode; 371 var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight); 372 //var variableInterval = (Interval)currentInstr.data; 373 374 Interval variableInterval; 375 if (variableIntervals != null && variableIntervals.ContainsKey(variableTreeNode.VariableName)) 376 variableInterval = variableIntervals[variableTreeNode.VariableName]; 377 else 378 variableInterval = (Interval)currentInstr.data; 379 380 result = Interval.Multiply(variableInterval, weightInterval); 381 break; 382 } 394 383 case OpCodes.Constant: { 395 var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode;396 result = new Interval(constTreeNode.Value, constTreeNode.Value);397 break;398 }384 var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode; 385 result = new Interval(constTreeNode.Value, constTreeNode.Value); 386 break; 387 } 399 388 //Elementary arithmetic rules 400 389 case OpCodes.Add: { 401 //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);402 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);403 for (var i = 1; i < currentInstr.nArguments; i++) {404 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);405 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);406 result = Interval.Add(result, argumentInterval);407 }408 409 break;410 }390 //result = Evaluate(instructions, ref instructionCounter, nodeIntervals); 391 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 392 for (var i = 1; i < currentInstr.nArguments; i++) { 393 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 394 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 395 result = Interval.Add(result, argumentInterval); 396 } 397 398 break; 399 } 411 400 case OpCodes.Sub: { 412 //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);413 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);414 if (currentInstr.nArguments == 1)415 result = Interval.Multiply(new Interval(-1, -1), result);416 417 for (var i = 1; i < currentInstr.nArguments; i++) {418 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);419 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);420 result = Interval.Subtract(result, argumentInterval);421 }422 423 break;424 }401 //result = Evaluate(instructions, ref instructionCounter, nodeIntervals); 402 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 403 if (currentInstr.nArguments == 1) 404 result = Interval.Multiply(new Interval(-1, -1), result); 405 406 for (var i = 1; i < currentInstr.nArguments; i++) { 407 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 408 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 409 result = Interval.Subtract(result, argumentInterval); 410 } 411 412 break; 413 } 425 414 case OpCodes.Mul: { 426 //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);427 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);428 for (var i = 1; i < currentInstr.nArguments; i++) {429 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);430 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);431 result = Interval.Multiply(result, argumentInterval);432 }433 434 break;435 }415 //result = Evaluate(instructions, ref instructionCounter, nodeIntervals); 416 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 417 for (var i = 1; i < currentInstr.nArguments; i++) { 418 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 419 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 420 result = Interval.Multiply(result, argumentInterval); 421 } 422 423 break; 424 } 436 425 case OpCodes.Div: { 437 //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);438 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);439 if (currentInstr.nArguments == 1)440 result = Interval.Divide(new Interval(1, 1), result);441 442 for (var i = 1; i < currentInstr.nArguments; i++) {443 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);444 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);445 result = Interval.Divide(result, argumentInterval);446 }447 448 break;449 }426 //result = Evaluate(instructions, ref instructionCounter, nodeIntervals); 427 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 428 if (currentInstr.nArguments == 1) 429 result = Interval.Divide(new Interval(1, 1), result); 430 431 for (var i = 1; i < currentInstr.nArguments; i++) { 432 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 433 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 434 result = Interval.Divide(result, argumentInterval); 435 } 436 437 break; 438 } 450 439 //Trigonometric functions 451 440 case OpCodes.Sin: { 452 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);453 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);454 result = Interval.Sine(argumentInterval);455 break;456 }441 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 442 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 443 result = Interval.Sine(argumentInterval); 444 break; 445 } 457 446 case OpCodes.Cos: { 458 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);459 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);460 result = Interval.Cosine(argumentInterval);461 break;462 }447 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 448 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 449 result = Interval.Cosine(argumentInterval); 450 break; 451 } 463 452 case OpCodes.Tan: { 464 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);465 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);466 result = Interval.Tangens(argumentInterval);467 break;468 }453 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 454 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 455 result = Interval.Tangens(argumentInterval); 456 break; 457 } 469 458 case OpCodes.Tanh: { 470 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);471 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);472 result = Interval.HyperbolicTangent(argumentInterval);473 break;474 }459 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 460 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 461 result = Interval.HyperbolicTangent(argumentInterval); 462 break; 463 } 475 464 //Exponential functions 476 465 case OpCodes.Log: { 477 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);478 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);479 result = Interval.Logarithm(argumentInterval);480 break;481 }466 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 467 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 468 result = Interval.Logarithm(argumentInterval); 469 break; 470 } 482 471 case OpCodes.Exp: { 483 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);484 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);485 result = Interval.Exponential(argumentInterval);486 break;487 }472 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 473 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 474 result = Interval.Exponential(argumentInterval); 475 break; 476 } 488 477 case OpCodes.Square: { 489 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);490 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);491 result = Interval.Square(argumentInterval);492 break;493 }478 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 479 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 480 result = Interval.Square(argumentInterval); 481 break; 482 } 494 483 case OpCodes.SquareRoot: { 495 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);496 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);497 result = Interval.SquareRoot(argumentInterval);498 break;499 }484 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 485 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 486 result = Interval.SquareRoot(argumentInterval); 487 break; 488 } 500 489 case OpCodes.Cube: { 501 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);502 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);503 result = Interval.Cube(argumentInterval);504 break;505 }490 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 491 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 492 result = Interval.Cube(argumentInterval); 493 break; 494 } 506 495 case OpCodes.CubeRoot: { 507 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);508 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);509 result = Interval.CubicRoot(argumentInterval);510 break;511 }496 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 497 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 498 result = Interval.CubicRoot(argumentInterval); 499 break; 500 } 512 501 case OpCodes.Absolute: { 513 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);514 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);515 result = Interval.Absolute(argumentInterval);516 break;517 }502 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 503 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 504 result = Interval.Absolute(argumentInterval); 505 break; 506 } 518 507 case OpCodes.AnalyticQuotient: { 519 //result = Evaluate(instructions, ref instructionCounter, nodeIntervals);520 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);521 for (var i = 1; i < currentInstr.nArguments; i++) {522 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);523 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);524 result = Interval.AnalyticalQuotient(result, argumentInterval);525 }526 527 break;528 }508 //result = Evaluate(instructions, ref instructionCounter, nodeIntervals); 509 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 510 for (var i = 1; i < currentInstr.nArguments; i++) { 511 //var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals); 512 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 513 result = Interval.AnalyticalQuotient(result, argumentInterval); 514 } 515 516 break; 517 } 529 518 default: 530 519 throw new NotSupportedException($"The tree contains the unknown symbol {currentInstr.dynamicNode.Symbol}");
Note: See TracChangeset
for help on using the changeset viewer.