日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python牛顿法计算平方根_常用的平方根算法详解与实现

發布時間:2024/7/5 python 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python牛顿法计算平方根_常用的平方根算法详解与实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文從屬于筆者的數據結構與算法系列文章。

SquareRoot

平方根計算一直是計算系統的常用算法,本文列舉出幾張簡單易懂的平方根算法講解與實現。其中Java版本的代碼參考這里

Reference

Babylonian:巴比倫算法/牛頓法

巴比倫算法可能算是最早的用于計算$sqrt{S}$的算法之一,因為其可以用牛頓法導出,因此在很多地方也被成為牛頓法。其核心思想在于為了計算x的平方根,可以從某個任意的猜測值g開始計算。在真實的運算中,我們往往將g直接設置為x,不過也可以選擇其他任何的正數值。那么其計算的迭代過程為:

1.如果猜測值g已經足夠接近于正確的平方根,算法結束,函數將g作為結果返回。

2.如果猜測值g不夠精確,那么使用g和x/g的平均值作為新的猜測值。因為這兩個值中的一個小于確切的平方根,另一個則大于確切的平方根,選擇平均值有助于你得到一個更接近于正確答案的值。

3.把新的猜測值賦予給變量g,重復第一步的判斷。

綜上所述,其計算公式可以表述為:

其實現的參考代碼地址為SquareRoots:

public double Babylonian() {

double g = this.value;

while (isApproximate(g)) {

g = (g + this.value / g) / 2;

}

return g;

}

基于泰勒公式的級數逼近

微積分中的泰勒級數可以表示為:

在這個公式中,符號a表示某個常量,記號f'、f''和f'''表示函數f的一階、二階和三階導數,以此類推,這個公式稱為泰勒公式,基于這個公式,我們平方根公式的展開式為:

根據該公式我們可以在一定精度內逼近真實值,不過這個公式仍然存在一個問題,即是公式的收斂問題。在泰勒級數展開中,平方根函數的公式當且僅當參數值位于一個有效范圍內時才有效,在該范圍內計算趨于收斂。該范圍即是收斂半徑,當我們對平方根函數用a=1進行計算時,泰勒級數公式希望x處于范圍:$0

public double TSqrt() {

//設置修正系數

double correction = 1;

//因為要對原值進行縮小,因此設置臨時值

double tempValue = value;

while (tempValue >= 2) {

tempValue = tempValue / 4;

correction *= 2;

}

return this.TSqrtIteration(tempValue) * correction;

}

private double TSqrtIteration(double value) {

double sum = 0, coffe = 1, factorial = 1, xpower = 1, term = 1;

int i = 0;

while (Math.abs(term) > 0.000001) {

sum += term;

coffe *= (0.5 - i);

factorial *= (i + 1);

xpower *= (value - 1);

term = coffe * xpower / factorial;

i++;

}

return sum;

}

平方根倒數速算法

首先接收一個32位帶符浮點數,然后將之作為一個32位整數看待,以將其向右進行一次邏輯移位的方式將之取半,并用十六進制“魔術數字”0x5f3759df減之,如此即可得對輸入的浮點數的平方根倒數的首次近似值;而后重新將其作為浮點數,以牛頓法反復迭代,以求出更精確的近似值,直至求出符合精確度要求的近似值。在計算浮點數的平方根倒數的同一精度的近似值時,此算法比直接使用浮點數除法要快四倍。此算法最早被認為是由約翰·卡馬克所發明,但后來的調查顯示,該算法在這之前就于計算機圖形學的硬件與軟件領域有所應用,如SGI和3dfx就曾在產品中應用此算法。而就現在所知,此算法最早由Gary Tarolli在SGI Indigo的開發中使用。雖說隨后的相關研究也提出了一些可能的來源,但至今為止仍未能確切知曉此常數的起源。

其實現的參考代碼地址為SquareRoots:

public double FastInverseSquareRoot() {

double tempValue = value;

double xhalf = 0.5d * tempValue;

long i = Double.doubleToLongBits(tempValue);

i = 0x5fe6ec85e7de30daL - (i >> 1);

tempValue = Double.longBitsToDouble(i);

tempValue = tempValue * (1.5d - xhalf * tempValue * tempValue);

tempValue = this.value * tempValue;

return tempValue;

}

Comparsion:比較

筆者建立了一個專門的單元測試類來比較上述算法的準確度與性能,代碼參考SquareRootsTest,首先在準確度與穩定性測試方面,這幾種算法都能達到較好地穩定性,其中平方根倒數速算法相對而言是較好。

@Test

public void testBabylonian() {

for (int i = 0; i < 10000; i++) {

Assert.assertEquals(2.166795861438391, squareRoots.Babylonian(), 0.000001);

}

}

@Test

public void testTSqrt() {

for (int i = 0; i < 10000; i++) {

Assert.assertEquals(2.166795861438391, squareRoots.TSqrt(), 0.000001);

}

}

@Test

public void testFastInverseSquareRoot() {

for (int i = 0; i < 10000; i++) {

Assert.assertEquals(2.1667948388864198, squareRoots.FastInverseSquareRoot(), 0.000001);

}

}

而在性能測試方面,級數逼近的性能最差,巴比倫算法次之,平方根倒數速算法最好:

@Test

public void benchMark() {

//巴比倫算法計時器

long babylonianTimer = 0;

//級數逼近算法計時器

long tSqrtTimer = 0;

//平方根倒數速算法計時器

long fastInverseSquareRootTimer = 0;

//隨機數生成器

Random r = new Random();

for (int i = 0; i < 100000; i++) {

double value = r.nextDouble() * 1000;

SquareRoots squareRoots = new SquareRoots(value);

long start, stop;

start = System.currentTimeMillis();

squareRoots.Babylonian();

babylonianTimer += (System.currentTimeMillis() - start);

start = System.currentTimeMillis();

squareRoots.TSqrt();

tSqrtTimer += (System.currentTimeMillis() - start);

start = System.currentTimeMillis();

squareRoots.FastInverseSquareRoot();

fastInverseSquareRootTimer += (System.currentTimeMillis() - start);

}

System.out.println("巴比倫算法:" + babylonianTimer);

System.out.println("級數逼近算法:" + tSqrtTimer);

System.out.println("平方根倒數速算法:" + fastInverseSquareRootTimer);

}

/**

結果為:

巴比倫算法:17

級數逼近算法:34

平方根倒數速算法:7

**/

總結

以上是生活随笔為你收集整理的python牛顿法计算平方根_常用的平方根算法详解与实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。