### bind stack overflow in loop

Edwin Woollett <woollett <at> charter.net>

2014-08-16 21:36:00 GMT

I am trying to understand what is causing a lisp
error "bind stack overflow" in a simple loop, in which
the only "dangerous" thing I am doing is storing
values in a one dimensional array. (see code below).
Here is the maxima session (windows xp)
---------------------------------------------------------------------
Maxima 5.31.2 http://maxima.sourceforge.net
using Lisp GNU Common Lisp (GCL) GCL 2.6.8 (a.k.a. GCL)
(%i1) load(poisson3);
(%o1) "c:/k3/poisson3.mac"
(%i2) arrays;
(%o2) []
(%i3) outL : poisson3(25,0.002,0.95,5)$
array phiL defined
r exact diff
start numerov loop
2001 2002 2003 2004 2005
Maxima encountered a Lisp error:
Error in PROGN [or a callee]: Bind stack overflow.
Automatically continuing.
To enable the Lisp debugger set *debugger-hook* to nil.
(%i4) arrays;
(%o4) [phiL]
(%i5) for j:10500 thru 10494 step -1 do print(phiL[j])$
0.95
0.95
0.95
0.95
0.95
0.95
0.0
(%i6) phiL[10500];
(%o6) 0.95
(%i7) fpprintprec;
(%o7) 8
(%i8) phiL[12500];
(%o8) 0.95
(%i9)
=================================================
and here is the code file poisson3.mac
/* poisson3(rmax,h,frac,rprint) for inward integration of poisson's
equation without correction from r = rmax to r = 0 with step size h.
If frac > 0, uses frac times exact solution to get the first two points
at rmax and rmax-h; if frac < 0 uses phi = 1 at first two
points.
The (dimensionless) charge density is taken to be exp(-r)*/8/*%pi.
Values of phi internally are kept in the array phiL; declared arrays are
global objects until removed from memory using remarray.
The output is a list [rrL, phiL_list] in which rrL and phiL_list are
lists
created using makelist.
At intervals rprint, values of r, exact, and diff_phi are printed to the
screen
using the formated print function printf.
this version has debug printouts since lisp error "bind stack overflow"
occurs
when j = 2005.
*/
poisson3(rmax,h,frac, rprint) :=
block([phi_m,phi_z,phi_p,Sm,Sz,Sp, fac, phiL_list, num,
rrL,rr,exact, diff_phi, nprint, nstep, numer],numer:true,
local(phi_exact,S),
phi_exact(r) := 1 - (r+2)*exp(-r)/2,
S(r) := -r*exp(-r)/2,
if frac < 0 then (
phi_p : 1,
phi_z : 1)
else (
phi_p : frac*phi_exact(rmax),
phi_z : frac*phi_exact(rmax - h)),
Sp : S(rmax),
Sz : S(rmax - h),
fac : h^2/(12),
num : round (rmax/h), /* total number of steps to take */
/* create an array with num+1 elements, array indexing starts with 0,
phiL[0] = phi(r=0), phiL[n] = phi(r=n*h), phiL[num] = phi(rmax)
phiL holds all phi values */
array(phiL, flonum, num + 1), /* floating point number array
*/
print(" array phiL defined "),
phiL[num] : phi_p, /* phi( r = rmax ) */
phiL[num - 1] : phi_z, /* phi(r = rmax - h) */
nprint : round(rprint/h), /* number of steps between
printing */
nstep : 2, /* current value of nstep */
printf(true,"~&~2t~a~10t~a~28t~a","r","exact","diff"),
print(" start numerov loop "),
for j:2 thru num do (
if j > 2000 then printf(true," ~d", j),
rr : rmax - j*h, /* for j=2, rr = rmax - 2*h */
Sm : S(rr),
phi_m : 2*phi_z - phi_p + fac*(Sm + 10*Sz + Sp),
phiL[num - j] : phi_m,
if is(equal(nstep,nprint)) then (
exact : phi_exact(rr),
diff_phi : exact - phi_m,
/* print(" ",rr," ",exact," ",diff_phi), */
printf(true, "~&~2t~d~9t~9f~27t~15e ", rr, exact, diff_phi),
nstep : 0),
nstep : nstep + 1,
Sp : Sz, /* rotate values for Numerov
method */
Sz : Sm,
phi_p : phi_z,
phi_z : phi_m),
print(" make lists "),
rrL : makelist(j*h, j, 0, num), /* return lists of length
num+1 */
phiL_list : makelist(phiL[j], j, 0, num),
remarray(phiL), /* remove array from
memory */
[rrL, phiL_list])$
fpprintprec : 8$
========================
Ted Woollett
woollett <at> charter.net
------------------------------------------------------------------------------