Bill Allombert on Tue, 06 Feb 2024 00:54:30 +0100


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

Re: What explains this discrepancy in concat()?


On Tue, Feb 06, 2024 at 10:29:57AM +1100, Joe Slater wrote:
> I have a large matrix, the cells of each may be filled by a vector. It
> seems that concat() works very differently when called within a function:
> 
> > k(m,c=1)=concat(m[,c])
> %62 = (m,c=1)->concat(m[,c])
> > s1=k(a,15);
>   ***   Warning: increasing stack size to 400000000.
>   ***   Warning: increasing stack size to 800000000.
> time = 203 ms.
> > s2=concat(a[,15]);
> time = 78 ms.
> > s1==s2
> time = 32 ms.
> %65 = 1
> 
> What's going on here?

s1=k(a,15) requires GP to copy 'a' in case k() modifies it!
(imagine k is k(m,c=1)=a=0;concat(m[,c]). m[,c] would fail
because at this point m=0!).

There are two possible work-around:

1/ declare 'a' with my() so that k cannot possibly modify a
since it is not in scope of k.

2/ use k(~a,15) which skips the copy.

You get a warning 'compiler generates copy' if default(debug) is not 0:

? k(m,c=1)=concat(m[,c]);
? \g1
   debug = 1
? a=mathilbert(500); k(a,15);
  ***   Warning: compiler generates copy for `a'.
  *** mathilbert: Warning: increasing stack size to 16000000.
  ***   Warning: increasing stack size to 32000000.
  ***   Warning: increasing stack size to 64000000.
? my(a=mathilbert(500)); k(a,15);
  *** mathilbert: Warning: increasing stack size to 16000000.
? a=mathilbert(500); k(~a,15);
  *** mathilbert: Warning: increasing stack size to 16000000.

Cheers,
Bill.