lagrange approximation -c ++

Geo*_*rge 2 c++ numerical

我更新了代码.我想要做的是在指针d中保持每个拉格朗日的系数值.(例如对于L1(x)d [0]将是"x-x2/x1-x2",d 1将是(x-x2/x1-x2)*(x-x3/x1-x3)等

我的问题是

1)如何初始化d(我做了d [0] =(zx [i])/(x [k] -x [i])但我认为它不对"d [0]"

2)如何初始化L_coeff.(我使用的是L_coeff = new double [0],但我不确定它是否正确.

练习是:使用5个点(x = -1,-0.5,0,0.5和1)找出y(x)= cos(πx),x∈-1,1的拉格朗日多项式近似.

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

using namespace std;

const double pi=3.14159265358979323846264338327950288;

// my function
double f(double x){

return (cos(pi*x));

}


//function to compute lagrange polynomial
double lagrange_polynomial(int N,double *x){
//N = degree of polynomial

double z,y;
double *L_coeff=new double [0];//L_coefficients of every Lagrange L_coefficient
double *d;//hold the polynomials values for every Lagrange coefficient
int k,i;
//computations for finding lagrange polynomial
//double sum=0;

for (k=0;k<N+1;k++){
        for ( i=0;i<N+1;i++){
            if (i==0) continue;
            d[0]=(z-x[i])/(x[k]-x[i]);//initialization
            if (i==k) L_coeff[k]=1.0;
            else if (i!=k){
            L_coeff[k]*=d[i];

                      }

           }

cout <<"\nL("<<k<<") = "<<d[i]<<"\t\t\tf(x)= "<<f(x[k])<<endl;
}

}

int main()
{

    double deg,result;
    double *x;


    cout <<"Give the degree of the polynomial :"<<endl;
    cin >>deg;

    for (int i=0;i<deg+1;i++){
    cout <<"\nGive the points of interpolation : "<<endl;
    cin >> x[i];
    }

    cout <<"\nThe Lagrange L_coefficients are: "<<endl;
    result=lagrange_polynomial(deg,x);



    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是拉格朗日多项式的一个例子

这是我所做的解决方案

Thi*_*ilo 6

由于这似乎是家庭作业,我不会给你一个详尽的答案,而是试着让你走上正确的轨道.

  • 你如何在计算机软件中表示多项式?您希望存档为3x ^ 3 + 5x ^ 2-4等符号表达式的直观版本对于进一步计算非常不实用.
  • 通过保存(和输出)它的系数来完全定义多项式.

你上面所做的是希望C++为你做一些代数操作,并用符号变量简化你的产品.如果没有很多努力,C++就无法做到这一点.

您有两种选择:

  • 要么使用可以进行符号操作的合适的计算机代数系统(Maple或Mathematica就是一些例子)
  • 如果您使用C++,则必须更多地考虑如何计算多项式的单个系数.您的程序输出只能是一个数字列表(当然,根据符号表达式,您可以将其格式化为漂亮的字符串).

希望这会给你一些如何开始的想法.

编辑1

您的代码中仍然有一个未定义的表达式,因为您从未设置任何值y.这留下prod*=(y-x[i])/(x[k]-x[i])了一个不会返回有意义数据的表达式.C++只能使用数字,y现在不是你的数字,但你认为它是符号.

如果要在代码中设置,可以评估 lagrange近似值,比如值.这将给你(据我现在所见)正确的函数值,但没有函数本身的描述.1y=1

也许你应该首先拿一支笔和一张纸,并尝试将表达式写为精确的数学.尝试真正掌握您想要计算的内容.如果你那样做,也许你回到这里告诉我们你的想法.这应该可以帮助您了解那里发生了什么.

永远记住:C++需要数字,而不是符号.每当你的纸上的表达式中有一个符号,你不知道你的价值时,你可以找到一种方法来计算已知值的值,或者你必须消除使用这个符号计算的需要.

PS:一次在多个讨论板上发布相同的问题并不是一种好的风格......

编辑2

现在,您在y = 0.3处评估函数.如果要评估多项式,这是要采用的方法.但是,正如您所说,您需要多项式的所有系数.

再一次,我仍然觉得你不明白问题背后的数学.也许我会给你一个小例子.我将使用维基百科文章中使用的符号.

假设我们有k = 2和x = -1,1.此外,为了简单起见,让我的名字命名你的cos函数f.(如果没有乳胶,符号会变得相当难看......)然后将拉格朗日多项式定义为

f(x_0) * l_0(x) + f(x_1)*l_1(x)
Run Code Online (Sandbox Code Playgroud)

在哪里(通过象征性的再次简化)

l_0(x)= (x - x_1)/(x_0 - x_1) = -1/2 * (x-1) = -1/2 *x  + 1/2
l_1(x)= (x - x_0)/(x_1 - x_0) = 1/2 * (x+1)  = 1/2 * x  + 1/2
Run Code Online (Sandbox Code Playgroud)

所以,你拉格朗日多项式是

  f(x_0) * (-1/2 *x  + 1/2) + f(x_1) * 1/2 * x  + 1/2
= 1/2 * (f(x_1) - f(x_0)) * x     +     1/2 * (f(x_0) + f(x_1))
Run Code Online (Sandbox Code Playgroud)

因此,您想要计算的系数将是1/2*(f(x_1) - f(x_0))和1/2*(f(x_0)+ f(x_1)).

你现在的任务是找到一个算法来完成我所做的简化,但不使用符号.如果您知道如何计算l_j的系数,那么基本上就完成了,因为您可以将那些乘以相应的f值相加.

因此,即使进一步细分,您也必须找到一种方法,在逐个组件的基础上将l_j中的商相互相乘.弄清楚这是如何完成的,你几乎完成了.

编辑3

好的,让我们不要那么模糊.

我们首先想要计算L_i(x).这些只是线性函数的产物.如前所述,我们必须将每个多项式表示为系数数组.为了好的风格,我将使用std::vector而不是这个数组.然后,我们可以定义包含L_1(x)系数的数据结构,如下所示:

std::vector L1 = std::vector(5); 
// Lets assume our polynomial would then have the form 
// L1[0] + L2[1]*x^1 + L2[2]*x^2 + L2[3]*x^3 + L2[4]*x^4
Run Code Online (Sandbox Code Playgroud)

现在我们想用值填充这个多项式.

// First we have start with the polynomial 1 (which is of degree 0)
// Therefore set L1 accordingly:
L1[0] = 1;
L1[1] = 0; L1[2] = 0; L1[3] = 0; L1[4] = 0;
// Of course you could do this more elegant (using std::vectors constructor, for example)
for (int i = 0; i < N+1; ++i) {
    if (i==0) continue;  /// For i=0, there will be no polynomial multiplication
    // Otherwise, we have to multiply L1 with the polynomial
    // (x - x[i]) / (x[0] - x[i])
    // First, note that (x[0] - x[i]) ist just a scalar; we will save it:
    double c = (x[0] - x[i]);
    // Now we multiply L_1 first with (x-x[1]). How does this multiplication change our 
    // coefficients? Easy enough: The coefficient of x^1 for example is just
    // L1[0] - L1[1] * x[1]. Other coefficients are done similary. Futhermore, we have
    // to divide by c, which leaves our coefficient as
    // (L1[0] - L1[1] * x[1])/c. Let's apply this to the vector:
    L1[4] = (L1[3] - L1[4] * x[1])/c;
    L1[3] = (L1[2] - L1[3] * x[1])/c;
    L1[2] = (L1[1] - L1[2] * x[1])/c;
    L1[1] = (L1[0] - L1[1] * x[1])/c;
    L1[0] = (      - L1[0] * x[1])/c; 
    // There we are, polynomial updated.
}
Run Code Online (Sandbox Code Playgroud)

当然,这必须对所有L_i进行.之后,必须添加L_i并与函数相乘.那是你要弄明白的.(请注意,我在那里做了很多低效的东西,但我希望这可以帮助你更好地理解细节.)

希望这能让您了解如何继续.