Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Pythonの数学機能を学ぼう! その仕組も学ぼう!
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
curekoshimizu
September 27, 2024
2.7k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Pythonの数学機能を学ぼう! その仕組も学ぼう!
curekoshimizu
September 27, 2024
More Decks by curekoshimizu
See All by curekoshimizu
おしゃれ会社に入ったら CTOだけイケてなかった話
curekoshimizu
1
1.1k
AI時代を コンピュータ・アーキテクチャ視点で 取り組み 開発生産性をあげた話
curekoshimizu
1
130
[CTO of the YEAR 2025] すべてのECブランドに 最高の購入体験を届ける CTO 1年の挑戦の軌跡
curekoshimizu
0
430
会社を支える Pythonという言語戦略 ~なぜPythonを主要言語にしているのか?~
curekoshimizu
4
1.3k
Pythonスレッドとは結局何なのか? CPython実装から見るNoGIL時代の変化
curekoshimizu
6
2.9k
未経験でSRE、はじめました! 組織を支える役割と軌跡
curekoshimizu
1
940
級数を大改造劇的ビフォーアフター
curekoshimizu
0
46
Featured
See All Featured
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
200
Optimizing for Happiness
mojombo
378
71k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
540
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.3k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
200
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.5k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
230
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
62
54k
The Limits of Empathy - UXLibs8
cassininazir
1
360
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
230
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Transcript
Pythonの数学機能を学ぼう! その仕組も学ぼう!! PyCon JP 2024.9.28 Track3 11:10 - 11:40 Recustomer株式会社
CTO Shugo Manabe @curekoshimizu
Profile : 眞鍋 秀悟 ( X: @curekoshimizu ) 略歴 •
京都大学 / 大学院 ◦ 入試一位合格 ◦ 数学系 (多倍長数値計算を専門) [今回のお話と少し関係が深い] • Fixstars ◦ Executive Engineer • Mujin ◦ Architect • Preferred Networks ◦ Engineering Mananger • Hacobu ◦ 研究開発部部長・CTO室室長 • want.jp ◦ VPoP • [Now] Recustomer ◦ CTO かなり長い間 Pythonを 業務で使ってきた 2
今日のわかることの一例 3
-5と-6は違う! 4
-5と-6はやっぱり違う! 5
とかとか 6
• Pythonにおける数値型について • 整数型について深堀り ◦ SMALL_INTの導入 ◦ CPythonにおける整数型の実装 ◦ 整数型と多倍長整数
◦ 四則演算について • 浮動小数点型について深堀り • math moduleの関数について深堀り ◦ 関数の呼び出し方 ◦ Python3.13とmath moduleの展望 • 最後に 本日お話をすること 7
数学的な機能で最も重要なのは? 8
数の概念 9
Pythonはどのような数を 表現できるのであろうか? 10
Pythonが標準的に公開している数表現 1. 整数型 (int) 2. 浮動小数点数型 (float) 3. 複素数型 (complex)
4. 10進多倍長演算型 (Decimal) 5. 有理数型 (Fraction) 11
Pythonが標準的に公開している数表現 1. 整数型 (int) 2. 浮動小数点数型 (float) 3. 複素数型 (complex)
4. 10進多倍長演算型 (Decimal) 5. 有理数型 (Fraction) 本日は普段我々が最も使っているであろう、 int・floatという2つの型についてお話していく 12
数学の世界との対応 整数 有理数 実数 複素数 13
一般的な数学の世界との対応 整数型 (int 型) 有理数型 (Fraction型) ・浮動小数点数型 (float型) ・10進数多倍長型 (Decimal型)
・ 整数型 (int型) : (固定小数点と思うと) 複素数型 (complex型) 14
• Pythonにおける数値型について • 整数型について深堀り ◦ SMALL_INTの導入 ◦ CPythonにおける整数型の実装 ◦ 整数型と多倍長整数
◦ 四則演算について • 浮動小数点型について深堀り • math moduleの関数について深堀り ◦ 関数の呼び出し方 ◦ Python3.13とmath moduleの展望 • 最後に 本日お話をすること 15
その前に あなたにとって その前に理想の整数型とは? 16
高速であること? 17
n + 1 の計算が 絶対にできること? 18
例えば同じスクリプト言語として 比較されることもある JavaScript / TypeScript の場合 19
例えば同じスクリプト言語として 比較されることもある JavaScript / TypeScript の場合 n + 1 !=
n となる 20
例えば同じスクリプト言語として 比較されることもある JavaScript / TypeScript の場合 n + 1 !=
n となる n + 1 == n な場合がある 21
n + 1 の計算が n と 違うことを保証するのも プログラミング言語に よって違う (JavaScriptはこれを保証していない言語)
22
Go言語のようなコンパイル言語の場合 n + 1 をすると 0 などの裏回った値をとりうる 18446744073709551614 + 1
= 18446744073709551615 18446744073709551615 + 1 = 0 23
一方で Pythonは任意の整数nに対して n+1 が数学的な「n+1」が一致する 計算結果になる特徴をもつ (当たり前のようで当たり前ではない特徴) 24
• Pythonにおける数値型について • 整数型について深堀り ◦ SMALL_INTの導入 ◦ CPythonにおける整数型の実装 ◦ 整数型と多倍長整数
◦ 四則演算について • 浮動小数点型について深堀り • math moduleの関数について深堀り ◦ 関数の呼び出し方 ◦ Python3.13とmath moduleの展望 • 最後に 本日お話をすること 25
整数型 (int) 整数を表すものが整数型 例. • 0 • 1 • 2
• -5 • -32 • 123 • 10000000000000000000000000000000 26
整数型 (int) 整数を表すものが整数型 例. • 0 • 1 • 2
• -5 • -32 • 123 • 10000000000000000000000000000000 今日はPythonの気持ちで 2つのグループに 分けてみましょう 27
正解はいろいろあるのですが あるPythonのお気持ちで分類をするとこんな感じな気がする • 0 • 1 • 2 • -5
• 123 • -32 • 10000000000000000000000000000000 青グループ 赤グループ 28
この分類を正当化するために id 関数を導入することにする 29
id 関数 オブジェクトのメモリアドレスを示すもの 上の例では 10 という生成されたオブジェクトの位置がわかる 10 この場所 30
id 関数の実行結果例 (環境:Python3.12.6, x86-64) x id(x) 0 4354799288 1 4354799320
2 4354799352 -5 4354799128 123 4354803224 -32 4342934352 10000000000000000000000000000000 4347138224 値がとても近い! 31
id 関数の実行結果例2回目 (環境:Python3.12.6, x86-64) x id(x) 0 4354799288 1 4354799320
2 4354799352 -5 4354799128 123 4354803224 -32 4342936240 10000000000000000000000000000000 4347135200 値が不変 値が変化 32
id 関数の実行結果例3回目 (環境:Python3.12.6, x86-64) x id(x) 0 4354799288 1 4354799320
2 4354799352 -5 4354799128 123 4354803224 -32 4342934352 10000000000000000000000000000000 4347136640 値が不変 値が変化 33
確かに何やらこういう分類がある気がしてきた • 0 • 1 • 2 • -5 •
123 • -32 • 10000000000000000000000000000000 青グループ 赤グループ 34
CPythonより抜粋 -5, -4, .., 255, 256 に属する整数は 実はPython初期化時に 既にオブジェクトが生成されている (CPythonの特徴の一つといえる)
35
SMALL_INT -5, -4, .., 255, 256 (SMALL_INT) という数字か否かを確認するコードがあり、特殊扱いされていることがわかる 36
同様に初期化時に生成されるオブジェクトとは? -5, -4, .., 255, 256 以外にも初期化時に生成されるオブジェクトがある 例えば True・False・None オブジェクトである。
これらTrue・False・None は x is None などと is 関数で比較することができるオブジェクトである 37
is関数のCPythonでの実装 is 関数というのはオブジェクトのPointerが一致しているかを確認している 先ほどの True・False・None や -5, -4, .., 255,
256 という数は 初期化時に一度だけ生成されて、 それ以降はそのオブジェクトを使い回す。 そのため、これらのオブジェクトは isの比較をすることができる 38
x=y=True x=y=1 x=5000 y=5000 Trueや1は初期化時に1度だけ生成され、 そのobjectをプログラムで使い回す そのため、objectのポインターがすべて同じになる 5000 は 動的にobjectが生成され、
xとyのobjectは別物。そのためそれぞれのオブ ジェクトのポインターが異なるため is の比較は失敗 39
isによる比較ができるものとできないもの このように -5, -4, .., 255, 256 という数は is でも比較できてしまう特殊な実装
になっている。 だから、idも同じ値を返していた。 注意. だからといって、数値型を is をつかって比較すべきではなく、= を使って 比較すべきである 40
なぜ特殊実装になっているのか? -5, -4, .., 255, 256 という数は よく使われる可能性が高いためオブジェクトの生成コストを抑えるという 目的で生成されています。 例えば
0 という数は頻繁に登場する値 であり、 生成回数を抑えることにより高速化をしています 41
• Pythonにおける数値型について • 整数型について深堀り ◦ SMALL_INTの導入 ◦ CPythonにおける整数型の実装 ◦ 整数型と多倍長整数
◦ 四則演算について • 浮動小数点型について深堀り • math moduleの関数について深堀り ◦ 関数の呼び出し方 ◦ Python3.13とmath moduleの展望 • 最後に 本日お話をすること 42
PyObjectはすべてのルーツ Pythonではすべてのオブジェクトが PyObject の継承になっています。 そのため、 これからお話をする数値型の構造をお話するには、大前提な型になります。 43
PyObject型の大雑把な構造 Python3.11のPyObjectの実装 簡易的だが特徴を掴んでいる内容 44
PyObject型をC言語がわからない人向けにざっくり 簡易的だが特徴を掴んでいる内容 Python流に表すとこういう構造体 (全体は16Byteのデータ) 45
PyObjectは本当に16Byteなのか? sys.getsizeof:生成されたオブジェクトのサイズをPythonから知る方法 46
PyObjectからの継承 PyObject PyLongObject : 整数型 PyComplexObject : 複素数型 PyFloatObject :
浮動小数点数型 PyDecObject:10進数多倍長型 Fraction class :有理数 型 47
PyObjectからの継承 PyObject PyLongObject : 整数型 PyComplexObject : 複素数型 PyFloatObject :
浮動小数点数型 PyDecObject:10進数多倍長型 Fraction class :有理数 型 こちらをみていくことに! 48
PyLongObject型のC言語の正確な構造 PyObject型 を _PyLongValue で Wrapしているような構成 (PyObject型 + _PyLongValue) (C言語で継承を実現しようとすると例えばこうなる)
49
PyLongObject型の正確さを犠牲にしたわかりやすい表現 不正確だがわかりやすくした PyLongObject (整数型) PyLongObject のPython流の表現 継承 50
• Pythonにおける数値型について • 整数型について深堀り ◦ SMALL_INTの導入 ◦ CPythonにおける整数型の実装 ◦ 整数型と多倍長整数
◦ 四則演算について • 浮動小数点型について深堀り • math moduleの関数について深堀り ◦ 関数の呼び出し方 ◦ Python3.13とmath moduleの展望 • 最後に 本日お話をすること 51
ob_digit が Python の整数型の “long” な特徴 可変長な構造をもっている! (longっぽい) 52
Longという用語は Python2からの系譜 PyLongObject : 任意精度の整数 (python long integer object) PyIntObject
: 固定長整数 Python2 PyLongObject Python3 統合 もはや対比的についていた名前 “long”は比べる相手がいなくなったのだが 名前としては残っている 53
ob_digit という特徴 ob_digt[0] ob_digt[1] ob_digt[2] ob_digt[3] ob_digt[n-1] (必ず非0) ・・・ nが定まる
大きい桁 メモリーが許す限りいくらでも大きな整数を表現できる 54
小さい数の表現 ob_digt[0] (必ず非0) 小さい数は1つだけで成立する 55 n = 1
0の表現 empty list 0の場合には ob_digit は0個で成立する 56 n = 0
大きい数になると可変長領域が増えて objectの大きさが大きくなる PyObject : 16Byte 一番小さい PyLongObject は 28Byte 大きい整数になるにつれてPyLongObjectは
大きくなる 57
(余談) str から int を作ろうとしたときは 任意の大きさにはつくれない 58
メモリーの中身をみてみよう -5 -4 -3 -2 -1 0 1 int型の意味 参照カウント
(最大値) の意味 SMALL_INT(-5, -4, …) は連続してメモリー上に生成されていた! type(...)で int が 返ってくる理由 59
(余談) 参照カウントはメモリーをみなくとも Pythonから取得できる SMALL_INTである1は初期化時に生成して 以降削除することはないobjectなので、最大 値をとっている。 一方で、一般的なobjectである1000は その参照カウントが その関数での参照と、x、yの3となる。 生成と破棄はガベージコレクションに任され
ることを表している。 60
• Pythonにおける数値型について • 整数型について深堀り ◦ SMALL_INTの導入 ◦ CPythonにおける整数型の実装 ◦ 整数型と多倍長整数
◦ 四則演算について • 浮動小数点型について深堀り • math moduleの関数について深堀り ◦ 関数の呼び出し方 ◦ Python3.13とmath moduleの展望 • 最後に 本日お話をすること 61
PyLong同士の足し算を眺める 小さな数 (Compact)とは digits[] が0か1であるかということ 1個だけであれば 足し算をしても、桁上りが発生して、 digitsが増えることはほとんどない だから高速に計算できる! 符号部
* (digits[0]) が実際の数なのでその2数 の足し合わせで計算可能 小さな数同士の足し算の場合 (実用上多くの場合でこのケース) 62
PyLong同士の足し算を眺める 符号部を考えて、足し算か引きかを決定 複数のdigitsをもつ計算になる O(digits) の計算量の加減算 (多倍長数の計算になり遅い) 63
• Pythonにおける数値型について • 整数型について深堀り ◦ SMALL_INTの導入 ◦ CPythonにおける整数型の実装 ◦ 整数型と多倍長整数
◦ 四則演算について • 浮動小数点型について深堀り • math moduleの関数について深堀り ◦ 関数の呼び出し方 ◦ Python3.13とmath moduleの展望 • 最後に 本日お話をすること 64
浮動小数点数型 (PyFloatObject) PyObject PyLongObject : 整数型 PyComplexObject : 複素数型 PyFloatObject
: 浮動小数点数型 PyDecObject:10進数多倍長型 Fraction class :有理数 型 こちら! 65
PyFloatObject は simple な構造 PyObjectに一つ 倍精度浮動小数点数 (8Byte) が付与されている構造 PyFloatObjectのPython流な表現 PyFloatObjectのC言語の実装
66
整数型に比べて四則演算がとてもシンプル PyFloatObject型の四則演算は単純 CPUが直接計算できる レジスタレベルの計算 ここの中身を 加減乗除 して終わり と 思って大体間違いではないコードになっている 67
• Pythonにおける数値型について • 整数型について深堀り ◦ SMALL_INTの導入 ◦ CPythonにおける整数型の実装 ◦ 整数型と多倍長整数
◦ 四則演算について • 浮動小数点型について深堀り • math moduleの関数について深堀り ◦ 関数の呼び出し方 ◦ Python3.13とmath moduleの展望 • 最後に 本日お話をすること 68
mathモジュールは PyFloatObject型のための計算機能 • acos • acosh • asin • asinh
• atan • atan2 • atanh • cbrt • ceil • comb • copysign • cos • cosh • degrees • dist • e • erf • erfc • exp • exp2 • expm1 • fabs • factorial • floor • fmod • frexp • fsum • gamma • gcd • hypot • inf • isclose • isfinite • isinf • isnan • isqrt • lcm • ldexp • lgamma • log • log10 • log1p • log2 • modf • nan • nextafter • perm • pi • pow • prod • radians • remainder • sin • sinh • sqrt • tan • tanh • tau • trunc • ulp とてもたくさん! 69
これらの呼び出しで 一体何が起こるのだろうか? math.exp関数を例にとりあげる 70
exp関数の呼び出しはどうなっているのだろうか? math_exp 関数を呼ぶと math_1 という関数に exp という関数ポインタ を渡すという実装になっている ここの func
が exp 関数の本体! 71
exp関数の呼び出しはどうなっているのだろうか? 共有ライブラリ libm の expf64 を呼び出しているだけ (環境は x86_64, linux) 72
exp関数の呼び出しはどうなっているのだろうか? ここに書いている通り 「libmのwrapperなのである」 73
(余談) Go言語はexp関数を自作している点が面白い 多くのプログラミング言語が libmに依存している中 Go はこういうところに ユニークさをもった言語でもある 74
• Pythonにおける数値型について • 整数型について深堀り ◦ SMALL_INTの導入 ◦ CPythonにおける整数型の実装 ◦ 整数型と多倍長整数
◦ 四則演算について • 浮動小数点型について深堀り • math moduleの関数について深堀り ◦ 関数の呼び出し方 ◦ Python3.13とmath moduleの展望 • 最後に 本日お話をすること 75
mathライブラリに 久々に追加される関数がありますね math.fma が Python3.13 で追加されます 76
fma関数とは? fma(x, y, z) をすると x * y + z
をする関数です 77
そんな普通の関数って なにかすごいんですか? 78
fma関数とは? x * y + z という積和演算を1度に計算してくれるんです! (注. CPUがサポートしている場合にのみ) 79
いまいち良さがわからないです… という 感想が聞こえてきそう 80
コンピュータの 理論ピーク性能ってどうやって 計算するんだったか を思い出してみる 81
GeForce RTX 4090 の単精度理論ピーク性能 を計算してみる (注. どんなアーキテクチャでもこの計算方法というわけではない) 16384 (Cores) ×
2.52 (GHz) × 2 (FLOPS/CLOCK × Cores)) = 82.58TFLOPS 1度の計算で積和演算 (FMA) という 2回の浮動小数点計算をすることが 前提の「2」 積和演算がないと「1」になってしまう FLOPSとは 1秒間に何回浮動小数点の 計算ができるかの意味 82
FMAは計算機の 理論ピーク性能の計算にも 利用されている 性能を引き出すために必要な 命令の一つ 83
今日は2024.9.28! Python3.13 2024.10.1 のリリースが より楽しみになりましたね! 84
まだまだ進化の止まらない 数学関数の今後に期待です! 85
• Pythonにおける数値型について • 整数型について深堀り ◦ SMALL_INTの導入 ◦ CPythonにおける整数型の実装 ◦ 整数型と多倍長整数
◦ 四則演算について • 浮動小数点型について深堀り • math moduleの関数について深堀り ◦ 関数の呼び出し方 ◦ Python3.13とmath moduleの展望 • 最後に 本日お話をすること 86
本当は喋りたかったがスライドを作ってみた結果 時間の都合上入らなかった内容 • SMALL_INTだけではなくMEDIUM_INT・COMPACTについて • INTの多倍長整数演算の実装について • libmの中身の数学関数の実装について • Pythonのバイトコードへの展開と工夫について
• 有理数型と浮動小数点数型など数値型の使い分けについて • 今回登場していたCPythonのデバッグ方法について • numpyの素晴らしさ (なぜ自前で行列計算ライブラリを実装してはいけないか) いつかこういうお話ができる機会があると 非常にうれしいです! 87
全員で7名のエンジニア しかいないため Pythonが大好きな方 大募集中です! 27番ブースでお待ちしております 88
ご清聴ありがとうございました @curekoshimizu 89