#include?stdio.h
創(chuàng)新互聯(lián)公司于2013年創(chuàng)立,先為渝北等服務(wù)建站,渝北等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為渝北企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。
#define?PRECISION?0.000001
#define?ABS(x)?((x)??0???-(x)?:?(x))
double?sqr(double?x)?{
double?g?=?x;
if?(g??0)?{
while?(ABS(g*g-x)??PRECISION)?{
g?=?(g?+?x/g)?/?2;
}
return?g;
}?else?{
return?0;
}
}
/*?delta法解2次方程?*/
int?delta_2(double?A,?double?B,?double?C,?double?sols[])?{
double?delta?=?B?*?B?-?4?*?A?*?C;
if?(ABS(A)??PRECISION)?{
if?(ABS(delta)??PRECISION)?{?/*?delta?==?0?*/
sols[0]?=?-B?/?(2?*?A);
return?1;
}?else?if?(delta??0)?{
sols[0]?=?(-B?-?sqr(delta))?/?(2?*?A);
sols[1]?=?(-B?+?sqr(delta))?/?(2?*?A);
return?2;
}?else?{
return?0;
}
}?else?{
if?(ABS(B)??PRECISION)?{?/*?表達(dá)式為常數(shù),即?A?=?B?=?0,無(wú)解?*/
return?0;
}?else?{?/*?返回一元一次方程的根?*/
sols[0]?=?-C?/?B;
return?1;
}
}
}
/*?牛頓法解3次方程?*/
int?newton_3(double?args[],?double?sols[])?{
double?A=args[0],?B=args[1],?C=args[2],?D=args[3];
double?x0[3];
int?x0_num?=?0;
double?drts[2];?/*?此方程的導(dǎo)數(shù)的根?*/
int?drt_num?=?0;
int?i,?j,?limit_count?=?100;?/*?限制最多100次迭代,防止無(wú)解情況?*/
double?x?=?0,?xn?=?0;?/*?選x初值為0?*/
double?yl?=?0,?yr?=?0;
/*?判斷根的數(shù)量,現(xiàn)獲取導(dǎo)數(shù)的根,即為三次方程的轉(zhuǎn)向點(diǎn)?*/
drt_num?=?delta_2(3?*?A,?2?*?B,?C,?drts);
if?(drt_num?==?0)?{?/*?導(dǎo)數(shù)無(wú)實(shí)根,沒(méi)有?*/
x0_num?=?1;
x0[0]?=?0;
}?else?if?(drt_num?==?1)?{
x0_num?=?1;
x0[0]?=?drts[0]?+?1;
}?else?if?(drt_num?==?2)?{
x?=?drts[0];
yl?=?A*x*x*x?+?B*x*x?+?C*x?+?D;
x?=?drts[1];
yr?=?A*x*x*x?+?B*x*x?+?C*x?+?D;
if?(ABS(yl?*?yr)??PRECISION)?{
x0_num?=?2;
x0[0]?=?drts[0]?-?1;
x0[1]?=?drts[1]?+?1;
}?else?if?(yl?*?yr??0)?{
x0_num?=?1;
if?(A?*?yl??0)?{
x0[0]?=?drts[0]?-?1;
}?else?{
x0[0]?=?drts[1]?+?1;
}
}?else?{
x0_num?=?3;
x0[0]?=?drts[0]?-?1;
x0[1]?=?(drts[0]?+?drts[1])?/?2;
x0[2]?=?drts[1]?+?1;
}
}?else?{?/*?導(dǎo)數(shù)的二次系數(shù)為0,即函數(shù)的三次系數(shù)為0,所以不是三次函數(shù),返回二次結(jié)果?*/
return?delta_2(B,?C,?D,?sols);
}
for?(j?=?0;?j??x0_num;?j++)?{
for?(i?=?0,?x?=?x0[j];?i??limit_count;?i++)?{
xn?=?x?-?(A?*?x*x*x?+?B?*?x*x?+?C?*?x?+?D)?/?(3?*?A?*?x*x?+?2?*?B?*?x?+?C);
if?(xn?-?x??PRECISION??x?-?xn??PRECISION)?{
break;
}
x?=?xn;
}
sols[j]?=?xn;
}
return?x0_num;
}
int?main()?{
double?solutions[3];?/*?最多3個(gè)解?*/
int?i;
int?sol_num?=?0;
double?args[]?=?{3,?6.1407188500,?-7,?-15};?/*?3次方程的4個(gè)系數(shù),Ax^3?+?Bx^2?+?Cx?+?D?,在這里設(shè)置ABCD?*/
if?((sol_num?=?newton_3(args,?solutions))??0)?{
printf("共有%d個(gè)解:\n",?sol_num);
for?(i?=?0;?i??sol_num;?i++)?{
printf("x%d=%lf\n",?i+1,?solutions[i]);
}
}?else?{
puts("方程無(wú)解");
}
return?0;
}
先接代碼吧,然后解釋一下里面的函數(shù):
newton_3 是用牛頓迭代法求三次函數(shù)的解,三次函數(shù)的解有三種情況:(1)有一個(gè)根 (2)有兩個(gè)根 (3)有三個(gè)根。根據(jù)數(shù)學(xué)關(guān)系來(lái)進(jìn)行了各種情況的判斷。有一個(gè)根有兩種情況,分別是導(dǎo)數(shù)恒大于等于零和“導(dǎo)數(shù)等于0”的兩個(gè)根的函數(shù)值在X軸的同側(cè);有兩個(gè)根的情況就是“導(dǎo)數(shù)等于0”的其中一個(gè)根和X軸相切;三個(gè)跟的情況就是“導(dǎo)數(shù)等于0”的兩個(gè)根的函數(shù)值在X軸兩側(cè)。
delta_2 函數(shù)是用Δ法求二次函數(shù)的解,有三種情況:(1)無(wú)實(shí)根 (2)有一個(gè)實(shí)根 (3)有兩個(gè)實(shí)根。
sqr 是用牛頓迭代法計(jì)算平方根的運(yùn)算。math.h里面有sqrt可以實(shí)現(xiàn),但是如果只因這個(gè)函數(shù)而引用math.h有點(diǎn)不值得,正好這道題目是牛頓迭代法的,這里正好寫一個(gè)。
上面的代碼可以解任何一元三次以內(nèi)的函數(shù)的方程根。但是用來(lái)做你的問(wèn)題,其實(shí)沒(méi)有這么復(fù)雜,下面的代碼就可以了,和上面的sqr的實(shí)現(xiàn)差不多。
#include?stdio.h
#define?PRECISION?0.000001
#define?ABS(x)?((x)??0???-(x)?:?(x))
double?sancigenhao(double?y)?{
double?x0?=?y,?x;
while?(1)?{
x?=?x0?-?(x0?*?x0?*?x0?-?y)?/?(3?*?x0?*?x0);
if?(ABS(x?-?x0)??PRECISION)?{
return?x;
}
x0?=?x;
}
}
int?main()?{
printf("x=%lf\n",?sancigenhao(155));
return?0;
}
兩個(gè)方法都可以,用前面的通用方法,就把 A B C D 分別填寫 1 ?0 ?0 ?-155,就能得出解來(lái)。但是后面的方法用來(lái)解三次根號(hào)要簡(jiǎn)單多了
#include "stdio.h"
#include "math.h"
main()
{float x,f,f1; //f代表 f(x)=2x^3-4x^2+5x-18,f1代表 f‘(x)=2*x^2-4*2x^+5 =6*x*x-8*x+5;
x=8; // x的初值可為任意值
do
{
f=2*x*x*x-4*x*x+5*x-18; //f(x)=2x3-4x2+5x-18
f1=6*x*x-8*x+5; //f(x)的導(dǎo)數(shù): f‘(x)=2*3* x^2 - 4*2 *x+5 =6*x*x-8*x+5;
x=x-f/f1;
}while(fabs(f)0.00001);
printf("x=%f,f=%f\n",x,f);
}
#includestdio.h
#includemath.h
int main()
{
float x1,x,f1,f2;static int count=0;
x1=1.5//定義初始值
do
{
x=x1;
f1=x*(2*x*x-4*x+3)-6;
f2=6*x*x-8*x+3;//對(duì)函數(shù)f1求導(dǎo)
x1=x-f1/f2; count++;
}while(fabs(x1-x)=1e-5);
printf("%8.7f\n",x1); printf("%d\n",count);
return 0;
}
//2x3-4x2+3x-6//根據(jù)我改了初始值,查看結(jié)果,表明:改變初始值得到的結(jié)果并不一樣,但是迭代的次數(shù)并沒(méi)有改變?。?/p>
給你一點(diǎn)提示。
牛頓迭代法要計(jì)算
(1) y1=f(x) 在 x 的函數(shù)值
(2) d1=f(x) 的一階導(dǎo)數(shù) 在 x 的值
你可以寫兩個(gè)函數(shù),分別計(jì)算y1,d1
如果一階導(dǎo)數(shù)有解析解,則可用賦值語(yǔ)句,否則要寫數(shù)值解子程序。
步驟:
設(shè)解的精度,例 float eps=0.000001;
設(shè)x初值,x1;
算y1=f(x1);
迭代循環(huán)開(kāi)始
算一階導(dǎo)數(shù) 在 x1 的值 d1
用牛頓公式 算出 x2; [x2 = x1 - y1 / d1]
如果 fabs(x2-x1) eps 則從新迭代 -- 用新的函數(shù)值和一階導(dǎo)數(shù)值推下一個(gè) 新x.
#includestdio.h
#includemath.h
int a,b,c,d;
float f(float x)
{ float y;
y=((a*x+b)*x+c)*x+d;
return(y);
}
float f1(float x)
{ float y;
y=(3*a*x+2*b)*x+c;
return(y);
}
void main()
{ float x0=1.0,x1;
printf("請(qǐng)輸入a,b,c,d的值:\n");
scanf("%d,%d,%d,%d",a,b,c,d);
x1=1;
do
{
x0=x1;
x1=x0-f(x0)/f1(x0);
}
while(fabs(x1-x0) =0.00001);
printf("%f",x1);
}
牛頓迭代法:
牛頓迭代法(Newton's?method)又稱為牛頓-拉弗森方法(Newton-Raphson?method),它是一種在實(shí)數(shù)域和復(fù)數(shù)域上近似求解方程的方法。方法使用函數(shù)的泰勒級(jí)數(shù)的前面幾項(xiàng)來(lái)尋找方程的根。
分享標(biāo)題:c語(yǔ)言牛頓法求函數(shù),c語(yǔ)言用牛頓迭代法求方程
瀏覽地址:http://jinyejixie.com/article46/hojhhg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、手機(jī)網(wǎng)站建設(shè)、外貿(mào)建站、微信公眾號(hào)、建站公司、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)