0

我有 8x8 矩阵,其中有 15 条对角线。左上角“对角线 1”和右下角“对角线 15”。我想将特定的对角线集归零,例如 {9, 10, 11, 12, 13, 14, 15} 或 {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} . 有人请给我解决方案吗?

4

7 回答 7

2

我相信你可以使用:

M = M - diag(diag(M,k),k);

其中 k 对于主对角线为 0,对于下对角线为负(最多 -7),对于上对角线为正(最多 7 个)。

编辑:我的错,这只会将您选择的对角线之一归零。您可以对要归零的所有对角线重复该过程,但这可能不是最佳的:

for k=[9 10 11 12 13 14 15]
    M = M - diag(diag(M,k-length(M)),k-length(M));
end
于 2012-11-27T22:54:12.830 回答
0

另一种方法是直接使用索引。

对于 8x8 矩阵,如果要将主对角线处或下方的对角线之一中的条目归零,请使用以下命令:

M((n+1):9:(64-8*n))=0;

这将沿着对角线运行,当它到达最低行时停止。对于对角线以上的条目,您必须在 64-n 处结束,而不是从 n+1 开始,如下所示:

M((8*n+1):9:(64-n))=0;

在这两种情况下,n 是您离主对角线的距离 - 所以 n=0 是主对角线。这可以用一点逻辑概括:

idx=1:9:64;
M(idx((idx+8*n)<65&(idx+8*n)>0)+8*n)=0;

对于 n>=0,这将选择主对角线上方的第 n 个对角线。负值将选择主对角线下方的对角线。进一步推广,对于 NxN 矩阵,

idx=1:(N+1):N^2;
M(idx((idx+N*n)<=N^2&(idx+N*n)>0)+N*n)=0;

通过广播或适当使用 repmat(或乘以一个向量),这可以适应一次处理多个对角线,尽管它变得更加混乱。

于 2013-03-16T15:15:27.920 回答
0

我不确定我是否正确理解了您的问题。您是想将主对角线上的某些元素子集归零,还是试图将整个对角线归零?无论哪种方式,您都可以考虑使用 Matlab 的“诊断”功能。

如果你只想将主对角线上的一些元素归零,你可以使用类似的东西:

% A is a 15 x 15 matrix, want to zero out {1,2,3,8}th elements on the diagonal
d = diag(A); % diagonal elements of A
d([4:7 9:15]) = 0; % zero out the elements you want to KEEP
A = A - diag(d); % diag d is a diagonal matrix with d on the main diagonal

但是使用 for 循环会更容易:

for i=[1,2,3,8]
A(i,i) = 0;
end

将 A 的第 n 个对角线归零实际上更容易:

假设你想将第三条对角线归零,你会这样做: A = A - diag(diag(A,3),3);

于 2012-11-27T22:51:01.393 回答
0

假设您有一个方阵 M。如果您只想将整个对角线设置为零,您可以这样做:

M(sub2ind(size(M), [1:length(M)]',[1:length(M)]')) = 0;

如果您想将某些对角线设置为零,例如 1:5、8:11,您可以简单地修改为:

M(sub2ind(size(M), [1:5, 8:11]',[1:5, 8:11]')) = 0;

其他人建议使用 for 循环。除非绝对必要,否则永远不要在 Matlab 中使用 for 循环。原生 Matlab 函数要快得多。

于 2014-12-22T22:45:34.750 回答
0

如果我跟着你,这里有一个简单的方法:

a       = rand(8,8);
indx    = logical( diag(ones(1,8),0) ); 
a(indx) = 0;

或者如果您愿意,可以在 1 行中,

a(logical(diag(ones(1,8),0))) = 0;

请注意,当使用 diag(v,k) 设置 k=1 时,将 v 放置在主对角线上,k=1 将 v 放置在对角线上,主对角线上方一个位置,依此类推。

然后通过相应地改变 k 和 v 的大小来重复非主对角线。

于 2012-11-28T00:36:13.993 回答
0

我认为我的对角线是相反的,但你应该明白这一点。

Python代码:

import numpy as np

matrix = np.ones((8,8))

print "matrix = \n", matrix

# Need to map "diagnals" to starting row & offset, this is for 8x8

start_map = {}

start_map[ 0] = (0, 7)
start_map[ 1] = (0, 6)
start_map[ 2] = (0, 5)
start_map[ 3] = (0, 4)
start_map[ 4] = (0, 3)
start_map[ 5] = (0, 2)
start_map[ 6] = (0, 1)
start_map[ 7] = (0, 0)
start_map[ 8] = (1, 0)
start_map[ 9] = (2, 0)
start_map[10] = (3, 0)
start_map[11] = (4, 0)
start_map[12] = (5, 0)
start_map[13] = (6, 0)
start_map[14] = (7, 0)

# Zero out selected "diagnal"

M, N = matrix.shape

for i in xrange(15):

    new_matrix = np.array(matrix)

    m, n = start_map[i]

    while m < M and n < N:

        new_matrix[m, n] = 0.0

        m += 1
        n += 1

    print "'diag' = %d\n" % i, new_matrix

这是截断的输出:

matrix = 
[[ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]]
'diag' = 0
[[ 1.  1.  1.  1.  1.  1.  1.  0.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]]
'diag' = 3
[[ 1.  1.  1.  1.  0.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  0.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  0.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  0.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]]
'diag' = 7
[[ 0.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  0.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  0.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  0.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  0.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  0.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  0.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  0.]]
'diag' = 8
[[ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 0.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  0.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  0.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  0.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  0.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  0.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  0.  1.]]
'diag' = 9
[[ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 0.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  0.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  0.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  0.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  0.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  0.  1.  1.]]
于 2012-11-27T23:50:26.433 回答
0

另一种基于Glen O's answer 的解决方案也适用于非方阵,如下所示:

%% // Example inputs
N_ROWS = 6;
N_COLS = 4;
A = randi(20,N_ROWS,N_COLS);
DIAG_TO_MODIFY = -1;
REPLACE_VEC = rand(size(diag(A,DIAG_TO_MODIFY))); %// Will error if diagonal # is invalid.

%% // Processing; can be made a function
if  -DIAG_TO_MODIFY > N_ROWS-1 || ... 
     DIAG_TO_MODIFY > N_COLS-1
    error('Invalid diagonal number.');
end

if DIAG_TO_MODIFY < 0
    firstInd = 1 - DIAG_TO_MODIFY;
elseif DIAG_TO_MODIFY > 0
    firstInd = 1 + DIAG_TO_MODIFY*N_ROWS;
else %// DIAG_TO_MODIFY == 0 
    firstInd = 1;
end
A(firstInd:N_ROWS+1:end) = REPLACE_VEC;
于 2015-09-18T06:28:22.680 回答