方程求根——牛顿迭代法

这段代码实现了牛顿切线法、简化牛顿法和牛顿下山法这三种方程求解法,由于输出结果较长,只以牛顿下山法为例写一段例题

  1.代码

%%牛顿迭代法
%%method为-1时为牛顿切线法,method为0时为简化牛顿法,method为1时为牛顿下山法
%%f是表达式f(x) = 0,X0是初值,epsilon是精度,interval是包含解的区间
function NM = Newton_method(f,X0,epsilon,interval,method)

Y0 = subs(f,X0);
%%作图
t = interval(1):(interval(2)-interval(1))/1000:interval(2);
T = subs(f,t);
T1 = zeros(1,max(size(t)));
Y1 = subs(f,X0)+subs(diff(f),X0)*(t-X0);
h = figure;
set(h,‘color‘,‘w‘);
plot(t,T,‘c‘,t,Y1,‘g‘,X0,Y0,‘ro‘,t,T1,‘y‘);
grid on;
xlabel(‘x shaft‘);ylabel(‘y shaft‘);
title(‘函数图像‘);
hold on

x(1) = X0;
ub = 100;e = floor(abs(log(epsilon)));

if method == -1
    disp(‘牛顿切线法‘);
    for i = 2:ub
        x(i) = x(i-1)-subs(f,x(i-1))/subs(diff(f),x(i-1));
        delta = x(i)-x(i-1);
        if abs(delta) < epsilon
            break;
        end
    end
    disp(‘迭代次数为:‘);
    i-1
    disp(‘迭代解为:‘);
    NM = vpa(x,e);
    X_end = x(i);
    Y_end = subs(f,X_end);

    X = double([X0 X_end]);Y = double([Y0 Y_end]);
    Y2 = Y_end+subs(diff(f),X_end)*(t-X_end);
    plot(t,Y2,‘b‘,X_end,Y_end,‘mo‘);
    legend(‘T:函数图像‘,‘Y1:初始点处切线‘,‘Y0:初始值处切点‘,‘T1:直线y=0‘,‘Y2:迭代解处的切线‘,‘Y_end:迭代解处切点‘);

    for i = 1:2
        text(X(i),Y(i),[‘(‘,num2str(X(i)),‘,‘,num2str(Y(i)),‘)‘],‘color‘,[0.02 0.79 0.99]);
    end

elseif method == 0
    disp(‘简化牛顿法‘);
    for i = 2:ub
        x(i) = x(i-1)-subs(f,x(i-1))/subs(diff(f),x(1));
        delta = x(i)-x(i-1);
        if abs(delta) < epsilon
            break;
        end
    end
    disp(‘迭代次数为:‘);
    i-1
    disp(‘迭代解为:‘);
    NM = vpa(x,e);
    X_end = x(i);
    Y_end = subs(f,X_end);

    X = double([X0 X_end]);Y = double([Y0 Y_end]);
    Y2 = Y_end+subs(diff(f),X_end)*(t-X_end);
    plot(t,Y2,‘b‘,X_end,Y_end,‘mo‘);
    legend(‘T:函数图像‘,‘Y1:初始点处切线‘,‘Y0:初始值处切点‘,‘T1:直线y=0‘,‘Y2:迭代解处的切线‘,‘Y_end:迭代解处切点‘);

    for i = 1:2
        text(X(i),Y(i),[‘(‘,num2str(X(i)),‘,‘,num2str(Y(i)),‘)‘],‘color‘,[0.02 0.79 0.99]);
    end

elseif method == 1
    disp(‘牛顿下山法‘);
    lambda = input(‘输入下山因子:‘);
    for i = 2:ub
        x(i) = x(i-1)-lambda*subs(f,x(i-1))/subs(diff(f),x(1));
        delta = x(i)-x(i-1);
        if abs(delta) < epsilon
            break;
        end
    end
    disp(‘迭代次数为:‘);
    i-1
    disp(‘迭代解为:‘);
    NM = vpa(x,e);
    X_end = x(i);
    Y_end = subs(f,X_end);

    X = double([X0 X_end]);Y = double([Y0 Y_end]);
    Y2 = Y_end+subs(diff(f),X_end)*(t-X_end);
    plot(t,Y2,‘b‘,X_end,Y_end,‘mo‘);
    legend(‘T:函数图像‘,‘Y1:初始点处切线‘,‘Y0:初始值处切点‘,‘T1:直线y=0‘,‘Y2:迭代解处的切线‘,‘Y_end:迭代解处切点‘);

    for i = 1:2
        text(X(i),Y(i),[‘(‘,num2str(X(i)),‘,‘,num2str(Y(i)),‘)‘],‘color‘,[0.02 0.79 0.99]);
    end
end

  2.例子

clear all
clc
syms x;
f = x^exp(x)-1;
X0 = 0.8;
epsilon=1e-6;
interval = [0,2];
method = 1;

%%牛顿下山法
X = Newton_method(f,X0,epsilon,interval,method)

  结果如下

牛顿下山法
输入下山因子:0.8
迭代次数为:
ans =
    21
迭代解为:
X =
[ 0.8, 1.025142203855, 0.9839179688712, 1.008330092139, 0.995101056432, 1.002691649998, 0.9984619264687, 1.000859946529, 0.99951321039, 1.000273650001, 0.9998455622605, 1.000086966616, 0.9999509665425, 1.000027626624, 0.9999844283422, 1.000008774959, 0.9999950545033, 1.000002787045, 0.9999984292923, 1.000000885191, 0.9999995011337, 1.000000281144]

  

由于迭代函数原因,图象上的数据显示出现了遮挡,这一部分的代码以后再进行优化

原文地址:https://www.cnblogs.com/guliangt/p/12119173.html

时间: 2024-10-11 16:49:25

方程求根——牛顿迭代法的相关文章

关于方程求根的解决方案

对于方程求根主要的思想主要采取迭代的思想,通过条件判断,循环执行直到满足条件以后直接跳出循环输出 下面以x-cos(x)=0:为例  采用do-while 循环,输出Root: #include "stdio.h"#include "math.h"#include "stdio.h"double fun(){ double x1=0,x0; do { x0=x1; x1=cos(x0); } while(fabs(x0-x1)>=1e-6)

方程求根——二分法

二分法求根主要应用了区间套定理,这一算法实现简单且结果也迭代的较好,但对于复杂函数其结果不理想 1.代码 %%二分法求根 %%f为函数表达式,interval0为初始区间,epsilon为控制精度 function RD = Roots_dichotomy(f,interval0,epsilon) x_low = interval0(1);x_up = interval0(2);x_ave = (x_low+x_up)/2; %%作图 t = x_low:(x_up-x_low)/1000:x_

方程求根——两种加速迭代法

这段代码实现了埃特金加速迭代法和斯特芬森加速迭代法,我们以斯特粉森迭代为例 1.代码 %%注意,这里的fei不再是形如f(x)=0的形式而是x=fei(x)的形式,有些fei(x)不收敛,需要寻找,X0是初始值,method取值0和1代表上述两种方法 function AIM = Accelerated_iteration_method(fei,X0,epsilon,method) %%作图 t = X0/2:X0/1000:2*X0; T = subs(fei,t); y0 = t; h=fi

方程求根

一. 二分法 题目:用二分法求方程x3-2x-5=0在区间[2,3]内的一个实根,要求误差不超过0.01. 1 #include <iostream> 2 using namespace std; 3 4 double f(double x) 5 { 6 return x*x*x - 2*x - 5; 7 } 8 9 int main() 10 { 11 double left = 2.0, right = 3.0; 12 double mid; 13 while(right - left &

c语言:用牛顿迭代法求方程在1.5附近的根:2x^3-4x^2+3x-6=0.

用牛顿迭代法求方程在1.5附近的根:2x^3-4x^2+3x-6=0. 解:牛顿迭代法又叫牛顿切线法.设f =2x^3-4x^2+3x-6,f1为方程的导数,则f1 = 6x^2 - 8x+3,且f1=(f(x0)-0)/(x0-x1),推导得:x1 = x0 - f / f1 程序: #include<stdio.h> #include<math.h> int main() { double x0,x1,f,f1; x1 = 1.5; do { x0 = x1; f = 2*x0

牛顿迭代法 求方程根

牛顿迭代法 牛顿迭代法(Newton's method)又称为牛顿-拉夫逊方法(Newton-Raphson method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法.多数方程不存在求根公式,因此求精确根非常困难,甚至不可能,从而寻找方程的近似根就显得特别重要. 方法使用函数f(x)的泰勒级数的前面几项来寻找方程f(x) = 0的根.牛顿迭代法是求方程根的重要方法之一,其最大优点是在方程f(x) = 0的单根附近具有平方收敛,而且该法还可以用来求方程的重根.复根,此时线性

c程序设计 8.12 用牛顿迭代法求根。方程为:ax^3+bx^2+cx+d=0 ,系数a,b,c,d由主函数输入。求X在1附近的一个实根。求出后由主函数输出.

//https://baike.baidu.com/item/%E7%89%9B%E9%A1%BF%E8%BF%AD%E4%BB%A3%E6%B3%95/10887580?fr=aladdin#4 //百度牛顿迭代法 #include <stdio.h> #include <math.h> double solut(double a,double b,double c,double d) { double x1=1,x,f,f1; //迭代 do { x=x1; f=((a*x+b

C语言之基本算法25—牛顿迭代法求方程近似根

//牛顿迭代法! /* ============================================================ 题目:用牛顿迭代法求解3*x*x*x-2*x*x-16=0的近似解. ============================================================ */ #include<stdio.h> #include<math.h> #define E 1e-8 double hs(double x) {

OJ刷题之《牛顿迭代法求根》

题目描述 用牛顿迭代法求根.方程为ax3+bx2+cx+d=0.系数a,b,c,d的值一次为1,2,3,4,由主函数输入.求x在1附近的一个实根.求出根后由主函数输出.结果保留两位小数. 输入 系数a,b,c,d的值 输出 x在1附近的一个实根 样例输入 1 2 3 4 样例输出 -1.65 提示 主函数已给定如下,提交时不需要包含下述主函数 /* C代码 */ int main() { double solut(double ,double ,double ,double ); double