【问题标题】:How to extract coefficients of variables in a matrix in Matlab如何在Matlab中提取矩阵中变量的系数
【发布时间】:2016-02-06 04:59:24
【问题描述】:

假设我有下面的矩阵:

syms x y z
M = [x+y-z;2*x+3*y+-5*z;-x-y6*z];

我想要一个由变量 x、y 和 z 的系数组成的矩阵:

CM = [1,1,-1;2,3,-5;-1,-1,6];

如果我将CM 乘以[x;y;z],我希望得到M

编辑

我有一个 ODE 系统:

(d/dt)A = B

AB 是方阵。我想解决这些方程组。我不想使用 Matlab 的 ode 求解命令。 如果我把上面的方程组变成:

(d/dt)a = M*a

那么我可以通过矩阵M的特征向量和值轻松求解。这里a是包含变量的列向量,M是从B中提取的系数矩阵。

【问题讨论】:

  • 或者,如果您使用的是符号数学工具箱:[diff(M,x) diff(M,y) diff(M,z)]。我在 2 分钟的搜索中找不到合适的渐变;对于 3 个变量,这可以做到。
  • 变量的实际数量是64个,我需要自动完成。
  • @Daniel 我不想得到解决方案。 CMM 都是 3by3。
  • @MOON 那你看到我的回答了吗?
  • 我添加了symbolic-math 标签。

标签: matlab matrix linear-algebra symbolic-math


【解决方案1】:

由于您似乎在使用符号数学工具箱,您应该以符​​号方式 diff,保存每个变量的导数:

syms x y z;
M=[x+y-z;2*x+3*y-5*z;-x-y+6*z];
Mdiff=[];
for k=symvar(M)
   Mdiff=[Mdiff diff(M,k)];
end

然后你得到

Mdiff =

[  1,  1, -1]
[  2,  3, -5]
[ -1, -1,  6]

如果您想以非字典顺序的方式对列进行排序,那么您需要使用自己的向量而不是 symvar

更新

由于您提到这种方法很慢,因此使用coeffsM 视为其变量的多项式可能会更快:

 syms x y z;
 M=[x+y-z;2*x+3*y-5*z;-x-y+6*z];
 Mdiff2=[];
 varnames=symvar(M);

 for k=1:length(M)
    Mdiff2=[Mdiff2; coeffs(M(k),varnames(end:-1:1))];
 end

请注意,由于某种原因(我不明白)coeffs 的输出与其输入变量列表相比是相反的,这就是为什么我们使用 symvar(M) 的显式反转版本来调用它。

输出:

>> Mdiff2

Mdiff2 =

[  1,  1, -1]
[  2,  3, -5]
[ -1, -1,  6]

作为@horchler pointed out,如果您的符号向量在其组件中具有不同数量的变量,则第二个解决方案将不起作用。由于速度只有在您必须多次执行此操作时才重要,并且您的M 中的参数有许多配置,我建议以参数方式构造M(以便系数也是syms)是可能的,那么您只需执行第一个版本一次。剩下的只是替换到结果中。

【讨论】:

  • 对于大量变量,它会变慢,例如对于 64 个变量,sit 需要 1 秒。因为我必须针对不同的参数进行多次迭代,所以它变得非常慢。有没有更好的方法来做到这一点?
  • 第二种方法只有在M 的每个元素都是同一个完整变量集的函数时才有效。此外,将MdiffMdiff2 预分配为符号矩阵可能是个好主意。
  • @horchler 谢谢,我没有注意到变量。当然,您对预分配是正确的;我没有预先分配的原因是,在我的第一个解决方案中,我没有明确使用索引,并且通过连接构造 Mdiff 更简单。无论如何,应该使用参数矩阵进行一次计算(使用第一个更通用的解决方案),然后将该结果用于参数的各种值。符号数学并不以速度快而著称。
  • M 的元素确实不是同一个完整变量集的函数。
  • @MOON 是否有机会以参数方式定义您的矩阵,这样您就不必分别提取每个矩阵的参数?
猜你喜欢
  • 2017-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多