Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/13/19 14:50:26 (4 years ago)
Author:
chaider
Message:

#3032

  • Added IsAlmost method with an epsilon parameter
  • Added check for floating point issues at interval constructor
  • Updated absolute operator (jump over zero between lower and upper bound)
  • Updated analytical quotient to use already implemented operators to build it
  • Updated test cases for operators
  • Refactored test method names
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval.cs

    r17348 r17350  
    3737    protected Interval(StorableConstructorFlag _) { }
    3838
     39    /// <summary>
     40    /// Creates an interval with given bounds, where lower bound must be smaller than
     41    /// the upper bound. Floating point precision errors trough calculations are fixed by,
     42    /// checking if the intervals are almost the same (E-12). If this is the case, the bounds
     43    /// will be set to the bound closer to zero.
     44    /// </summary>
     45    /// <param name="lowerBound">Lower bound of the interval</param>
     46    /// <param name="upperBound">Upper bound of the interval</param>
    3947    public Interval(double lowerBound, double upperBound) {
     48      if (lowerBound.IsAlmost(upperBound)) {
     49        //If the bounds go over zero
     50        if (lowerBound <= 0 && upperBound >= 0) {
     51          lowerBound = 0.0;
     52          upperBound = 0.0;
     53          //Interval is negative
     54        } else if (upperBound < 0) {
     55          lowerBound = upperBound;
     56          //Interval is positive
     57        } else {
     58          upperBound = lowerBound;
     59        }
     60      }
     61
    4062      if (lowerBound > upperBound)
    4163        throw new ArgumentException("LowerBound must be smaller than UpperBound.");
     
    5880                double.IsNaN(LowerBound) || double.IsNaN(UpperBound);
    5981      }
     82    }
     83
     84    /// <summary>
     85    /// True if the interval is positive without zero
     86    /// </summary>
     87    public bool IsPositive {
     88      get => LowerBound > 0.0;
     89    }
     90
     91    /// <summary>
     92    /// True if the interval is negative without zero
     93    /// </summary>
     94    public bool IsNegative {
     95      get => UpperBound < 0.0;
    6096    }
    6197
     
    128164    }
    129165
    130     //mkommend: Division by intervals containing 0 is implemented as defined in
     166    //Division by intervals containing 0 is implemented as defined in
    131167    //http://en.wikipedia.org/wiki/Interval_arithmetic
    132168    public static Interval Divide(Interval a, Interval b) {
     
    171207    public static Interval Tangens(Interval a) {
    172208      return Interval.Divide(Interval.Sine(a), Interval.Cosine(a));
    173     } 
     209    }
    174210    public static Interval HyperbolicTangent(Interval a) {
    175211      return new Interval(Math.Tanh(a.LowerBound), Math.Tanh(a.UpperBound));
     
    206242      if (a.UpperBound <= 0) return new Interval(a.UpperBound * a.UpperBound, a.LowerBound * a.LowerBound);     // interval is negative
    207243      else if (a.LowerBound >= 0) return new Interval(a.LowerBound * a.LowerBound, a.UpperBound * a.UpperBound); // interval is positive
    208       else return new Interval(0, Math.Max(a.LowerBound*a.LowerBound, a.UpperBound*a.UpperBound)); // interval goes over zero
     244      else return new Interval(0, Math.Max(a.LowerBound * a.LowerBound, a.UpperBound * a.UpperBound)); // interval goes over zero
    209245    }
    210246
     
    235271      var absLower = Math.Abs(a.LowerBound);
    236272      var absUpper = Math.Abs(a.UpperBound);
    237       return new Interval(Math.Min(absLower, absUpper), Math.Max(absLower, absUpper));
     273      var min = Math.Min(absLower, absUpper);
     274      var max = Math.Max(absLower, absUpper);
     275
     276      if (a.Contains(0.0)) {
     277        min = 0.0;
     278      }
     279
     280      return new Interval(min, max);
    238281    }
    239282
    240283    public static Interval AnalyticalQuotient(Interval a, Interval b) {
    241       if (b.LowerBound <= 0 && b.UpperBound >= 0) //Second interval goes over zero or is zero
    242         return new Interval(a.LowerBound, a.UpperBound);
    243 
    244       var values = new List<double> {
    245         a.LowerBound / Math.Sqrt(Math.Pow(b.LowerBound, 2) + 1),
    246         a.LowerBound / Math.Sqrt(Math.Pow(b.UpperBound, 2) + 1),
    247         a.UpperBound / Math.Sqrt(Math.Pow(b.LowerBound, 2) + 1),
    248         a.UpperBound / Math.Sqrt(Math.Pow(b.UpperBound, 2) + 1)
    249       };
    250 
    251       return new Interval(values.Min(), values.Max());
     284      var dividend = a;
     285      var divisor = Add(Square(b), new Interval(1.0, 1.0));
     286      divisor = SquareRoot(divisor);
     287
     288      var quotient = Divide(dividend, divisor);
     289      return quotient;
    252290    }
    253291    #endregion
Note: See TracChangeset for help on using the changeset viewer.