NA-PTA-NA Lab7 正交多项式拟合的免病态方法

Orthogonal Polynomials Approximation

在这里插入图片描述
Format of function:

int OPA( double (*f)(double t), int m, double x[], double w[], double c[], double *eps );

在这里插入图片描述

Sample program of judge:

#include <stdio.h>
#include <math.h>

#define MAX_m 200
#define MAX_n 5

double f1(double x)
{
    return sin(x);
}

double f2(double x)
{
    return exp(x);
}

int OPA( double (*f)(double t), int m, double x[], double w[], double c[], double *eps );

void print_results( int n, double c[], double eps)
{    
    int i;

    printf("%d\n", n);
    for (i=0; i<=n; i++)
        printf("%12.4e ", c[i]);
    printf("\n");
    printf("error = %9.2e\n", eps);
    printf("\n");
}

int main()
{
    int m, i, n;
    double x[MAX_m], w[MAX_m], c[MAX_n+1], eps;

    m = 90;
    for (i=0; i<m; i++) {
        x[i] = 3.1415926535897932 * (double)(i+1) / 180.0;
        w[i] = 1.0;
    }
    eps = 0.001;
    n = OPA(f1, m, x, w, c, &eps);
    print_results(n, c, eps);

    m = 200;
    for (i=0; i<m; i++) {
        x[i] = 0.01*(double)i;
        w[i] = 1.0;
    }
    eps = 0.001;
    n = OPA(f2, m, x, w, c, &eps);
    print_results(n, c, eps);

    return 0;
}

/* Your function will be put here */

Sample Output:

3
 -2.5301e-03   1.0287e+00  -7.2279e-02  -1.1287e-01 
error =  6.33e-05

4
  1.0025e+00   9.6180e-01   6.2900e-01   7.0907e-03   1.1792e-01 
error =  1.62e-04

在这里插入图片描述
My Answer:
这个代码还有两个点没过,但是不知道为什么。

#include <string.h>
#include <stdlib.h>
int M;
double W[MAX_m];

double myPow(double x, int n)
{
	double res = 1.0;
	while (n--) res *= x;
	return res;
}
double CalculatePoly(double poly[], double x)
{
	double res = 0;
	for (int i = 0; i < MAX_n + 1; i++)
		res += poly[i] * myPow(x, i);
	return res;
}

double InnerProd_yy(double y[])
{	// y直接提供第一二个基函数值
	double sum = 0;
	for (int i = 0; i < M; i++) 
		sum += W[i] * y[i] * y[i];
	return sum;
}
double InnerProd_y(double poly1[], double x[], double y[])
{	// f的系数在x[]求值提供第一个基函数值  y直接提供第二个基函数值
	double sum = 0;
	for (int i = 0; i < M; i++) 
		sum += W[i] * CalculatePoly(poly1, x[i]) * y[i];
	return sum;
}
double InnerProd(double poly1[], double poly2[], double x[])
{	// f的系数在x[]求值提供第一个基函数值  g的系数在x[]求值提供第二个基函数值
	double sum = 0;
	for (int i = 0; i < M; i++) 
		sum += W[i] * CalculatePoly(poly1, x[i]) * CalculatePoly(poly2, x[i]);
	return sum;
}
 poly deal /
double* x_Mul_Poly(double poly[])
{
	double* new_poly = (double*)malloc((MAX_n + 1) * sizeof(double));

	for (int i = MAX_n; i >= 1; i--) 
		new_poly[i] = poly[i - 1];
	new_poly[0] = 0.0;

	return new_poly;
}
double* Poly_Sub_Val(double poly[], double val)
{
	double* new_poly = (double*)malloc((MAX_n + 1) * sizeof(double));
	
	memcpy(new_poly, poly, (MAX_n + 1) * sizeof(double));
	new_poly[0] -= val;
	
	return new_poly;
}
double* Val_Mul_Poly(double val, double poly[])
{
	double* new_poly = (double*)malloc((MAX_n + 1) * sizeof(double));

	for (int i = 0; i <= MAX_n; i++)
		new_poly[i] = val * poly[i];

	return new_poly;
}
double* Get_x_poly()
{
	double* new_poly = (double*)malloc((MAX_n + 1) * sizeof(double));

	memset(new_poly, 0, (MAX_n + 1) * sizeof(double));
	new_poly[1] = 1.0;

	return new_poly;
}
double* Poly_Add_Poly(double* poly1, double* poly2)
{
	double* new_poly = (double*)malloc((MAX_n + 1) * sizeof(double));

	for (int i = 0; i <= MAX_n; i++)
		new_poly[i] = poly1[i] + poly2[i];

	return new_poly;
}
double* Poly_Sub_Poly(double* poly1, double* poly2)
{
	double* new_poly = (double*)malloc((MAX_n + 1) * sizeof(double));

	for (int i = 0; i <= MAX_n; i++)
		new_poly[i] = poly1[i] - poly2[i];

	return new_poly;
}

 opa ///

int OPA(double(*f)(double t), int m, double x[], double w[], double c[], double *eps)
{
		M = m;
		memcpy(W, w, MAX_m * sizeof(double));

		double y[MAX_m];
		for (int i = 0; i < m; i++) y[i] = f(x[i]);

		double phi[MAX_n + 1][MAX_n + 1] = { 0 };		// 多项式升序排列 项次数从0到MAX_n  phi[MAX_n]也是需要的 因为phi_k也要计算
		double a[MAX_n + 3] = { 0 };					// 插值多项式phi(x)的系数
		double B[MAX_n + 3] = { 0 };
		double C[MAX_n + 3] = { 0 };
		double err = InnerProd_yy(y);

		// initialize   以B C phi a err的顺序
		phi[0][0] = 1;
		a[0] = InnerProd_y(phi[0], x, y) / InnerProd(phi[0], phi[0], x);
		err -= a[0] * InnerProd_y(phi[0], x, y);

		B[1] = InnerProd(x_Mul_Poly(phi[0]), phi[0], x) / InnerProd(phi[0], phi[0], x);
		memcpy(phi[1], Poly_Sub_Val(Get_x_poly(), B[1]), (MAX_n + 1) * sizeof(double));
		a[1] = InnerProd_y(phi[1], x, y) / InnerProd(phi[1], phi[1], x);
		err -= a[1] * InnerProd_y(phi[1], x, y);

		int k;
		for (k = 2; k <= MAX_n; k++) {
			B[k] = InnerProd(x_Mul_Poly(phi[k - 1]), phi[k - 1], x) / InnerProd(phi[k - 1], phi[k - 1], x);
			C[k] = InnerProd(x_Mul_Poly(phi[k - 1]), phi[k - 2], x) / InnerProd(phi[k - 2], phi[k - 2], x);
			memcpy(phi[k], Poly_Sub_Poly(
				Poly_Sub_Poly(x_Mul_Poly(phi[k - 1]), Val_Mul_Poly(B[k], phi[k - 1])),
				Val_Mul_Poly(C[k], phi[k - 2])),
				(MAX_n + 1) * sizeof(double));
			a[k] = InnerProd_y(phi[k], x, y) / InnerProd(phi[k], phi[k], x);
			err -= a[k] * InnerProd_y(phi[k], x, y);

			if (fabs(err) < *eps) break;
		}
		int deg = k;	// res_poly的次数是0-k

		double* res_poly = (double*)malloc((MAX_n + 1) * sizeof(double));
		memset(res_poly, 0, (MAX_n + 1) * sizeof(double));
		for (int k = 0; k <= deg; k++) {
			res_poly = Poly_Add_Poly(res_poly, Val_Mul_Poly(a[k], phi[k]));
		}

		// store the res_poly[] in c[]
		memcpy(c, res_poly, (MAX_n + 1) * sizeof(double));

		*eps = err;

		return deg;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值