0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【中二が挑戦】C++で数学ライブラリ作ってみたらpython自作の数学ライブラリより実行速度が約30倍早くなった話

0
Posted at

【中2が挑戦】C++ × Pybind11で自作数学ライブラリを作ったら以前自作した、Pythonの数学ライブラリより30倍高速化した話

(記事は自分が一回ベースを書いてAIに修正させました。なのでAIぽいかもしれないですがこ了承ください)

1.はじめに

中学2年生です!数学の勉強を兼ねて、C++で独自の数学ライブラリを作ってみました。
さらに、Pythonから手軽に呼び出せるように Pybind11 を使ってパッケージングし、型スタブファイル(.pyi)も自作してVS Codeでの自動補完が効くようにしています。
(ここはAIに任せました)

ベンチマークテストを行った結果、Pythonで自作した同ロジックのライブラリに比べて約30倍高速に動作することが確認できました!(arctanの場合)


2.こだわった工夫ポイント:三角関数の周期性(2π)エラー回避

三角関数(sin, cos,tan)をマクローリン展開で愚直に計算すると、入力値 $x$ が大きくなったときに展開式の累乗部分が爆発し、一瞬で値が無限大に破綻してしまいます。

これを防ぐため、計算の前に入力値を $2\pi$(2 * pie)で割った余り(周期性)に変換してから展開に回すロジックを実装しました。この工夫により、どんなに大きな数値が入力されても、精度を保ったまま正確に計算できるようになりました!


3. ベンチマーク結果(arctanでのベンチマークテスト)

※ 開発にあたり、arctan のマクローリン展開ロジックの最適化部分に関しては一部AIの力を借りて実装(コピペ)しました。

  • Python自作版: 約 1.300
  • C++自作版(mathp): 0.045404 秒(約30倍高速!)
  • Python標準(math.atan): 約 0.006841

標準ライブラリ(プロの実装)は異次元の速さ(チェビシェフ近似やCORDICアルゴリズムなどの数学トリック)を使っており、圧倒的な実力差を痛感しました。しかし、全く同じロジックでも言語をC++に変えるだけで30倍の壁を突破できたのは大きな収穫です。


4. 今回の挑戦でわかったこと・結論

「中学2年生であっても、C++やモダンなプログラミングツール(Pybind11)、探究心があれば、大学レベルの数学を完全に理解していなくてもコードとして実装し、動かすことができる」

高度な数式を完全に証明できなくても、「コンピューターがどう計算しているか」という仕組みや、数学の性質(周期性など)に目を向け、AIも道具として上手く活用すれば、中学生でもプロの領域の入り口に立つことは十分に可能だと分かりました。

次は、プロの実装に少しでも近づくために「チェビシェフ近似」などを学び、さらにライブラリを爆速に進化させたいと思います!

おまけsin・階乗のC++コード

long double factorial(const double x){
    long double factorial_const = 1.0;
    for (int factorial_var=1; factorial_var<x+1; factorial_var++){
        factorial_const*=factorial_var;
    }
    return factorial_const;
}
const long double pie = 3.14159265358979323846L;

double sin(double x){
    // 💡 工夫ポイント:2πで割った余りを求めて、値の爆発(オーバーフロー)を防ぐ!
    x = std::fmod(x, 2 * pie);
    
    double sin_const = 0.0;
    for (int sin_var = 0; sin_var < 15; sin_var++){
        double sin_mainasu = std::pow(-1, sin_var);
        long double sin_factorial = factorial((2 * sin_var + 1));
        long double sisu = std::pow(x, 2 * sin_var + 1);
        sin_const += sin_mainasu * (sisu / sin_factorial);
    }
    return sin_const;
}

(若干AIに書かせましたが、ベースは私が作りました。)
(読みやすさのため、主要なロジック部分のみを抜粋しています(#include等は省略しています)。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?