#!/usr/bin/env python # encoding: utf-8 from .polynom import Polynom from .expression import Expression from .fraction import Fraction from .operator import op from .random_expression import RdExpression from sympy import sqrt, latex # from sympy.fractions import Fraction as sp.Fraction __all__ = ["Polynom_deg2"] class Polynom_deg2(Polynom): """ Degree 2 polynoms Child of Polynom with some extra tools """ @classmethod def random( self, coefs_form=[ "{c}", "{b}", "{a}"], conditions=[], letter="x", name="P"): """ Create a 2nd degree poly from coefs_form ans conditions :param coefs_form: list of forms (one by coef) (ascending degree sorted) :param conditions: condition on variables :param letter: the letter for the polynom """ if len(coefs_form) != 3: raise ValueError( "Polynom_deg2 have to be degree 2 polynoms, they need 3 coefficients, {} are given".format( len(coefs_form))) form = str(coefs_form) # On créé les valeurs toutes concaténées dans un string coefs = RdExpression(form, conditions)() # On "parse" ce string pour créer les coefs coefs = [eval(i) if isinstance(i, str) else i for i in eval(coefs)] # Création du polynom return Polynom_deg2(coefs=coefs, letter=letter, name=name) def __init__(self, coefs=[0, 0, 1], letter="x", name="P", poly=0): if poly: coefs = poly._coef letter = poly._letter name = poly.name if len(coefs) < 3 or len(coefs) > 4: raise ValueError( "Polynom_deg2 have to be degree 2 polynoms, they need 3 coefficients, {} are given".format( len(coefs))) if coefs[2] == 0: raise ValueError( "Polynom_deg2 have to be degree 2 polynoms, coefficient of x^2 can't be 0") Polynom.__init__(self, coefs, letter, name=name) @property def a(self): return self._coef[2] @property def b(self): return self._coef[1] @property def c(self): return self._coef[0] @property def delta(self): """Compute the discriminant expression :returns: discriminant expression >>> P = Polynom_deg2([1,2,3]) >>> P.delta -8 >>> for i in P.delta.explain(): ... print(i) 2^{ 2 } - 4 \\times 3 \\times 1 4 - 4 \\times 3 4 - 12 -8 """ return Expression([self.b, 2, op.pw, 4, self.a, self.c, op.mul, op.mul, op.sub]).simplify() @property def alpha(self): """ Compute alpha the abcisse of the extremum >>> P = Polynom_deg2([1,2,3]) >>> P.alpha < Fraction -1 / 3> >>> for i in P.alpha.explain(): ... print(i) \\frac{ - 2 }{ 2 \\times 3 } \\frac{ -2 }{ 6 } \\frac{ -1 \\times 2 }{ 3 \\times 2 } \\frac{ -1 }{ 3 } """ return Expression([self.b, op.sub1, 2, self.a, op.mul, op.div]).simplify() @property def beta(self): r""" Compute beta the extremum of self >>> P = Polynom_deg2([1,2,3]) >>> P.beta < Fraction 2 / 3> >>> for i in P.beta.explain(): # Ça serait bien que l'on puisse enlever des étapes maintenant... ... print(i) 3 \times ( \frac{ -1 }{ 3 } )^{ 2 } + 2 \times \frac{ -1 }{ 3 } + 1 3 \times ( \frac{ -1 }{ 3 } )^{ 2 } + \frac{ -1 }{ 3 } \times 2 + 1 3 \times \frac{ ( -1 )^{ 2 } }{ 3^{ 2 } } + \frac{ -1 \times 2 }{ 3 } + 1 3 \times \frac{ 1 }{ 9 } + \frac{ -2 }{ 3 } + 1 \frac{ 1 }{ 9 } \times 3 + \frac{ -2 }{ 3 } + 1 \frac{ 1 \times 3 }{ 3 \times 3 } + \frac{ -2 }{ 3 } + 1 \frac{ 1 }{ 3 } + \frac{ -2 }{ 3 } + 1 \frac{ 1 - 2 }{ 3 } + 1 \frac{ -1 }{ 3 } + 1 \frac{ -1 \times 1 }{ 3 \times 1 } + \frac{ 1 \times 3 }{ 1 \times 3 } \frac{ -1 }{ 3 } + \frac{ 3 }{ 3 } \frac{ -1 + 3 }{ 3 } \frac{ 2 }{ 3 } """ return self(self.alpha) def roots(self, after_coma=2): """ Compute roots of the polynom /!\ Can't manage nice rendering because of sqrt. It use sympy to compute roots # TODO: Pymath has to know how to compute with sqare root |mar. févr. 24 18:40:04 CET 2015 >>> P = Polynom_deg2([1, 1, 1]) >>> P.roots() [] >>> P = Polynom_deg2([1, 2, 1]) >>> P.roots() [-1] >>> P = Polynom_deg2([-1, 0, 1]) >>> P.roots() ['-1', '1'] >>> P = Polynom_deg2([1, 4, 1]) >>> P.roots() ['-2 - \\\\sqrt{3}', '-2 + \\\\sqrt{3}'] """ if self.delta > 0: self._roots = [latex((-self.b - sqrt(self.delta)) / (2 * self.a)), latex((-self.b + sqrt(self.delta)) / (2 * self.a))] elif self.delta == 0: self._roots = [Fraction(-self.b, 2 * self.a).simplify()] else: self._roots = [] return self._roots def tbl_sgn_header(self): """ Return header of the sign line for tkzTabLine""" if self.delta > 0: return "{$-\\infty$, $" + str(min(self.roots())) + \ "$ , $" + str(max(self.roots())) + "$ , $+\\infty$}" elif self.delta == 0: return "{$-\\infty$, $" + str(self.roots()[0]) + "$ , $+\\infty$}" else: return "{$-\\infty$, $+\\infty$}" def tbl_sgn(self): """ Return the sign line for tkzTabLine >>> P = Polynom_deg2([2, 5, 2]) >>> print(P.tbl_sgn()) \\tkzTabLine{, +, z, -, z , +,} >>> P = Polynom_deg2([2, 1, -2]) >>> print(P.tbl_sgn()) \\tkzTabLine{, -, z, +, z , -,} >>> P = Polynom_deg2([1, 2, 1]) >>> print(P.tbl_sgn()) \\tkzTabLine{, +, z, +,} >>> P = Polynom_deg2([0, 0, -2]) >>> print(P.tbl_sgn()) \\tkzTabLine{, -, z, -,} >>> P = Polynom_deg2([1, 0, 1]) >>> print(P.tbl_sgn()) \\tkzTabLine{, +,} >>> P = Polynom_deg2([-1, 0, -1]) >>> print(P.tbl_sgn()) \\tkzTabLine{, -,} """ if self.delta > 0: if self.a > 0: return "\\tkzTabLine{, +, z, -, z , +,}" else: return "\\tkzTabLine{, -, z, +, z , -,}" elif self.delta == 0: if self.a > 0: return "\\tkzTabLine{, +, z, +,}" else: return "\\tkzTabLine{, -, z, -,}" else: if self.a > 0: return "\\tkzTabLine{, +,}" else: return "\\tkzTabLine{, -,}" def tbl_variation(self, limits=False): """Return the variation line for tkzTabVar :param limit: Display or not limits in tabular >>> P = Polynom_deg2([1,2,3]) >>> print(P.tbl_variation()) \\tkzTabVar{+/{}, -/{$\\frac{ 2 }{ 3 }$}, +/{}} >>> print(P.tbl_variation(limits = True)) \\tkzTabVar{+/{$+\\infty$}, -/{$\\frac{ 2 }{ 3 }$}, +/{$+\\infty$}} """ beta = self.beta if limits: if self.a > 0: return "\\tkzTabVar{+/{$+\\infty$}, -/{$" + \ str(beta) + "$}, +/{$+\\infty$}}" else: return "\\tkzTabVar{-/{$-\\infty$}, +/{$" + \ str(beta) + "$}, -/{$-\\infty$}}" else: if self.a > 0: return "\\tkzTabVar{+/{}, -/{$" + str(beta) + "$}, +/{}}" else: return "\\tkzTabVar{-/{}, +/{$" + str(beta) + "$}, -/{}}" # ----------------------------- # Reglages pour 'vim' # vim:set autoindent expandtab tabstop=4 shiftwidth=4: # cursor: 16 del