2009-11-25 54 views
3

我正在尝试编写一个Matlab程序,该程序接受来自用户的系统变量,但存在比系统参数更多的变量。具体而言,六个变量在三个方程:在超参数化系统中求解变量

w - d - M = 0 
l - d - T = 0 
N - T + M = 0 

这可以用矩阵形式表示为A*x=0其中

A = [1 0 0 -1 0 -1; 
    0 1 0 -1 -1 0; 
    0 0 1 0 -1 1]; 

x = [w l N d T M]'; 

我希望能够解决这个系统给出的已知子集变量。例如,如果用户给出d,T,M,那么对于其他三个变量,系统可以得到平凡解决。如果用户提供w,N,M,则它变成可解的3-DOF系统。等等。 (如果用户过度或不足指定系统然后错误当然可以结果。的)

鉴于这些组合起来很简单的任何一个(先验)使用矩阵代数来计算未知量。但我不知道如何解决一般情况,除了使用符号工具箱(为了兼容性原因,我不想这么做)。

当我开始使用这种方法时,我认为这一步很简单,但我的线性代数是生锈的;我错过了一些简单的东西吗

回答

4

首先,让x为具有未知值的NaN的向量。这允许您使用ISNAN来查找未知数的独立性。如果只计算用户指定的术语A*x,则会给出一列常量b。将这些常数放在等式的右边,并且您有一个形式为A*x = -b的等式。

A = [1 0 0 -1 0 -1; 
    0 1 0 -1 -1 0; 
    0 0 1 0 -1 1]; 

idx = ~isnan(x); 
b = A(:,idx)*x(idx); % user provided constants 
z = A(:,~idx)\(-b); % solution of Ax = -b 
x(~idx) = z; 

随着输入x = [NaN NaN NaN 1 1 1]',例如,你得到的结果[2 2 0 1 1 1]'。这使用MLDIVIDE,我不太熟悉线性代数,知道PINV或其他什么会更好。

+0

这看起来很有前途,谢谢! – 2009-11-25 12:12:43

+0

事实上,它就像一个魅力:)看到解决方案之后,我应该能够为自己想象......对我来说,太长的一个晚上,我想! – 2009-11-25 12:30:56

0

方程组是固定的吗?如果你存储存在的变量在三个方程中的每公式列表:

(w, d, M) 
(l, d, T) 
(N, T, M) 

然后你得到了用户的输入,你可以计算出每个方程在给定的变量数:

User input: w, N, M 
Given variables: 
(w, d, M) -> 2 
(l, d, T) -> 0 
(N, T, M) -> 1 

这可以从第一个等式中得到d。因此,你最终得到两个包含两个变量的方程,并且你知道你需要解决的方程系统。

它基本上是您自己的简单符号求解器,适用于单个方程组。

+0

是的,这就是我想要做的......但这是我在这里遇到麻烦时遗漏的细节。我同意用代数方法很容易,但棘手的部分通常是这样做的(但也许我总是过于乐观/雄心勃勃)。 – 2009-11-25 12:10:38

3

鉴于线性系统

A = [1 0 0 -1 0 -1; 
    0 1 0 -1 -1 0; 
    0 0 1 0 -1 1]; 

A*x = 0 

其中x的元素被确定为:

x = [w l N d T M]'; 

现在,假设{d,T,M}已经已知的固定值。我们需要的是这些元素的索引。我们选择了x的第4,第5和第6个元素作为知识。

known_idx = [4 5 6]; 
unknown_idx = setdiff(1:6,known_idx); 

现在,让我为这些已知变量挑选一些任意数字。

xknown = [1; -3; 7.5]; 

我们将A分成两个子矩阵,分别对应已知和未知变量。

Aknown = A(:,known_idx); 
Aunknown = A(:,unknown_idx); 

现在,将已知值移动到相等的右侧,然后求解。看到Aknown是一个3x3矩阵,所以问题是(希望)很好地提出。

xunknown = Aunknown\(-Aknown*xknown) 
xunknown = 
     -8.5 
      2 
     10.5 

将这一切结合到最终的解决方案中。

x = zeros(6,1); 
x(known_idx) = xknown; 
x(unknown_idx) = xunknown; 
x = 
     -8.5 
      2 
     10.5 
      1 
      -3 
      7.5 

请注意,我已将这一切扩展为几行,以便更清楚地显示发生的情况。但是我可以在一行或两行代码中完成所有工作,但我希望能够简化。

最后,看看我选择了其他几组数字作为知识,例如{l,d,T},那么所得到的系统将是单数的。所以你必须注意那个事件。对Aunknown排名进行测试可能有助于清除问题。或者你可以选择使用pinv来构建解决方案。