Recently in programming Category

February 2, 2012

pipeを使ってgnuplotをCで書いたプログラムから制御する方法(Win32)

gnuplotは優れたプロットプログラムである。インタラクティブにコマンドを入力してもよいし、スクリプトを書いてバッチ処理もできる。そしてWin32であっても、パイプを使って外部プログラムから制御することもできる。ここではWin32 APIを使って、Cで書かれたプログラムからgnuplotを操作してみた。

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

static const char *GNUPLOT = "c:\\gnuplot\\binary\\gnuplot.exe -persist";

int main(int argc, char* argv[])
{
	FILE *pPipe = _popen(GNUPLOT, "w");
	
	if(NULL == pPipe){
		printf("popen fail\n");
		return 0;
	}

	fprintf(pPipe, "set terminal png\n");
	fprintf(pPipe, "set output 'test.png'\n");
	fprintf(pPipe, "plot cos(x)\n");
	_pclose(pPipe);
	return 0;
}

 非常に簡単だ。UNIX同様パイプを作成し、パイプにコマンドを入力する。この例だと、test.pngというファイルにcos(x)のグラフがPNG画像として保存される。ポイントは、gnuplotコマンドに -persistオプションを付けることである。

そういえば、気になっていたスタイルシートを修正しました。

September 12, 2010

GNU RとJavaScriptの無名再帰をやってみた

 例によって、なんのこっちゃわからんと言われる類の記事である。

 昨日のOSC2010 Tokyo/Fall の2次会で話題になった、RとJavaScriptの無名再帰を確かめてみた。
 まずはJavaScript。例えば5の階乗を計算する関数を書いて、

var result = function(val, n){
    if(n===0) 
	return val;    
    return arguments.callee(val*n, n-1);
}(1,5);
print(result);

これをfac.jsという名前で保存して実行してみると、

$ js fac.js 
120

正しい結果が返ってきている。ポイントは呼び出した関数オブジェクトが、変数 arguments.callee に束縛されていること。再帰は呼び出された関数をその関数内で呼び出す必要があるので、自分がどの関数なのか特定する必要がある。普通の再帰は名前が付いているので問題ないが、無名再帰の場合名前がない。そこで言語側で仕組みを用意する必要がある。ということでJavaScriptすげぇ。

 次にGNU R。同じく5の階乗を計算するコード

> (function(tmp, n){
+ if(0==n) return(tmp)
+ return(Recall(tmp*n, n-1))
+ })(1, 5)
[1] 120

すばらしい。Rの場合のポイントはRecall関数。再帰呼び出しをするための関数だ。Recallを使うことで名前を使わずに、自身の関数を再帰呼び出しすることができる。

他の言語の無名再帰については、例えばDan Kogai氏らがPerlで試みているようだ。

July 13, 2010

プリプロセッサ命令#と##のメモ

 今日読んでいるコードに、知らなかったプリプロセッサ命令が出てきたのでメモ。

#include <stdio.h>

#define tcat(x,y,z) x ## y ## z
#define cat(x) # x

#define abc "Hello"

int main(void)
{
  printf("%s\n", tcat(a, b, c));
  printf("%s\n", cat(a b c));
  return 0;
}

実行すると、

chome@sid:~/src/test$ ./a.out 
Hello
a b c

となる。

May 23, 2010

dpkg-buildpackageメモ

 Debianパッケージの作成プロセスを自動化するコマンドであるdpkg-buildpackageのメモ。dpkg-buildpackageは以下の手順でパッケージを作成する。

  1. 環境変数の準備。dpkg-architectureでBuild archやHost arch等を設定し、またCCFLAGS、CXXFLAGS、LDFLAGS等を設定
  2. build-dependencyとbuild-conflictsのチェック。(-d でスキップ)
  3. debian/rule clean (-nc でスキップ)
  4. dpkg-source (-b, -B, -A のいずれかが設定されているとスキップ)
  5. -b, -B, -Aオプションによって以下のいずれかに分岐
    • debian/rules build (デフォルトまたは-b)
    • debian/rules binary-arch (-B)
    • debian/rules binary-indep (-A)
  6. dscファイルを署名 (-us でスキップ)
  7. dpkg-genchanges でchangesファイルを生成
  8. changesファイルを署名 (-uc でスキップ)
  9. もしも-tcが指定されていたら、debian/rules clean

-j で、並列に動かすCPUの数を指定することができる。はしょったところもあるので、dpkg-buildpackage(1)を確認のこと。

April 17, 2010

Singletonをまじめに書いてみた

SingletonパターンをC++でまじめに書いてみた。Singletonは生成は簡単なんだけれど、後始末が難しい。GoF本とかには、後始末のことはあまり詳しく書かれていなかったような気がする。あとModern C++ Designにこのことは詳しくかかれている。

 今回は最初に思いついたリンクカウントを採用してみた。Singletonを参照しているオブジェクトの数を数えておいて、0になったらdeleteする。

#ifndef _SINGLETON_H
#define _SINGLETON_H

namespace impl{
template <class T>
class Singleton{
public:
  static Singleton* initInstance()
  {
    if(linkcount == 0){
      instance = new Singleton();
      linkcount = 1;
    }else{
      linkcount+=1;
    }
    return instance;
  }

  void destroy()
  {
    if(0 == (linkcount-=1)){
      delete instance;
    }
  }

  T* object(){
    return &obj;
  }

private:
  Singleton(){
  }

public:
  virtual ~Singleton(){
  }

private:
  static Singleton *instance;
  static int linkcount;
  T obj;
};


template <class T> Singleton<T> *Singleton<T>::instance;
template <class T> int Singleton<T>::linkcount = 0;
}

template <class T>
class Singleton{
 public:
  Singleton(){
    s = impl::Singleton<T>::initInstance();
  }
  
  T* operator->(){
    return s->object();
  }

  ~Singleton(){
    s->destroy();
  }

 private:
  Singleton(const Singleton&){}

 private:
  impl::Singleton<T> *s;
};
#endif // _SINGLETON_H

で、一つしかインスタンスを作りたくないクラスを定義してあげて、::Singletonのテンプレート引数に入れてあげればよい。例えばこんな感じ。

#include "singleton.h"
using namespace std;

class Hello
{
public:
  Hello()
  {
    i = 0;
  }

  void run()
  {
    i += 1;
    cout<< "Hello World "<< i<< endl;
  }

  ~Hello()
  {
    cout<< "destroy"<< endl;
  }
  int i;
};


int main(void)
{
  Singleton<Hello> i1;
  Singleton<Hello> i2;
  Singleton<Hello> i3;

  i1->run();
  i2->run();
  i3->run();

  return 0;
}

 このテストコードを実行すると、次のようになる。

Hello World 1
Hello World 2
Hello World 3
destroy

 同じテンプレート引数の::Singletonインスタンスを複数生成しているが、それらは同じインスタンス変数にアクセスしており、デストラクタは1度しか呼ばれていない。ちゃんと動いているようだ。ただこのコードでは、Helloの初期化をデフォルトコンストラクタでしかできない。これではちょっとカッコ悪い。もう少し考えなければ。

October 29, 2009

JavaScriptでのクロージャーのテスト

 WHATWGでHTML5仕様がLast Callになった。徐々にではあるが、Web Application が普及する環境が整いつつある。(どうもW3Cは聞いていなかったらしく、ちょっと揉めそうな感じみたいだが。)

 さて、以前もここで書いたとおりHTML5はそれまでの文書の構造化に加え、振る舞いの要素の追加が行われており、スクリプト言語のインターフェースも規定されている。このスクリプト言語は仕様の上では指定されているわけではないが、事実上JavaScriptだろう。ということでそろそろちゃんとJavaScriptを書けるようにならなきゃいかんのかなぁ。ということで、まずはクロージャーからやってみた。

<html lang="ja">
<head>
  <title>Closure Test</title>
  <meta http-equiv="Content-Type" content="text/plain;charset=UTF-8">
</head>

<body onload="onLoad()">
<script type="text/javascript">
var countUp;

function makefunc()
{
    var x=0;
    return function(){return x++;};
}

function onLoad()
{
    countUp = makefunc();
    window.setInterval(onTimer, 100);
}

function onTimer()
{
    document.getElementById('count').innerHTML = countUp();
}

</script>

<div id="count"></div>
</body>
</html>

 このコードは、100ms毎にカウントアップして表示するもの。makefuncがカウントアップする関数オブジェクトを作り、onloadハンドラでグローバル変数countupに保存しておく。それを100ms毎に呼び出している。実行すると下のようになる。

October 11, 2009

時系列データファイルから必要な時間のデータを取り出すスクリプト

久しぶりにshell (bash) script。一つのデータが一行ごとに並んでいるファイルから必要な部分を取り出すスクリプト。今回はbashの組み込み関数である getopts を使ってみた。

#!/bin/bash
#
# clip.sh -f FROM -t TO FILE
#

while getopts "f:t:" i;do
	case $i in
		f) FROM=$OPTARG;; # Time From
		t) TO=$OPTARG;;   # Time To
	esac
done

shift $(($OPTIND - 1))
FILE=$1

LINES=`wc --line $FILE | cut -d " " -f 1`
FLINE=`grep -n $FROM $FILE | cut -d : -f 1 | head -n 1`
TLINE=`grep -n $TO $FILE | cut -d : -f 1 | head -n 1`

if [ $FLINE -ge $TLINE ]; then
	TMP=$FLINE;
	FLINE=$TLINE;
	TLINE=$TMP;	
fi

HEAD=$(($TLINE-$FLINE))
TAIL=$(($LINES-$FLINE+1))

tail -n $TAIL $FILE | head -n $HEAD

 たとえばこのようなファイルがあるとすると

11:00:17 24.93 72.9
11:00:17 24.94 72.8
11:00:17 24.94 72.7
11:00:18 24.95 72.4
11:00:19 24.96 72.1
11:00:20 24.97 71.9
11:00:21 24.97 71.8
11:00:22 24.98 71.7
11:00:23 24.99 71.4
11:00:24 25.00 71.2
....

このファイルをdata.txtというファイル名として、この中から12:00:00から13:00:00まで取り出したいとすると、

$ clip.sh -f 12:00:00 -t 13:00:00 data.txt

とすれば標準出力に出力される。

 ふ、例によって誰もついて来れまい。あ、ぴらふとCZDの二氏は除く。ってかこのくらいのコマンドは、textutilあたりにありそう。良い解法があればコメントよろ。

June 14, 2009

続・C++でStringTokenizerっぽいことをやってみる

 前回の記事haveの指摘に従い、参照渡しをやめてヴェクタを返す関数にしてみた。

std::vector<string> 
slice(const std::string source, const std::string dem)
{
  std::string::size_type i1 = 0;
  std::string::size_type i2 = source.find(dem);
  std::vector<string> retval;

  if(std::string::npos == i2)
    return retval;

  std::string s = source + dem;

  do{
    retval.push_back(s.substr(i1, i2-i1));
    i1 = i2+1;
  }while(std::string::npos != (i2 = s.find(dem, i1)));

  return retval;
}

 ちょっと効率は落ちたが、Atomicになったので前回のコードにくらべ、マルチスレッドプログラミングで安全に使えるようになった。

Thanks! nice comment > Have

June 13, 2009

C++でStringTokenizerっぽいことをやってみる

C++を書いていて、JavaのSttringTokenizerのようなことをやりたいことがある。C++標準ライブラリだけで書いてみた。

void slice(const std::string source, 
	   const std::string dem, 
	   std::vector<std::string> *retval)
{
  std::string::size_type i1 = 0;
  std::string::size_type i2 = source.find(dem);

  if(std::string::npos == i2)
    return;

  std::string s = source + dem;

  do{
    retval->push_back(s.substr(i1, i2-i1));
    i1 = i2+1;
  }while(std::string::npos != (i2 = s.find(dem, i1)));
}

 この関数は、sourceで指定した文字列をdemで指定した文字で切り分けて、切り分けた結果をretvalで指定したヴェクタに格納ものである。テストしてみると。


using namespace std;

int main(void)
{
  string source = 
    "DCV_,___,___,-00.0073E-3,DCV_,___,___,+00.000E-3,6247865";

  vector<string> vec;
  vec.clear();

  slice(source, ",", &vec);
  if(vec.empty()){
    cout<< "not found"<< endl;
    return -1;
  }

  cout<< vec[3]<< " "<< vec[7]<< endl;
  return 0;
}


$ ./a.out
-00.0073E-3 +00.000E-3

 ちゃんと値は切り出せている。listに結果を格納するようにすれば、もっとStringTokenizerっぽくなるかな。

June 3, 2009

久しぶりScheme

PHOTO: On Lisp Cover

 久しぶりにschemeでコードを書いてみた。実用のコードでは初かな。処理系はGaucheで、標準入力から数値を入力して標準偏差を計算するコード。

(define (ave-list lst)
  (/ (fold + 0 lst) (length lst)))

(define (var lst)
  (let ((ave (ave-list lst)))
    (/ (fold + 0 
	     (map (lambda (x) (* x x)) 
		  (map (lambda (x) (- x ave)) lst)))
       (length lst))))

(define (sd lst)
  (sqrt (var lst)))

(display (sd 
	  (map string->number (port->string-list 
			       (current-input-port)))))

リストを修正するコードの連鎖と高階関数。この感覚がLISPっぽい。

 新しいカメラは届きました。

2009-06-06 追記
 はぁ?LET?とか言われそうなので(誰に?)、LETなしバージョンは、sdをこうすれば良い。


(define (var lst)
  ((lambda (ave)
    (/ (fold + 0
	     (map (lambda (x) (expt x 2))
		  (map (lambda (x) (- x ave)) lst)))
       (length lst)))
   (ave-list lst)))

もう誰もついてきてないか....
あと写真を追加しました。

About this Archive

This page is an archive of recent entries in the programming category.

photograph is the previous category.

radiation is the next category.

Find recent content on the main index or look in the archives to find all content.