1  using System;


2  using System.Diagnostics;


3 


4  namespace 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  } 
