使用勒让德多项式的GSL问题

问题描述 投票:1回答:1

我正在尝试使用已弃用的函数更新使用GSL版本的旧代码,但我遇到了如何使用新版本的规范化勒让德多项式函数的麻烦。这是一个总结问题的片段:

#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,它明确地需要关键字进行规范化(GSL_SF_LEGENDRE_SPHARM)并且不要求参数m。旧版本给出了一致的结果,而新版本在25 t循环后返回分段错误。你们中的任何人都可以帮我纠正代码并向我解释我做错了什么吗?

c++ gsl
1个回答
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时,使用临时变量和在调用函数之前/之后打包/解包的数组是很有用的。不是很漂亮,但不容易出错,而且由于你使用的是“plusspluss”版本的C,你总是可以将实现包装在class中。希望它是有帮助的。


编辑:

我尝试增加legendre数组的大小,程序在大小设置为时完成:

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

也许知道这些功能如何运作的人可以回答为什么......

© www.soinside.com 2019 - 2024. All rights reserved.