2013-07-07 65 views
1

有沒有辦法在matlab中有效定義多個變量?我發現的一切都不太符合我的要求。這是的情況:有效定義多個變量

parstrs = {'a','b','c'}; 
parvals = [1 2 3]; 

我想要一個有效的命令,實際上會做到以下;

parstrs = parvals; 

其中結果是,數字1被存儲在變量a,2存儲在b,和3被存儲在c

我願意與細胞這樣做或結構。

有什麼建議嗎?

更多解釋:正如我在下面提到的,我想編寫代碼,不關心變量名稱列表在曲線擬合中使用多長時間。我發現最好的方法是使用結構,如下所示:

parstrs = {'a','b','c'}; 
parvals = num2cell([1 2 3]); 
partmp = {parstrs{:};parvals{:}}; 
pars = struct(partmp{:}); 

這樣做的問題是,標準桿結構不能以同樣的方式進行編輯。也就是說,

pars = setfield(pars,partmp{:}); 

會拋出以下錯誤:

Error using setfield (line 48) 
Inputs must be either cell arrays or strings. 
+0

你不能使用循環的最後一個命令,錯誤?當然是 –

+0

。我甚至已經寫了一個multisetfield函數(還有一個在lightpeed工具箱中,可能會更快)。我只是試圖避免循環,因爲頌歌的rhs在優化運行中被稱爲1000次。 – dmbortz

+0

如果其他人遇到這個問題,我的經驗是循環setfield命令是最好的。它需要約1/3的時間循環eval命令。 – dmbortz

回答

0

你可以這樣做:

[a, b] = function_returning_values(); 

您還可以使用eval

+0

我試過使用eval以及'function_returning_values'類型的命令,但是eval命令需要一個邪惡的循環:)而另一種方式需要變量的硬連線規範。 – dmbortz

2

您正在尋找eval,但是這可能仍然需要一個循環(是的,你可以生成一個較長的命令,但你真的想要嗎?):

環路(請不要使用此功能!) :

for ii=1:numel(parvals) 
    eval([parstrs(ii) '=parvals(' ii ')']); 
end 

eval大部分時間完全不需要和泄氣;更改爲單元格更容易管理和使用。你已經有了向量中的變量,使用索引來檢查它們有什麼問題?

你應該多說明一下你的應用程序,這樣我們才能明白你真的在做什麼之後,爲什麼你真的想用這種變量賦值。

爲了從GUI到基礎MATLAB環境之外輸出變量,您可以切換到evalin,並且按如下方式使用它:

function main_gui() 

    % do your thing, generate some values 
    parvals = [1 2 3]; 

    % now is the time to export 
    give_me_my_vars({'a','b','c'}); 

    % note that the following function is nested: 
    function give_me_my_vars(parstrs) 
     for ii=1:numel(parvals) 
      evalin('base',[parstrs(ii) '=' parvals(ii)]); 
     end 
    end 
end 

這是唯一可能的簡單的標量,它適合在一個字符串。我想你實際上是想尋找一些東西把變量從一個工作區切換到另一個工作區(gui到base),但我不知道這是否可能。

+0

該應用程序與曲線擬合有關。我有一個頌歌的右側,這將被稱爲大量的時間和參數將被估計。爲了瞭解哪些參數可以估算,我希望將參數名稱的單元格發送到rhs函數(其中變量名稱的順序與來自優化程序的輸入向量中的值的順序一致)。大衛 – dmbortz

+0

是的,我已經認爲它會是這樣的,檢查我的編輯 –

+0

我已經廣泛嘗試eval,evalin,arrayfun,cellfun等eval作品,但仍然必須有循環。當我嘗試給他們匿名的函數調用eval時,arrayfun和cellfun會遇到範圍問題。 – dmbortz

0

大多數,你可以存儲值在單個陣列中的機會:

x = [1 2 3]; 

然後,而不是寫a,寫x(1),而不是bx(2)等..

2

您可以使用

parstrs = {'a','b','c'}; 
parvals = {'1' '2' '3'}; 

cellfun(@(x,y)evalin('caller', [x '=' y]), parstrs, parvals) 

另外,你可以不喜歡

parstrs = {'a','b','c'}; 
parvals = {1 2 3}; 

parstrs = cellfun(@(x)[x ','], parstrs, 'UniformOutput', false); 
eval(['[' parstrs{:} '] = deal(parvals{:});']) 

然而,隨着MATLAB代碼分析器就已經抱怨,這是a bit smelly。通常,使用eval和朋友的質量定義變量是您應該考慮採用不同方法的標誌。

例如,爲什麼你甚至希望能夠通過單獨的變量名來解決這些值呢?爲什麼parvals(1),parvals(2)等不夠好?

+0

具體的應用程序更多地涉及擬合系統生物學模型。而且,常常不清楚哪些參數可以適合,哪些不適合。即,「parvals」變量的順序和長度可以根據所研究的假設而改變。我有一個使用結構正常工作的循環;我只是想知道是否有人知道任何比 更好的技巧。pars.OptStr = {'alpha','beta1','beta2','r1','r2','r3', 'I0'}; for i = 1:length(pars.OptStr); pars = setfield(pars,pars.OptStr {i},valfit(i)); end 感謝大家的想法! – dmbortz

0

怎麼樣像[a,b,c] = deal(1,2,3)?還是我簡單化了?

1

您可以從parstrs創建字段名的結構與parvals採取像這樣的值:

parstrs = {'a', 'b', 'c'}; 
parvals = [1 2 3]; 

nValues = length(parvals); 

for iValue = 1:nValues 
    s.(parstrs{iValue}) = parvals(iValue); 
end 

結構,s,那麼看起來是這樣的:

s = 
    a: 1 
    b: 2 
    c: 3 

所以不是a = 1 ,你會有s.a = 1,但我認爲這是否是你以後的。