2012-08-06 48 views
1

假設我有這個Mathematica代碼,其輸出是一個實數,取決於輸入,比如x,y,z。如何根據代碼在x,y,z中創建實值函數?功能性編程

如果代碼描述了x,y,z之間的簡單關係,我可以直接定義這個函數。這裏的要點是給定的代碼是一個非常複雜的塊(或模塊)。

例如,如果代碼簡單地總結X,Y,Z,我會簡單地定義

f[x_,y_,z_]=x+y+z 

如果我有一個非常複雜的例子,像下面這樣:

s0[a_, b_, x_] := 
{1, 0, (a + b) x + (1 - a - b)} 

s1[a_, b_, c_, d_, p_, q_, n_, x_] := 

Which[0 <= x <= c, {2, n - 1, x/c*q + p}, 
c <= x <= c + d, {2, n, (x - c)/d*p}, 
c + d <= x <= 1, {1, n + 1, (x - (c + d))/(1 - c - d)*(1 - a - b)}] 

s2[s_, t_, c_, d_, p_, q_, n_, x_] := 

Which[0 <= x <= 1 - s - t, {2, n - 1, 
x/(1 - s - t)*(1 - p - q) + p + q}, 
1 - s - t <= x <= 1 - s, {3, 
n - 1, (x - (1 - s - t))/t*(1 - c - d) + c + d}, 
1 - s <= x <= 1, {3, n, (x - (1 - s))/s*d + c}] 

s3[c_, a_, b_, s_, t_, n_, x_] := 

Which[0 <= x <= 1 - a - b, {4, n - 1, x/(1 - a - b)*t + 1 - s - t}, 
1 - a - b <= x <= 1 - a, {4, n, (x - (1 - a - b))/b*(1 - s - t)}, 
1 - a <= x <= 1, {3, n + 1, (x - (1 - a))/a*c}] 

s4[p_, q_, s_, a_, b_, n_, x_] := 

Which[0 <= x <= p, {4, n - 1, x/p*s + 1 - s}, 
p <= x <= p + q, {5, n - 1, (x - p)/q*a/(a + b) + b/(a + b)}, 
p + q <= x <= 1, {5, n, (x - (p + q))/(1 - p - q)*b/(a + b)}] 

F[{k_, n_, x_}] := 
Which[k == 0, s0[a, b, x], 
k == 1, s1[a, b, c, d, p, q, n, x], 
k == 2, s2[s, t, c, d, p, q, n, x], 
k == 3, s3[c, a, b, s, t, n, x], 
k == 4, s4[p, q, s, a, b, n, x]] 

G[x_] := NestWhile[F, {0, 0, x}, Function[e, Extract[e, {1}] != 5]] 
H[x_] := Extract[G[x], {2}] + Extract[G[x], {3}] 
H[0] 

對於上面的代碼運行,需要指定列表

{a,b,c,d,p,q,s,t} 

而輸出是實數。如何在a,b,c,d,p,q,s,t中定義一個函數來分析這些實數?

+0

好的問題因爲在mathematica中的訣竅是使用模式符號「_」來使用模式進行函數式編程。在mathematica中使用Partition []函數或Split []函數來分割數字。記得用「。」對於數字來說,讓他們真正成爲數學家喜歡的符號,不知道它就像沒有「。」的真實數字。有 – 2012-08-07 04:04:42

+0

查看在線幫助中的「Piecewise」和「Switch」。至少可以使用'Switch'作爲'F'定義。你還沒有定義'e',所以你需要這樣做。但否則,目前尚不清楚你的問題是什麼。是的,你需要定義諸如's1'這樣的輔助功能來保持代碼的可讀性,但是沒有任何問題。要傳遞其他參數,您需要重新定義每個函數以獲取列表中的所有參數,或者在可以在其中全局設置的選項中進行選擇。在幫助中查找'SetOptions'。 – Verbeia 2012-08-07 06:05:43

+0

@Verbeia我的代碼似乎運行良好,沒有定義'e'。我認爲''e''''''''''''''''''''''''''''''''''''''''''''''s'''''''''''''''''''''''''''''''''''''''''''''''''''''''這是正確的理解嗎? – 2012-08-15 22:42:38

回答

6

你的本質問題是,你必須在你的輔助功能,大量的參數,但你的大字母的功能(FGH並通過數學方式單一資本字母的函數名是一個壞想法)只需要三個參數,您的輔助功能(s0等)只返回三個值在返回列表中。

有兩種可能的解決方法。

您可以重新定義一切,要求所有在整個系統中所需的參數 - 我假設整個輔助功能通用參數名稱真的是共同的價值觀 - 是這樣的:

G[x_, a_, b_, c_, d_, p_, q_, s_, t_] := 
NestWhile[F, {0, 0, x, a, b, c, d, p, q, s, t}, 
    Function[e, Extract[e, {1}] != 5]] 

您可以設置一些選項來爲整個系統全局設置這些參數。查看OptionsOptionsPattern。你會做這樣的事情:

首先,定義默認選項:這樣

Options[mySystem] = {aa -> 0.2, bb -> 1., cc -> 2., dd -> 4., 
    pp -> 0.2, qq -> 0.1, ss -> 10., tt -> 20.} 
SetOptions[mySystem, {aa->0.2, bb->1., cc->2., dd->4., pp->0.2, 
    qq->0.1, ss->10., tt->20.}] 

然後再編寫功能:

F[{k_, n_, x_}, OptionsPattern[mySystem]] := 
With[{a = OptionValue[aa], b = OptionValue[bb], c = OptionValue[cc], 
    d = OptionValue[dd], p = OptionValue[pp], q = OptionValue[qq], 
    s = OptionValue[ss], t = OptionValue[tt]}, 
    Which[k == 0, s0[a, b, x], k == 1, s1[a, b, c, d, p, q, n, x], 
    k == 2, s2[s, t, c, d, p, q, n, x], k == 3, 
    s3[c, a, b, s, t, n, x], k == 4, s4[p, q, s, a, b, n, x]] ] 

也有一些非常錯誤的與您使用的Extract(假設列表中有更多的部分比前幾次迭代中的實際部分多),但這會回答您的主要問題。

+0

第一個選項工作。對於第二個,我可能不得不花更多的時間來理解它。我沒有看到使用Extract有什麼問題。我的代碼似乎正在工作。你能解釋一下嗎? – 2012-08-15 22:33:17

+0

@MichaelC只是當我運行你的代碼時,它想要在抽象出的第n部分中提取出某些東西,比如列表中的'n-2'部分。所以它找不到第n個部分並拋出錯誤。 – Verbeia 2012-08-15 22:37:36