2011-11-18 55 views
4

我在MATLAB中做了科學圖像處理,它需要解決奇怪的優化問題,許多參數被「實驗」函數使用,該函數有許多不同的「輔助函數」參數的子集。傳遞這些參數是件痛苦的事情,我想要一個優雅的可擴展解決方案。matlab或其他語言中的「相對全局」變量

我的首選解決方案是一個「相對全局」變量 - 對於「main」函數的工作空間是常見的,以及主函數調用並指定他們想要共享該變量的任何子函數。但是相關的全局變量不會在聲明它的函數外部存在,並且一旦主函數返回就會消失。

的代碼是這樣的,除了會有更多的experiment_helpers,每個使用不同的方法的參數:

function y = experiment(p1,p2,p3,...) 

% declare relative global variables. 
% these will not change value within this experiment function, 
% but this experiment will be reused several times in the calling function, 
% each time with different parameter values. 
relative global p1, p2, p3 ... 

% load and process some data based on parameters 
... 

% call the helper + return 
y = experiment_helper(y,z); 

end 

function y = experiment_helper(y,z) 

relative global p1, p3 

%% do some stuff with y, z, possibly using p1 and p3, but not changing either of them. 
... 

end 

我意識到,你可以在其他幾個方面所期望的行爲 - 你可以將參數傳遞給實驗所調用的子函數,您可以將這些參數放在參數結構中並將它們傳遞給子函數,依此類推。第一個是可怕的,因爲每次我想改變參數的使用時,我都必須改變所有子功能的參數。第二個是可以的,但每次我想使用變量時都必須包含結構前綴。

我想我的問題的「正確」解決方案是使用選項結構,就像matlab在它自己的優化代碼中一樣。我只是想知道,每次我想使用參數「value」時,是否沒有一種不涉及我輸入「paramStruct.value」的輕鬆方式。我認識到相對全局變量可能導致各種調試噩夢,但我認爲它們不一定比現有全局變量造成的更糟糕。而且他們至少會擁有比不合格的全局更多的地方。

那麼真正的程序員如何處理這個問題呢?是否有優雅,易於創建和維護這類問題的設計?它可以在matlab中完成嗎?如果不是,你會怎麼做另一種語言? (我總是對使用matlab感到內疚,因爲它並不完全鼓勵良好的設計。我總是希望切換到python,但不能證明重新學習的東西和遷移代碼庫 - 除非它能讓我成爲一個更快更好的程序員在幾周內,特定於matlab的工具(如小波和優化工具箱)可以很快在python中輕鬆找到或複製。)

+0

我覺得這裏的答案應該包含單詞「命名空間層次結構」,但我不知道究竟是怎麼回事,因爲我不是csci專家。 – Paul

+0

現在我已經正確地闡述了這個問題,我已經開始尋找解決方案。 [Python模塊](http://stackoverflow.com/questions/423379/using-global-variables-in-a-function-other-than-the-one-that-c​​reated-them/423668#423668)似乎有我希望的功能,但我仍然不確定,我很確定它們不存在於matlab中。 – Paul

+1

在大多數其他語言中,類變量(「成員變量」)隱式添加到成員函數的名稱搜索空間中,因此可以在沒有進一步限定的情況下訪問它們。 –

回答

2

不,我不認爲你正在尋找Matlab。

最好的答案取決於您的主要關注點是由於傳輸參數所需的鍵入量所致,或者您在傳輸大型數據集時擔心內存使用量。我採取了幾種方法,他們都有優點和缺點。

  1. 結構中的參數。你已經在你的問題中提到過這個問題,但我想強化它在大多數情況下是一個很好的答案。而不是調用我的參數結構paramStruct,我通常只是叫它p。它始終侷限於我正在使用的功能,然後我需要鍵入p.value而不是value。我相信額外的兩個字符非常值得能夠輕鬆傳遞整套參數。

  2. InputParser。在設計需要大量輸入的功能時,我使用InputParser類。這實際上符合(1),因爲可以傳入參數結構,或者可以使用'參數'/值對,並且yuo可以允許您的函數定義默認值。很有用。

  3. 嵌套函數可以幫助在有限的情況下,但只有當您的所有功能可以分層定義時。如果你的一個內部函數足夠通用以支持多個父函數,它將限制代碼重用。

  4. 通過引用使用句柄類傳遞。如果你關心的是記憶。新的 類形式實際上允許您定義一個通過引用傳遞的參數結構。該代碼看起來是這樣的:

    classdef paramStructure < handle 
        properties (SetAccess = public, GetAccess = public) 
         param1 = []; 
         param2 = []; 
         % ... 
         param100 = []; 
        end 
    end 
    

    然後你就可以創建一個新的過程,通過引用的結構是這樣

    p = paramStructure; 
    

    和設定值

    p.param1 = randn(100,1); 
    

    由於這是通過周圍,所有傳球都是參考,與專業人士(較少的內存使用,使一些編碼風格)和缺點(通常更容易犯一些錯誤。)

  5. global變量。我盡力避免這些,但他們是一種選擇。

1

您所描述的內容在MATLAB中使用嵌套函數完全可用。他們有自己的工作區,但他們也可以訪問它們所嵌套的父功能的工作區。所以父函數可以定義你的參數,嵌套函數可以看到它們,因爲它們有一個共享範圍。

這是一個非常優雅的編程方式,並且導致調試比全局性問題少得多。 MATLAB的最新版本甚至在編輯器中用淺藍色突出顯示共享變量,以幫助實現這一點。

+0

我知道嵌套函數,但我不認爲它們正是我想要的。如果我不希望嵌套函數訪問父級工作區中的所有內容,該怎麼辦?給定一個子函數,我可能有三種類型的變量:從父工作區傳遞變量,子函數創建並修改本地副本;我想要子功能共享的父級工作區中的參數變量;以及父工作空間中的其餘變量,我不希望這些子函數因爲害怕造成錯誤而陷入困境。嵌套函數能夠正確執行所有這些嗎? – Paul

+0

從這裏,我猜我想要的是一個「安全」嵌套函數 - 我可以指定一個我希望它可以在父級工作空間中訪問的變量列表。我只是覺得給一個函數完全不受限制的訪問父項目的工作空間。我想要控制嵌套函數在父類中可能會發生什麼 - 無需編寫一堆eval語句或其他東西。我應該停止變得如此挑剔,每當我想使用paramValue時只寫「opt.paramValue」,並將opt傳遞給需要它的所有函數...... – Paul

+0

嵌套函數可以訪問父工作區的所有變量。如果您需要這種控制,也許面向對象的方法會更好,您可以指定變量是私有的,公共的還是受保護的。 –

相關問題