Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
10/03/19 12:30:19 (5 years ago)
Author:
gkronber
Message:

#2994 continued refactoring and extended unit tests. Interval calculation still fails for some edge cases (mainly for undefined behaviour). VectorEvaluator and VectorAutoDiffEvaluator produce the same results as the LinearInterpreter. TODO: check gradient calculation

Location:
branches/2994-AutoDiffForIntervals/HeuristicLab.Tests
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/2994-AutoDiffForIntervals/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis-3.4/AutoDiffIntervalTest.cs

    r17299 r17303  
    102102      //Division by 0 ==> IsInfiniteOrUndefined == true
    103103      AssertAreEqualInterval(Divide(d, b), new AlgebraicInterval(double.NegativeInfinity, double.PositiveInfinity));
     104
     105      // [0, 1] / [0, 1]
     106      AssertAreEqualInterval(new AlgebraicInterval(0, 1).Div(new AlgebraicInterval(0, 1)), new AlgebraicInterval(1, double.PositiveInfinity)); // returns [NaN, PositiveInfinity]
     107
    104108    }
    105109
     
    177181    [TestProperty("Time", "short")]
    178182    public void TestIntervalSqrOperator() {
    179       AssertAreEqualInterval(new AlgebraicInterval(1, 4), Square(new AlgebraicInterval(1, 2)));
    180       AssertAreEqualInterval(new AlgebraicInterval(1, 4), Square(new AlgebraicInterval(-2, -1)));
    181       AssertAreEqualInterval(new AlgebraicInterval(0, 4), Square(new AlgebraicInterval(-2, 2)));
    182     }
    183 
    184     private AlgebraicInterval Square(AlgebraicInterval algebraicInterval) {
    185       return algebraicInterval.IntPower(2);
     183      AssertAreEqualInterval(new AlgebraicInterval(1, 4), new AlgebraicInterval(1, 2).IntPower(2));
     184      AssertAreEqualInterval(new AlgebraicInterval(1, 4), new AlgebraicInterval(-2, -1).IntPower(2));
     185      AssertAreEqualInterval(new AlgebraicInterval(0, 4), new AlgebraicInterval(-2, 2).IntPower(2));
     186
     187      AssertAreEqualInterval(new AlgebraicInterval(0, 16), new AlgebraicInterval(-2, 2).Mul(new AlgebraicInterval(2, 2)).IntPower(2));
    186188    }
    187189
     
    190192    [TestProperty("Time", "short")]
    191193    public void TestIntervalSqrtOperator() {
    192       AssertAreEqualInterval(new AlgebraicInterval(1, 2), SquareRoot(new AlgebraicInterval(1, 4)));
    193       AssertAreEqualInterval(new AlgebraicInterval(double.NaN, double.NaN), SquareRoot(new AlgebraicInterval(-4, -1)));
    194     }
    195 
    196     private AlgebraicInterval SquareRoot(AlgebraicInterval algebraicInterval) {
    197       return algebraicInterval.IntRoot(2);
     194      AssertAreEqualInterval(new AlgebraicInterval(1, 2), new AlgebraicInterval(1, 4).IntRoot(2));
     195      AssertAreEqualInterval(new AlgebraicInterval(double.NaN, double.NaN), new AlgebraicInterval(-4, -1).IntRoot(2));
    198196    }
    199197
     
    202200    [TestProperty("Time", "short")]
    203201    public void TestIntervalCubeOperator() {
    204       AssertAreEqualInterval(new AlgebraicInterval(1, 8), Cube(new AlgebraicInterval(1, 2)));
    205       AssertAreEqualInterval(new AlgebraicInterval(-8, -1), Cube(new AlgebraicInterval(-2, -1)));
    206       AssertAreEqualInterval(new AlgebraicInterval(-8, 8), Cube(new AlgebraicInterval(-2, 2)));
    207     }
    208 
    209     private AlgebraicInterval Cube(AlgebraicInterval algebraicInterval) {
    210       return algebraicInterval.IntPower(3);
    211     }
     202      AssertAreEqualInterval(new AlgebraicInterval(1, 8), new AlgebraicInterval(1, 2).IntPower(3));
     203      AssertAreEqualInterval(new AlgebraicInterval(-8, -1), new AlgebraicInterval(-2, -1).IntPower(3));
     204      AssertAreEqualInterval(new AlgebraicInterval(-8, 8), new AlgebraicInterval(-2, 2).IntPower(3));
     205    }
     206
    212207
    213208    [TestMethod]
     
    228223    [TestProperty("Time", "short")]
    229224    public void TestIntervalCbrtOperator() {
    230       AssertAreEqualInterval(new AlgebraicInterval(1, 2), CubicRoot(new AlgebraicInterval(1, 8)));
    231       AssertAreEqualInterval(new AlgebraicInterval(-2, -1), CubicRoot(new AlgebraicInterval(-8, -1)));
    232     }
    233 
    234     private AlgebraicInterval CubicRoot(AlgebraicInterval algebraicInterval) {
    235       return algebraicInterval.IntRoot(3);
     225      AssertAreEqualInterval(new AlgebraicInterval(1, 2), new AlgebraicInterval(1, 8).IntRoot(3));
     226      AssertAreEqualInterval(new AlgebraicInterval(-2, -1), new AlgebraicInterval(-8, -1).IntRoot(3));
    236227    }
    237228  }
  • branches/2994-AutoDiffForIntervals/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis-3.4/IntervalCalculationComparison.cs

    r17291 r17303  
    1414    [TestMethod]
    1515    [TestCategory("Problems.DataAnalysis")]
    16     [TestProperty("Time", "short")]
     16    [TestProperty("Time", "long")]
    1717    public void TestIntervalCalculationForRandomExpressions() {
    1818      var grammar = new TypeCoherentExpressionGrammar();
     
    2323      grammar.Symbols.First(s => s is Cube).Enabled = true;
    2424      grammar.Symbols.First(s => s is CubeRoot).Enabled = true;
     25      grammar.Symbols.First(s => s is Sine).Enabled = true;
     26      grammar.Symbols.First(s => s is Cosine).Enabled = true;
     27      grammar.Symbols.First(s => s is Exponential).Enabled = true;
     28      grammar.Symbols.First(s => s is Logarithm).Enabled = true;
     29      grammar.Symbols.First(s => s is Absolute).Enabled = false; // XXX not yet supported by old interval calculator
     30      grammar.Symbols.First(s => s is AnalyticQuotient).Enabled = false; // not yet supported by old interval calculator
    2531
    2632      var varSy = (Variable)grammar.Symbols.First(s => s is Variable);
     
    5157
    5258      var formatter = new InfixExpressionFormatter();
     59      var sb = new StringBuilder();
    5360      foreach (var interval in new[] { posIntervals, negIntervals, fullIntervals, specialIntervals }) {
    5461        int N = 10000;
    55         var sb = new StringBuilder();
    5662        int i = 0;
    5763        while (i < N) {
     
    6167          // Console.WriteLine(formatter.Format(t));
    6268
     69          // all NaN is ok (but don't count NaN expressions)
    6370          if (double.IsNaN(r1.LowerBound) && double.IsNaN(r2.LowerBound) && double.IsNaN(r1.UpperBound) && double.IsNaN(r2.UpperBound)) continue;
    64 
    65           if (!double.IsNaN(r1.LowerBound) && !double.IsNaN(r2.LowerBound))
    66             if ((double.IsPositiveInfinity(r1.LowerBound) && !double.IsPositiveInfinity(r2.LowerBound)) ||
    67               (double.IsNegativeInfinity(r1.LowerBound) && !double.IsNegativeInfinity(r2.LowerBound)) ||
    68                (Math.Abs(r1.LowerBound - r2.LowerBound) > Math.Abs(r1.LowerBound * 1e-4))
    69               ) {
    70               sb.AppendLine($"{r1} <> {r2} for {formatter.Format(t)} x={interval["x"]} y={interval["y"]}");
    71             }
    72           if (!double.IsNaN(r1.UpperBound) && !double.IsNaN(r2.UpperBound))
    73             if ((double.IsPositiveInfinity(r1.UpperBound) && !double.IsPositiveInfinity(r2.UpperBound)) ||
    74               (double.IsNegativeInfinity(r1.UpperBound) && !double.IsNegativeInfinity(r2.UpperBound)) ||
    75                (Math.Abs(r1.UpperBound - r2.UpperBound) > Math.Abs(r1.UpperBound * 1e-4))
    76               ) {
    77               sb.AppendLine($"{r1} <> {r2} for {formatter.Format(t)} x={interval["x"]} y={interval["y"]}");
    78             }
     71          if (r1.LowerBound == r2.LowerBound && r1.UpperBound == r2.UpperBound) {
     72            /* exactly the same value (incl. Inf / -Inf) => ok */
     73          } else if ((Math.Abs(r1.LowerBound - r2.LowerBound) < Math.Max(1e-10, Math.Abs(r1.LowerBound * 1e-4))) &&
     74                     (Math.Abs(r1.UpperBound - r2.UpperBound) < Math.Max(1e-10, Math.Abs(r1.UpperBound * 1e-4)))) {
     75            /* approximately the same value => OK */
     76          } else {
     77            sb.AppendLine($"{r1} <> {r2} for {formatter.Format(t)} x={interval["x"]} y={interval["y"]}");
     78          }
    7979          i++;
    8080        }
    81         if (sb.Length > 0) {
    82           Console.WriteLine(sb.ToString());
    83           Assert.Fail("There were different interval calculation results");
     81      }
     82      if (sb.Length > 0) {
     83        Console.WriteLine(sb.ToString());
     84        Assert.Fail("There were different interval calculation results");
     85      }
     86    }
     87
     88    [TestMethod]
     89    [TestCategory("Problems.DataAnalysis")]
     90    [TestProperty("Time", "short")]
     91    public void TestExampleIntervalExpressions() {
     92      var parser = new InfixExpressionParser();
     93      var eval1 = new IntervalEvaluator();
     94      var eval2 = new IntervalInterpreter();
     95      IDictionary<string, Interval> interval = new Dictionary<string, Interval>() {
     96        { "x", new Interval(1, 2) },
     97        { "y", new Interval(0, 1) },
     98        { "z", new Interval(double.NegativeInfinity, double.PositiveInfinity) },
     99      };
     100
     101      var exprs = new string[] {
     102        "CUBE((0.642971622547268*'x')) * (-16.5400720573962)",
     103        "sqr(y / y)", // one interpreter produces [NaN, inf], the other [NaN, 0]
     104        "cuberoot(-x)", // the old interpreter calculates cuberoot incorrectly
     105        "sqr(log(-x))", // Interval: [NaN, NaN] <> Interval (old): [NaN, 0]
     106        "log(1.8*'y' - 1.4*'y')", // Interval: [NaN, 0,587786664902119] <> Interval (old): [0,587786664902119, NaN]
     107        "log(z)", // Interval: [NaN, ∞] <> Interval (old): [∞, NaN]
     108        "sqr(sqrt(-1))" // Interval: [NaN, NaN] <> Interval (old): [NaN, 0]
     109      };
     110
     111      var formatter = new InfixExpressionFormatter();
     112      var sb = new StringBuilder();
     113      foreach (var expr in exprs) {
     114        var t = parser.Parse(expr);
     115
     116        var r1 = eval1.Evaluate(t, interval);
     117        var r2 = eval2.GetSymbolicExpressionTreeInterval(t, interval);
     118        // Console.WriteLine(formatter.Format(t));
     119
     120        // all NaN is ok
     121        if (double.IsNaN(r1.LowerBound) && double.IsNaN(r2.LowerBound) && double.IsNaN(r1.UpperBound) && double.IsNaN(r2.UpperBound)) continue;
     122        if (r1.LowerBound == r2.LowerBound && r1.UpperBound == r2.UpperBound) continue;  // Inf, -Inf and exactly the same value are ok
     123
     124        if ((Math.Abs(r1.LowerBound - r2.LowerBound) < Math.Abs(r1.LowerBound * 1e-4)) &&
     125            (Math.Abs(r1.UpperBound - r2.UpperBound) < Math.Abs(r1.UpperBound * 1e-4))) { /* OK */ } else {
     126          sb.AppendLine($"{r1} <> {r2} for {formatter.Format(t)} x={interval["x"]} y={interval["y"]}");
    84127        }
     128      }
     129      if (sb.Length > 0) {
     130        Console.WriteLine(sb.ToString());
     131        Assert.Fail("There were different interval calculation results");
    85132      }
    86133    }
  • branches/2994-AutoDiffForIntervals/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis-3.4/IntervalTest.cs

    r17290 r17303  
    7575      Assert.IsTrue(Interval.Divide(a, c).IsInfiniteOrUndefined);
    7676      Assert.AreEqual<Interval>(Interval.Divide(d, b), new Interval(double.NegativeInfinity, double.PositiveInfinity));
     77
     78      // [0, 1] / [0, 1]
     79      Assert.AreEqual(Interval.Divide(new Interval(0, 1), new Interval(0, 1)), new Interval(1, double.PositiveInfinity)); // returns [NaN, NaN] because of (0 / 0)
    7780    }
    7881
     
    159162    public void TestIntervalCbrtOperator() {
    160163      Assert.AreEqual<Interval>(new Interval(1, 2), Interval.CubicRoot(new Interval(1, 8)));
    161       Assert.AreEqual<Interval>(new Interval(-2, -1), Interval.CubicRoot(new Interval(-8, -1)));
     164      Assert.AreEqual<Interval>(new Interval(-2, -1), Interval.CubicRoot(new Interval(-8, -1))); // XXX should be fixed for old interval calculation
    162165    }
    163166  }
  • branches/2994-AutoDiffForIntervals/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs

    r17216 r17303  
    285285      grammar.Symbols.First(s => s is Cube).Enabled = true;
    286286      grammar.Symbols.First(s => s is CubeRoot).Enabled = true;
     287      grammar.Symbols.First(s => s is Exponential).Enabled = true;
     288      grammar.Symbols.First(s => s is Logarithm).Enabled = true;
     289      grammar.Symbols.First(s => s is Sine).Enabled = true;
     290      grammar.Symbols.First(s => s is Cosine).Enabled = true;
     291      grammar.Symbols.First(s => s is Absolute).Enabled = true;
     292      grammar.Symbols.First(s => s is AnalyticQuotient).Enabled = true;
    287293
    288294      var refInterpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter();
Note: See TracChangeset for help on using the changeset viewer.