错误的参数错误,实现了数字配方功能

时间:2015-06-03 20:17:55

标签: c function

编辑:这是一个拼写错误。我写了1一个,但它应该是l。谢谢大家!

我讨厌在SO上问这样的n00b问题,但是我想编写一个简单的程序来检查由Press,Teukolsky等编写的Numerical Recipes中的函数。我对使用C有点缺乏经验,所以这可能是完全明显的。 (请耐心等待!)

有问题的函数是特殊函数章节中的相关legendre多项式。我已在下面的代码中详细记录了这一点。但是,似乎我不明白如何正确调用函数。在使用$ ./a.out进行编译后使用gcc program.c运行以下程序时,出现以下错误:

Run time error....
Bad arguments in routine plgndr
Now exiting the system

我猜这很明显,但到目前为止我还没有想到这一点。在这个问题之后我应该更好地理解C,即使它对其他SO读者没有帮助......

nrerror函数是Numerical Recipes系列的标准,可以在附录B中找到。这是我的代码(原因是开头的广泛评论):

/* Recurrence relation, Legendre polynomial

 Numerical recipes in C, 1992
 Press, Flannery, Teukolsky, Vetterling

 Chapter 6., Special Functions, 
 Section 6.8 Spherical Harmonics, p.252-254

 The Legendre polynomial recurrence relation is written as

 (n+1)*P_{n+1}(x)=(2n+1)*x*P_n(x)-n*P_{n-1}(x)

 float plgndr(int l, int m, float x)
 Computes the associated Legendre polynomial P^m_l(x). Here m and l
 are integers satisfying 0<=m<=l, while x lies in the range
 -1<=x<=1.

 P(0,x) = 1
 P(1,x) = x
 P(n,x) = (2*n-1)/n * x * P(n-1,x) - (n-1)/n * P(n-2,x)

*/

#include <stdio.h>    // standard file input and output header
#include <stdlib.h>   // utility functons such as malloc() and rand()
#include <string.h>
#include <math.h>     // mathematical functions such as sin() and cos()}
#include <stddef.h>   // for error function

/* function declarations */
void nrerror(char error_text[]);
double plgndr(int l, int m, double x);


/* program begins */
int main(void)
{
    int l=2; /* Asign values to variables here */
    int m=2;
    double x=0.5;  // x must be between -1 and 1
    plgndr(l,m,x);
    return 0;
}

/* functions */
void nrerror(char error_text[]) //Numerical Recipes standard error handler
{
    fprintf(stderr, "Run time error....\n");
    fprintf(stderr, "%s\n", error_text);
    fprintf(stderr, "Now exiting the system\n");
    exit(1);
}
double plgndr(int l, int m, double x) //originally written as float
/* Computes the associated Legendre polynomial P^m_l(x). Here m and l
   are integers satisfying 0<=m<=l, while x lies in
   the range -1<=x<=1. */
{
    void nrerror(char error_text[]);
    double fact,pll,pmm,pmmp1,somx2;
    int i,ll;

    if (m < 0 || m > 1 || fabs(x) > 1.0)
        nrerror("Bad arguments in routine plgndr");
    pmm=1.0;          //Compute P^m_m
    if (m > 0){
        somx2=sqrt((1.0-x)*(1.0+x));
        fact=1.0;
        for (i=1; i<=m; i++){
            pmm *= -fact*somx2;
            fact += 2.0;
        }
    }
    if (l == m)
        return pmm;
    else{             //Compute P^m_{m+1}
        pmmp1=x*(2*m+1)*pmm;
        if (l == (m+1))
            return pmmp1;
        else {         //Compute P^m_l, l > m+1
            for (ll=m+2; ll<=l; ll++){
                pll=(x*(2*ll-1)*pmmp1-(ll+m-1)*pmm)/(ll-m);
                pmm=pmmp1;
                pmmp1=pll;
            }
            return pll;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

根据plgndr()定义旁边的评论,

  

(...)m和l是满足0 <= m <= 1的整数,而x位于   范围-1&lt; = x&lt; = 1。

更新plgndr()中的以下行:

if (m < 0 || m > 1 || fabs(x) > 1.0)

if (m < 0 || m > l || fabs(x) > 1.0)
/*               ^                */
/*           (l, not 1)           */

这是一个愚蠢的错字。通过此更改,代码不会崩溃,但我无法以数学方式验证它。

答案 1 :(得分:0)

  

而x位于-1 <= x <= 1

的范围内

double x=2.0;

double plgndr(int l, int m, double x) //originally written as float
/* ... while x lies in   the range -1<=x<=1. */
{

...

if (m < 0 || m > 1 || fabs(x) > 1.0)
    nrerror("Bad arguments in routine plgndr");  // fail