2015年8月2日日曜日

Gnuplot連携ライブラリ(C言語)

大学時代から数値計算結果のプロットは、もっぱらGnuplot(http://www.gnuplot.info/)を使っています。なんだかんだお手軽で便利なんですよねGnuplot。

C/C++から呼び出すときには、popen(3)でGnuplotを呼び出して要件に合わせてプロットするコードを書きますが、毎度毎度書くのは面倒で、いつかはライブラリ化しようと思いつつも、大学時代に自分用に作ったプロット用関数群を使用し続けていました。

最近久しぶりにコード書いてて、コードからGnuplot呼び出そうとしたときに、せっかくだからライブラリ化しよう思いました。大学時代の自分なら闇雲にいきなりコードを書いてしまったでしょうが(車輪の再発明が大好きだったのです)、当時よりは少しだけ冷静に行動できるようになっていますので、既に公開されているライブラリはないか探してみました。そして探してみたら、あっさり見つかりました。

gnuplot interfaces in ANSI Chttp://ndevilla.free.fr/gnuplot/

まだ、サンプルコードいじった程度ですが、シンプルで使いやすそう。自分で必要な機能を追加するにしても、これをベースに作っていこうかなと思いました。

/*
 * Examples of gnuplot_i.c usage
 */

#include <stdio.h>
#include <stdlib.h>

#include "gnuplot_i.h"

#define SLEEP_LGTH  2
#define NPOINTS     50

int main(int argc, char *argv[]) 
{
    gnuplot_ctrl    *   h1,
                    *   h2,
                    *   h3,
                    *   h4 ;
    double              x[NPOINTS] ;
    double              y[NPOINTS] ;
    int                 i ;

    /*
     * Initialize the gnuplot handle
     */
    printf("*** example of gnuplot control through C ***\n") ;
    h1 = gnuplot_init() ;

    /*
     * Slopes
     */
    gnuplot_setstyle(h1, "lines") ;
    
    printf("*** plotting slopes\n") ;
    printf("y = x\n") ;
    gnuplot_plot_slope(h1, 1.0, 0.0, "unity slope") ;
    sleep(SLEEP_LGTH) ;

    printf("y = 2*x\n") ;
    gnuplot_plot_slope(h1, 2.0, 0.0, "y=2x") ;
    sleep(SLEEP_LGTH) ;

    printf("y = -x\n") ;
    gnuplot_plot_slope(h1, -1.0, 0.0, "y=-x") ;
    sleep(SLEEP_LGTH) ;
    

    /*
     * Equations
     */

    gnuplot_resetplot(h1) ;
    printf("\n\n") ;
    printf("*** various equations\n") ;
    printf("y = sin(x)\n") ;
    gnuplot_plot_equation(h1, "sin(x)", "sine") ;
    sleep(SLEEP_LGTH) ;

    printf("y = log(x)\n") ;
    gnuplot_plot_equation(h1, "log(x)", "logarithm") ;
    sleep(SLEEP_LGTH) ;

    printf("y = sin(x)*cos(2*x)\n") ;
    gnuplot_plot_equation(h1, "sin(x)*cos(2*x)", "sine product") ;
    sleep(SLEEP_LGTH) ;


    /*
     * Styles
     */

    gnuplot_resetplot(h1) ;
    printf("\n\n") ;
    printf("*** showing styles\n") ;

    printf("sine in points\n") ;
    gnuplot_setstyle(h1, "points") ;
    gnuplot_plot_equation(h1, "sin(x)", "sine") ;
    sleep(SLEEP_LGTH) ;
    
    printf("sine in impulses\n") ;
    gnuplot_setstyle(h1, "impulses") ;
    gnuplot_plot_equation(h1, "sin(x)", "sine") ;
    sleep(SLEEP_LGTH) ;
    
    printf("sine in steps\n") ;
    gnuplot_setstyle(h1, "steps") ;
    gnuplot_plot_equation(h1, "sin(x)", "sine") ;
    sleep(SLEEP_LGTH) ;

    /*
     * User defined 1d and 2d point sets
     */

    gnuplot_resetplot(h1) ;
    gnuplot_setstyle(h1, "impulses") ;
    printf("\n\n") ;
    printf("*** user-defined lists of doubles\n") ;
    for (i=0 ; i<NPOINTS ; i++) {
        x[i] = (double)i*i ;
    }
    gnuplot_plot_x(h1, x, NPOINTS, "user-defined doubles") ;
    sleep(SLEEP_LGTH) ;

 printf("*** user-defined lists of points\n");
    for (i=0 ; i<NPOINTS ; i++) {
        x[i] = (double)i ;
        y[i] = (double)i * (double)i ;
    }
    gnuplot_resetplot(h1) ;
    gnuplot_setstyle(h1, "points") ;
    gnuplot_plot_xy(h1, x, y, NPOINTS, "user-defined points") ;
    sleep(SLEEP_LGTH) ;


    /*
     * Multiple output screens
     */

    printf("\n\n") ;
    printf("*** multiple output windows\n") ;
    gnuplot_resetplot(h1) ;
    gnuplot_setstyle(h1, "lines") ;
    h2 = gnuplot_init() ;
    gnuplot_setstyle(h2, "lines") ;
    h3 = gnuplot_init() ;
    gnuplot_setstyle(h3, "lines") ;
    h4 = gnuplot_init() ;
    gnuplot_setstyle(h4, "lines") ;

    printf("window 1: sin(x)\n") ;
    gnuplot_plot_equation(h1, "sin(x)", "sin(x)") ;
    sleep(SLEEP_LGTH) ;
    printf("window 2: x*sin(x)\n") ;
    gnuplot_plot_equation(h2, "x*sin(x)", "x*sin(x)") ;
    sleep(SLEEP_LGTH) ;
    printf("window 3: log(x)/x\n") ;
    gnuplot_plot_equation(h3, "log(x)/x", "log(x)/x");
    sleep(SLEEP_LGTH) ;
    printf("window 4: sin(x)/x\n") ;
    gnuplot_plot_equation(h4, "sin(x)/x", "sin(x)/x") ;
    sleep(SLEEP_LGTH) ;
    
    /*
     * close gnuplot handles
     */


    printf("\n\n") ;
    printf("*** end of gnuplot example\n") ;
    gnuplot_close(h1) ;
    gnuplot_close(h2) ;
    gnuplot_close(h3) ;
    gnuplot_close(h4) ;
    return 0 ;
}

またやってしまった

前回の投稿をしてから1年以上経ってしまった・・・

この1年以上の間にいろいろなことがありました。MDM(Mobile Device Management)製品(※)にどっぷりだったり、MacBook Pro 15-inch, Mid 2014を購入したり、プライベートでもいろいろあったりと、とにかく色々あったのでした。

プログラミング関連の知識・スキルを高めたいと思っていたけど、仕事が忙しかったりして全然できず、むしろ錆び付いてしまったけど、また徐々にやっていこうと思って投稿を再会しました。

(※)市場を牽引するベンダーがEMM(Enterprise Mobile Management)って言葉をつくってたりします。

2014年5月10日土曜日

自作Androidアプリの実機確認

自分メモ.
root化したAndroid端末では実行できなかった(実行してもアクティビティが表示されない).

root化した端末でも実行する方法はあるんだろうけど別に困っていないからいいや.

iPhoneアプリに挑戦

年明けにiPhone4Sから5Sに機種変更して早くも5ヶ月目.
3ヶ月目でアスファルトの上に落っことしてしまったので, 既に傷だらけになってしまった.
・・・まぁそんなことはどうでもいいや.

眠くて文章まとめるのが面倒なので, なんで今更iPhoneアプリに挑戦しようと思った経緯をプライベートと仕事に分けて書いてみる.

プライベート

自宅PCが老朽化してきて, 『買い替えようかなぁ』とネットでPCを選んでたけど, どれもイマイチ.

そういえば以前買ったiMacが1回しか電源入れずに2年近く沈黙していることに気づく.

『もったいないし, この際Macに移行するか』と思い立つ. 割とスムーズにMacに移行できた.

どうせXcode入れるし, せっかくだからiPhoneアプリ作ってみたいな〜
iPhone5Sに機種変更して4Sを実機確認用に使えるしちょうどいいや.

仕事

DBセキュリティの仕事がなくて将来不安〜

今年度は, MDMできるようになっておまんま食べられるようにしよう.

iPhone/Androidのアプリの動きがわかってるとMDM製品の理解に役立つだろうな〜

とまぁこんなわけです.
GW中にiOS Developer Programにも登録したった.
お金払ったらすぐにアクティベートされると思ったら, 2日くらいステータスがPendingのままでちと焦った.
それと実機で動作確認するまでに結構ややこしかったから後でまとめておこうと思う.

2013年12月7日土曜日

CentOSにmDNSを設定する

ノートPCにインストールしたCentOSに, mDNSに設定したときのメモ.

経緯

このCentOSは, 持ち運び可能なサーバとして運用している. ポータブルな環境に固定IP設定するのは微妙だし, IPアドレス直打ちでアクセスするにしても, 毎回IP確認するのは面倒くさい.
そこで, mDNSを設定して「ホスト名.local」でアクセスできるようにした.

ホスト名の設定

まずは, ホスト名を設定する.
NETWORKING=yes
HOSTNAME=hoge.local

nss-mdnsのインストール

nss-mdnsパッケージは, CentOSの標準リポジトリにないのでEPELを追加する.

◆EPELのインストール
$ wget http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ sudo rpm -ivh epel-release-6-8.noarch.rpm
nss-mdnsをインストールするだけなので, 普段はEPELを有効にしないようにしておく(/etc/yum.repos.d/epel.repoの[epel]セクションで「enable=0」にする).

◆nss-mdnsのインストール
$ sudo yum --enablerepo=epel install nss-mdns

nss-mdnsの設定

名前解決の手段として使用するには, /etc/nsswitch.confの修正が必要だが, nss-mdnsをインストールすると自動で修正されているはず.
hosts:      files mdns4_minimal [NOTFOUND=return] dns

Firewallの設定

system-config-firewall-tuiを起動して, 「マルチキャスト DNS (mDNS)」を信頼したサービスに追加しておく. 追加すると, 224.0.0.251:5353宛のUDP通信が許可される.

再起動

いろいろ設定を変更したので, rebootして設定を反映させる(もちろん各サービスの再起動でも可).

2013年10月19日土曜日

数値計算(流体):粒子法のシミュレーション動画

9月の終わり頃, データの整理をしていたら, 大学院時代に作成した粒子法のシミュレーション動画が出てきた.
初めて粒子法のプログラムを作ったときは、青子守歌さんのダムブレークシミュレーションの動画を見ながら, 『自分のプログラムで動かしてみたい!』ってモチベーションを維持してたのを思い出した.
あれから3年近く経ったけど, (自作プログラムの)粒子法動画ってあまり増えてなかったから, ニコニコ動画にアップロードしてみた.
ついでに差分法で計算したK-H/R-T不安定性のシミュレーション動画もアップロードした.










昔のデータが出てきて当時のプログラムを眺めてたら, 『やっぱり数値計算面白い!』って改めて思った.
粒子法で翼まわりの流れをシミュレーションするのを目標に勉強し直そうと思う.

2013年9月22日日曜日

C言語からTcl/Tkを呼び出す

前回のTcl/Tk版 Hello WorldをC言語から実行させることができたのでメモ.

まずは, ソース. Tcl_Initの前にTcl_FindExecutableが必須と説明している文書もあったが, 無くても動いたのでそのまま.
#include <tcl.h>
#include <tk.h>

int main(int argc, char* argv[])
{
    Tcl_Interp* interp;
    char        wish_cmd[] =
      "wm title . \"Hello World\"\n"
      "wm geometry . \"480x240\"\n"
      "label .label -text \"Hello, World! with Tcl/Tk.\"\n"
      "pack .label -side top -anchor w";
    
    interp = Tcl_CreateInterp();
    Tcl_Init(interp);
    Tk_Init(interp);
    Tcl_Eval(interp, wish_cmd);
    Tk_MainLoop();
    
    return 0;
}


次にコンパイル.
$ gcc -Wall hello_tcltk.c -ltcl86 -ltk86
/mingw/libの下にlibtcl86.aとlibtk86.aが配置されていたので, 上記のようにした.
また, CentOSでもTcl/Tkをインストールして, 上記のソースコードをコンパイルしてみた. こちらは, 以下のコマンドでOKだった.
$ gcc -Wall hello_tcltk.c -ltcl -ltk
ちなみに, これをMinGW/msysで実行すると, 当然のことながらld先生に「cannot find ...」と怒られる.