matlab解符号方程用subs代入数据速度太慢!解决方法

在用matlab解方程时经常用到符号变量syms,在后续对得到的解进行分析时,本小白采用的方法是用函数subs()进行数据的带入计算。但是方程过于复杂,数据量特别大的时候,发现这种做法非常非常慢!

直接向量化操作求数据是最快的,但是解方程有时候根本解不出来显式解,无法直接向量化操作。这时候可以利用for循环去求解N个数值方程的解来构成数据集,这样做可以避免解符号方程以及用subs求数据集

解一个符号方程,再subs代入N组数据 ,不如直接解N个数值方程!!!

---------------------------------------------------------------------------------(●'◡'●)----------------------------------------------------------------------------------

这里列举我解过的一个矩阵方程加以说明,求解这个含参矩阵J_open的特征值,并绘图分析特征值随参数PL的变化趋势

优化前:

clc;
clear;
tic;

syms P_L;%变量
%参数值如下:
R=4;
C1=24e-6;
C2=24e-6;
L1=360e-6;
L2=480e-6;
r1=0.5;
r2=0.5;
VIN=24;
VREF=36;
D=VREF/(VIN+VREF);
n=D*VIN/(1-D);
m=(D/(1-D))^2*r1+r2;
delta=n^2-4*m*P_L*(1+m/R);
V2OL=(n+sqrt(delta))/(2*(1+m/R));


a11=-r1/L1;
a12=0;
a13=-(1-D)/L1;
a14=0;
a21=0;
a22=-r2/L2;
a23=D/L2;
a24=-1/L2;
a31=(1-D)/C1;
a32=-D/C1;
a33=0;
a34=0;
a41=0;
a42=1/C2;
a43=0;
a44=P_L/(C2*V2OL^2)-1/(R*C2);
J_open=[a11,a12,a13,a14;
    a21,a22,a23,a24;
    a31,a32,a33,a34;
    a41,a42,a43,a44];

tzzopen=eig(J_open);
disp(tzzopen);%方程的解是tzzopen

P_L=100;
start=0;
step=1;
%P_L为0-100时对应的tzzopen数据集:用subs代入参数求数据集
real_tzzopen1=real(subs(tzzopen(1),start:step:P_L));
imag_tzzopen1=imag(subs(tzzopen(1),start:step:P_L));
real_tzzopen2=real(subs(tzzopen(2),start:step:P_L));
imag_tzzopen2=imag(subs(tzzopen(2),start:step:P_L));
real_tzzopen3=real(subs(tzzopen(3),start:step:P_L));
imag_tzzopen3=imag(subs(tzzopen(3),start:step:P_L));
real_tzzopen4=real(subs(tzzopen(4),start:step:P_L));
imag_tzzopen4=imag(subs(tzzopen(4),start:step:P_L));
z=0:step:P_L;
plot3(real_tzzopen1,imag_tzzopen1,z,'r*');
hold on;
plot3(real_tzzopen2,imag_tzzopen2,z,'g*');
plot3(real_tzzopen3,imag_tzzopen3,z,'b*');
plot3(real_tzzopen4,imag_tzzopen4,z,'cyan*');
xline(0);
legend('\lambda1','\lambda2','\lambda3','\lambda4');
xlabel('$Re(\lambda)$','Interpreter','latex');
ylabel('$Im(\lambda)$','Interpreter','latex');
hold off;
t1=toc

t1是1.5288e3,难绷,这个参数变化是从0到100,只有101个数据,数据再多会更慢。。。当时我就是用这段代码分析矩阵出的图,慢的要死,还一度以为我的电脑太垃圾,拖慢科研进度

优化后:

clc;
clear;
tic;

root1_real=[];
root1_imag=[];
root2_real=[];
root2_imag=[];
root3_real=[];
root3_imag=[];
root4_real=[];
root4_imag=[];


P_L=100;
step=1;
start=0;
for i=start:step:P_L
    lambda=SolEigValues(i);
    root1_real=[root1_real,real(lambda(1))];
    root1_imag=[root1_imag,imag(lambda(1))];
    root2_real=[root2_real,real(lambda(2))];
    root2_imag=[root2_imag,imag(lambda(2))];
    root3_real=[root3_real,real(lambda(3))];
    root3_imag=[root3_imag,imag(lambda(3))];
    root4_real=[root4_real,real(lambda(4))];
    root4_imag=[root4_imag,imag(lambda(4))];
end

z=0:step:P_L;
plot3(root1_real,root1_imag,z,'r*');
hold on;
plot3(root2_real,root2_imag,z,'g*');
plot3(root3_real,root3_imag,z,'b*');
plot3(root4_real,root4_imag,z,'cyan*');
%xline(0);
legend('\lambda1','\lambda2','\lambda3','\lambda4');
xlabel('$Re(\lambda)$','Interpreter','latex');
ylabel('$Im(\lambda)$','Interpreter','latex');
hold off;
t2=toc



function y=SolEigValues(PL)

R=4;
C1=24e-6;
C2=24e-6;
L1=360e-6;
L2=480e-6;
r1=0.5;
r2=0.5;
VIN=24;
VREF=36;
D=VREF/(VREF+VIN);
n=D*VIN/(1-D);
m=(D/(1-D))^2*r1+r2;
delta=n^2-4*m*PL*(1+m/R);
V2OL=(n+sqrt(delta))/(2*(1+m/R));

a11=-r1/L1;
a12=0;
a13=-(1-D)/L1;
a14=0;
a21=0;
a22=-r2/L2;
a23=D/L2;
a24=-1/L2;
a31=(1-D)/C1;
a32=-D/C1;
a33=0;
a34=0;
a41=0;
a42=1/C2;
a43=0;
a44=PL/(C2*V2OL^2)-1/(R*C2);
A=[a11,a12,a13,a14;
    a21,a22,a23,a24;
    a31,a32,a33,a34;
    a41,a42,a43,a44];
y=eig(A);
end

t2是0.2338,可见速度差异有多大了。还是看了师兄写的代码才知道,原来它可以这么快,秒出结果。本来是定义符号变量解方程,再用subs将变量数据代入解求取数据集;但这段代码直接写for循环求数值解得到数据集,避免解符号方程,而且写了个SolEigValues函数来求解每个点下的数据解,简化了代码结构。

---------------------------------------------------------------------------------(●'◡'●)----------------------------------------------------------------------------------

综上,直接解数值方程远远快于解符号方程再代入数据,解一个符号方程,再subs代入N组数据 ,不如直接解N个数值方程!

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值