CPP&MATLAB实现拉格朗日插值法
开始学习MATLAB(R和Python先放一放。。。),老师推荐一本书,看完基础就是各种算法。。。首先是各种插值。先说拉格朗日插值法,这原理楼主完全不懂的,查的维基百科,好久才看懂。那里讲的很详细,这里就不在赘述了。一般看这个范例,在回头看公式就比较容易理解。

关于MATLAB的实现,查了很多资料,下面的版本最好理解。
%lagran1.m
%求拉格朗日插值多项式和基函数
%输入的量:n+1个节点(x_i,y_i)(i = 1,2, ... , n+1)横坐标向量X,纵坐标向量Y
%输出的量:n次拉格朗日插值多项式L,基函数l
function [L,l] = lagran1(X,Y)
% m为已知插值点的个数
m = length(X);
for k = 1 : m
% 迭代相乘前的初始化
% V代表每个k下的拉格朗日基本多项式
V = 1;
for i = 1 : m
if k ~= i
% conv这里是用于多项式相乘
% poly(a) 当a为数时,返回多项式(x - a)
V = conv(V,poly(X(i))) / (X(k) - X(i));
end
end
%l将所有的拉格朗日多项式存为一列
%poly2sym就是转化为多项式,下文有简单的demo
l(k, :) = poly2sym(V);
end
% 得到最终的拉格朗日多项式
L = Y * l;
关于poly2sym,是将数组转化为多项式的函数,不指定符号,默认为x.

运行函数:

查看拉格朗日多项式:

运用此函数进行插值:

接下来,最近学了一点cpp,就想用用cpp实现一遍,查到了这篇博文。这里就直接贴上了。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
/*
vector:不是一种数据类型。 vector<int>是一种数据类型。
vector容器是一个模板类,可以存放任何类型的对象(但必须是同一类对象)。
vector对象可以在运行时高效地添加元素,并且vector中元素是连续存储的。
*/ // 关于 & 的解释
/*
当我们声明一个变量的同时,它必须被存储到内存中一个具体的单元中。
通常我们并不会指定变量被存储到哪个具体的单元中—幸亏这通常是由编译器和操作系统自动完成的,
但一旦操作系统指定了一个地址,有些时候我们可能会想知道变量被存储在哪里了。
这可以通过在变量标识前面加与符号ampersand sign (&)来实现,它表示"...的地址" ("address of"),
因此称为地址操作符(adress operator),又称去引操作符(dereference operator)
*/ // 函数声明,是的其在完整定义前可以被(main函数)使用
double Lagrange(int N,vector<double>&X,vector<double>&Y,double x); int main()
{
char a='n';
do{
cout<<"请输入插值次数n的值:"<<endl;
int N;
cin>>N;
vector<double>X(N,0);
vector<double>Y(N,0);
cout<<"请输入插值点对应的值及其函数值(Xi,Yi):"<<endl;
for(int a=0;a<N;a++){
cin>>X[a]>>Y[a];
}
cout<<"请输入要求值的x的值:"<<endl;
double x;
cin>>x;
double result=Lagrange(N,X,Y,x);
cout<<"由拉格朗日插值法得出的结果:"<<result<<endl;
cout<<"是否要继续?<y/n>:";
cin>>a;
}while(a=='y');
return 0;
} //vector<double>,创建空容器,其对象类型为double类
double Lagrange(int N,vector<double>&X,vector<double>&Y,double x)
{
double result=0;
for(int i=0;i<N;i++){
double temp=Y[i];
for(int j=0;j<N;j++){
if(i != j){
temp = temp*(x-X[j]);
temp = temp/(X[i]-X[j]);
}
}// 与上文MATLAB实现不同,这里直接将拉格朗日多项式的各项直接相加
result += temp;
}
return result;
}
关于 & 的用法:

运行结果:

嗯,和上面MATLAB还是一样的,看来代码没问题咯。但是呢,从输出可以看到,这里一次拟合只能插一个值,那么如果同样的数据,我们想要插入两个点,这个代码就行不通了。其实改也很简单,只要挪一下do-while循环的位置就可以了。下面是改进的代码。
#include<iostream>
#include<string>
#include<vector>
using namespace std; // 函数声明,是的其在完整定义前可以被(main函数)使用
double Lagrange(int N,vector<double>&X,vector<double>&Y,double x); int main()
{
char a='n'; cout<<"请输入插值次数n的值:"<<endl;
int N;
cin>>N;
vector<double>X(N,0);
vector<double>Y(N,0);
cout<<"请输入插值点对应的值及其函数值(Xi,Yi):"<<endl;
for(int a=0;a<N;a++){
cin>>X[a]>>Y[a];}
// 注意do从上面移动到了这里,也就是改变了循环的内容
do{
cout<<"请输入要求值的x的值:"<<endl;
double x;
cin>>x;
double result=Lagrange(N,X,Y,x);
cout<<"由拉格朗日插值法得出的结果:"<<result<<endl;
cout<<"是否要继续?<y/n>:";
cin>>a;
}while(a=='y');
return 0;
} //vector<double>,创建空容器,其对象类型为double类
double Lagrange(int N,vector<double>&X,vector<double>&Y,double x)
{
double result=0;
for(int i=0;i<N;i++){
double temp=Y[i];
for(int j=0;j<N;j++){
if(i != j){
temp = temp*(x-X[j]);
temp = temp/(X[i]-X[j]);
}
}// 与上文MATLAB实现不同,这里直接将拉格朗日多项式的各项直接相加
result += temp;
}
return result;
}
运行结果:

CPP&MATLAB实现拉格朗日插值法的更多相关文章
- Matlab数值计算示例: 牛顿插值法、LU分解法、拉格朗日插值法、牛顿插值法
本文源于一次课题作业,部分自己写的,部分借用了网上的demo 牛顿迭代法(1) x=1:0.01:2; y=x.^3-x.^2+sin(x)-1; plot(x,y,'linewidth',2);gr ...
- 拉格朗日插值法——用Python进行数值计算
插值法的伟大作用我就不说了.... 那么贴代码? 首先说一下下面几点: 1. 已有的数据样本被称之为 "插值节点" 2. 对于特定插值节点,它所对应的插值函数是必定存在且唯一的(关 ...
- codeforces 622F. The Sum of the k-th Powers 拉格朗日插值法
题目链接 求sigma(i : 1 to n)i^k. 为了做这个题这两天真是补了不少数论, 之前连乘法逆元都不知道... 关于拉格朗日插值法, 我是看的这里http://www.guokr.com/ ...
- bzoj4559[JLoi2016]成绩比较 容斥+拉格朗日插值法
4559: [JLoi2016]成绩比较 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 261 Solved: 165[Submit][Status ...
- 集训DAYn——拉格朗日插值法
看zzq大佬的博客,看到了这个看似很深奥的东西,实际很简单(反正比FFT简单,我是一个要被FFT整疯了的孩子) 拉格朗日插值法 是什么 可以找到一个多项式,其恰好在各个观测点取到观测到的值.这样的多项 ...
- 牛客网多校训练第一场 F - Sum of Maximum(容斥原理 + 拉格朗日插值法)
链接: https://www.nowcoder.com/acm/contest/139/F 题意: 分析: 转载自:http://tokitsukaze.live/2018/07/19/2018ni ...
- 【BZOJ3453】XLkxc [拉格朗日插值法]
XLkxc Time Limit: 20 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 给定 k,a,n,d,p f(i ...
- Educational Codeforces Round 7 F. The Sum of the k-th Powers 拉格朗日插值法
F. The Sum of the k-th Powers 题目连接: http://www.codeforces.com/contest/622/problem/F Description Ther ...
- [国家集训队] calc(动规+拉格朗日插值法)
题目 P4463 [国家集训队] calc 集训队的题目真是做不动呀\(\%>\_<\%\) 朴素方程 设\(f_{i,j}\)为前\(i\)个数值域\([1,j]\),且序列递增的总贡献 ...
随机推荐
- [redis] windwos下安装和使用redis
一篇很好的入门学习文章:Redis学习 Redis是一种nosql数据库,在开发中常用做缓存. 1.下载地址: 低版本下载地址:https://github.com/dmajkic/redis/dow ...
- Java GC系列(3):垃圾回收器种类
本文由 ImportNew - 好好先生 翻译自 javapapers. 目录 垃圾回收介绍 垃圾回收是如何工作的? 垃圾回收的类别 垃圾回收监视和分析 在这篇教程中我们将学习几种现有的垃圾回收器.在 ...
- iOS视频直播初窥:高仿<喵播APP>
视频直播初窥 视频直播,可以分为 采集,前处理,编码,传输, 服务器处理,解码,渲染 采集: iOS系统因为软硬件种类不多, 硬件适配性比较好, 所以比较简单. 而Android端市面上机型众多, 要 ...
- 注解配置springMvc及向作用域中赋值
1.在applicationContext.xml中配置包扫描器 <!-- 使用注解配置扫描器 --> <context:component-scan base-package=&q ...
- SerialPort使用
1.简介随 着USB的流行,串口通讯已经应用到日常生活的很多方面了,USB是一种高速的串口通讯协议,USB接口非常复杂,通常被用在需要传输大量数据数据的地 方,如U盘.相机.打印机等.除了USB这种较 ...
- lucene底层数据结构——底层filter bitset原理,时间序列数据压缩将同一时间数据压缩为一行
如何联合索引查询? 所以给定查询过滤条件 age=18 的过程就是先从term index找到18在term dictionary的大概位置,然后再从term dictionary里精确地找到18这个 ...
- BZOJ3999 [TJOI2015]旅游
题面:给定一个有$n$个节点的树,每个点又点权$v_i$,每次选取一条树链$[a, b]$,求出$max(v_i - v_j)$,其中$i, j \in [a, b]$且$i$出现在$j$前面,最后树 ...
- BZOJ4003 [JLOI2015]城池攻占
这题有两种做法来着... 第一种就是一开始想到的比较不靠谱,不过貌似可以过掉: 看从$1$号节点开始到$p$号节点最大需要的体力,记录单调上升的体力,询问的时候二分跳着走就可以了 不过精度问题还有可能 ...
- charCodeAt 和 fromCharCode
1.charCodeAt() 定义和用法 charCodeAt() 方法可返回指定位置的字符的 Unicode 编码.这个返回值是 0 - 65535 之间的整数. 方法 charCodeAt() 与 ...
- mysql 远程连接速度慢的解决方案
PHP远程连接MYSQL速度慢,有时远程连接到MYSQL用时4-20秒不等,本地连接MYSQL正常,出现这种问题的主要原因是,默认安装的MYSQL开启了DNS的反向解析,在MY.INI(WINDOWS ...