From 5b661514c1bbabd8205fdbd22a0ba0f6b1ac6305 Mon Sep 17 00:00:00 2001 From: Vivien Maisonneuve Date: Sun, 13 Jul 2014 09:04:48 +0200 Subject: [PATCH] Add _repr_latex_ methods for IPython prettyprint --- pypol/domains.py | 6 ++++ pypol/linexprs.py | 65 +++++++++++++++++++++++++++++------ pypol/polyhedra.py | 17 +++++++-- pypol/tests/test_linexprs.py | 2 +- pypol/tests/test_polyhedra.py | 4 +-- 5 files changed, 79 insertions(+), 15 deletions(-) diff --git a/pypol/domains.py b/pypol/domains.py index d80fd91..10d12c5 100644 --- a/pypol/domains.py +++ b/pypol/domains.py @@ -438,6 +438,12 @@ class Domain(GeometricObject): strings = [repr(polyhedron) for polyhedron in self.polyhedra] return 'Or({})'.format(', '.join(strings)) + def _repr_latex_(self): + strings = [] + for polyhedron in self.polyhedra: + strings.append('({})'.format(polyhedron._repr_latex_().strip('$'))) + return '${}$'.format(' \\vee '.join(strings)) + @classmethod def fromsympy(cls, expr): import sympy diff --git a/pypol/linexprs.py b/pypol/linexprs.py index 229e8d9..c8745b5 100644 --- a/pypol/linexprs.py +++ b/pypol/linexprs.py @@ -240,18 +240,17 @@ class Expression: string = '' for i, (symbol, coefficient) in enumerate(self.coefficients()): if coefficient == 1: - string += '' if i == 0 else ' + ' - string += '{!r}'.format(symbol) + if i != 0: + string += ' + ' elif coefficient == -1: string += '-' if i == 0 else ' - ' - string += '{!r}'.format(symbol) + elif i == 0: + string += '{}*'.format(coefficient) + elif coefficient > 0: + string += ' + {}*'.format(coefficient) else: - if i == 0: - string += '{}*{!r}'.format(coefficient, symbol) - elif coefficient > 0: - string += ' + {}*{!r}'.format(coefficient, symbol) - else: - string += ' - {}*{!r}'.format(-coefficient, symbol) + string += ' - {}*'.format(-coefficient) + string += '{}'.format(symbol) constant = self.constant if len(string) == 0: string += '{}'.format(constant) @@ -261,6 +260,30 @@ class Expression: string += ' - {}'.format(-constant) return string + def _repr_latex_(self): + string = '' + for i, (symbol, coefficient) in enumerate(self.coefficients()): + if coefficient == 1: + if i != 0: + string += ' + ' + elif coefficient == -1: + string += '-' if i == 0 else ' - ' + elif i == 0: + string += '{}'.format(coefficient._repr_latex_().strip('$')) + elif coefficient > 0: + string += ' + {}'.format(coefficient._repr_latex_().strip('$')) + elif coefficient < 0: + string += ' - {}'.format((-coefficient)._repr_latex_().strip('$')) + string += '{}'.format(symbol._repr_latex_().strip('$')) + constant = self.constant + if len(string) == 0: + string += '{}'.format(constant._repr_latex_().strip('$')) + elif constant > 0: + string += ' + {}'.format(constant._repr_latex_().strip('$')) + elif constant < 0: + string += ' - {}'.format((-constant)._repr_latex_().strip('$')) + return '${}$'.format(string) + def _parenstr(self, always=False): string = str(self) if not always and (self.isconstant() or self.issymbol()): @@ -340,6 +363,9 @@ class Symbol(Expression): def __repr__(self): return self.name + def _repr_latex_(self): + return '${}$'.format(self.name) + @classmethod def fromsympy(cls, expr): import sympy @@ -378,6 +404,9 @@ class Dummy(Symbol): def __repr__(self): return '_{}'.format(self.name) + def _repr_latex_(self): + return '${}_{{{}}}$'.format(self.name, self._index) + def symbols(names): if isinstance(names, str): @@ -430,7 +459,23 @@ class Rational(Expression, Fraction): def fromstring(cls, string): if not isinstance(string, str): raise TypeError('string must be a string instance') - return Rational(Fraction(string)) + return Rational(string) + + def __repr__(self): + if self.denominator == 1: + return '{!r}'.format(self.numerator) + else: + return '{!r}/{!r}'.format(self.numerator, self.denominator) + + def _repr_latex_(self): + if self.denominator == 1: + return '${}$'.format(self.numerator) + elif self.numerator < 0: + return '$-\\frac{{{}}}{{{}}}$'.format(-self.numerator, + self.denominator) + else: + return '$\\frac{{{}}}{{{}}}$'.format(self.numerator, + self.denominator) @classmethod def fromsympy(cls, expr): diff --git a/pypol/polyhedra.py b/pypol/polyhedra.py index e745d7d..6b5f9ab 100644 --- a/pypol/polyhedra.py +++ b/pypol/polyhedra.py @@ -182,14 +182,27 @@ class Polyhedron(Domain): else: strings = [] for equality in self.equalities: - strings.append('0 == {}'.format(equality)) + strings.append('Eq({}, 0)'.format(equality)) for inequality in self.inequalities: - strings.append('0 <= {}'.format(inequality)) + strings.append('Ge({}, 0)'.format(inequality)) if len(strings) == 1: return strings[0] else: return 'And({})'.format(', '.join(strings)) + def _repr_latex_(self): + if self.isempty(): + return '$\\emptyset$' + elif self.isuniverse(): + return '$\\Omega$' + else: + strings = [] + for equality in self.equalities: + strings.append('{} = 0'.format(equality._repr_latex_().strip('$'))) + for inequality in self.inequalities: + strings.append('{} \\ge 0'.format(inequality._repr_latex_().strip('$'))) + return '${}$'.format(' \\wedge '.join(strings)) + @classmethod def fromsympy(cls, expr): domain = Domain.fromsympy(expr) diff --git a/pypol/tests/test_linexprs.py b/pypol/tests/test_linexprs.py index 6ec8993..01f844f 100644 --- a/pypol/tests/test_linexprs.py +++ b/pypol/tests/test_linexprs.py @@ -275,7 +275,7 @@ class TestRational(unittest.TestCase): def setUp(self): self.zero = Rational(0) self.one = Rational(1) - self.pi = Rational(Fraction(22, 7)) + self.pi = Rational(22, 7) def test_new(self): self.assertEqual(Rational(), self.zero) diff --git a/pypol/tests/test_polyhedra.py b/pypol/tests/test_polyhedra.py index 689602b..e813609 100644 --- a/pypol/tests/test_polyhedra.py +++ b/pypol/tests/test_polyhedra.py @@ -20,11 +20,11 @@ class TestPolyhedron(unittest.TestCase): def test_str(self): self.assertEqual(str(self.square), - 'And(0 <= x, 0 <= -x + 1, 0 <= y, 0 <= -y + 1)') + 'And(Ge(x, 0), Ge(-x + 1, 0), Ge(y, 0), Ge(-y + 1, 0))') def test_repr(self): self.assertEqual(repr(self.square), - "And(0 <= x, 0 <= -x + 1, 0 <= y, 0 <= -y + 1)") + "And(Ge(x, 0), Ge(-x + 1, 0), Ge(y, 0), Ge(-y + 1, 0))") def test_fromstring(self): self.assertEqual(Polyhedron.fromstring('{x >= 0, -x + 1 >= 0, ' -- 2.20.1