Hello.

That's a good idea but you will have to explain what you mean by infinite
sets.

An easy task is to produce something for the reunions of intervals which can
contain {a} = [a, a].

I've made an incomplete code so as to work with intervals (I'm not sure that
all the classes work well). Feel free to correct it, and adapt and port it
to sympy.

Christophe BAL

=== My code - START ===

#!/usr/bin/env python
#coding=utf-8

# Code writing by BAL Christophe
# Mail : [email protected]

def endPointsToUser(europeanEndpoints, notation):
# Lines automatically built by tool_simpleSets.py. ===== START
    epEuropean_2_User = {}

# AM-erican notations.
    epEuropean_2_User['am'] = {']]': '(]', '[[': '[)', '[]': '[]', '][':
'()'}
# CZ-ech notations.
    epEuropean_2_User['cz'] = {']]': '(>', '[[': '<)', '[]': '<>', '][':
'()'}
# EU-ropean notations.
    epEuropean_2_User['eu'] = {'[[': '[[', ']]': ']]', '][': '][', '[]':
'[]'}
# Lines automatically built by tool_simpleSets.py. ===== END

    return epEuropean_2_User[notation][europeanEndpoints]


class Interval():
    """

    """
    def __init__(self, minPoint=0, maxPoint=0, endpoints='', notation =
'am'):
# Lines automatically built by tool_simpleSets.py. ===== START
        epNotationIsValid = {}
        epUser_2_European = {}

# AM-erican notations.
        epNotationIsValid['am'] = ['[]', '(]', '[)', '()']
        epUser_2_European['am'] = [{'(': ']', '[': '['}, {')': '[', ']':
']'}]
# CZ-ech notations.
        epNotationIsValid['cz'] = ['<>', '(>', '<)', '()']
        epUser_2_European['cz'] = [{'(': ']', '<': '['}, {')': '[', '>':
']'}]
# EU-ropean notations.
        epNotationIsValid['eu'] = ['[]', ']]', '[[', '][']
        epUser_2_European['eu'] = [{'[': '[', ']': ']'}, {'[': '[', ']':
']'}]
# Lines automatically built by tool_simpleSets.py. ===== END

        self.notation = notation

# An empty set ?
        if endpoints == '':
            minPoint = 0
            minPoint = 0
            endpoints = endPointsToUser('][', self.notation)

        if minPoint=='+inf':
            raise TypeError('The first value ' + str(minPoint) + ' is not
lower or equal to the second one ' + str(maxPoint) + '.')

        elif maxPoint=='-inf':
            raise TypeError('The first value ' + str(minPoint) + ' is not
lower or equal to the second one ' + str(maxPoint) + '.')

        elif minPoint != '-inf' and maxPoint != '+inf':
            if minPoint > maxPoint:
                raise TypeError('The first value ' + str(minPoint) + ' is
not lower or equal to the second one ' + str(maxPoint) + '.')

        self.minPoint = minPoint
        self.maxPoint = maxPoint
        self.endpoints = endpoints

        if self.endpoints not in epNotationIsValid[self.notation]:
            raise TypeError('Unknown endpoints of interval : "' +
str(endpoints) + '"')

# In the code we are gonning to work with the european notations.
        if self.notation == 'eu':
            self.europeanEndpoints = self.endpoints
        else:
            self.europeanEndpoints =
epUser_2_European[self.notation][0][self.endpoints[0]] +
epUser_2_European[self.notation][1][self.endpoints[1]]

#        print 'self.notation = ' + self.notation
#        print 'self.endpoints = ' + self.endpoints
#        print 'self.europeanEndpoints = ' + self.europeanEndpoints

    def __str__(self):
        if self.minPoint == self.maxPoint:
            if self.europeanEndpoints == '[]':
                return '{' + str(self.minPoint) + '}'
            else:
                return 'Empty Set'

        return self.endpoints[0] + str(self.minPoint) + ';' +
str(self.maxPoint) + self.endpoints[1]

# Thanks to Nicolas we explain me this trick.
    @property
    def isEmpty(self):
        return str(self) == 'Empty Set'

    def __and__(self, otherInterval):
# We reimplement the use of  & .

# The intersection is empty.
        if self.isEmpty or otherInterval.isEmpty:
            return Interval()

        maxOfminPoints = max(self.minPoint, otherInterval.minPoint)
        minOfmaxPoints = min(self.maxPoint, otherInterval.maxPoint)

        if maxOfminPoints > minOfmaxPoints:
            return Interval()

# The intersection could be a set with a single element.
        if minOfmaxPoints == maxOfminPoints:
            if self.maxPoint == minOfmaxPoints:
                if self.europeanEndpoints[1] == '[' or
otherInterval.europeanEndpoints[0] ==']':
                    return Interval()
                else:
                    return Interval(minOfmaxPoints, minOfmaxPoints,
endPointsToUser('[]', self.notation), self.notation)

            else:
                if self.europeanEndpoints[0] == ']' or
otherInterval.europeanEndpoints[1] =='[':
                    return Interval()
                else:
                    return Interval(minOfmaxPoints, minOfmaxPoints,
endPointsToUser('[]', self.notation), self.notation)

# What is the endpoints of the intersection ?
        interEndPtMin = '['

        if self.minPoint == maxOfminPoints :
            interEndPtMin = self.europeanEndpoints[0]

        if otherInterval.minPoint == maxOfminPoints and interEndPtMin ==
'[':
            interEndPtMin = otherInterval.europeanEndpoints[0]

        interEndPtMax = ']'

        if self.maxPoint == minOfmaxPoints :
            interEndPtMax = self.europeanEndpoints[1]

        if otherInterval.maxPoint == minOfmaxPoints and interEndPtMax ==
']':
            interEndPtMax = otherInterval.europeanEndpoints[1]

#        print 'interEndPtMin + interEndPtMax'
#        print interEndPtMin + interEndPtMax
#        print endPointsToUser(interEndPtMin + interEndPtMax, self.notation)
        return Interval(maxOfminPoints, minOfmaxPoints,
endPointsToUser(interEndPtMin + interEndPtMax, self.notation),
self.notation)

    def __or__(self, otherSet):
# We reimplement the use of or.
        if self.isEmpty :
            return otherSet

        if isinstance(otherSet, Interval):
#            print UnionIntervals([self, otherSet]).simplify()
            return UnionIntervals([self, otherSet]).simplify()
        else:
#            print otherSet
#            print isinstance(otherSet[0], UnionIntervals)
            return UnionIntervals([self] +
otherSet.shorListIntervals).simplify()


    def __mul__(self, realNumber):
        """
        I*k ok mais pas k*I : il faudrait réimplémenter les multiplications
des réels,...
        """
# We reimplement the use of or.
        if isinstance(realNumber, int):
            if realNumber < 0:
                if self.europeanEndpoints[1]=='[':
                    newEndpoints = ']'
                else:
                    newEndpoints = '['
                if self.europeanEndpoints[0]==']':
                    newEndpoints += '['
                else:
                    newEndpoints += ']'

                return Interval(realNumber*self.maxPoint,
realNumber*self.minPoint, endPointsToUser(newEndpoints, self.notation),
self.notation)
            else:
                return Interval(realNumber*self.minPoint,
realNumber*self.maxPoint, self.endpoints, self.notation)
        else:
            raise Exception('You can multiply an interval only by an
interger')

    def __rmul__(self, realNumber):
        """ I*k ok mais pas k*I : il faudrait réimplémenter les
multiplications des réels,...
        """
# We reimplement the use of or.
        return self*realNumber



    def __add__(self, otherSet):
# We reimplement the use of or.
        if isinstance(otherSet, Interval):
            if self.isEmpty or otherSet.isEmpty:
                return Interval()

            if self.minPoint == '-inf' or otherSet.minPoint == '-inf' :
                minAddIntervals = '-inf'
                endpointsAddIntervals = ']'
            else:
                minAddIntervals = self.minPoint + otherSet.minPoint
                if self.europeanEndpoints[0] == ']' or
otherSet.europeanEndpoints[0] == ']':
                    endpointsAddIntervals = ']'
                else:
                    endpointsAddIntervals = '['

            if self.maxPoint == '+inf' or otherSet.maxPoint == '+inf' :
                maxAddIntervals = '+inf'
                endpointsAddIntervals += '['
            else:
                maxAddIntervals = self.maxPoint + otherSet.maxPoint
                if self.europeanEndpoints[1] == '[' or
otherSet.europeanEndpoints[1] == '[':
                    endpointsAddIntervals += '['
                else:
                    endpointsAddIntervals += ']'


            return Interval(minAddIntervals, maxAddIntervals,
endPointsToUser(endpointsAddIntervals, self.notation), self.notation)
        else:
            disjointUnion = otherSet.simplify()
            listAdditionOneByOne = []
            for i in range(len(disjointUnion.listIntervals)):
                listAdditionOneByOne.append(self +
disjointUnion.listIntervals[i])
            return UnionIntervals(listAdditionOneByOne).simplify()

    def __contains__(self, x):
        if self.isEmpty:
            return False

        if x == self.minPoint:
            return self.europeanEndpoints[0] =='['

        if x == self.maxPoint:
            return self.europeanEndpoints[1] ==']'

        if str(self.minPoint) == '-inf':
            return x < self.maxPoint
        elif str(self.maxPoint) == 'inf':
            return x > self.minPoint
        else:
            return self.minPoint < x < self.maxPoint


class UnionIntervals():
    def __init__(self, listIntervals):
        if listIntervals == []:
            self.listIntervals = [Interval(0, 0, '')]
        else:
            self.listIntervals = listIntervals

        self.shortListIntervals = None
# The first notation will be used for the simplified union.
        self.notation = self.listIntervals[0].notation

# Thanks to Nicolas we explain me this trick.
    @property
    def isEmpty(self):
        if self.shortListIntervals == None:
            self.simplify()
        return (len(self.shortListIntervals) == 1) and
(str(self.shortListIntervals[0])=='Empty Set')


    def __str__(self):
        if len(self.listIntervals)==1:
            return str(self.listIntervals[0])

        t = str(self.listIntervals[0])
        for i in range(1, len(self.listIntervals)):
            t += ' u ' + str(self.listIntervals[i])

        return t

    def __add__(self, otherSet):
# We reimplement the use of or.
        if isinstance(otherSet, Interval):
            return otherSet + self

        else:
            if self.shortListIntervals==None:
                listCurrentSet= self.simplify().listIntervals
            else:
                listCurrentSet= self.shortListIntervals

            listOtherSet = otherSet.simplify().listIntervals

            listAdditionOneByOne = []
            for i in range(len(listCurrentSet)):
                for j in range(len(listOtherSet)):
                    listAdditionOneByOne.append(listCurrentSet[i] +
listOtherSet[j])

            return UnionIntervals(listAdditionOneByOne).simplify()

    def __mul__(self, realNumber):
        """ Union*k ok mais pas k*Union : il faudrait réimplémenter les
multiplications des réels,...
        """
# We reimplement the use of or.
        listProductOneByOne = []
        for i in range(len(self.listIntervals)):
            listProductOneByOne.append(self.listIntervals[i] * realNumber)

        return UnionIntervals(listProductOneByOne).simplify()

    def __or__(self, otherSet):
# We reimplement the use of +.
        if self.isEmpty :
            return otherSet

        if isinstance(otherSet, Interval):
            newUnion = UnionIntervals(self.listIntervals + [otherSet])
        else:
            newUnion = UnionIntervals(self.listIntervals +
otherSet.listIntervals)

        return newUnion.simplify()


    def __unionOfTwo(self, interval_1, interval_2):
        """
        intervalle ranbgés
        """

        if not (interval_1 & interval_2).isEmpty :
            minPoint = min(interval_1.minPoint, interval_2.minPoint)
            maxPoint = max(interval_1.maxPoint, interval_2.maxPoint)

            if minPoint == interval_1.minPoint:
                if minPoint == interval_2.minPoint:
                    if interval_1.europeanEndpoints[0]==']' and
interval_2.europeanEndpoints[0]==']':
                        europeanEndpoints = ']'
                    else:
                        europeanEndpoints = '['
                else:
                    europeanEndpoints = interval_1.europeanEndpoints[0]
            else:
                europeanEndpoints = interval_2.europeanEndpoints[0]

            if maxPoint == interval_1.maxPoint:
                if maxPoint == interval_2.maxPoint:
                    if interval_1.europeanEndpoints[1]=='[' and
interval_2.europeanEndpoints[1]=='[':
                        europeanEndpoints += '['
                    else:
                        europeanEndpoints += ']'
                else:
                    europeanEndpoints += interval_1.europeanEndpoints[1]
            else:
                europeanEndpoints += interval_2.europeanEndpoints[1]

            return Interval(minPoint, maxPoint,
endPointsToUser(europeanEndpoints, self.notation), self.notation)

        if interval_1.maxPoint == interval_2.minPoint and
(interval_1.europeanEndpoints[1]==']' or
interval_2.europeanEndpoints[0]=='['):
            return Interval(interval_1.minPoint, interval_2.maxPoint,
endPointsToUser(interval_1.europeanEndpoints[0] +
interval_2.europeanEndpoints[1], self.notation), self.notation)

        return None

    def simplify(self):
        if self.shortListIntervals != None :
            return self.shortListIntervals

# We only keep non-empty intervals.
        self.shortListIntervals = []
        for i in range(len(self.listIntervals)):
            if self.listIntervals[i].isEmpty == False:
                self.shortListIntervals.append(self.listIntervals[i])

        if self.shortListIntervals == []:
            return UnionIntervals([Interval()])

        if len(self.shortListIntervals) == 1:
            return UnionIntervals(self.shortListIntervals)

# We start by sorting the intervals regarding to their minPoint value.
        self.shortListIntervals.sort(key=lambda x: x.minPoint)

# We can start the simplification.
        i = 0
        while (i < len(self.shortListIntervals)-1):
            newUnion = self.__unionOfTwo(self.shortListIntervals[i],
self.shortListIntervals[i+1])
            if newUnion==None:
                i+=1
            else:
                self.shortListIntervals.pop(i)
                self.shortListIntervals[i] = newUnion

        return UnionIntervals(self.shortListIntervals)


class IntersectionIntervals():
    def __init__(self, listIntervals):
        if listIntervals == []:
            self.listIntervals = [Interval(0, 0, '')]
        else:
            self.listIntervals = listIntervals

        self.finalIntersection = None
# The first notation will be used for the simplified union.
        self.notation = self.listIntervals[0].notation

    def __str__(self):
        if len(self.listIntervals)==1:
            return str(self.listIntervals[0])

        t = str(self.listIntervals[0])
        for i in range(1, len(self.listIntervals)):
            t += ' n ' + str(self.listIntervals[i])

        return t

    def simplify(self):
        if self.finalIntersection!=None:
            return self.finalIntersection

        if len(self.listIntervals) == 1:
            self.finalIntersection = self.listIntervals[0]
            return self.finalIntersection

        self.finalIntersection = self.listIntervals[0]

        for i in range(1, len(self.listIntervals)):
            if self.finalIntersection.isEmpty:
                break
            self.finalIntersection = self.finalIntersection &
self.listIntervals[i]

        return self.finalIntersection

class MixingIntervals():
    """
    """
    def __init__(self, strIntervalsMixed, notation = 'am'):
        self.strIntervalsMixed = strIntervalsMixed
        self.notation = notation
        self.minimalUnion = None

    def __str__(self):
        return self.strIntervalsMixed

    def simplify(self):
        """
        (-5;3)  n  ([-4;3]  u  (-2;7])  n  ([-3;13] u {24})
        """
        if self.minimalUnion != None:
            return self.minimalUnion

        piecesOfUnions = self.strIntervalsMixed.split('u')
        listIntervalsUnion = []

        for i in range(len(piecesOfUnions)):
#            print
#            print 'piecesOfIntersections'
            piecesOfIntersections = piecesOfUnions[i].split('n')
            listIntervalsIntersection = []

            for j in range(len(piecesOfIntersections)):
                oneInterval = piecesOfIntersections[j].strip()
                endpoints = oneInterval[0] + oneInterval[-1]
                if endpoints=='{}':
                    endpoints='[]'
                    minMax = [oneInterval[1:-1], oneInterval[1:-1]]
                else:
                    minMax = oneInterval[1:-1].split(';')
#                print 'Interval(minMax[0], minMax[1], endpoints,
self.notation)'
#                print Interval(minMax[0], minMax[1], endpoints,
self.notation)
                listIntervalsIntersection.append(Interval(int(minMax[0]),
int(minMax[1]), endpoints, self.notation))
#            print
'IntersectionIntervals(listIntervalsIntersection).simplify()'
#            print
IntersectionIntervals(listIntervalsIntersection).simplify()

listIntervalsUnion.append(IntersectionIntervals(listIntervalsIntersection).simplify())

#        print 'listIntervalsUnion'
        for i in range(len(listIntervalsUnion)):
            print(listIntervalsUnion[i])

        return UnionIntervals(listIntervalsUnion).simplify()

# Some special intervals.
empty = Interval()
R = Interval('-inf','+inf','()')
Rpos = Interval('0','+inf','[)')
RposStrict = Interval('0','+inf','()')
Rneg = Interval('-inf','0','(]')
RnegStrict = Interval('-inf','0','()')
Rstar = RnegStrict or RposStrict

==== My code - END ====

2011/3/18 SherjilOzair <[email protected]>

> The Set class of sympy is not complete.
> I plan to add a full FiniteSet class functionality which will inherit
> the Set class, we can also have an InfiniteSet abstract class later
> which Interval and Union can inherit.
>
> A FiniteSet would behave something like this,
>
> a=Set([1,2,3,4,5])
> b=Set([4,5,6,7])
> c=a+b // or c=a.union(b)
> print c
> [1,2,3,4,5,6]
>
> and similar behavior for intersection, complement, contains
> functions.
> Feel free to suggest me more features.
>
> With a good polys class, we can also add conversion from set-builder
> notation to list notation.
>
> I ask more experienced developers to tell me if there is any design
> flaw in this.
> I need the go-ahead to start coding this class.
>
> Thanks,
> Sherjil
>
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/sympy?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to