研究で必要な雑多な知識をごった煮で
プロフィール

termoshtt

Author:termoshtt
大学院生
専攻:流体物理学
Editor: vim
Language: C++,python

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
--/--/-- --:-- スポンサー広告 TB(-) CM(-)
makeは非常に優秀なツールだ。
一度依存関係を書いておきさえすれば、それにしたがって勝手にコンパイルしてくれる。
しかも一つの言語ともいえるような機能を持っている。

例えば変数を持てる。Makefile中では
ARG = value
ARG := value

の2つの代入の形式がある。
ちょっと複雑なことを使用とするとき、両者の違いは重要だ。
違いは右辺に変数が含まれるときに生じる。
前者は右辺に含まれる変数も代入された変数が評価されるときに初めて評価される。
一方後者では、代入時に右辺値が確定される。
C言語でいえば、前者は引数のない関数の定義、あるいは参照変数に近く、後者は通常の手続きにおける代入に対応する。

さらにmakeの機能にinclude文がある。
include sub.mk
とすればsub.mkの中身を今読んでいるMakefileに追加したのち、コンパイルを行ってくれる。

もう一つ、makeには文字列操作に関して非常に強力な組み込みの関数がある。
今回使うのはword,words,wordlistの3つである。
これらはlistの管理を簡単にしてくれる関数である。
list = a b c d
$(word 2,$(list)) # b
$(words $(list)) # 4
$(wordlist 2,3,$(list)) # b c

wordは所定の位置の要素を抜きだし、wordsはlistの長さを返し、wordlistは部分listをつくる。



さて、本題のfor文に取り掛かろう。
種を先にあかしておくと、再帰的にsub.mkを読み込むのである。
幸いにもinclude文は自分自身を読み込むことを拒否しないので、自己再帰的にfor文を構成する。
次のMakefileを見て欲しい。
main.mk:
TARGET = test
LIST = a b c d
all : $(TARGET)
$(TARGET) : subd
touch $(TARGET)
include sub.mk

sub.mk:
VAR := $(word 1,$(LIST))
LIST := $(wordlist 2,$(words $(LIST)),$(LIST))
sub$(VAR):
touch $@
ifneq ($(VAR),) # VARが空でなければ真
include sub.mk
endif

依存関係を解決するだけの簡単なMakefileだが、
制御が自己再帰的になっているので読みにくいかもしれない。
ポイントはsub.mkの2行目のLISTを一つずらすところと、
最後のsub.mkからsub.mkをincludeするところである。
LISTの先頭の値をVARに受け取り、LISTは一つ前につめる。
この変数は次のincludeのときにも引き継がれるので、
LISTが空になるまでsubdの生成方法が検索され続ける。
これによりsubdが4回目のincludeの後に発見され、めでたくtestはコンパイルされるのであった。


。。。とまぁ、for文が出来上がったのだが。
なんに使おうかな?

これを調べている途中で、

LIST = a.c b.c c.c d.c
$(LIST) : %.c : %.o
icpc $< -o $@

のような条件付きルールを書く方法を知り、当初の目的が果たせたので、
このfor文は今回必要ないのであった。
2011/09/07 23:51 Programming TB(0) CM(0)
自動化は素晴らしい。適切に構築された自動化スクリプトは単調な作業からの開放を約束し、人為的ミスを事前に防ぐ。
ということでコンパイル時の依存関係の解決の自動化である。
結局は偉大な先人のあしあとをたどるだけなのだが、
http://d.hatena.ne.jp/ritchey/20070519/1179595462
ちょっとそのままでは問題が生じたので変更点をメモ。

上サイトから拝借した、
%.d: %.c
@set -e; $(CC) -MM $(CPPFLAGS) $< \
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
[ -s $@ ] || rm -f $@

が問題の部分。sedの所が問題で、もしファイル名に/が含まれる場合、それをsedコマンドが間違えて読んでしまうため、"「s」へのオプションが未知です"って怒られる。例えば一つ親のフォルダの.cppが必要なときはファイル名が../some.cppとなり/が含まれてしまう。

解決策1:$*を$(echo $* | sed 's/\//\\\//g')などとして、/を\/に置き換えてやる。こうするとsedは\/を文字の/として認識するのでのぞみの結果が得られる。

これならわざわざlogに残すまでもないことなのだが、その後とあることに気がついた。

解決策2:sedのパターンを区切る文字は「/」以外でも可。
参考HP:http://www.geocities.co.jp/geo_sunisland/filter_sed.html
なので例えば
sed 's%\($*\)\.o[ :]*%\1.o $@ : %g' > $@

とする。こうすれば$*に/が含まれていても問題なく処理できる。

なお、同様のことがvimのコマンドにも使える。つまり
:%s%before%after%g

とできる。これを使えば、基本的に特殊文字をエスケープする必要がなくなる。
使える文字としては、アルファベット[a-zA-Z]は不可能、バックスラッシュ\も不可能。他の文字は可能のようだ。

思っても見なかった知識を得た。
2011/02/16 02:54 Programming TB(0) CM(0)
前回に引き続きNumpyについて。
以下では
A = mat([[1,2,3],[4,5,6],[7,8,9]])
v = mat([1,2,3]).T
とする。

行列要素へのアクセス:
ここは注意が必要。C++のublas::matrix<double>のように
A[i][j]でのアクセスができない。これはちょっと演算子のかたちが変わって、
A[i,j]でアクセスしないといけない。
同じクラスなので当たり前だが、v[i]では要素は取り出せない。

なお、AやvにはメンパにA.A,v.Aが存在し、これはarrayのインスタンスだった。
このメンバに対してはA.A[i][j]のようなアクセスができるので、
array型を想定した関数に投げるときはこれを使うと便利。


2010/12/16 02:16 Programming TB(0) CM(0)
pythonの便利な数学ライブラリ、Numpy。
本家HP:http://numpy.scipy.org/

この中の行列の扱いにはまったのでメモ。
ipython -pylabで起動かもしくは
from numpy import * を想定。
numpyをimportして使うときは適宜読み替えること。

生成法:
A = mat([[1,2,3],[4,5,6],[7,8,9]])
のようにつくる。引数はリストでもタプルでも可。

ベクトルの生成:
v = mat([1,2,3])
で横ベクトルができる。縦ベクトルは
v = mat([[1],[2],[3]])
とすればできるが、
v = mat([1,2,3]).T
のように転置を取るほうが書きやすい。

ベクトルをこのように使うと、行列とベクトルの掛け算
A = mat([[1,2,3],[4,5,6],[7,8,9]])
v = mat([1,2,3]).T
A*v
とかける。
2010/12/16 02:14 Programming TB(0) CM(0)
検索フォーム
ブロとも申請フォーム
QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。