Joe Slater
Joe Slater

Reputation: 115

How can I concatenate vectors and/or exchange variable references in Pari/GP with less overhead?

I'm trying to improve the existing Pari/GP program for generating the elements of A060322. My code is much faster than the existing program, but a lot of stack and a fair amount of time is wasted with concatenating vectors and exchanging the contents of variables that refer to them. Is there a way to do this with less overhead?

A060322(N) = {
    my(a=Vec([1, 1, 1, 1, 2], N), p=[], q=[5]); 
    for(n=6, N, 
        r=concat([
                  [4*x+1 | x<-p],
                  [4*x\3 | x<-p, 1==x%6],
                  [2*x\3 | x<-q, 5==x%6]
                 ]);
        a[n]=a[n-1]+#r; 
        p=q; 
        q=r);
        a 
    }

So far my only thought is to use a three-element vector of vectors instead of the three vectors (p,q,r), and reference each vector by a changing index rather than copy between them - but that's clumsy, and I would still have the problem of concatenation.

Upvotes: 0

Views: 25

Answers (1)

Charles
Charles

Reputation: 11479

Generally, concat is pretty inefficient. You could see if Lists are better for your use case. I would try

A060322(N)=
{
  my(a=Vec([1, 1, 1, 1, 2], N), p=[], q=[5]); 
  for(n=6, N,
    my(r=List());
    for(i=1,#p,
      listput(r, 4*p[i]+1);
      p[i]%6==1 && listput(r, 4*p[i]\3);
    );
    for(i=1,#q,
      q[i]%6==5 && listput(r, 2*q[i]\3);
    );
    a[n]=a[n-1]+#r; 
    p=q; 
    q=r
  );
  a;
}

and see if that's better. But it looks like you have some pretty hefty vectors to carry around, so you'd probably be better off seeing if you could use vectorsmall (or code in C).

Upvotes: 0

Related Questions