Bill Allombert on Thu, 19 May 2005 11:09:23 +0200


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

Re: fordiv() memory hungry


On Thu, May 19, 2005 at 12:06:53AM -0700, Phil Carmody wrote:
> --- Igor Schein <igor@txc.com> wrote:
> > On Thu, May 19, 2005 at 12:44:03AM +0200, Bill Allombert wrote:
> > > On Wed, May 18, 2005 at 06:01:09PM -0400, Igor Schein wrote:
> > > > Hi,
> > > > 
> > > > (17:51:45) gp> fordiv(32!,x,0)
> > > >   *** fordiv: the PARI stack overflows !
> > > >   current stack size: 256000000 (244.141 Mbytes)
> > > >   [hint] you can increase GP stack with allocatemem()
> > > > 
> > > > Looks like fordiv() is no improvement over divisors() by virtue of
> > > > having to create the whole static array first.  Is it possible to make
> > > > fordiv() more memory-effcient without sacrificing the speed?
> > > 
> > > Depends if you insist about having the divisors in increasing order.
> > > If you don't, you can use forvec() instead.
> > 
> > I can't figure out how to use forvec() to obtain an unsorted list of
> > divisors.  Is it possible?
> 
> The fine manual says all you need:
> 
> ? ?forvec
> forvec(x=v,seq,{flag=0}): v being a vector of two-component vectors of length
> n, the sequence is evaluated with x[i] going from v[i][1] to v[i][2] for
> i=n,..,1 if flag is zero or omitted. If flag = 1 (resp. flag = 2), restrict to
> increasing (resp. strictly increasing) sequences.

... and the nice FAQ says: 
<http://www.math.u-psud.fr/~belabas/pari/doc/faq.html#loopdiv>
which give you the solution:

loopdiv(N)=
{ local(P, E);

  P = factor(N); E = P[,2]; P = P[,1]; 
  forvec( v = vector(length(E), i, [0,E[i]]),
    d = factorback(P, v);
    print(d);\\ or whatever you want to do with d
  );  
}

Cheers,
Bill.