#Julia言語 ほとんどマクローリン展開なのですが、DS1~DS6の値をじっと見れば、高次の係数ほど大きくずらしてあって、ぴったりマクローリン展開にはなっていないことが分かります。

この微妙な点も結構面白いはず。

Juliaのリポジトリへのリンク↓
github.com/JuliaLang/juli… Image
#Julia言語 返答や引用ツイートを見ると、これをテイラー・マクローリン展開そのものだと誤解している人が多いな。

マクローリン展開ならDS1, DS2が

-1/6=-0.16666…
1/120=0.0083333…

と6,3がずっと続くことになるのですが、そうなっていない。

マクローリン展開そのものだと精度的に損。
#Julia言語 #数楽

浮動小数点数の mod 2π での剰余を求めるのは非常に大変。

Juliaではそのためのコードが別ファイルになっていて、非常に複雑。

rem_pio2_kernel(x::Union{Float32, Float64}) はxをπ/2で割った剰余とxを2πで割った剰余がその何倍かを計算。

github.com/JuliaLang/juli… Image
#Julia言語 mod 2π の浮動小数点数での計算は大変なので sin(x) の実装は大変。

sin(πx) ならば圧倒的に楽。

Juliaのtrig.jlではsinpi(x)も定義されています。

sin(2πx) を計算したい場合にはJuliaでは sinpi(2x) と書いた方がお得です。sin(2πpx) なら sinpi(2p*x)

github.com/JuliaLang/juli… Image
#Julia言語

Julia界では「初等及び特殊函数をpure Juliaで実装しておくことには自動微分でメリットがある」とよく言われています(した)。

現実のメリット→既存のライブラリをJulia版で置き換えると計算速度が上がることが多いのと、Julia界は数学強者が多いので、だったらJuliaで書いちゃえと。
#Julia言語

pure Juliaで書くこと関連情報↓

discourse.julialang.org/t/specialfunct…
#Julia言語

Juliaに限らず、特殊函数や高速フーリエ変換などのコードをどのように書くべきか(生成するべきか!)については、


JuliaCon 2019 | Keynote: Professor Steven G. Johnson

を視聴するとよいです。これ、何度も勧めているのですが、めちゃくちゃ面白いです。
#Julia言語 Juliaの周辺の情報をあさると数学の勉強になってしまうことがよくあります。

高速計算の話題ではすぐにSIMDやコンパイラによる最適化などの話題にしたがる人が多いのですが、上で紹介したSteven G. Johnsonさんは全然違います。 Image
#Julia言語 JuliaConでの講演なのでJuliaも話題に。

pure Juliaで書き直したerfinv函数はSciPyで使われているFortranライブラリよりも2~3倍速いらしい。

これを「Juliaのコンパイラの最適化がすごいのか?」のように解釈しちゃダメです。Johnsonさんはもっと普遍的な方法の解説をしています。 Image
#Julia言語 erfinv函数は正規分布を扱うときには必須の基本特殊函数です。そういう基本特殊函数の普及しているライブラリが採用しているアルゴリズムは十分に最適化されていないっぽい。

そういうことがJuliaで特殊函数を実装し直すことによって判明してしまったわけです。
#Julia言語 SpecialFunctions.jlのerfinvのコード

こちらでは多項式近似ではなく、有理函数近似が使われています。

Horner法で分子分母の多項式を効率よく計算している。

この方法はJulia以外の言語でもほとんどそのまま使えます。

github.com/JuliaMath/Spec… Image
#Julia言語 SGJさんはMITでの講義で指数積分函数E₁(z)の実装を宿題で出しています。その模範解答(Julia v0.6版)が

nbviewer.jupyter.org/github/steveng…
(↑これも非常に面白い!)

にあり、Julia v1でも動くようにしたものが

nbviewer.jupyter.org/gist/genkuroki…

にある。あるFortranライブラリの5~6倍の速さ!
既存の基本特殊函数ライブラリの最適化が不十分であることは、 #Julia言語 について調べた人が気付いてしまう驚くべき事実の一つだと思います。

誰かCでも使えるような(ゆえにほとんどの環境で使えるような)、爆速の基本特殊函数ライブラリを書くべきだと思います。
例えばベイズ統計関連の数値計算(例えばMCMC法)では確率密度函数の対数の計算が膨大な回数繰り返されます。その計算では基本特殊函数が使われます。

仮にその部分が数倍高速化がすればMCMC法の計算も体感できるくらい速くなると思う。

基本特殊函数ライブラリの最適化は重要です。
ただし、CやFortranで書かれた基本特殊函数ライブラリが十分に最適化されていなかったことには理由があると思う。

MITでの宿題の答え nbviewer.jupyter.org/github/steveng… を見ると、特殊函数のコードの最適化を気分よく行うためには、コードの自動生成(マクロ)、視覚化、その他諸々の道具が必須なことが分かる。
#数楽 #Julia言語 #統計 google.com/search?q=minim…
minimax polynomial approximation of sine を検索

「ミニマックス」は「最悪の(最大の)誤差を最小化するようにパラメータを調節すること」を意味しています。

統計的推測のミニマックスゲームの例↓
最悪の場合の害を最小化すること(ミニマックス)は多くのゲームの基本。

例えば、相手が自分にとって最悪の手を指して来ても対応できるような手を探すことが将棋や囲碁の基本。

そういう考え方は最悪の誤差を最小化したい場面でも出て来る。
#数楽 私も知らないので、自分でテキトーにやってみました。

* チェビシェフ多項式のミニマックス性を使って、sin((π/4)x)の十分高次のマクローリン展開を区間[-1, 1]で最良近似する13次の多項式を数値的に求める。

* そこからsin(x)の近似多項式を作る。

gist.github.com/genkuroki/2f82… ImageImageImageImage
#数楽 高次の多項式を低次の多項式で区間[-1,1]上のsupノルムの意味で最良近似するにはチェビシェフ多項式を使えます。

だから、原理的には、sin((π/4)x)を[-1,1]でものすごい精度で近似する多項式を高次のマクローリン展開で作って、低次の多項式で最良近似すれば欲しいものが得られます。
#数楽 チェビシェフ多項式を使った計算はBigFloatで遂行。

添付画像の上半分のグラフはそのようにして私が作った多項式函数の値とJuliaの例のsinの差の10^16倍のグラフです。ほぼ一致!

下半分のグラフは13次のマクローリン展開の場合です。x=π/4の近くで誤差が大きい

gist.github.com/genkuroki/2f82… Image
#数楽 #Julia言語

添付画像は上から順に

* BigFloat表示での私が求めた13次の近似多項式
* Juliaのtrig.jlにある係数
* Float64に変換した私が求めた13次の近似多項式
* Float64に変換した13次のマクローリン展開

Juliaのと私のでは結構値が違います。

gist.github.com/genkuroki/2f82… Image
#数楽 #Julia言語

何も知らないので(チェビシェフ多項式は知っていた)、全部自分でテキトーにやってみた↓

gist.github.com/genkuroki/2f82…
sin(x)の13次の多項式による近似

結果的にJuliaのsinの値とほぼ同じ値を区間[0,π/4]上で計算できるようになりました。

自分でやってみると色々分かる。
#数楽 以上の計算法はRemez法とは全然違う。

ja.wikipedia.org/wiki/Remez%E3%…
Remezのアルゴリズム
#数楽

#Julia言語 のtrig.jlにおけるsin(x)を近似する13次多項式と私が求めた13次多項式の係数がかなり違う理由:

* Juliaの側は最大相対誤差を最小化
* 私の側はsupノルムで測った最大絶対誤差を最小化

添付画像

① 絶対誤差
② 相対誤差

S(x)は私が求めたもので、sin_Float64はJuliaのやつ。 ImageImage
#数楽 あまりにも違う答えが出て来たので悩みました。

最大相対誤差の最小化と最大絶対誤差(supノルムで測った距離)の最小化で、結果が違うのは当たり前でした。

でも、13次多項式によるsinの2つの近似の差はFloat64の精度では大したことないです。
#数楽 マクローリン展開をそのまま使うことの効率の悪さが印象的。同じ計算量で最悪の誤差が100倍以上悪化する。

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with 黒木玄 Gen Kuroki

黒木玄 Gen Kuroki Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @genkuroki

21 Feb
#超算数

「(算数は)定義とか論理じゃないので」のようなことを、100年以上の伝統を持つ非常識な算数教育の伝統に沿って言う人達は基本的に嘘つき。

例えば、小2算数教科書での長方形と正方形の定義は非常に正確で小2の子にも「正方形は長方形の特別な場合であること」が分かるようになっています。
#超算数 長方形と正方形については、すでに小2算数教科書に正確な定義が噛み砕かれた形式で載っているのに、ちょー算数の伝統に則って算数の教え方を指南する人達が、小学校の先生達をおかしな方向に誘導している。

ちょー算数信者の発言は大体において全部「嘘」だと思っておく方がよいです。
#超算数 小2の子であっても、正方形を見せて、すべての角が直角かどうかを聞いてみて、全部直角だと答えた直後に、教科書にある長方形の定義を読ませて、その条件を満たしていることを確認させると、正方形も長方形の一種であることをすぐに理解できます。

教科書に書いてあるルールに従うだけ。
Read 13 tweets
21 Feb
その程度のことは #Julia言語 では実現済み(添付画像)。

64ビットのいつもの浮動小数点数の規格だけに特化されたコードを書くことに投資し続けることが、長期的に適切なやり方だとは思えない、という非常に穏健で普通の話をしているのだと私は思いました。
#Julia言語 で sin(2πkx) を計算するコードを書くときには

sinpi(2k*x)

のように書いた方が精度的にも効率的にも得です。三角函数の引数にπがかけられている場合は多いので、覚えておく価値があります。
sinpiの #Julia言語 での実装のコード(添付画像①)はすでに紹介済み。

そのコードを見れば分かるように、sinpi(1/2)やsinpi(1/6)などを特別扱いして添付画像②のようになっているわけではないです。
Read 4 tweets
21 Feb
今まで数秒で計算できていたのに、精度を上げた途端に数十秒~数分の計算時間が必要になるのはかなり不快なので、①そういう犠牲を払う価値がある問題を扱うこと、②精度を上げたことによる速度的劣化を最小化することの2つが重要。最適化をちょっとサボるだけで計算速度は容易に1〜2桁下がる。
#Julia言語 では、実行時に、必要な精度が与えられたときに、その精度で効率よく計算できるコードを自動的に生成して、即時ネイティブコードにコンパイルして実行する、というようなことができます。

Juliaのような環境では、各精度ごとに最適化をダイナミックに行えるという利点があります。
以下のSGJさんの講演の最後の方では、与えられた諸々の状況に合わせてFFT(高速フーリエ変換)の効率的なコードが自動生成されるようにしておけば、ハードウェアに依存しないジェネリックで効率的なFFTのライブラリを作れるという話をしています(それがFFTW!)。続く

Read 10 tweets
19 Feb
#JuliaLang

v1.5.3 vs. v1.6.0-rc1

random counting

11 sec (v1.5.3)

3 sec (v1.6.0-rc1)

😊😊😊😊😊

gist.github.com/genkuroki/33f6…
#JuliaLang

3 sec (v1.6.0-rc1, single thread)

0.9 sec (v1.6.0-rc1, ThreadPools.tmap)

ThreadPools.tmap example.ipynb
gist.github.com/genkuroki/2e8f…
#Julia言語

forループの函数版:返り値のある函数fをX成分ごとに作用させた結果を得るためにはmap(f,X)を使い、返り値を使わずにXの各成分ごとにfを実行するにはforeach(f,X)を使う。

それぞれのスレッド並列版がThreadPools.{tmap, tforeach}。
github.com/tro3/ThreadPoo…
Read 18 tweets
19 Feb
#超算数

【超算数をインストールされた人、なぜか再生産を行う傾向にある】

そうなる理由↓

日本で算数教育で飯を食って行きたい場合には、ちょー算数マスターになると、就職先が増えたり、出世できる可能性が増えたりする。

ちょー算数には100年以上の伝統に支えられた社会的基盤があります。
かけ算順序問題が新聞で話題にされても、ダメージも受けない理由は、社会的に硬い基盤を持っているから。

子供の保護者側は自分ちの子が被害を受けずに通過すれば発言を続ける意欲は減ります。

ちょー算数マスターになると算数教育界で出世してより良い地位に転職できるかもしれない。

この対比。
例えば、算数の教科書の著作者リストに載っている人達がちょー算数についてどのような考え方を持っているか、どこでその考えを身につけたのか、どのような経歴で算数の教科書の著作者まで出世できたのか、などについては調べる価値があります。

これ面倒な作業で結構大変。
Read 8 tweets
19 Feb
#Julia言語

github.com/johnmyleswhite…

は古過ぎるパッケージであることがProject.tomlがないことからわかります。

そして、add ContinuedFractionsでインストールされるパッケージはさらに古く、ContinuedFraction自体を持っていません。

古めのパッケージが放置されていることがあるので要注意。
#Julia言語 適当なフォルダに

github.com/johnmyleswhite…

をクローンしておいて、そこにaddで追加されたContinuedFractionsのProject.tomlをコピーして、devで使えるようにすれば、ContinuedFractionを最初から含むそのパッケージを使えるようになります。

たまにこういうことがある。
#Julia言語 スクショ

~/.julia/dev/ContinuedFractions にリポジトリのクローンを置いておいて、そこにProject.tomlを追加し、

pkg> dev ContinuedFractions

してある。こうしておけば、ContinuedFractions.jlパッケージを使える↓
Read 4 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!