本次更新针对符号计算部分功能进行说明与修复,补充说明符号函数定义,微分方程求解,修复 subs 多字符替换,完善 series 和 int 的语法等功能。
更新方式:
1.完成2.0预览版中的更新操作
2.下载下面的文件,并将里面的代码和文件夹覆盖复制到北太天元安装目录的/plugins/SymPy/scripts下
以下为具体更新内容、旧版问题、新版用法及示例:
原说明文档中仅介绍了 syms 支持定义基础符号变量,无法直接创建符号函数(如 f (x)、g (x,y))。
Syms 支持直接创建符号函数,可一键定义单 / 多变量函数;支持先定义变量再定义函数 或 变量 + 函数同步定义。
% 方式1:先定义变量,再定义函数 syms x % 先创建变量x syms f(x) % 定义单变量函数f(x) syms 'g(x)' % 或使用字符串形式 % 方式2:变量+函数同步定义 syms x f(x) % 定义单个变量 syms t w z(w,t) % 定义多个变量
注意:使用方式1时一定要先定义自变量,然后定义符号函数,否则命令会未生效但不进行报错。
使用 dsolve 函数出现错误,本次修复了部分问题完善语法,并给出了注意事项。
1.S = dsolve(eqn) :求解微分方程 eqn,其中 eqn 是符号方程。使用 diff 和 == 来表示微分方程。例如,diff(y,x) == y 表示方程 dy/dx = y。通过将 eqn 指定为由微分方程组中的方程组成的向量来求解该微分方程组。
2.S = dsolve(eqn,cond) 求解具有初始条件或边界条件 cond 的 eqn。
3.S = dsolve(eqns,conds) 求解具有初始条件或边界条件 conds 的 方程组 eqns。
注意:这里的 eqns 需要使用 horzcat 进行并置或者使用元胞数组, conds 仅支持使用元胞数组的形式。
% 求解一阶微分方程
syms a t f(t)
eqf = eq(diff(f, t), a*f);
disp(dsolve(eqf))
% 输出结果为: C1*exp(a*t)
% 加上初值条件:
disp(dsolve(eqf, eq(subs(f, t, 0), 5)))
% 输出结果为: 5*exp(a*t)
% 求解二阶微分方程:
eqf2 = eq(diff(f, t, 2), a*f);
disp(dsolve(eqf2))
% 输出结果为: C1*exp(-sqrt(a)*t) + C2*exp(sqrt(a)*t)
% 加上两个初值条件:
df = diff(f, t);
conds = {eq(subs(f, t, 0), 0), eq(subs(df, t, 0), 1)};
disp(dsolve(eqf2, conds))
% 输出结果为:exp(sqrt(a)*t)/(2*sqrt(a)) - exp(-sqrt(a)*t)/(2*sqrt(a))
% 求解二元常微分方程组:
syms t y(t) z(t)
eq1 = diff(y,t)==z;
eq2 = diff(z,t)==-y;
eqs = {eq1,eq2};
s = dsolve(eqs);
% 此时会返回 cell 数组:
disp(s{1})
% 输出结果为: Eq(y(t), C1*sin(t) + C2*cos(t))
disp(s{2})
% 输出结果为: Eq(z(t), C1*cos(t) - C2*sin(t))subs 支持多字符替换但是结果不对,应该是命令未生效所致。本次修复了该问题。
syms x y z % 定义符号变量 expr = x + 2*y + 3*z; vars = horzcat(x,y,z); % 使用horzcat将变量并置 syms a b values = horzcat(1,a,b); newexpr = subs(expr,vars,values); % 使用变量替换 disp(newexpr) % 修改前输出结果为 x + 2*y + 3*z (似乎是未生效) % 修改后输出结果为 2*a + 3*b + 1
函数series的语法使用有限,仅支持 series(f),其他情况均报错。在出现错误的基础上也完善了语法功能。
1.series(f):默认按symvar(f,1)变量,在0 点展开至 5 阶
2.series(f, var):指定变量var,在0 点展开至 5 阶
3.series(f, var, a):指定变量var,在a 点展开
4.series(__,Name,Value):指定展开点 ExpansionPoint、阶数 Order(Name-Value 参数)
syms x f = sqrt(x) + x^2; % 待展开函数 % 示例1:默认展开 s1 = series(f); disp(s1) % 示例2:指定展开变量 s2 = series(f,x); disp(s2) % 示例3:指定展开点 s3 = series(f,x,1); disp(s3) % 示例4:指定展开点inf,展开阶数 9 s4 = series(f,x,'ExpansionPoint',Inf,'Order',9); disp(s4)
当指定参数上下界 a,b 时运行报错。对 int 的所有输入参数组合进行的完善。下面是现已支持的语法。
1.F = int(expr) :计算符号表达式 expr 的积分。使用默认积分变量。
2.F = int(expr,var) :计算 expr 关于符号标量变量 var 的不定积分。
3.F = int(expr,a,b) :计算 expr 从 a 到 b 的定积分。使用默认积分变量。
4.int(expr,[a b]) 等效于 int(expr,a,b)。
5.F = int(expr,var,a,b) :计算 expr 关于符号标量变量 var 从 a 到 b 的定积分。
6.int(expr,var,[a b]) 等效于 int(expr,var,a,b)。
7.F = int(___,Name,Value) :使用一个或多个 Name,Value 参量指定附加选项。支持的 Name 包括 'IgnoreSpecialCases', 'PrincipalValue', 'Hold'。
% 示例: % 不定积分 syms x y disp(int(cos(x))) % 输出结果为 sin(x) disp(int(log(x + y), x)) % 输出结果为 x*log(x + y) - x + y*log(x + y) % 定积分、重积分 disp(int(exp(-x), 0, inf)) % 输出结果为 1 disp(int(2*x, sin(y), cos(y))) % 输出结果为 cos(2*y) disp(int(int(exp(-x^2 - y^2), x, -inf, inf), y, -inf, inf)) % 输出结果为 pi % 保持积分号和计算 Cauchy 主值 syms x; disp(int(1/(x - 1), x, 0, 2)) % 输出结果为 nan disp(int(1/(x - 1), x, 0, 2, "Hold", true)) % 输出结果为 Integral(1/(x - 1), (x, 0, 2)) disp(int(1/(x - 1), x, 0, 2, "PrincipalValue", true)) % 0
expand 函数使用均报错,本次解决修复了报错问题。
1.expand(S) 将展开 S 中的所有括号,并通过应用标准恒等式简化 cos(x + y) 等函数的输入。
2.expand(S,Name,Value) 使用一个或多个名称-值对组参量指定的附加选项。支持的 Name 包含 'ArithmeticOnly' 、'IgnoreAnalyticConstraints'。
clear; clc; %% 示例 1:多项式展开 % 展开二项式 (x+y)^2,验证基本的多项式展开功能 syms x y g = expand((x+y)^2); disp(g) % 输出: x^2 + 2*x*y + y^2 dg = diff(g, x); % 对展开后的多项式求关于 x 的导数 disp(dg) % 输出: 2*x + 2*y %% 示例 2:向量元素的批量展开 % 对向量中的每个元素分别进行展开,演示 horzcat 构造向量及批量展开 syms t V = horzcat(sin(2*t), cos(2*t)); % 构造水平向量 [sin(2t), cos(2t)] vf = expand(V); disp(vf) % 输出: Matrix([[2*sin(t)*cos(t), 2*cos(t)^2 - 1]]) %% 示例 4:三角函数展开与 ArithmeticOnly 选项 % 对比默认展开与仅算术展开的效果,演示 ArithmeticOnly 选项的作用 syms x f = (sin(3*x) - 1)^2; disp(expand(f)) % 输出: 16*sin(x)^6 - 24*sin(x)^4 + 8*sin(x)^3 + 9*sin(x)^2 - 6*sin(x) + 1(完全展开三角函数) disp(expand(f, 'ArithmeticOnly', true)) % 输出: sin(3*x)^2 - 2*sin(3*x) + 1(不展开 sin(3*x),仅展开代数部分) %% 示例 5:对数展开与 IgnoreAnalyticConstraints 选项 % 对比默认展开与强制展开对数的效果,演示忽略解析约束的作用 syms a b c f = log((a*b/c)^2); disp(expand(f)) % 输出: log(a^2*b^2/c^2)(默认不展开对数,因涉及定义域限制) disp(expand(f, 'IgnoreAnalyticConstraints', true)) % 输出: 2*log(a) + 2*log(b) - 2*log(c)(强制展开,忽略 a,b,c>0 的约束)
solve 函数在求解多元方程组含有多个解的问题时会出现报错,修复该问题,并输出结构体数组形式包含解。
%% 多元方程组求解,多个解 syms u v % 定义方程组:使用 horzcat 将多个方程水平拼接 % 方程1: 2*u^2 + v^2 = 0 (两个平方项之和为零) % 方程2: u - v = 1 (线性约束) eqns = horzcat(2*u^2 + v^2 == 0, u - v == 1); % 指定求解变量顺序 [v, u] % vars 的顺序会影响返回结构体 S 中字段的排列:S.v 在前,S.u 在后 vars = horzcat(v, u);% 求解方程组 S = solve(eqns, vars)% 输出包含 v,u 字段的1×2结构体,说明有两组解 disp(S.v) % 输出解的v的值 disp(S.u) % 输出解的u的值
注意:多元方程组得到多个解时的结果保存在结构体数组中,数组的大小代表解的个数,结构体中的字段代表未知变量,使用 disp 显示时需要使用类似 disp(S.x) 的形式来分别显示所有解中x的值。
syms x f = x^3; fLog10 = log10(f) disp(fLog10) % 输出 log(x^3)/log(10)
