secant_method

本文介绍了一个使用迭代法求解非线性方程的C语言程序实例。该程序通过输入初值和精度要求,利用迭代公式逐步逼近方程的根,并在每次迭代后输出当前的近似解。当连续两次迭代的结果之差小于预设的精度要求时,迭代过程结束。
#include<stdio.h>
#include<math.h>
double cal(double x)
{
return 4+2.0/3*cos(x);
}
int main()
{
double x0,x1,flag,x;
int N;
printf("x0 x1 flag N\n");
scanf("%lf %lf %lf %d",&x0,&x1,&flag,&N);
int n=1;
while(n<=N)
{
x=x1-cal(x1)*(x1-x0)/(cal(x1)-cal(x0))*1.0;
printf("迭代次数:%d 近似解:%lf",n,x);
if(fabs(x-x1)<flag)
{
printf("");
printf("迭代次数:%d 近似解:%lf",n,x);
return 0;
}
++n;
x0=x1;
x1=x;
}
return 0;
}

import numpy as np import matplotlib.pyplot as plt # 定义方程:4cos(x) - e^x def f(x): return 4 * np.cos(x) - np.exp(x) # 定义牛顿法的导数:-4sin(x) - e^x def df(x): return -4 * np.sin(x) - np.exp(x) # 1. 牛顿法 def newton_method(x0, tol=1e-4, max_iter=100): x = x0 errors = [] iter_count = 0 while iter_count < max_iter: fx = f(x) dfx = df(x) x_next = x - fx / dfx error = abs(x_next - x) errors.append(error) iter_count += 1 if error < tol: return x_next, iter_count, errors x = x_next return x, iter_count, errors # 2. 弦截法(使用图中公式,固定 x0) def secant_method(x0, x1, tol=1e-4, max_iter=100): x_prev = x1 # 初始迭代点 errors = [] iter_count = 0 while iter_count < max_iter: fx_prev = f(x_prev) fx0 = f(x0) # 固定 x0 的函数值 # 图中公式:x_{k+1} = x_k - [f(x_k)/(f(x_k) - f(x0))] * (x_k - x0) x_next = x_prev - (fx_prev / (fx_prev - fx0)) * (x_prev - x0) error = abs(x_next - x_prev) errors.append(error) iter_count += 1 if error < tol: return x_next, iter_count, errors x_prev = x_next return x_prev, iter_count, errors # 3. 快速弦截法(常规弦截法,对比用) def accelerated_secant_method(x0, x1, tol=1e-4, max_iter=100): x_prev = x0 x_curr = x1 errors = [] iter_count = 0 while iter_count < max_iter: fx_prev = f(x_prev) fx_curr = f(x_curr) # 常规弦截法公式:x_{k+1} = x_k - f(x_k) * (x_k - x_{k-1}) / (f(x_k) - f(x_{k-1})) x_next = x_curr - (fx_curr * (x_curr - x_prev)) / (fx_curr - fx_prev) error = abs(x_next - x_curr) errors.append(error) iter_count += 1 if error < tol: return x_next, iter_count, errors x_prev, x_curr = x_curr, x_next return x_curr, iter_count, errors # 初始值设置 x0_newton = np.pi / 4 # 牛顿法初始值 x0_secant = np.pi / 4 # 弦截法固定 x0 x1_secant = np.pi / 2 # 弦截法初始迭代点 x0_acc_secant = np.pi / 4 # 快速弦截法初始值1 x1_acc_secant = np.pi / 2 # 快速弦截法初始值2 # 调用方法求解 root_newton, iter_newton, errors_newton = newton_method(x0_newton) root_secant, iter_secant, errors_secant = secant_method(x0_secant, x1_secant) root_acc_secant, iter_acc_secant, errors_acc_secant = accelerated_secant_method(x0_acc_secant, x1_acc_secant) # 打印结果 print("===== 牛顿法 =====") print(f"根:{root_newton:.6f},迭代次数:{iter_newton}") print(f"误差:{errors_newton[-1]:.6e}") print("\n===== 弦截法(图中公式) =====") print(f"根:{root_secant:.6f},迭代次数:{iter_secant}") print(f"误差:{errors_secant[-1]:.6e}") print("\n===== 快速弦截法(常规弦截法) =====") print(f"根:{root_acc_secant:.6f},迭代次数:{iter_acc_secant}") print(f"误差:{errors_acc_secant[-1]:.6e}") # 绘制迭代误差随迭代次数变化的图形 plt.figure(figsize=(10, 6)) plt.plot(range(1, iter_newton + 1), errors_newton, 'o-', label='牛顿法') plt.plot(range(1, iter_secant + 1), errors_secant, 's-', label='弦截法(图中公式)') plt.plot(range(1, iter_acc_secant + 1), errors_acc_secant, 'd-', label='快速弦截法(常规)') plt.yscale('log') # 对数刻度显示误差 plt.xlabel('迭代次数') plt.ylabel('误差(log scale)') plt.title('迭代误差随迭代次数变化') plt.legend() plt.grid(True) plt.show() 修改上述代码,第二种方法设置一个步长继续计算
06-07
program solve_equation implicit none integer :: method real(8), parameter :: tol = 1.0e-6 real(8) :: root, a, b, x0 ! 主菜单 print *, "请选择求解方法:" print *, "1. 牛顿迭代法" print *, "2. 二分法" print *, "3. 弦截法" read *, method select case (method) case (1) print *, "请输入初始猜测值 x0:" read *, x0 root = newton_method(x0, tol) case (2) print *, "请输入区间 [a, b] 的两个端点:" read *, a, b root = bisection_method(a, b, tol) case (3) print *, "请输入两个初始点 x0 和 x1:" read *, a, b root = secant_method(a, b, tol) case default print *, "无效的选择!" stop end select print *, "方程的根为:", root contains ! 定义函数 f(x) = x^3 - x - 2 function f(x) result(func_val) real(8), intent(in) :: x real(8) :: func_val func_val = x**3 - x - 2 end function f ! 定义导数 f'(x) = 3*x^2 - 1 function df(x) result(deriv_val) real(8), intent(in) :: x real(8) :: deriv_val deriv_val = 3 * x**2 - 1 end function df ! 牛顿迭代法 function newton_method(x0, tol) result(root) real(8), intent(in) :: x0, tol real(8) :: root, x1 integer :: iter = 0, max_iter = 100 x1 = x0 do while (iter < max_iter) root = x1 - f(x1) / df(x1) if (abs(root - x1) < tol) exit x1 = root iter = iter + 1 end do end function newton_method ! 二分法 function bisection_method(a, b, tol) result(root) real(8), intent(in) :: a, b, tol real(8) :: root, fa, fb, fc integer :: iter = 0, max_iter = 100 fa = f(a) fb = f(b) if (fa * fb > 0.0) then print *, "在区间 [a, b] 内没有根!" stop end if do while (iter < max_iter) root = (a + b) / 2.0 fc = f(root) if (fc == 0.0 .or. (b - a) / 2.0 < tol) exit if (fa * fc < 0.0) then fb = fc else fa = fc end if iter = iter + 1 end do end function bisection_method ! 弦截法 function secant_method(x0, x1, tol) result(root) real(8), intent(in) :: x0, x1, tol real(8) :: root, fx0, fx1, temp_x1 integer :: iter = 0, max_iter = 100 fx0 = f(x0) fx1 = f(x1) temp_x1 = x1 ! 创建一个临时变量来避免直接修改 x1 do while (iter < max_iter) root = temp_x1 - fx1 * (temp_x1 - x0) / (fx1 - fx0) if (abs(root - temp_x1) < tol) exit fx0 = fx1 temp_x1 = root fx1 = f(temp_x1) iter = iter + 1 end do end function secant_method end program solve_equation 逐行注释这个程序
最新发布
06-24
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值