source: branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/AlgebraicDouble.cs @ 17303

Last change on this file since 17303 was 17303, checked in by gkronber, 3 years ago

#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

File size: 3.4 KB
Line 
1using System;
2using System.Diagnostics;
3
4namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
5  // algebraic type wrapper for a double value
6  [DebuggerDisplay("{Value}")]
7  public sealed class AlgebraicDouble : IComparableAlgebraicType<AlgebraicDouble> {
8    public static implicit operator AlgebraicDouble(double value) { return new AlgebraicDouble(value); }
9    public static implicit operator double(AlgebraicDouble value) { return value.Value; }
10    public double Value;
11
12    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
13    public AlgebraicDouble Zero => new AlgebraicDouble(0.0);
14    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
15    public AlgebraicDouble One => new AlgebraicDouble(1.0);
16
17    public bool IsInfinity => IsNegativeInfinity || IsPositiveInfinity;
18    public bool IsNegativeInfinity => double.IsNegativeInfinity(Value);
19    public bool IsPositiveInfinity => double.IsPositiveInfinity(Value);
20    public AlgebraicDouble() { }
21    public AlgebraicDouble(double value) { this.Value = value; }
22    public AlgebraicDouble Assign(AlgebraicDouble a) { Value = a.Value; return this; }
23    public AlgebraicDouble Add(AlgebraicDouble a) { Value += a.Value; return this; }
24    public AlgebraicDouble Sub(AlgebraicDouble a) { Value -= a.Value; return this; }
25    public AlgebraicDouble Mul(AlgebraicDouble a) { Value *= a.Value; return this; }
26    public AlgebraicDouble Div(AlgebraicDouble a) { Value /= a.Value; return this; }
27    public AlgebraicDouble Scale(double s) { Value *= s; return this; }
28    public AlgebraicDouble AssignInv(AlgebraicDouble a) { Value = 1.0 / a.Value; return this; }
29    public AlgebraicDouble AssignNeg(AlgebraicDouble a) { Value = -a.Value; return this; }
30    public AlgebraicDouble AssignSin(AlgebraicDouble a) { Value = Math.Sin(a.Value); return this; }
31    public AlgebraicDouble AssignCos(AlgebraicDouble a) { Value = Math.Cos(a.Value); return this; }
32    public AlgebraicDouble AssignTanh(AlgebraicDouble a) { Value = Math.Tanh(a.Value); return this; }
33    public AlgebraicDouble AssignLog(AlgebraicDouble a) { Value = Math.Log(a.Value); return this; }
34    public AlgebraicDouble AssignExp(AlgebraicDouble a) { Value = Math.Exp(a.Value); return this; }
35    public AlgebraicDouble AssignIntPower(AlgebraicDouble a, int p) { Value = Math.Pow(a.Value, p); return this; }
36    public AlgebraicDouble AssignIntRoot(AlgebraicDouble a, int r) { Value = IntRoot(a.Value, r); return this; }
37    //public AlgebraicDouble AssignMin(AlgebraicDouble other) { Value = Math.Min(Value, other.Value); return this; }
38    //public AlgebraicDouble AssignMax(AlgebraicDouble other) { Value = Math.Max(Value, other.Value); return this; }
39    public AlgebraicDouble AssignAbs(AlgebraicDouble a) { Value = Math.Abs(a.Value); return this; }
40    public AlgebraicDouble AssignSgn(AlgebraicDouble a) { Value = double.IsNaN(a.Value) ? double.NaN : Math.Sign(a.Value); return this; }
41
42    // helper
43    private static double IntRoot(double value, int r) {
44      if (r % 2 == 0) return Math.Pow(value, 1.0 / r);
45      else return value < 0 ? -Math.Pow(-value, 1.0 / r) : Math.Pow(value, 1.0 / r);
46    }
47
48    public AlgebraicDouble Clone() { return new AlgebraicDouble(Value); }
49
50    public override string ToString() {
51      return Value.ToString();
52    }
53
54    public int CompareTo(AlgebraicDouble other) {
55      return Value.CompareTo(other.Value);
56    }
57  }
58}
Note: See TracBrowser for help on using the repository browser.