source: sage/rings/polynomial/polynomial_integer_dense_ntl.pyx @ 7284:ba70e8043d97

Revision 7284:ba70e8043d97, 23.1 KB checked in by Carl Witty <cwitty@…>, 6 years ago (diff)

Add ring= parameter for polynomial .roots() method.

Line 
1"""
2Dense univariate polynomials over Z, implemented using NTL.
3
4AUTHORS:
5    -- David Harvey: split off from polynomial_element_generic.py (2007-09)
6    -- David Harvey: rewrote to talk to NTL directly, instead of via ntl.pyx (2007-09);
7               a lot of this was based on Joel Mohler's recent rewrite of the NTL wrapper
8
9"""
10
11################################################################################
12#       Copyright (C) 2007 William Stein <wstein@gmail.com>
13#
14#  Distributed under the terms of the GNU General Public License (GPL)
15#
16#                  http://www.gnu.org/licenses/
17################################################################################
18
19include "../../ext/stdsage.pxi"
20
21
22from sage.rings.polynomial.polynomial_element cimport Polynomial
23from sage.structure.element cimport ModuleElement, RingElement
24
25from sage.rings.integer_ring import IntegerRing
26from sage.rings.integer_ring cimport IntegerRing_class
27ZZ_sage = IntegerRing()
28
29
30from sage.rings.polynomial.polynomial_element import is_Polynomial
31
32from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX
33
34from sage.rings.integer_ring import ZZ
35from sage.rings.rational_field import QQ
36from sage.rings.integer import Integer
37from sage.rings.integer cimport Integer
38
39from sage.libs.all import pari, pari_gen
40from sage.structure.factorization import Factorization
41
42from sage.rings.fraction_field_element import FractionFieldElement
43from sage.rings.arith import lcm
44import sage.rings.polynomial.polynomial_ring
45
46
47cdef class Polynomial_integer_dense_ntl(Polynomial):
48    r"""
49    A dense polynomial over the integers, implemented via NTL.
50    """
51
52    def __new__(self, parent=None, x=None, check=True, is_gen=False, construct=False):
53        r"""
54        calls the underlying NTL constructor
55        """
56        ZZX_construct(&self.__poly)
57
58
59    def __dealloc__(self):
60        r"""
61        calls the underlying NTL destructor
62        """
63        ZZX_destruct(&self.__poly)
64
65
66    cdef Polynomial_integer_dense_ntl _new(self):
67        r"""
68        Quickly creates a new initialized Polynomial_integer_dense_ntl
69        with the correct parent and _is_gen == 0.
70        """
71        cdef Polynomial_integer_dense_ntl x = PY_NEW(Polynomial_integer_dense_ntl)
72        x._parent = self._parent
73        x._is_gen = 0
74        return x
75
76                                           
77    def __init__(self, parent, x=None, check=True, is_gen=False, construct=False):
78        r"""
79        EXAMPLES:
80            sage: R.<x> = PolynomialRing(ZZ)
81            sage: x
82            x
83
84        Construct from list:
85            sage: R([])
86            0
87            sage: R([1, -2, 3])
88            3*x^2 - 2*x + 1
89
90        Coercions from other rings are attempted automatically:
91            sage: R([1, -6/3, 3])
92            3*x^2 - 2*x + 1
93            sage: R([1, 5/2, 2])
94            Traceback (most recent call last):
95            ...
96            TypeError: no coercion of this rational to integer
97
98        Construct from constant:
99            sage: R(3)
100            3
101
102        Coercion from PARI polynomial:
103            sage: f = R([-1, 2, 5]); f
104            5*x^2 + 2*x - 1
105            sage: type(f)
106            <type 'sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl'>
107            sage: type(pari(f))
108            <type 'sage.libs.pari.gen.gen'>
109            sage: type(R(pari(f)))
110            <type 'sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl'>
111            sage: R(pari(f))
112            5*x^2 + 2*x - 1
113     
114        Coercion from NTL polynomial:
115            sage: f = ntl.ZZX([1, 2, 3])
116            sage: print R(f)
117            3*x^2 + 2*x + 1
118
119        Coercion from dictionary:
120            sage: f = R({2: -4, 3: 47}); f
121            47*x^3 - 4*x^2
122
123        Coercion from fraction field element with trivial denominator:
124            sage: f = (x^3 - 1) / (x - 1)
125            sage: type(f)
126            <class 'sage.rings.fraction_field_element.FractionFieldElement'>
127            sage: g = R(f); g
128            x^2 + x + 1
129
130        """
131        Polynomial.__init__(self, parent, is_gen=is_gen)
132
133        if x is None:
134            return         # leave initialized to 0 polynomial.
135
136        if isinstance(x, Polynomial):
137            if x.parent() is self.parent():
138                # copy with NTL assignment operator
139                self.__poly = (<Polynomial_integer_dense_ntl>x).__poly
140                return
141            else:
142                # coerce coefficients into SAGE integers
143                x = [Integer(a) for a in x.list()]
144                check = False
145
146        elif isinstance(x, dict):
147            x = self._dict_to_list(x, ZZ(0))
148
149        elif isinstance(x, pari_gen):
150            x = [Integer(w) for w in x.Vecrev()]
151            check = False
152           
153        elif isinstance(x, ntl_ZZX):    # coercion from ntl.pyx object
154            # copy with NTL assignment operator
155            self.__poly = (<ntl_ZZX>x).x
156            return
157
158        elif isinstance(x, FractionFieldElement) and \
159                 isinstance(x.numerator(), Polynomial_integer_dense_ntl):
160            if x.denominator() == 1:
161                # fraction of the form f(x)/1
162                self.__poly = (<Polynomial_integer_dense_ntl>x.numerator()).__poly
163                return
164
165        elif not isinstance(x, list):
166            x = [x]   # constant polynomials
167
168        if check:
169            x = [Integer(z) for z in x]
170
171        cdef Py_ssize_t i
172        cdef ZZ_c y
173
174        for i from 0 <= i < len(x):
175            mpz_to_ZZ(&y, &(<Integer>x[i]).value)
176            ZZX_SetCoeff(self.__poly, i, y)
177
178
179    def content(self):
180        r"""
181        Return the greatest common divisor of the coefficients of this
182        polynomial. The sign is the sign of the leading coefficient.
183        The content of the zero polynomial is zero.
184
185        EXAMPLES:
186            sage: R.<x> = PolynomialRing(ZZ)
187            sage: (2*x^2 - 4*x^4 + 14*x^7).content()
188            2
189            sage: (2*x^2 - 4*x^4 - 14*x^7).content()
190            -2
191            sage: x.content()
192            1
193            sage: R(1).content()
194            1
195            sage: R(0).content()
196            0
197        """
198        cdef ZZ_c y
199        cdef Integer z = PY_NEW(Integer)
200        ZZX_content(y, self.__poly)
201        ZZ_to_mpz(&z.value, &y)
202        return z
203
204
205    def __reduce__(self):
206        r"""
207        Used for pickling.
208
209        EXAMPLES:
210            sage: R.<x> = PolynomialRing(ZZ)
211            sage: loads(dumps(x)) == x
212            True
213            sage: f = 2*x + 3
214            sage: loads(dumps(f)) == f
215            True
216        """
217        return Polynomial_integer_dense_ntl, \
218               (self.parent(), self.list(), False, self.is_gen())
219
220       
221    def __getitem__(self, long n):
222        r"""
223        Returns coefficient of x^n, or zero if n is negative.
224
225        EXAMPLES:
226            sage: R.<x> = PolynomialRing(ZZ)
227            sage: f = 2*x^2 - 3
228            sage: f[0]
229            -3
230            sage: f[1]
231            0
232            sage: f[2]
233            2
234            sage: f[3]
235            0
236            sage: f[-1]
237            0
238        """
239        # todo: this is performing an unnecessary copy. We need
240        # a function that returns a (const!) pointer to the coefficient
241        # of the NTL polynomial.
242        cdef ZZ_c temp = ZZX_coeff(self.__poly, n)
243        cdef Integer z = PY_NEW(Integer)
244        ZZ_to_mpz(&z.value, &temp)
245        return z
246
247
248    def __getslice__(self, long i, long j):
249        r"""
250        EXAMPLES:
251            sage: R.<x> = PolynomialRing(ZZ)
252            sage: f = 1 + x + 2*x^2 + 3*x^3 + 4*x^4 + 5*x^5
253            sage: f[2:4]
254            3*x^3 + 2*x^2
255            sage: f[-2:4]
256            3*x^3 + 2*x^2 + x + 1
257            sage: f[4:100]
258            5*x^5 + 4*x^4
259        """
260        cdef long k
261        i = max(0, i)
262        j = min(j, self.degree()+1)
263        v = [self[k] for k from i <= k < j]
264        P = self.parent()
265        return P([0] * int(i) + v)
266
267     
268    cdef ModuleElement _add_c_impl(self, ModuleElement right):
269        r"""
270        Returns self plus right.
271       
272        EXAMPLES:
273            sage: R.<x> = PolynomialRing(ZZ)
274            sage: f = 2*x + 1
275            sage: g = -3*x^2 + 6
276            sage: f + g
277            -3*x^2 + 2*x + 7
278        """
279        cdef Polynomial_integer_dense_ntl x = self._new()
280        ZZX_add(x.__poly, self.__poly,
281                (<Polynomial_integer_dense_ntl>right).__poly)
282        return x
283
284
285    cdef ModuleElement _sub_c_impl(self, ModuleElement right):
286        r"""
287        Return self minus right.
288       
289        EXAMPLES:
290            sage: R.<x> = PolynomialRing(ZZ)
291            sage: f = 2*x + 1
292            sage: g = -3*x^2 + 6
293            sage: f - g
294            3*x^2 + 2*x - 5
295        """
296        cdef Polynomial_integer_dense_ntl x = self._new()
297        ZZX_sub(x.__poly, self.__poly,
298                (<Polynomial_integer_dense_ntl>right).__poly)
299        return x
300
301
302    cdef ModuleElement _neg_c_impl(self):
303        r"""
304        Returns negative of self.
305       
306        EXAMPLES:
307            sage: R.<x> = PolynomialRing(ZZ)
308            sage: f = 2*x - 1
309            sage: -f
310            -2*x + 1
311        """
312        cdef Polynomial_integer_dense_ntl x = self._new()
313        ZZX_negate(x.__poly, self.__poly)
314        return x
315
316
317    def quo_rem(self, right):
318        r"""
319        Returns a tuple (quotient, remainder) where
320            self = quotient*other + remainder.
321
322        If the quotient and remainder are not integral,
323        an exception is raised.
324
325        EXAMPLES:
326            sage: R.<x> = PolynomialRing(ZZ)
327            sage: f = R(range(10)); g = R([-1, 0, 1])
328            sage: q, r = f.quo_rem(g)
329            sage: q, r
330            (9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 25*x + 20)
331            sage: q*g + r == f
332            True
333        """
334        if not isinstance(right, Polynomial_integer_dense_ntl):
335            right = self.parent()(right)
336        elif self.parent() is not right.parent():
337            raise TypeError
338
339        # ugggh this isn't pretty. Lots of unnecessary copies.
340        cdef ZZX_c *r, *q
341        ZZX_quo_rem(&self.__poly, &(<Polynomial_integer_dense_ntl>right).__poly, &r, &q)
342        cdef Polynomial_integer_dense_ntl rr = self._new()
343        cdef Polynomial_integer_dense_ntl qq = self._new()
344        rr.__poly = r[0]
345        qq.__poly = q[0]
346        ZZX_delete(&r[0])
347        ZZX_delete(&q[0])
348        return (qq, rr)
349
350       
351    def gcd(self, right):
352        r"""
353        Return the GCD of self and right.  The leading
354        coefficient need not be 1.
355
356        EXAMPLES:
357            sage: R.<x> = PolynomialRing(ZZ)
358            sage: f = (6*x + 47)*(7*x^2 - 2*x + 38)
359            sage: g = (6*x + 47)*(3*x^3 + 2*x + 1)
360            sage: f.gcd(g)
361            6*x + 47
362        """
363        if not isinstance(right, Polynomial_integer_dense_ntl):
364            right = self.parent()(right)
365        elif self.parent() is not right.parent():
366            raise TypeError
367
368        # todo: we're doing an unnecessary copy here
369        cdef Polynomial_integer_dense_ntl x = self._new()
370        cdef ZZX_c* temp = ZZX_gcd(&self.__poly, &(<Polynomial_integer_dense_ntl>right).__poly)
371        x.__poly = temp[0]
372        ZZX_delete(temp)
373        return x
374
375
376    def lcm(self, right):
377        """
378        Return the LCM of self and right.
379
380        EXAMPLES:
381            sage: R.<x> = PolynomialRing(ZZ)
382            sage: f = (6*x + 47)*(7*x^2 - 2*x + 38)
383            sage: g = (6*x + 47)*(3*x^3 + 2*x + 1)
384            sage: h = f.lcm(g); h
385            126*x^6 + 951*x^5 + 486*x^4 + 6034*x^3 + 585*x^2 + 3706*x + 1786
386            sage: h == (6*x + 47)*(7*x^2 - 2*x + 38)*(3*x^3 + 2*x + 1)
387            True
388        """
389        if not isinstance(right, Polynomial_integer_dense_ntl):
390            right = self.parent()(right)
391        elif self.parent() is not right.parent():
392            raise TypeError
393
394        g = self.gcd(right)
395        return (self * right).quo_rem(g)[0]
396
397
398    def xgcd(self, right):
399        """
400        Return $g, u, v$ such that \code{g = u*self + v*right}.
401
402        If self and right are coprime as polynomials over the
403        rationals, then $g$ is guaranteed to be the resultant of self
404        and right, as a constant polynomial.
405
406        EXAMPLES:
407            sage: P.<x> = PolynomialRing(ZZ)
408            sage: F = (x^2 + 2)*x^3; G = (x^2+2)*(x-3)
409            sage: g, u, v = F.xgcd(G)
410            sage: g, u, v
411            (27*x^2 + 54, 1, -x^2 - 3*x - 9)
412            sage: u*F + v*G
413            27*x^2 + 54
414            sage: x.xgcd(P(0))
415            (1, 0, x)
416            sage: f = P(0)
417            sage: f.xgcd(x)
418            (x, 0, 1)
419            sage: F = (x-3)^3; G = (x-15)^2
420            sage: g, u, v = F.xgcd(G)
421            sage: g, u, v
422            (2985984, -432*x + 8208, 432*x^2 + 864*x + 14256)
423            sage: u*F + v*G
424            2985984
425        """
426        if not isinstance(right, Polynomial_integer_dense_ntl):
427            right = self.parent()(right)
428        elif self.parent() is not right.parent():
429            raise TypeError
430
431        cdef ZZX_c *s, *t
432        cdef ZZ_c *r
433
434        ZZX_xgcd(&self.__poly, &(<Polynomial_integer_dense_ntl>right).__poly, &r, &s, &t, 1)    # proof = 1
435        cdef Integer rr = PY_NEW(Integer)
436        ZZ_to_mpz(&rr.value, r)
437        cdef Polynomial_integer_dense_ntl ss = self._new()
438        cdef Polynomial_integer_dense_ntl tt = self._new()
439        ss.__poly = s[0]
440        tt.__poly = t[0]
441        ZZ_delete(r)
442        ZZX_delete(s)
443        ZZX_delete(t)
444
445        if rr == 0:
446            f = self.base_extend(QQ)
447            g, u, v = f.xgcd(right.base_extend(QQ))
448            d = lcm([g.denominator(), u.denominator(), v.denominator()])
449            R = self.parent()
450            return R(d*g), R(d*u), R(d*v)
451        else:
452            S = self.parent()
453            return S(rr), ss, tt
454       
455
456    cdef RingElement _mul_c_impl(self, RingElement right):
457        r"""
458        Returns self multiplied by right.
459       
460        EXAMPLES:
461            sage: R.<x> = PolynomialRing(ZZ)
462            sage: (x - 2)*(x^2 - 8*x + 16)
463            x^3 - 10*x^2 + 32*x - 32
464        """
465        cdef Polynomial_integer_dense_ntl x = self._new()
466        ZZX_mul(x.__poly, self.__poly,
467                (<Polynomial_integer_dense_ntl>right).__poly)
468        return x
469
470
471    cdef ModuleElement _lmul_c_impl(self, RingElement right):
472        r"""
473        Returns self multiplied by right, where right is a scalar (integer).
474
475        EXAMPLES:
476            sage: R.<x> = PolynomialRing(ZZ)
477            sage: x*3
478            3*x
479            sage: (2*x^2 + 4)*3
480            6*x^2 + 12
481        """
482        cdef Polynomial_integer_dense_ntl x = self._new()
483        cdef ZZ_c _right
484
485        mpz_to_ZZ(&_right, &(<Integer>right).value)
486        ZZX_mul_ZZ(x.__poly, self.__poly, _right)
487        return x
488
489
490    cdef ModuleElement _rmul_c_impl(self, RingElement right):
491        r"""
492        Returns self multiplied by right, where right is a scalar (integer).
493
494        EXAMPLES:
495            sage: R.<x> = PolynomialRing(ZZ)
496            sage: 3*x
497            3*x
498            sage: 3*(2*x^2 + 4)
499            6*x^2 + 12
500        """
501        cdef Polynomial_integer_dense_ntl x = self._new()
502        cdef ZZ_c _right
503
504        mpz_to_ZZ(&_right, &(<Integer>right).value)
505        ZZX_mul_ZZ(x.__poly, self.__poly, _right)
506        return x
507
508
509    def __floordiv__(self, right):
510        """
511        todo: write a doctest for this as soon as someone figures out
512        what it's actually supposed to do
513        """
514        if is_Polynomial(right) and right.is_constant() and right[0] in ZZ:
515            d = ZZ(right[0])
516        elif (right in self.parent().base_ring()):
517            d = ZZ(right)
518        else:
519            return Polynomial.__floordiv__(self, right)
520        return self.parent()([c // d for c in self.list()], construct=True)
521                               
522
523    def _unsafe_mutate(self, long n, value):
524        r"""
525        Sets coefficient of x^n to value.
526
527        This is very unsafe, because SAGE polynomials are supposed
528        to be immutable. (Shhhh don't tell anyone!)
529
530        EXAMPLES:
531            sage: R.<x> = PolynomialRing(ZZ)
532            sage: f = 2*x^2 + 3; f
533            2*x^2 + 3
534            sage: f._unsafe_mutate(1, 42); f
535            2*x^2 + 42*x + 3
536        """
537        n = int(n)
538        if n < 0:
539            raise IndexError, "n must be >= 0"
540        value = Integer(value)
541        cdef ZZ_c y
542        mpz_to_ZZ(&y, &(<Integer>value).value)
543        ZZX_SetCoeff(self.__poly, n, y)
544     
545
546    def real_root_intervals(self):
547        """
548        Returns isolating intervals for the real roots of this polynomial.
549
550        EXAMPLE:
551        We compute the roots of the characteristic polynomial of some Salem numbers:
552            sage: R.<x> = PolynomialRing(ZZ)
553            sage: f = 1 - x^2 - x^3 - x^4 + x^6
554            sage: f.real_root_intervals()
555            [((1/2, 3/4), 1), ((1, 3/2), 1)]
556        """
557
558        from sage.rings.polynomial.real_roots import real_roots
559
560        return real_roots(self)
561
562##     def __copy__(self):
563##         f = Polynomial_integer_dense(self.parent())
564##         f.__poly = self.__poly.copy()
565##         return f
566       
567
568    def degree(self):
569        """
570        Return the degree of this polynomial.  The zero polynomial
571        has degree -1.
572
573        EXAMPLES:
574            sage: R.<x> = PolynomialRing(ZZ)
575            sage: x.degree()
576            1
577            sage: (x^2).degree()
578            2
579            sage: R(1).degree()
580            0
581            sage: R(0).degree()
582            -1
583        """
584        return ZZX_deg(self.__poly)
585
586
587    def discriminant(self, proof=True):
588        r"""
589        Return the discriminant of self, which is by definition
590        $$
591            (-1)^{m(m-1)/2} {\mbox{\tt resultant}}(a, a')/lc(a),
592        $$
593        where m = deg(a), and lc(a) is the leading coefficient of a.
594        If proof is False (the default is True), then this function
595        may use a randomized strategy that errors with probability no
596        more than $2^{-80}$.
597
598        EXAMPLES:
599            sage: f = ntl.ZZX([1,2,0,3])
600            sage: f.discriminant()
601            -339
602            sage: f.discriminant(proof=False)
603            -339
604        """
605        cdef ZZ_c* temp = ZZX_discriminant(&self.__poly, proof)
606        cdef Integer x = PY_NEW(Integer)
607        ZZ_to_mpz(&x.value, temp)
608        ZZ_delete(temp)
609        return x
610
611                           
612    def _pari_(self, variable=None):
613        """
614        EXAMPLES:
615            sage: t = PolynomialRing(ZZ,"t").gen()
616            sage: f = t^3 + 3*t - 17
617            sage: pari(f)
618            t^3 + 3*t - 17
619        """
620        if variable is None:
621            variable = self.parent().variable_name()
622        return pari(self.list()).Polrev(variable)
623
624
625    def squarefree_decomposition(self):
626        """
627        Return the square-free decomposition of self.  This is
628        a partial factorization of self into square-free, relatively
629        prime polynomials.
630
631        This is a wrapper for the NTL function SquareFreeDecomp.
632
633        EXAMPLES:
634            sage: R.<x> = PolynomialRing(ZZ)
635            sage: p = 37 * (x-1)^2 * (x-2)^2 * (x-3)^3 * (x-4)
636            sage: p.squarefree_decomposition()
637            (37) * (x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3
638        """
639
640        cdef Polynomial_integer_dense_ntl p = self
641        c = p.content()
642        if c != 1:
643            p = self.parent()(p / c)
644       
645        cdef ZZX_c** v
646        cdef long* e
647        cdef long i, n
648        cdef Polynomial_integer_dense_ntl z
649        ZZX_squarefree_decomposition(&v, &e, &n, &p.__poly)
650        F = []
651        for i from 0 <= i < n:
652            z = self._new()
653            z.__poly = v[i][0]
654            F.append((z, e[i]))
655            ZZX_delete(v[i])
656        free(v)
657        free(e)
658        return Factorization(F, unit=c, sort=False)
659   
660
661    def factor_mod(self, p):
662        """
663        Return the factorization of self modulo the prime p.
664
665        INPUT:
666            p -- prime
667
668        OUTPUT:
669            factorization of self reduced modulo p.
670
671        EXAMPLES:
672            sage: R.<x> = ZZ['x']
673            sage: f = -3*x*(x-2)*(x-9) + x
674            sage: f.factor_mod(3)
675            x
676            sage: f = -3*x*(x-2)*(x-9)
677            sage: f.factor_mod(3)
678            Traceback (most recent call last):
679            ...
680            ValueError: factorization of 0 not defined
681           
682            sage: f = 2*x*(x-2)*(x-9)
683            sage: f.factor_mod(7)
684            (2) * x * (x + 5)^2
685        """
686        from sage.rings.finite_field import FiniteField
687        p = Integer(p)
688        if not p.is_prime():
689            raise ValueError, "p must be prime"
690        f = self._pari_()
691        if f * pari('Mod(1,%s)'%p) == pari(0):
692            raise ValueError, "factorization of 0 not defined"
693        G = f.factormod(p)
694        k = FiniteField(p)
695        R = sage.rings.polynomial.polynomial_ring.PolynomialRing(k, names=self.parent().variable_name())
696        return R(1)._factor_pari_helper(G, unit=R(self).leading_coefficient())
697       
698
699    def factor_padic(self, p, prec=10):
700        """
701        Return p-adic factorization of self to given precision.
702
703        INPUT:
704            p -- prime
705            prec -- integer; the precision
706
707        OUTPUT:
708            factorization of self reduced modulo p.
709
710        EXAMPLES:
711            sage: R.<x> = PolynomialRing(ZZ)
712            sage: f = x^2 + 1
713            sage: f.factor_padic(5, 4)
714            ((1 + O(5^4))*x + (2 + 5 + 2*5^2 + 5^3 + O(5^4))) * ((1 + O(5^4))*x + (3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4)))
715           
716        """
717        from sage.rings.padics.factory import Zp
718        p = Integer(p)
719        if not p.is_prime():
720            raise ValueError, "p must be prime"
721        prec = Integer(prec)
722        if prec <= 0:
723            raise ValueError, "prec must be positive"
724        K = Zp(p, prec, type='capped-abs')
725        R = sage.rings.polynomial.polynomial_ring.PolynomialRing(K, names=self.parent().variable_name())
726        return R(self).factor()
727     
728
729    def list(self):
730        """
731        Return a new copy of the list of the underlying
732        elements of self.
733
734        EXAMPLES:
735            sage: x = PolynomialRing(ZZ,'x').0
736            sage: f = x^3 + 3*x - 17
737            sage: f.list()
738            [-17, 3, 0, 1]
739            sage: f = PolynomialRing(ZZ,'x')(0)
740            sage: f.list()
741            []
742        """
743        return [self[i] for i in range(self.degree()+1)]
744
745
746    def resultant(self, other, proof=True):
747        """
748        Returns the resultant of self and other, which must lie in the same
749        polynomial ring.
750
751        If proof = False (the default is proof=True), then this function may use a
752        randomized strategy that errors with probability no more than $2^{-80}$.
753
754        INPUT:
755            other -- a polynomial
756
757        OUTPUT:
758            an element of the base ring of the polynomial ring
759
760        EXAMPLES:
761            sage: x = PolynomialRing(ZZ,'x').0
762            sage: f = x^3 + x + 1;  g = x^3 - x - 1
763            sage: r = f.resultant(g); r
764            -8
765            sage: r.parent() is ZZ
766            True
767        """
768        cdef Polynomial_integer_dense_ntl _other = <Polynomial_integer_dense_ntl>(self.parent()._coerce_(other))
769        cdef ZZ_c* temp = ZZX_resultant(&self.__poly, &_other.__poly, proof)
770        cdef Integer x = PY_NEW(Integer)
771        ZZ_to_mpz(&x.value, temp)
772        ZZ_delete(temp)
773        return x
Note: See TracBrowser for help on using the repository browser.