精华内容
下载资源
问答
  • C语言实现变步长求积分算法

    千次阅读 2018-10-26 09:46:30
    链接: ... 博主详细介绍了复合... //将上次一的积分结果和减小步长后的积分结果均值 } printf("初始步长得到的积分值:%lf 所分的区间个数:%d\n",T2,step); } 3、结果: 4、验证:  

    链接:https://blog.csdn.net/chen_dsir/article/details/71257631  博主详细介绍了复合梯形公式,

    链接:https://wenku.baidu.com/view/b300c53deefdc8d376ee3228.html 详细介绍了变步长的目的,以及变换的方式

    下面求解如下问题:

    1、变步长:

            由于多数情况下,并不知道步长设置为多少合适,所以我们可以设置一个初始步长,求解一次,再把步长变为原来的一半,依次接下去,直到达到我们所需的精度。

    2、代码:

    #include<stdio.h>
    #include<math.h>
    
    #define left 1.0   //左端的值 
    #define right 3.0   //右端的值 
    #define  precision 0.0001   //定义精度 
    
    
    double f(double x)
    {
    	double m=100/(x*x)*sin(10/x);
    	return m;
    }
    
    int main()
    {
    	int i;
    	int step=100;  //初始化步数
    	double stepLength=(right-left)/step; //步长
    	double T=f(left)+f(right);   //积分的值 
    	for(i=1;i<=step-1;i++) 
    	{
    		double x=left+i*stepLength;
    		T+=2*f(x);
    	}
    	T=stepLength/2*T;  //符合梯形公式求解结果
    	printf("初始步长得到的积分值:%lf   所分的区间个数:%d\n",T,step);
    	//下面改变步长,来细化精度
    	double T1=T+100;
    	double T2=T;
    	double H;      //减小步长后得到的积分值 
    	while(fabs(T1-T2)>precision/2) 
    	{
    		T1=T2;
    		step=step*2;
    		stepLength=(right-left)/step; 
    		H=0;
    		for(i=1;i<step;i++)
    		{
    			H+=2*f(left+stepLength*i);
    		}
    		H=f(left)+f(right)+H;
    		H=H*stepLength/2;     
    		T2=(T1+H)/2;    //将上次一的积分结果和减小步长后的积分结果求均值 
    		
    	}	
    	printf("初始步长得到的积分值:%lf   所分的区间个数:%d\n",T2,step);
    	
    	 
    	
    }

    3、结果:

    4、验证:

     

    展开全文
  • Romberg算法求积分MATLAB和C语言实现

    千次阅读 2020-01-01 14:46:09
    经测试,博主所写的Romberg算法对于最终不能整除的,精度能够达到小数点后15位。 比如积分 和 的计算结果如下: 1.计算步骤 (说明:a——积分下限,b——积分上限,eps——误差) 1)准备初值: 2)按复化...

    目录

    1.计算步骤

    2.MATLAB代码

    3.C语言代码


    经测试,博主所写的Romberg算法对于最终不能整除的,精度能够达到小数点后15位。

    比如积分 \int_{1}^{3}\frac{1}{x}dx  和 \int_{1}^{3}xdx 的计算结果如下:


    1.计算步骤

    (说明:a——积分下限,b——积分上限,eps——误差)

    1)准备初值:T_{1}^{(0)}=\frac{b-a}{2}[f(a)+f(b)]

    2)按复化梯形公式的递推关系计算:T_{1}^{(l)}=\frac{1}{2} \left \{ T_{1}^{(l-1)}+\frac{b-a}{2^{l-1}}\sum _{i=1}^{2^{l-1}}f[a+(2i-1)\frac{b-a}{2^{l}}] \right \},l=1,2,3,...

    3)计算加速值:T_{m+1}^{(k-1)}=\frac{4^{m}T_{m}^{(k)}-T_{m}^{(k-1)}}{4^{m}-1},m=1,2,...,l; k=1,2,...,l-m+1

    4)判断精度:\left | T_{l}^{(0)} -T_{l-1}^{(0)}\right |< eps,满足条件就停止计算,否则回转继续执行 2)

    2.MATLAB代码

    % @brief  用Romberg算法求定积分∫x^(-1)dx(上限3下限1,eps=tbd)。
    % @author SLF 2019/12/23
    % @notice 若要使用此代码,请注明来源!
    
    EPS = 1e-18; % 误差
    MAX = 18;   % 最高迭代次数
    a   = 1.0;  % 积分下限
    b   = 3.0;  % 积分上限
    arry = zeros(1, MAX + 1); % 存储T值
    lastT0 = 0.0; % 用于缓存上一迭代的Tx0数值
    % cut = 0.0;
    % s = 1.0;
    Txx1 = 0.0; % 两个算法处理中间变量
    Txx2 = 0.0;
    m = 1; % 每次迭代完数组arry中的有效长度
    n = 1; % 求和上限(2从0开始取幂)
    % k = 0;
    cnt = 0;% 迭代次数统计
    
    cut = b - a;% 存储积分区间长度,以及对积分区间进行2^1,2^2,2^3,2^4,……等分后的长度
    % 算法公式一实现
    arry(1) = cut * 0.5 * (IntergrandFunc(a) + IntergrandFunc(b)); % T10
    
    while (m <= MAX)
        cnt = cnt + 1;
        % 算法公式二实现
        Txx1 = 0.0;   % 清除最后一个for循环跳出时的赋值
        for i=0:(n-1) % 计算∑f[a+(2i-1)*(b-a)/2^l]
            Txx1 = Txx1 + IntergrandFunc(a + (i + 0.5)*cut);
        end
        Txx1 = (arry(1) + cut * Txx1) * 0.5; % T11;T12;T13;T14;……
        
        % 算法公式三实现
        s = 1.0;
        for j=1:m
            s = 4.0*s;
            Txx2 = (s*Txx1 - arry(j)) / (s - 1.0); % T20;T21、T30;T22、T31、T40;T23、T32、T41、T50;……
            
            if (j == m)
                lastT0 = arry(j);
            end
            arry(j) = Txx1;
    		Txx1 = Txx2;
        end
        
        % 停机判断
        if ((abs(Txx2 - lastT0) < EPS)) % 前后两次迭代计算结果比较 (T20-T10);(T30-T20);(T40-T30);(T50-T40);……
            break;
        end
        
        m = m + 1;
    	arry(m) = Txx2;
    
    	n = n + n;
        cut = cut * 0.5;
    end
    
    if (MAX + 1  == m)
        fprintf("\n!!!迭代阈值设置太低,请修改!!!当前设置值为%d次\n\n", MAX);
    else
        fprintf("\n总共迭代:%d次\n", cnt);
        fprintf("\nRomberg算法积分结果为:%.20f\n", Txx2);
        fprintf(" (设置精度eps = %.e)\n\n", EPS);
    end
    
    % Function:定积分被积函数
    function ff = IntergrandFunc(x) 
    ff = x^(-1);
    % ff = x;
    end

    运行结果(Matlab R2017b):

    3.C语言代码

    /**
     * @brief    用Romberg算法求定积分∫x^(-1)dx(上限3下限1,eps=1e-18)。
     * @author   SLF 2019/12/23
     * @notice   若要使用此代码,请注明来源!
     **/
    #include <stdio.h>
    #include <math.h>
    
    #define	EPS	    1e-18	// 误差
    #define	MAX	    18U	        // 最高迭代次数
    #define	MAX_INVAL   9999.99L	// 最高迭代次数太小
    
    // 函数原型声明
    double IntegrandFunc(double x);
    double RombergAlgorithm(double a, double b, double (*f)(double x));
    
    /**
     * @brief     Main函数
     * @param     void
     * @retval    0
     * @author    SLF 2019/12/23
     **/
    int   main(void)
    {
    	double a = 1.0, b = 3.0;
    	double calcResult = 0.0;
    	
    	/*printf("\nstep1: 请输入积分下限a=");
    	scanf("%f", &a);
    	printf("\nstep2: 请输入积分上限b=");
    	scanf("%f", &b);
    	printf("\n");*/
    
    	calcResult = RombergAlgorithm(a, b, IntegrandFunc);
    	if(MAX_INVAL != calcResult)
    	{
    		printf("\nRomberg算法积分结果为:%.20f\n", calcResult);
    		printf(" (设置精度eps = %.e)\n\n", EPS);
    	}
     
    	return 0;
    }
    
    /**
     * @brief    定积分被积函数
     * @param    x: 积分变量
     * @retval   double	
     * @author   SLF 2019/12/23
     **/
    double IntegrandFunc(double x)
    {
    	double ff = 0.0;
    	ff = pow(x,-1) ;
    
    	return ff;
    }
    
    /**
     * @brief    Romberg算法
     * @param    as follows:
     *		a: 积分下限
     *		b: 积分上限
     *		*f:  指向被积函数的指针
     * @retval   double	
     * @author   SLF 2019/12/23
     **/
    double RombergAlgorithm(double a, double b, double (*f)(double x))
    {
    	double arry[MAX + 1] = {0.0};	 // 存储T值
    	double lastT0 = 0.0;  // 用于缓存上一迭代的Tx0数值
    	double cut = 0.0;     // 存储积分区间长度,以及对积分区间进行2^1,2^2,2^3,2^4,……等分后的长度
    	double s = 1.0;       // 存储对4取幂的结果
    	double Txx1 = 0.0, Txx2 = 0.0;   // 两个算法处理中间变量
    	unsigned int m = 1, n = 1, k = 0;// m: 每次迭代完数组arry中的有效长度   n: 求和上限(2从0开始取幂)   k: 循环通用累加量
    	unsigned int cnt = 0; // 迭代次数统计
    
    	cut = b - a;
    	/*** 算法公式一实现 ***/
    	arry[0] = cut * 0.5 * (f(a) + f(b)) ; // T10
    
    	m =  n = 1;
    	while (m <= MAX)
    	{
    		cnt++;
    
    		/*** 算法公式二实现 ***/
    		Txx1 = 0.0; // 清除最后一个for循环跳出时的赋值
    		for (k = 0; k<n; k++) // n=1 2 4 8 ……
    		{// 计算∑f[a+(2i-1)*(b-a)/2^l]
    			Txx1 +=  f(a + (k + 0.5)*cut);
    		}
    		Txx1 = (arry[0] + cut*Txx1) *0.5;  // T11;T12;T13;T14;……
    
    		/*** 算法公式三实现 ***/
    		s = 1.0;
    		for (k = 1; k <= m; k++)  // m=1 2 3 4 ……
    		{
    			s = 4.0*s; // s = pow(4,k)
    			Txx2 = (s*Txx1 - arry[k - 1]) / (s - 1.0); // T20;T21、T30;T22、T31、T40;T23、T32、T41、T50;……
    
    			if(k == m)
    			{
    				lastT0 = arry[k - 1];
    			}
    			arry[k - 1] = Txx1;
    			Txx1 = Txx2;
    		}
    
    		/*** 停机判断 ***/
    		if((fabs(Txx2 - lastT0) < EPS)) // 前后两次迭代计算结果比较 (T20-T10);(T30-T20);(T40-T30);(T50-T40);……
    		{
    			break;
    		}
    
    		m++;
    		arry[m - 1] = Txx2;
    
    		n += n;		// 2 4 8 16……
    		cut *= 0.5;	// 对积分区间进行2^1,2^2,2^3,2^4,……等分
    	}
    
    	if(MAX + 1  == m)
    	{
    		printf("\n!!!迭代阈值设置太低,请修改!!!当前设置值为%d次\n\n", MAX);
    		return MAX_INVAL;
    	}
    
    	printf("\n总共迭代:%d次\n", cnt);
    
    	return Txx2;
    }

    运行结果(Microsoft Visual C++2010):

     

    郑重提示:广大博友若有能继续提高计算精度的方法,欢迎在评论区讨论留言!

     

    展开全文
  • 变步长的Simpson公式计算积分算法基本分析:输入a,b(积分上下限),n为积分区间等分数,eps为计算精度,我这里1/...变步长梯形算法计算积分,本题目取的例子为数值书131面的例子2,f(x)= sin(x)/x,下面给出代码:

    变步长的梯形公式计算积分.算法基本分析:输入a,b(积分上下限),n为积分区间等分数,eps为计算精度,我这里1/2e-6,代表0.5乘以10的负6次方.变步长梯形求积算法计算积分,本题目取的例子为数值书131面的例子2,f(x)= sin(x)/x,下面给出代码:

    ps:略微更新纠正一下,复合梯形公式和复合simpson公式是不一样的:

    复合梯形公式:

    复合simpson公式(这个我们数值书131面有算法描述):


    我这个就是梯形公式,一张别人写的算法描述:


    我写的代码逻辑比较模糊,当时懒得修改:网上有一篇别人写的梯形公式算法逻辑比较清晰,可以看看:http://www.cnblogs.com/quantumplan/archive/2014/03/07/3586429.html


    /******************************************** 
        > File Name: Ladder.c 
        > Author:chendiyang 
        > School:WUST_CST_1501班 
        > Myblog:www.chendsir.com 
        > Mail:1441353519@qq.com  
        > Created Time: 2017年05月5日 星期五 21时19分21秒 
     ************************************************************************/  
    #include <stdio.h>  
    #include <math.h>  
    //本题目取的例子为数值书131面的例子2,f(x)= sin(x)/x  
    #define m 100 //积分区间等分数,偶数不宜过大  
    #define a 0.000000001 //分母是0,a计算的时候不能为0,所以我们只能无限接近于0,否则会计算不出值   
    #define b 1.0  //积分上限  
    #define eps 0.5e-6 //计算的精度  
      
    double f(double x)//我们的积分函数,如果是其他的就在return里面改  
    {  
        return sin(x)/x;//值得注意的是以e为底的指数函数如何表示呢,C语言用exp()函数表示  
    }           //比如以e为底的指数函数e的-x*x,则exp(-x*x)表示  
    int main()  
    {  
        int n=m;  
        int i;  
        double T,H,T1,T2;  
        double h=(b-a)/n;//积分步长
        T=(f(a)+f(b))/2;  
        for(i=1;i<n;i++)  
          T+=f(a+h*i);  
        T*=h;  
        T2=T;  
        T1=T2+100;  
        do  
        {  
            T1=T2;  
            for(i=0,H=0;i<n;i++)  
              H+=f(a+h*i+h/2);  
            H*=h;  
            T2=(T1+H)/2;  
            h=h/2;  
            n=n*2;    
        }while(fabs(T1-T2)>3*eps);  
      
        printf("T=%lf\n",T2);    
       return 0;  
    }  
    
    

    运行结果:


    结果和书上的是一样的,只不过书上的精确度更高些.


    展开全文
  • 自适应复化辛普森公式求积算法C语言实现)利用复化辛普森公式求积分自适应步骤基于C语言实现的代码 利用复化辛普森公式求积分自适应步骤 h为步长,a为积分下限,b为积分上限,f为积分函数,n为划分的积分次数,ε...

    自适应复化辛普森公式求积算法(C语言实现)

    利用复化辛普森公式求积分自适应步骤

    h为步长,a为积分下限,b为积分上限,f为积分函数,n为划分的积分次数,ε为允许误差限(若要求精度为10的负n次方,则误差限为0.5乘以10的负n次方)
    步骤来自《数值与计算方法》黄云清著

    基于C语言实现的代码

    代码中积分函数f(x)为1/(1+x^2)(在step2中的for循环中可以看到,如需改变函数则改变这里的值)

    #include "stdio.h"
    
    void step2(double *h, int *n, double *S, double *S1, double *S2)
    {
    	int i = 0;
    	*S = 0;
    	for(i = 0; i < *n; i++)
    	{
    		*S += ( 2.0/(1 + ((i+0.25)*(*h) - 4) * ((i+0.25)*(*h) - 4) ) - 1/(1 + ((i+0.5)*(*h) - 4) * ((i+0.5)*(*h) - 4) ) + 2.0/(1 + ((i+0.75)*(*h) - 4) * ((i+0.75)*(*h) - 4) ));
    	}
    	*S2 = 0.5 * (*S1) + (*h)/6.0 * (*S);
    }
    
    int step3(double *S1, double *S2)//判断精度是否满足 
    {
    	if((*S1 - *S2)>0)
    	{
    		if((*S1 - *S2) < 0.0000005)//0.0000005为10的负6次方精确度 
    			return 1;
    		else
    			return 0;
    	}
    	else 
    	{
    		if((*S2 - *S1) < 0.0000005)
    			return 1;
    		else
    			return 0;
    	}
    }
    
    main()
    {
    	double h = 8;
    	int n = 1;
    	int j = 0;
    	double S = 0;
    	double S1 = 280.0/51.0; 
    	double S2 = 0;
    	step2(&h, &n, &S, &S1, &S2);
    	while(!step3(&S1, &S2))
    	{
    		h /= 2.0;
    		n *= 2;
    		S1 = S2;
    		step2(&h, &n, &S, &S1, &S2);
    	}
    	printf("%.10f",S2);
    }
    
    展开全文
  • c语言实现积分的方法

    万次阅读 2012-06-07 14:37:59
    复化梯形公式,复化抛物线公式和Romberg积法的算法程序: 以下程序均定义误差限为1*10^-5; 1)复化梯形公式: #include  #include  #define e 1e-5 #define a 0 //积分下限a #define b 1 //积分...
  • C语言实现龙贝格积分

    千次阅读 2017-12-08 20:54:12
    用Romberg算法求下列积分,允许误差eps=0.00001 /***************************************************************** 《数值分析》实验习题2 机械工程 现代制造技术教育部重点实验室 ************************...
  • C语言常用算法

    2012-03-28 10:48:37
    117 积分 118 满足特异条件的数列 119 超长正整数的加法 第四部分 图形篇 120 绘制直线 121 绘制圆 122 绘制圆弧 123 绘制椭圆 124 设置背景色和前景色 125 设置线条类型 126 设置填充类型和填充...
  • C语言实现龙贝格

    2016-01-20 11:26:31
    龙贝格积公式也称为逐次分半加速法。它是在梯形公式、辛普森公式和柯特斯公式之间的关系的基础上,构造出一种加速计算积分的方法。 作为一种外推算法, 它在不增加计算量的前提下提高了误差的精度.
  • 《妙趣横生的算法(C语言实现)》可作为算法入门人员的教程,也可以作为学习过C语言程序设计的人士继续深造的理想读物,也可作为具有一定经验的程序设计人员巩固和提高编程水平,查阅相关算法实现和数据结构知识的参考...
  • 龙贝格积分法的C语言实现及应用

    千次阅读 2019-06-15 16:29:43
    问题背景与提出 ...龙贝格公式在变步长的积过程中运用三个加速公式,由变步长的梯形加速法,逐步得到梯形加速公式、抛物线加速公式,进而由粗糙的积分近似值迅速加工成精度较高的积分近似值。...
  • 数值作业:二分法方程的根之C语言实现代码

    万次阅读 多人点赞 2017-04-19 18:05:36
    二分法是方程近似解的一种简单直观的方法,设函数f(x)在[a,b]上连续,且f(a)*f(b),则表明f(x)在[a,b]上至少有一个零点,这是微积分中的介值定理(不得不吐槽一下大学微分方程老师讲课跟个煞笔一样,反正我是重来没...
  • 此篇博客记录了几个基于C语言的数学上常用的几个功能的实现代码,有秦九韶算法求函数值、求积分、二分法、牛顿迭代法求非线性方程组,最后配了个计算方法的总结图。
  • 6. 牛顿-科特斯积公式,积分 <!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->#includestdio.h>#includemath.h>int NC(a,h,n,r,f)float (*a)[];
  • 4.龙贝格积公式,求解定积分 #includestdio.h> #includemath.h>#define f(x) (sin(x)/x)#define N20#define MAX20 #define a2#define b4#define e0.00001 float LBG(float p,float q,int n){int i; float sum=0,...
  • 6. 牛顿-科特斯积公式,积分 C/C++ code #includestdio.h>#includemath.h>int NC(a,h,n,r,f)float (*a)[];float h;int n,f;float *r;{ int nn,i; float ds; if(n>1000||n2) { if (f) printf("/n Faild! Check...
  • erf()函数C语言代码

    热门讨论 2012-08-05 13:00:12
    该源代码采用C语言实现了误差函数erf(),其精度可根据参数ERF_N来调节(默认100),...该实现采用的是麦克劳林展开方法再逐项求积分。 另外,还包含了标准正态分布函数的计算函数norm_cdf(),该函数调用了erf()函数。
  • C语言实战105例源码

    2012-04-11 18:41:37
    (无需积分C语言实战105例源码 其他的都是要分值的,转来的不要积分 第1部分 基础篇 实例1 一个价值“三天”的BUG 2 实例2 灵活使用递增(递减)操作符 5 实例3 算术运算符计算器 7 实例4 逻辑运算符...
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    答:对于复杂而开发时间紧的项目时,可以采用C语言,但前提是要求对该MCU系统的C语言和C编译器非常熟悉,特别要注意该C编译系统所能支持的数据类型和算法。虽然C语言是最普遍的一种高级语言,但不同的MCU厂家其...
  • c语言经典源码例子100篇

    热门讨论 2008-09-23 12:13:17
    第一篇 基础知识篇 ...实例94 用C语言实现遗传算法 实例95 人工神经网络的C语言实现 实例96 K_均值算法 实例97 ISODATA算法 实例98 快速傅立叶变换 实例99 求解野人与传教士问题 实例100 简单专家系统
  • C语言实现K均值算法,菜鸟水平有点混乱。上传求积分。囧。。。。。
  • 计算方法(C语言版)

    热门讨论 2011-04-16 13:44:36
    全书共分9章,主要内容包括算法与误差、非线性方程根、线性方程组的直接求解和迭代求解、代数插值、数值积分、矩阵特征值与特征向量的计算、常微分方程初值问题的数值解法等。 本书的特色和优势是:注重算法与程序...
  • C语言精彩编程百例.pdf(附书源码)

    千次下载 热门讨论 2011-06-29 10:49:46
    C语言精彩编程百例》,作者:...实例94 用c语言实现遗传算法 实例95 人工神经网络的c语言实现 实例96 k_均值算法 实例97 isodata算法 实例98 快速傅立叶变换 实例99 求解野人与传教士问题 实例100 简单专家系统
  • 基本信息 ...实例94 用C语言实现遗传算法 实例95 人工神经网络的C语言实现 实例96 K_均值算法 实例97 ISODATA算法 实例98 快速傅立叶变换 实例99 求解野人与传教士问题 实例100 简单专家系统
  • 牛顿 科特斯积公式

    2010-12-16 22:00:52
    牛顿科特斯积公式的C语言编程,经典算法。此算法已在C语言实现编程。方便积分计算。
  • 本书对科学计算上所用到的数值计算进行了详细的介绍,包括:线性代数方程组的求解,内插,外推,函数积分,函数值,...本给出了其C语言实现算法。 剑桥大学出版社正式授权出版。 可以作为计算机编程人员的工具书
  • (10uF 电容接 VCC 与 RESET,即可实现上电复位) 5. 内置振荡电路,外部只要接晶体至 X1(PIN18)和 X0(PIN19);(频率为主频的 12 倍) 6. 程序配置 EA(PIN31)接高电平 VCC;(运行单片机内部 ROM 中的程序) ...

空空如也

空空如也

1 2
收藏数 39
精华内容 15
关键字:

c语言求积分算法实现

c语言 订阅