2015-05-31 705 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