Changeset 16744
- Timestamp:
- 04/02/19 13:55:49 (6 years ago)
- Location:
- branches/2994-AutoDiffForIntervals
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Interpreter.cs
r16738 r16744 285 285 var g = code[0].value.Gradient; 286 286 for (int j = 0; j < nParams; ++j) { 287 if (g.Elements.TryGetValue(j, out AlgebraicDoubleVector v)) {287 if (g.Elements.TryGetValue(j, out AlgebraicDoubleVector v)) { 288 288 v.CopyColumnTo(jac, j, rowIndex, BATCHSIZE); 289 289 } else { … … 490 490 public AlgebraicDouble AssignSin(AlgebraicDouble a) { Value = Math.Sin(a.Value); return this; } 491 491 public AlgebraicDouble AssignCos(AlgebraicDouble a) { Value = Math.Cos(a.Value); return this; } 492 public AlgebraicDouble AssignLog(AlgebraicDouble a) { Value = a.Value <= 0 ?double.NegativeInfinity : Math.Log(a.Value); return this; } // alternative definiton of log to prevent NaN492 public AlgebraicDouble AssignLog(AlgebraicDouble a) { Value = a.Value <= 0 ? double.NegativeInfinity : Math.Log(a.Value); return this; } // alternative definiton of log to prevent NaN 493 493 public AlgebraicDouble AssignExp(AlgebraicDouble a) { Value = Math.Exp(a.Value); return this; } 494 494 public AlgebraicDouble AssignIntPower(AlgebraicDouble a, int p) { Value = Math.Pow(a.Value, p); return this; } 495 495 public AlgebraicDouble AssignIntRoot(AlgebraicDouble a, int r) { Value = Math.Pow(a.Value, 1.0 / r); return this; } 496 496 public AlgebraicDouble AssignAbs(AlgebraicDouble a) { Value = Math.Abs(a.Value); return this; } 497 public AlgebraicDouble AssignSgn(AlgebraicDouble a) { Value = double.IsNaN(a.Value) ? double.NaN : Math.Sign(a.Value); return this; }497 public AlgebraicDouble AssignSgn(AlgebraicDouble a) { Value = double.IsNaN(a.Value) ? double.NaN : Math.Sign(a.Value); return this; } 498 498 public AlgebraicDouble Clone() { return new AlgebraicDouble(Value); } 499 499 … … 828 828 } 829 829 830 // Exponentiation by a natural power[a, b] k:831 //832 // if 0∈[a, b], then833 // [a, b]^0 = [0, 1]834 // [a, b]^2n = [0, max(a2n, b2n)]835 // [a, b]^2n+1 = [a2n+1, b2n+1]836 // if [a, b]>0, then837 // [a, b]^0 = [1, 1]838 // [a, b]^k>0 = [ak, bk]839 // if [a, b]<0, then840 // [a, b]^0 = [1, 1]841 // [a, b]^2n = [b2n, a2n]842 // [a, b]^2n+1 = [a2n+1, b2n+1]843 844 830 public AlgebraicInterval AssignIntPower(AlgebraicInterval a, int p) { 845 if (p == 0) {846 // => 1847 low = new MultivariateDual<AlgebraicDouble>(1.0);848 high = new MultivariateDual<AlgebraicDouble>(1.0);849 return this;850 }851 if (p == 1) return this;852 853 831 if (p < 0) { // x^-3 == 1/(x^3) 854 832 AssignIntPower(a, -p); 855 833 return AssignInv(this); 856 } else { 834 } else if (p == 0) { 835 if (a.Contains(0.0)) { 836 // => 0^0 = 0 ; might not be relevant 837 low = new MultivariateDual<AlgebraicDouble>(0.0); 838 high = new MultivariateDual<AlgebraicDouble>(1.0); 839 return this; 840 } else { 841 // => 1 842 low = new MultivariateDual<AlgebraicDouble>(1.0); 843 high = new MultivariateDual<AlgebraicDouble>(1.0); 844 return this; 845 } 846 } else if (p == 1) return this; 847 else if (p % 2 == 0) { 857 848 // p is even => interval must be positive 858 if (p % 2 == 0) { 859 if (a.Contains(0.0)) { 860 low = new MultivariateDual<AlgebraicDouble>(0.0); 861 high = Algebraic.Max(a.low.IntPower(p), a.high.IntPower(p)); 862 } else { 863 var lowPower = a.low.IntPower(p); 864 var highPower = a.high.IntPower(p); 865 low = Algebraic.Min(lowPower, highPower); 866 high = Algebraic.Max(lowPower, highPower); 867 } 849 if (a.Contains(0.0)) { 850 low = new MultivariateDual<AlgebraicDouble>(0.0); 851 high = Algebraic.Max(a.low.IntPower(p), a.high.IntPower(p)); 868 852 } else { 869 // p is uneven870 853 var lowPower = a.low.IntPower(p); 871 854 var highPower = a.high.IntPower(p); … … 873 856 high = Algebraic.Max(lowPower, highPower); 874 857 } 875 return this; 876 } 858 } else { 859 // p is uneven 860 if (a.Contains(0.0)) { 861 low.AssignIntPower(a.low, p); 862 high.AssignIntPower(a.high, p); 863 } else { 864 var lowPower = a.low.IntPower(p); 865 var highPower = a.high.IntPower(p); 866 low = Algebraic.Min(lowPower, highPower); 867 high = Algebraic.Max(lowPower, highPower); 868 } 869 } 870 return this; 877 871 } 878 872 -
branches/2994-AutoDiffForIntervals/Tests/AutoDiffTest.cs
r16738 r16744 107 107 108 108 { 109 // Interval tests 110 var intervals = new Dictionary<string, Interval>(); 111 intervals.Add("x", new Interval(-2.0, 3.0)); 112 intervals.Add("p", new Interval(1.0, 2.0)); 113 intervals.Add("n", new Interval(-2.0, -1.0)); 114 115 AssertInterval("10*x", intervals, -20, 30); 116 AssertInterval("sqr(p)", intervals, 1, 4); 117 AssertInterval("sqr(n)", intervals, 1, 4); 118 AssertInterval("sqr(x)", intervals, 0, 9); 119 120 AssertInterval("cube(p)", intervals, 1, 8); 121 AssertInterval("cube(n)", intervals, -8, -1); 122 AssertInterval("cube(x)", intervals, -8, 27); 123 } 124 125 { 109 126 // interval eval and auto-diff 110 127 var parser = new InfixExpressionParser(); … … 226 243 227 244 } 245 246 private void AssertInterval(string expression, Dictionary<string, Interval> intervals, double expectedLow, double expectedHigh) { 247 var parser = new InfixExpressionParser(); 248 var t = parser.Parse(expression); 249 var evaluator = new IntervalEvaluator(); 250 var result = evaluator.Evaluate(t, intervals); 251 Assert.AreEqual(expectedLow, result.LowerBound); 252 Assert.AreEqual(expectedHigh, result.UpperBound); 253 } 228 254 } 229 255 }
Note: See TracChangeset
for help on using the changeset viewer.