2017-01-23 4 views
1

出力として1次元配列と結果を持つパラメトリック解析からデータを後処理する必要があります。 この1次元配列を、調査したパラメータの次元が正しい順序である多次元行列に再整形したいと考えています。これらの次元は数値が異なる場合があります。潜在的に非常に大きな1次元配列を可変次元の多次元行列に変形する

私はfor-loopsに基づいて関数を考え出すことができましたが、問題は非常に大きな配列ではRAMが不足していることです。私はこれがこれを行う最も賢い方法ではないことを完全に認識しています。 このような大きな配列を操作し、私の関数と同じ仕事をするよりスマートな方法があるのだろうかと思っていました。例として

function [Tensor, n_dimensions]=reshape_array(Data,ndim) 

n_dimensions=length(ndim); 
n_elements=prod(ndim); 

reshape_string=[]; 
for i=n_dimensions:-1:1 
    if i==1 
    reshape_string=strcat(reshape_string, ' ndim(', num2str(i) , ')])'); 
    elseif i== n_dimensions 
    reshape_string=strcat(reshape_string, ' [ndim(', num2str(i) , ')'); 
    else 
    reshape_string=strcat(reshape_string, ' ndim(', num2str(i) , ') '); 
    end 

end 

invert_string=[]; 
for i=1:n_dimensions 
    if i==1 
    invert_string=strcat(invert_string, 'ndim(', num2str(i) , '),'); 
    elseif i== n_dimensions 
    invert_string=strcat(invert_string, ' ndim(', num2str(i) , ')'); 
    else 
    invert_string=strcat(invert_string, ' ndim(', num2str(i) , '),'); 
    end 

end 

reshape_statement=strcat('reshape(Data,',reshape_string); 
invert_statement=strcat('zeros(',invert_string,');'); 

Tens1=eval(reshape_statement); 
Tens2=eval(invert_statement); 

nLoops=length(ndim); 
str = ''; 
str_dim_tens=''; 
str_dim_indeces=''; 
for i=1:nLoops 
    str = strcat(sprintf('%s \n for i%d=1:',str,i), sprintf('%d',ndim(i))); 
    if i<nLoops 
    str_dim_tens=strcat(str_dim_tens,'i',num2str(i),','); 
    else 
    str_dim_tens=strcat(str_dim_tens,'i',num2str(i)); 
    end 
end 

for i=nLoops:-1:1 
    if i~=1 
    str_dim_indeces=strcat(str_dim_indeces,'i',num2str(i),','); 
    else 
    str_dim_indeces=strcat(str_dim_indeces,'i',num2str(i)); 
    end 
end 

str = strcat(sprintf('%s \n Tens2(%s)=Tens1(%s);',str,str_dim_tens,str_dim_indeces)); 

for i=1:nLoops 
    str = sprintf('%s \n end',str); 
end 

eval(str) 

Tensor=Tens2; 

end 

ndim=[2 3]; 
Data=1:2*3 
[Tensor, n_dimensions]=reshape_array(Data,ndim); 

n_dimensions = 

    2 

Tensor = 

    1  2  3 
    4  5  6 

Iは要素数百万の複数の寸法(例えば、最小4)とデータ配列と機能するであろう。例はM(10,10,10,300000) である可能性があります。これは、私が仕事をするために計算上最も費用のかからない方法を探していた理由です。

ありがとうございました!

答えて

5

コードから、Matlabのcolumn-majorの反対のディメンションオーダーを使用して、再構成された配列の要素を塗りつぶしたいとします。

これは、次元が逆順(reshapeを使用)で配列に再形成され、次元の順序が逆順になるようにすることで行うことができますpermute)。

n_dimensions = numel(ndim); 
Tensor = reshape(Data, ndim(end:-1:1)); % reshape with dimensions in reverse order 
Tensor = permute(Tensor, n_dimensions:-1:1); % reverse back order of dimensions 
+1

本当に細胞が必要ですか?変形を形状入力として配列に受け入れないか? –

+0

良い点!私はそう思います。私は後でそれを編集します、今私は実行する必要があります。または自分で編集してください:-) –

+1

スマートで、速く、短く。ありがとう! –