Changeset 17100


Ignore:
Timestamp:
07/07/19 23:47:53 (2 weeks ago)
Author:
mkommend
Message:

#2966: Merged 16629, 16631, 16646, 16740, 16743, 16757, 16758, 16769, 16822 to stable.

Location:
stable
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • stable

  • stable/HeuristicLab.Problems.DataAnalysis

  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic

  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs

    r17097 r17100  
    6969    #endregion
    7070
    71     public Interval GetSymbolicExressionTreeInterval(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows = null) {
     71    public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows = null) {
    7272      var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
    73       return GetSymbolicExressionTreeInterval(tree, variableRanges);
    74     }
    75 
    76     public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset,
    77       out Dictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals, IEnumerable<int> rows = null) {
     73      return GetSymbolicExpressionTreeInterval(tree, variableRanges);
     74    }
     75
     76    public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset,
     77      out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals, IEnumerable<int> rows = null) {
    7878      var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
    79       return GetSymbolicExressionTreeIntervals(tree, variableRanges, out nodeIntervals);
    80     }
    81 
    82     public Interval GetSymbolicExressionTreeInterval(ISymbolicExpressionTree tree, Dictionary<string, Interval> variableRanges) {
     79      return GetSymbolicExpressionTreeIntervals(tree, variableRanges, out nodeIntervals);
     80    }
     81
     82    public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IDictionary<string, Interval> variableRanges) {
    8383      lock (syncRoot) {
    8484        EvaluatedSolutions++;
     
    8888      var outputInterval = Evaluate(instructions, ref instructionCount);
    8989
    90       return outputInterval;
    91     }
    92 
    93 
    94     public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree,
    95       Dictionary<string, Interval> variableRanges, out Dictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals) {
     90      // because of numerical errors the bounds might be incorrect
     91      if (outputInterval.LowerBound <= outputInterval.UpperBound)
     92        return outputInterval;
     93      else
     94        return new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
     95    }
     96
     97
     98    public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree,
     99      IDictionary<string, Interval> variableRanges, out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals) {
    96100      lock (syncRoot) {
    97101        EvaluatedSolutions++;
     
    102106      var outputInterval = Evaluate(instructions, ref instructionCount, intervals);
    103107
    104       nodeIntervals = intervals;
    105 
    106       return outputInterval;
    107     }
    108 
    109 
    110     private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree, Dictionary<string, Interval> variableRanges) {
     108      // fix incorrect intervals if necessary (could occur because of numerical errors)
     109      nodeIntervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
     110      foreach (var kvp in intervals) {
     111        var interval = kvp.Value;
     112        if (interval.IsInfiniteOrUndefined || interval.LowerBound <= interval.UpperBound)
     113          nodeIntervals.Add(kvp.Key, interval);
     114        else
     115          nodeIntervals.Add(kvp.Key, new Interval(interval.UpperBound, interval.LowerBound));
     116      }
     117
     118      // because of numerical errors the bounds might be incorrect
     119      if (outputInterval.IsInfiniteOrUndefined || outputInterval.LowerBound <= outputInterval.UpperBound)
     120        return outputInterval;
     121      else
     122        return new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
     123    }
     124
     125
     126    private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree, IDictionary<string, Interval> variableRanges) {
    111127      if (variableRanges == null)
    112128        throw new ArgumentNullException("No variablew ranges are present!", nameof(variableRanges));
     
    125141    }
    126142
    127     private Interval Evaluate(Instruction[] instructions, ref int instructionCounter, Dictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null) {
     143    private Interval Evaluate(Instruction[] instructions, ref int instructionCounter, IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null) {
    128144      Instruction currentInstr = instructions[instructionCounter];
    129145      //Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side
     
    200216            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    201217            result = Interval.Tangens(argumentInterval);
     218            break;
     219          }
     220        case OpCodes.Tanh: {
     221            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     222            result = Interval.HyperbolicTangent(argumentInterval);
    202223            break;
    203224          }
  • stable/HeuristicLab.Problems.DataAnalysis/3.4

  • stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval.cs

    r17097 r17100  
    124124
    125125      double min = Math.Min(Math.Min(v1, v2), Math.Min(v3, v4));
    126       double max = Math.Max(Math.Min(v1, v2), Math.Max(v3, v4));
     126      double max = Math.Max(Math.Max(v1, v2), Math.Max(v3, v4));
    127127      return new Interval(min, max);
    128128    }
     
    167167    }
    168168    public static Interval Cosine(Interval a) {
    169       return Interval.Sine(Interval.Subtract(a, new Interval(Math.PI / 2, Math.PI / 2)));
     169      return Interval.Sine(Interval.Add(a, new Interval(Math.PI / 2, Math.PI / 2)));
    170170    }
    171171    public static Interval Tangens(Interval a) {
    172172      return Interval.Divide(Interval.Sine(a), Interval.Cosine(a));
     173    } 
     174    public static Interval HyperbolicTangent(Interval a) {
     175      return new Interval(Math.Tanh(a.LowerBound), Math.Tanh(a.UpperBound));
    173176    }
    174177
     
    201204
    202205    public static Interval Square(Interval a) {
    203       return Power(a, new Interval(2, 2));
    204     }
    205 
    206     public static Interval Cubic(Interval a) {
    207       return Power(a, new Interval(3, 3));
     206      if (a.UpperBound <= 0) return new Interval(a.UpperBound * a.UpperBound, a.LowerBound * a.LowerBound);     // interval is negative
     207      else if (a.LowerBound >= 0) return new Interval(a.LowerBound * a.LowerBound, a.UpperBound * a.UpperBound); // interval is positive
     208      else return new Interval(0, Math.Max(a.LowerBound*a.LowerBound, a.UpperBound*a.UpperBound)); // interval goes over zero
     209    }
     210
     211    public static Interval Cube(Interval a) {
     212      return new Interval(Math.Pow(a.LowerBound, 3), Math.Pow(a.UpperBound, 3));
    208213    }
    209214
     
    216221
    217222    public static Interval SquareRoot(Interval a) {
    218       return Root(a, new Interval(2, 2));
     223      if (a.LowerBound < 0) return new Interval(double.NaN, double.NaN);
     224      return new Interval(Math.Sqrt(a.LowerBound), Math.Sqrt(a.UpperBound));
    219225    }
    220226
    221227    public static Interval CubicRoot(Interval a) {
    222       return Root(a, new Interval(3, 3));
     228      if (a.LowerBound < 0) return new Interval(double.NaN, double.NaN);
     229      return new Interval(Math.Pow(a.LowerBound, 1.0/3), Math.Pow(a.UpperBound, 1.0/3));
    223230    }
    224231    #endregion
  • stable/HeuristicLab.Tests

  • stable/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis-3.4/IntervalTest.cs

    r16436 r17100  
    11using System;
    2 using HeuristicLab.Problems.DataAnalysis;
    32using Microsoft.VisualStudio.TestTools.UnitTesting;
    43
     
    5251      //([-1, 1] * [0, 3]) * [-2, 2] = [-6, 6]
    5352      Assert.AreEqual<Interval>(Interval.Multiply(Interval.Multiply(a, c), b), new Interval(-6, 6));
     53
     54      // [-2, 0] * [-2, 0]  = [0, 4]
     55      Assert.AreEqual<Interval>(new Interval(0, 4), Interval.Multiply(new Interval(-2, 0), new Interval(-2, 0)));
    5456    }
    5557
     
    124126      Assert.AreEqual<Interval>(new Interval(1, Math.Exp(1)), Interval.Exponential(new Interval(0, 1)));
    125127    }
     128
     129
     130    [TestMethod]
     131    [TestCategory("Problems.DataAnalysis")]
     132    [TestProperty("Time", "short")]
     133    public void TestIntervalSqrOperator() {
     134      Assert.AreEqual<Interval>(new Interval(1, 4), Interval.Square(new Interval(1, 2)));
     135      Assert.AreEqual<Interval>(new Interval(1, 4), Interval.Square(new Interval(-2, -1)));
     136      Assert.AreEqual<Interval>(new Interval(0, 4), Interval.Square(new Interval(-2, 2)));
     137    }
     138
     139    [TestMethod]
     140    [TestCategory("Problems.DataAnalysis")]
     141    [TestProperty("Time", "short")]
     142    public void TestIntervalSqrtOperator() {
     143      Assert.AreEqual<Interval>(new Interval(1, 2), Interval.SquareRoot(new Interval(1, 4)));
     144      Assert.AreEqual<Interval>(new Interval(double.NaN, double.NaN), Interval.SquareRoot(new Interval(-4, -1)));
     145    }
     146
     147    [TestMethod]
     148    [TestCategory("Problems.DataAnalysis")]
     149    [TestProperty("Time", "short")]
     150    public void TestIntervalCubeOperator() {
     151      Assert.AreEqual<Interval>(new Interval(1, 8), Interval.Cube(new Interval(1, 2)));
     152      Assert.AreEqual<Interval>(new Interval(-8, -1), Interval.Cube(new Interval(-2, -1)));
     153      Assert.AreEqual<Interval>(new Interval(-8, 8), Interval.Cube(new Interval(-2, 2)));
     154    }
     155
     156    [TestMethod]
     157    [TestCategory("Problems.DataAnalysis")]
     158    [TestProperty("Time", "short")]
     159    public void TestIntervalCbrtOperator() {
     160      Assert.AreEqual<Interval>(new Interval(1, 2), Interval.CubicRoot(new Interval(1, 8)));
     161      Assert.AreEqual<Interval>(new Interval(double.NaN, double.NaN), Interval.CubicRoot(new Interval(-8, -1)));
     162    }
    126163  }
    127164}
  • stable/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/IntervalInterpreterTest.cs

    r16438 r17100  
    3434    }
    3535
    36     private void EvaluateTest(string expression, Interval expectedResult, Dictionary<string, Interval> variableRanges = null) {
     36    private void EvaluateTest(string expression, Interval expectedResult, Dictionary<string, Interval> variableRanges = null, double lowerDelta =0, double upperDelta = 0) {
    3737      var parser = new InfixExpressionParser();
    3838      var tree = parser.Parse(expression);
     
    4040      Interval result;
    4141      if (variableRanges == null)
    42         result = interpreter.GetSymbolicExressionTreeInterval(tree, problemData.Dataset, problemData.AllIndices);
     42        result = interpreter.GetSymbolicExpressionTreeInterval(tree, problemData.Dataset, problemData.AllIndices);
    4343      else
    44         result = interpreter.GetSymbolicExressionTreeInterval(tree, variableRanges);
     44        result = interpreter.GetSymbolicExpressionTreeInterval(tree, variableRanges);
    4545
    46       Assert.AreEqual(expectedResult, result);
     46      Assert.AreEqual(expectedResult.LowerBound, result.LowerBound, lowerDelta);
     47      Assert.AreEqual(expectedResult.UpperBound, result.UpperBound, upperDelta);
    4748    }
    4849
     
    7980      EvaluateTest("sin(x1+x2)", new Interval(-1, 1), variableRanges);
    8081      EvaluateTest("sin(1+2)", new Interval(Math.Sin(3), Math.Sin(3)));
     82
     83      var localVarRanges = new Dictionary<string, Interval>();
     84      localVarRanges.Add("x1", new Interval(-1, 1));
     85      localVarRanges.Add("x2", new Interval(-(Math.PI / 2), 0));
     86      localVarRanges.Add("x3", new Interval(0, Math.PI / 2));
     87      localVarRanges.Add("x4", new Interval(-Math.PI, Math.PI));
     88      localVarRanges.Add("x5", new Interval(Math.PI/4, Math.PI*3.0/4));
     89
     90      EvaluateTest("sin(x1)", new Interval(Math.Sin(-1), Math.Sin(1)), localVarRanges, 1E-8, 1E-8);
     91      EvaluateTest("sin(x2)", new Interval(-1, 0), localVarRanges, 1E-8, 1E-8);
     92      EvaluateTest("sin(x3)", new Interval(0, 1), localVarRanges, 1E-8, 1E-8);
     93      EvaluateTest("sin(x4)", new Interval(-1, 1), localVarRanges, 1E-8, 1E-8);
     94      EvaluateTest("sin(x5)", new Interval(Math.Sin(Math.PI/4), 1), localVarRanges, 1E-8, 1E-8);
    8195    }
    8296
     
    87101      EvaluateTest("cos(x1+x2)", new Interval(-1, 1));
    88102      EvaluateTest("cos(x1+x2)", new Interval(-1, 1), variableRanges);
    89       EvaluateTest("cos(1+2)", new Interval(Math.Sin(3 - Math.PI / 2), Math.Sin(3 - Math.PI / 2)));
     103      EvaluateTest("cos(1+2)", new Interval(Math.Sin(3 + Math.PI / 2), Math.Sin(3 + Math.PI / 2)));
     104
     105      var localVarRanges = new Dictionary<string, Interval>();
     106      localVarRanges.Add("x1", new Interval(-1, 1));
     107      localVarRanges.Add("x2", new Interval(-(Math.PI / 2), 0));
     108      localVarRanges.Add("x3", new Interval(0, Math.PI / 2));
     109      localVarRanges.Add("x4", new Interval(-Math.PI, Math.PI));
     110      localVarRanges.Add("x5", new Interval(Math.PI / 4, Math.PI * 3.0 / 4));
     111
     112      EvaluateTest("cos(x1)", new Interval(Math.Cos(-1), 1), localVarRanges, 1E-8, 1E-8);
     113      EvaluateTest("cos(x2)", new Interval(0, 1), localVarRanges, 1E-8, 1E-8);
     114      EvaluateTest("cos(x3)", new Interval(0, 1), localVarRanges, 1E-8, 1E-8);
     115      EvaluateTest("cos(x4)", new Interval(-1, 1), localVarRanges, 1E-8, 1E-8);
     116      EvaluateTest("cos(x5)", new Interval(Math.Cos(Math.PI *3.0/ 4), Math.Cos(Math.PI/ 4)), localVarRanges, 1E-8, 1E-8);
     117
    90118    }
     119
     120    [TestMethod]
     121    [TestCategory("Problems.DataAnalysis.Symbolic")]
     122    [TestProperty("Time", "short")]
     123    public void TestIntervalInterpreterTan() {
     124      // critical values:
     125      // lim tan(x) = -inf for x => -pi/2
     126      // lim tan(x) = +inf for x =>  pi/2
     127      var variableRanges = new Dictionary<string, Interval>();
     128      variableRanges.Add("x1", new Interval(-1, 1));
     129      variableRanges.Add("x2", new Interval(-(Math.PI / 2), 0));
     130      variableRanges.Add("x3", new Interval(0, Math.PI / 2));
     131      variableRanges.Add("x4", new Interval(-Math.PI, Math.PI));
     132
     133      EvaluateTest("tan(x1)", new Interval(Math.Tan(-1), Math.Tan(1)), variableRanges, 1E-8, 1E-8);
     134      EvaluateTest("tan(x2)", new Interval(double.NegativeInfinity, 0), variableRanges, 0, 1E-8);
     135      EvaluateTest("tan(x3)", new Interval(0, 8.16588936419192E+15), variableRanges, 0, 1E6); // actually upper bound should be infinity.
     136      EvaluateTest("tan(x4)", new Interval(double.NegativeInfinity, double.PositiveInfinity), variableRanges);
     137    }
     138
     139    [TestMethod]
     140    [TestCategory("Problems.DataAnalysis.Symbolic")]
     141    [TestProperty("Time", "short")]
     142    public void TestIntervalInterpreterTanh() {
     143      // critical values:
     144      // lim tanh(x) = -1 for x => -inf
     145      // lim tanh(x) =  1 for x =>  inf
     146      var variableRanges = new Dictionary<string, Interval>();
     147      variableRanges.Add("x1", new Interval(-1, 1));
     148      variableRanges.Add("x2", new Interval(double.NegativeInfinity, 0));
     149      variableRanges.Add("x3", new Interval(0, double.PositiveInfinity));
     150
     151      EvaluateTest("tanh(x1)", new Interval(Math.Tanh(-1), Math.Tanh(1)), variableRanges);
     152      EvaluateTest("tanh(x2)", new Interval(-1, 0), variableRanges);
     153      EvaluateTest("tanh(x3)", new Interval(0, 1), variableRanges);
     154    }
     155
    91156
    92157    [TestMethod]
Note: See TracChangeset for help on using the changeset viewer.