return self._dimension
def disjoint(self):
+ """
+ Returns this set as disjoint.
+ """
islset = self._toislset(self.polyhedra, self.symbols)
islset = libisl.isl_set_make_disjoint(mainctx, islset)
return self._fromislset(islset, self.symbols)
def isempty(self):
+ """
+ Returns true if this set is an Empty set.
+ """
islset = self._toislset(self.polyhedra, self.symbols)
empty = bool(libisl.isl_set_is_empty(islset))
libisl.isl_set_free(islset)
return not self.isempty()
def isuniverse(self):
+ """
+ Returns true if this set is the Universe set.
+ """
islset = self._toislset(self.polyhedra, self.symbols)
universe = bool(libisl.isl_set_plain_is_universe(islset))
libisl.isl_set_free(islset)
return universe
def isbounded(self):
+ """
+ Returns true if this set is bounded.
+ """
islset = self._toislset(self.polyhedra, self.symbols)
bounded = bool(libisl.isl_set_is_bounded(islset))
libisl.isl_set_free(islset)
return bounded
def __eq__(self, other):
+ """
+ Returns true if two sets are equal.
+ """
symbols = self._xsymbols([self, other])
islset1 = self._toislset(self.polyhedra, symbols)
islset2 = other._toislset(other.polyhedra, symbols)
return equal
def isdisjoint(self, other):
+ """
+ Return True if two sets have a null intersection.
+ """
symbols = self._xsymbols([self, other])
islset1 = self._toislset(self.polyhedra, symbols)
islset2 = self._toislset(other.polyhedra, symbols)
return equal
def issubset(self, other):
+ """
+ Report whether another set contains this set.
+ """
symbols = self._xsymbols([self, other])
islset1 = self._toislset(self.polyhedra, symbols)
islset2 = self._toislset(other.polyhedra, symbols)
return equal
def __le__(self, other):
+ """
+ Returns true if this set is less than or equal to another set.
+ """
return self.issubset(other)
def __lt__(self, other):
+ """
+ Returns true if this set is less than another set.
+ """
symbols = self._xsymbols([self, other])
islset1 = self._toislset(self.polyhedra, symbols)
islset2 = self._toislset(other.polyhedra, symbols)
return equal
def complement(self):
+ """
+ Returns the complement of this set.
+ """
islset = self._toislset(self.polyhedra, self.symbols)
islset = libisl.isl_set_complement(islset)
return self._fromislset(islset, self.symbols)
def __invert__(self):
+ """
+ Returns the complement of this set.
+ """
return self.complement()
def simplify(self):
- #does not change anything in any of the examples
- #isl seems to do this naturally
+ """
+ Returns a set without redundant constraints.
+ """
islset = self._toislset(self.polyhedra, self.symbols)
islset = libisl.isl_set_remove_redundancies(islset)
return self._fromislset(islset, self.symbols)
def aspolyhedron(self):
- # several types of hull are available
- # polyhedral seems to be the more appropriate, to be checked
+ """
+ Returns polyhedral hull of set.
+ """
from .polyhedra import Polyhedron
islset = self._toislset(self.polyhedra, self.symbols)
islbset = libisl.isl_set_polyhedral_hull(islset)
return self
def project(self, dims):
- # use to remove certain variables
+ """
+ Return new set with given dimensions removed.
+ """
islset = self._toislset(self.polyhedra, self.symbols)
n = 0
for index, symbol in reversed(list(enumerate(self.symbols))):
return Domain._fromislset(islset, dims)
def sample(self):
+ """
+ Returns a single subset of the input.
+ """
islset = self._toislset(self.polyhedra, self.symbols)
islpoint = libisl.isl_set_sample_point(islset)
if bool(libisl.isl_point_is_void(islpoint)):
return point
def intersection(self, *others):
+ """
+ Return the intersection of two sets as a new set.
+ """
if len(others) == 0:
return self
symbols = self._xsymbols((self,) + others)
return self._fromislset(islset1, symbols)
def __and__(self, other):
+ """
+ Return the intersection of two sets as a new set.
+ """
return self.intersection(other)
def union(self, *others):
+ """
+ Return the union of sets as a new set.
+ """
if len(others) == 0:
return self
symbols = self._xsymbols((self,) + others)
return self._fromislset(islset1, symbols)
def __or__(self, other):
+ """
+ Return a new set with elements from both sets.
+ """
return self.union(other)
def __add__(self, other):
+ """
+ Return new set containing all elements in both sets.
+ """
return self.union(other)
def difference(self, other):
+ """
+ Return the difference of two sets as a new set.
+ """
symbols = self._xsymbols([self, other])
islset1 = self._toislset(self.polyhedra, symbols)
islset2 = other._toislset(other.polyhedra, symbols)
return self._fromislset(islset, symbols)
def __sub__(self, other):
+ """
+ Return the difference of two sets as a new set.
+ """
return self.difference(other)
def lexmin(self):
+ """
+ Return a new set containing the lexicographic minimum of the elements in the set.
+ """
islset = self._toislset(self.polyhedra, self.symbols)
islset = libisl.isl_set_lexmin(islset)
return self._fromislset(islset, self.symbols)
def lexmax(self):
+ """
+ Return a new set containing the lexicographic maximum of the elements in the set.
+ """
islset = self._toislset(self.polyhedra, self.symbols)
islset = libisl.isl_set_lexmax(islset)
return self._fromislset(islset, self.symbols)
def num_parameters(self):
- #could be useful with large, complicated polyhedrons
+ """
+ Return the total number of parameters, input, output or set dimensions.
+ """
islbset = self._toislbasicset(self.equalities, self.inequalities, self.symbols)
num = libisl.isl_basic_set_dim(islbset, libisl.isl_dim_set)
return num
def involves_dims(self, dims):
- #could be useful with large, complicated polyhedrons
+ """
+ Returns true if set depends on given dimensions.
+ """
islset = self._toislset(self.polyhedra, self.symbols)
dims = sorted(dims)
symbols = sorted(list(self.symbols))
_RE_COORDINATE = re.compile(r'\((?P<num>\-?\d+)\)(/(?P<den>\d+))?')
def vertices(self):
- #returning list of verticies
+ """
+ Return a list of vertices for this Polygon.
+ """
from .polyhedra import Polyhedron
+ if not self.isbounded():
+ raise ValueError('domain must be bounded')
islbset = self._toislbasicset(self.equalities, self.inequalities, self.symbols)
vertices = libisl.isl_basic_set_compute_vertices(islbset);
vertices = islhelper.isl_vertices_vertices(vertices)
coordinate = -Fraction(constant, coefficient)
coordinates.append((symbol, coordinate))
else:
+
# horrible hack, find a cleaner solution
string = islhelper.isl_multi_aff_to_str(expr)
matches = self._RE_COORDINATE.finditer(string)
return points
def points(self):
+ """
+ Returns the points contained in the set.
+ """
if not self.isbounded():
raise ValueError('domain must be bounded')
from .polyhedra import Universe, Eq
def And(*domains):
+ """
+ Return the intersection of two sets as a new set.
+ """
if len(domains) == 0:
from .polyhedra import Universe
return Universe
return domains[0].intersection(*domains[1:])
def Or(*domains):
+ """
+ Return the union of sets as a new set.
+ """
if len(domains) == 0:
from .polyhedra import Empty
return Empty
return domains[0].union(*domains[1:])
def Not(domain):
+ """
+ Returns the complement of this set.
+ """
return ~domain
return self,
def disjoint(self):
+ """
+ Return this set as disjoint.
+ """
return self
def isuniverse(self):
+ """
+ Return true if this set is the Universe set.
+ """
islbset = self._toislbasicset(self.equalities, self.inequalities,
self.symbols)
universe = bool(libisl.isl_basic_set_is_universe(islbset))
return universe
def aspolyhedron(self):
+ """
+ Return polyhedral hull of this set.
+ """
return self
def __contains__(self, point):
for m in points[1:]:
om = Vector(o, m)
normprod = norm_oa * om.norm()
- cosinus = oa.dot(om) / normprod
+ cosinus = max(oa.dot(om) / normprod, -1.)
sinus = u.dot(oa.cross(om)) / normprod
angle = math.acos(cosinus)
angle = math.copysign(angle, sinus)
return faces
def plot(self):
+ """
+ Display 3D plot of set.
+ """
import matplotlib.pyplot as plt
- from matplotlib.path import Path
import matplotlib.patches as patches
if len(self.symbols)> 3:
raise TypeError
elif len(self.symbols) == 2:
- verts = self.vertices()
- points = []
- codes = [Path.MOVETO]
- for vert in verts:
- pairs = ()
- for sym in sorted(vert, key=Symbol.sortkey):
- num = vert.get(sym)
- pairs = pairs + (num,)
- points.append(pairs)
- points.append((0.0, 0.0))
- num = len(points)
- while num > 2:
- codes.append(Path.LINETO)
- num = num - 1
- else:
- codes.append(Path.CLOSEPOLY)
- path = Path(points, codes)
- fig = plt.figure()
- ax = fig.add_subplot(111)
- patch = patches.PathPatch(path, facecolor='blue', lw=2)
- ax.add_patch(patch)
- ax.set_xlim(-5,5)
- ax.set_ylim(-5,5)
- plt.show()
+ import pylab
+ points = []
+ for verts in self.vertices():
+ pairs=()
+ for coordinate, point in verts.coordinates():
+ pairs = pairs + (float(point),)
+ points.append(pairs)
+ cent=(sum([p[0] for p in points])/len(points),sum([p[1] for p in points])/len(points))
+ points.sort(key=lambda p: math.atan2(p[1]-cent[1],p[0]-cent[0]))
+ pylab.scatter([p[0] for p in points],[p[1] for p in points])
+ pylab.gca().add_patch(patches.Polygon(points,closed=True,fill=True))
+ pylab.grid()
+ pylab.show()
elif len(self.symbols)==3:
- return 0
-
+ from mpl_toolkits.mplot3d import Axes3D
+ from mpl_toolkits.mplot3d.art3d import Poly3DCollection
+ faces = self.faces()
+ fig = plt.figure()
+ ax = Axes3D(fig)
+ for face in faces:
+ points = []
+ vertices = Polyhedron._sort_polygon_3d(face)
+ for verts in vertices:
+ pairs=()
+ for coordinate, point in verts.coordinates():
+ pairs = pairs + (float(point),)
+ points.append(pairs)
+ collection = Poly3DCollection([points], alpha=0.7)
+ face_color = [0.5, 0.5, 1] # alternative: matplotlib.colors.rgb2hex([0.5, 0.5, 1])
+ collection.set_facecolor(face_color)
+ ax.add_collection3d(collection)
+ ax.set_xlabel('X')
+ ax.set_xlim(0, 5)
+ ax.set_ylabel('Y')
+ ax.set_ylim(0, 5)
+ ax.set_zlabel('Z')
+ ax.set_zlim(0, 5)
+ plt.grid()
+ plt.show()
return points
-
+
+ @classmethod
+ def limit(cls, faces, variable, lim):
+ sym = []
+ if variable is 'x':
+ n = 0
+ elif variable is 'y':
+ n = 1
+ elif variable is 'z':
+ n = 2
+ for face in faces:
+ for vert in face:
+ coordinates = vert.coordinates()
+ for point in enumerate(coordinates):
+ coordinates.get(n)
+ sym.append(points)
+ if lim == 0:
+ value = min(sym)
+ else:
+ value = max(sym)
+ return value
def _polymorphic(func):
@functools.wraps(func)
@_polymorphic
def Lt(left, right):
+ """
+ Return true if the first set is less than the second.
+ """
return Polyhedron([], [right - left - 1])
@_polymorphic
def Le(left, right):
+ """
+ Return true the first set is less than or equal to the second.
+ """
return Polyhedron([], [right - left])
@_polymorphic
def Eq(left, right):
+ """
+ Return true if the sets are equal.
+ """
return Polyhedron([left - right], [])
@_polymorphic
def Ne(left, right):
+ """
+ Return true if the sets are NOT equal.
+ """
return ~Eq(left, right)
@_polymorphic
def Gt(left, right):
+ """
+ Return true if the first set is greater than the second set.
+ """
return Polyhedron([], [left - right - 1])
@_polymorphic
def Ge(left, right):
+ """
+ Return true if the first set is greater than or equal the second set.
+ """
return Polyhedron([], [left - right])