2015-11-06 57 views
1

我得到以下錯誤:「在PARFOR變量X_bs不能 分類」試圖運行以下PARFOR循環時:Matlab的:PARFOR環和電池陣列工作不

y = zeros(1000,1) 
     parfor bb = 1:1000 
      rng(bb) 
      % deleted line: X_bs{8} = []; 
      for ii = 1:8 
       ind = ceil(N(ii)*rand(N(ii),1)); 
       X_bs{ii} = X{ii}(ind,:); 
      end 

      y(bb) = another_function(X_bs) 

     end 

X是1×8單元陣列,每個單元包含一個N(ii)x4矩陣(N(ii)變化)。該代碼重新對X的行進行採樣,並創建一個稱爲X_bs的單元陣列。我通過一個輸出我感興趣的變量的函數X_bsy(bb)

爲什麼我會收到此錯誤?我如何解決這個問題?

下面是一個例子:

X{1} = [1 ; 2 ; 3] 
X{2} = [4 ; 5 ; 6; 7] 
N(1) = 3 % size of X{1} 
N(2) = 4 % size of X{2} 
    parfor bb=1:10 
     rng(bb) 
     for ii = 1:2 
      X_bs{ii} = zeros(N(ii),1); 
      ind = ceil(N(ii)*rand(N(ii),1)); 
      X_bs{ii} = X{ii}(ind,:); 
     end 
     % Output is a function of X_bs. For illustration, say it is the sum 
     y(bb) = sum(X_bs{1}) + sum(X_bs{2}); 
    end 

上面的代碼得到相同的錯誤如前面:「在PARFOR可變X_bs不能被分類」。這裏是一個,它工作,不使用細胞結構簡單的版本:

X = [1 ; 2 ; 3] 
N = 3; %size of X 
parfor bb=1:10 
    rng(bb) 
    X_bs = zeros(N,1); 
    ind = ceil(N*rand(N,1)); 
    X_bs= X(ind,:); 
    y(bb) = sum(X_bs) 
end 

的問題(我認爲)位於內覆蓋細胞結構。也許parfor將細胞結構視爲切片變量而不是臨時變量。有什麼想法嗎?

更新:Adriaan提出,隨機向量ind和單元格結構X_bs{ii}存在問題。這裏要說的是不調用所述隨機矢量IND一個簡單的例子,並且仍然具有相同的錯誤:

X{1} = [1 ; 2 ; 3] 
X{2} = [4 ; 5 ; 6; 7] 
N(1) = 3 % size of X{1} 
N(2) = 4 % size of X{2} 
    parfor bb=1:10 
     for ii = 1:2 
      X_bs{ii} = X{ii}; 
     end 
     % Output is a function of X_bs. For illustration, say it is the sum 
     y(bb) = sum(X_bs{1}) + sum(X_bs{2}); 
    end 

因此,我相當肯定MATLAB是未治療的細胞結構,X_bs{ii},作爲臨時變量。

+0

我編輯並將shares_bs更改爲X_bs以避免混淆。 X_bs應該是一個臨時變量。刪除行X_bs {8} = [];後仍然出現錯誤。 –

回答

0

解決方案(感謝Andriaan的評論)是將嵌套函數randomize_X中產生X_bs的forloop放在一起。請參閱下面的解決方案對工作示例:

X{1} = [1 ; 2 ; 3] 
X{2} = [4 ; 5 ; 6; 7] 
N(1) = 3 % size of X{1} 
N(2) = 4 % size of X{2} 
parfor bb=1:10 
    [X_bs] = randomize_X(X,N) 
    % Output is a function of X_bs. For illustration, say it is the sum 
    y(bb) = sum(X_bs{1}) + sum(X_bs{2}); 
end 

其中

function [X_bs] = randomize_X(X,N) 
    for ii = 1:2 
     X_bs{ii} = zeros(N(ii),1); 
     ind = ceil(N(ii)*rand(N(ii),1)); 
     X_bs{ii} = X{ii}(ind,:); 
    end 
end 

我相當肯定,作爲切片變量,則parfor循環治療的細胞結構,因此需要事先指定的,不能在parfor循環中被覆蓋。爲了解決這個問題,一個簡單的技巧就是將單元結構的計算髮送到另一個函數。 parfoor循環與優化工具箱CVX有類似的問題。也可以使用相同的技巧 - 在parfor內的子程序中調用CVX。

1

問題是上線發佈:

ind = ceil(N(ii)*rand(N(ii),1)); 

和曲面的位置:

X_bs{ii} = X{ii}(ind,:); 

ind大小是執行parfor之前「未知」,以MATLAB,因此不能運行。 parfor不以連續順序運行,這使得事先指定所有需要的大小至關重要。或許你可以在調用y(bb)之前使用clear X_bs來繞開這個問題,這會將它們從內存中移除,並確保包含的矩陣的大小與您分配先前迭代的大小不同。

如果另一方面這不能解決它,你不能平行,因爲你每次都在使用隨機大小的矩陣。要擴大此:rand(N(ii))可以產生相當多的數字範圍。不管那個範圍,重要的事實是範圍是不確定,這意味着在執行它之前你不知道它會是什麼。儘管這通常沒有問題,但由於該單元格將存儲任何舊的矩陣大小,所以需要以便知道所有大小,以便在將作業分配給工作人員之前優化存儲器和CPU使用率。

如果可能:獲取最大值ind可以獲得並初始化臨時變量中所需的矩陣,使其成爲最大可允許的大小,並只訪問所使用的條目。

+0

閱讀過'parfor' docs,這裏有一個最後的猜測:把'parfor'放在一個函數中,它把'bb'作爲輸入參數。這種方式'parfor'很可能會運行,但我不確定它是否會加快速度。 – Adriaan

+0

謝謝。我會看看這是否有效。它可能會像我以前稱爲CVX或Knitro的類似技巧 - MatLab在parfor循環中調用CVX時遇到問題,但在循環內部嵌套函數非常好。 –