使用Legendre多项式的GSL问题

时间:2019-04-10 08:08:27

标签: c++ gsl

我正在尝试更新一个旧版本的代码,该代码使用的GSL版本已弃用函数,但是我很难找到如何使用标准化的Legendre多项式函数的新版本。这是一个总结问题的代码段:

#include <iostream>
#include <gsl/gsl_sf_legendre.h>
#include <cmath>

#define GSL_NEW

using namespace std;

int main() {

  int order = 17;
  int ntheta = 36;
  double theta_step = M_PI / ntheta;
  double c, theta;
  double legendre[ntheta][order+1];

  for( int m = 0; m <= order; m += 2) {
    for(int l = m; l <= ntheta; l += 2 ) {
      for( int t = 0; t < ntheta; t++ ) {
        theta = ( ntheta + 0.5 ) * theta_step;
        c = cos(theta);

        if( l == m ) {
#ifdef GSL_NEW
          gsl_sf_legendre_array( GSL_SF_LEGENDRE_SPHARM, order, c, &legendre[t][l] );
          cout << legendre[t][l] << endl;
#else
          gsl_sf_legendre_sphPlm_array(order, m, c, &legendre[t][l] );
          cout << legendre[t][l] << endl;
#endif
        }
      }
    }
  }
}

当我使用GSL 1.9进行编译时,我使用了不赞成使用的函数gsl_sf_legendre_sphPlm_array,而当我使用GSL 2.5进行计算时,我使用了新函数gsl_sf_legendre_array,该函数显然需要使用关键字进行规范化({{1} }),并且不要求参数GSL_SF_LEGENDRE_SPHARM。旧版本为我提供了一致的结果,而新版本则在25 t循环后返回了分段错误。你们中的任何人都可以帮助我更正代码并向我解释我做错了什么吗?

1 个答案:

答案 0 :(得分:1)

我尝试使用调试符号进行编译(以下命令中的-g标志假定您的程序称为“ main.cpp”)

usr@cmptr $ g++ -g main.cpp -lgsl -lgslcblas -lm -o main

然后使用调试器运行程序,例如gdb(GNU调试器):

usr@cmptr $ gdb main
(gdb) run main
Starting program: /home/usr/Desktop/main 
0, 0, 0.282095
1, 0, 0.282095
2, 0, 0.282095
3, 0, 0.282095
4, 0, 0.282095
5, 0, 0.282095
6, 0, 0.282095
7, 0, 0.282095
8, 0, 0.282095
9, 0, 0.282095
10, 0, 0.282095
11, 0, 0.282095
12, 0, 0.282095
13, 0, 0.282095
14, 0, 0.282095
15, 0, 0.282095
16, 0, 0.282095
17, 0, 0.282095
18, 0, 0.282095
19, 0, 0.282095
20, 0, 0.282095
21, 0, 0.282095
22, 0, 0.282095
23, 0, 0.282095
24, 0, 0.282095

Program received signal SIGSEGV, Segmentation fault.
0x0000555555554ded in main () at main.cpp:26
26            cout << t << ", " << l << ", " << legendre[t][l] << endl;
(gdb) quit

该错误在您写入屏幕的第26行中。原因可能是您试图超出范围访问阵列。也许看看如何在manual for gsl Legendre polynomials中“适当地”分配内存。我特别在考虑功能gsl_sf_legendre_array_ngsl_sf_legendre_array_index

  

注意:   我自己没有使用过GSL的这一部分,但是我通常会发现,使用GSL时,使用在调用函数之前/之后打包/解压缩的临时变量和数组会很有用。它不是很漂亮,但是出错的可能性较小,并且由于您使用的是C的“ plusspluss”版本,因此您始终可以将实现包装在class中。   希望它会有所帮助。


编辑:

我尝试增加legendre数组的大小,并且将大小设置为以下值时程序完成:

double legendre[ntheta + 10][order + 4];

也许有人知道函数的工作原理可以回答为什么...