球面上のランダムウォーク

codeなにがし::球面上のランダムウォークからの引用です。 このページに C で書かれたプログラムがありますので、これを awk に移植して実際に gnuplot でプロットしてみます。

言語を学習する際に、他の言語を自分の得意な言語に翻訳することは、他の言語を知るためにも有益で、自分の言語の得意とする部分や不得意な部分を気づかせてくれます。 ここでは C を awk に変換しますので、かなり似通った構文になります。

#! /usr/bin/gawk -f
# random_walk.awk

BEGIN {
    M_PI = 2 * atan2(1, 0);
    R = M_PI * 4;
    x = R; y = 0.0; z = 0.0;
    theta = 0; phi = M_PI / 2;

    step = ARGV[1] + 0;
    if (ARGC != 2 || step <= 0) {
        printf("Usage: %s <step-number>\n", argv[0]) > "/dev/stdout";
        exit 1;
    }

    srand();
    printf("%.3f\t%.3f\t%.3f\n", x, y, z);
    for (i = 0; i < step; i++) {
        omega = rand() * M_PI * 2;
        theta += cos(omega) / R;
        if (theta < 0) {
            theta += M_PI * 2;
        } else if (theta > M_PI * 2) {
            theta -= M_PI * 2;
        }
        phi += sin(omega) / R;
        if (phi < 0) {
            phi = -phi;
        } else if (phi > M_PI) {
            phi = M_PI * 2 - phi;
        }

        x = R * cos(theta) * sin(phi);
        y = R * sin(theta) * sin(phi);
        z = R              * cos(phi);
        printf("%.3f\t%.3f\t%.3f\n", x, y, z);
    }

    exit 0;
}

非常にオリジナルに似たものですが、大きく異なるところが 3 点あります。

1 点目は define ができないために R = M_PI / 4 と代入することで代用しています。 また、M_PI は math ライブラリがないため、2 * atan2(1, 0) として円周率を計算しています。

2 点目は (step=atoi(argv1))<=0 という部分ですが、awk には atoi() 関数がないことと、awk では代入できたかどうかを評価する条件式として解釈されてしまうため、代入と値の評価を分けています。

3 点目は (double)rand() / (double)RAND_MAX という部分は awk ではズバリ rand() 関数そのものになりますので、そのまま rand() 関数に置き換えています。 つまり、同じ rand() 関数でも持つ意味が異なっています。

さて、実行して gnuplot に代入してみます。

$ nawk -f random_walk.awk 10000 > random_walk.dat

$ gnuplot

    G N U P L O T
    Version 4.2 patchlevel 3
    last modified Mar 2008
    System: Linux 2.6.27.21-170.2.56.fc10.i686

    Copyright (C) 1986 - 1993, 1998, 2004, 2007, 2008
    Thomas Williams, Colin Kelley and many others

    Type `help` to access the on-line reference manual.
    The gnuplot FAQ is available from http://www.gnuplot.info/faq/

    Send bug reports and suggestions to <http://sourceforge.net/projects/gnuplot>


Terminal type set to 'wxt'
gnuplot> plot 'random_walk.dat' with line
gnuplot>

DoukakuAWK_146.png

このような図が描けます。 DoukakuAWK 058:AWK Users JP :: CPU 負荷率のグラフ化でも gnuplot を用いて図を作成していますが、awk を使うことで gnuplot を使って簡単に可視化することができます。

tag_nawk.pngtag_nawk.pngtag_nawk.pngtag_nawk.png