[已解决] subs效率非常低该怎么破

[复制链接]
rogerdelanostin 发表于 2022-6-16 11:48:02
我有一个syms的(含变量有560个)矩阵560*560,矩阵是通过matlab微积分分求出来,带有变量560个,这560个变量分布在矩阵的每个位置上。
c = subs(J,q,p0);
—J是生成的syms矩阵560*560,q是含有560个变量组成的向量,p0是我要替换的数值组成的向量。subs处理这类问题效率极低。
看过很多方法:
1、matlabFunction,效率更慢;
2、str2func,变量太多,@变量的时候需要一个一个敲,太麻烦;(若有人能解决也可以)
3、symfun,与2同理,变量太多,变量可以向量代替,但是输入不能用向量代替,需要一个一个敲。

有什么比较好的思路提供一下,谢谢啦!
c = subs(J,q,p0);

含变量的矩阵

含变量的矩阵

要替换的变量向量

要替换的变量向量

替换的数字矩阵

替换的数字矩阵


最佳答案


maple1314168 发表于 2022-6-16 17:13:59
syms x y
f=[x^2+y^2;x^3];
fun1=matlabFunction(f);
str=sprintf('x(%d),',1:2);
fun=eval(['@(x)fun1(',str(1:end-1),')'])
fun =@(x)fun1(x(1),x(2))
回复此楼

19 条回复


maple1314168 发表于 2022-6-16 17:13:59
syms x y
f=[x^2+y^2;x^3];
fun1=matlabFunction(f);
str=sprintf('x(%d),',1:2);
fun=eval(['@(x)fun1(',str(1:end-1),')'])
fun =@(x)fun1(x(1),x(2))
回复此楼

rogerdelanostin 发表于 2022-6-16 20:29:37
maple1314168 发表于 2022-6-16 17:13
syms x y
f=[x^2+y^2;x^3];
fun1=matlabFunction(f);

大神 关于这个str=sprintf('x(%d),',1:2); 如果中间有间断的变量怎么处理,比如这个是连续的x1,x2,x3,x4,x5...若是中间间断着,比如x1,x2,x4,x5..这样缺少x3...怎么处理

rogerdelanostin 发表于 2022-6-16 20:35:23
rogerdelanostin 发表于 2022-6-16 20:29
大神 关于这个str=sprintf('x(%d),',1:2); 如果中间有间断的变量怎么处理,比如这个是连续的x1,x2,x3,x4, ...

这个间断变量问题我已经处理了,大神先忽略。我把过程发一下,大神看下,貌似也代入不进去。

rogerdelanostin 发表于 2022-6-16 20:56:29
本帖最后由 rogerdelanostin 于 2022-6-17 11:14 编辑
maple1314168 发表于 2022-6-16 17:13
syms x y
f=[x^2+y^2;x^3];
fun1=matlabFunction(f);

fun1=matlabFunction(J);
str=sprintf('q%d,',1:1:12,14:1:25);
fun=eval(['@(q)fun1(',str(1:end-1),')']);
dd=fun(p0);

矩阵{ J }变量是q1,q2,q3......还有乘积q1*q3以及q1^2这种...其实这个还好,只要变量能被代入,这些计算都不是问题。
下载4.png
下载3.png
下载2.png
下载1.png

rogerdelanostin 发表于 2022-6-16 21:28:43
maple1314168 发表于 2022-6-16 17:13
syms x y
f=[x^2+y^2;x^3];
fun1=matlabFunction(f);

大神好,我感觉我知道哪里有问题了,因为我的fun1里面的变量是q1,q2,q3...并非q(1),q(2),q(3)...
所以方程就相当于@(q)fun1(q1,q2,q3,q4,q5,q6,q7,q8,q9,q10,q11,q12,q14,q15,q16,q17,q18,q19,q20,q21,q22,q23,q24,q25),而q在这里并没有参与fun1.相当于此处的q是文本变换成的q,且fun1只有q一个变量的意思。不是我最开始定义的那个q=[q1 q2 q3 q4 q5 q6 q7...]这个,所以我把p0数值向量代换q在fun1里面就不成功。但是,要怎么处理呢。求指教。。

maple1314168 发表于 2022-6-16 22:07:59
rogerdelanostin 发表于 2022-6-16 21:28
大神好,我感觉我知道哪里有问题了,因为我的fun1里面的变量是q1,q2,q3...并非q(1),q(2),q(3)...
所以方 ...

能不能用代码体现出来。
太多的文字都难解释清楚。

rogerdelanostin 发表于 2022-6-17 10:06:23
本帖最后由 rogerdelanostin 于 2022-6-17 10:12 编辑
maple1314168 发表于 2022-6-16 22:07
能不能用代码体现出来。
太多的文字都难解释清楚。
clear;clc
syms q [1,10]
F = [exp(-exp(-(q(1)+q(2)+q(9)))) - q(2)^2*(1+q(3)^2);
      q(1)*q(3)*cos(q(2)) + q(4)^2*sin(q(5)) - 0.5;
      2*q(4)*q(5)*q(7) - q(6) *q(8)- exp(-q(5)^2);
      -q(7)^2 + 2*q(10)*q(1) - exp(-q(9))+exp(-q(8)*q(10))];% 最少的方程组,实际有500-1000个。
  J = jacobian(F,q); % 形成雅各比矩阵
  p0=[1,1,1,2,2,2,2,3,3,3];% 要带入的值。
  J1=subs(J,q,p0);%一般我们会这样带入p0来替换方程里面的q,但是此处效率极低,若方程是1000个左右。
  J2=double(J1);% 变成double形式。
%%用大神的方法
fun1=matlabFunction(J);
str=sprintf('q%d,',1:1:10);
fun=eval(['@(q)fun1(',str(1:end-1),')']);
dd=fun(p0); %借出来的dd是含有q1.q1.q3...未知数的。如图



rogerdelanostin 发表于 2022-6-17 10:16:49
本帖最后由 rogerdelanostin 于 2022-6-17 10:30 编辑
maple1314168 发表于 2022-6-16 22:07
能不能用代码体现出来。
太多的文字都难解释清楚。
clear;clc
% 我的原方程太长了,我简化成以下内容。
syms q [1,10]  %最少的变量 实际可能有1000个左右
F = [exp(-exp(-(q(1)+q(2)+q(9)))) - q(2)^2*(1+q(3)^2);
      q(1)*q(3)*cos(q(2)) + q(4)^2*sin(q(5)) - 0.5;
      2*q(4)*q(5)*q(7) - q(6) *q(8)- exp(-q(5)^2);
      -q(7)^2 + 2*q(10)*q(1) - exp(-q(9))+exp(-q(8)*q(10))];% 最少的方程组,实际有500-1000个。
  J = jacobian(F,q); % 形成雅各比矩阵
  p0=[1,1,1,2,2,2,2,3,3,3];% 要带入的值。
  J1=subs(J,q,p0);%一般我们会这样带入p0来替换方程里面的q,但是此处效率极低,若方程是1000个左右。
  J2=double(J1);% 变成double形式。
%用大神的方法
fun1=matlabFunction(J);
str=sprintf('q%d,',1:1:10);
fun=eval(['@(q)fun1(',str(1:end-1),')']);
dd=fun(p0);%出来的结果是含有q1,q2,..q10的变量的,不是可以转化成double的纯数组。
%我感觉我知道哪里有问题,因为我的fun1里面的变量是q1,q2,q3...并非q(1),q(2),q(3)...
%所以方程相当于@(q)fun1(q1,q2,q3,q4,q5,q6,q7,q8,q9,q10),
%而q在这里并没有参与fun1里面的q(1),q(2),q(3)。。。
%相当于此处的q是文本变换成的q,且fun1只有q一个变量的意思。不是我最开始定义的那个q=[q1 q2 q3 q4 q5 ...]这个,
%所以我把p0数值向量代换q在fun1里面就不成功。

maple1314168 发表于 2022-6-17 10:42:31
本帖最后由 maple1314168 于 2022-6-17 10:44 编辑
rogerdelanostin 发表于 2022-6-17 10:16
clear;clc
% 我的原方程太长了,我简化成以下内容。
syms q [1,10]  %最少的变量 实际可能有1000个左右

你没有按照我的方法写 str!
      str=sprintf('q(%d),',1:10);


rogerdelanostin 发表于 2022-6-17 10:49:59
本帖最后由 rogerdelanostin 于 2022-6-17 11:03 编辑
maple1314168 发表于 2022-6-17 10:42
你没有按照我的方法写 str!
      str=sprintf('q(%d),',1:10);

改过来了!!!感谢大神,连续的变量可以跑了,我还有个小问题请教一下。clear;clc
syms q [1,10]  
F = [exp(-exp(-(q(1)+q(2)+q(9)))) - q(2)^2*(1+q(3)^2);
      q(1)*q(3)*cos(q(2)) + q(6)^2*sin(q(5)) - 0.5;
      2*q(6)*q(5)*q(7) - q(6) *q(8)- exp(-q(5)^2);
      -q(7)^2 + 2*q(10)*q(1) - exp(-q(9))+exp(-q(8)*q(10))];
  J = jacobian(F,q);
  p0=[1,1,1,2,2,2,3,3,3];
%用大神的方法
fun1=matlabFunction(J);
str=sprintf('q(%d),',1:3,5:10); %这里如果有中断的变量,没有q(4),我这样改,就不能用了。
fun=eval(['@(q)fun1(',str(1:end-1),')']);

dd=fun(p0);

maple1314168 发表于 2022-6-17 10:55:59
rogerdelanostin 发表于 2022-6-17 10:49
clear;clc

syms q [1,10]  

自己检查啊!!!!
str=sprintf('q%d,',1:1:10); % 这儿改过来了
str=sprintf('q(%d),',1:1:10)
你用了中文的格式!!

q的建立一般是:
q=sym('q',[1,10]);

rogerdelanostin 发表于 2022-6-17 11:05:50
本帖最后由 rogerdelanostin 于 2022-6-17 12:14 编辑
maple1314168 发表于 2022-6-17 10:55
自己检查啊!!!!
str=sprintf('q(%d),',1:1:10); % 这儿改过来了
str=sprintf('q(%d),',1:1:10)

大神教育的是,,改过来了!!!感谢大神,连续的变量可以跑了,我还有个小问题请教一下。clear;clc
q=sym('q',[1,10]);
F= [exp(-exp(-(q(1)+q(2)+q(9)))) - q(2)^2*(1+q(3)^2);
    q(1)*q(3)*cos(q(2)) + 2^2*sin(q(5)) - 0.5;
    2*2*q(5)*q(7) - q(6) *q(8)- exp(-q(5)^2);
    -q(7)^2 + 2*q(10)*q(1) - exp(-q(9))+exp(-q(8)*q(10))]; % 现在q(4)的值已知,代入方程后消去q(4)变量,相当于此时只剩下9个变量了。
q(:,4)=[]; % 此处删掉一个变量q(4)  
%形成没有q(4)的新矩阵
J = jacobian(F,q);
p0=[1,1,1,2,2,2,3,3,3]; %这儿只有9个代入值了。
%用大神的方法
fun1=matlabFunction(J);
str=sprintf('q(%d),',1:3,5:10);%这里如果有中断的变量,没有q(4),我这样改.
fun=eval(['@(q)fun1(',str(1:end-1),')']);
dd=fun(p0); %这里就跑不了了。

索引超出数组元素的数目(9)。
出错 test_MATLAB_online>@(q)fun1(q(1),q(2),q(3),q(5),q(6),q(7),q(8),q(9),q(10))
出错 test_MATLAB_online (第 13 行)
dd=fun(p0);

maple1314168 发表于 2022-6-17 15:11:38
rogerdelanostin 发表于 2022-6-17 11:05
大神教育的是,,改过来了!!!感谢大神,连续的变量可以跑了,我还有个小问题请教一下。clear;clc
q=sym ...

先看看 fun1有多少个变量!str就生成几个就可以!
一般按照字母的顺序!参数在乎位置,是什么符号没有影响。
@(q1,q2,q3,q5,q6,q7,q8,q9,q10) 。。。。@(q)(q(1),q(2),....,q(9))。。就可以
你自己的p0=[1,1,1,2,2,2,3,3,3]也不知道缺少那一个。

rogerdelanostin 发表于 2022-6-17 17:22:45
本帖最后由 rogerdelanostin 于 2022-6-17 17:28 编辑
maple1314168 发表于 2022-6-17 15:11
先看看 fun1有多少个变量!str就生成几个就可以!
一般按照字母的顺序!参数在乎位置,是什么符号没有影 ...

%% 大神你好,你的意思我明白的,但是依然运行不了,请看以下。
clear;clc
q=sym('q',[1,10]);
F= [exp(-exp(-(q(1)+q(2)+q(9)))) - q(2)^2*(1+q(3)^2);
    q(1)*q(3)*cos(q(2)) + 2^2*sin(q(5)) - 0.5;
    2*2*q(5)*q(7) - q(6) *q(8)- exp(-q(5)^2);
    -q(7)^2 + 2*q(10)*q(1) - exp(-q(9))+exp(-q(8)*q(10))];
% 我已将q(4)的数值代入方程,代入方程后就没有q(4)这个变量了,见上面的F。
%相当于此时只剩下9个变量[q(1) q(2) q(3) q(5) q(6) q(7) q(8) q(9) q(10)] 此处不含q(4).
q(:,4)=[]; % 此处删掉一个变量q(4),形成没有q(4)的新矩阵
J = jacobian(F,q); % 对剩下的变量q向量进行雅各比矩阵。
p0=[1,1,1,2,2,2,3,3,3]; %这儿只有9个代入值(去除q4)。
%用大神的方法
fun1=matlabFunction(J); % 最后形成的是fun1= @(q1,q2,q3,q5,q6,q7,q8,q9,q10)reshape([exp(-q1-q2-q9)......是没有含q4变量的fun1.
str=sprintf('q(%d),',1:3,5:10);% 这里run了之后结果是str= 'q(1),q(2),q(3),q(5),q(6),q(7),q(8),q(9),q(10),'也是不含q4的字符串。
fun=eval(['@(q)fun1(',str(1:end-1),')']); % 这里run了的结果也是fun= @(q)fun1(q(1),q(2),q(3),q(5),q(6),q(7),q(8),q(9),q(10)),不含q4。
dd=fun(p0); % 但是这里就是代入不了。按理来说fun含9个参数,那么p0是9个数值的向量,可以等价替换。但是这里替换不了。问题就在这儿,9个数值换9个变量不成功。我试了下,如果p0换成10个数值就能代入。。但是问题来了,fun不是已经换成了9个变量的函数吗,为啥还要10个数值的向量。

索引超出数组元素的数目(9)。
出错 test_MATLAB_online>@(q)fun1(q(1),q(2),q(3),q(5),q(6),q(7),q(8),q(9),q(10))
出错 test_MATLAB_online (第 17 行)
dd=fun(p0);



maple1314168 发表于 2022-6-17 17:45:03
rogerdelanostin 发表于 2022-6-17 17:22
%% 大神你好,你的意思我明白的,但是依然运行不了,请看以下。
clear;clc
q=sym('q',[1,10]);

当时,这个我没有考虑到。
可以在 p0里面 p0(4) 插上一个随意的数用来占位!

rogerdelanostin 发表于 2022-6-17 19:34:43
maple1314168 发表于 2022-6-17 17:45
当时,这个我没有考虑到。
可以在 p0里面 p0(4) 插上一个随意的数用来占位! ...

可以有办法把这个bug给完善了吗 大神

maple1314168 发表于 2022-6-17 19:38:32
rogerdelanostin 发表于 2022-6-17 19:34
可以有办法把这个bug给完善了吗 大神

这个还是bug吗?
本身p0 中你也不知道缺少那些?
可以读取fun1中的变量,自动补充到p0。这个你可以做吧。

rogerdelanostin 发表于 2022-6-17 20:25:27
maple1314168 发表于 2022-6-17 19:38
这个还是bug吗?
本身p0 中你也不知道缺少那些?
可以读取fun1中的变量,自动补充到p0。这个你可以做吧。 ...

比如这个例子  只能p0(4)处插个值占位吗  p0总共还是要输入10个值。

rogerdelanostin 发表于 2022-6-17 20:27:38
maple1314168 发表于 2022-6-17 19:38
这个还是bug吗?
本身p0 中你也不知道缺少那些?
可以读取fun1中的变量,自动补充到p0。这个你可以做吧。 ...

我验证过了,只有在p0(4)处补充一个任意数结果才不会变,换成其他位置结果都和正确的不一样。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

相关帖子
相关文章
热门教程
站长推荐
快速回复 返回顶部 返回列表