Michael Stoll on Sun, 19 Apr 1998 21:41:50 +0200

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

A few bugs and suggestions

Here a a few bugs in pari-2.0.7-alpha.

(1) gp> truncate(1/2+O(2))
    %1 = 0

Patch (keeping mulii() if possible for the sake of efficiency):
*** gen3.c.orig Sun Apr 19 15:33:15 1998
--- gen3.c      Sun Apr 19 20:55:47 1998
*** 1699,1703 ****
  gtrunc(GEN x)
!   long tx=typ(x),av,tetpil,i;
    GEN y;

--- 1699,1703 ----
  gtrunc(GEN x)
!   long tx=typ(x),av,tetpil,i,v;
    GEN y;

*** 1715,1720 ****
      case t_PADIC:
        if (!signe(x[4])) return gzero;
!       av=avma; y=gpuigs((GEN)x[2],valp(x)); tetpil=avma;
!       return gerepile(av,tetpil, mulii(y,(GEN)x[4]));

      case t_RFRAC: case t_RFRACN:
--- 1715,1731 ----
      case t_PADIC:
        if (!signe(x[4])) return gzero;
!       av=avma; v=valp(x);
!       if (v>=0) /* p^v is an integer */
!       {
!         y=gpuigs((GEN)x[2],v); tetpil=avma;
!         return gerepile(av,tetpil,mulii(y,(GEN)x[4]));
!       }
!       else /* result is fraction x[4]/p^(-v);
!               should already be in lowest terms */
!       { y=cgetg(3,t_FRAC);
!         y[1]=lcopy((GEN)x[4]);
!         y[2]=lpuigs((GEN)x[2],-v); tetpil=avma;
!         return gerepile(av,tetpil,y);
!       }

      case t_RFRAC: case t_RFRACN:

(2) gp> polresultant(u+v,u-v,v)
    %4 = x + u
    gp> polresultant(u+v,u-v)
    %5 = 2*u

Patch (this was an easy one, although it took me some time to find it):
*** polarit2.c.orig     Sun Apr 19 15:57:16 1998
--- polarit2.c  Sun Apr 19 20:30:05 1998
*** 1725,1731 ****
    if (v >= 0)
      x = fix_pol(x,v, &m);
!     y = fix_pol(x,v, &m);
--- 1725,1731 ----
    if (v >= 0)
      x = fix_pol(x,v, &m);
!     y = fix_pol(y,v, &m);

Now for the suggestions:

(3) Is there anybody out there who hasn't yet cursed gp while writing
    statements like
      subst(subst(subst(subst(......subst(expr,v1,e1),v2,e2),.....)  ?
    It would be much nicer to simply write
    (with the substitution done in parallel, of course!). This will require
    some rewriting of gsubst(). The best thing to do probably is to order
    the variables v1,v2,.... first.

(4) Consider the following gp code.
      expr = v^2+v+1;
      test1(a  /* local: */ ,v,u) = v = a^2; u = eval(expr); test2(u)
      test2(u) = subst(expr,v,u)
    (Admittedly, this doesn't make much sense, but you get the idea...)
      gp> test1(1)
      ***   variable name expected: subst(expr,v,u)
    Why? This is because v is bound by test1 (this would even happen if
    we don't use v in test1 at all) and this binding is in effect when
    test2 is called. This is the kind of non-local effect (you can't detect
    it from looking at the definition of test2) that is a typical problem of
    dynamically bound variables.
    Now it would be fine to have lexically scoped variables in gp, but this
    is quite obviously not within reach. Instead I suggest to introduce
    a construct that takes a variable name and returns the corresponding
    variable unevaluated. I suggest the name quote for it, and 'a would be
    a convenient shorthand for quote(a) (ever heard of Lisp?). Note that
    this can't be a function, but belongs with for,if,vector and friends.

(5)   gp> valuation(0,5)
        ***   zero argument in gval.
    This might be OK (but is a nuisance quite often), but the following is
      gp> valuation([1,2,3,0],5)
        ***   zero argument in gval.
    (Strangely enough, it does work for polynomials that contain zero coeffs.)
    I suggest replacing line 667 in gen2.c
        if (isexactzero(x)) err(talker,"zero argument in gval");
        if (isexactzero(x)) reteurn VERYBIGINT;
    (compare padicprec). If there are objections, then I'd suggest
    introducing a flag to switch between the two behaviours.

That much for today --