Changeset 17314


Ignore:
Timestamp:
10/04/19 10:40:51 (11 days ago)
Author:
gkronber
Message:

#2994: fix bug in calculation of cos() and sin()

Location:
branches/2994-AutoDiffForIntervals
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/AlgebraicInterval.cs

    r17303 r17314  
    99  [DebuggerDisplay("[{low.Value}..{high.Value}]")]
    1010  public class AlgebraicInterval : IAlgebraicType<AlgebraicInterval> {
     11
     12    // turn a double into an interval (of size 0)
     13    public static implicit operator AlgebraicInterval(double value) { return new AlgebraicInterval(value, value); }
     14
    1115    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    1216    private MultivariateDual<AlgebraicDouble> low;
     
    193197    }
    194198
     199
     200    // TODO: move to constants
     201    private const double pi_2 = Math.PI / 2.0;
     202    private static readonly double[] maxima = new double[] { -3 * pi_2, pi_2, 5 * pi_2 };
     203    private static readonly double[] minima = new double[] { -5 * pi_2, -pi_2, 3 * pi_2 };
     204
    195205    public AlgebraicInterval AssignSin(AlgebraicInterval a) {
    196206      var lower = a.LowerBound.Value.Value;
     
    213223
    214224      // handle min = -1 and max = 1 cases explicitly
    215       var pi_2 = Math.PI / 2.0;
    216       var maxima = new double[] { -3 * pi_2, pi_2 };
    217       var minima = new double[] { -pi_2, 3 * pi_2 };
    218225
    219226      // override min and max if necessary
     
    294301      if (xs.Length <= 2) throw new ArgumentException("need at least 3 arguments");
    295302      AssignLowAndHigh(xs[0], xs[1]);
    296       for(int i=2;i<xs.Length;i++) {
     303      for (int i = 2; i < xs.Length; i++) {
    297304        // we must make sure that low and high are different objects when a == b
    298305        if (low.Value.CompareTo(xs[i].Value) > 0) low.Assign(xs[i]);
  • branches/2994-AutoDiffForIntervals/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis-3.4/AutoDiffIntervalTest.cs

    r17310 r17314  
    142142      AssertAreEqualInterval(Cosine(new AlgebraicInterval(0, 2 * Math.PI)), new AlgebraicInterval(-1, 1));
    143143      AssertAreEqualInterval(new AlgebraicInterval(-1, 1), Cosine(new AlgebraicInterval(Math.PI, 4 * Math.PI / 2)));
     144
     145      // some random expression that were problematic
     146      AssertAreEqualInterval(new AlgebraicInterval(-0.0326026961803847, 1), new AlgebraicInterval(1, 2).Scale(1.73269159006613).Add(9.23027422279119).Cos());
     147      AssertAreEqualInterval(new AlgebraicInterval(0.54030230586814, 1), new AlgebraicInterval(1, 2).Scale(3.39318455754522).Cos().IntPower(2).Cos());
     148      AssertAreEqualInterval(new AlgebraicInterval(-0.825841274068331, 1), new AlgebraicInterval(1, 2).Scale(-16.7140105366707 * -0.223806041028346).Cos());
     149      AssertAreEqualInterval(new AlgebraicInterval(0, 1), new AlgebraicInterval(1, 2).Scale(1.03513653909418).Exp().Cos().IntPower(2));
     150      AssertAreEqualInterval(new AlgebraicInterval(-1, 1), new AlgebraicInterval(1, 2).Scale(0.535386838272755).Exp().IntPower(2).Cos());
    144151    }
    145152
     
    285292      };
    286293      var r = eval.Evaluate(t, intervals, paramNodes, out double[] lg, out double[] ug);
    287       Assert.AreEqual(XXX, r.LowerBound);
    288       Assert.AreEqual(XXX, r.UpperBound);
    289 
    290       Assert.AreEqual(XXX, lg[0]); // x
    291       Assert.AreEqual(XXX, ug[0]);
    292 
    293       for  { "x", new Interval(1, 2) },
    294         { "y", new Interval(0, 1) },
    295 
    296       0 <> -2,50012500572888E-05 for y in SQR(LOG('y'))
    297       0 <> 2, 49987500573946E-05 for x in SQR(LOG('x'))
     294      // TODO
     295      // Assert.AreEqual(XXX, r.LowerBound);
     296      // Assert.AreEqual(XXX, r.UpperBound);
     297      //
     298      // Assert.AreEqual(XXX, lg[0]); // x
     299      // Assert.AreEqual(XXX, ug[0]);
     300      //
     301      // for  { "x", new Interval(1, 2) },
     302      //   { "y", new Interval(0, 1) },
     303      //
     304      // 0 <> -2,50012500572888E-05 for y in SQR(LOG('y'))
     305      // 0 <> 2, 49987500573946E-05 for x in SQR(LOG('x'))
    298306    }
    299307
     
    411419      Assert.AreEqual(3, r.UpperBound);
    412420
    413       Assert.AreEqual(0.0, lg[0]); // x
    414       Assert.AreEqual(0.0, ug[0]); XXXX
    415 
    416       t = parser.Parse("sqrt(y)");
     421      Assert.AreEqual(2.0 / 3.0, lg[0]); // x
     422      Assert.AreEqual(1.0, ug[0]);
     423
     424      t = parser.Parse("cuberoot(y)");
    417425      paramNodes = t.IterateNodesPostfix().Where(n => n.SubtreeCount == 0).ToArray();
    418426      r = eval.Evaluate(t, intervals, paramNodes, out lg, out ug);
    419       Assert.AreEqual(0.0, r.LowerBound);
    420       Assert.AreEqual(0.0, r.UpperBound);
    421 
    422       Assert.AreEqual(0.0, lg[0]); // y
    423       Assert.AreEqual(0.0, ug[0], 1e-5);
     427      Assert.AreEqual(Math.Pow(1, 1.0/3.0), r.LowerBound);
     428      Assert.AreEqual(Math.Pow(2, 1.0 / 3.0), r.UpperBound);
     429
     430      Assert.AreEqual(1.0 / 3.0, lg[0]); // y
     431      Assert.AreEqual(1.0 / 3.0 * Math.Pow(2, 1.0/3.0), ug[0], 1e-5);
    424432
    425433      t = parser.Parse("sqrt(z)");
     
    427435      r = eval.Evaluate(t, intervals, paramNodes, out lg, out ug);
    428436      Assert.AreEqual(0.0, r.LowerBound);
    429       Assert.AreEqual(0.0, r.UpperBound);
     437      Assert.AreEqual(1.0, r.UpperBound);
    430438
    431439      Assert.AreEqual(0.0, lg[0]); // z
    432       Assert.AreEqual(0.0, ug[0], 1e-5);
     440      Assert.AreEqual(1.0/3.0, ug[0], 1e-5);
    433441    }
    434442
  • branches/2994-AutoDiffForIntervals/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis-3.4/IntervalTest.cs

    r17312 r17314  
    7777
    7878      // [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)
     79      Assert.AreEqual(expected: new Interval(1, double.PositiveInfinity), actual: Interval.Divide(new Interval(0, 1), new Interval(0, 1))); // returns [NaN, NaN] because of (0 / 0)
    8080    }
    8181
Note: See TracChangeset for help on using the changeset viewer.