2022年11月28日月曜日

コルーチンを勉強する

 最近、機械学習系のライブラリとかゲームのライブラリとか動画を扱うライブラリがコルーチンという方法で書かかれているのをよく見ます。

Async/awaitパターンとも言われているそうです。


Async/await

https://ja.wikipedia.org/wiki/Async/await



パイプラインとかのような複雑な非同期非ブロッキングの関数を普通の同期関数と同じように記述できるから便利らしいです。たしかに機械学習の学習とか時間のかかる関数とかを簡単にマルチスレッド化できるし。

気が付けば、C言語も、C++言語も、Pythonも、JavaScriptも、ありとあらゆる言語が、コルーチンをサポートし、いろんなライブラリがそれで書かれている。

基本どのプログラム言語にも、async、awaitってものがあって、promiseというものに結果を格納するらしい。


しかしこの概念、久々に見た衝撃の難しさ。

いろいろな説明ページ見ても何言ってんの?っていうくらい難しい。

日本語でC++で正しく書かれているサイトないし。

年取るとこういう概念にとっさについていけない。

そもそもプロミスって最短30分くらいで簡単にお借入れできなかったっけ?

朝から夜まで一週間くらいずっと眺めて、やっとさっき主要な言語のpromiseの仕組みがわかかった。



C++のサンプル

-----------------------------------------

#include <coroutine>

#include <iostream>

#include <stdexcept>

#include <thread>


auto switch_to_new_thread(std::jthread& out) {

    struct awaitable {

        std::jthread* p_out;

        bool await_ready() { return false; }

        void await_suspend(std::coroutine_handle<> h) {

            std::jthread& out = *p_out;

            if (out.joinable())

                throw std::runtime_error("Output jthread parameter not empty");

            out = std::jthread([h] { h.resume(); });

            //潜在的な未定義の動作:潜在的に破壊された*thisへのアクセス

            // std :: cout << "新しいスレッドID:" << p_out-> get_id()<<'\ n';

            std::cout << "New thread ID: " << out.get_id() << '\n'; // これで結構です

        }

        void await_resume() {}

    };

    return awaitable{ &out };

}


struct task {

    struct promise_type {

        task get_return_object() { return {}; }

        std::suspend_never initial_suspend() { return {}; }

        std::suspend_never final_suspend() noexcept { return {}; }

        void return_void() {}

        void unhandled_exception() {}

    };

};


task resuming_on_new_thread(std::jthread& out) {

    std::cout << "Coroutine started on thread: " << std::this_thread::get_id() << '\n';

    co_await switch_to_new_thread(out);

    //ここでウェイターが破壊されました

    std::cout << "Coroutine resumed on thread: " << std::this_thread::get_id() << '\n';

}


int main() {

    std::jthread out;

    resuming_on_new_thread(out);

}

-----------------------------------------






2022年10月21日金曜日

ブラウザでC/C++のプログラムを動かす

 最近、TensorFlow.jsとかOnnxRuntimeなど、C/C++言語で書かれた機械学習のライブラリが何故かブラウザで動きます。

調べてみると、emscriptenを使ってC/C++のソースをコンパイルすると、WebAssemblyのバイナリーができて、C/C++等で書かれたプログラムがブラウザで動くようです。

ブラウザはJavaScriptしか動かないと思っていたら、いつの間にかブラウザで動くすごいアプリはみんなC/C++で書かれている・・・。

おじさんの大好きなC/C++で書かれている。


PythonもOpenCVもffmpegもみんなWebAssemblyで動くようにコンパイルされたバイナリーがあります。

それをHTMLに組み込むと、ブラウザでPythonもOpenCVもffmpegも動くのね。

ゲームのエミュレータやLinuxなどのOSもWebAssemblyで動くようです。


すげー。


https://dev.classmethod.jp/articles/cpp-webassembly-emscripten/


とってもすごいんだけど、emscriptenのインストールとか開発環境がとっても不便。

でもこれでプログラムを作れば、スマホやPCなど、すべてのデバイスでプログラムが動く。


ぼくもとりあえずhello.cppを作ってみました。

2022年10月5日水曜日

AIでプログラムしてみた。

最近はAIがプログラムしてくれるようになったらしいです。

おじさんのような人がコードを書かなくてもAIが自動でコードを書いてくれるらしいです。

おじさんがコード書いたことにしてお金もらえないかなぁ。


前からやってみたかったのですが、プログラムするAIを学習させるのがとても大変で誰かやってくれないかなぁとおもっていたら、やってくれた人がいました。




https://aiprogrammer.hashlab.jp/


--------------------

nまでの素数を求めるプログラム

--------------------

#include <iostream>

#include <math.h>


using namespace std;


int main()

{

int i, j;

int n;

int prime;


cout << "nを入力してください:";

cin >> n;


for (i = 2; i <= n; i++) {

prime = 1;

for (j = 2; j <= sqrt(i); j++) {

if (i%j == 0) {

prime = 0;

break;

}

}

if (prime == 1) {

cout << i << " ";

}

}


cout << endl;


return 0;

}

--------------------

おーあってる。
ちゃんとコンパイルして動くし。


--------------------

高速にnまでの素数を求めるプログラム

--------------------

#include <iostream>

#include <vector>


using namespace std;


vector<int> primeNumbers(int n) {

vector<int> res;


for (int i = 2; i <= n; i++) {

bool isPrime = true;

for (int j = 2; j * j <= i; j++) {

if (i % j == 0) {

isPrime = false;

break;

}

}

if (isPrime) res.push_back(i);

}


return res;

}


int main() {

int n;

cin >> n;

vector<int> res = primeNumbers(n);

for (int i = 0; i < res.size(); i++) {

cout << res[i] << endl;

}


return 0;

}

--------------------


おーこれもあっている。
しかも高速に求めてるし。
ニュートン法とかいけるのかな?


--------------------

ニュートン法で平方根を求めるプログラム

--------------------

#include <iostream>

#include <cmath>

using namespace std;


double NewtonMethod(double x)

{

double result = x;

double prevResult;

double epsilon = 1.0e-6;

int i = 0;

do

{

prevResult = result;

result = result - (result - x / result) / 2;

i++;

} while (fabs(result - prevResult) > epsilon && i < 100);

return result;

}


int main()

{

double input;

cin >> input;

cout << NewtonMethod(input) << endl;

return 0;

}

--------------------


すげー、情報系の大学2年生くらいのレベルはありそうですね。
マクローリン展開とかもできるのでしょうか?


--------------------

マクローリン展開でsinを求めるプログラム

--------------------

#include <iostream>

#include <cmath>


using namespace std;


int main()

{

double x;

cin >> x;


double result = 0;

for (int i = 0; i < 10; i++)

{

result += pow(-1, i) * pow(x, 2 * i + 1) / (2 * i + 1);

}


cout << result << endl;


return 0;

}

--------------------

マクローリン展開もできてる。
あらーすごい。
これは大学のレポート作成にもってこいだわ。
海外の大学だとアルバイトにお金払えば大学の宿題とかレポートやってくれるんですが、お金払わなくていいじゃん!



だけど、まだオープンソースとか作れるプロのプログラマーレベルではないみたい。
数値計算はとっても得意だけれどエスケープ処理とか文字列とかの細かい処理が苦手?


2022年9月5日月曜日

PytorchのC++のライブラリlibtorchを使う2022

最近AI囲碁や将棋、たんぱく質の構造推定などあらゆるAIでResNetが使われています。

ResNetって画像分類以外のこともできるようです。

ResNetくらいなら簡単なものならおじさんの個人所有のGPUでもなんとか学習ができそう。

C++でやってみたい・・・・



c++でResNetができるフレームワークを探すと、Pytorchがでてきます。

Pytorchはもともとコア部分がlibtorchにまとまっていてc++から使えるようになっているし、Android版はNewralNetworkAPIなどに対応しており、GPUを使って高速に演算ができるようです。

 最近、GoogleのTensorFlow、マイクロソフトのonnxruntime、FacebookのPytorchなど、いろいろな機械学習フレームワークが続々とONNX対応、c++対応やスマホ対応になってきています。

Pytorchのようなスマホ対応のフレームワークを使えば、フルセットのPytorchがスマホでも動き、GPU付きのPCで学習させてスマホでその結果を利用することもできるようです。

いろいろなOSで動いて、学習データの再利用ができてほんとうに便利ねー。


そこで、本日は最新のPytorch 1.12.1のc++ライブラリlibtorchをビルドして動かしてみたいと思います。


ビルド方法はドキュメントに書かれている通りでとっても簡単

以前の自分のブログに書いてある通りでビルドできます。

http://yomeiotani.blogspot.com/2019/04/windowslibtorch.html


--------------------

cd <pytorch_root>\tools

mkdir build

cd build

python ..\build_libtorch.py

--------------------

上記のように打つだけ。
Windowsでのビルドは、公式にはVisualStudio 2017にしか対応していないようですが、コンパイラのバージョンをチェックしている部分を直せばVisualStudio 2022でもビルドできるようです。
外部依存ライブラリが前回より変わっています。
演算をより高速にするためにいろいろな機能を追加しているみたいですね。

PyTorchのexample/cppフォルダにはc++のサンプルがあります。
このなかに定番の文字認識「MNIST」のlibtorch版、mnist.cppがあります。


とりあえずビルドして動かしてみました。
----------------------------
Training on CPU.
Train Epoch: 1 [59584/60000] Loss: 0.2362
Test set: Average loss: 0.2119 | Accuracy: 0.935
Train Epoch: 2 [59584/60000] Loss: 0.1365
Test set: Average loss: 0.1301 | Accuracy: 0.959
Train Epoch: 3 [59584/60000] Loss: 0.1805
Test set: Average loss: 0.1069 | Accuracy: 0.965
Train Epoch: 4 [59584/60000] Loss: 0.1147
Test set: Average loss: 0.0899 | Accuracy: 0.970
Train Epoch: 5 [59584/60000] Loss: 0.1017
Test set: Average loss: 0.0834 | Accuracy: 0.974
Train Epoch: 6 [59584/60000] Loss: 0.0549
Test set: Average loss: 0.0725 | Accuracy: 0.976
Train Epoch: 7 [59584/60000] Loss: 0.0657
Test set: Average loss: 0.0697 | Accuracy: 0.979
Train Epoch: 8 [59584/60000] Loss: 0.0832
Test set: Average loss: 0.0639 | Accuracy: 0.980
Train Epoch: 9 [59584/60000] Loss: 0.0523
Test set: Average loss: 0.0609 | Accuracy: 0.982
Train Epoch: 10 [59584/60000] Loss: 0.0504
Test set: Average loss: 0.0559 | Accuracy: 0.983
----------------------------

なんかあってそう。
とりあえずlibtorchのカスタムビルドができたから次はResNetでいろいろ遊ぼうっと。
android版のビルドもしてみたいなぁ。

2022年2月22日火曜日

株価指数を計算する。

 おじさん、今週は株価指数を計算するライブラリを作成しています。


株価指数って、まずTOPIXが基本らしい。

株系のWebページって結構みんな読まれるためか、いろいろな人がいろいろなことを書いているのですが、結構適当な記事が多いです。


ある経済ライターさんのページには以下のように書かれています。

https://seikeidenron.jp/articles/584

------------------

景気を知るためにもう一つ覚えておきたいのが「TOPIX(東証株価指数)」。

こちらは、東証一部に上場しているすべての銘柄の時価総額(株価×発行済株式数)を足して、銘柄数で割ったものだ。

------------------


平均だから銘柄数で割ったら平均になりそうだけどね。

うそつきー。うそのこと書くなよ!

景気を知る前に株価指数のこと知れよ!!!!



おじさんがプログラムで計算した式は、


(今の浮遊株時価総額)÷(昔の浮遊株時価総額)×(100または1000)

(浮遊株時価総額)=(浮遊株数)×(終値)


だぞ!


おじさんも二週間、朝から晩までプログラム書いて株価指数の計算方法がわかったので、こういう嘘のことを書いているのがわかるようになりました。

おじさんの勉強では平均株価ってだいたい「浮動株基準時価総額加重平均型株価」って方法で計算するらしい。


https://ja.wikipedia.org/wiki/%E6%99%82%E4%BE%A1%E7%B7%8F%E9%A1%8D%E5%8A%A0%E9%87%8D%E5%B9%B3%E5%9D%87%E5%9E%8B%E6%A0%AA%E4%BE%A1%E6%8C%87%E6%95%B0


でもこの株価指数の計算ってなかなか大変。

浮遊株数とか基準時時価総額とかの具体的な計算例や一覧データはどこにもフリーのデータがありません。

東証から月3300円で入手しないといけないっぽいです。

10年分とると40万円いるじゃないか!

うそ書いてるやると金とるやつしかいない・・・・。

なんという厳しい世界。


TOPIXでさえ、株価指数の計算の仕方が正確に書かれていないので、おじさんきちんとTOPIXを求めてみました。

浮遊株数ってどうやって計算するんだろ?

おじさん頑張ってフリーのデータから基準時時価総額と浮遊株数を計算する方法を見つけました。



まず、東京証券取引所からTOPIXの銘柄別のウェイト情報を入手

https://www.jpx.co.jp/markets/indices/topix/index.html

構成銘柄別ウエイト一覧


つぎに、年末の浮遊株時価総額と基準時時価総額を入手。

https://www.jpx.co.jp/markets/indices/related/value/index.html

2021年12月末現在



上記の二個のファイルから、TOPIX時価総額にウェイトをかけて各銘柄の浮遊株時価総額を計算。

浮遊株時価総額をその日の終値で割って、浮遊株式数を逆計算で取得。

浮遊株式数から株価指数を計算。


さらに実際には、銘柄変更、上場廃止、一時取引停止、株式分割などいろいろなイベントが毎週あるので、これらのイベントに対応し計算しないといけないためかなりめんどくさい。


でもこの方法で業種別の株価指数を計算できるようになりました。

これでただで業種別株価指数を使ってAIで株価分析してやる。



ソースはこちら。

https://github.com/yomei-o/Protra_cpp





2022年2月16日水曜日

33業種データベースを作る。

 おじさん、以下のサイトで株価はマーケットや業種ごとに傾向がことなることを勉強しました。

https://qiita.com/blog_UKI/items/25dc1c2559c61890a449

なるほど、ウイリアム・シャープっていうノーベル賞を受賞したおちゃんが言っているのね。

https://ja.wikipedia.org/wiki/%E8%B3%87%E6%9C%AC%E8%B3%87%E7%94%A3%E4%BE%A1%E6%A0%BC%E3%83%A2%E3%83%87%E3%83%AB


何言ってるのかよくわからん。

けど、機械学習とかって論文や資料が全部英語なんだけど、金融経済分野って資料が全部日本語に翻訳されている・・・。

きっとこの分野、お金が有り余ってるに違いない。


株のリターンを計算するには、上場企業の「業種」やどのマーケットに上場しているのかのデータが必要らしいです。

Protraの上場企業データベースには、上場しているマーケット情報はあるのですが、業種のデータベースがありません。なので、本日は上場企業の業種のデータベースを作ろうと思ういます。


上場企業の業種の一覧ってどこにあるんだろ?

調べてみると、東京証券取引所にあるみたい。



https://www.jpx.co.jp/markets/statistics-equities/misc/01.html

ここにいろんな企業の株に関するデータがありました。

ここの東証上場銘柄一覧というエクセルの中に業種があるのね。


しかしこのエクセル、「食品    」のように業種の文字のあとにスペースが入ってる・・・。

たしかに見た感じわかんないひっかけだけど、微妙に間違ってるのね。

金融とか証券ってこういうの間違っちゃいけないと思うんだけど・・・。

きっと誰もこのエクセル使っていないのね。


エクセルを見ると、「17業種コード」と「33業種コード」があるらしい。

「17業種コード」は1から連番なのですが、「33業種コード」は7250とか意味不明な数字が・・・

図書館の本の分類の日本十進分類だって連番なのに、Kaggleのようにあちこちにいろんな罠があります。

https://ja.wikipedia.org/wiki/%E6%97%A5%E6%9C%AC%E5%8D%81%E9%80%B2%E5%88%86%E9%A1%9E%E6%B3%95


こういう不連続なデータをきちんと機械学習できるように連番にしていきます。

データを正確に分類するのって結構大変なのね。


ということで、いろいろ罠があり時間がかかってしまいましたが、上場企業の業種のライブラリができた!


https://github.com/yomei-o/Protra_cpp/blob/main/src/Industory.h




2022年2月14日月曜日

ローソク足を表示する

 おじさん、今日はどうやってJavaScriptで株価のローソク足を描画するのか調べています。

日経平均株価のリアルタイム表示サイトとかで使われている赤と緑のグラフのやつね。

デフォルトのChart.jsだとローソク足表示はできないらしい。

だけど、なかなかあれと同じようなちょうどいいライブラリがないねぇ。


いろいろ試してみると、このライブラリが一番きれいにローソク足が表示できそう。

https://github.com/chartjs/chartjs-chart-financial/tree/master/docs

Chart.jsのプラグインになっているようです。



思う通りの日経平均株価のローソク足表示ができた。
おじさんシステムトレードのプログラム作るより、証券会社のWebページを作った方が儲かるんじゃないかと思えてきました。
自分で作って分かったのですが、証券会社のWebページって結構製作難易度高いように思ういます。
みんなどのように作っているのでしょうね?

ソースコードはこちら