Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab J-by-2矩阵行的块对角化_Matlab - Fatal编程技术网

Matlab J-by-2矩阵行的块对角化

Matlab J-by-2矩阵行的块对角化,matlab,Matlab,例如,给定一个J-by-2矩阵 A = [1 2 ; 3 4 ; 5 6] 我想阻止它对角化。也就是说,我想要: B = [1 2 0 0 0 0 ; 0 0 3 4 0 0 ; 0 0 0 0 5 6]. 执行此操作的一个命令是: blkdiag(A(1,:),A(2,:),A(3,:)) 如果J很大,这将是缓慢而乏味的。是否有一个内置的Matlab函数可以做到这一点?这里有一个针对jx2数组情况的黑客解决方案,使用- 只有一个函数调用(忽略size,因为它必须是最小的)开销zero,甚

例如,给定一个
J
-by-2矩阵

A = [1 2 ; 3 4 ; 5 6]
我想阻止它对角化。也就是说,我想要:

B = [1 2 0 0 0 0 ; 0 0 3 4 0 0 ; 0 0 0 0 5 6].
执行此操作的一个命令是:

blkdiag(A(1,:),A(2,:),A(3,:))
如果
J
很大,这将是缓慢而乏味的。是否有一个内置的Matlab函数可以做到这一点?

这里有一个针对
jx2
数组情况的黑客解决方案,使用-

只有一个函数调用(忽略
size
,因为它必须是最小的)开销
zero
,甚至可以使用-

样本运行-

A =
     1     2
     3     4
     5     6
     7     8
out =
     1     2     0     0     0     0     0     0
     0     0     3     4     0     0     0     0
     0     0     0     0     5     6     0     0
     0     0     0     0     0     0     7     8

以下是迄今为止发布的解决方案的基准测试

基准测试代码

%//Set up some random data
J = 7000;   A = rand(J,2);
%// Warm up tic/toc
for k = 1:100000
    tic(); elapsed = toc();
end   
disp('---------------------------------- With @mikkola solution')
tic
temp = mat2cell(A, ones(J,1), 2);
B = blkdiag(temp{:});
toc, clear B temp
disp('---------------------------------- With @Jeff Irwin solution')
tic
m = size(A, 1);
n = size(A, 2);
B = zeros(m, m * n);
for k = 1: n
    B(:, k: n: m * n) = diag(A(:, k));
end
toc, clear B k m n
disp('---------------------------------- With Hacky1 solution')
tic
N = size(A,1);                   
idx = 1:2*N+1:(N-1)*(2*N+1)+1;   
out = zeros(N,N*2);
out([idx(:) idx(:)+N]) = A;
toc, clear out idx N
disp('---------------------------------- With Hacky2 solution')
tic
N = size(A,1);                   
idx = 1:2*N+1:(N-1)*(2*N+1)+1;
out(N,N*2) = 0;
out([idx(:) idx(:)+N]) = A;
toc, clear out idx N
运行时

---------------------------------- With @mikkola solution
Elapsed time is 0.546584 seconds.
---------------------------------- With @Jeff Irwin solution
Elapsed time is 1.330666 seconds.
---------------------------------- With Hacky1 solution
Elapsed time is 0.455735 seconds.
---------------------------------- With Hacky2 solution
Elapsed time is 0.364227 seconds.

这是另一个解决方案。不确定它的效率有多高,但它适用于任何大小的矩阵
a

A = [1 2; 3 4; 5 6]
m = size(A, 1)
n = size(A, 2)

B = zeros(m, m * n)
for k = 1: n
    B(:, k: n: m * n) = diag(A(:, k))
end
这里有一个用于重塑为J-by-1单元数组的元素,其中每个元素包含一行
a
。然后使用
{:}
操作符将内容作为逗号分隔的变量列表推送到
blkdiag

%//Set up some random data
J = 100;
A = rand(J,2);
%// Solution for arbitrary J-by-2 A
temp = mat2cell(A, ones(J,1), 2);
B = blkdiag(temp{:})

很好的解决方案!我这里有一些计时结果,但通过@Divakar运行基准测试代码重复了它们。下面是我这边的结果

---------------------------------- With @mikkola solution
Elapsed time is 0.100674 seconds.
---------------------------------- With @Jeff Irwin solution
Elapsed time is 0.283275 seconds.
---------------------------------- With @Divakar Hacky1 solution
Elapsed time is 0.079194 seconds.
---------------------------------- With @Divakar Hacky2 solution
Elapsed time is 0.051629 seconds.

我找到了一种方法,使用
sparse
在内存和时钟时间方面都优于其他解决方案:

N = size(A,1);
ind_1 = [1:N].';
ind_2 = [1:2:2*N-1].';
A_1   = sparse(ind_1,ind_2,A(:,1),N,2*N);
ind_2 = [2:2:2*N].';
A_2   = sparse(ind_1,ind_2,A(:,2),N,2*N);
out       = A_1 + A_2;
使用与@Divakar相同的基准代码报告以下结果:

---------------------------------- With @mikkola solution
Elapsed time is 0.065136 seconds.
---------------------------------- With @Jeff Irwin solution
Elapsed time is 0.500264 seconds.
---------------------------------- With Hacky1 solution
Elapsed time is 0.200303 seconds.
---------------------------------- With Hacky2 solution
Elapsed time is 0.011991 seconds.
---------------------------------- With @Matt T solution
Elapsed time is 0.000712 seconds.

不确定您使用的基准测试代码,但我已经添加了我的代码,以防人们想查看。结果在我这方面是不同的。@Divakar我重复了运行您的代码的基准测试。订购与您的终端相同。无任何函数调用开销的索引显然比FTW更快+1.@rayryeng未记录的MATLAB FTW!;)谢谢设置
out=sparse(N,2*N)
而不是
out(N,N*2)=0
可能是有意义的,这样可以避免
N
很大时的大量开销。@MattT我没有处理过多少sparse,所以我不确定。但是,如果这行得通的话,当然@MattT分配给
稀疏
矩阵的成本非常高。最好是使用非零内容初始化
sparse
矩阵,而不是创建空的
sparse
矩阵并赋值。嵌套调用
diag
会降低性能,但这是解决此问题的最规范的方法之一+1.
N = size(A,1);
ind_1 = [1:N].';
ind_2 = [1:2:2*N-1].';
A_1   = sparse(ind_1,ind_2,A(:,1),N,2*N);
ind_2 = [2:2:2*N].';
A_2   = sparse(ind_1,ind_2,A(:,2),N,2*N);
out       = A_1 + A_2;
---------------------------------- With @mikkola solution
Elapsed time is 0.065136 seconds.
---------------------------------- With @Jeff Irwin solution
Elapsed time is 0.500264 seconds.
---------------------------------- With Hacky1 solution
Elapsed time is 0.200303 seconds.
---------------------------------- With Hacky2 solution
Elapsed time is 0.011991 seconds.
---------------------------------- With @Matt T solution
Elapsed time is 0.000712 seconds.