Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.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中设置除对角线元素外的特定行和列零_Matlab - Fatal编程技术网

在matlab中设置除对角线元素外的特定行和列零

在matlab中设置除对角线元素外的特定行和列零,matlab,Matlab,假设我得到了一些索引,比如B=[10 23 32….] 现在让我们假设我有一个矩阵a。我想做的是,对于B中的每个索引,让我们假设我,我想将a的第I行和第I列设置为0,除了对角元素a(I,I)(它保持不变) 我可以通过循环来实现这一点。但是我想要一些基于矩阵乘法的,比循环更快的 各位有什么想法吗?假设 B=[10 23 32 12 15 18 20] M=true(6) M(B)=false %making the indexed elements false M=or(M,diag(true(

假设我得到了一些索引,比如
B=[10 23 32….]

现在让我们假设我有一个矩阵a。我想做的是,对于B中的每个索引,让我们假设我,我想将a的第I行和第I列设置为0,除了对角元素a(I,I)(它保持不变)

我可以通过循环来实现这一点。但是我想要一些基于矩阵乘法的,比循环更快的

各位有什么想法吗?

假设

B=[10 23 32 12 15 18 20]
M=true(6)
M(B)=false  %making the indexed elements false
M=or(M,diag(true(size(M,1),1)))  %keep the diagonal elements one

% creating a matrix which has zero in ith row and ith column and diagonal has ones
M1=and(bsxfun(@or,bsxfun(@and,repmat(min(M,[],2),1,size(M,2)),min(M,[],1)),diag(true(size(M,1),1))),M)  

%Now just multiply M1 with your matrix A, and you are done.
newA=A.*M1

您可以将以上两行合并为一行,但为了便于阅读,我更希望它们不相交。

您有一个选择:

创建对角线元素的线性索引:

[I, J]=size(A);
idx=sub2ind([I,J], B, B);
NewA=A;
NewA(B, :)=zeros(numel(B),J);
NewA(:, B)=zeros(I,numel(B));
NewA(idx)=A(idx);
将水平和垂直设置为0,并替换对角线元素:

[I, J]=size(A);
idx=sub2ind([I,J], B, B);
NewA=A;
NewA(B, :)=zeros(numel(B),J);
NewA(:, B)=zeros(I,numel(B));
NewA(idx)=A(idx);

您可以将对角线元素临时存储在其他地方,用B索引到A中,将相应的行和列设置为零,最后插入对角线元素-

%// rows in A
rows = size(A,1);

%// Store the diagonal elements temporarily somewhere else
tmp_diagA = A(1:rows+1:end);

%// Set the ith rows and cols (obtained from B) to zero
A(B,:)=0;
A(:,B)=0;

%// Plug back in the diagonal elements in place
A(1:rows+1:end) = tmp_diagA;

函数调用在MATLAB中应该是很昂贵的,在这段代码中几乎没有函数调用,所以我希望它足够快。

对于square
A

b = zeros(size(A,1),1);
b(B) = B;
A = A.*bsxfun(@eq, b, b.')
b1 = zeros(size(A,1),1);
b1(B) = B;
b2 = zeros(1,size(A,2));
b2(B) = B;
A = A.*bsxfun(@eq, b1, b2);
对于常规
A

b = zeros(size(A,1),1);
b(B) = B;
A = A.*bsxfun(@eq, b, b.')
b1 = zeros(size(A,1),1);
b1(B) = B;
b2 = zeros(1,size(A,2));
b2(B) = B;
A = A.*bsxfun(@eq, b1, b2);

我认为最后应该是
A(idx)
。这也应该相当快。我不认为在
bsxfun
@Divakar更正后,整个第I行和列都设置为零。谢谢非常有帮助,因为现在通常是这样!好用口罩+1此处提供的解决方案是否适用于您?