Changeset 17756


Ignore:
Timestamp:
09/24/20 10:16:49 (22 months ago)
Author:
gkronber
Message:

#3073 suggested refactoring / fix for splitting algorithm

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3073_IA_constraint_splitting/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs

    r17742 r17756  
    4343
    4444    public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter =>
    45       (IFixedValueParameter<IntValue>) Parameters[EvaluatedSolutionsParameterName];
     45      (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName];
    4646
    4747    public IFixedValueParameter<IntValue> MinSplittingWithParameter =>
    48       (IFixedValueParameter<IntValue>) Parameters[MinSplittingWidthParameterName];
     48      (IFixedValueParameter<IntValue>)Parameters[MinSplittingWidthParameterName];
    4949
    5050    public IFixedValueParameter<IntValue> MaxSplittingDepthParameter =>
    51       (IFixedValueParameter<IntValue>) Parameters[MaxSplittingDepthParameterName];
     51      (IFixedValueParameter<IntValue>)Parameters[MaxSplittingDepthParameterName];
    5252
    5353    public IFixedValueParameter<BoolValue> UseIntervalSplittingParameter =>
    54       (IFixedValueParameter<BoolValue>) Parameters[UseIntervalSplittingParameterName];
     54      (IFixedValueParameter<BoolValue>)Parameters[UseIntervalSplittingParameterName];
    5555
    5656    public int MinSplittingWidth {
     
    109109    public Interval GetSymbolicExpressionTreeInterval(
    110110      ISymbolicExpressionTree tree, IDataset dataset,
    111       IEnumerable<int> rows = null, int splitDirection = 0) {
     111      IEnumerable<int> rows = null) {
    112112      var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
    113113      return GetSymbolicExpressionTreeInterval(tree, variableRanges);
     
    117117      ISymbolicExpressionTree tree, IDataset dataset,
    118118      out IDictionary<ISymbolicExpressionTreeNode, Interval>
    119         nodeIntervals, IEnumerable<int> rows = null, int splitDirection = 0) {
     119        nodeIntervals, IEnumerable<int> rows = null) {
    120120      var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
    121121      return GetSymbolicExpressionTreeIntervals(tree, variableRanges, out nodeIntervals);
     
    124124    public Interval GetSymbolicExpressionTreeInterval(
    125125      ISymbolicExpressionTree tree,
    126       IReadOnlyDictionary<string, Interval> variableRanges, int splitDirection = 0) {
     126      IReadOnlyDictionary<string, Interval> variableRanges) {
    127127      lock (syncRoot) {
    128128        EvaluatedSolutions++;
     
    133133      if (UseIntervalSplitting) {
    134134        outputInterval = GetSymbolicExpressionTreeIntervals(tree, variableRanges,
    135           out var nodeIntervals);
     135          out var _);
    136136      } else {
    137137        var instructionCount = 0;
     
    150150      IReadOnlyDictionary<string, Interval> variableRanges,
    151151      out IDictionary<ISymbolicExpressionTreeNode, Interval>
    152         nodeIntervals, int splitDirection = 0) {
     152        nodeIntervals) {
    153153      lock (syncRoot) {
    154154        EvaluatedSolutions++;
     
    171171          //outputInterval = EvaluateRecursive(instructions, intervals, writeableVariableRanges, variables, MinSplittingWidth, MaxSplittingDepth,
    172172          //  ref currIndex, ref currDepth, tree);
    173           outputInterval = EvaluateWithSplitting(instructions, intervals, writeableVariableRanges, splitDirection);
     173          outputInterval = EvaluateWithSplitting(instructions, intervals, writeableVariableRanges);
    174174        } else {
    175175          var instructionCount = 0;
     
    212212      var code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
    213213      foreach (var instr in code.Where(i => i.opCode == OpCodes.Variable)) {
    214         var variableTreeNode = (VariableTreeNode) instr.dynamicNode;
     214        var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
    215215        instr.data = variableRanges[variableTreeNode.VariableName];
    216216      }
     
    221221    public static Interval EvaluateWithSplitting(Instruction[] instructions,
    222222                                                 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
    241237      var ic = 0;
    242238      //Calculate full box
    243239      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?!
    251251      for (var depth = 0; depth < 200; ++depth) {
    252         var firstBox = priorityList.First();
    253         priorityList.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;
    262262          }
    263263
     
    265265          var res = Evaluate(instructions, ref ic, nodeIntervals,
    266266            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          }
    271272        }
    272273      }
    273274
    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;
    278278    }
    279279
    280280    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 })
    282282                     .ToList();
    283283
     
    285285    }
    286286
    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);
    298305        }
    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;
    318307      }
    319308    }
     
    379368        //Variables, Constants, ...
    380369        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           else
    389             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          }
    394383        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          }
    399388        //Elementary arithmetic rules
    400389        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          }
    411400        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          }
    425414        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          }
    436425        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          }
    450439        //Trigonometric functions
    451440        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          }
    457446        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          }
    463452        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          }
    469458        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          }
    475464        //Exponential functions
    476465        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          }
    482471        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          }
    488477        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          }
    494483        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          }
    500489        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          }
    506495        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          }
    512501        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          }
    518507        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          }
    529518        default:
    530519          throw new NotSupportedException($"The tree contains the unknown symbol {currentInstr.dynamicNode.Symbol}");
Note: See TracChangeset for help on using the changeset viewer.