3

システム内の各遺伝子のタイプを与える呼び出し関数を含むコードがあります。各遺伝子の順序をその子および親と比較することで見つけることができます。コードは少量のセル配列で正常に動作しますが、量を数千に増やすと数時間かかります。コードは次のとおりです。

Types=[];
type1=level1_root; % it is fixed value (GO:0008150)
% sample values for p1 and c1 are given below
for k=1:100
    type{k}=type_fc(p1,c1,type1); % a function call - see function below
    type1=type{k}'; %'
    temp1=num2cell(repmat(k+1,length(type1),1));
    type1=[type1 temp1];
    Types=[Types; type1];
 end
 % display the output:
 Types

サブ機能:

function type=type_fc(p1,c1,type1)
type=[];
for j=1:length(type1)
    for i=1:length(p1)
        a=[p1(i),c1(i)];
        if isequal(a(1), type1(j))
            type=[type a(2)];
        end
    end
end

13 個の遺伝子について、次のサンプル入力があります。

p1'= %refer to parent genes  
      'GO:0008150'
      'GO:0016740'
      'GO:0016787'
      'GO:0008150'
      'GO:0016740'
      'GO:0016740'
      'GO:0016787'
      'GO:0016787'
      'GO:0016787'
      'GO:0006810'
      'GO:0006412'
      'GO:0004672'


 c1'=  % refer to children genes    
  'GO:0016740'
  'GO:0016787'
  'GO:0006810'
  'GO:0006412'
  'GO:0004672'
  'GO:0016779'
  'GO:0004386'
  'GO:0003774'
  'GO:0016298'
  'GO:0016192'
  'GO:0005215'
  'GO:0030533'

結果は次のようになります。Types =

  'GO:0016740'    [2]
  'GO:0006412'    [2]
  'GO:0016787'    [3]
  'GO:0004672'    [3]
  'GO:0016779'    [3]
  'GO:0005215'    [3]
  'GO:0006810'    [4]
  'GO:0004386'    [4]
  'GO:0003774'    [4]
  'GO:0016298'    [4]
  'GO:0030533'    [4]
  'GO:0016192'    [5]

このコードの速度を上げる方法はありますか?

4

2 に答える 2

7

一見すると、コードにいくつかの問題があることがわかります。

  1. Types何よりもまずtype、ループ内で動的に成長しています。これは、実行時間に関して MATLAB で非常に高くつく可能性があります。代わりに、ループの前にメモリを事前に割り当てます (つまり、事前に決定された最終要素数で配列を作成します) と、パフォーマンスが劇的に向上する可能性があります。

  2. ループを使用しています。ベクトル化されたソリューションがある場合 (まだ確認していません)、計算にかかる時間が大幅に短縮される可能性があります。

  3. ループ反復子の変数名としてiandインデックスを使用しています。jこれらの変数には、すでに別の目的があります。虚数単位を表しsqrt(-1)ます。iMATLAB では変数名におよびを引き続き使用できますjが、正しいコンテキストを把握するために行う変数名の解決には多少のコストがかかります。iiや など、他の名前を選ぶべきjjです。
    編集: についても同様です。MATLAB ではtype既に予約済みの関数名です。

次の最適化されたバージョンを試してみてください。少なくとも 1 桁速く実行されるはずです。

Types = cell(numel(c1), 2);      % # Preallocate memory
type1 = level1_root;             % # ... or p1{1}
kk = [1, 2];                     % # Initialize indices
while ~isempty(type1)
    type_fc = cellfun(@(x)c1(strcmp(x, p1)), type1, 'Uniform', false);
    type1 = vertcat(type_fc{:});
    idx = kk(1):kk(1) + numel(type1) - 1;
    Types(idx, 1) = type1;
    Types(idx, 2) = {kk(2)};
    kk = kk + [numel(type1), 1]; % # Advance indices
end
Types = Types(1:kk(1) - 1, :);   % # Remove empty output cells
于 2012-12-19T09:09:18.283 に答える
2

私が正しく読んでいれば、関数はタイプ1の値をp1の親遺伝子と比較し、一致を見つけてからc1から対応する子遺伝子を返します。これは正しいです?

その場合、ベクトル化されたソリューションはstrcmpを使用して、type1(j) と p1 の間の一致の論理配列を取得します。

>> strcmp(type1(j),p1)

これは、配列 c1 の論理アドレス指定に使用できます。事実上、抽出する c1 からの値の真理値表です。これらをセル配列として扱っていると仮定しています。その場合、このようなものが機能すると思います。

function type=type_fc(p1,c1,type1)
type={};
for j=1:length(type1)
    type=[type{:} c1(strcmp(type1(j),p1))'];
end

これで速くなるかどうかはわかりませんが、テストしていただければ幸いです。これは、「ベクトル化された」ソリューションに対する私の提案です。

于 2012-12-19T09:47:07.467 に答える