本文主要介绍如同利用MATLAB的内置函数进行符号计算(solve)和数值求解(fsolve)。

‌引言: 数值计算和符号计算

数值计算处理离散近似数值,存在计算误差;符号计算处理精确数学符号,可实现完全准确的解析推导。两者主要存在以下区别:

(1)‌处理对象‌:

  • 数值计算:以具体数值为运算元素,需预先赋值变量。‌‌
  • 符号计算:以符号(如字母、公式)为运算元素,通过代数规则处理抽象表达式。‌‌‌‌

‌(2)计算精度‌:

  • 数值计算:结果为近似值,存在舍入误差和截断误差,误差累积可能引发病态问题。‌‌
  • 符号计算:结果为绝对精确的解析解,无计算误差。‌‌‌‌

‌(3)运算方式‌:

  • 数值计算依赖离散化方法(如有限元逼近),注重算法稳定性和计算速度。‌‌
  • 符号计算通过数学定理推导,需要更深广的数学知识支撑。‌‌

1. 符号计算(使用solve)

如果你正在处理的是符号方程,或者需要进行公式的推导,可以使用solve函数。使用之前,你需要定义方程和变量为符号类型,然后就可以根据需求对公式进行推导或求得解析解。

1.1 代数方程的求解

对于代数方程组,可以使用solve函数得到精确的解析解。

示例1(求解简单的方程):

假设我们要解的方程是 x 2 − 4 = 0 x^2 - 4 = 0 x24=0

syms x;  % 定义x为符号变量
eqn = x^2 - 4 == 0;  % 定义方程
sol = solve(eqn, x);  % 解方程
disp(sol);  % 显示解

figure,
fplot(x^2 - 4,[-10 10])
grid on

在这里插入图片描述
示例2(求解复杂单变量方程):
s i n ( x ) = x 2 − 1 sin(x) = x^2 - 1 sin(x)=x21

syms x
eqn = (sin(x) == x^2 - 1);
solve(eqn, x)

figure
fplot(sin(x), [-2 2])  
hold on
fplot(x^2 - 1, [-2 2]) 

在这里插入图片描述

示例3(求解多变量方程)

syms a b c x
eqn = (a*x^2 + b*x + c == 0);
answ1 = solve(eqn, x)  % 将x视为未知数求解 
answ2 = solve(eqn, a)  % 将a视为未知数求解
% answ1 =
% -(b + (b^2 - 4*a*c)^(1/2))/(2*a)
% -(b - (b^2 - 4*a*c)^(1/2))/(2*a)
%  
% answ2 =
% -(c + b*x)/x^2

示例4(解非线性方程组):
x 2 + y = 5 x^2 + y = 5 x2+y=5
2 ∗ x − y = 3 2*x - y = 3 2xy=3


syms x y; % 定义符号变量
eq1 = x^2 + y == 5;
eq2 = 2*x - y == 3;
sol = solve([eq1, eq2], [x, y]); % 解方程组
disp(sol)

示例5(解周期函数):

syms x
eqn = (sin(x) == 1);
[answ, params, condions] = solve(eqn, x, 'ReturnConditions', true)
answ =pi/2 + 2*pi*k
params =k 
condions =in(k, 'integer')

1.2 微分方程的求解

对于微分方程,MATLAB同样使用solve函数(在符号计算工具箱中)。例如,解常微分方程:

d y / d t = x + y dy/dt = x + y dy/dt=x+y
d x / d t = − y dx/dt = -y dx/dt=y

首先,你需要定义一个符号函数来表示:

syms t x(t) y(t); % 定义符号变量和函数
eq1 = diff(x) == x + y; % 对x求导
eq2 = diff(y) == -y; % 对y求导
sol = dsolve([eq1, eq2]); % 解微分方程组
disp(sol)

%x=C2*exp(t) - (C1*exp(-t))/2
%y=C1*exp(-t)

2. 数值计算(使用fsolve)

fsolve是一个优化函数,可以解决复杂的方程问题,他所接受的函数不能仅仅是一个字符变量,需要重新创造函数文件,而函数文件的格式也有要求。

如果你需要解决的是一个数值方程,可以使用fsolve函数。这种方法通常用于找到方程的数值解,而不是符号解。

假设我们要解的方程是 x 2 − 4 = 0 x^2 - 4 = 0 x24=0

func = @(x) x^2 - 4;  % 定义函数句柄
x0 = 2;  % 初始猜测值
[x_sol, fval, exitflag, output] = fsolve(func, x0);  % 解方程
disp(['解为: ', num2str(x_sol)]);  % 显示解

3. 非线性方程组的数值解(使用fsolve)

对于非线性方程组,可以使用fsolve函数进行数值求解,而不是符号计算中的solve。
如果你有多个非线性方程需要解决,也可以使用fsolve。你需要定义一个函数来返回所有方程的向量形式。

示例:

假设我们要解的方程组是:

x + y = 3 x + y = 3 x+y=3

x 2 + y 2 = 5 x^2 + y^2 = 5 x2+y2=5

function F = myEquations(vars)
    x = vars(1);
    y = vars(2);
    F(1) = x + y - 3;  % 第一个方程
    F(2) = x^2 + y^2 - 5;  % 第二个方程
end
 
vars0 = [1, 1];  % 初始猜测值向量
[vars_sol, resnorm, residual, exitflag, output] = fsolve(@myEquations, vars0);
disp(['解为: x = ', num2str(vars_sol(1)), ', y = ', num2str(vars_sol(2))]);

以上就是在MATLAB中解决方程和方程组的基本方法。选择哪种方法取决于你的具体需求,是要求解符号方程还是数值方程。对于符号计算,solve是一个很好的选择;对于数值计算,特别是需要迭代求解的复杂情况,fsolve是非常有效的工具。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐