Beispiel #1
0
        public bool Equals(IntDomain2 domain)
        {
            if (ReferenceEquals(domain, this))
            {
                return(true);
            }

            if (IsSimple() && domain.IsSimple())
            {
                return(m_Interval.Equals(domain.m_Interval));
            }

            if (IsSimple() ^ domain.IsSimple())
            {
                return(false);
            }

            bool equal = m_IntervalList.Count == domain.m_IntervalList.Count;

            if (equal)
            {
                for (int idx = 0; idx < m_IntervalList.Count && equal; ++idx)
                {
                    equal &= m_IntervalList[idx].Equals(domain.m_IntervalList[idx]);
                }
            }

            return(equal);
        }
Beispiel #2
0
        public IntDomain2 Square()
        {
            if (IsEmpty())
            {
                return(m_Empty);
            }

            if ((m_Interval.IsZero()) ||
                (m_Interval.Min == 1 && m_Interval.Max == 1))
            {
                return(this);
            }

            IntDomain2 result = new IntDomain2();

            result.m_Interval = m_Interval.Square();

            if (IsSimple())
            {
                return(result);
            }

            result.m_IntervalList = new List <IntInterval>(m_IntervalList.Count);
            foreach (IntInterval interval in m_IntervalList)
            {
                result.m_IntervalList.Add(interval.Square());
            }

            return(result);
        }
Beispiel #3
0
        public bool IntersectsWith(IntDomain2 domain)
        {
            if (ReferenceEquals(domain, this))
            {
                return(true);
            }

            if (domain.IsEmpty())
            {
                return(false);
            }

            // 1, 6
            if (!m_Interval.IntersectsWith(domain.m_Interval))
            {
                return(false);
            }

            if (domain.IsSimple())
            {
                return(IntersectsWith(domain.m_Interval));
            }

            if (IsSimple())
            {
                return(domain.IntersectsWith(m_Interval));
            }

            int  index0    = 0;
            int  index1    = 0;
            bool intersect = false;

            while (index0 < m_IntervalList.Count &&
                   index1 < domain.m_IntervalList.Count &&
                   !intersect)
            {
                IntInterval ival0 = m_IntervalList[index0];
                IntInterval ival1 = domain.m_IntervalList[index1];

                if (ival0.Max < ival1.Min)
                {
                    ++index0;
                }
                else if (ival1.Max < ival0.Min)
                {
                    ++index1;
                }
                else
                {
                    intersect = true;
                }
            }

            return(intersect);
        }
Beispiel #4
0
        public IntDomain2 Subtract(IntDomain2 domain)
        {
            IntInterval interval = domain.Interval;

            if (interval.Min == 0 && interval.Max == 0)
            {
                return(this);
            }

            return(new IntDomain2(m_Interval - interval));
        }
Beispiel #5
0
        public IntDomain2 Multiply(IntDomain2 domain)
        {
            IntInterval interval = domain.Interval;

            if (interval.Min == 1 && interval.Max == 1)
            {
                return(this);
            }

            return(new IntDomain2(m_Interval * interval));
        }
Beispiel #6
0
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(this, obj))
            {
                return(true);
            }

            IntDomain2 domain = obj as IntDomain2;

            if (!ReferenceEquals(domain, null))
            {
                return(Equals(domain));
            }

            return(false);
        }
Beispiel #7
0
        public IntDomain2 Sqrt()
        {
            if (IsEmpty())
            {
                return(m_Empty);
            }

            if (m_Interval.Max < 0)
            {
                return(m_Empty);
            }

            if ((m_Interval.IsZero()) ||
                (m_Interval.Min == 1 && m_Interval.Max == 1))
            {
                return(this);
            }

            IntDomain2 result = new IntDomain2();

            result.m_Interval = m_Interval.Sqrt();

            if (IsSimple())
            {
                return(result);
            }

            result.m_IntervalList = new List <IntInterval>(m_IntervalList.Count);
            for (int idx = 0; idx < m_IntervalList.Count; ++idx)
            {
                IntInterval interval = m_IntervalList[idx];

                if (interval.Max >= 0)
                {
                    result.m_IntervalList.Add(interval.Sqrt());
                }
            }

            return(result);
        }
Beispiel #8
0
        public IntDomain2 Negate()
        {
            if (m_Interval.IsBound() && m_Interval.Min == 0)
            {
                return(this);
            }

            IntDomain2 result = new IntDomain2();

            result.m_Interval = -m_Interval;
            if (IsSimple())
            {
                return(result);
            }

            result.m_IntervalList = new List <IntInterval>(m_IntervalList.Count);
            for (int idx = m_IntervalList.Count; idx > 0; --idx)
            {
                result.m_IntervalList.Add(-m_IntervalList[idx - 1]);
            }

            return(result);
        }
Beispiel #9
0
        public IntDomain2 Divide(IntDomain2 domain)
        {
            IntInterval interval = domain.Interval;

            if (interval.Min == 1 && interval.Max == 1)
            {
                return(this);
            }

            bool div2 = false;

            IntInterval intv1 = IntInterval.Divide1(m_Interval, interval, ref div2);

            if (div2)
            {
                IntInterval intv2 = IntInterval.Divide2(m_Interval, interval, div2);

                return(new IntDomain2(new IntInterval[] { intv1, intv2 }));
            }
            else
            {
                return(new IntDomain2(intv1));
            }
        }
Beispiel #10
0
        public IntDomain2 Intersect(IntDomain2 domain)
        {
            if (ReferenceEquals(domain, this))
            {
                return(this);
            }

            if (domain.IsEmpty())
            {
                return(m_Empty);
            }

            if (domain.IsSimple())
            {
                return(Intersect(domain.m_Interval));
            }

            // 1, 6
            if (!IntersectsWith(domain))
            {
                return(m_Empty);
            }

            // If the target is contained, then the result would be equal to the domain, hence we return the domain.
            if (IsSimple())
            {
                if (domain.Contains(m_Interval))
                {
                    return(this);
                }

                if (m_Interval.Contains(domain.m_Interval))
                {
                    return(domain);
                }
            }
            // Need to be a bit smart, put our interval in a list, in case it gets chopped up.
            List <IntInterval> intervalList;

            if (IsSimple())
            {
                intervalList = new List <IntInterval>(1);
                intervalList.Add(m_Interval);
            }
            else
            {
                intervalList = m_IntervalList;
            }

            IntDomain2 result = new IntDomain2();

            result.m_IntervalList = new List <IntInterval>(intervalList.Count + domain.m_IntervalList.Count);

            int  idx    = 0;
            int  domIdx = 0;
            bool equal  = true;

            while (idx < intervalList.Count ||
                   domIdx < domain.m_IntervalList.Count)
            {
                // 6
                if (idx == intervalList.Count)
                {
                    domIdx = domain.m_IntervalList.Count;
                }
                // 1
                else if (domIdx == domain.m_IntervalList.Count)
                {
                    idx   = intervalList.Count;
                    equal = false;
                }
                else
                {
                    IntInterval intv    = intervalList[idx];
                    IntInterval domIntv = domain.m_IntervalList[domIdx];

                    // 1 : completely before
                    if (domIntv.Max < intv.Min - 1)
                    {
                        ++domIdx;
                    }
                    // 6 : completely after
                    else if (domIntv.Min > intv.Max + 1)
                    {
                        ++idx;
                        equal = false;
                    }
                    // 3
                    else if (domIntv.Min <= intv.Min && domIntv.Max >= intv.Max)
                    {
                        result.m_IntervalList.Add(intv);
                        ++idx;
                    }
                    // ~4 : divide into two intervals...
                    else if (domIntv.Min > intv.Min && domIntv.Max < intv.Max)
                    {
                        result.m_IntervalList.Add(domIntv);
                        ++domIdx;
                        equal = false;
                    }
                    // 2
                    else if (domIntv.Min <= intv.Min && domIntv.Max < intv.Max)
                    {
                        result.m_IntervalList.Add(intv.Intersect(domIntv));
                        ++domIdx;
                        equal = false;
                    }
                    // 5
                    else if (domIntv.Min > intv.Min && domIntv.Max >= intv.Max)
                    {
                        result.m_IntervalList.Add(intv.Intersect(domIntv));
                        ++idx;
                        equal = false;
                    }
                }
            }

            if (equal)
            {
                return(this);
            }

            result.UpdateInterval();

            return(result);
        }
Beispiel #11
0
        public IntDomain2 Intersect(IntInterval interval)
        {
            if (interval.IsEmpty())
            {
                return(m_Empty);
            }

            // 1, 6
            if (!IntersectsWith(interval))
            {
                return(m_Empty);
            }

            // 3
            if (m_Interval.Min >= interval.Min && m_Interval.Max <= interval.Max)
            {
                return(this);
            }

            IntInterval intv = m_Interval.Intersect(interval);

            IntDomain2 result = new IntDomain2();

            result.m_Interval = intv;

            if (!IsSimple())
            {
                result.m_IntervalList = new List <IntInterval>(m_IntervalList.Count);

                int idx = 0;

                // 6 : completely before
                for ( ; idx < m_IntervalList.Count && m_IntervalList[idx].Max < interval.Min; ++idx)
                {
                }
                ;

                // 2
                if (idx < m_IntervalList.Count &&
                    m_IntervalList[idx].Min < interval.Min &&
                    m_IntervalList[idx].Max <= interval.Max)
                {
                    result.m_IntervalList.Add(m_IntervalList[idx].Intersect(interval));
                    ++idx;
                }

                // 4
                if (idx < m_IntervalList.Count &&
                    m_IntervalList[idx].Min <interval.Min &&
                                             m_IntervalList[idx].Max> interval.Max)
                {
                    result.m_IntervalList.Add(m_IntervalList[idx].Intersect(interval));
                }
                // 3
                else
                {
                    for ( ; idx < m_IntervalList.Count && interval.Contains(m_IntervalList[idx]); ++idx)
                    {
                        result.m_IntervalList.Add(m_IntervalList[idx]);
                    }
                }

                // 5
                if (idx < m_IntervalList.Count &&
                    m_IntervalList[idx].Min > interval.Min &&
                    m_IntervalList[idx].Max >= interval.Max)
                {
                    result.m_IntervalList.Add(m_IntervalList[idx].Intersect(interval));
                    ++idx;
                }

                // 1 : complete after can be skipped

                result.CheckSimple();
            }

            return(result);
        }
Beispiel #12
0
 public IntDomain2(IntDomain2 domain)
 {
     m_Interval     = domain.m_Interval;
     m_IntervalList = domain.m_IntervalList;
 }
Beispiel #13
0
        public IntDomain2 Difference(IntDomain2 domain)
        {
            if (ReferenceEquals(domain, this))
            {
                return(m_Empty);
            }

            if (domain.IsEmpty())
            {
                return(this);
            }

            if (domain.IsSimple())
            {
                return(Difference(domain.m_Interval));
            }

            //1, 6
            if (!IntersectsWith(domain.m_Interval))
            {
                return(this);
            }

            // Need to be a bit smart, put our interval in a list, in case it gets chopped up.
            List <IntInterval> intervalList;

            if (IsSimple())
            {
                intervalList = new List <IntInterval>(1);
                intervalList.Add(m_Interval);
            }
            else
            {
                intervalList = m_IntervalList;
            }

            IntDomain2 result = new IntDomain2();

            result.m_IntervalList = new List <IntInterval>(intervalList.Count + domain.m_IntervalList.Count);

            int idx    = 0;
            int domIdx = 0;

            while (idx < intervalList.Count ||
                   domIdx < domain.m_IntervalList.Count)
            {
                // 6
                if (idx == intervalList.Count)
                {
                    domIdx = domain.m_IntervalList.Count;
                }
                // 1
                else if (domIdx == domain.m_IntervalList.Count)
                {
                    idx = intervalList.Count;
                }
                else
                {
                    IntInterval intv    = intervalList[idx];
                    IntInterval domIntv = domain.m_IntervalList[domIdx];

                    // 1 : completely before
                    if (domIntv.Max < intv.Min - 1)
                    {
                        ++domIdx;
                    }
                    // 6 : completely after
                    else if (domIntv.Min > intv.Max + 1)
                    {
                        result.m_IntervalList.Add(intv);
                        ++idx;
                    }
                    // 3
                    else if (domIntv.Min < intv.Min && domIntv.Max > intv.Max)
                    {
                        ++idx;
                    }
                    // 4 : divide into two intervals...
                    else if (domIntv.Min > intv.Min && domIntv.Max < intv.Max)
                    {
                        while (domIdx < domain.m_IntervalList.Count &&
                               domIntv.Min > intv.Min &&
                               domIntv.Max < intv.Max)
                        {
                            result.m_IntervalList.Add(new IntInterval(intv.Min, domIntv.Min - 1));

                            intv = new IntInterval(domIntv.Max + 1, intv.Max);

                            ++domIdx;

                            if (domIdx < domain.m_IntervalList.Count)
                            {
                                domIntv = domain.m_IntervalList[domIdx];
                            }
                        }

                        result.m_IntervalList.Add(intv);
                    }
                    // 2
                    else if (domIntv.Min <= intv.Min && domIntv.Max < intv.Max)
                    {
                        result.m_IntervalList.Add(intv.Difference(domIntv));

                        ++domIdx;
                    }
                    // 5
                    else if (domIntv.Min > intv.Min && domIntv.Max >= intv.Max)
                    {
                        result.m_IntervalList.Add(intv.Difference(domIntv));

                        ++idx;
                    }
                }
            }

            result.UpdateInterval();

            return(result);
        }
Beispiel #14
0
        public IntDomain2 Difference(IntInterval interval)
        {
            if (interval.IsEmpty())
            {
                return(this);
            }

            // 1, 6
            if (!IntersectsWith(interval))
            {
                return(this);
            }

            // 3 : completely remove interval => empty
            if (interval.Min <= m_Interval.Min && interval.Max >= m_Interval.Max)
            {
                return(m_Empty);
            }

            // Result domain
            IntDomain2 result = new IntDomain2();

            result.m_Interval = m_Interval.Difference(interval);

            if (IsSimple())
            {
                // 4 : divide into two intervals...
                if (interval.Min > m_Interval.Min && interval.Max < m_Interval.Max)
                {
                    result.m_IntervalList = new List <IntInterval>(2);
                    result.m_IntervalList.Add(new IntInterval(m_Interval.Min, interval.Min - 1));
                    result.m_IntervalList.Add(new IntInterval(interval.Max + 1, m_Interval.Max));
                }
            }
            else
            {
                result.m_IntervalList = new List <IntInterval>(m_IntervalList.Count + 1);

                int idx = 0;

                // 6
                for ( ; idx < m_IntervalList.Count && m_IntervalList[idx].Max < interval.Min; ++idx)
                {
                    result.m_IntervalList.Add(m_IntervalList[idx]);
                }

                // 2
                if (idx < m_IntervalList.Count &&
                    m_IntervalList[idx].Min < interval.Min &&
                    m_IntervalList[idx].Max <= interval.Max)
                {
                    result.m_IntervalList.Add(m_IntervalList[idx].Difference(interval));
                    ++idx;
                }

                // 4 : divide into two intervals...
                if (idx < m_IntervalList.Count &&
                    m_IntervalList[idx].Min <interval.Min &&
                                             m_IntervalList[idx].Max> interval.Max)
                {
                    result.m_IntervalList.Add(new IntInterval(m_Interval.Min, interval.Min - 1));
                    result.m_IntervalList.Add(new IntInterval(interval.Max + 1, m_Interval.Max));
                }
                // 3
                else
                {
                    for ( ; idx < m_IntervalList.Count && interval.Contains(m_IntervalList[idx]); ++idx)
                    {
                    }
                }

                // 5
                if (idx < m_IntervalList.Count &&
                    m_IntervalList[idx].Min >= interval.Min &&
                    m_IntervalList[idx].Max > interval.Max)
                {
                    result.m_IntervalList.Add(m_IntervalList[idx].Difference(interval));
                    ++idx;
                }

                // 1
                for ( ; idx < m_IntervalList.Count; ++idx)
                {
                    result.m_IntervalList.Add(m_IntervalList[idx]);
                }

                result.CheckSimple();
            }

            return(result);
        }
Beispiel #15
0
        public IntDomain2 Union(IntDomain2 domain)
        {
            if (ReferenceEquals(domain, this))
            {
                return(this);
            }

            if (domain.IsEmpty())
            {
                return(this);
            }

            if (IsEmpty())
            {
                return(domain);
            }

            if (domain.IsSimple())
            {
                return(Union(domain.m_Interval));
            }

            if (IsSimple())
            {
                if (m_Interval.Contains(domain.m_Interval))
                {
                    return(this);
                }

                return(domain.Union(m_Interval));
            }
            else
            {
                IntDomain2 result = new IntDomain2();
                result.m_Interval     = m_Interval.Union(domain.m_Interval);
                result.m_IntervalList = new List <IntInterval>(m_IntervalList.Count + domain.m_IntervalList.Count);

                // 1 : completely before
                if (domain.m_Interval.Max < m_Interval.Min - 1)
                {
                    result.m_IntervalList.AddRange(domain.m_IntervalList);
                    result.m_IntervalList.AddRange(m_IntervalList);
                }

                // 6 : completely after
                else if (domain.m_Interval.Min > m_Interval.Max + 1)
                {
                    result.m_IntervalList.AddRange(m_IntervalList);
                    result.m_IntervalList.AddRange(domain.m_IntervalList);
                }
                else
                {
                    int  idx    = 0;
                    int  domIdx = 0;
                    bool equal  = true;

                    while (idx < m_IntervalList.Count ||
                           domIdx < domain.m_IntervalList.Count)
                    {
                        // 6 :
                        if (idx == m_IntervalList.Count)
                        {
                            equal = false;

                            for ( ; domIdx < domain.m_IntervalList.Count; ++domIdx)
                            {
                                result.m_IntervalList.Add(domain.m_IntervalList[domIdx]);
                            }
                        }

                        // 1 : remaining intervals after
                        else if (domIdx == domain.m_IntervalList.Count)
                        {
                            for ( ; idx < m_IntervalList.Count; ++idx)
                            {
                                result.m_IntervalList.Add(m_IntervalList[idx]);
                            }
                        }
                        else
                        {
                            IntInterval intv    = m_IntervalList[idx];
                            IntInterval domIntv = domain.m_IntervalList[domIdx];

                            // 1 : completely before
                            if (domIntv.Max < intv.Min - 1)
                            {
                                equal = false;

                                result.m_IntervalList.Add(domIntv);
                                ++domIdx;
                            }
                            // 6 : completely after
                            else if (domIntv.Min > intv.Max + 1)
                            {
                                result.m_IntervalList.Add(intv);
                                ++idx;
                            }
                            // 3
                            else if (domIntv.Min < intv.Min && domIntv.Max > intv.Max)
                            {
                                equal = false;

                                ++idx;
                            }
                            // 4
                            else if (domIntv.Min >= intv.Min && domIntv.Max <= intv.Max)
                            {
                                ++domIdx;
                            }
                            // 2, 5
                            else
                            {
                                equal = false;

                                IntInterval intvTmp = intv.Union(domIntv);

                                ++idx;

                                // contains...
                                for ( ; idx < m_IntervalList.Count &&
                                      intvTmp.Contains(m_IntervalList[idx]);
                                      ++idx)
                                {
                                }
                                ;

                                // adjacent | intersect...
                                while (idx < m_IntervalList.Count &&
                                       IntersectsWithOrIsAdjacent(m_IntervalList[idx], intvTmp))
                                {
                                    intvTmp = intvTmp.Union(m_IntervalList[idx]);
                                    ++idx;
                                }

                                result.m_IntervalList.Add(intvTmp);

                                ++domIdx;
                            }
                        }
                    }

                    if (equal)
                    {
                        return(this);
                    }


                    result.CheckSimple();
                }

                return(result);
            }
        }
Beispiel #16
0
        public IntDomain2 Union(IntInterval interval)
        {
            if (interval.IsEmpty())
            {
                return(this);
            }

            if (IsEmpty())
            {
                return(new IntDomain2(interval));
            }

            // ~4
            if (Contains(interval))
            {
                return(this);
            }

            // 3
            if (interval.Contains(m_Interval))
            {
                return(new IntDomain2(interval));
            }

            if (IsSimple())
            {
                // 1
                if (interval.Max < m_Interval.Min - 1)
                {
                    return(new IntDomain2(interval, m_Interval));
                }

                // 6
                if (interval.Min > m_Interval.Max + 1)
                {
                    return(new IntDomain2(m_Interval, interval));
                }

                // 2, 5
                return(new IntDomain2(m_Interval.Union(interval)));
            }
            else
            {
                IntDomain2 result = new IntDomain2();
                result.m_Interval     = m_Interval.Union(interval);
                result.m_IntervalList = new List <IntInterval>(m_IntervalList.Count + 1);

                // 1
                if (interval.Max < m_Interval.Min - 1)
                {
                    result.m_IntervalList.Add(interval);
                    result.m_IntervalList.AddRange(m_IntervalList);
                }

                // 6
                else if (interval.Min > m_Interval.Max + 1)
                {
                    result.m_IntervalList.AddRange(m_IntervalList);
                    result.m_IntervalList.Add(interval);
                }
                else
                {
                    // 6
                    int idx = 0;
                    for ( ; idx < m_IntervalList.Count && m_IntervalList[idx].Max < interval.Min - 1; ++idx)
                    {
                        result.m_IntervalList.Add(m_IntervalList[idx]);
                    }

                    if (idx < m_IntervalList.Count)
                    {
                        IntInterval intv = interval;

                        // adjacent | intersect
                        if (idx < m_IntervalList.Count &&
                            IntersectsWithOrIsAdjacent(m_IntervalList[idx], intv))
                        {
                            intv = intv.Union(m_IntervalList[idx]);
                            ++idx;
                        }

                        // 3
                        for ( ; idx < m_IntervalList.Count && intv.Contains(m_IntervalList[idx]); ++idx)
                        {
                        }

                        // adjacent | intersect
                        if (idx < m_IntervalList.Count &&
                            IntersectsWithOrIsAdjacent(m_IntervalList[idx], intv))
                        {
                            intv = intv.Union(m_IntervalList[idx]);
                            ++idx;
                        }

                        result.m_IntervalList.Add(intv);

                        // 1
                        for ( ; idx < m_IntervalList.Count; ++idx)
                        {
                            result.m_IntervalList.Add(m_IntervalList[idx]);
                        }
                    }
                    else
                    {
                        // 6
                        result.m_IntervalList.Add(interval);
                    }
                }

                result.CheckSimple();

                return(result);
            }
        }
Beispiel #17
0
 public SimpleIntervalEnumerator(IntDomain2 domain)
 {
     m_MoveNext = true;
     m_Domain   = domain;
 }