2012-02-12 19 views
2

我試圖創建三個獨立的圖表,這個代碼將會給你的想法:動態Mathematica中沒有重複的代碼

f[t_] := Sin[10 t] + Cos[15 t]; 
Slider[Dynamic[dx], {0.01, 1}] 
var = Dynamic[Fourier[Table[f[t], {t, 0, 100, dx}]]]; 
ListLinePlot[Abs[var]] 
ListLinePlot[Re[var]] 
ListLinePlot[Im[var]] 

這不會起作用,因爲無功並沒有進行評估的那麼ListLinePlot/Abs/Re/Im不會將其識別爲數字列表。動態必須包裝ListLinePlot。

包裝ListLinePlot以及其他一切與動態工作。但是,那麼我將不得不計算傅立葉[表格[...每個圖表一次...。根據原則,我不想有這樣的代碼重複。

這是避免重複的代碼,但不是語義爲我所提出的不工作上面例子的方式,再加上它把所有系列中的一個圖形,而不是在三個獨立:

Dynamic[ 
ListLinePlot[ 
    (#[Fourier[ 
     Table[f[t], {t, 0, 100, dx}] 
     ]]) & /@ {Abs,Re,Min}, DataRange -> {0, 100} 
    ] 
] 

希望你可以現在看看我正在努力實現的目標。就像我的第一段代碼,除了它應該工作。我怎樣才能做到這一點?

+0

你見過新的[Mathematica StackExchange](http://mathematica.stackexchange.com/)嗎?大多數曾經在\ [mathematica \]標籤中回答的人已經移到那裏。你可能會在那裏得到更好的回覆。 – Szabolcs 2012-02-13 07:58:27

回答

4

在你只需要包裝Dynamic周圍需要重新計算表達式大多數情況下。正如你注意到沒有,如果你包裹Dynamic周圍的var內容時,它不會工作,因爲ListPlot會看到一個Dynamic頭,不在列表,當你通過var它。在這種情況下需要重新計算的是完整的ListPlot

正確的解決方法是使用一個延遲定義爲var(即:=而不是=)和周圍ListPlot包裹Dynamic

f[t_] := Sin[10 t] + Cos[15 t]; 
Slider[Dynamic[dx], {0.01, 1}] 

var := Fourier[Table[f[t], {t, 0, 100, dx}]]; 

[email protected][Abs[var]] 
[email protected][Re[var]] 
[email protected][Im[var]] 

人們常常會混淆Dynamic因爲它有時深顯示了在表達式中,例如在你的Slider例子中。但Dynamic有一個不同的功能:設置一個值。

通常,除非用於設置值,否則Dynamic總是需要是表達式中最外面的頭部。 (有一些例外,尤其是當我們正在處理的是直接對應什麼是顯示在屏幕上的表達,並通過前端被處理,如基本圖形:Slider[Dynamic[x], {0, 5}]Graphics[{Disk[], [email protected][{x, 0}]}]會奏效。)

Dynamic隻影響表達式在前端顯示的方式,而不是內核如何看待它們。這裏有一個例子:

x=1 
arr = {Dynamic[x], 2, 3} 

前端顯示arr{1, 2, 3},但內核仍然將其視爲{Dynamic[x], 2, 3}。因此,如果我們計算Total[arr],則前端將顯示爲1 + 5,但內核將看到是否爲Dynamic[x] + 5。我希望這可以澄清一些情況。

注意:我不想在此解決方案中使用Manipulate,因爲OP沒有使用它。 Manipulate只是一個高級便利功能,它可以通過Dynamic和一些控件(如Slider)實現。

0

未經測試:

f[t_] := Sin[10 t] + Cos[15 t]; 
Slider[Dynamic[dx], {0.01, 1}] 
Dynamic[var = Fourier[Table[f[t], {t, 0, 100, dx}]]]; 
Dynamic[ListLinePlot[Abs[var]]] 
Dynamic[ListLinePlot[Re[var]]] 
Dynamic[ListLinePlot[Im[var]]] 

我想這應該算Fourier只有一次。根據我的理解,在評估Fourier(注意,var的分配是內部的Dynamic)之後,應通過var的變化觸發ListLinePlot

+0

我無法得到這個工作。看起來它有同樣的問題。 – 2012-02-12 13:21:44

+0

好吧,不幸的是我目前無法測試它。但是,你確定所有的舊定義都被清除了嗎(最好是通過啓動一個新的內核)?你如何檢查傅里葉執行的頻率?請注意,移動滑塊可能會觸發執行多個*不同*值。如果直接分配給'dx',會發生什麼? – celtschk 2012-02-12 13:26:32

+0

我知道該列表是正確的,因爲發生了什麼,它會在紅色背景上打印出來。像這樣:ListLinePlot [Abs [<傅立葉變換數字列表(與f [t]相反的複數)>]]。這些值隨着滑塊的變化而變化。 – 2012-02-12 16:19:52

2

你可能想是這樣的:

f[t_] := Sin[10 t] + Cos[15 t] 

DynamicModule[{var}, 
Manipulate[ 
    var = Fourier[Table[f[t], {t, 0, 100, dx}]]; 
    {ListLinePlot[Abs[var]], 
    ListLinePlot[Re[var]], 
    ListLinePlot[Im[var]]}, 
    {dx, 0.01, 1} 
]] 

Mathematica graphics