在c ++中的gauss-legendre

时间:2011-03-16 18:18:12

标签: c++ numerical

我正在尝试根据以下算法创建gauss-legendre代码:

获得n分 for n points

也就是说,它创建了一个2n方程系统(如果我们要求对2n-1阶的多项式精确,

ti是n阶的legendre多项式的根。给出了传说中的poynominals:

和wi:

我的代码是:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <cmath>


using namespace std;

const double pi=3.14;


//my function with limits (-1,1)
double f(double x){
double y;
y=(pi/4.0)*(log((pi*(x+1.0))/4.0 +1.0));
return y;

}

double legendre (int n){

    double *L,*w,*t;
    double x,sum1,sum2,result;
    L=new double [n];
    w=new double [n];
    t=new double [n];


        while(n<10){

         L[0]=1;
         L[1]=x;


        //legendre coef
        for (int i=1;i<=10;i++){
        L[i+1]=((2.0*i+1.0)*x*L[i] - i*L[i-1])/(i+1.0);


        }

        //weights w
        w=0;
        for (int i=1;i<=10;i++){
        w[i]+=(2.0*(1.0-x*x))/(i*i*(L[i-1]*L[i-1]));
        }


        //sums  w*t
        for (int i=1;i<=10;i++){
            sum1=0.0; //for k=1,3,5,2n-1
            for (int k=1;k<=2*n-1;k+=2){
                sum1+=w[i]*(pow(t[i],k));
            }
                sum1=0;
                sum2=0.0;//for k=0,2,4,2n-2
                for(int k=0;k<=2*n-2;k+=2){
                    sum2+=w[i]*(pow(t[i],k));
                }
                sum2=2.0/n;
        }


    }

    result=w*f(*t);

    return result;

}


int main()
{
    double eps=1e-8;//accuracy
    double exact=0.8565899396;//exact solution for the integral
    double error=1.0;
    double result;

    int n=1;//initial point


    while (fabs(result-exact)>eps) {
        result=legendre(n);
        cout <<"\nFor n = "<<n<<",error = "<<fabs(error-exact)<<",value = "<<result;

    n++;
    }

    return 0;
}

我的问题是:

1)编译器给我:错误:类型'double *'和'double'到二进制'operator *'的无效操作数 - &gt; at result = w * f(* t);

2)我不确定我是否完成了整个事情。我的意思是,如果我把所有的东西组合在一起,如果我实现了算法。

4 个答案:

答案 0 :(得分:2)

w是一个指针,你试图将它与某个东西相乘......你必须使用索引

w[index] * f(*t)

*t也是t数组的第一个元素。这是你的意思吗?

答案 1 :(得分:2)

我不知道算法,但你的代码错了。
第一:

        while(n<10)
        {
         L[0]=1;
         L[1]=x;
        //legendre coef
        for (int i=1;i<=10;i++){
        L[i+1]=((2.0*i+1.0)*x*L[i] - i*L[i-1])/(i+1.0);
        }

你必须改变n的值(增量,减量等),否则这是一个无限循环。

第二:

//weights w
    w=0;
    for (int i=1;i<=10;i++){
    w[i]+=(2.0*(1.0-x*x))/(i*i*(L[i-1]*L[i-1]));
    }

w是一个指针。如果要重置它,请使用memset(w,0,sizeof(double)*n);不要使其等于0.

最后:

result=w*f(*t);

由于您使用wt指针作为数组,因此必须提供某种类型的索引,例如result=w[ind] * f(t[ind]);。在这里,您只是将指针w的值乘以而不是w所指向的值(顺便提一下,w的值为0),第一个值为t指向的双数组。

此外,我的代码与问题中的公式之间没有任何关系。所以我的谦虚建议就是不要使用C或C ++。如果必须,那么不要使用指针,因为它似乎你不熟悉它们。你可以很容易地使用std :: vector而不是指针。

答案 2 :(得分:1)

关于算法,x(横坐标值)应该是勒让德多项式的零。我没有看到你在任何地方定义它们。定义它们有点痛苦。我正在做类似的事情,发现这个(它是一个Matlab文件,而不是一个C ++文件)定义了N xi和wi值。该算法工作正常:http://www.mathworks.com/matlabcentral/fileexchange/4540-legendre-gauss-quadrature-weights-and-nodes

答案 3 :(得分:1)

alglibgsl都实现了高斯求积法。两者都是GPL许可证。