Changeset 17212 for branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Interpreter.cs
- Timestamp:
- 08/13/19 13:41:21 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Interpreter.cs
r17203 r17212 484 484 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 485 485 public AlgebraicDouble One => new AlgebraicDouble(1.0); 486 487 public bool IsInfinity => IsNegativeInfinity || IsPositiveInfinity; 488 public bool IsNegativeInfinity => double.IsNegativeInfinity(Value); 489 public bool IsPositiveInfinity => double.IsPositiveInfinity(Value); 486 490 public AlgebraicDouble() { } 487 491 public AlgebraicDouble(double value) { this.Value = value; } … … 497 501 public AlgebraicDouble AssignCos(AlgebraicDouble a) { Value = Math.Cos(a.Value); return this; } 498 502 public AlgebraicDouble AssignTanh(AlgebraicDouble a) { Value = Math.Tanh(a.Value); return this; } 499 public AlgebraicDouble AssignLog(AlgebraicDouble a) { Value = a.Value <= 0 ? double.NegativeInfinity : Math.Log(a.Value); return this; } // alternative definiton of log to prevent NaN503 public AlgebraicDouble AssignLog(AlgebraicDouble a) { Value = Math.Log(a.Value); return this; } 500 504 public AlgebraicDouble AssignExp(AlgebraicDouble a) { Value = Math.Exp(a.Value); return this; } 501 505 public AlgebraicDouble AssignIntPower(AlgebraicDouble a, int p) { Value = Math.Pow(a.Value, p); return this; } … … 803 807 var v4 = high.Clone().Mul(a.high); 804 808 805 low = Algebraic.Min(Algebraic.Min(v1, v2), Algebraic.Min(v3, v4)); 806 high = Algebraic.Max(Algebraic.Max(v1, v2), Algebraic.Max(v3, v4)); 807 return this; 809 low = Min(Min(v1, v2), Min(v3, v4)); 810 high = Max(Max(v1, v2), Max(v3, v4)); 811 812 return this; 813 } 814 815 // algebraic min() / max() do not work for infinities 816 // detect and handle infinite values explicitly 817 private static MultivariateDual<AlgebraicDouble> Min(MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) { 818 if (a.Value.IsInfinity || b.Value.IsInfinity) return a.Value < b.Value ? a : b; // NOTE: this is not differentiable but for infinite values we do not care 819 else return Algebraic.Min(a, b); // differentiable statement 820 } 821 private static MultivariateDual<AlgebraicDouble> Max(MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) { 822 if (a.Value.IsInfinity || b.Value.IsInfinity) return a.Value >= b.Value ? a : b; // NOTE: this is not differentiable but for infinite values we do not care 823 else return Algebraic.Max(a, b); // differentiable statement 808 824 } 809 825 … … 815 831 816 832 public AlgebraicInterval AssignCos(AlgebraicInterval a) { 817 return AssignSin(a.Clone(). Sub(new AlgebraicInterval(Math.PI / 2, Math.PI / 2)));833 return AssignSin(a.Clone().Add(new AlgebraicInterval(Math.PI / 2, Math.PI / 2))); 818 834 } 819 835 … … 821 837 if (a.Contains(0.0)) { 822 838 if (a.low.Value.Value == 0 && a.high.Value.Value == 0) { 839 if (this.low.Value >= 0) { 840 // pos / 0 841 } else if (this.high.Value <= 0) { 842 // neg / 0 843 } else { 844 low = new MultivariateDual<AlgebraicDouble>(double.NegativeInfinity); 845 high = new MultivariateDual<AlgebraicDouble>(double.PositiveInfinity); 846 } 847 } else if (a.low.Value.Value >= 0) { 848 // a is positive 849 Mul(new AlgebraicInterval(a.Clone().high.Inv(), new MultivariateDual<AlgebraicDouble>(double.PositiveInfinity))); 850 } else if (a.high.Value <= 0) { 851 // a is negative 852 Mul(new AlgebraicInterval(new MultivariateDual<AlgebraicDouble>(double.NegativeInfinity), a.low.Clone().Inv())); 853 } else { 854 // a is interval over zero 823 855 low = new MultivariateDual<AlgebraicDouble>(double.NegativeInfinity); 824 856 high = new MultivariateDual<AlgebraicDouble>(double.PositiveInfinity); 825 } else if (a.low.Value.Value == 0) 826 Mul(new AlgebraicInterval(a.Clone().high.Inv(), new MultivariateDual<AlgebraicDouble>(double.PositiveInfinity))); 827 else 828 Mul(new AlgebraicInterval(new MultivariateDual<AlgebraicDouble>(double.NegativeInfinity), a.low.Clone().Inv())); 857 } 829 858 } else { 830 859 Mul(new AlgebraicInterval(a.high.Clone().Inv(), a.low.Clone().Inv())); // inverting leads to inverse roles of high and low … … 947 976 low = new MultivariateDual<AlgebraicDouble>(-1.0); // zero gradient 948 977 high = new MultivariateDual<AlgebraicDouble>(1.0); 978 return this; 949 979 } 950 980 … … 1145 1175 public MultivariateDual<V> AssignAbs(MultivariateDual<V> a) { v.AssignAbs(a.v); dv.Assign(a.dv).Scale(a.v.Clone().Sgn()); return this; } // abs(f(x))' = f(x)*f'(x) / |f(x)| doesn't work for intervals 1146 1176 public MultivariateDual<V> AssignSgn(MultivariateDual<V> a) { v.AssignSgn(a.v); dv = a.dv.Zero; return this; } // sign(f(x))' = 0; 1177 1147 1178 } 1148 1179 }
Note: See TracChangeset
for help on using the changeset viewer.