2016-08-21 5 views
2

私は大きな行列を持っていますが、大きな行列全体に渡って動くスライディングウィンドウから取り出した小さな行列を抽出する必要がありますが、行列は変更されないので、新しいコピーを作成せずにサブ行列を抽出したいのですが、代わりに大きな行列の一部を指すCポインタのように機能します。これどうやってするの?どうもありがとうございました、私を助けてください:)Matlabでコピーを作成せずに部分行列を抽出する方法

+1

MATLABにはポインタはありませんが、あなたのサブマトリックスの境界を追跡し、この 'M(rmin:rmax、cmin:cmax)'のような元の行列を参照することができます – jodag

+0

@jodagしかし、 M(rmin:rmax、cmin:cmax)は新しい行列を作成しませんか?そして、M(rmin:rmax、cmin:cmax)を書くのはちょっと冗長です:( –

+2

はい、新しい行列を作成します。そして、おそらく新しい行列は、何があっても部分行列に対して計算が行われると割り当てられます。 – jodag

答えて

0

を私は明示的な一時的な行列を使用しないと高速であり、そしてそれはおそらくないかどうかをテストするためにいくつかのベンチマークをした:

function move_mean(N) 
M = randi(100,N); 
window_size = [50 50]; 
dir_time = timeit(@() direct(M,window_size)) 
tmp_time = timeit(@() with_tmp(M,window_size)) 
end 

function direct(M,window_size) 
m = zeros(size(M)./2); 
for r = 1:size(M,1)-window_size(1) 
    for c = 1:size(M,2)-window_size(2) 
     m(r,c) = mean(mean(M(r:r+window_size(1),c:c+window_size(2)))); 
    end 
end 
end 

function with_tmp(M,window_size) 
m = zeros(size(M)./2); 
for r = 1:size(M,1)-window_size(1) 
    for c = 1:size(M,2)-window_size(2) 
     tmp = M(r:r+window_size(1),c:c+window_size(2)); 
     m(r,c) = mean(mean(tmp)); 
    end 
end 
end 

M用サイズ100 * 100で:

dir_time = 
     0.22739 
tmp_time = 
     0.22339 

したがって、一時変数を使用すると、コードが読みやすくなり、遅くならないようです。

+0

実際には、あなたのテストの違いは、直接ケースの 'mean'への二重呼び出しにあると思います。もしあなたがtemp caseコードを' mean(mean(tmp)) 'に変更すると、違いはありません。 –

+0

@NoelSeguraあなた、私はあまりにも控えめでした。それを修正するために私の答えを編集しました。 – EBH

0

この回答では、一般的に「最良の」解決策について説明します。この回答のために、私は、「最高」を重要なパフォーマンスヒットなしに最も読みやすいものとして定義します。 (既存の回答によって部分的に示されている)。

は基本的にあなたがであってもよく、2つの状況がある。

1.あなたは、一般的に最善の解決策は、部分行列を含む一時的な変数を作成することである。このような状況では、あなたの部分行列数回

を使用しています。

A = M(rmin:rmax, cmin:cmax) 

あなたを幸せにしません(機能/匿名関数あなたのための行列にインデックスを定義する)、それを回避する方法が、一般的にはあるかもしれません。

M(rmin:rmax, cmin:cmax) 

部分行列を使用して、特定の場合のみ1:あなたはあなたの部分行列だけで1時間

はこの場合、最善の解決策は、あなたがコメントで言及まさに一般的である使用

2時間は、それが関数に一度渡されるときです。もちろん、サブマトリックスの内容はその機能で数回使用されるかもしれませんが、それは無関係です。

関連する問題