工程计算7——函数逼近与曲线拟合

连续函数空间C[a,b]

  • 定义
    • 在区间[a,b]上连续函数的全体构成的集合
    • 空间是无限维的
    • 满足线性运算的封闭性
  • 范数
    • ||f(x)||=maxx[a,b]|f(x)|
    • ||f(x)||1=ba|f(x)|dx
    • ||f(x)||2=[baf2(x)dx]12
  • 内积
    • 离散:
      • (f,g)=mi=0wif(xi)g(xi)
      • ||f||2=(f,f)=mi=0wi[f(xi)]2
    • 连续
      • (f,g)=baρ(xi)f(xi)g(xi)dx
      • ||f||2=(f,f)=baρ(xi)[f(xi)]2dx

函数逼近

基本概念
  • 定义
    • 在选定的一类函数中寻找某个函数g,使它是已知函数ƒ在一定意义下的近似表示,使得用g近似表示 ƒ而产生的误差最小。
  • 分类
    • 范数:最佳一致逼近
    • 1范数、2范数
      • 曲线之间的面积最小
      • 2范数:最佳平方逼近和最小二乘逼近
连续函数的最佳平方逼近
  • 定义
    • 这里写图片描述
  • 求解 S(x)
    • 这里写图片描述
    • 这里写图片描述
    • 存在唯一性
  • 最佳平方逼近多项式
    • 可能出现病态方程
    • 适用于低次函数逼近
  • 用正交基求最佳平方逼近
    • 由于正交基的性质,G矩阵只有对角元不为0
    • ak=(ϕk,f)/(ϕk,ϕk)
    • 这里写图片描述
    • 例:用勒让德多项式来求函数 f=1+x2 x[1,1] 的逼近函数g
double g(int k,double v)
{
    if(k == 0) return 1;
    else if(k == 1) return v;
    else return (3 * v * v - 1) / 2.0;
}
double f(double x)
{
    return sqrt(x * x + 1);
}
double gf(int k)
{
    double s = 0;
    int nn = 10000;
    double begin_ = -1;
    for(int i = 0;i < nn; i++)
    {
        s += g(k,begin_) * f(begin_) * (2.0 / (nn * 1.0));
        begin_ += (2.0 / (nn * 1.0));
    }
    return s;
}
double gg(int k)
{
    double s = 0;
    int nn = 1000;
    double begin_ = -1;
    for(int i = 0;i < nn; i++)
    {
        s += g(k,begin_) * g(k,begin_)  * (2.0 / (nn * 1.0));
        begin_ += (2.0 / (nn * 1.0));
    }
    return s;
}
void Compute_AB()
{
    for(int i = 0; i < n; i++)
    {
        A[i] = gg(i);
    }
    for(int i = 0; i < n; i++)
    {
        B[i] = gf(i);
    }
}
曲线拟合的最小二乘法(离散)
  • 定义
    • 已知函数值表 (xi,yi) ,在函数空间 ϕ 求解 S(x) ,使得 mi=0wi[S(xi)yi]2=mins(x)ϕmi=0wi[S(xi)yi]2
  • 求解
    • 与连续函数得到一样的法方程
    • 只是 (ϕk,f) 的计算方式不同。参考内积的离散和连续形式。
  • 三项递推公式
    • 这里写图片描述
  • 用三项递推公式来拟合一下5个点
x00.250.50.751
y0.10.350.811.091.96
double f(double k,double v)
{
    if(k == 0) return 1;
    else if(k == 1) return v - 0.5;
    else return (v - 0.5) * (v - 0.5) - 0.125;
}
void Compute_B()
{
    double s;
    for(int i = 0; i < n; i++)
    {
        s = 0;
        for(int j = 0; j < m; j++)
        {
            s += f(i , x[j]) *  y[j];
        }
        B[i] = s;
    }
}
void Compute_A()
{
    double s;
    for(int i = 0; i < n; i++)
    {
        s = 0;
        for(int j = 0;j < m;j++)
        {
            s += f(i,x[j]) * f(i,x[j]);
        }
        A[i] = s;
    }
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值