2015-05-31 665 views
0

我不确定是否使用了标题中的措辞来解释问题。请随意编辑它以反映下面的描述。在Matlab中为索引子矩阵的子矩阵赋值

假设我有一个独解算器程序并可以说该输入矩阵是以下,

A = randi(10,[9,9])-1; 

I指数从1 3×3子矩阵coulumnwise至9假设可变nSubMat表示此索引可能需要1之间的任何值到9。

我索引子矩阵以下面的方式,

SubMat(nSubMat) = A((1:3)+(3*floor((nSubMat-1)/3)),(1:3)+(3*mod(nSubMat-1,3))); 

现在,我想访问并修改SubMat(2x3)位置中的值,而无需首先创建SubMat(说避免不必要的副本)。

要详细,如果我有一个功能子矩阵(),这将实现上述,我的发言看起来像下面

submatrix(A((1:3)+(3*floor((nSubMat-1)/3)),(1:3)+(3*mod(nSubMat-1,3))),[2,3]) = 5; 

甚至,

submatrix(A((1:3)+(3*floor((nSubMat-1)/3)),(1:3)+(3*mod(nSubMat-1,3))),[2:3,2:3]) = [1 2;3 4]; 

我知道Matlab解释器会自动优化LHS = RHS类型的赋值速度,但上述矩阵操作对于更多理由(算法上)而言非常重要,而不仅仅是减少副本并加快代码的速度,这一点我不会在此讨论。我在一个名为Armadillo的C++库中看到了所需的语法,但我不确定是否可以用MATLAB来完成相同的语法。

+0

您是否发现任何有用的答案?如果是的话,那么请接受它,以便它得到未答复的列表。 –

回答

1

你可以使用简单的线性索引来做到这一点。以下代码是不言自明的。

matrixRows=9; 
matrixCols=9; 
blockRows=3; 
blockCols=3; 
accessRow=2; 
accessCol=3; 

A = randi(10,[matrixRows,matrixCols])-1; 
allPos=allcomb(accessRow:blockRows:matrixRows,accessCol:blockCols:matrixCols); 
linPos=sub2ind(size(A),allPos(:,1),allPos(:,2)); 

% access them as usual and put any value 
A(linPos)=-100; 

结果:

A = 

8  9  7  3  6  4  1  6  8 
9  1  9  6  3  4  4  8  2 
1  9  6  1  9  6  9  9  9 
9  9  0  7  0  7  3  5  3 
6  4  8  0  4  7  5  1  1 
0  8  9  2  3  2  2  1  2 
2  1  6  0  7  6  7  2  6 
5  4  7  0  7  6  2  8  4 
9  9  7  8  1  1  5  2  3 

上面的代码运行后:

A = 

8  9  7  3  6  4  1  6  8 
9  1 -100  6  3 -100  4  8 -100 
1  9  6  1  9  6  9  9  9 
9  9  0  7  0  7  3  5  3 
6  4 -100  0  4 -100  5  1 -100 
0  8  9  2  3  2  2  1  2 
2  1  6  0  7  6  7  2  6 
5  4 -100  0  7 -100  2  8 -100 
9  9  7  8  1  1  5  2  3 

注:allcomb生成的输入参数的所有可能组合。您也可以使用比allcomb更快的this(根据答案)。

+0

一个犰狳[submat views](http://arma.sourceforge.net/docs.html#submat)类型的访问是我正在寻找,但线性索引应该做的。此外,对于大数字矩阵,更大的存取区域或数独中的大量迭代,allcomb()的效率如何? – Naveen

+0

我认为这将是非常有效的。正如我所提到的,您也可以测试显然更快的替代方案。 –

1

这是任何规模的数独谜题的一般功能。

function index = SudukoIndex(varargin) 
%%%SudukoIndex provides the index or indicies of a sub-block of any n*n 
%%%Suduko puzzle 

%Possible inputs 
% One (1) number (i) between 1 and n will provide a sqrt(n) * sqrt(n) set of 
%  indicies from the i-th block. Note this is counted using Matlab 
%  syntax going from top to bottom then left to right, a simple check 
%  for this can be found by typing the command 'reshape(1:n, sqrt(n), 
%  sqrt(n))' into the command window. 
% Two (2) numbers between 1 and n will provide the single number index of 
%  the row, column combination 
% Three (3) numbers the first (i) between 1 and n and the second (j) and 
%  third (k) between 1 and sqrt(n) will provide the index of the (j,k) 
%  point in the i-th cell 
n = 9; 

if nargin == 1 
    sM = varargin{1}; 
    majorColumn = floor((sM-1)/sqrt(n)) + 1; 
    majorRow = mod(sM-1, sqrt(n)) + 1; 

    x = (1:sqrt(n))'; 
    y = (1:n:n^1.5); 
    [x, y] = meshgrid(x, y); 
    m = (x + y - 1)'; 

    index = (n^1.5)*(majorColumn - 1) + sqrt(n)*(majorRow - 1) + m; 
elseif nargin == 2 
    index = n*(varargin{2} - 1) + varargin{1}; 
elseif nargin == 3 
    m = nsm(varargin{1}); 
    index = m(varargin{2}, varargin{3}); 
end 
end