0

所以我想用 gp 从一个特定的 projecteuler 问题中计算一个总和。这是不可理解的代码:

{
n = 10000;
m=100;
sum(k=1,n,eulerphi(k),0.) - (sum(k=1,n,eulerphi(k)*(k * binomial(n-k,m-1) + sum(p = max(m + k - n - 1,1), k-1, (k-p)*binomial(n+p-k-1,m-2),0.)), 0.))/binomial(n,m)
}

这段代码需要两到三分钟才能在我相当普通的机器上输出答案,但它不会超出默认值parisize = 8000000(大约 8 MB 内存)。

现在,我在某处读到将脚本gp2c编译为代码可以提高性能的文章。gpc

所以我只是做了一个program.gp文件:

calculate() = {n = 10000; m=100; sum(k=1,n,eulerphi(k),0.) - (sum(k=1,n,eulerphi(k)*(k * binomial(n-k,m-1) + sum(p = max(m + k - n - 1,1), k-1, (k-p)*binomial(n+p-k-1,m-2),0.)), 0.))/binomial(n,m)}

并运行它gp2c-run program.gp

在出现的交互式提示中,我刚刚执行了calculate(). 然而,令我惊讶的是,我得到了一个堆栈溢出,它要求我增加堆栈大小,即使我更改parisizemax为几乎 2 GB。

? default(parisizemax, 2000000000)
  ***   Warning: new maximum stack size = 2000003072 (1907.352 Mbytes).
? calculate()
  *** calculate: Warning: increasing stack size to 16000000.
  *** calculate: Warning: increasing stack size to 32000000.
  *** calculate: Warning: increasing stack size to 64000000.
  *** calculate: Warning: increasing stack size to 128000000.
  *** calculate: Warning: increasing stack size to 256000000.
  *** calculate: Warning: increasing stack size to 512000000.
  *** calculate: Warning: increasing stack size to 1024000000.
  *** calculate: Warning: increasing stack size to 2000003072.
  ***   at top-level: calculate()
  ***                 ^-----------
  *** calculate: the PARI stack overflows !
  current stack size: 2000003072 (1907.352 Mbytes)
  [hint] you can increase 'parisizemax' using default()

  ***   Break loop: type 'break' to go back to GP prompt

为什么同一个程序在编译时c需要这么多额外的内存?作为参考,使用 n = 1000 而不是 10000 的同一程序仅在将堆栈大小增加到256000000(250 MB) 后才显示答案,而仅在使用gp. 有些东西没有加起来。

4

1 回答 1

2

默认情况下,既不gp2c也不gp2c-run生成代码来处理 PARI 堆栈,这意味着您将很快得到堆栈溢出。使用gp2c-run -g program.gp:该-g标志将导致gp2c随着计算的进行清理堆栈。gp2c 教程中有这样一个例子。

于 2021-07-24T18:16:06.457 回答