Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
10/03/19 12:30:19 (5 years ago)
Author:
gkronber
Message:

#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:
1 edited

Legend:

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

    r17295 r17303  
    4747      var v4 = high.Clone().Mul(a.high);
    4848
    49       low = Min(Min(v1, v2), Min(v3, v4));
    50       high = Max(Max(v1, v2), Max(v3, v4));
    51 
    52       return this;
    53     }
    54 
    55 
    56     private static MultivariateDual<AlgebraicDouble> Min(MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) {
    57       return a.Value < b.Value ? a : b;
    58     }
    59     private static MultivariateDual<AlgebraicDouble> Max(MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) {
    60       return a.Value > b.Value ? a : b;
     49      AssignLowAndHigh(v1, v2, v3, v4);
     50
     51      return this;
    6152    }
    6253
     
    133124        if (a.Contains(0.0)) {
    134125          low = new MultivariateDual<AlgebraicDouble>(0.0);
    135           high = a.low.IntPower(p).AssignMax(a.high.IntPower(p));
    136         } else {
    137           var lowPower = a.low.IntPower(p);
    138           var highPower = a.high.IntPower(p);
    139           low = lowPower.AssignMin(highPower);
    140           high = lowPower.AssignMax(highPower);
     126          AssignMax(high, a.low.IntPower(p), a.high.IntPower(p));
     127        } else {
     128          AssignLowAndHigh(a.low.IntPower(p), a.high.IntPower(p));
    141129        }
    142130      } else {
     
    148136          var lowPower = a.low.IntPower(p);
    149137          var highPower = a.high.IntPower(p);
    150           low = lowPower.AssignMin(highPower);
    151           high = lowPower.AssignMax(highPower);
     138          AssignMin(low, lowPower, highPower);
     139          AssignMax(high, lowPower, highPower);
    152140        }
    153141      }
     
    217205
    218206      // assume low and high are in the same quadrant
    219       low = Algebraic.Min(a.LowerBound.Clone().Sin(), a.UpperBound.Clone().Sin());
    220       high = Algebraic.Max(a.LowerBound.Clone().Sin(), a.UpperBound.Clone().Sin());
     207      AssignLowAndHigh(a.LowerBound.Clone().Sin(), a.UpperBound.Clone().Sin()); // AssignLowAndHigh determines the lower and higher value
    221208
    222209      // override min and max if necessary
     
    260247    public AlgebraicInterval AssignAbs(AlgebraicInterval a) {
    261248      if (a.Contains(0.0)) {
     249        low.Assign(new MultivariateDual<AlgebraicDouble>(0.0)); // lost gradient for lower bound
     250        AssignMax(high, a.low.Clone().Abs(), a.high.Clone().Abs());
     251      } else {
    262252        var abslow = a.low.Clone().Abs();
    263253        var abshigh = a.high.Clone().Abs();
    264         a.high.Assign(Algebraic.Max(abslow, abshigh));
    265         a.low.Assign(new MultivariateDual<AlgebraicDouble>(0.0)); // lost gradient for lower bound
    266       } else {
    267         var abslow = a.low.Clone().Abs();
    268         var abshigh = a.high.Clone().Abs();
    269         a.low.Assign(Algebraic.Min(abslow, abshigh));
    270         a.high.Assign(Algebraic.Max(abslow, abshigh));
     254        AssignLowAndHigh(abslow, abshigh);
    271255      }
    272256      return this;
     
    279263    }
    280264
    281     public AlgebraicInterval AssignMin(AlgebraicInterval other) {
    282       low.AssignMin(other.low);
    283       high.AssignMin(other.high);
    284       return this;
    285     }
    286 
    287     public AlgebraicInterval AssignMax(AlgebraicInterval other) {
    288       low.AssignMax(other.low);
    289       high.AssignMax(other.high);
    290       return this;
    291     }
     265
     266    #region helper
     267    private void AssignMin(MultivariateDual<AlgebraicDouble> dest, MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) {
     268      if (a.Value.CompareTo(b.Value) <= 0) {
     269        dest.Assign(a);
     270      } else {
     271        dest.Assign(b);
     272      }
     273    }
     274    private void AssignMax(MultivariateDual<AlgebraicDouble> dest, MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) {
     275      if (a.Value.CompareTo(b.Value) <= 0) {
     276        dest.Assign(b);
     277      } else {
     278        dest.Assign(a);
     279      }
     280    }
     281
     282    // determines the smaller and larger value and sets low and high accordingly
     283    private void AssignLowAndHigh(MultivariateDual<AlgebraicDouble> a, MultivariateDual<AlgebraicDouble> b) {
     284      // we must make sure that low and high are different objects when a == b
     285      if (a.Value.CompareTo(b.Value) == 0) {
     286        low.Assign(a);
     287        high.Assign(b);
     288      } else {
     289        AssignMin(low, a, b);
     290        AssignMax(high, a, b);
     291      }
     292    }
     293    private void AssignLowAndHigh(params MultivariateDual<AlgebraicDouble>[] xs) {
     294      if (xs.Length <= 2) throw new ArgumentException("need at least 3 arguments");
     295      AssignLowAndHigh(xs[0], xs[1]);
     296      for(int i=2;i<xs.Length;i++) {
     297        // we must make sure that low and high are different objects when a == b
     298        if (low.Value.CompareTo(xs[i].Value) > 0) low.Assign(xs[i]);
     299        if (high.Value.CompareTo(xs[i].Value) < 0) high.Assign(xs[i]);
     300      }
     301    }
     302    #endregion
     303
    292304  }
    293305}
Note: See TracChangeset for help on using the changeset viewer.