Rename coordinates.py into geometry.py
authorVivien Maisonneuve <v.maisonneuve@gmail.com>
Fri, 11 Jul 2014 17:48:04 +0000 (19:48 +0200)
committerVivien Maisonneuve <v.maisonneuve@gmail.com>
Fri, 11 Jul 2014 17:49:28 +0000 (19:49 +0200)
pypol/__init__.py
pypol/coordinates.py [deleted file]
pypol/domains.py
pypol/geometry.py
pypol/polyhedra.py
pypol/tests/test_geometry.py [moved from pypol/tests/test_coordinates.py with 99% similarity]

index be1440b..166ccf4 100644 (file)
@@ -2,8 +2,8 @@
 A polyhedral library based on ISL.
 """
 
 A polyhedral library based on ISL.
 """
 
+from .geometry import Point, Vector
 from .linexprs import Expression, Symbol, Dummy, symbols, Rational
 from .linexprs import Expression, Symbol, Dummy, symbols, Rational
-from .coordinates import Point, Vector
 from .polyhedra import Polyhedron, Eq, Ne, Le, Lt, Ge, Gt, Ne, Empty, Universe
 from .domains import Domain, And, Or, Not
 
 from .polyhedra import Polyhedron, Eq, Ne, Le, Lt, Ge, Gt, Ne, Empty, Universe
 from .domains import Domain, And, Or, Not
 
diff --git a/pypol/coordinates.py b/pypol/coordinates.py
deleted file mode 100644 (file)
index ceab418..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-import math
-import numbers
-import operator
-
-from collections import OrderedDict, Mapping
-
-from .geometry import GeometricObject
-from .linexprs import Symbol
-
-
-__all__ = [
-    'Point',
-    'Vector',
-]
-
-
-class Coordinates:
-
-    __slots__ = (
-        '_coordinates',
-    )
-
-    def __new__(cls, coordinates):
-        if isinstance(coordinates, Mapping):
-            coordinates = coordinates.items()
-        self = object().__new__(cls)
-        self._coordinates = OrderedDict()
-        for symbol, coordinate in sorted(coordinates,
-                key=lambda item: item[0].sortkey()):
-            if not isinstance(symbol, Symbol):
-                raise TypeError('symbols must be Symbol instances')
-            if not isinstance(coordinate, numbers.Real):
-                raise TypeError('coordinates must be real numbers')
-            self._coordinates[symbol] = coordinate
-        return self
-
-    @property
-    def symbols(self):
-        return tuple(self._coordinates)
-
-    @property
-    def dimension(self):
-        return len(self.symbols)
-
-    def coordinates(self):
-        yield from self._coordinates.items()
-
-    def coordinate(self, symbol):
-        if not isinstance(symbol, Symbol):
-            raise TypeError('symbol must be a Symbol instance')
-        return self._coordinates[symbol]
-
-    __getitem__ = coordinate
-
-    def __bool__(self):
-        return any(self._coordinates.values())
-
-    def __hash__(self):
-        return hash(tuple(self.coordinates()))
-
-    def __repr__(self):
-        string = ', '.join(['{!r}: {!r}'.format(symbol, coordinate)
-            for symbol, coordinate in self.coordinates()])
-        return '{}({{{}}})'.format(self.__class__.__name__, string)
-
-    def _map(self, func):
-        for symbol, coordinate in self.coordinates():
-            yield symbol, func(coordinate)
-
-    def _iter2(self, other):
-        if self.symbols != other.symbols:
-            raise ValueError('arguments must belong to the same space')
-        coordinates1 = self._coordinates.values()
-        coordinates2 = other._coordinates.values()
-        yield from zip(self.symbols, coordinates1, coordinates2)
-
-    def _map2(self, other, func):
-        for symbol, coordinate1, coordinate2 in self._iter2(other):
-            yield symbol, func(coordinate1, coordinate2)
-
-
-class Point(Coordinates, GeometricObject):
-    """
-    This class represents points in space.
-    """
-
-    def isorigin(self):
-        return not bool(self)
-
-    def __add__(self, other):
-        if not isinstance(other, Vector):
-            return NotImplemented
-        coordinates = self._map2(other, operator.add)
-        return Point(coordinates)
-
-    def __sub__(self, other):
-        coordinates = []
-        if isinstance(other, Point):
-            coordinates = self._map2(other, operator.sub)
-            return Vector(coordinates)
-        elif isinstance(other, Vector):
-            coordinates = self._map2(other, operator.sub)
-            return Point(coordinates)
-        else:
-            return NotImplemented
-
-    def __eq__(self, other):
-        return isinstance(other, Point) and \
-            self._coordinates == other._coordinates
-
-    def aspolyhedron(self):
-        from .polyhedra import Polyhedron
-        equalities = []
-        for symbol, coordinate in self.coordinates():
-            equalities.append(symbol - coordinate)
-        return Polyhedron(equalities)
-
-
-class Vector(Coordinates):
-    """
-    This class represents displacements in space.
-    """
-
-    def __new__(cls, initial, terminal=None):
-        if not isinstance(initial, Point):
-            initial = Point(initial)
-        if terminal is None:
-            coordinates = initial._coordinates
-        elif not isinstance(terminal, Point):
-            terminal = Point(terminal)
-            coordinates = terminal._map2(initial, operator.sub)
-        return super().__new__(cls, coordinates)
-
-    def isnull(self):
-        return not bool(self)
-
-    def __add__(self, other):
-        if isinstance(other, (Point, Vector)):
-            coordinates = self._map2(other, operator.add)
-            return other.__class__(coordinates)
-        return NotImplemented
-
-    def angle(self, other):
-        """
-        Retrieve the angle required to rotate the vector into the vector passed
-        in argument. The result is an angle in radians, ranging between -pi and
-        pi.
-        """
-        if not isinstance(other, Vector):
-            raise TypeError('argument must be a Vector instance')
-        cosinus = self.dot(other) / (self.norm()*other.norm())
-        return math.acos(cosinus)
-
-    def cross(self, other):
-        """
-        Calculate the cross product of two Vector3D structures.
-        """
-        if not isinstance(other, Vector):
-            raise TypeError('other must be a Vector instance')
-        if self.dimension != 3 or other.dimension != 3:
-            raise ValueError('arguments must be three-dimensional vectors')
-        if self.symbols != other.symbols:
-            raise ValueError('arguments must belong to the same space')
-        x, y, z = self.symbols
-        coordinates = []
-        coordinates.append((x, self[y]*other[z] - self[z]*other[y]))
-        coordinates.append((y, self[z]*other[x] - self[x]*other[z]))
-        coordinates.append((z, self[x]*other[y] - self[y]*other[x]))
-        return Vector(coordinates)
-
-    def __truediv__(self, other):
-        """
-        Divide the vector by the specified scalar and returns the result as a
-        vector.
-        """
-        if not isinstance(other, numbers.Real):
-            return NotImplemented
-        coordinates = self._map(lambda coordinate: coordinate / other)
-        return Vector(coordinates)
-
-    def dot(self, other):
-        """
-        Calculate the dot product of two vectors.
-        """
-        if not isinstance(other, Vector):
-            raise TypeError('argument must be a Vector instance')
-        result = 0
-        for symbol, coordinate1, coordinate2 in self._iter2(other):
-            result += coordinate1 * coordinate2
-        return result
-
-    def __eq__(self, other):
-        return isinstance(other, Vector) and \
-            self._coordinates == other._coordinates
-
-    def __hash__(self):
-        return hash(tuple(self.coordinates()))
-
-    def __mul__(self, other):
-        if not isinstance(other, numbers.Real):
-            return NotImplemented
-        coordinates = self._map(lambda coordinate: other * coordinate)
-        return Vector(coordinates)
-
-    __rmul__ = __mul__
-
-    def __neg__(self):
-        coordinates = self._map(operator.neg)
-        return Vector(coordinates)
-
-    def norm(self):
-        return math.sqrt(self.norm2())
-
-    def norm2(self):
-        result = 0
-        for coordinate in self._coordinates.values():
-            result += coordinate ** 2
-        return result
-
-    def asunit(self):
-        return self / self.norm()
-
-    def __sub__(self, other):
-        if isinstance(other, (Point, Vector)):
-            coordinates = self._map2(other, operator.sub)
-            return other.__class__(coordinates)
-        return NotImplemented
index 5d98af8..d80fd91 100644 (file)
@@ -6,8 +6,7 @@ from fractions import Fraction
 
 from . import islhelper
 from .islhelper import mainctx, libisl
 
 from . import islhelper
 from .islhelper import mainctx, libisl
-from .geometry import GeometricObject
-from .coordinates import Point
+from .geometry import GeometricObject, Point
 from .linexprs import Expression, Symbol
 
 
 from .linexprs import Expression, Symbol
 
 
index d0146cf..ce055a4 100644 (file)
@@ -1,8 +1,17 @@
-from abc import ABC, abstractmethod, abstractproperty
+import math
+import numbers
+import operator
+
+from abc import ABC, abstractproperty, abstractmethod
+from collections import OrderedDict, Mapping
+
+from .linexprs import Symbol
 
 
 __all__ = [
     'GeometricObject',
 
 
 __all__ = [
     'GeometricObject',
+    'Point',
+    'Vector',
 ]
 
 
 ]
 
 
@@ -22,3 +31,216 @@ class GeometricObject(ABC):
 
     def asdomain(self):
         return self.aspolyhedron()
 
     def asdomain(self):
         return self.aspolyhedron()
+
+
+class Coordinates:
+
+    __slots__ = (
+        '_coordinates',
+    )
+
+    def __new__(cls, coordinates):
+        if isinstance(coordinates, Mapping):
+            coordinates = coordinates.items()
+        self = object().__new__(cls)
+        self._coordinates = OrderedDict()
+        for symbol, coordinate in sorted(coordinates,
+                key=lambda item: item[0].sortkey()):
+            if not isinstance(symbol, Symbol):
+                raise TypeError('symbols must be Symbol instances')
+            if not isinstance(coordinate, numbers.Real):
+                raise TypeError('coordinates must be real numbers')
+            self._coordinates[symbol] = coordinate
+        return self
+
+    @property
+    def symbols(self):
+        return tuple(self._coordinates)
+
+    @property
+    def dimension(self):
+        return len(self.symbols)
+
+    def coordinates(self):
+        yield from self._coordinates.items()
+
+    def coordinate(self, symbol):
+        if not isinstance(symbol, Symbol):
+            raise TypeError('symbol must be a Symbol instance')
+        return self._coordinates[symbol]
+
+    __getitem__ = coordinate
+
+    def __bool__(self):
+        return any(self._coordinates.values())
+
+    def __hash__(self):
+        return hash(tuple(self.coordinates()))
+
+    def __repr__(self):
+        string = ', '.join(['{!r}: {!r}'.format(symbol, coordinate)
+            for symbol, coordinate in self.coordinates()])
+        return '{}({{{}}})'.format(self.__class__.__name__, string)
+
+    def _map(self, func):
+        for symbol, coordinate in self.coordinates():
+            yield symbol, func(coordinate)
+
+    def _iter2(self, other):
+        if self.symbols != other.symbols:
+            raise ValueError('arguments must belong to the same space')
+        coordinates1 = self._coordinates.values()
+        coordinates2 = other._coordinates.values()
+        yield from zip(self.symbols, coordinates1, coordinates2)
+
+    def _map2(self, other, func):
+        for symbol, coordinate1, coordinate2 in self._iter2(other):
+            yield symbol, func(coordinate1, coordinate2)
+
+
+class Point(Coordinates, GeometricObject):
+    """
+    This class represents points in space.
+    """
+
+    def isorigin(self):
+        return not bool(self)
+
+    def __add__(self, other):
+        if not isinstance(other, Vector):
+            return NotImplemented
+        coordinates = self._map2(other, operator.add)
+        return Point(coordinates)
+
+    def __sub__(self, other):
+        coordinates = []
+        if isinstance(other, Point):
+            coordinates = self._map2(other, operator.sub)
+            return Vector(coordinates)
+        elif isinstance(other, Vector):
+            coordinates = self._map2(other, operator.sub)
+            return Point(coordinates)
+        else:
+            return NotImplemented
+
+    def __eq__(self, other):
+        return isinstance(other, Point) and \
+            self._coordinates == other._coordinates
+
+    def aspolyhedron(self):
+        from .polyhedra import Polyhedron
+        equalities = []
+        for symbol, coordinate in self.coordinates():
+            equalities.append(symbol - coordinate)
+        return Polyhedron(equalities)
+
+
+class Vector(Coordinates):
+    """
+    This class represents displacements in space.
+    """
+
+    def __new__(cls, initial, terminal=None):
+        if not isinstance(initial, Point):
+            initial = Point(initial)
+        if terminal is None:
+            coordinates = initial._coordinates
+        elif not isinstance(terminal, Point):
+            terminal = Point(terminal)
+            coordinates = terminal._map2(initial, operator.sub)
+        return super().__new__(cls, coordinates)
+
+    def isnull(self):
+        return not bool(self)
+
+    def __add__(self, other):
+        if isinstance(other, (Point, Vector)):
+            coordinates = self._map2(other, operator.add)
+            return other.__class__(coordinates)
+        return NotImplemented
+
+    def angle(self, other):
+        """
+        Retrieve the angle required to rotate the vector into the vector passed
+        in argument. The result is an angle in radians, ranging between -pi and
+        pi.
+        """
+        if not isinstance(other, Vector):
+            raise TypeError('argument must be a Vector instance')
+        cosinus = self.dot(other) / (self.norm()*other.norm())
+        return math.acos(cosinus)
+
+    def cross(self, other):
+        """
+        Calculate the cross product of two Vector3D structures.
+        """
+        if not isinstance(other, Vector):
+            raise TypeError('other must be a Vector instance')
+        if self.dimension != 3 or other.dimension != 3:
+            raise ValueError('arguments must be three-dimensional vectors')
+        if self.symbols != other.symbols:
+            raise ValueError('arguments must belong to the same space')
+        x, y, z = self.symbols
+        coordinates = []
+        coordinates.append((x, self[y]*other[z] - self[z]*other[y]))
+        coordinates.append((y, self[z]*other[x] - self[x]*other[z]))
+        coordinates.append((z, self[x]*other[y] - self[y]*other[x]))
+        return Vector(coordinates)
+
+    def __truediv__(self, other):
+        """
+        Divide the vector by the specified scalar and returns the result as a
+        vector.
+        """
+        if not isinstance(other, numbers.Real):
+            return NotImplemented
+        coordinates = self._map(lambda coordinate: coordinate / other)
+        return Vector(coordinates)
+
+    def dot(self, other):
+        """
+        Calculate the dot product of two vectors.
+        """
+        if not isinstance(other, Vector):
+            raise TypeError('argument must be a Vector instance')
+        result = 0
+        for symbol, coordinate1, coordinate2 in self._iter2(other):
+            result += coordinate1 * coordinate2
+        return result
+
+    def __eq__(self, other):
+        return isinstance(other, Vector) and \
+            self._coordinates == other._coordinates
+
+    def __hash__(self):
+        return hash(tuple(self.coordinates()))
+
+    def __mul__(self, other):
+        if not isinstance(other, numbers.Real):
+            return NotImplemented
+        coordinates = self._map(lambda coordinate: other * coordinate)
+        return Vector(coordinates)
+
+    __rmul__ = __mul__
+
+    def __neg__(self):
+        coordinates = self._map(operator.neg)
+        return Vector(coordinates)
+
+    def norm(self):
+        return math.sqrt(self.norm2())
+
+    def norm2(self):
+        result = 0
+        for coordinate in self._coordinates.values():
+            result += coordinate ** 2
+        return result
+
+    def asunit(self):
+        return self / self.norm()
+
+    def __sub__(self, other):
+        if isinstance(other, (Point, Vector)):
+            coordinates = self._map2(other, operator.sub)
+            return other.__class__(coordinates)
+        return NotImplemented
index c30fd13..5d9c287 100644 (file)
@@ -5,8 +5,7 @@ import numbers
 from . import islhelper
 
 from .islhelper import mainctx, libisl
 from . import islhelper
 
 from .islhelper import mainctx, libisl
-from .geometry import GeometricObject
-from .coordinates import Point
+from .geometry import GeometricObject, Point
 from .linexprs import Expression, Symbol, Rational
 from .domains import Domain
 
 from .linexprs import Expression, Symbol, Rational
 from .domains import Domain
 
similarity index 99%
rename from pypol/tests/test_coordinates.py
rename to pypol/tests/test_geometry.py
index 044d773..e602616 100644 (file)
@@ -1,7 +1,7 @@
 import math
 import unittest
 
 import math
 import unittest
 
-from ..coordinates import *
+from ..geometry import *
 from ..linexprs import Symbol
 from ..polyhedra import Eq
 
 from ..linexprs import Symbol
 from ..polyhedra import Eq