Changeset 16404


Ignore:
Timestamp:
12/19/18 14:03:10 (4 months ago)
Author:
chaider
Message:

#2966

  • Variable name changes
  • Changed GetVaribleRanges in DatasetUtil
  • Added method to get interval ranges from a double enumeration in Interval class
  • Added some comments
Location:
branches/2966_interval_calculation
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs

    r16403 r16404  
    6969    #endregion
    7070
    71     public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows = null) {
     71    public Interval GetSymbolicExressionTreeInterval(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows = null) {
    7272      var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
    73       return GetSymbolicExressionTreeIntervals(tree, variableRanges);
     73      return GetSymbolicExressionTreeInterval(tree, variableRanges);
    7474    }
    7575
    7676    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset,
    77       out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals, IEnumerable<int> rows = null) {
     77      out Dictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals, IEnumerable<int> rows = null) {
    7878      var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
    79       return GetSymbolicExressionTreeIntervals(tree, variableRanges, out intervals);
    80     }
    81 
    82     public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, Dictionary<string, Interval> customIntervalsForVariables) {
     79      return GetSymbolicExressionTreeIntervals(tree, variableRanges, out nodeIntervals);
     80    }
     81
     82    public Interval GetSymbolicExressionTreeInterval(ISymbolicExpressionTree tree, Dictionary<string, Interval> variableRanges) {
    8383      lock (syncRoot) {
    8484        EvaluatedSolutions++;
    8585      }
    8686      int instructionCount = 0;
    87       var instructions = PrepareInterpreterState(tree, customIntervalsForVariables);
     87      var instructions = PrepareInterpreterState(tree, variableRanges);
    8888      var outputInterval = Evaluate(instructions, ref instructionCount);
    8989
     
    9393
    9494    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree,
    95       Dictionary<string, Interval> customIntervalsForVariables, out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
     95      Dictionary<string, Interval> variableRanges, out Dictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals) {
    9696      lock (syncRoot) {
    9797        EvaluatedSolutions++;
    9898      }
    9999      int instructionCount = 0;
    100       intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
    101       var instructions = PrepareInterpreterState(tree, customIntervalsForVariables);
     100      var intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
     101      var instructions = PrepareInterpreterState(tree, variableRanges);
    102102      var outputInterval = Evaluate(instructions, ref instructionCount, intervals);
    103103
     104      nodeIntervals = intervals;
     105
    104106      return outputInterval;
    105107    }
    106108
    107109
    108     private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree, Dictionary<string, Interval> customIntervalsForVariables) {
     110    private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree, Dictionary<string, Interval> variableRanges) {
     111      if (variableRanges == null)
     112        throw new ArgumentNullException("No variablew ranges are present!", nameof(variableRanges));
     113
     114      //Check if all variables used in the tree are present in the dataset
     115      foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName).Distinct()) {
     116        if (!variableRanges.ContainsKey(variable)) throw new InvalidOperationException($"No ranges for variable {variable} is present");
     117      }
     118
    109119      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
    110 
    111       if (customIntervalsForVariables == null)
    112         throw new ArgumentException("No interval ranges are present!", nameof(customIntervalsForVariables));
    113 
    114       foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName).Distinct()) {
    115         if (!customIntervalsForVariables.ContainsKey(variable)) throw new InvalidOperationException($"No ranges for variable {variable} is present");
    116       }
    117 
    118120      foreach (Instruction instr in code.Where(i => i.opCode == OpCodes.Variable)) {
    119121        var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
    120         instr.data = customIntervalsForVariables[variableTreeNode.VariableName];
     122        instr.data = variableRanges[variableTreeNode.VariableName];
    121123      }
    122124      return code;
    123125    }
    124126
    125     private Interval Evaluate(Instruction[] instructions, ref int instructionCount, Dictionary<ISymbolicExpressionTreeNode, Interval> intervals = null) {
    126       Instruction currentInstr = instructions[instructionCount++];
     127    private Interval Evaluate(Instruction[] instructions, ref int instructionCounter, Dictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null) {
     128      Instruction currentInstr = instructions[instructionCounter];
     129      //Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side
     130      //Update instructionCounter, whenever Evaluate is called
     131      instructionCounter++;
    127132      Interval result = null;
    128133
     
    131136        case OpCodes.Variable: {
    132137            var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
    133             var variableWeight = variableTreeNode.Weight;
    134             var varibleWeightInterval = new Interval(variableWeight, variableWeight);
    135 
    136             result = Interval.Multiply((Interval)currentInstr.data, varibleWeightInterval);
     138            var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight);
     139            var variableInterval = (Interval)currentInstr.data;
     140
     141            result = Interval.Multiply(variableInterval, weightInterval);
    137142            break;
    138143          }
     
    144149        //Elementary arithmetic rules
    145150        case OpCodes.Add: {
    146             result = Evaluate(instructions, ref instructionCount, intervals);
    147             for (int i = 1; i < currentInstr.nArguments; i++) {
    148               var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     151            result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     152            for (int i = 1; i < currentInstr.nArguments; i++) {
     153              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    149154              result = Interval.Add(result, argumentInterval);
    150155            }
     
    152157          }
    153158        case OpCodes.Sub: {
    154             result = Evaluate(instructions, ref instructionCount, intervals);
     159            result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    155160            if (currentInstr.nArguments == 1)
    156161              result = Interval.Multiply(new Interval(-1, -1), result);
    157            
    158             for (int i = 1; i < currentInstr.nArguments; i++) {
    159               var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     162
     163            for (int i = 1; i < currentInstr.nArguments; i++) {
     164              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    160165              result = Interval.Subtract(result, argumentInterval);
    161166            }
     
    163168          }
    164169        case OpCodes.Mul: {
    165             result = Evaluate(instructions, ref instructionCount, intervals);
    166             for (int i = 1; i < currentInstr.nArguments; i++) {
    167               var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     170            result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     171            for (int i = 1; i < currentInstr.nArguments; i++) {
     172              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    168173              result = Interval.Multiply(result, argumentInterval);
    169174            }
     
    171176          }
    172177        case OpCodes.Div: {
    173             result = Evaluate(instructions, ref instructionCount, intervals);
    174             if(currentInstr.nArguments == 1)
    175               result = Interval.Divide(new Interval(1,1),result);
    176 
    177             for (int i = 1; i < currentInstr.nArguments; i++) {
    178               var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     178            result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     179            if (currentInstr.nArguments == 1)
     180              result = Interval.Divide(new Interval(1, 1), result);
     181
     182            for (int i = 1; i < currentInstr.nArguments; i++) {
     183              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    179184              result = Interval.Divide(result, argumentInterval);
    180185            }
     
    183188        //Trigonometric functions
    184189        case OpCodes.Sin: {
    185             var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     190            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    186191            result = Interval.Sine(argumentInterval);
    187192            break;
    188193          }
    189194        case OpCodes.Cos: {
    190             var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     195            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    191196            result = Interval.Cosine(argumentInterval);
    192197            break;
    193198          }
    194199        case OpCodes.Tan: {
    195             var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     200            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    196201            result = Interval.Tangens(argumentInterval);
    197202            break;
     
    199204        //Exponential functions
    200205        case OpCodes.Log: {
    201             var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     206            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    202207            result = Interval.Logarithm(argumentInterval);
    203208            break;
    204209          }
    205210        case OpCodes.Exp: {
    206             var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     211            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    207212            result = Interval.Exponential(argumentInterval);
    208213            break;
    209214          }
    210215        case OpCodes.Power: {
    211             result = Evaluate(instructions, ref instructionCount, intervals);
    212             for (int i = 1; i < currentInstr.nArguments; i++) {
    213               var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     216            result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     217            for (int i = 1; i < currentInstr.nArguments; i++) {
     218              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    214219              result = Interval.Power(result, argumentInterval);
    215220            }
     
    217222          }
    218223        case OpCodes.Square: {
    219             var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     224            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    220225            result = Interval.Square(argumentInterval);
    221226            break;
    222227          }
    223228        case OpCodes.Root: {
    224             result = Evaluate(instructions, ref instructionCount, intervals);
    225             for (int i = 1; i < currentInstr.nArguments; i++) {
    226               var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     229            result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     230            for (int i = 1; i < currentInstr.nArguments; i++) {
     231              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    227232              result = Interval.Root(result, argumentInterval);
    228233            }
     
    230235          }
    231236        case OpCodes.SquareRoot: {
    232             var argumentInterval = Evaluate(instructions, ref instructionCount, intervals);
     237            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    233238            result = Interval.SquareRoot(argumentInterval);
    234239            break;
     
    238243      }
    239244
    240       if (intervals != null)
    241         intervals.Add(currentInstr.dynamicNode, result);
     245      if (nodeIntervals != null)
     246        nodeIntervals.Add(currentInstr.dynamicNode, result);
    242247
    243248      return result;
  • branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis/3.4/DatasetUtil.cs

    r16383 r16404  
    9797
    9898      foreach (var variable in dataset.VariableNames) {
    99         var min = double.MaxValue;
    100         var max = double.MinValue;
    10199        IEnumerable<double> values = null;
    102100
     
    104102        else values = dataset.GetDoubleValues(variable, rows);
    105103
    106         foreach (var val in values) {
    107           if (val < min) min = val;
    108           if (val > max) max = val;
    109         }
    110 
    111         variableRanges.Add(variable, new Interval(min, max));
     104        var range = Interval.GetInterval(values);
     105        variableRanges.Add(variable, range);
    112106      }
    113107
  • branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval.cs

    r16327 r16404  
    5151                double.IsNaN(LowerBound) || double.IsNaN(UpperBound);
    5252      }
     53    }
     54
     55    public static Interval GetInterval(IEnumerable<double> values) {
     56      if (values == null) throw new ArgumentNullException("The given value set is not defined.");
     57      if (!values.Any()) throw new ArgumentException($"No valid values are present.");
     58
     59      var min = double.MaxValue;
     60      var max = double.MinValue;
     61
     62      foreach (var value in values) {
     63        //If an value is NaN return an interval [NaN, NaN]
     64        if (double.IsNaN(value)) return new Interval(double.NaN, double.NaN);
     65
     66        if (value < min) min = value;
     67        if (value > max) max = value;
     68      }
     69
     70      return new Interval(min, max);
    5371    }
    5472
Note: See TracChangeset for help on using the changeset viewer.