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 but 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); } switch(flag) { --- 1725,1731 ---- if (v >= 0) { x = fix_pol(x,v, &m); ! y = fix_pol(y,v, &m); } switch(flag) { 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 subst(expr,[v1,v2,....],[e1,e2,....]) (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...) Now 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 not. 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"); with 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 -- Michael