m
vbFc@shdZdkZdklZdefdYZdefdYZdefdYZ[[dS( sPolynomials. Coefficients are assumed numeric. Only natural powers are considered.
$Id: polynomial.py,v 1.19 2007/06/03 16:42:30 eddy Exp $
N(sLazytinvalidCoefficientcBstZdZRS(s"Invalid coefficient for polynomial(t__name__t
__module__t__doc__(((t,/home/eddy/.sys/py/study/maths/polynomial.pyRstunNaturalPowercBstZdZRS(s7Power of variable in polynomial is not a natural number(RRR(((RR st
PolynomialcBstZdZdZeieieieifdZ e dZ
[ dZeieifddZdZ
dZd Zd
ZdZeZdZd
ZedZ[dZdZedZ[dZedZ[dZedZ[dZdZeZdZ dZ!dZ"e"Z#dZ$e$Z%dZ&dZ'e'dZ(dZ)e'e)d Z*['[)d!Z+e+d"Z,e+eieifd#d$Z-[+d%Z.d&Z/d'Z0d(d(d)Z1d*Z2d+Z3d,Z4d-Z5d.Z6ei7d/Z8d0Z9d1Z:d2Z;d3Z<d4Z=d5Z>d6Z?d7Z@d8ZAd9kBlCZCeCd:ZD[Cd(d;d<ZEeFd=ZGd>ZHd?d(d@ZIdAZJRS(Bs:Model of the mathematical ring of polynomials (in one free variable).
Supports arithmetic (+, -, *, /, %, divmod, power, negation), comparison
(but cmp() will yield zero in some cases where == will say no),
representation (as a python lambda expression), evaluation (i.e. calling as
a function), repeated integration (as <<) and differentiation (as >>), use
as boolean (only the zero polynomial is false) and (lazy) hashing.
Lazy attributes:
===============
rank -- highest power of the free variable with non-zero coefficient
normalised -- same polynomial scaled so rank's coefficient is 1
derivative -- result of differentiating the polynomial
assquares -- decompose as sum of scaled squares and a remainder
sign -- like cmp(self, 0) but None when ill-defined or variable
isreal -- are all coefficients real ?
factors -- tuple of normalised irreducible factors and an optional scalar
Note that a poly with true isreal considers positive-definite quadratic
factors to be irreducible; assigning isreal = None will persuade a poly to
believe quadratic factors are reducible. The value of p.assquares is of
form (bok, rem) with rem either zero or of odd degree and p-rem equal to
reduce(lambda y, (x, v): y + x*x*v, bok.items(), 0).
The value of sign may presently sometimes be None when it needn't be; I've
yet to find an example, but the computation in use only deals with `easy
enough' cases. Note that cmp() yields zero when the difference's sign is
None or zero; but == is true only when sign is zero (actual equality).
Methods:
========
coefficient(n) -- yields coefficient of (: x**n ←x :) in polynomial
hcf([poly, ...]) -- yields highest common factor of arbitrarily many
integral([start=0, base=0]) -- integration
unafter(poly) -- input to poly yielding self as output
seek_root([guess=0, tol=1e-6]) -- find an input mapped to zero
seek_factor([guess=None]) -- find a factor, if possible
See individual methods' docs for details.
cGsh|_y|\}||i|Wntj
o|i|nmtttfj
oWy|i |i
ddfWn#tj
o|id|qX|i
|nXdS(s Constructor.
If exactly one argument is passed and it is a mapping, its keys are used
as powers and values as coefficients of each power's term in the
polynomial; if exactly one argument is passed and it is a sequence, it
is interpreted as a mapping whose keys are indices into the list and
values are entries in the list. Otherwise, each argument must be
numeric and the arguments are interpreted as if they'd been passed as a
sequence.
Thus:
Polynomial({ power: coeff ... }) == (: sum(: coeff * x**power :) <- x :)
Polynomial([ co_0_, co_1_ ... ]) ==
Polynomial(( co_0_, co_1_ ... )) ==
Polynomial( co_0_, co_1_ ... ) == (: sum(: co_i_ * x**i <- i :) <- x :)
As special cases of the last, Polynomial( value ) generates the constant
polynomial value <- x and Polynomial() generates the zero polynomial -
but note that this is the scalar zero polynomial; if a vector zero or
dimensioned zero is desired, supply it as the value for a constant
polynomial; but if your vector type supports slicing, you'd better pass
it as Polynomial({0: zero}) instead.
The polynomial 1 + 2.x + 3.x**2 <- x may thus be generated by any of:
Polynomial(1,2,3), Polynomial((1,2,3)), Polynomial([1,2,3]) or
Polynomial({0:1,1:2,2:3}). The last, dictionary, form is generally
preferrable for sparse polynomials (ie, rank >> the number of non-zero
coefficients): tuple form is better for short and sweet forms like that
illustrated.
Note that setting z = Polynomial(0, 1) provides a `free variable' that
can then be used to generate polynomials the way many folk prefer; with
this, Polynomial(1,2,3) can simply be written 3*z*z +2*z +1. If you
want a polynomial's representation to use the name z (rather than x),
simply set the polynomial's .variablename to 'z' (but note that this
only applies to that polynomial, not to ones computed from it).
iN(tselft_Polynomial__coefstargstargt_Polynomial__fromseqt
ValueErrortAttributeErrort TypeErrortKeyErrortitemstgettNonet_Polynomial__storet_Polynomial__frombok(RR R
((Rt__init__6s% cCsnt||jo)|t|jot|Sn|Sn/t|dot|do|SntdS(Nt__add__t__mul__(ttypetvaltoktypestlongthasattrR(RR((Rt
_get_coeffks cCs1|o|||i|scCsVxO|iD]A\}}||p
|djo
tq
|i||q
WdS(Ni(tbokRtkeyRtokRRR(RR)R+RR*((Rt __fromboks
cCsqx9|iiD](}|i|djo|i|=qqWyt|iiSWntj
odSnXdS(Nf0.0i(RRtkeysR*tmaxR(RtignoredR*((Rt_lazy_get_rank_scGs5x.|D]&}x|o|||}}qWqW|S(N(totherstotherR(RR1R2((RthcfscGs|i|idjS(Ni(RR3R1trank(RR1((RtcoprimescCsJ|idjo
tdn|i|i}|djo|Sn||S(NisCan't normalise zeroi(RR4RRtscale(RR/R6((Rt_lazy_get_normalised_s
cCs~y|iSWntj
onX|ig}|i|d}ddi|}|p|d}n||}||_|S(Nislambda %s: s, t0(
Rt_Polynomial__reprR
tvariablenametnamest_Polynomial__representttexttjointlambtans(RR?R=R;R@((Rt__repr__s
tzcCssy!|idjo
|i}nWntj
onXy|i|d|SWntj
ot|SnXdS(Nii(tnumtimagtrealR
R<R;tdepthtstr(RCR;RF((Rtformatsc Csxc|t|joO|dddjo|idq|itt|dddqWd||}}x|i D]}|i|}|o|djo
d}nS|djo
d}n<||||}d|jod |d
}n|d7}|djo||7}qK|d||f7}n||||}|d djo|d|7}q|d
|7}qW|d d
jo|dSn|d djo|dSn|S(NiitatZitt-t t(s)*t*s%s**%ds +i(RFtlenR;tappendtchrtordtresulttnameRt_powersR*tcoefficientRtfragtfmt( RR;RFRYRXRURR*RT((Rt__represents<*
cCs@h}x-|iiD]\}}||||x)|djo|i|d}}qW|S(sf << n -> nth integral of fliiN(R2Rtintegral(RR2((Rt
__lshift__s
cCs5d|?x&|djo|i|d}}qW|S(sf >> n -> nth derivative of fliiN(R2Rt
derivative(RR2((Rt
__rshift__s
cCsMh}x:|iiD])\}}|o||||d V-> V and +: V-> V-> V, we can
evaluate p(t) by substituting t in as the value of p's formal
parameter.
iiN(
RRVR-R}t
IndexErrorR!RWRTR*R
(RR
R-RTR*R}((Rt__call__s"
cCs|h}}x|o|i|iotd|d|n|i|i}t|||\}}|idjpt |i||ijpt |i
d||