1. 程式人生 > >Boost裡面終於有了multiple precision的工具了

Boost裡面終於有了multiple precision的工具了

In this example we'll show several implementations of the Jahnke and Emden Lambda function, each implementation a little more sophisticated than the last.

The Jahnke-Emden Lambda function is defined by the equation:

JahnkeEmden(v, z) = Γ(v+1) * Jv(z) / (z / 2)v

If we were to implement this at double precision using Boost.Math's facilities for the Gamma and Bessel function calls it would look like this:

double JEL1(double v, double z)
{
   return boost::math::tgamma(v + 1) * boost::math::cyl_bessel_j(v, z) / std::pow(z / 2, v);
}

Calling this function as:

std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::digits10);
std::cout << JEL1(2.5, 0.5) <<
std::endl;

Yields the output:

9.822663964796047e-001

Now let's implement the function again, but this time using the multiprecision type cpp_dec_float_50 as the argument type:

boost::multiprecision::cpp_dec_float_50
   JEL2(boost::multiprecision::cpp_dec_float_50 v, boost::multiprecision::cpp_dec_float_50
z) { return boost::math::tgamma(v + 1) * boost::math::cyl_bessel_j(v, z) / boost::multiprecision::pow(z / 2, v); }

The implementation is almost the same as before, but with one key difference - we can no longer call std::pow, instead we must call the version inside the boost::multiprecision namespace. In point of fact, we could have omitted the namespace prefix on the call to pow since the right overload would have been found via argument dependent lookup in any case.

Note also that the first argument to pow along with the argument to tgamma in the above code are actually expression templates. The pow and tgamma functions will handle these arguments just fine.

Here's an example of how the function may be called:

std::cout << std::scientific << std::setprecision(std::numeric_limits<cpp_dec_float_50>::digits10);
std::cout << JEL2(cpp_dec_float_50(2.5), cpp_dec_float_50(0.5)) << std::endl;

Which outputs:

9.82266396479604757017335009796882833995903762577173e-01

Now that we've seen some non-template examples, lets repeat the code again, but this time as a template that can be called either with a builtin type (floatdouble etc), or with a multiprecision type:

template <class Float>
Float JEL3(Float v, Float z)
{
   using std::pow;
   return boost::math::tgamma(v + 1) * boost::math::cyl_bessel_j(v, z) / pow(z / 2, v);
}

Once again the code is almost the same as before, but the call to pow has changed yet again. We need the call to resolve to either std::pow (when the argument is a builtin type), or toboost::multiprecision::pow (when the argument is a multiprecision type). We do that by making the call unqualified so that versions of pow defined in the same namespace as type Float are found via argument dependent lookup, while the using std::pow directive makes the standard library versions visible for builtin floating point types.

Let's call the function with both double and multiprecision arguments:

std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::digits10);
std::cout << JEL3(2.5, 0.5) << std::endl;
std::cout << std::scientific << std::setprecision(std::numeric_limits<cpp_dec_float_50>::digits10);
std::cout << JEL3(cpp_dec_float_50(2.5), cpp_dec_float_50(0.5)) << std::endl;

Which outputs:

9.822663964796047e-001
9.82266396479604757017335009796882833995903762577173e-01

Unfortunately there is a problem with this version: if we were to call it like this:

boost::multiprecision::cpp_dec_float_50 v(2), z(0.5);
JEL3(v + 0.5, z);

Then we would get a long and inscrutable error message from the compiler: the problem here is that the first argument to JEL3 is not a number type, but an expression template. We could obviously add a typecast to fix the issue:

JEL(cpp_dec_float_50(v + 0.5), z);

However, if we want the function JEL to be truly reusable, then a better solution might be preferred. To achieve this we can borrow some code from Boost.Math which calculates the return type of mixed-argument functions, here's how the new code looks now:

template <class Float1, class Float2>
typename boost::math::tools::promote_args<Float1, Float2>::type
   JEL4(Float1 v, Float2 z)
{
   using std::pow;
   return boost::math::tgamma(v + 1) * boost::math::cyl_bessel_j(v, z) / pow(z / 2, v);
}

As you can see the two arguments to the function are now separate template types, and the return type is computed using the promote_args metafunction from Boost.Math.

Now we can call:

std::cout << std::scientific << std::setprecision(std::numeric_limits<cpp_dec_float_100>::digits10);
std::cout << JEL4(cpp_dec_float_100(2) + 0.5, cpp_dec_float_100(0.5)) << std::endl;

And get 100 digits of output:

9.8226639647960475701733500979688283399590376257717309069410413822165082248153638454147004236848917775e-01

As a bonus, we can now call the function not just with expression templates, but with other mixed types as well: for example float and double or int and double, and the correct return type will be computed in each case.

Note that while in this case we didn't have to change the body of the function, in the general case any function like this which creates local variables internally would have to usepromote_args to work out what type those variables should be, for example:

template <class Float1, class Float2>
typename boost::math::tools::promote_args<Float1, Float2>::type
   JEL5(Float1 v, Float2 z)
{
   using std::pow;
   typedef typename boost::math::tools::promote_args<Float1, Float2>::type variable_type;
   variable_type t = pow(z / 2, v);
   return boost::math::tgamma(v + 1) * boost::math::cyl_bessel_j(v, z) / t;
}

相關推薦

Boost裡面終於multiple precision工具

In this example we'll show several implementations of the Jahnke and Emden Lambda function, each implementation a little more sophisticated than the las

終於任何程式設計師都能快速編寫文件的工具

李老闆:小王,咱們馬上要參加一個宇宙超級管理系統的投標,你組織人員寫個競標方案!李老闆:小王,那個宇宙超級管理系統咱們中標了,你這幾天寫個需求文件馬上安排開發吧!李老闆:小王,宇宙超級管理系統已經上線了,客戶反映使用太複雜,你寫個使用者手冊吧!小王:競標方案,幾百頁都算是少的

十五年的網,今天終於自己的博客。

學習 時間 生活 現在 意見 qq炫舞 在那 clas 開始 如果從8歲那年開始算起,我已經接觸網絡這個東西十五年有余了。 從最初的暴力摩托、cs1.5、流星蝴蝶劍、到征服、奇跡、魔域、武魂、跑跑卡丁車、勁舞團、泡泡堂、QQ堂、再到騰訊出品的QQ炫舞、穿越火線。 再到現在的

很多未解之謎終於答案——2018年JVM生態系統報告出爐

在Java開發者中,一直存在著很多鄙視鏈。如: IntelliJ → Eclipse → NetBeans Unix → Linux → Mac OS→ Windows → DOS Emacs → Vim → Sublime → Word → Power Point 這諸多鄙視鏈中一直存在著很大的

App邀請追蹤技術如何實現?終於答案

場景:分享二維碼給好友,邀請好友下載 App,這種情況下如何追蹤使用者來源。 以球球大作戰為例,掃描對方二維碼跳轉到一個 web 頁面 下載頁面可以選擇下載的使用者型別:安卓或 IOS。點選 ios 會跳轉到 appstore, 點選 Android,會直接讓下

終於電腦用!搗鼓好久的小玉家的電費

終於組裝了臺電腦,花了三千塊。Ryzen5 2600+GTS250,8G DDR4駭客神條,240G SSD。幾秒鐘就能開機,開機完立刻就能開啟軟體,還能同時開很多軟體,徹底顛覆了之前我對電腦的印象。 拿到新電腦肯定刷洛谷啊,之前都沒時間刷。結果新手村就卡住了(忘記怎麼不開double四捨五入)。這麼久不用

GGTalk即時通訊系統(支援廣域網)終於移動端!(技術原理、實現、原始碼)

      首先要感謝大家一直以來對於GGTalk即時通訊系統的關注和支援!GGTalk即時通訊系統的不斷完善與大家的支援分不開! 從2013年最初的GG1.0開放原始碼以來,到後來陸續增加了網盤功能、遠端協助功能、離線檔案功能、群聊功能、語音聊天功能、視訊聊天功能、以及視訊錄製功能、和增加了資料庫——一路走

終於自己的blog

我的blog終於誕生了,以前總是給自己找種種理由,不願邁出這第一步,其實邁出之後才發現一切都是那麼的簡單(呵呵)。從我剛接觸網路起,我就想能在浩瀚無邊的網路的海洋中有自己的一席之位,做過自己的網站,申請過自己的空間,但現

ReportMachine終於更新

從2006年下半年開始RM就沒更新過,老王也找不到人了,我打算以後要換FAST REPORT了,最近在他的群裡看到了一點希望,好像老王又出來了,而且網址也換了。(http://rmachine.5d6d.com)現在就是

回撥函式,終於個講的明白的

所以,實現庫函式時,庫函式的一些功能如果想讓使用者自己去定製,那此時就留下一個回撥函式的引數。 呼叫者呼叫庫函式,庫函式又反過來呼叫呼叫者自己寫的函式,這個過程就叫回調。 簡單說,看到一個函式(一般是庫函式,普通函式或者自己寫的某些api也可以)裡的引數有函式指標,這個指

打擊破解軟體,終於解決良方

    長久以來,智慧財產權是私權,侵犯智慧財產權是對神聖私有財產的侵犯,其行為等價於盜竊甚至搶劫。隨著時間發展和宣傳的不斷增強,這種觀點已經成為了現代社會的一個普遍被接受的價值觀念。“盜版”等於“偷竊”已經成為了新的道德標準。乃至很多國家的法律甚至對個人下載盜版內容都處以

那些困擾你多年的專案管理問題,終於解決方案

> 一個專案經理的自述: > “資源永遠是少的,時間永遠是不夠的,需求永遠是變化的,客戶永遠是不成熟的。”這話雖然有些

新研究個東東,家裡的廢舊顯示器終於利用價值

這些年下來,家裡,公司有很多廢舊的電視機,顯示器,投影機。你說扔掉吧,有點可惜,賣給收廢品的吧,其實和扔也差不多。總想著怎麼把這個淘汰下來的顯示器給利用上呢。 這些顯示器都有個共性,就是帶有VGA介面。上網搜尋研究了一下,發現VGA介面是可以程式設計驅動的。 VGA的電氣介面除了GND以外,基本的必須有5條訊

不會裝系統?這篇就夠

class 等待 中文專業 選中 sof 可靠的 自動下載 all 並且 這裏我便把我知道的安裝系統的知識分享給大家。其實安裝系統是一個十分簡單的工作,但是很多朋友畏於電腦系統的復雜,總是害怕自己安裝會出問題,甚至把電腦裝壞。其實大可不必有此擔心,隨便你怎麽安裝系統,頂多也

出事!出大事!51CTO博客新動作啦!

博客 文章 排行榜 我的朋友 我在博文中分享了那麽多的幹貨,要怎麽分享給我的朋友呢?我都升級到專家博主了,我怎麽才能在廣而告之呢?現在移動端都做的這麽牛掰,為啥文章卻只能屈居於PC端?圖樣圖森破!現在我們的51CTO博客全都可以適配哦! 活動內容:1.申請推薦博文凡在2017年5月17日-20

想要對HTML5深入解,必須解這些

設備 能夠 地理定位 target 學習 pro program 網絡存儲 並且 你想要創建動態的、交互的、富數據的、保持連接的網頁。等等,網頁?為什麽不直接使用HMTL5來創建成熟的web應用?還有,為什麽不使用那些現代技術來實現,它們早在支持移動設備的時候就已經支持你的

5、終於代碼積累越來越多……

pythonpython的學習,看了也寫了一些代碼,慢慢發現沒一條語句的標準寫法以及作用和效果好吧!繼續ing 慢慢充實知識庫。5、終於代碼積累越來越多了……

Docker 1.13 最實用命令行:終於可以愉快地打掃房間

存儲 清理 有用 磁盤使用 資源 命令 esc 沒有 空間 Docker 1.13 出來已經有一段時間了,新版本添加了許多有用的命令,本文作者從處女座的潔癖(此處有霧)出發,告訴大家一些整理環境的小技巧。打掃房間再也不需費時又費力了,簡單的命令,就可以輕松地把物品

終於開始我的java旅程

查詢 3.3 今天 ase htm windows 歷史版本 1.8 .html 首先今天先裝了jdk1.7 ,找了半天,因為官網是都是讓你裝1.8的最新版本,地址如下: 所有jdk的歷史版本: http://www.oracle.com/technetwork/java/