Beispiel #1
0
        private static int?Compare(T left, Bound <T> right)
        {
            switch (right._type)
            {
            case BoundType.NegativeInfinity:
                return(1);

            case BoundType.PositiveInfinity:
                return(-1);

            case BoundType.Closed:
                return(left.CompareTo((T)right));

            default: {
                int cmp = left.CompareTo((T)right);
                return(cmp == 0 ? (int?)null : cmp);
            }
            }
        }
Beispiel #2
0
        private static void CheckBounds(Bound <T> lowerBound, Bound <T> upperBound)
        {
            if (lowerBound == null || upperBound == null)
            {
                throw new ArgumentException("Bounds cannot be null.");
            }

            if (lowerBound.IsPositiveInfinity())
            {
                throw new ArgumentException("Lower bound cannot be positive infinity.");
            }

            if (upperBound.IsNegativeInfinity())
            {
                throw new ArgumentException("Upper bound cannot be negative infinity.");
            }

            if (!lowerBound.IsNegativeInfinity() && (T)lowerBound > upperBound ||
                !upperBound.IsPositiveInfinity() && lowerBound > (T)upperBound)
            {
                throw new ArgumentException("Lower bound must be <= upper bound.");
            }
        }
Beispiel #3
0
        private static List <Interval <T> > SingleIntervalComplement <T>(Interval <T> interval) where T : IComparable
        {
            if (interval.IsEmpty())
            {
                return(new List <Interval <T> > {
                    Interval <T> .FromBounds(Bound <T> .NegativeInfinity(), Bound <T> .PositiveInfinity())
                });
            }

            if (interval.LowerBound.IsNegativeInfinity())
            {
                if (interval.UpperBound.IsPositiveInfinity())
                {
                    return(new List <Interval <T> > {
                        Interval <T> .Empty()
                    });
                }

                return(new List <Interval <T> > {
                    UpperUnbounded()
                });
            }

            if (interval.UpperBound.IsPositiveInfinity())
            {
                return(new List <Interval <T> > {
                    LowerUnbounded()
                });
            }

            return(new List <Interval <T> > {
                LowerUnbounded(), UpperUnbounded()
            });

            // Local functions

            Interval <T> UpperUnbounded()
            {
                return(Interval <T> .FromBounds(interval.UpperBound.IsOpen()
                                                ?Bound <T> .Closed(interval.UpperBound)
                                                : Bound <T> .Open(interval.UpperBound), Bound <T> .PositiveInfinity()));
            }

            Interval <T> LowerUnbounded()
            {
                return(Interval <T> .FromBounds(Bound <T> .NegativeInfinity(), interval.LowerBound.IsOpen()
                                                ?Bound <T> .Closed(interval.LowerBound)
                                                : Bound <T> .Open(interval.LowerBound)));
            }
        }
Beispiel #4
0
 /// <summary>
 /// Two bounds are considered equal if their type (open, closed) and their values are equal. infinity bounds
 /// are always considered not equal.
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public bool Equals(Bound <T> other)
 {
     return(_type != BoundType.PositiveInfinity &&
            _type != BoundType.NegativeInfinity &&
            EqualityComparer <T> .Default.Equals(_value, other._value) && _type == other._type);
 }
Beispiel #5
0
 /// <summary>
 /// Creates an interval given its bounds.
 /// </summary>
 /// <param name="lowerBound">The lower bound.</param>
 /// <param name="upperBound">The upper bound.</param>
 /// <returns>The newly created interval.</returns>
 public static Interval <T> FromBounds(Bound <T> lowerBound, Bound <T> upperBound)
 {
     return(lowerBound == upperBound && (lowerBound.IsOpen() || upperBound.IsOpen())
         ? new EmptyInterval <T>()
         : new Interval <T>(lowerBound, upperBound));
 }
Beispiel #6
0
 /// <summary>
 /// Creates an interval with a closed lower bound and an open upper bound.
 /// </summary>
 /// <param name="lowerBound">The lower bound.</param>
 /// <param name="upperBound">The upper bound.</param>
 public static Interval <T> ClosedOpen(T lowerBound, T upperBound)
 {
     return(FromBounds(Bound <T> .Closed(lowerBound), Bound <T> .Open(upperBound)));
 }
Beispiel #7
0
 /// <summary>
 /// Creates an interval given its bounds.
 /// </summary>
 /// <param name="lowerBound">The lower bound.</param>
 /// <param name="upperBound">The upper bound.</param>
 private Interval(Bound <T> lowerBound, Bound <T> upperBound)
 {
     CheckBounds(lowerBound, upperBound);
     LowerBound = lowerBound;
     UpperBound = upperBound;
 }