loader.ioを試す
loader.ioはWebサイトの負荷テストをしてくれるサービス。
制限つきだが、無料で使えるので試してみる。
ユーザ登録してログインすると、まずこのような画面になっている。
New Host
で先に進むと次はこのような画面。ここにテスト対象のホスト名を入力する。
今回はこれ用に立ち上げたEC2インスタンスのPublicIPを指定。
すると今度は「そのホストが本当にあなたのものか確認させてくれ」とくる。
やることは単純で、loader.ioがアクセス可能な場所に指定のファイルを置くこと。
指定された通りのファイル名で、ファイルの内容も指定の通りにして配置しておく。
確認がとれるとこのような画面になる。
テスト内容の設定をする。
今回は19秒で100リクエストとした。アクセス先はルート。
この状態で実行すると、すぐ停止してしまった。
理由は単純で、用意したばかりのサーバだったためindex.htmlさえ置いていなかったから。エラー率が閾値を超えて停止した。
index.htmlをちゃんと配置して改めて実行すると最後まで実行完了。
所感としては、やっぱり圧倒的に楽。 とはいえ、無料プランでできる範囲が小さいので、それだったら適当なサーバ1台にjmeterなどのツールを入れてやるほうがいいとも言える。
macにLaTeXiT環境を整える
新しいmacbook proに買い換えてからLaTeXiT環境を整えていなかったので整備。
LaTeXiTがあれば資料に貼る用の綺麗な数式を簡単に作れる。
まず、brew(cask)にLaTeXiTがあるか調べたらあったのでそれを入れてみた。
$ brew search latexit caskroom/cask/latexit $ brew cask install latexit
で、これを起動しても動かない。
brewでLaTeXiTを入れても、そもそものTeX環境を自動では入れてくれないので、「pdflatexが無い」などと怒られる。
ではLaTeX環境をbrewで入れてみようとすると、どうやらMacTeXを入れることが推奨されている様子。
$ brew search latex latex2html latex2rtf latexila latexml rtf2latex2e If you meant "latex" specifically: Installing TeX from source is weird and gross, requires a lot of patches, and only builds 32-bit (and thus can't use Homebrew dependencies) We recommend using a MacTeX distribution: https://www.tug.org/mactex/ You can install it with Homebrew-Cask: brew cask install mactex
MacTeXにはLaTeXiTも含まれている。
https://www.tug.org/mactex/mactex-download.html
MacTeX also installs Ghostscript, an open source version of Postscript, and it installs the GUI programs TeXShop, LaTeXiT, TeX Live Utility, BibDesk, and Excalibur, as well as an install package for cocoAspell, a spelling service which does not mark LaTeX commands as misspelled.
先ほどインストールしたLaTeXiTは無駄なので消してしまう。
$ brew cask uninstall latexit ==> Uninstalling Cask latexit ==> Removing App '/Applications/LaTeXiT.app'.
ここでようやくMacTeXをインストールする。ダウンロードにかなりの時間がかかるので気長に待つ。
また途中でsudoパスワードを聞かれるので入力する。
$ brew cask install mactex
以上で環境セットアップが完了。
odeintでMAPK cascadeのシミュレーション
odeintを試す題材としてMAPK cascadeのモデルを利用してみる。
成果物はここ → GitHub - mythosil/odeint-mapk
モデルの入手
モデルはBioModelsから取得。
BIOMD0000000010 - Kholodenko2000 - Ultrasensitivity and negative feedback bring oscillations in MAPK cascade
結果確認に利用するため、Online Simulatorでシミュレーション結果を入手。
Actions
→ BioModels Online Simulation
と選択していけば良い。
Select all species
にチェックを入れ、シミュレーションを実行する。
結果をgnuplotで表示するとこのようになる。
シミュレータ実装
まず必要なものをinclude。
#include <iostream> #include <boost/array.hpp> #include <boost/numeric/odeint.hpp>
次にsystem
を作る。BioModelsから数式を写し書きする作業。
/** * @see https://www.ebi.ac.uk/biomodels-main/BIOMD0000000010 */ struct MapkSystem { using StateType = boost::array<double, 8>; static constexpr StateType InitialState = { 90.0, // Mos 10.0, // Mos-P 280.0, // Mek1 10.0, // Mek1-P 10.0, // Mek1-PP 280.0, // Erk2 10.0, // Erk2-P 10.0 // Erk2-PP }; /* 係数定義は略 */ void operator()(const StateType &x, StateType &dxdt, double t) { // d[Mos]/dt = // - uVol*V1*Mos/((1+(Erk2-PP/Ki)^n)*(K1+Mos)) // + uVol*V2*Mos-P/(KK2+Mos-P) dxdt[0] = - V1 * x[0] / ((1.0 + pow(x[7] / Ki, n)) * (K1 + x[0])) + V2 * x[1] / (KK2 + x[1]); // d[Mos-P]/dt = // uVol*V1*Mos/((1+(Erk2-PP/Ki)^n)*(K1+Mos)) // - uVol*V2*Mos-P/(KK2+Mos-P) dxdt[1] = V1 * x[0] / ((1.0 + pow(x[7] / Ki, n)) * (K1 + x[0])) - V2 * x[1] / (KK2 + x[1]); // d[Mek1]/dt = // - uVol*k3*Mos-P*Mek1/(KK3+Mek1) // + uVol*V6*Mek1-P/(KK6+Mek1-P) dxdt[2] = - k3 * x[1] * x[2] / (KK3 + x[2]) + V6 * x[3] / (KK6 + x[3]); // d[Mek1-P]/dt = // uVol*k3*Mos-P*Mek1/(KK3+Mek1) // - uVol*k4*Mos-P*Mek1-P/(KK4+Mek1-P) // + uVol*V5*Mek1-PP/(KK5+Mek1-PP) // - uVol*V6*Mek1-P/(KK6+Mek1-P) dxdt[3] = k3 * x[1] * x[2] / (KK3 + x[2]) - k4 * x[1] * x[3] / (KK4 + x[3]) + V5 * x[4] / (KK5 + x[4]) - V6 * x[3] / (KK6 + x[3]); // d[Mek1-PP]/dt = // uVol*k4*Mos-P*Mek1-P/(KK4+Mek1-P) // - uVol*V5*Mek1-PP/(KK5+Mek1-PP) dxdt[4] = k4 * x[1] * x[3] / (KK4 + x[3]) - V5 * x[4] / (KK5 + x[4]); // d[Erk2]/dt = // - uVol*k7*Mek1-PP*Erk2/(KK7+Erk2) // + uVol*V10*Erk2-P/(KK10+Erk2-P) dxdt[5] = - k7 * x[4] * x[5] / (KK7 + x[5]) + V10 * x[6] / (KK10 + x[6]); // d[Erk2-P]/dt = // uVol*k7*Mek1-PP*Erk2/(KK7+Erk2) // - uVol*k8*Mek1-PP*Erk2-P/(KK8+Erk2-P) // + uVol*V9*Erk2-PP/(KK9+Erk2-PP) // - uVol*V10*Erk2-P/(KK10+Erk2-P) dxdt[6] = k7 * x[4] * x[5] / (KK7 + x[5]) - k8 * x[4] * x[6] / (KK8 + x[6]) + V9 * x[7] / (KK9 + x[7]) - V10 * x[6] / (KK10 + x[6]); // d[Erk2-PP]/dt = // uVol*k8*Mek1-PP*Erk2-P/(KK8+Erk2-P) // - uVol*V9*Erk2-PP/(KK9+Erk2-PP) dxdt[7] = k8 * x[4] * x[6] / (KK8 + x[6]) - V9 * x[7] / (KK9 + x[7]); } };
途中経過を表示するためobserver
を用意する。標準出力にCSV形式で出力させる。
struct StdoutObserver { void operator()(const MapkSystem::StateType &x , const double t) { std::cout << t; auto size = x.size(); for (auto i = 0; i < size; i++) { std::cout << " " << x[i]; } std::cout << std::endl; } };
RK4でシミュレーション実行。
int main(int argc, char **argv) { const double start = 0.0; const double duration = 1000.0; const double interval = 0.1; MapkSystem system; StdoutObserver observer; odeint::runge_kutta4<MapkSystem::StateType> stepper; auto state = MapkSystem::InitialState; odeint::integrate_const(stepper, system, state, start, duration, interval, std::ref(observer)); return 0; }
RK-Dopriならこう書く。ステップサイズをadaptiveにすることで、細かく刻むよりも実行時間を大幅に短縮できる。
int main(int argc, char **argv) { const double start = 0.0; const double duration = 1000.0; const double interval = 0.1; MapkSystem system; StdoutObserver observer; odeint::runge_kutta_dopri5<MapkSystem::StateType> stepper; auto controlledStepper = odeint::make_controlled(0.0001, 0.0001, stepper); auto state = MapkSystem::InitialState; odeint::integrate_adaptive(controlledStepper, system, state, start, duration, interval, std::ref(observer)); return 0; }
結果
Online Simulatorとほぼ同じ結果が得られている。
Next Step
陰解法も比較的容易に実装できるので試す。ヤコビ行列を用意する必要あり。
また、途中でイベントが挟まるようなモデルをodeintでどう扱うかも調べる。公式にはサポートされていないようなので、odeint自体に手を入れる必要がありそう。