如何编码依赖于其他矢量化表达式的矢量化表达式?

时间:2016-01-27 10:20:05

标签: matlab vectorization

例如,如果我有三个表达式:ABC,如下所示:

A(i+1) = A(i) + C(i).k
B(i+1) = B(i) + A(i).h
C(i+1) = A(i) + B(i)

其中kh是一些常量,mnC的所需大小。 i是之前获得的值,i+1是下一个值。现在,如果我使用for循环,那么我可以将其编码为:

A(1)= 2;
B(1)= 5;
C(1)= 3;
for i=1:10
    A(i+1) = A(i) + C(i)*2;
    B(i+1) = B(i) + A(i)*3;
    C(i+1) = A(i) + B(i);
end

它运作得很好。但我希望以矢量形式对其进行编码,而不必使用循环。但问题是我不知道如何绕过依赖:

  • A关于其之前的值和之前的C
  • B上的C
  • 之前的值和A
  • C关于AB
  • 之前的值

2 个答案:

答案 0 :(得分:7)

这是一种基于矩阵的方法,用于获取n向量的[A;B;C] - 值。我不会把它称为矢量化,但这可以为你加快速度:

[A,B,C] = deal(zeros(11,1));
A(1)= 2;
B(1)= 5;
C(1)= 3;

%% // Original method
for k=1:10
  A(k+1) = A(k) + C(k)*2;
  B(k+1) = B(k) + A(k)*3;
  C(k+1) = A(k) + B(k);
end

%% // Matrix method:
%// [ A ]     [1  0  2][ A ]
%// | B |  =  |3  1  0|| B |
%// [ C ]     [1  1  0][ C ]
%//      i+1                i
%// 
%// [ A ]     [1  0  2][ A ]        [1  0  2]   ( [1  0  2][ A ] )
%// | B |  =  |3  1  0|| B |    =   |3  1  0| * ( |3  1  0|| B | )
%// [ C ]     [1  1  0][ C ]        [1  1  0]   ( [1  1  0][ C ] )
%//      i+2                i+1                                 i

%// Thus, this coefficient matrix taken to the n-th power, multiplied by the input 
%// vector will yield the values of A(n+1), B(n+1), and C(n+1):
M = [1 0 2
     3 1 0
     1 1 0];
isequal(M^10*[A(1);B(1);C(1)],[A(11);B(11);C(11)])

实际上,您可以M使用适当的权力(正面或负面)从任何[A,B,C] k获取任何[A,B,C] n < / sub> ...

答案 1 :(得分:5)

首先,请原谅我滥用Matlab语法表达数学内容。

请考虑以下代码,我们的示例与您的示例完全相同。请注意,A,B,CX的行。

X = zeros(3,N+1);
X(:,1) = [2,5,3];
M= [1,0,2;3,1,0;1,1,0];
for i=1:N
X(:,i+1) = M*X(:,i);
end

这只是上述代码的矩阵向量符号。我认为它甚至更慢。请注意,我们还可以计算:X(:,i+1) = M^i * X(:,1)甚至更慢。

请注意,我们可以使用特征值分解:

[V,D] = eigs(M);
X(:,i+1) = [V*D*inv(V)]^i * X;

因此

X(:,i+1) = V*D^i*inv(V) * X;

所以V*D^i*inv(V)i+1 X期的明确公式。我建议用分析方法计算这些,然后再次将你得到的公式插入代码中。

编辑:我写了一些应该接近分析解决系统的代码,你可以比较运行时。看来最终预分配与您的第一种方法仍然是最快 IF 您需要 ALL 这些条款。如果你只需要其中一个,我建议的方法肯定更快。

clear;clc
N = 10000000;
tic
    A(1)= 2;
    B(1)= 5;
    C(1)= 3;
    A = zeros(1,N+1);
    B=A;C=A;
    for i=1:N
    A(i+1) = A(i) + C(i)*2;
    B(i+1) = B(i) + A(i)*3;
    C(i+1) = A(i) + B(i);
    end
toc

tic
    X = zeros(3,N+1);
    X(:,1) = [2,5,3];
    M= [1,0,2;3,1,0;1,1,0];
    for i=1:N
    X(:,i+1) = M*X(:,i);
    end
toc



tic
    M= [1,0,2;3,1,0;1,1,0];
    [V,D]=eig(M); 
    v=0:N;
    d=diag(D);
    B=bsxfun(@power,repmat(d,1,N+1),v);
    Y=bsxfun(@times,V * B, V \[2;5;3]);
toc


tic
    M= [1,0,2;3,1,0;1,1,0];
    [V,D]=eig(M); 
    v=0:N;
    d=diag(D);
    Y = ones(3,N+1);
    for i=1:N
    Y(:,i+1) = d.*Y(:,i);
    end
    Y=bsxfun(@times,V * B, V \[2;5;3]);
toc