2014-03-04 25 views
1

這對於那些有經驗的人來說應該很簡單。 我想用R求解一個方程。我知道你可以用Solve()解決不同的線性/二次方程。如何解決這樣的象徵性功能R

但我有這樣的事情:

1/20 = 1/8 * (1/(12+x)) + 1/4*(1/(40+x)) + 3/4*(1/(50+x)) 

我該如何解決X在這種情況下?它不能手工完成。 它需要一些數字方法來解決這個問題,如TI83。

有沒有一種簡單而快速的方式來在R中做到這一點,而不寫行代碼? 謝謝!

+0

看看[Ryacas包](http://cran.r-project.org/web/packages/Ryacas/),它可能會有幫助 – Barranka

回答

4

正如你所說,確實有根。第一件事,就是繪製功能:

f <- function(x) {1/20 - 1/8 * (1/(12+x)) + 1/4*(1/(40+x)) + 3/4*(1/(50+x))} 
x <- seq(-100,100) 
par(mar=c(2,2,1,2))  # this just minimizes plot margins 
plot(x,f(x), type="l") 
abline(0,0,col="blue",lty=2) 

所以,很顯然,f(x)做跨0,幾次。

下一步是估計交叉口。要做到這一點的方法之一是尋找變化的跡象:

x <- seq(-75,0,0.001) 
y <- sign(f(x))      # vector of +1 or -1 
plus.to.minus <- which(diff(y)<0) # diff(y)<0 when f crosses from (+) to (-) 
minus.to.plus <- which(diff(y)>0) # diff(y)>0 when f crosses from (-) to (+) 
# first two roots are (+) to (-); third is (-) to (+) 
lower <- c(plus.to.minus[1:2],minus.to.plus[3]) 
roots <- sapply(lower,function(i)uniroot(f,interval=c(x[i],x[i+1]))$root) 
lapply(roots,function(x) points(roots,c(0,0,0),col="red",pch=16)) 
roots 
# [1] -67.38961 -41.72593 -10.38446 

此代碼試圖找到x其中f(x)改變符號。實際上有兩個原因,f(x)可能會改變符號:根或漸近線。在你的情況下,有三個根,三個漸近線。這裏的成功取決於在x中有一個足夠小的增量,這樣你就不會錯過一個十字路口。根據上面的圖表,0.001看起來足夠小。

這裏,y是在-75和0之間以0.001爲增量包含在x處的f的符號(如+1或-1)的向量。通過檢查上面的圖來選擇限制(-75,0)。我們可以從視覺上看到有三個根源。從(+)到( - )的前兩個十字,以及從( - )到(+)的第三個十字。因此,我們確定出現交叉點的x的索引(使用which(...)),然後創建一個包含plus.to.minus的前兩個元素和minus.to.plus的第三個元素的向量。然後我們使用increment=c(x[i],x[i+1])呼叫uniroot(...),其中i是適當交叉口的索引。

最後,我們繪製結果以確認我們已經找到了根。這非常重要 - 總是,總是繪製結果。事實證明,uniroot(...)會在有漸近線的地方找到「根」,因此您必須確保找到了真正的根。

+0

謝謝!您必須在最後添加$ root以表明我們正在尋找圍繞根的答案? – lulumink

+0

查看'uniroot(...)'的文檔。它返回一個包含幾個元素的列表; 'uniroot $ root'是根的值。 'uniroot $ f.root'是根目錄下函數的值(接近,但不是0),依此類推。 – jlhoward

+0

謝謝!我一定會研究它。 – lulumink

2

使用uniroot()解方程的一個變量:

f <- function(x){ 
    1/8 * (1/(12+x)) + 1/4*(1/(40+x)) + 3/4*(1/(50+x)) - 1/20 
} 
uniroot(f, interval = c(-1e+08, 1e+08)) 

注意的是,在功能,f,我減去1/20。這是因爲uniroot()找到該函數的零。

在這種情況下,你將得到錯誤:

Error in uniroot(f, interval = c(-1e+08, 1e+08)) : 
    f() values at end points not of opposite sign 

要糾正這一點,你需要確保零​​存在,如果是這樣,移動的時間間隔,(A,B),從而使得f (a)== -f(b)

+0

感謝您的意見。爲什麼你的輸出有錯誤?我試過並得到了同樣的結果。這裏有什麼問題,即使我將它設置爲等於零的功能? – lulumink

+0

這是因爲在那個區間內零沒有解決方案。你需要確保零​​點存在,如果存在,移動時間間隔'(a,b)',這樣'f(a)== -f(b)'。 –

+0

我很確定有一個解決我的另一個功能。它仍然給我這個錯誤。 – lulumink