在 MatLab 中迭代矩阵的对角线元素
Iterate over diagonal elements of a Matrix in MatLab
我需要获取矩阵中所有对角线的索引。矩阵可以是非方阵。
diag
函数给出了值,但我需要坐标。因此,例如:[1 2 3; 4 5 6; 7 8 9]
,我想要 [1 1; 2 2; 3;3]
加上 [2 6]
和 3
,因为它们是矩阵的上对角线,下面也一样,即 [4 8]
和 7
。所以完整的索引列表是:[1 1; 2 2; 3 3], [1 2; 2 3], [1 3], [2 1], [3 2], [3 1]
.
而且我在另一个对角线方向也需要这个...
它需要适用于任何形状的矩阵,即不仅仅是方形矩阵,包括向量(即 1xn 和 nx1)——但我想我可以测试最后两种情况并分别处理。
编辑:
非方阵的一个例子是这个 3x2 矩阵:
1 2
3 4
5 6
在这种情况下,我需要的索引是:
[1 1; 2 2]
[2 1; 3 2]
[1 2]
[3 1]
然后对角线也是如此 运行 反过来...
我知道 diag
函数并且可以编写一些代码来遍历矩阵,但是我不知道如何轻松地将这些值转换为索引。
至于为什么我需要这个:这是我在 MatLab 上的在线课程。使用 MatLab 编程简介。我是一个相当有经验的程序员,但我不熟悉 MatLab,我想了解更多。
该问题要求我们找到任何 n
数字在任何方向上的最大乘积,即行、列和对角线(双向)。问题是我们没有 return 产品,我们 return 构成该产品的元素的索引。
我希望这能提供更多信息。
编辑 2:
很抱歉没有回复你们,我一直很忙做其他事情。当我第一次在这里发帖时,我以为我遗漏了一些东西,而这需要几行。但这比那更棘手,所以你们发布的代码将花费我更多的时间来完成和理解等。但我希望今天这样做并接受一个作为答案。感谢大家的回复。
不要忘记 Matlab 理解多维矩阵的线性索引。对于 OP 的 3*3
(我们称之为 a
)矩阵示例,表达式 a(3)
标识与 a(3,1)
相同的元素(Matlab 使用列优先布局)。因此,对于 k*k
矩阵,表达式
[1, k+2, 2k+3, 3k+4, ...]
给出主对角线上元素的索引。有多种方法可以生成该向量。然后,明智地应用 ind2sub
会将二维索引放入同一矩阵中。
将这种方法推广到其他对角线和非方阵应该不难。
这是 "northwest to southeast" 对角线的解决方案。
A = [1,2,3,4,5;6,7,8,9,10;11,12,13,14,15];
rows = size (A,1); cols = size (A,2); padding = rows - 1;
padded = [ones(rows, padding), A, ones(rows, padding)];
% Create a Helper array containing column/row pairs and a product
Helper = zeros (cols + padding, rows * 2 + 1);
for i = 1 : cols + padding; % i moves along columns of the padded array
i0 = i - padding; % "actual" index w.r.t A, where leftmost index is 1-padding
c = 1; % a counter used for filling current "Helper" row appropriately
for j = 1 : rows; % j moves along rows
Helper(i, c) = i0; % store current "actual" column
Helper(i, c+1) = j; % store current row
c = c + 2; % move to next 2 slots in "Helper"
i0 = i0 + 1; % move to next "actual" column for processing
end
% Process product at appropriate indices
Helper(i, end) = prod (padded (sub2ind ( ...
size (padded), ...
Helper(i,2:2:end-1), ...
Helper(i,1:2:end-1)+padding ...
)));
end
% Isolate the correct indices for which the product is largest
[~, biggest] = max (Helper(:, end)); % column index of largest product in Helper
Pairs = reshape (Helper(biggest, 1:end-1), 2, []); % collect indices
Pairs = fliplr (Pairs.'); % express as rows/cols
% Remove pairs where column occurs in the "padded" zone
for i = 1 : size (Pairs, 1)
if Pairs(i, 1) < 1 || Pairs(i, 1) > cols; Pairs(i, :) = []; end
end
display(Pairs)
如果你理解这背后的逻辑,"NorthEast to SouthWest" 对角线也应该是小菜一碟。我会留给你弄明白:)
执行此操作的简单方法是构造一个与输入形状相同的数组,其中每个元素的值是其索引。然后你可以得到每个对角线的值(索引)。
function diag_cell = alldiags(A)
[m,n] = size(A);
M = reshape(1:m*n, m, n); % construct array of indices
% there are (m-1) diagonals below the main (k parameter negative)
% and (n-1) diagonals above, plus 0 for the main diagonal
for d = 1-m:n-1
C1{d+m} = diag(M, d); % store in C1{1}..C1{m+n-1}
end
% to get the antidiagonals, rotate the index matrix `M` and repeat
% (remember to swap `m` and `n`):
M = rot90(M);
for d = 1-n:m-1
C2{d+n} = diag(M, d);
end
diag_cell = {C1{:}, C2{:}}; % concatenate the cell arrays and return
end
这是一个使用 3x3 样本矩阵的测试 运行:
A =
1 2 3
4 5 6
7 8 9
>> alldiags(A)
ans =
{
[1,1] = 3
[1,2] =
2
6
[1,3] =
1
5
9
[1,4] =
4
8
[1,5] = 7
[1,6] = 1
[1,7] =
4
2
[1,8] =
7
5
3
[1,9] =
8
6
[1,10] = 9
}
如果确实需要,您可以随时将所有索引转换为下标,但如果您要访问原始矩阵,则使用索引可能更容易。这是将主对角线转换为下标的示例:
>> C{3}
ans =
1
5
9
>> [r,c] = ind2sub(size(A), C{3});
>> subs = [r c]
subs =
1 1
2 2
3 3
这里有一个例子来说明为什么会这样。让我们取一个随机的 6x3 矩阵 A
:
A =
0.634825 0.560609 0.926716
0.049504 0.226152 0.748278
0.746754 0.493896 0.773868
0.993245 0.457522 0.412092
0.430003 0.695042 0.641917
0.935298 0.960166 0.022872
函数做的第一件事是获取输入矩阵的大小 A
并创建一个相同大小的新矩阵,使每个元素的值等于其线性索引。线性索引从下标 [1,1]
处的 1
开始,向下增加列到 [m,1]
处的 m
,然后转到 m+1
下标 [1,2]
,在索引 m*n
下标 [m,n]
.
处结束
>> [m,n] = size(A)
m = 6
n = 3
>> M = reshape(1:m*n, m, n)
M =
1 7 13
2 8 14
3 9 15
4 10 16
5 11 17
6 12 18
此矩阵的输出 diag_cell
如下所示(经过大量重新格式化,因此更容易一次看到所有内容):
diag_cell =
{
[1,1] = 6
[1,2] = 5 12
[1,3] = 4 11 18
[1,4] = 3 10 17
[1,5] = 2 9 16
[1,6] = 1 8 15
[1,7] = 7 14
[1,8] = 13
[1,9] = 1
[1,10] = 7 2
[1,11] = 13 8 3
[1,12] = 14 9 4
[1,13] = 15 10 5
[1,14] = 16 11 6
[1,15] = 17 12
[1,16] = 18
}
条目的前半部分是正常对角线(从左上到右下),后半是反对角线(从右上到左下)。
以对角线为例diag_cell{4} = [3; 10; 17]
。您可以查看矩阵 M
以查看这些索引引用了哪些元素。
A =
0.634825 0.560609 0.926716
0.049504 0.226152 0.748278
*0.746754* 0.493896 0.773868
0.993245 *0.457522* 0.412092
0.430003 0.695042 *0.641917*
0.935298 0.960166 0.022872
这条对角线从 [3,1]
开始,到 [5,3]
结束。如果我们从 A
恢复值,我们得到:
>> A(diag_cell{4})
ans =
0.74675
0.45752
0.64192
这个解决方案一直到你的最终任务 - 找到矩阵中任何向量的最大乘积的索引:
function out = maxVecProd(A)
% validate the input is a vector\matrix:
assert(ismatrix(A),'Input must be a vector or matrix')
[cmax,cind] = max(prod(A,1)); % find where the maximum prod in the columns
[rmax,rind] = max(prod(A,2)); % find where the maximum prod in the rows
if all(size(A))>1 % if its a matrix:
all_d = -(size(A,1)-1):(size(A,1)-1); % get all the valid diagonals
pd = zeros(2*numel(all_d),2); % the solution of all products
c = 1;
for d = all_d
pd(c,1) = prod(diag(A,d)); % get the diagonal product
pd(c,2) = prod(diag(fliplr(A),d)); % get the anti-diagonal product
c = c+1;
end
[dmax,dind] = max(pd(:)); % find where the maximum prod in the diagonals
% get the orientation of the maximum prod (column, row, diagonal)
[~,dirmax] = max([rmax,cmax,dmax]);
else
[~,dirmax] = max([rmax,cmax]);
end
switch dirmax
case 1
% create the indices for the maximum row:
out = [repelem(rind,size(A,2)).' (1:size(A,2)).'];
case 2
% create the indices for the maximum column:
out = [(1:size(A,1)).' repelem(cind,size(A,1)).'];
case 3
[r,dir] = ind2sub(size(pd),dind); % convert to [row,column]
d_ind = all_d(r); % find which value of d gave the maximum product
[R,C] = ndgrid(1:size(A,1),1:size(A,2)); % create a grid of all indices
if dir==1
% find the indices for a diagonal:
out = [diag(R,d_ind),diag(C,d_ind)];
else
% find the indices for an anti-diagonal:
out = [diag(fliplr(R),d_ind),diag(fliplr(C),d_ind)];
end
end
end
你得到 maxVecProd(A)
:
out =
1 2
2 2
3 2
表示(1,2),(2,2),(3,2)中元素的最大prod。
好的,所以我昨晚自己编写了代码。它很长,我相信它可以用更好的方式完成。我不太了解 MatLab,所以我的解决方案非常幼稚。但它有效。
function indicies = maxproduct(A, n)
function diagIndicies = getAllReverseDiagonalIndicies()
% This function returns lists of indicies in the reverse diagonal direction (top-right to bottom-left)
if rows == 1
numCells = 0;
for j=1:length(A)
temp = [1, j];
numCells = numCells + 1;
diagIndicies{numCells} = temp;
end
return
end
% This loop adds all diagonals down and to the right, to the end of the matrix.
%fprintf('Diagonals down to main one are:\n');
numCells = 0;
for x=1:rows
rowNum = x;
colNum = 1;
temp = [];
while rowNum >= 1 && rowNum <= rows && colNum <= cols
temp = [temp; [rowNum colNum]];
rowNum = rowNum - 1;
colNum = colNum + 1;
end
numCells = numCells + 1;
temp = flipud(temp); % Need row major order for assignment
%disp(temp);
diagIndicies{numCells} = temp;
end
% Now go along bottom row
%fprintf('Diagonals along bottom are:\n');
for y=2:cols
rowNum = rows;
colNum = y;
temp = [];
while rowNum >= 1 && colNum <= cols
temp = [temp; [rowNum colNum]];
rowNum = rowNum - 1;
colNum = colNum + 1;
end
numCells = numCells + 1;
temp = flipud(temp); % Need row major order for assignment
%disp(temp);
diagIndicies{numCells} = temp;
end
end
function diagIndicies = getAllDiagonalIndicies()
% This function returns lists of indicies in the main diagonal direction (top-left to bottom-right)
if rows == 1
numCells = 0;
for j=1:length(A)
temp = [1, j];
numCells = numCells + 1;
diagIndicies{numCells} = temp;
end
return
end
% This loop adds all diagonals down and to the left, to the lhs of the matrix.
%fprintf('Diagonals down to main one are:\n');
numCells = 0;
for x=1:rows
rowNum = x;
colNum = cols;
temp = [];
while rowNum >= 1 && rowNum <= rows && colNum >= 1
temp = [temp; [rowNum colNum]];
rowNum = rowNum - 1;
colNum = colNum - 1;
end
numCells = numCells + 1;
temp = flipud(temp); % Need row major order for assignment
%disp(temp);
diagIndicies{numCells} = temp;
end
% Now go along bottom row...
%fprintf('Diagonals along bottom are:\n');
for y=cols-1:-1:1
rowNum = rows;
colNum = y;
temp = [];
while rowNum >= 1 && colNum >= 1
temp = [temp; [rowNum colNum]];
rowNum = rowNum - 1;
colNum = colNum - 1;
end
numCells = numCells + 1;
temp = flipud(temp); % Need row major order for assignment
%disp(temp);
diagIndicies{numCells} = temp;
end
end
% Main function starts here.
[rows, cols] = size(A);
theMaxProduct = -10000000;
indicies = [];
if isscalar(A)
if A == 1 && n == 1
indicies = [1,1];
return;
else
return;
end
end
% Find max product in each row of A
for i=1:rows
for j=1:cols-n+1
theProduct = 1;
for k=j:j+n-1
theProduct = theProduct * A(i, k);
end
if theProduct > theMaxProduct
theMaxProduct = theProduct;
indicies = [];
for k=j:j+n-1
indicies = [indicies; [i, k]];
end
end
end
end
fprintf('theMaxProduct after examining rows = %15.15f\n', theMaxProduct);
% Find max product in each column of A
for i=1:cols
for j=1:rows-n+1
theProduct = 1;
for k=j:j+n-1
theProduct = theProduct * A(k, i);
end
if theProduct > theMaxProduct
theMaxProduct = theProduct;
indicies = [];
for k=j:j+n-1
indicies = [indicies; [k, i]];
end
end
end
end
fprintf('theMaxProduct after examining cols = %15.15f\n', theMaxProduct);
% Find max product along reverse diagonals of A
diagIndicies = getAllReverseDiagonalIndicies();
%disp(diagIndicies);
for i=1: length(diagIndicies)
[numIndicies, ~] = size(diagIndicies{i});
for j=1:numIndicies-n+1
theProduct = 1;
for k=j:j+n-1
theProduct = theProduct * A(diagIndicies{i}(k, 1), diagIndicies{i}(k, 2));
end
if theProduct > theMaxProduct
theMaxProduct = theProduct;
indicies = [];
for k=j:j+n-1
indicies = [indicies; [diagIndicies{i}(k, 1), diagIndicies{i}(k, 2)]];
end
end
end
end
fprintf('theMaxProduct after examining reverse diag = %15.15f\n', theMaxProduct);
% Find max product along diagonals of A
diagIndicies = getAllDiagonalIndicies();
%disp(diagIndicies);
for i=1: length(diagIndicies)
[numIndicies, ~] = size(diagIndicies{i});
for j=1:numIndicies-n+1
theProduct = 1;
for k=j:j+n-1
theProduct = theProduct * A(diagIndicies{i}(k, 1), diagIndicies{i}(k, 2));
end
if theProduct > theMaxProduct
theMaxProduct = theProduct;
indicies = [];
for k=j:j+n-1
indicies = [indicies; [diagIndicies{i}(k, 1), diagIndicies{i}(k, 2)]];
end
end
end
end
fprintf('theMaxProduct after examining main diag = %15.15f\n', theMaxProduct);
结束
我需要获取矩阵中所有对角线的索引。矩阵可以是非方阵。
diag
函数给出了值,但我需要坐标。因此,例如:[1 2 3; 4 5 6; 7 8 9]
,我想要 [1 1; 2 2; 3;3]
加上 [2 6]
和 3
,因为它们是矩阵的上对角线,下面也一样,即 [4 8]
和 7
。所以完整的索引列表是:[1 1; 2 2; 3 3], [1 2; 2 3], [1 3], [2 1], [3 2], [3 1]
.
而且我在另一个对角线方向也需要这个...
它需要适用于任何形状的矩阵,即不仅仅是方形矩阵,包括向量(即 1xn 和 nx1)——但我想我可以测试最后两种情况并分别处理。
编辑: 非方阵的一个例子是这个 3x2 矩阵:
1 2
3 4
5 6
在这种情况下,我需要的索引是:
[1 1; 2 2]
[2 1; 3 2]
[1 2]
[3 1]
然后对角线也是如此 运行 反过来...
我知道 diag
函数并且可以编写一些代码来遍历矩阵,但是我不知道如何轻松地将这些值转换为索引。
至于为什么我需要这个:这是我在 MatLab 上的在线课程。使用 MatLab 编程简介。我是一个相当有经验的程序员,但我不熟悉 MatLab,我想了解更多。
该问题要求我们找到任何 n
数字在任何方向上的最大乘积,即行、列和对角线(双向)。问题是我们没有 return 产品,我们 return 构成该产品的元素的索引。
我希望这能提供更多信息。
编辑 2: 很抱歉没有回复你们,我一直很忙做其他事情。当我第一次在这里发帖时,我以为我遗漏了一些东西,而这需要几行。但这比那更棘手,所以你们发布的代码将花费我更多的时间来完成和理解等。但我希望今天这样做并接受一个作为答案。感谢大家的回复。
不要忘记 Matlab 理解多维矩阵的线性索引。对于 OP 的 3*3
(我们称之为 a
)矩阵示例,表达式 a(3)
标识与 a(3,1)
相同的元素(Matlab 使用列优先布局)。因此,对于 k*k
矩阵,表达式
[1, k+2, 2k+3, 3k+4, ...]
给出主对角线上元素的索引。有多种方法可以生成该向量。然后,明智地应用 ind2sub
会将二维索引放入同一矩阵中。
将这种方法推广到其他对角线和非方阵应该不难。
这是 "northwest to southeast" 对角线的解决方案。
A = [1,2,3,4,5;6,7,8,9,10;11,12,13,14,15];
rows = size (A,1); cols = size (A,2); padding = rows - 1;
padded = [ones(rows, padding), A, ones(rows, padding)];
% Create a Helper array containing column/row pairs and a product
Helper = zeros (cols + padding, rows * 2 + 1);
for i = 1 : cols + padding; % i moves along columns of the padded array
i0 = i - padding; % "actual" index w.r.t A, where leftmost index is 1-padding
c = 1; % a counter used for filling current "Helper" row appropriately
for j = 1 : rows; % j moves along rows
Helper(i, c) = i0; % store current "actual" column
Helper(i, c+1) = j; % store current row
c = c + 2; % move to next 2 slots in "Helper"
i0 = i0 + 1; % move to next "actual" column for processing
end
% Process product at appropriate indices
Helper(i, end) = prod (padded (sub2ind ( ...
size (padded), ...
Helper(i,2:2:end-1), ...
Helper(i,1:2:end-1)+padding ...
)));
end
% Isolate the correct indices for which the product is largest
[~, biggest] = max (Helper(:, end)); % column index of largest product in Helper
Pairs = reshape (Helper(biggest, 1:end-1), 2, []); % collect indices
Pairs = fliplr (Pairs.'); % express as rows/cols
% Remove pairs where column occurs in the "padded" zone
for i = 1 : size (Pairs, 1)
if Pairs(i, 1) < 1 || Pairs(i, 1) > cols; Pairs(i, :) = []; end
end
display(Pairs)
如果你理解这背后的逻辑,"NorthEast to SouthWest" 对角线也应该是小菜一碟。我会留给你弄明白:)
执行此操作的简单方法是构造一个与输入形状相同的数组,其中每个元素的值是其索引。然后你可以得到每个对角线的值(索引)。
function diag_cell = alldiags(A)
[m,n] = size(A);
M = reshape(1:m*n, m, n); % construct array of indices
% there are (m-1) diagonals below the main (k parameter negative)
% and (n-1) diagonals above, plus 0 for the main diagonal
for d = 1-m:n-1
C1{d+m} = diag(M, d); % store in C1{1}..C1{m+n-1}
end
% to get the antidiagonals, rotate the index matrix `M` and repeat
% (remember to swap `m` and `n`):
M = rot90(M);
for d = 1-n:m-1
C2{d+n} = diag(M, d);
end
diag_cell = {C1{:}, C2{:}}; % concatenate the cell arrays and return
end
这是一个使用 3x3 样本矩阵的测试 运行:
A =
1 2 3
4 5 6
7 8 9
>> alldiags(A)
ans =
{
[1,1] = 3
[1,2] =
2
6
[1,3] =
1
5
9
[1,4] =
4
8
[1,5] = 7
[1,6] = 1
[1,7] =
4
2
[1,8] =
7
5
3
[1,9] =
8
6
[1,10] = 9
}
如果确实需要,您可以随时将所有索引转换为下标,但如果您要访问原始矩阵,则使用索引可能更容易。这是将主对角线转换为下标的示例:
>> C{3}
ans =
1
5
9
>> [r,c] = ind2sub(size(A), C{3});
>> subs = [r c]
subs =
1 1
2 2
3 3
这里有一个例子来说明为什么会这样。让我们取一个随机的 6x3 矩阵 A
:
A =
0.634825 0.560609 0.926716
0.049504 0.226152 0.748278
0.746754 0.493896 0.773868
0.993245 0.457522 0.412092
0.430003 0.695042 0.641917
0.935298 0.960166 0.022872
函数做的第一件事是获取输入矩阵的大小 A
并创建一个相同大小的新矩阵,使每个元素的值等于其线性索引。线性索引从下标 [1,1]
处的 1
开始,向下增加列到 [m,1]
处的 m
,然后转到 m+1
下标 [1,2]
,在索引 m*n
下标 [m,n]
.
>> [m,n] = size(A)
m = 6
n = 3
>> M = reshape(1:m*n, m, n)
M =
1 7 13
2 8 14
3 9 15
4 10 16
5 11 17
6 12 18
此矩阵的输出 diag_cell
如下所示(经过大量重新格式化,因此更容易一次看到所有内容):
diag_cell =
{
[1,1] = 6
[1,2] = 5 12
[1,3] = 4 11 18
[1,4] = 3 10 17
[1,5] = 2 9 16
[1,6] = 1 8 15
[1,7] = 7 14
[1,8] = 13
[1,9] = 1
[1,10] = 7 2
[1,11] = 13 8 3
[1,12] = 14 9 4
[1,13] = 15 10 5
[1,14] = 16 11 6
[1,15] = 17 12
[1,16] = 18
}
条目的前半部分是正常对角线(从左上到右下),后半是反对角线(从右上到左下)。
以对角线为例diag_cell{4} = [3; 10; 17]
。您可以查看矩阵 M
以查看这些索引引用了哪些元素。
A =
0.634825 0.560609 0.926716
0.049504 0.226152 0.748278
*0.746754* 0.493896 0.773868
0.993245 *0.457522* 0.412092
0.430003 0.695042 *0.641917*
0.935298 0.960166 0.022872
这条对角线从 [3,1]
开始,到 [5,3]
结束。如果我们从 A
恢复值,我们得到:
>> A(diag_cell{4})
ans =
0.74675
0.45752
0.64192
这个解决方案一直到你的最终任务 - 找到矩阵中任何向量的最大乘积的索引:
function out = maxVecProd(A)
% validate the input is a vector\matrix:
assert(ismatrix(A),'Input must be a vector or matrix')
[cmax,cind] = max(prod(A,1)); % find where the maximum prod in the columns
[rmax,rind] = max(prod(A,2)); % find where the maximum prod in the rows
if all(size(A))>1 % if its a matrix:
all_d = -(size(A,1)-1):(size(A,1)-1); % get all the valid diagonals
pd = zeros(2*numel(all_d),2); % the solution of all products
c = 1;
for d = all_d
pd(c,1) = prod(diag(A,d)); % get the diagonal product
pd(c,2) = prod(diag(fliplr(A),d)); % get the anti-diagonal product
c = c+1;
end
[dmax,dind] = max(pd(:)); % find where the maximum prod in the diagonals
% get the orientation of the maximum prod (column, row, diagonal)
[~,dirmax] = max([rmax,cmax,dmax]);
else
[~,dirmax] = max([rmax,cmax]);
end
switch dirmax
case 1
% create the indices for the maximum row:
out = [repelem(rind,size(A,2)).' (1:size(A,2)).'];
case 2
% create the indices for the maximum column:
out = [(1:size(A,1)).' repelem(cind,size(A,1)).'];
case 3
[r,dir] = ind2sub(size(pd),dind); % convert to [row,column]
d_ind = all_d(r); % find which value of d gave the maximum product
[R,C] = ndgrid(1:size(A,1),1:size(A,2)); % create a grid of all indices
if dir==1
% find the indices for a diagonal:
out = [diag(R,d_ind),diag(C,d_ind)];
else
% find the indices for an anti-diagonal:
out = [diag(fliplr(R),d_ind),diag(fliplr(C),d_ind)];
end
end
end
你得到 maxVecProd(A)
:
out =
1 2
2 2
3 2
表示(1,2),(2,2),(3,2)中元素的最大prod。
好的,所以我昨晚自己编写了代码。它很长,我相信它可以用更好的方式完成。我不太了解 MatLab,所以我的解决方案非常幼稚。但它有效。
function indicies = maxproduct(A, n)
function diagIndicies = getAllReverseDiagonalIndicies()
% This function returns lists of indicies in the reverse diagonal direction (top-right to bottom-left)
if rows == 1
numCells = 0;
for j=1:length(A)
temp = [1, j];
numCells = numCells + 1;
diagIndicies{numCells} = temp;
end
return
end
% This loop adds all diagonals down and to the right, to the end of the matrix.
%fprintf('Diagonals down to main one are:\n');
numCells = 0;
for x=1:rows
rowNum = x;
colNum = 1;
temp = [];
while rowNum >= 1 && rowNum <= rows && colNum <= cols
temp = [temp; [rowNum colNum]];
rowNum = rowNum - 1;
colNum = colNum + 1;
end
numCells = numCells + 1;
temp = flipud(temp); % Need row major order for assignment
%disp(temp);
diagIndicies{numCells} = temp;
end
% Now go along bottom row
%fprintf('Diagonals along bottom are:\n');
for y=2:cols
rowNum = rows;
colNum = y;
temp = [];
while rowNum >= 1 && colNum <= cols
temp = [temp; [rowNum colNum]];
rowNum = rowNum - 1;
colNum = colNum + 1;
end
numCells = numCells + 1;
temp = flipud(temp); % Need row major order for assignment
%disp(temp);
diagIndicies{numCells} = temp;
end
end
function diagIndicies = getAllDiagonalIndicies()
% This function returns lists of indicies in the main diagonal direction (top-left to bottom-right)
if rows == 1
numCells = 0;
for j=1:length(A)
temp = [1, j];
numCells = numCells + 1;
diagIndicies{numCells} = temp;
end
return
end
% This loop adds all diagonals down and to the left, to the lhs of the matrix.
%fprintf('Diagonals down to main one are:\n');
numCells = 0;
for x=1:rows
rowNum = x;
colNum = cols;
temp = [];
while rowNum >= 1 && rowNum <= rows && colNum >= 1
temp = [temp; [rowNum colNum]];
rowNum = rowNum - 1;
colNum = colNum - 1;
end
numCells = numCells + 1;
temp = flipud(temp); % Need row major order for assignment
%disp(temp);
diagIndicies{numCells} = temp;
end
% Now go along bottom row...
%fprintf('Diagonals along bottom are:\n');
for y=cols-1:-1:1
rowNum = rows;
colNum = y;
temp = [];
while rowNum >= 1 && colNum >= 1
temp = [temp; [rowNum colNum]];
rowNum = rowNum - 1;
colNum = colNum - 1;
end
numCells = numCells + 1;
temp = flipud(temp); % Need row major order for assignment
%disp(temp);
diagIndicies{numCells} = temp;
end
end
% Main function starts here.
[rows, cols] = size(A);
theMaxProduct = -10000000;
indicies = [];
if isscalar(A)
if A == 1 && n == 1
indicies = [1,1];
return;
else
return;
end
end
% Find max product in each row of A
for i=1:rows
for j=1:cols-n+1
theProduct = 1;
for k=j:j+n-1
theProduct = theProduct * A(i, k);
end
if theProduct > theMaxProduct
theMaxProduct = theProduct;
indicies = [];
for k=j:j+n-1
indicies = [indicies; [i, k]];
end
end
end
end
fprintf('theMaxProduct after examining rows = %15.15f\n', theMaxProduct);
% Find max product in each column of A
for i=1:cols
for j=1:rows-n+1
theProduct = 1;
for k=j:j+n-1
theProduct = theProduct * A(k, i);
end
if theProduct > theMaxProduct
theMaxProduct = theProduct;
indicies = [];
for k=j:j+n-1
indicies = [indicies; [k, i]];
end
end
end
end
fprintf('theMaxProduct after examining cols = %15.15f\n', theMaxProduct);
% Find max product along reverse diagonals of A
diagIndicies = getAllReverseDiagonalIndicies();
%disp(diagIndicies);
for i=1: length(diagIndicies)
[numIndicies, ~] = size(diagIndicies{i});
for j=1:numIndicies-n+1
theProduct = 1;
for k=j:j+n-1
theProduct = theProduct * A(diagIndicies{i}(k, 1), diagIndicies{i}(k, 2));
end
if theProduct > theMaxProduct
theMaxProduct = theProduct;
indicies = [];
for k=j:j+n-1
indicies = [indicies; [diagIndicies{i}(k, 1), diagIndicies{i}(k, 2)]];
end
end
end
end
fprintf('theMaxProduct after examining reverse diag = %15.15f\n', theMaxProduct);
% Find max product along diagonals of A
diagIndicies = getAllDiagonalIndicies();
%disp(diagIndicies);
for i=1: length(diagIndicies)
[numIndicies, ~] = size(diagIndicies{i});
for j=1:numIndicies-n+1
theProduct = 1;
for k=j:j+n-1
theProduct = theProduct * A(diagIndicies{i}(k, 1), diagIndicies{i}(k, 2));
end
if theProduct > theMaxProduct
theMaxProduct = theProduct;
indicies = [];
for k=j:j+n-1
indicies = [indicies; [diagIndicies{i}(k, 1), diagIndicies{i}(k, 2)]];
end
end
end
end
fprintf('theMaxProduct after examining main diag = %15.15f\n', theMaxProduct);
结束