MATLAB 与 C 语言的混合编程实战之辛普森积分法、自适应辛普森积分
时间:2022-07-26
本文章向大家介绍MATLAB 与 C 语言的混合编程实战之辛普森积分法、自适应辛普森积分,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目要求
题目大意是让你用c系语言实现辛普森积分法对定积分的粗略估计,所谓辛普森积分法即为:
定义:辛普森法则(Simpson's rule)是一种数值积分方法,是牛顿-莱布尼茨公式的特殊形式,以二次曲线逼近的方式取代矩形或梯形积分公式,以求得定积分的数值近似解。其近似值如下:
那很明显可以看出,改进积分结果有两种方法,一是二分区间之后再次二分不断逼近,二是从积分间隔入手,不断缩小积分间隔
给出Matlab-C++代码
//Author:glm
#include<cstdio>
#include<cmath>
#include<iostream>
#include "mex.h"
#define ll long long int
#define rg register ll
inline double f(double x)
{
if(x==0)return 1;
return sin(x)/x;
}
inline double calculate(double a,double b)//int(f,a,b)=(b-a)/6*(f(a)+4*f((a+b)/2+f(b))
{
double sum=0;
for(rg i=0;i<(ll)((b-a)/0.025);i++)
{
double a1=a+0.0250*i,b1=a1+0.0250,mid=(a1+b1)/2.0;
sum+=(mid-a1)/6*(f(a1)+4*f((a1+mid)/2)+f(mid))+(b1-mid)/6*(f(mid)+4*f((b1+mid)/2)+f(b1));
}
return sum;
/* int parts=(int)((b-a)/0.01);
double ans=0;
for (int i=0;i<parts;i++)
{
double ai=a+i*0.01;
double bi=ai+0.01;
double mi=(ai+bi)/2;
ans+=(mi-ai)/6*(f(ai)+4*f((ai+mi)/2)+f(mi))+(bi-mi)/6*(f(mi)+4*f((bi+mi)/2)+f(bi));
//ans+=(bi-ai)/6*(f(ai)+4*f((ai+bi)/2)+f(bi));
}
return ans;*/
}
void mexFunction (int nlhs,mxArray *plhs[],int nrhs,const mxArray * prhs[])
{
double *a;
double b,c;
plhs[0]=mxCreateDoubleMatrix(1,1,mxREAL);
a=mxGetPr(plhs[0]);//
b=*(mxGetPr(prhs[0]));
c=*(mxGetPr(prhs[1]));
*a=calculate(b,c);
}
报告的latex代码~
documentclass[12pt]{article}
usepackage{amsmath}
usepackage{mathtools}
usepackage{graphics,epsfig}
usepackage{xspace}
usepackage{color}
usepackage{amssymb}
usepackage{subfigure}
usepackage{multirow}
usepackage{listings}
usepackage{graphicx}
usepackage{url}
%%uncomment following line if you are going to use ``Chinese''
%usepackage{ctex}
definecolor{ballblue}{rgb}{0.13, 0.67, 0.8}
definecolor{cornflowerblue}{rgb}{0.39,0.58,0.93}
definecolor{babyblueeyes}{rgb}{0.63, 0.79, 0.95}
% preset-listing options
lstset{
backgroundcolor=color{white},
basicstyle=footnotesize,
language=matlab,
breakatwhitespace=false,
breaklines=true, % sets automatic line breaking
captionpos=b, % sets the caption-position to bottom
commentstyle=color{ballblue}, % comment style
extendedchars=true,
frame=single, % adds a frame around the code
keepspaces=true,
keywordstyle=color{blue}, % keyword style
numbers=left,
numbersep=5pt,
numberstyle=tinycolor{blue},
rulecolor=color{babyblueeyes},
stepnumber=1,
stringstyle=color{black}, % string literal style
tabsize=4, % sets default tabsize to 4 spaces
title=lstname
}
usepackage{geometry}
geometry{
a4paper,
total={210mm,297mm},
left=20mm,
right=20mm,
top=20mm,
bottom=20mm,
}
marginparwidth = 10pt
begin{document}
title{Weekly Assignment:Simpson’s rule of calculation}
author{ \ Stdudent Guo LiMin \ Id: 22920182204174}
maketitle
section{Problem Description}
Given function $f(x)=cfrac{sinx}{x}$ , the integral range [a, b], please work out its numerical integral in range [a, b].
You are required to calculate the numerical integral by Simpson’s rule.
\\{color{red}Requirements:}\\ 1. Your function myQuad MUST be implemented in C and called by Matlab\
2. The command interface in Matlab looks like: v = myQuad(a, b);\
3. You are NOT allowed to use “recursive procedure” when you implement Simpson’s
rule\
4. Given $F(x) =int^{6}_{-2}cfrac{sinx}{x}dx$, please plot out the curve of F(x) in the range [-2 6]\
5. According to Simpson’s rule, the number of intervals will impact on the precision.
You are required to try different numbers of intervals and see how it impacts your
result. Please present an analysis about this in your report.
section{Code of Solution}
The followings are codes implemented by C++,no fancy algorithm included,working out this problem only by using simple simulations\
%
%if one wants to paste part of the code into the report
%one can put in following manner
begin{lstlisting}[language=c++, linewidth=linewidth,caption={main working function(myQuad.cpp)}]
#include<cstdio>
#include<cmath>
#include<iostream>
#include "mex.h"
#define ll long long int
#define rg register ll
inline double f(double x)
{
return sin(x)/x;
}
inline double calculate(double a,double b)//int(f,a,b)=(b-a)/6*(f(a)+4*f((a+b)/2+f(b))
{
double sum=0;
for(rg i=0;i<(ll)((b-a)/0.001);i++)
{
double a1=a+0.001*i,b1=a1+0.001,mid=(a1+b1)/2.0;
sum+=(mid-a1)/6*(f(a1)+4*f((a1+mid)/2)+f(mid))+(b1-mid)/6*(f(mid)+4*f((b1+mid)/2)+f(b1));
}
return sum;
/* int parts=(int)((b-a)/0.01);
double ans=0;
for (int i=0;i<parts;i++)
{
double ai=a+i*0.01;
double bi=ai+0.01;
double mi=(ai+bi)/2;
ans+=(mi-ai)/6*(f(ai)+4*f((ai+mi)/2)+f(mi))+(bi-mi)/6*(f(mi)+4*f((bi+mi)/2)+f(bi));
//ans+=(bi-ai)/6*(f(ai)+4*f((ai+bi)/2)+f(bi));
}
return ans;*/
}
void mexFunction (int nlhs,mxArray *plhs[],int nrhs,const mxArray * prhs[])
{
double *a;
double b,c;
plhs[0]=mxCreateDoubleMatrix(1,1,mxREAL);
a=mxGetPr(plhs[0]);//
b=*(mxGetPr(prhs[0]));
c=*(mxGetPr(prhs[1]));
*a=calculate(b,c);
}
end{lstlisting}
begin{lstlisting}[language=c++, linewidth=linewidth,caption={Draw the contrast curve and main interface code(test.m)}]
mex myQuad.cpp
syms t
a=-2:0.27:6;
b=-2:0.27:6;
c=-2:0.27:6;
cnt=0;
for x=-2:0.27:6
y=int(sin(t)/t,-2,x);
cnt=cnt+1;
b(cnt)=y;
c(cnt)=myQuad(-2,x);
b(cnt),c(cnt);
end
plot(a,b,'r',a,c,'b')
end{lstlisting}
section{Experiment Theory and Results}
Given function f(x), and its range of x [a,b], it is possible to estimate its integral in range [a,b]
by quandratic interpolation based on “Simpson’s rule”. The “Simpson’s rule” is given as
follows.\
begin{equation}
begin{split}$int^{b}_{a}cfrac{sinx}{x}dx &=cfrac{(b-a)}{6}*[f(a)+4*f(cfrac{a+b}{2})+f(b)]\
&=cfrac{(m-6)}{6}*[f(a)+4*f(cfrac{a+m}{2})+f(m)]+cfrac{(b-m)}{6}*[f(m)+4*f(cfrac{b+m}{2})+f(b)]nonumber$
end{split}
end{equation}
\
What’s more,The more number of segments used in the range [a, b], the better is the approximation.
\\
To start with,we should learn how to compile c/c++ files with matlab and how to write fantastic and unified-formatted papers,
this aspect of learning has been updated to my personal blog {color{red}url{newcoder-glm.blog.csdn.net}},so for more information,please go up to visit my blog.
\\
After mastering the mixtrue of C/C++& matlab programming technique(It's just an interface that calls an external compiler in essence),as easy as pie we can write the codes above and
should curve figures(check out the attachment for more details) which shows graphs of the result and the exact result obtained by Simpson integral method when the interval of integral interval is divided differently(when the value is 0.05 0.25)
begin{table}[h]
caption{Circumstances when we apply different intervals}
begin{center}
begin{tabular}{|c|c|c|c|}
hline
Interval & 0.01 & 0.10 & 0.25\ hline
Results & textbf{2.551496047169967}& textbf{2.551496048068467} & textbf{2.551496047173387 } \ hline
end{tabular}
end{center}
end{table}
subsection{further ideas}
We can see from the Simpson integral (the simple three-point formula) that there is some error, and it's easy to see that the smaller the interval, the more accurate the integral,
however,if we shorten the interval, of course the results' accuracy come up, but at the cost of higher time complexity.\
So here we introduce "Adaptive Simpson’s rule" which is the integral can automatically control the size and length of the cutting interval, so that the accuracy can meet the requirements.
In particular, if the midpoint of [a,b] is c, the result will be directly returned if and only then {color{red}$[S(a,c)+S(c,b)-S(a,b)]<15Eps$} Otherwise, the recursive call will divide the interval again. The accuracy of Eps should be reduced by half when recursion is called.
begin{figure}[h]
centering
{includegraphics[width=0.7linewidth]{025.pdf}}
hspace{0.15in}
end{figure}
begin{figure}[h]
centering
{includegraphics[width=0.7linewidth]{005.pdf}}
hspace{0.15in}
end{figure}
section{What I learned from the Project}
1.learning how to programing cpp files with powerful matlab,excuted with high efficiency and conciseness}
\\2.the ability of exploring new territory that never have been leart and mastering it(hand in report in time)}
\\3.learning how to write fantastic and unified-formatted papers with modernized Latex}
section{Two attached pictures of point three}
end{document}
报告的pdf~
- 剖析响应式编程的本质
- 从机器学习学python(二) ——iteritems、itemgetter、sorted、sort
- 基于MVC理解React+Redux
- JavaScript的IIFE(即时执行方法)
- 从机器学习学python(三) ——数组冒号取值与extend
- 从机器学习学python(四) ——numpy矩阵基础
- 从map函数引发的讨论
- AngularJs中,如何在render完成之后,执行Js脚本
- PHP取得上周一、上周日,下周一
- 代码诊所
- 《编程之美》读书笔记(一)——中国象棋将帅有效位置
- 有趣的Code Poster
- div 自适应高度 自动填充剩余高度
- PHP开发人员常犯的10个MysqL错误
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP pthreads v3使用中的一些坑和注意点分析
- php ActiveMQ的安装与使用方法图文教程
- ThinkPHP5与单元测试PHPUnit使用详解
- php实现通过stomp协议连接ActiveMQ操作示例
- PHP pthreads v3下的Volatile简介与使用方法示例
- php实现根据身份证获取精准年龄
- php 使用ActiveMQ发送消息,与处理消息操作示例
- php使用gearman进行任务分发操作实例详解
- laravel框架select2多选插件初始化默认选中项操作示例
- PHP pthreads v3在centos7平台下的安装与配置操作方法
- laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
- PHP Beanstalkd消息队列的安装与使用方法实例详解
- 解决windows上php xdebug 无法调试的问题
- php7 图形用户界面GUI 开发示例
- Django开发的简易留言板案例详解