数値計算の際のちょっとしたテクニック

 ニューメリカルレシピのコード読んでて見つけたテクニックを紹介する。
詳細な説明は見当たらなかった。どこかに書いてあったのかな。
コード読んでて何だ?この処理。ってなった内容なのでメモとして残しておく。

if(b/a < c) ...

というコードを考える。...は適当な文ね。
割り算は気持ちが悪いので

if(a>0)
{
if(b<a*c)...
}
else
{
if(b>a*c)...
}

とした方が気持ちはすっきりする。

a<0のときは
b>a*c → -b<-a*c → -b<|a|*c

と書ける。つまり、

if(a<0) b *= -1;
if(b<|a|*c)...

と書いても同じことである。おおー、ってなった。
一般的によく知られているテクニックなのかもしれないけど始めて知った。
もちろんa=0の場合には注意が必要だけど。
ジャジャガッチ | C/C++ | 10:22 | comments(0) | trackbacks(0) |

ファイル名変更プログラム

 データ解析等をするとき、処理対称のファイルを"aaa.txt"として、処理後のファイルを
"aaa_out.txt"などとしたいことがよくある。
大体手を抜いて出力ファイル名は"out.txt"とかに統一してしまう。
でもこれだと"aaa.txt"を処理した後"bbb.txt"を処理すると最初の"out.txt"は
上書きされてしまう。
これは面倒くさいということでこの機会にプログラムを作った。

#include <stdio.h>
#include <string.h>

void fn(char *name,char *name2)//name="aaa.txt"
{
    int l = strlen(name);//文字列の長さ取得 ¥0は含まない

    int i;
    for(i=l-1;i>=0;i--)
    {
        if(name[i]=='.') break;
    }

    char A[256],B[256];
    strcpy(A,name);
    A[i] = '¥0';//A="aaa"

    strcpy(B,&name[i]);//B=".txt"

    strcat(A,"_out");//A="aaa_out"
    strcat(A,B);//A="aaa_out.txt"

    strcpy(name2,A);
}

int main(int argc,char **argv)
{
    char test[256];
    fn(argv[1],test);

    printf("%s¥n",test);
    return 0;
}
ジャジャガッチ | C/C++ | 10:17 | comments(0) | trackbacks(0) |

テキストファイルの行数を求める

 プログラム書いててよく必要になる処理がテキストファイルの行数取得だ。
僕がよく使う形式は
1
2
a
b
c
というように空白行なしのものだ。列は複数列あってもいい。
こういうファイルの行数を取得したいのだが、問題はファイルの終端付近だ。
例えば
1¥n
2¥n
(¥nは改行)となっていれば¥nをカウントすればいい。でも、
1¥n
2
となってる場合も、
1¥n
2¥n
¥n
となっている場合もよくある。この場合単純に¥nを数えると正しく行数を求められない。
ここで欲しいのはデータのある行数だからだ。
最近特にこういう処理が必要になることが多いので関数を作ってみた。

#include <stdio.h>


int Line(char *FileName)
{
    FILE *fp = fopen(FileName,"r");
    int c,Line = 1;
    while((c=fgetc(fp))!=EOF)
    {
        if(c=='¥n')
        {
            c = fgetc(fp);
            if(c!='¥n' && c!=EOF) Line++;
            else break;
        }
    }
    fclose(fp);

    return Line;
}

int main(int argc,char **argv)
{
    printf("%d¥n",Line(argv[1]));
    return 0;
}
ジャジャガッチ | C/C++ | 21:01 | comments(0) | trackbacks(0) |

コイントスをシミュレーション(ベイズ統計)

 今、何度かコイントス実験を行ったものとする。
その結果に基づいて表の出る確率θを推定したい。
最も実験結果を再現しやすいθを選ぶのが最尤推定法である。

一方、ベイズ的な考え方では、θは確率変数である。
まず、事前の知識に基づいて事前分布を与える必要がある。
コインについて全く情報がない場合はすべてのθが平等だとする。
この場合は最尤推定に帰着する。

実験を何度か行って事後分布を計算した後、さらに実験を行った場合は、最初に求めた事後分布を事前分布として計算を行えばよい。
シミュレーションの目的は実験回数によって事後分布がどのように変化していくのか、また事前分布の選び方がどのように影響するのかを確認することだ。

シミュレーション結果を示す。事前分布は一様であるとした。θは0.5に設定した。
赤が3回実験後(表、裏、裏)、緑が5回実験後(表、裏、表、表、裏)の分布である。
3回実験は裏の回数の方が多いので小さい側へ偏っている。5回実験の場合も
同様の理由により大きい側へ偏っている。

次に100回実験を行ってみる。ほぼ0.5にピークがきている。

次に事前分布を二次関数にしてみた。
5回実験(表、表、裏、裏、裏)の結果を示す。
緑が事前分布である。裏の方が回数が多いにも関わらず、θの大きい側に偏っている。

100回実験結果を示す。赤が事前分布を一様としたもの、緑が二次関数にしたもの。
どちらも実験結果に偏りがあって0.5中心にはなっていないが形状はほとんど差がない。
ちなみに事前分布で0とおいた範囲は多分実験を繰り返しても0のままだと思うので少しでも可能性があれば0には設定しないほうがいいんだと思う。

ベイズ統計に関してはよくわからないところがたくさんあるので要勉強だ。

シミュレーションに用いたソースは続きから。

続きを読む >>
ジャジャガッチ | コンピュータ | 19:12 | comments(0) | trackbacks(0) |
1/1PAGES | |

07
--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
--
>>
<<
--
PR
RECOMMEND
RECENT COMMENT
MOBILE
qrcode
OTHERS
Since 2013/09/17
LATEST ENTRY
CATEGORY
ARCHIVE
LINKS
PROFILE
SEARCH