ラベル 数学 の投稿を表示しています。 すべての投稿を表示
ラベル 数学 の投稿を表示しています。 すべての投稿を表示

2021年2月23日火曜日

AndroidでLatex(数式)を扱う方法

 Androidの標準機能では数式を扱うことはできないので、外部ライブラリを探してみた。
Latexで数式が書けるライブラリを発見したので、使い方まとめ

2019年9月7日土曜日

HTML5で折れ線グラフを描く

Webページで折れ線グラフを描くことになったので、いい感じのライブラリ探したところ、
Chart.jsを発見した。
次回いつ使うかわからないけど、備忘録にまとめておく

2017年10月20日金曜日

プログラムでオイラー数を求めてみる


オイラー数については良く知らないんだけど、プログラムする機会があったのでまとめてみる

 オイラー数とは
オイラー数は、双曲線正割関数のテイラー展開における展開係数として定義される \[ sech(z) = \frac{1}{sinh(z)}= \frac{2}{e^{z}+e^{-z}}= \sum_{k=0}^{\infty} \frac{E_{k}}{k!}z^{k} \] この$E_{k}$がオイラー数である
特徴として、この数列は整数であり、奇数項がすべて 0、偶数項の符号が交互に切り替わる
オイラー数$E_{k}$は$k$が偶数のとき以下の漸化式を満たす
\[ E_0 = 1 \ \ ,\ \ \sum_{i=0}^{n} {}_{2n} C _{2i} E_{2i} = 0 \] ほぼWikiのコピペだけど、前知識はこんなもん。漸化式が解ればプログラムは組めるので..

2017年6月25日日曜日

R言語で逆行列を求める

R言語には逆行列を解く関数がある

連立方程式のときも使ったsolve関数を使うと、逆行列を求めることができる
例えば \[ \begin{equation} A= \begin{pmatrix} 2 &4 \\ 1 &3 \end{pmatrix} \Longrightarrow A^{-1}= \begin{pmatrix} 1.5 &-2 \\ -0.5 &1 \end{pmatrix} \end{equation} \]
> # 行列を生成
> A <- matrix(c(2, 1, 4, 3),2,2)
> A # 確認
     [,1] [,2]
[1,]    2    4
[2,]    1    3
>
> #逆行列を求める組み込み関数
> solve(A)
     [,1] [,2]
[1,]  1.5   -2
[2,] -0.5    1

すげー楽

2017年5月20日土曜日

R言語で連立方程式を解く

R言語には連立方程式を解く関数があった

最近R言語にはまってる。
行列を行列として扱える言語のため、逆行列を求める組み込み関数とかあり
逆行列から連立方程式を求めるプログラムが簡単に作れるやん!
って思ってたら、連立方程式を求める組み込み関数が存在してた。
以下の連立方程式で使用方法紹介 \[ \left\{ \begin{array} _2x_1 + 4x_2 = 10 & \\ x_1 + 3x_2 = 6 & \end{array} \right. \tag{1} \]
> # 係数行列を生成
> A <- matrix(c(2, 1, 4, 3),2,2)
> A # 確認
     [,1] [,2]
[1,]    2    4
[2,]    1    3
>
> # 右辺の行列を生成
> b <- matrix(c(10, 6), 2, 1)
> b # 確認
     [,1]
[1,]   10
[2,]    6
>
> #連立方程式を解く組み込み関数
> solve(A,b)
     [,1]
[1,]    3
[2,]    1

超楽で速い!!

2016年10月8日土曜日

三角形ボタンの押下判定方法

基本的にViewで作成されるレイアウトは四角形だ
そこにいろんな形の画像でボタンを作るには、背景を透過にした絵のイメージ画像を使う
この方法で実装した際、Viewの絵の部分をクリックしたときに動作させたいが、画像の余白(透過)部分を押しても反応してしまう問題がある

三角形の画像を想定したとき、
Viewの余白を押したときは反応せず、画像部分を押したときに反応する処理を考える

2016年8月16日火曜日

数字の桁数を取得する方法(2進数ver)

前回紹介した「 数字の桁数を取得する方法」で
2進数表記時の桁数取得方法について触れてなかったので、改めて書いてく
基本的には2進数でもやり方は同じだ

2016年7月29日金曜日

数字の桁数を取得する方法

数字の桁数を取得する関数って意外とない。。
結構使うものだと思うんだけど、なんで提供されてないんだろ?
備忘録にまとめとく

2016年7月23日土曜日

ユークリッドの互除法による約分プログラム


問題
次の分数は約分できますか。できるのであれば、約分してもとっとも簡単な分数で表しなさい
\[ \frac{10033}{12877} \]
ユークリッドやなーって感じの問題が数学検定1級の練習問題で出てきた
そういえば
ユーグリットの互除法は、プログラムだと再起関数の例題でよく見かけるが、実際組んだことなかったので
プログラムでこの問題を解いてみることにする

2016年5月21日土曜日

掃き出し法による連立方程式の解法プログラム

以前、クラメルの公式を使った連立方程式の解法を紹介したが、13元くらいからめちゃくちゃ遅くなることがわかった
そこで今回は一番よくつかわれてる掃き出し法による解法で作ってみる

N元連立1次方程式の解法プログラム(マルチスレッド版)
N元連立1次方程式の解法プログラム組んでみた


掃き出し法とは

$N$元一次方程式$Ax=b$の解法の一つ
係数行列$A$に定数項の列ベクトル$b$を加えた行列 $[A|b]$ に「行列の基本変形」を行い $[E|u]$ に変形したとき、方程式の解$x_i=u_i$となる
行列の基本変形
行の入れ替え:n行目とm行目を入れ替える
行の定数倍:n行目を定数倍する ( 定数≠0 )
行の加減算:n行目を定数倍した値をm行目に加減算する
上記「行列の基本変形」を使うことで、行列を変形させていき、解を導いていく方法が掃き出し法だ
言葉だけじゃよくわからないので例で計算してみる

2016年4月23日土曜日

モンティホール問題をシミュレーションしてみる

最近、統計学にハマってるので、有名なモンティホール問題をベイズの定理で解いてみる
また、プログラムも組んで理論解と数値解の比較もしてみる
モンティ・ホール問題
3つの箱があり、その内1つにアタリがある
最初に自分は箱を1つ選ぶ
その後、司会者は「自分が選んだ箱」以外からハズレの箱を1つ公開する
自分は箱を選び直す権利があるが、選び直すべきか?

2016年3月19日土曜日

N元連立1次方程式の解法プログラム(マルチスレッド版)

前、Fock-Joinフレームワークを使ったフィボナッチ数列を書いたとき、
連立方程式に応用したらもっとはやく計算できるんじゃね?と思ったので、作ってみた
連立方程式は前回同様クラメルの公式。今更だけど、連立方程式は掃き出し法が最強だと思う。。

前回との演算の違い

前の行列式を求めるロジックはこんな感じ
※総和を返すと書いているが、厳密には総和ではなく (-1)j * a0j の係数が付きます

これを単一スレッドで処理すればそりゃ遅くなる。
そこで今回は上図の水色部分をすべてスレッドにして平行処理させようと思う

2015年12月12日土曜日

フィボナッチ数列を逐次、並行処理してみた

Java7 Goldの勉強してて、並行処理の分野で「Fork/Join Framework」を試したくなったのでちょっと実装
お題はフィボナッチ数列を逐次/並行で計算すると、どのくらい差が出るのか
javaで書くから逐次と平行じゃ結構差が出るのでは。と予想

2015年6月30日火曜日

確率とモンテカルロシミュレーション

問題
Aさんには三人の子供がいる
「日曜日生まれの男の子はいるか?」と訊くと「いる」と答えた
Aさんの子供が三人とも男の子である確率は?
最近2ちゃんまとめで上の問題やってみて、
これをモンテカルロでやってみたら結果は理論解に収束するのかな?
って思ったのでやってみた

 モンテカルロシミュレーションとは
シミュレーションや数値計算を乱数を用いて行う手法の総称。元々は、中性子が物質中を動き回る様子を探るために考案された。
強みは基礎的な理論さえ把握していれば、一定のアプローチに従って幅広い問題を解決できるという点
by Wiki
まぁ簡単にいえば、乱数つかって事象を表現して、それをループ文で何回も試し大数の法則でまとめ上げる手法

例:コインを投げた時の裏表の確率
表=1,裏=0として、0か1の乱数を生成。これを10万回(試行回数)繰り返し、1(表)が出たときの数をカウントしておく
コインが表になる確率は、「カウント数 / 10万(試行回数)」で求まる。


 理論解(ベイズの定理)
初見で1/4って思って恥じ書いたww三人のうち、一人が男確定だから、残り二人が男の確立Pは下の通り \[ P=\frac{1}{2}\cdot\frac{1}{2} =\frac{1}{4} \] ( ̄ー ̄) ドヤッ!
はい。日曜日を軽視してましたーww

これはどう見ても事後確率だから、ベイズの定理を使って解いてくのが定石
事象$A$:3人とも男が生まれる
事象$B$:少なくとも1人は日曜日に生まれの男がいる
  とおくと、求める確率$P(A|B)$はベイズの定理より \[ P(A|B)=\frac{P(A \land B)}{P(B)} \]
$P(B)$は「3人とも日曜生まれの男でない」場合の余事象なので \[ P(B)=1-\frac{ 13^3}{14^3}=\frac{547}{2744} \]
$P(A \land B)$は3人とも男で、うち少なくとも一人は日曜日に生まれてる \[ P(A \land B)= _3C_0\left(\frac{1}{14}\right)^3\left(\frac{6}{14}\right)^0+ _3C_1\left(\frac{1}{14}\right)^2\left(\frac{6}{14}\right)^1+ _3C_2\left(\frac{1}{14}\right)^1\left(\frac{6}{14}\right)^2\\ =\frac{127}{2744} \] よって \[ P(A|B)=\frac{P(A \land B)}{P(B)}=\frac{127}{547} \]
 数値解(モンテカルロ法)
今回はCで書いてみた
誕生曜日、性別を持つ構造体をつくり、事象Bを満たす三兄弟を乱数使って生成
三兄弟が全員男である場合をカウントしていく。
最後に、試行回数(ループ数)とカウンターの比率がP(A|B)の確率となる
#include<stdio.h>
#include<math.h>
#include <time.h>

#define SEX_BOY 0
#define SEX_GIRL 1

#define WEEK_SUNDAY    0
#define WEEK_MONDAY    1
#define WEEK_TUESDAY   2
#define WEEK_WEDNESDAY 3
#define WEEK_THURSDAY  4
#define WEEK_FRIDAY    5
#define WEEK_SATURDAY  6

#define LOOP_MAX 10000000

typedef struct {
    int sex;
    int week;
} human_t;

main() {
    srand((unsigned)time(NULL));
    long unsigned loop_count, check_count = 0;
    const human_t target_child = {SEX_BOY, WEEK_SUNDAY};
    human_t children[3];

    for (loop_count = 0; loop_count < LOOP_MAX; loop_count++) {

        // 事象B:少なくとも一人日曜生まれの男がいる条件を成立させる
        int check_flg = -1;
        while(check_flg != 0) {
            int i;
            for (i = 0; i < 3; i++) {
                human_t child = {rand() % 2, rand() % 7};
                children[i] = child;
                if (memcmp(&target_child, &child, sizeof(human_t)) == 0) {
                    check_flg = 0;
                }
            }
        }

        // 事象A:全員男の場合を調べる
        if( (children[0].sex == SEX_BOY)
              &&(children[1].sex == SEX_BOY)
              &&(children[2].sex == SEX_BOY)) {
            check_count++;
        }
    }
    double reslt = check_count/(double)LOOP_MAX;
    printf("reslt = %f",reslt);
}

結果は
reslt = 0.232030

理論解を小数点表記にすると、 127/547 = 0.232175503
よって、誤差は0.0006
いい感じ(^q^)

★ちなみに★

事象Bのロジックについて。。。。
ソースの31~42行目で生成してる三兄弟は
三兄弟を乱数で生成 → その中に日曜生まれ男がいるかチェック → いれば三兄弟を指標として採用。いなければ作り直し
// 事象B:少なくとも一人日曜生まれの男がいる条件を成立させる
int check_flg = -1;
while(check_flg != 0) {
    int i;
    for (i = 0; i < 3; i++) {
        human_t child = {rand() % 2, rand() % 7};
        children[i] = child;
        if (memcmp(&target_child, &child, sizeof(human_t)) == 0) {
            check_flg = 0;
        }
    }
}
となってる。
これが面倒で
三兄弟を乱数で生成、その後、兄弟の誰かを日曜生まれ男に差し替える
// 事象B:少なくとも一人日曜生まれの男がいる条件を成立させる
human_t children[3] = {
    {rand()%2, rand()%7},
    {rand()%2, rand()%7},
    {rand()%2, rand()%7}
};
// 三人のうち誰かを日曜生まれ男に差し替え
children[rand()%3] = target_child;
とか
長男を日曜生まれ男で固定し、残り二人を乱数で生成
// 事象B:少なくとも一人日曜生まれの男がいる条件を成立させる
human_t children[3] = {
    {SEX_BOY, WEEK_SUNDAY}, // 日曜男
    {rand()%2, rand()%7},
    {rand()%2, rand()%7}
};
などをすると、数値解析結果は
  • 三兄弟を乱数で生成、その後、兄弟の誰かを日曜生まれ男に差し替える
  • reslt = 0.249997
  • 長男を日曜生まれ男で固定し、残り二人を乱数で生成
  • reslt = 0.249940

僕が理論解でミスった値、1/4に収束していることがわかる
これは事後確率であることがプログラム上で示せていないため
つまり、ちょっと難しいが、モンテカルロシミュレーションでも事後確率と普通の確率は区別して求めることができる!

 まとめ
モンテカルロシミュレーションで事後確率を示すには、
前提条件の定義さえしっかりプログラムできていれば求めることができる!

2015年5月31日日曜日

積分方法の比較

FORTRANの環境作ったし、実際に計算させてみた
やっぱJavaより早い気がするw
今回は積分のプログラミング方法3パターンの比較を行って、収束具合、正確性を見ていく

 積分の計算種類
\[ \begin{eqnarray} \int_a^b f(x) dx \end{eqnarray} =\lim_{n \to \infty} \sum^n_{i=0}f(x)\Delta x \] 基本的に積分は上記式のように区分求積法で計算していくわけだけど、「$n \to \infty$」はプログラムでは実現できない。なので、様々な計算法で近似して数値解を求める必要がある。
  1. 長方形近似
  2. 一番基本形。積分する領域を長方形に切り刻んで全部足す方法
    ・数式 \[ \begin{eqnarray} \int_a^b f(x) dx \end{eqnarray} =\sum^n_{i=a}f(i)\Delta x \]
    刻み幅$\Delta x$はループ数$N$を使い、$\Delta x = (b - a) / N$となる

    $x$座標の始点、終点、ループ回数を引数にした関数だとこんな感じ
  3. 台形近似
  4. 長方形近似の上位互換。積分する領域を台形に刻むことで、勾配を配慮した形
    ・数式 \[ \begin{eqnarray} \int_a^b f(x) dx \end{eqnarray} =\sum^n_{i=a}\frac{f(i)+f(i+\Delta x)}{2}\Delta x \]
    刻み幅$\Delta x$はループ数$N$を使い、$\Delta x = (b - a) / N$となる

    $x$座標の始点、終点、ループ回数を引数にした関数だとこんな感じ
  5. シンプソンの公式
  6. f(x) を二次関数 P(x) で近似する数値解析方法
    ・数式 \[ \begin{eqnarray} \int_a^b f(x) dx \end{eqnarray} =\frac{h}{3}\Bigl\{f(a)+4\sum^m_{i=1}f(x_{2i-1})+2\sum^{m-1}_{i=1}f(x_{2i})+f(b)\Bigr\} \]
    $h=(b-a)/(2m)$ $x_i=a+ih$ $(i=1,2,3...2m-1)$

    $x$座標の始点、終点、ループ回数を引数にした関数だとこんな感じ
 積分の比較
次に3つの積分方法の正確性、収束性、計算スピードについてみていく
  1. 正確性
  2. 下記式の左辺の数値解をそれぞれを求め、$\pi$にどれだけ近づくか見てみる \[ \begin{eqnarray} \int_0^1 \frac{4}{1+x^2} dx \end{eqnarray} =\pi \]
    計算方法解析解正確性[%]
    長方形近似 3.17157602 100.9544002 
    台形近似 3.16147637 100.6329184 
    シンプソンの公式 3.15489316 100.4233683 
    刻み回数100回の場合の積分結果
    どの結果も同じオーダーなので、違いが分かりにくい。。。

  3. 収束性
  4. 解の収束度合はどうだろうか。
    x軸に刻み回数、y軸に数値解とし、刻み回数と解の収束をグラフ化した
    sekibun1→長方形近似、sekibun2→台形近似、sekibun3→シンプソンの公式、pi→$\pi$
    収束度合の数値化がちょっとできてないけど、シンプソンの公式がかなり早い段階で収束することがわかる。

  5. 計算スピード
  6. 最後に計算速度の差について
    この程度なら差を感じないけど、計算に一週間かかる場合とかだと重要になってくる。それぞれのアルゴリズムの計算回数からだいたいの計算時間のオーダーを求める
    $f(x)$の計算ステップが$F$、分割数$N$とすると
    計算方法オーダー
    長方形近似$N(4+F)$
    台形近似$N(6+2F)$
    シンプソンの公式$N(6+F)$


    つまり、長方形近似>シンプソンの公式>台形近似の順で早いことになる。
    特に$f(x)$の計算ステップが異常にかかる系だと、台形近似が大変

 結論
シンプソンの公式が収束率、計算速度が優れていてよさげ
でも、実装が一番楽な長方形近似で分割数を膨大に増やして計算するのが、実装ミス、手間が省けて効率いいかも思った
以上

2015年1月11日日曜日

N元連立1次方程式の解法プログラム組んでみた

せっかく数式が使えるようになったしちょっと数学系書いてみる
N元連立1次方程式にはいろいろ解き方あるけど、アルゴリズムが一番楽なクラメルの公式

クラメルの公式とは

$A$を正方行列としたとき $Ax=b$で与えられる連立方程式の$i$番目の解は \[ x_i=\frac{det(A_i)}{det(A)} \]

2015年1月8日木曜日

ブログで数式を扱う方法

プログラムの技術系ブログだけど、物理シミュレーションプログラムとかもやっていくつもりなので数式を表示する方法を調べてみた。

◆MathJax

\[ \sum_{n=1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6} \tag{1} \]
こんな感じに書ける

  1. プラグイン導入
  2. 
    
    
    
    これをマイブログ→レイアウト→HTMLを編集→<title>タグのうしろ位に挿入
    コレで準備OK
  3. 使い方
  4. Latex書くのと同じように書く
    プログラムで使いそうなのちょっと書く
    • ベクトル(足し算)
    • \[
        \vec{a} + \vec{a} = 2 \vec{a}
      \]
      
      \[ \vec{a} + \vec{a} = 2 \vec{a} \]
    • ベクトル(要素)
    • \[
        \vec{a} = (a_1, a_2, \cdots, a_n)
      \]
      
      \[ \vec{a} = (a_1, a_2, \cdots, a_n) \]
    • 行列1
    • \[
        A = \left(
          \begin{array}{ccc}
            a & b & c \\
            d & e & f \\
            g & h & i
          \end{array}
        \right)
      \]
      
      \[ A = \left( \begin{array}{ccc} a & b & c \\ d & e & f \\ g & h & i \end{array} \right) \]
    • 行列2
    • \[
        A = \left(
          \begin{array}{cccc}
            a_{11} & a_{12} & \ldots & a_{1n} \\
            a_{21} & a_{22} & \ldots & a_{2n} \\
            \vdots & \vdots & \ddots & \vdots \\
            a_{m1} & a_{m2} & \ldots & a_{mn}
          \end{array}
        \right)
      \]
      
      \[ A = \left( \begin{array}{cccc} a_{11} & a_{12} & \ldots & a_{1n} \\ a_{21} & a_{22} & \ldots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \ldots & a_{mn} \end{array} \right) \]
こんなかんじ!
あれ?なんかスマホだと表記が違うΣ( ̄ロ ̄lll)