2011-09-26 16 views
12

這一點與此相關的問題如何定義操縱控制變量定義的一部分,以減少代碼的重複

Define control as variable in Mathematica

但上面的問題沒有回答我的問題,因爲它談論的全控制定義。 (我也嘗試了一些在那裏顯示的技巧,但他們不適合我的問題)。

我現在問的只是部分控件的定義。 (使用這種論壇格式跟進一個老問題也很困難,因爲使用微小的評論區域時,很難提問和展示更多問題,比如在問一個空間較大的新問題時,可以粘貼代碼和圖片)。

我所做的所有嘗試都不起作用。我將以簡單的例子來解釋問題。

假設一個想寫

Clear["Global`*"]; 

Manipulate[Plot[f*g, {x, -1, 1}], 
Grid[{ 
    {Style["f(x)="], 
    PopupMenu[Dynamic[f], {x, x^2, x^3}, ImageSize -> Tiny]},{Style["g(x)="], 
    PopupMenu[Dynamic[g], {x, x^2, x^3}, ImageSize -> Tiny]} 
    }] 
] 

,你可以看到有配發在每個控制定義代碼重複的。 (之類的東西IMAGESIZE,Spacings->等衆多裝飾設置,重複一遍又一遍地爲每個控制。

enter image description here

什麼將是巨大的,如果我能寫類似

Manipulate[Plot[f*g, {x, -1, 1}], 
Grid[{ 
    {Style["f(x)="], PopupMenu[Dynamic[f], [email protected]@v]}, 
    {Style["g(x)="], PopupMenu[Dynamic[g], [email protected]@v]} 
    }], 

Initialization :> 
    (
    v = {{x, x^2, x^3}, ImageSize -> Tiny} 
    ) 
] 

但是,這是行不通的。我會嘗試很多其他的事情沿上述路線,並沒有什麼作品。像

{Style["f(x)="], PopupMenu[Dynamic[f], v]}, 

{Style["f(x)="], PopupMenu[Dynamic[f], [email protected]]} 

Manipulate[Plot[f*g, {x, -1, 1}], 

{{v, {{x, x^2, x^3}, ImageSize -> Tiny}}, None}, 
Grid[{ 
    {Style["f(x)="], PopupMenu[Dynamic[f], [email protected]]}, 
    {Style["g(x)="], PopupMenu[Dynamic[g], v]} 
    }] 
] 

無法得到它的工作。

但是,下面是遊戲規則:這將用於演示,因此,代碼必須以Manipulate開頭。模塊不能在外部操作。另外,不能使用Hold及其朋友。但可以使用未評估。

我希望這裏的專家可能有一個技巧來做到這一點。如果可以做到這一點,將減少代碼的大小,因爲我有許多控件,它包含許多像上面這些相同的「選項」,並且能夠執行上述操作將使代碼更易於閱讀和管理。

謝謝,

ps。我所要求的,有點類似於人們對繪圖選項所做的描述,其中人們可以使用SetOptions來設置一些常用的默認選項,以便每次不必爲每個繪圖命令重複它們。但在這種情況下沒有這樣的事情。

更新

使用下面列昂尼德所示的方法,(宏把戲),我想用它來幫助我確定的控制數,都使用一個常用的設置。這是我嘗試過的:

Manipulate[{x, y}, 

[email protected][ 
    { 
    control1 = Function[{var, initialValue, str, from, to, incr}, 
     { 
     {{var, initialValue, str}, from, to, incr, ImageSize -> Tiny} 
     } 
     , 
     HoldAll 
     ] 
    }, 

    { 
     [email protected][x, 0, "x=", 0, 1, .1], 
     [email protected][y, 0, "y=", 0, 2, .1], 
     [email protected][z, 0, "z=", 0, 10, .1] 
    }, 

    ] 
] 

這個問題只是一個額外的問題,否則它會起作用。將繼續努力解決這個問題。但接近。嘗試序列[]和平鋪[..,1]等,但還不能做到這一點。多喝咖啡,應該有所幫助。

更新2

這是利用以下方法西蒙使用,以幫助在一個以上的控制限定共同定義一個例子。這樣,人們可以使用它來減少代碼重複,以便在一組單獨的控件上使用通用選項。

注意,必須使用Control[]來控制它。

Manipulate[{x, y, z}, 

Dynamic[Grid[{ 
    {control1[x, 0, "x=", 0, 1, .1]}, 
    {control1[y, 0, "y=", 0, 2, .1]}, 
    {control1[z, 0, "z=", 0, 10, .1]} 
    }]], 

{{control1, 
    Function[{var, initialValue, str, from, to, incr}, 
    Control[{{var, initialValue, str}, from, to, incr, 
     ImageSize -> Tiny}], HoldFirst]}, None} 

] 

enter image description here

更新3

,並得到獅子座的方法也工作在一個以上的控制。訣竅是使用Control[]。不能使用普通的老版本{{x,0,"x"},...} [編輯,是的,你可以,只需要如下列Leonid更新所示的Sequence @@方法。]。

這就是:

Manipulate[{x, y, z}, 

[email protected][ 
    { 
    control1 = Function[{var, initialValue, str, from, to, incr}, 
     Control[{{var, initialValue, str}, from, to, incr, 
     ImageSize -> Tiny}] 
     , HoldAll 
     ] 
    }, 

    Grid[{ 
    {control1[x, 0, "x=", 0, 1, .1]}, 
    {control1[y, 0, "y=", 0, 2, .1]}, 
    {control1[z, 0, "z=", 0, 10, .1]} 
    }] 

    ] 
] 

enter image description here

我會嘗試(擁有超過600線的只是控制佈局代碼,到目前爲止,這些方法之一融入我的主要演示和成長一分鐘,希望這些方法會縮小這個相當多)

更新9/26/11。下午7點

我以爲我發佈了'鳥眼'的代碼保存視圖,通過使用'宏'來定義控件,其中包含許多常見的鍋爐代碼。這是前後的屏幕截圖。

再次感謝所有的答案和幫助。

enter image description here

+1

由於所有的答案(列昂尼德,西蒙,WReach)。所有偉大的答案。我選擇使用Leonid的宏觀方法只是因爲它沒有使用Dynamics,而我對Dynamics沒有太大的好處,並且似乎對它們有麻煩:)。儘管兩種方法都運行良好,但所有事情都是平等的,我更喜歡一種不使用動態的方法,只是個人的偏好,還有我缺乏動態的經驗。我發佈了一個更新,上面顯示了我獲得的代碼縮減,因爲我開始整合這種新的佈局控件的方式,並將代碼保存爲令人驚歎的演示。 – Nasser

+0

不幸的是,在許多情況下,在Mathematica中很難獲得這樣的代碼縮減,因爲它很難控制評估/寫入宏。我認爲,更好的方法來做到這一點在mma中尚未被發現(我對這個話題特別感興趣)。 –

+0

從看你的屏幕截圖我注意到你遺漏了純函數(宏)的'HoldAll'屬性。雖然這在大多數情況下都能正常工作,但在Manipulate中使用的變量的預定義值可能會導致麻煩(我不知道這是否可以在演示的背景下實際發生)。通過添加屬性,你將保護你的代碼免受這種情況的影響(這是一個將函數轉換爲宏的屬性,就其語義而言) –

回答

10

這個怎麼樣

Manipulate[Plot[f*g, {x, -1, 1}], 
[email protected] 
    With[{styleAndpopup = 
     Function[{st, fun}, 
     { 
      Style[st], 
      PopupMenu[Dynamic[fun], {x, x^2, x^3}, ImageSize -> Tiny] 
     }, 
     HoldAll]}, 
    Grid[{styleAndpopup["f(x)=", f], styleAndpopup["g(x)=", g]}]]] 

這實際上是在工作的代碼生成的微小的例子,因爲如果你看一下導致ManipulateFullForm,你會看到相同的你最初的表情。 styleAndpopup其實不是一個函數,而是一個使用With在本地定義的宏。

編輯

%的OP的要求 - 推廣到許多控件。最簡單的解決方法是插入[email protected]@...作爲Sequence @@ {[email protected][...。然而,有一些多餘的東西,可以被同時刪除:

Manipulate[{x, y}, 
[email protected][{control1 = 
    Function[{var, initialValue, str, from, to, incr}, 
     [email protected]{{var, initialValue, str}, from, to, incr, ImageSize -> Tiny}, 
     HoldAll]}, 
    Sequence @@ { 
    control1[x, 0, "x=", 0, 1, .1], 
    control1[y, 0, "y=", 0, 2, .1], 
    control1[z, 0, "z=", 0, 10, .1]}]] 
+0

你是否如何使用你的方法來定義使用'通用'定義的多個控件?請參閱我的編輯2以瞭解我所嘗試的內容。我想我正在接近。謝謝 – Nasser

+0

@Nasser edit2?我只看到一個更新。 –

+0

@sorry,只是更新,只有一個,不是2.謝謝! – Nasser

7

我去給一個解決方案几乎相同,獅子座的,並使用With插入代碼,但他打我,所以這裏的另一種方式。定義使用ControlType -> None,做你的造型動態局部功能:

Manipulate[Plot[{f, g + 1}, {x, -1, 1}], 
Dynamic[Grid[{{Style["f(x)="], pu[f]}, 
     {Style["g(x)="], pu[g]}}]], 
{{pu, Function[{f}, PopupMenu[Dynamic[f], {x, x^2, x^3}, ImageSize -> Tiny], 
     HoldFirst]}, None}] 

順便說一句,在Style["f(x)="]Style[]是多餘的,因爲你實際上並沒有設置任何風格...

+0

一個不錯的選擇 - +1。實際上,在我的解決方案中'With'並不重要,可以用'Module'來代替(儘管在這裏我認爲'With'看起來更清潔一些,但這是一個有趣的事情)。 –

+0

@Simon,我不知道我明白,上面的代碼不起作用,我在V 8.01上。是否可能有一些遺漏的代碼?我複製並運行它,請在計算機上查看編輯1的結果。 (Windows 7的)。 (並且我確實從新內核開始),謝謝。 – Nasser

+0

@Nasser:對不起,錯過了'Dynamic' ... – Simon

1

一個可以這樣做:

Manipulate[ 
    Plot[f*g, {x, -1, 1}] 
, Grid[ 
    { {Style["f(x)="], PopupMenu[Dynamic[f], opts]} 
    , {Style["g(x)="], PopupMenu[Dynamic[g], opts]} 
    } 
    ] 
] /. opts -> Sequence[{x, x^2, x^3}, ImageSize -> Tiny] 

如果一個人在分配下值的名字符號的習慣不$開始,那麼這將是謹慎地包裹在整件事210的情況下,xopts具有全局定義的值。

類似的技術是可能的多個控件的情況下:

Manipulate[ 
    {x, y, z} 
, Grid[ 
    { {control1[x, 0, "x=", 0, 1, .1]} 
    , {control1[y, 0, "y=", 0, 2, .1]} 
    , {control1[z, 0, "z=", 0, 10, .1]} 
    } 
    ] 
] /. control1[var_, initialValue_, str_, from_, to_, incr_] :> 
     Control[{{var, initialValue, str}, from, to, incr, ImageSize -> Tiny}] 
+1

這裏的問題是代碼不是以'Manipulate'開始的,而是以'ReplaceAll'開頭。這是否可以接受的示範我不知道,但它沒有達到OP在這方面的規格。當然,如果我們釋放這種情況,可能有更多的方法來達到要求的目標。 –

+0

@Leonid爲了值得,我成功地將這段代碼上傳到了Wolfram Demonstrations。 OP可以根據其他要求自由地取消其資格。 – WReach

+0

很高興知道。我沒有嘗試自己,所以依靠@Nasser所說的。 +1。 –