function [c, iter] = bisection(f, a, b, tol, max_iter) iter = 0; while (b - a) / 2 > tol && iter < max_iter c = (a + b) / 2; if f(c) == 0 break; elseif f(a) * f(c) < 0 b = c; else a = c; end iter = iter + 1; end c = (a + b) / 2;end
特点:无条件收敛(只要函数连续且端点异号),线性收敛,每步精度提高一倍。
牛顿迭代法
推导:在 xk 处一阶 Taylor 展开 f(x)≈f(xk)+f′(xk)(x−xk),令其为零得
xk+1=xk−f′(xk)f(xk)
收敛阶:一般情况下二阶收敛(p=2)。重根时退化为一阶。
matlab
function [x, iter] = newton(f, df, x0, tol, max_iter) x = x0; for iter = 1:max_iter fx = f(x); if abs(fx) < tol return; end x_new = x - fx / df(x); if abs(x_new - x) < tol x = x_new; return; end x = x_new; endend
初始值敏感性:当初值远离根时可能发散。可通过先做几步二分法寻找合适的初值。
弦截法
推导:用差商替代导数,过 (xk−1,f(xk−1)) 和 (xk,f(xk)) 作割线:
xk+1=xk−f(xk)f(xk)−f(xk−1)xk−xk−1
收敛阶:超线性收敛,p=21+5≈1.618,无需计算导数。
matlab
function [x, iter] = secant(f, x0, x1, tol, max_iter) for iter = 1:max_iter f0 = f(x0); f1 = f(x1); x2 = x1 - f1 * (x1 - x0) / (f1 - f0); if abs(x2 - x1) < tol x = x2; return; end x0 = x1; x1 = x2; end x = x2;end
3. 线性方程组数值求解
直接法
高斯消元法
将方程组 Ax=b 通过初等行变换化为上三角形式 Ux=b~,然后回代求解。
列主元高斯消元:每步消元前选取当前列绝对值最大元素作为主元,交换行以避免除以小主元造成的误差放大。
matlab
function x = gauss_pivot(A, b) n = length(b); Aug = [A, b]; for k = 1:n-1 [~, p] = max(abs(Aug(k:n, k))); p = p + k - 1; if p ~= k Aug([k, p], :) = Aug([p, k], :); end for i = k+1:n m = Aug(i, k) / Aug(k, k); Aug(i, k:n+1) = Aug(i, k:n+1) - m * Aug(k, k:n+1); end end x = zeros(n, 1); x(n) = Aug(n, n+1) / Aug(n, n); for i = n-1:-1:1 x(i) = (Aug(i, n+1) - Aug(i, i+1:n) * x(i+1:n)) / Aug(i, i); endend
LU 分解
将 A 分解为下三角矩阵 L 和上三角矩阵 U,满足 A=LU。解方程分两步:
前代:Ly=b
回代:Ux=y
Doolittle 分解:L 对角元为 1。对 k=1,…,n:
matlab
function [L, U] = lu_doolittle(A) n = size(A, 1); L = eye(n); U = zeros(n); for k = 1:n U(k, k:n) = A(k, k:n) - L(k, 1:k-1) * U(1:k-1, k:n); for i = k+1:n L(i, k) = (A(i, k) - L(i, 1:k-1) * U(1:k-1, k)) / U(k, k); end endend
计算量:解 n 阶方程组约需 32n3 次浮点运算。
迭代法
将 Ax=b 分裂为 A=D−L−U(D 为对角阵,−L 为严格下三角,−U 为严格上三角)。
Jacobi 迭代
x(k+1)=D−1(L+U)x(k)+D−1b
分量形式:xi(k+1)=aii1(bi−∑j=iaijxj(k))
matlab
function [x, iter] = jacobi(A, b, x0, tol, max_iter) n = length(b); x = x0; for iter = 1:max_iter x_new = zeros(n, 1); for i = 1:n sigma = A(i, 1:i-1) * x(1:i-1) + A(i, i+1:n) * x(i+1:n); x_new(i) = (b(i) - sigma) / A(i, i); end if norm(x_new - x, Inf) < tol x = x_new; return; end x = x_new; endend
function c = newton_coeff(x, y) n = length(x); T = zeros(n, n); T(:, 1) = y(:); for j = 2:n for i = j:n T(i, j) = (T(i, j-1) - T(i-1, j-1)) / (x(i) - x(i-j+1)); end end c = diag(T);end
三次样条插值
在每段 [xi,xi+1] 上用三次多项式拼接,要求:
节点处函数值连续
一阶导数连续
二阶导数连续
自然边界条件 S′′(x0)=S′′(xn)=0 可唯一确定。
MATLAB 内置 spline(x, y, xq) 可直接调用。
5. 数值积分与数值微分
数值积分(Newton-Cotes 公式)
代数精度:若求积公式对所有次数 ≤m 的多项式精确成立,而对 m+1 次多项式不精确,则具有 m 次代数精度。
梯形公式
在 [a,b] 上用一次 Lagrange 插值:
∫abf(x)dx≈2b−a[f(a)+f(b)]
代数精度 1。误差:−12(b−a)3f′′(ξ)。
Simpson 公式
用二次插值(三个等距节点):
∫abf(x)dx≈6b−a[f(a)+4f(2a+b)+f(b)]
代数精度 3。误差:−2880(b−a)5f(4)(ξ)。
复合公式
将 [a,b] 等分为 n 段(h=nb−a):
复合梯形:
Tn=2h[f(a)+f(b)+2i=1∑n−1f(xi)]
误差 O(h2)。
复合 Simpson:
Sn=3h[f(a)+f(b)+4奇数∑f(xi)+2偶数∑f(xi)]
误差 O(h4),需 n 为偶数。
matlab
function I = composite_simpson(f, a, b, n) if mod(n, 2) ~= 0 n = n + 1; end h = (b - a) / n; x = a:h:b; y = f(x); I = h/3 * (y(1) + y(end) + ... 4 * sum(y(2:2:end-1)) + ... 2 * sum(y(3:2:end-2)));end
数值微分
有限差分公式
两点公式:
前向差分:f′(x)≈hf(x+h)−f(x),截断误差 O(h)
后向差分:f′(x)≈hf(x)−f(x−h),截断误差 O(h)
中点差分:f′(x)≈2hf(x+h)−f(x−h),截断误差 O(h2)
三点公式:
端点公式:f′(x0)≈2h−3f(x0)+4f(x1)−f(x2),O(h2)
中点公式:f′(x1)≈2hf(x2)−f(x0),O(h2)
五点中点公式(更高精度):
f′(x)≈12hf(x−2h)−8f(x−h)+8f(x+h)−f(x+2h),O(h4)
基于插值多项式的求导
对 Lagrange 或 Newton 插值多项式直接求导即得数值微分公式,误差源于插值余项的导数项。
6. 常微分方程初值问题
问题的提法
求初值问题 {y′=f(t,y)y(t0)=y0 的数值解。
显式单步法的一般形式:yn+1=yn+hΦ(tn,yn,h)。
欧拉法
向前欧拉(一阶显式):
yn+1=yn+hf(tn,yn)
局部截断误差 O(h2),全局误差 O(h)。
matlab
function [t, y] = euler(f, tspan, y0, h) t = tspan(1):h:tspan(2); y = zeros(length(t), length(y0)); y(1, :) = y0(:)'; for i = 1:length(t)-1 y(i+1, :) = y(i, :) + h * f(t(i), y(i, :))'; endend