用python算微積分及牛頓迭代求解高階方程

前段時間豌熄,工作中遇到了一個難題,網(wǎng)上查了很多資料也沒有明確的解決方案物咳,后來自己想到一種解決方法锣险,決定分享出來。
下面先說下問題:如何計算irr(內(nèi)部收益率)
我們先來看下百度百科對這1名詞的解釋和計算方式的描述:


image.png

image.png

看完上面的解釋览闰,給了一大堆公式芯肤,還是沒有告訴怎么求,查看其它資料也大部分言盡于此压鉴,固執(zhí)的我看了更多的名詞解釋崖咨,終于明白了這個是怎么來的,大概就是下面這個公式:


image.png

上面公式中的y和a1到an都是已知量油吭,x就是要求的irr击蹲。這個公式怎么來的,或者說在生活中的具體例子是什么呢上鞠,可以這樣理解:
小明往銀行存錢际邻,假設(shè)月利率是1%(只為舉例,實際生活中肯定是低于此值的)芍阎,1月到12月每月存入100塊世曾,問到年底小明能拿回多少錢,肯定是像下圖這樣算。


image.png

那么問題再升級一下轮听,如果小明每月存入的金額不固定了骗露,用an表示每月存入的金額,那結(jié)果怎么算呢血巍?那其實還是很簡單萧锉,把上面公式的100改成a1到a12就好了,如下公式:


image.png

那么問題再次升級述寡,如果告訴你小明年底能拿到1000元柿隙,每期存的金額分別是a1到a12,假設(shè)利率是穩(wěn)定不變的鲫凶,此時問你利率是多少禀崖,你該怎么算呢?首先肯定還是列出下面的公式:


image.png

公式是有了螟炫,但是這是一個高階方程波附,該如何求解呢,縱觀數(shù)學(xué)史上昼钻,方程一旦高于5次是沒有求根公式的掸屡,但是偉大的先賢們還是找到了一些解決方案,就是通過多次迭代之后然评,近似的找到方程的解仅财。今天要介紹的就是幾種迭代方案中的一種——牛頓迭代,用于求解f(x)=0的解:

下面我們來看看牛頓迭代的原理:
首先我們根據(jù)泰勒公式碗淌,我們知道f(x)可由其鄰域x0的n階導(dǎo)數(shù)的表達(dá)式近似表示满着,公式如下:


image.png

因為公式中后面項的分母越來越大,其對f(x)值的影響就越來越小贯莺,所以我們?nèi)【€性部分风喇,再通過迭代的方式可達(dá)到近似求解的目的:
1、取泰勒展開的線性部分


image.png

2缕探、解線性部分的方程


image.png

image.png

3魂莫、對第2部不斷進(jìn)行迭代,直到到達(dá)一定次數(shù)或者滿足自己所求的精度爹耗,停止迭代耙考。
4、幾何意義


image.png

第二步的公式中的f'(x0)可以看做△f(x0)/△x0=(f(x0)-0)/(x0-x1)=f(x0)/(x0-x1)潭兽,所以原式可化作x=x0-f(x0)/(f(x0/(x0-x1)))=x0-(x0-x1)=x1倦始,這相當(dāng)于做了一步什么操作呢,就是從(x0,f(x0))的點做函數(shù)f(x)的切線山卦,交x軸于x1鞋邑,然后從(x1,f(x1))的點做函數(shù)f(x)的切線,交x軸于x2,不斷迭代枚碗,我們會發(fā)現(xiàn)f(xn)會越來越趨近于0逾一,這也就是牛頓迭代的中心思想。

方法是有了肮雨,可是我們怎么用程序?qū)崿F(xiàn)呢遵堵,因為公式中涉及了導(dǎo)數(shù),需要用到微分怨规,當(dāng)然陌宿,你可以用數(shù)學(xué)的方式把導(dǎo)數(shù)的表達(dá)式都計算好了,然后再通過代碼的形式帶入波丰,但是這顯然不夠智能限番,如果函數(shù)f(x)會發(fā)生變化的話,每次還要去改代碼呀舔,非常的不靈活。
在此介紹一個非常好用的模塊扩灯,python的sympy模塊媚赖,通過這個模塊,我們可以非常方便的算出微積分的結(jié)果表達(dá)式珠插,下面來看demo:

from sympy import *

# 定義一個數(shù)學(xué)符號x
x, y = symbols('x y')
# 定義一個數(shù)學(xué)表達(dá)式
exam = 3*x**4 + 5*x**3 + x**2 + 8*x + 6

# ======================求導(dǎo)
# 求導(dǎo)
print(exam.diff(x))
print(diff(exam, x))
# 結(jié)果:12*x**3 + 15*x**2 + 2*x + 8

# 求二次導(dǎo)
print(exam.diff(x, x))
print(diff(exam, x, x))
# 結(jié)果:2*(18*x**2 + 15*x + 1)

# 可以先將計算公式存儲到一個變量中惧磺,然后再通過doit計算,其實和diff的效果是一樣的
deriv = Derivative(exam, x, x)
print(deriv.doit())
# 結(jié)果:2*(18*x**2 + 15*x + 1)

# ======================求積分
# 求不定積分
print(integrate(exam, x))
print(exam.integrate(x))
# 結(jié)果:3*x**5/5 + 5*x**4/4 + x**3/3 + 4*x**2 + 6*x

# 二次不定積分
print(integrate(exam, x, x))
print(exam.integrate(x, x))
# 結(jié)果:x**6/10 + x**5/4 + x**4/12 + 4*x**3/3 + 3*x**2

# 定積分捻撑,x在0到2的積分
print(integrate(exam, (x, 0, 2)))
print(exam.integrate((x, 0, 2)))
# 結(jié)果:1048/15

# 二元積分(可定積分和不定積分結(jié)合)
print(integrate(x**2 + y**2, (x, 0, 1), (y, 0, 1)))
# 結(jié)果:2/3
print((x**2 + y**2).integrate((x, 0, 1), y))
# 結(jié)果:y**3/3 + y/3

# ======================求極限
print(limit(sin(x)/x, x, 0))
# 結(jié)果:1
print(limit(sin(x)/x, x, oo))
# 結(jié)果:0

# 當(dāng)x趨于0時磨隘,從負(fù)方向或是正方向逼近,可能會有不同的結(jié)果
print(limit(1/x, x, 0, '+'))
# 結(jié)果:oo
print(limit(1/x, x, 0, '-'))
# 結(jié)果:-oo

# ======================求泰勒展開公式
# 傳入的參數(shù)分別為x0的取值顾患、泰勒展開項數(shù)
print((x**4).series(x, 2, 2))
# 結(jié)果:-48 + 32*x + O((x - 2)**2, (x, 2))
print(series((x**4), x, 2, 6))
# 結(jié)果:32*x + (x - 2)**4 + 8*(x - 2)**3 + 24*(x - 2)**2 - 48

好了番捂,有了以上知識為基礎(chǔ)就可以解決問題了,還是回到上面的公式江解,為了方便碼字设预,我們假設(shè)小明每期的投資都是50元,上面的公式可表示為:


image.png

可以轉(zhuǎn)化為f(x)=0的形式:


image.png

接下來初始化一個x0犁河,比如0.2鳖枕,然后一步步進(jìn)行迭代x0,直到f(x0)足夠接近0桨螺,或是達(dá)到一定輪數(shù)停止宾符,即可得到近似解,下面用代碼進(jìn)行展示:
from sympy import *


x = Symbol('x')


# 獲取fx的表達(dá)式
def get_fx():
    result = 10000
    for i in range(1, 13):
        result -= 50 * (1 + x)**i
    return result


# 獲取fx導(dǎo)數(shù)的表達(dá)式
def get_diff_fx():
    fx = get_fx()
    diff_fx = fx.diff(x)
    return diff_fx


# 獲取函數(shù)的值
def get_fx_value(fx, x, limit_val):
    return limit(fx, x, limit_val)


# 牛頓迭代計算近似解
def newton_iter():
    # 初值灭翔,根據(jù)經(jīng)驗選取魏烫,如果選取的值與最終求得值得接近,會減少迭代次數(shù),提高程序效率
    x0 = 0.2
    # 精度要求则奥,當(dāng)誤差小于此值時考润,結(jié)束迭代
    prec = 0.0001
    # 最多迭代20次
    for i in range(15):
        fx = get_fx_value(get_fx(), x, x0)
        print(fx)
        if abs(fx) <= prec:
            break
        diff_fx = get_fx_value(get_diff_fx(), x, x0)
        x0 -= fx / diff_fx
    print("共進(jìn)行了%s次迭代,最終的解為%s读处,最終算得的fx的值為%s" % (i, x0, round(fx, 10)))


newton_iter()
# 運行結(jié)果:共進(jìn)行了7次迭代糊治,最終的解為0.403702825570710,最終算得的fx的值為-2.86490831058472e-11

以上為代碼罚舱,我用x0=0.4又做了一次測試井辜,發(fā)現(xiàn)只要迭代3次就是算出結(jié)果了,

共進(jìn)行了3次迭代管闷,最終的解為0.403702825570709粥脚,最終算得的fx的值為-2.86490831058472e-11

以上內(nèi)容適用范圍并不僅限于計算irr或是銀行率,而是所有涉及到高階方程的場景包个。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刷允,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子碧囊,更是在濱河造成了極大的恐慌树灶,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糯而,死亡現(xiàn)場離奇詭異天通,居然都是意外死亡,警方通過查閱死者的電腦和手機熄驼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門像寒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瓜贾,你說我怎么就攤上這事诺祸。” “怎么了祭芦?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵序臂,是天一觀的道長。 經(jīng)常有香客問我实束,道長奥秆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任咸灿,我火速辦了婚禮构订,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘避矢。我一直安慰自己悼瘾,他們只是感情好囊榜,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著亥宿,像睡著了一般卸勺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上烫扼,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天曙求,我揣著相機與錄音,去河邊找鬼映企。 笑死悟狱,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的堰氓。 我是一名探鬼主播挤渐,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼双絮!你這毒婦竟也來了浴麻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤囤攀,失蹤者是張志新(化名)和其女友劉穎软免,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抚岗,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年哪怔,在試婚紗的時候發(fā)現(xiàn)自己被綠了宣蔚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡认境,死狀恐怖胚委,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情叉信,我是刑警寧澤亩冬,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站硼身,受9級特大地震影響硅急,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜佳遂,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一营袜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丑罪,春花似錦荚板、人聲如沸凤壁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拧抖。三九已至,卻和暖如春免绿,著一層夾襖步出監(jiān)牢的瞬間唧席,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工针姿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留袱吆,地道東北人。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓距淫,卻偏偏與公主長得像绞绒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子榕暇,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 牛頓法是一種近似求解非線性方程根的迭代算法蓬衡。本文簡要敘述該算法并使用MATLAB實現(xiàn)該算法求解一元非線性方程和多元...
    edwin91閱讀 9,727評論 0 5
  • 題目: 請定義一個函數(shù)quadratic(a, b, c),接收3個參數(shù)彤枢,返回一元二次方程:ax2+ bx + c...
    kevin282閱讀 16,082評論 0 1
  • 當(dāng)你不辭而別狰晚,留下我一個,在這掙扎缴啡,我的生活變得如此的沉重壁晒,親愛的人,你好嗎业栅?
    隨心飄渺閱讀 188評論 0 1
  • 和沙漠有個約會 可能大多數(shù)人奔赴摩洛哥的最大動力秒咐,就是撒哈拉沙漠。除了原本對于沙漠遼闊與火熱的期待外碘裕,對于中國人來...
    先生姓安_AN閱讀 1,829評論 17 60
  • 像文中餐廳采用顧客監(jiān)督上菜速度携取,以果盤作為獎勵的方式,體會到當(dāng)管理成本大于交易成本時帮孔,采用雇傭客戶用于監(jiān)督雷滋,客戶從...
    伊森田慧慧閱讀 253評論 0 0