Karim BELABAS on Tue, 16 Nov 1999 13:04:48 +0100 (MET)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: Coefficients of Polynomials


[Annegret Weng:]
> I would like to use the Pari-Library. I read through the User's Guide and
> then I tried to write a small C++-program. It turned out that I still
> don't know how to build a polynomial, more precisely how to assign values
> to the coefficients of a polynomial.
> Can anyone help me? I think a small sample program would be very helpful.

Well, the library itself is a nice sample code...

If the coefficients already exist in an object x somewhere (e.g are the entries
of a PARI vector), you can use gtopoly(x, v)  [ correspond to Pol() under GP ]

To avoid chicken-egg recursion, here's how you do it "from basic principles":
the following snippet creates x^4 + 7x^3 + 2*x [ I assume you use version
2.0.* ]

{
  const long deg = 4;
  const long var = 0; /* x */
  GEN pol = cgetg(deg+3, t_POL); /* cgetg fills in the first codeword */

  /* fill the second codeword */
  pol[1] = evalsigne(1) | evalvarn(var) | evallgef(deg+3);

  pol[2] = (long)stoi(0); /* start from lowest degree term */
  pol[3] = (long)stoi(2);
  pol[4] = (long)stoi(0);
  pol[5] = (long)stoi(7);
  pol[6] = (long)stoi(1);
}
[ I could have used gun and gzero instead of stoi(1) and stoi(0) respectively,
and lstoi instead of (long)stoi ]

You can make it look nicer by using another pointer for the coefficients:
{
  const long deg = 4;
  const long var = 0;
  GEN pol = cgetg(deg+3, t_POL);
  GEN *P = (GEN*) (pol+2);

  pol[1] = evalsigne(1) | evalvarn(var) | evallgef(deg+3);
  P[0] = stoi(0);
  P[1] = stoi(2);
  P[2] = stoi(0);
  P[3] = stoi(7);
  P[4] = stoi(1);
}

Another possibility is to build the polynomial from different pieces,
starting from polx[var], but it's _much_ slower. It works nicely for
recursively defined polynomials [ I use the same polynomial; for a
non-trivial example, see cyclo() in src/basemath/bibli2.c ]

/* Inefficient, ugly, and only meant to examplify basic principles. If you
 * want efficient code, look at the library sources */
{
  const long var = 0; /* x */
  const long ltop = avma; /* record stack pointer */
  GEN pol, X = polx[var];

  pol = gpowgs(X,4);
  pol = gadd(pol, gmulsg(7, gpowgs(X,3)));
  pol = gadd(pol, gmulsg(2, X));
  pol = gerepileupto(ltop, pol); /* clean up accumulated garbage */
}

Hope this helps,

  Karim.

P.S: Since you intend to program in C++, it should be trivial to overload
operators so as to write the above simply as

  pol = X^4 + 7*X^3 + 2*X

Corresponding C++ wrappers have even be written by various people, but (I
believe) never widely distributed. You can have a look at

  http://www.math.u-bordeaux.fr/~papanik/pali.html

[PaLi also implements automatic garbage collection, at the expense of some
efficiency]. I don't share all the goals expressed in the page above, but the
project itself was interesting. It more or less died when Thomas left
Bordeaux, unfortunately.
__
Karim Belabas                    email: Karim.Belabas@math.u-psud.fr
Dep. de Mathematiques, Bat. 425
Universite Paris-Sud             Tel: (00 33) 1 69 15 57 48
F-91405 Orsay (France)           Fax: (00 33) 1 69 15 60 19
--
PARI/GP Home Page: http://hasse.mathematik.tu-muenchen.de/ntsw/pari/