常用功能实现
1、秦九韶算法求多项式函数值
#include <cstdio>
#include <cstdlib>
#include <cmath>
double P(double a[],double x,int n)
{
double p=a[n-1];
for(int i=n-2;i>-1;i--)
{
p=p*x+a[i];
}
return p;
}
int main()
{
double x,a[]={5,-1.0/3,-7,4,-1.0/2,5};//多项式的系数,从零次幂到最高次幂
int n=sizeof(a)/sizeof(a[0]);
printf("请输入x的值:\n");
scanf("%lf",&x);
printf("P(x)=%f\n",P(a,x,n));
system("pause");
return 0;
}
2、微元法求定积分
这个函数参考《C语言程序设计》高建华等 P203
原理:
#include <cstdio>
int main()
{
float f1(float);
float integral(float,float,int,float(*)(float));
float a,b,v;//上下界及结果
int n; //分的总段数,越大结果越精确
printf("Please input the low limit and the upper limit:\n");
scanf("%f%f",&a,&b);
printf("Please input the number of sections:\n");
scanf("%d",&n);
v=integral(a,b,n,f1);
printf("v=%.2f",v); //输出积分结果
return 0;
}
float f1(float x)
{//计算不同的被积分函数,要改一下
return 1+x+x*x+x*x*x;
}
float integral(float a,float b,int n,float(*p)(float x))
{//求积分的函数,不用改 函数指针作为函数参数
int i;
float h,s=0;
h=(b-a)/n; //步长
s=((*p)(a)+(*p)(b))/2;
for(i=1;i<n;i++)
{
s+=(*p)(a+i*h);
}
return h*s;
}
3、二分法解非线性方程
这个函数参考《计算方法》李大美等 P198
二分法的计算步骤:将(a,b)二等分,判断子区间端点处函数值是否异号,如果异号,则方程的解在此子区间内,并将此子区间继续二分,直到找到满足精度要求的解.下面给出二分法实现的源代码:
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define PI 3.1415926535
typedef double(*pFUNCTION)(double);
/**
求函数在dX处的导函数值
@param pFunc待解方程对应的函数指针
@param dStartX X值初始起点值
@param dEndX X值初始终点值
@param dAccuracyX X值精度
@param dAccuracyY Y值精度
return 输出解的X值
@note若输入起点值和终点值使得待解函数值都为正或都为负
方法失效
*/
double Dichotomy(pFUNCTION pFunc, double dStartX,double dEndX, double dAccuracyX, double dAccuracyY)
{
double dStartY = (*pFunc)(dStartX);
double dEndY = (*pFunc)(dEndX);
static int K = 0;//迭代递归数
++K;
dAccuracyX = fabs(dAccuracyX);
dAccuracyY = fabs(dAccuracyY);
if (fabs(dStartY) <= dAccuracyY)
{
printf("Y达到最小值\n");
printf("迭代次数:%d;%lg;Y:%lg\n", K, dStartX, dStartY);
return dStartX;
}
else if (fabs(dEndY) <= dAccuracyY)
{
printf("Y达到最小值\n");
printf("迭代次数:%d;X:%lg;Y:%lg\n", K, dEndX, dEndY);
return dEndX;
}
else if (dStartY*dEndY > 0)
{
printf("选取的X值和结束的X值不正确,这两个值必须使函数值一正一负\n");
return - 1;
}
else
{
if (fabs(dEndX - dStartX) <= dAccuracyX)
{
printf("X分割达到最小值\n");
printf("迭代次数:%d;%lg;Y:%lg\n", K, dStartX, dStartY);
return dStartX;
}
else
{
double dMidX = (dStartX + dEndX) / 2.0;
double dMidY = (*pFunc)(dMidX);
if (dStartY*dMidY < 0)
dEndX = dMidX;
else
dStartX = dMidX;
return Dichotomy(pFunc, dStartX, dEndX, dAccuracyX, dAccuracyY);
}
}
}
double function(double x)//函数内容
{
return (x*x*x+4*x*x-10);
}
int main()
{
pFUNCTION pFunc = function;
Dichotomy(pFunc, 1, 2,1e-2, 1e-2);
system("pause");
return 0;
}
4、牛顿迭代法求非线性方程
这个函数参考《计算方法》李大美等 P200
#include<stdio.h>
#include<math.h>
#include<cstdlib>
typedef double( * pFUNCTION)(double);
/**
*求函数在dX处的导函数值
* param pFunc函数
* param dXX值点
* return dX值点的导函数值
*/
double df(pFUNCTION pFunc,double dX)
{//导函数
double epsilen=1.0e-4;
return((*pFunc)(dX+epsilen) - (*pFunc)(dX))/epsilen;
}
double NewtonIteration(pFUNCTION pFunc,double dStartX,double
dAccuracyX,double dAccuracyY,int N)
{
double dStartY=(*pFunc)(dStartX);
int K=0;//递归迭代次数
while(K<N)
{
double dCurrX=0;
double dfValue=df(pFunc,dStartX);
if(dfValue<=dAccuracyY){
printf("导函数在%lg值为0\n",dStartX);
return -1;
}//end if
dCurrX=dStartX-( *pFunc)(dStartX)/dfValue;
if(fabs(dCurrX-dStartX)<dAccuracyX){
printf("方程解为:%lg;迭代次数:%d\n",dCurrX,K);
return 0;
}
dStartX=dCurrX;
++K;
}
printf("迭代次数达到最大值%d迭代失败",N);
return 1;
}
//下面是求方程f(x)=x^3+x+1=0在区间[一1,2]内的解的源程序:
double function(double x)
{
return(1+x+x*x*x);
}
int main()
{
pFUNCTION pFunc=function;
NewtonIteration(pFunc,-1,1e-4,1e-8,1000);
system("pause");
return 0;
}