上図のように英字入力を入力ソースとして加える。
するとことえりを削除するための-ボタンが有効になるので、押す。
消える。
機械学習、科学計算、Webアプリ開発、モバイルアプリ開発、開発環境に関する記録
SOFTWARE=$HOME/.software tar xvf ghc-6.8.3-x86_64-unknown-linux.tar.bz2 cd ghc-6.8.3 CC=gcc44 ./configure --prefix=$SOFTWARE/ghc-6.8.3 make install特に問題なくインストールできた。
export PATH=$SOFTWARE/ghc-6.8.3/bin:$PATH cd ../ tar xvf ghc-6.10.4-src.tar.bz2 cd ghc-6.10.4 ./configure --prefix=$SOFTWARE/ghc-6.10.4 --with-gcc=gcc44 make && make installmakeに失敗。bfd.hのところで、#error config.h must be included before this header みたいなエラーがでた。Stackoverflowの投稿によると、autotools?を使っていないためPACKAGEとPACKAGE_NAMEがdefineされておらず怒られているっぽい。とりあえずの解決策として、怒られていたrts/Printer.cの先頭部分に
#define PACKAGE 1 #define PACKAGE_NAME 1を入れて再度makeしたらコンパイルが通った。
export PATH=$SOFTWARE/ghc-6.10.4/bin:$PATH cd ../ tar xvf ghc-7.0.3-src.tar.bz2 cd ghc-7.0.3 ./configure --with-gcc=gcc44 make && make install先ほどと同じbfd.hでこけるので同じ対応をしてビルド成功。
export PATH=$SOFTWARE/ghc-7.0.3/bin:$PATH cd ../ tar xvf haskell-platform-2011.2.0.1.tar.gz cd haskell-platform-2011.2.0.1 ./configure --prefix=$SOFTWARE/haskell-platform --with-gcc=gcc44 make make install問題なく成功。あとは.bashrcなどに以下のようなものを追加すれば良い。インストールの時に使ったファイルや古いGHCは消しても良い(と思う)。
SOFTWARE=$HOME/.software export PATH=$SOFTWARE/haskell-platform/bin:$SOFTWARE/ghc-7.0.3/bin:$PATH
couldn't read caba file xxxx.cabal的なことを言われる。stackoverflowのRichard曰く、cabalファイルのフォーマットが変わってしまい、古いcabalで読めないとのこと。新しいCabalをhttp://hackage.haskell.org/packages/archive/cabal-install/1.16.0.2/cabal-install-1.16.0.2.tar.gzからダウンロードしてREADMEの指示に従いインストールすることで解決ができるとのこと。
wget http://hackage.haskell.org/packages/archive/cabal-install/1.16.0.2/cabal-install-1.16.0.2.tar.gz tar xvf cabal-install-1.16.0.2.tar.gz cd cabal-install-1.16.0.2 chmod +x bootstrap.sh ./bootstrap.sh$HOME/.cabal/binにバイナリができるので、忘れずにパスを通す設定をする。
/home/git/gitlab-shell/bin/gitlab-shell:8: undefined method `require_relative' for main:Object (NoMethodError)どうやらrvmで設定したruby1.9.3が呼ばれていない模様。ユーザーgit向けにrvmはインストール済みでログインするとちゃんと
which ruby /home/git/.rvm/rubies/ruby-1.9.3-p392/bin/rubyとでる。 実はgit cloneは内部的にはSSHでgitユーザーでgitサーバーに接続して、サーバー側の~git/.ssh/authorized_keysに書かれたコマンドを実行するようになっている。そのコマンドは~git/gitlab-shell/bin/gitlab-shellを呼び出す。それがruby >1.9.2以上であることを想定して書かれている。
#! /bin/bash # RVM installed with single-user mode PATH=$PATH:$HOME/.rvm/bin # Add RVM to PATH for scripting [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session as a function # RVM installed with multi-user mode #RVMSH_PATH="/etc/profile.d/rvm.sh" #[[ -s $RVMSH_PATH ]] && source $RVMSH_PATH # Load RVM into a shell session as a function exec /home/git/gitlab-shell/bin/gitlab-shell.real $@
taro$ \curl -L https://get.rvm.io | sudo bash -s stableもしプロキシを使っていてうまく行かなかった場合は、環境変数HTTPS_PROXYをtaroで設定していたら、sudoに環境変数を渡すために-Eオプションをつけます。この後も、ネットワーク問題でハマったら、sudo -Eとしてください。
taro$ \curl -L https://get.rvm.io | sudo -E bash -s stable
taro$ sudo usermod -aG rvm taro
source /etc/profile.d/rvm.sh
taro$ id
taro$ rvm install 1.9.3 taro$ rvm use --default 1.9.3この時点ではbundlerはインストールしない。あとで、ユーザーgitlab(3. System Usersで追加される)だけにインストールする。
taro$ sudo su - gitlab~/.bashrcなどに"source /etc/profile.d/rvm.sh"を追加して再読み込み。
gitlab$ source .bashrcgitlabユーザー固有のgemsetを作る。
gitlab$ rvm user gemsets gitlab$ rvm istall 1.9.3 gitlab$ rvm use --default 1.9.3 gitlab$ rvm gemset create gitlab$ rvm gemset use default gitlab$ rvm gemset install bundler gitlab$ rvm gemset install charlock_holmes --version '0.6.9'DBにはMySQLを使ったので、without postgresでインストール。
gitlab$ cd /home/gitlab/gitlab gitlab$ bundle install --deployment --without development test postgres
taro$ sudo su - gitlab gitlab$ cd gitlab gitlab$ bundle exec rake gitlab:setup RAILS_ENV=productionここでしくじる。execコマンドがないと怒られる。調べると、issueが投稿されてた。Squeeze-backportsリポジトリからredis-serverを入れなおせとのこと。多分RedisServerが古かったのかと思われる。Ubuntu10.04。リポジトリを追加するために、/etc/apt/sources.list.d/squeeze-backports.listというファイルに
deb http://backports.debian.org/debian-backports squeeze-backports main
taro$ sudo apt-get update
taro$ sudo -E apt-key adv --keyserver keyserver.ubuntu.com --recv-keys AED4B06F473041FA taro$ sudo apt-get update taro$ sudo apt-get remove redis-server taro$ sudo apt-get -t squeeze-backports install redis-server
gitlab$ bundle exec rake gitlab:setup RAILS_ENV=production
taro$ sudo su - gitlab gitlab$ cd gitlab gitlab$ bundle exec rake gitlab:env:info RAILS_ENV=production gitlab$ bundle exec rake gitlab:check RAILS_ENV=productionこれで動きました。ローカルではない場合もservernameなどちゃんと設定すれば動きます。 参考: http://d.hatena.ne.jp/hiro_nemu/20120811/1344656084
def numpy_mult3_0_pure(npArr): for r in xrange(npArr.shape[0]): for c in xrange(npArr.shape[1]): if (r + c) % 3 == 0: npArr[r, c] = 0これを次のように呼び出す。
>>> side = 1000 >>> npArr = np.ones((side, side)) >>> numpy_mult3_0_pure(npArr) >>> print npArr結果は、以下。
[[ 0. 1. 1. ..., 1. 1. 0.] [ 1. 1. 0. ..., 1. 0. 1.] [ 1. 0. 1. ..., 0. 1. 1.] ..., [ 1. 1. 0. ..., 1. 0. 1.] [ 1. 0. 1. ..., 0. 1. 1.] [ 0. 1. 1. ..., 1. 1. 0.]]まったく前回のコピペです。
def numpy_mult3_0_weave(npArr): code = """ for(int r = 0; r < NnpArr[0]; r++) { for(int c = 0; c < NnpArr[1]; c++) { if((r + c) % 3 == 0) { NPARR2(r, c) = 0; } } } """ weave.inline(code, ['npArr'])前回やった、N+(変数名), (変数名大文字)+(次元数)のアクセス用マクロ関数を使えば、上のように書けるのです。どのくらい早くなるのか時間を計測してみます。
side = 1000 npArr = np.ones((side, side)) from context_timer import Timer with Timer("Pure"): numpy_mult3_0_pure(npArr) with Timer("Weave"): numpy_mult3_0_weave(npArr)このTimerについてはこちらの記事をご覧ください。出力は以下です。
[Pure] Elapsed: 0.272620201111 [Weave] Elapsed: 0.00578308105469Weaveの方が50倍近く早くなっていることがわかります。こんな感じにPythonコードにC++のコードを書くことで高速化することができます。
import numpy as np # numpyのインポート # 乱数配列の生成 2行3列 a = np.random.rand(2,3) b = np.random.rand(2,3) # 各要素ごとの掛け算 Matlabだと a .* b c = a * b # 行列としての掛け算 Matlabだと a' * b d = np.dot(a.T, b) # C = A^T * B (Cは2行2列になります) # 固有値分解 [E, V] = np.linalg.eig(d)Matlabでできることはほぼ全部できます。しかも、無料で。このページは参考になります。Numpy for Matlab Users
def numpy_mult3_0_pure(npArr): for r in xrange(npArr.shape[0]): for c in xrange(npArr.shape[1]): if (r + c) % 3 == 0: npArr[r, c] = 0これを次のように呼び出す。
>>> side = 1000 >>> npArr = np.ones((side, side)) >>> numpy_mult3_0_pure(npArr) >>> print npArr結果は、以下。
[[ 0. 1. 1. ..., 1. 1. 0.] [ 1. 1. 0. ..., 1. 0. 1.] [ 1. 0. 1. ..., 0. 1. 1.] ..., [ 1. 1. 0. ..., 1. 0. 1.] [ 1. 0. 1. ..., 0. 1. 1.] [ 0. 1. 1. ..., 1. 1. 0.]]時間を計測すると、0.384463787079[秒]でした。 これをWeaveを使ってC化して高速化します。この例に移る前にNumpyをWeaveに使う場合の基本から見ていきます。 weave.inlineはPython変数を渡すと自動的にC内で適当な型に変換してくれます(converterを指定することも可能)。Numpyのndarrayを渡した場合も自動で色々と変換を施してくれます。次の例を見てみます。
def numpy_converted_vars(): npArr = np.zeros((2, 3, 4), dtype=np.uint16) npArr[1, 1, 3] = 1 print '(py) ndim:', npArr.ndim print '(py) shape:', npArr.shape print '(py) strides:', npArr.strides code = """ // Number of dimension std::cout << "ndim: " << DnpArr << std::endl; // Shape std::cout << "shape:"; for (int i = 0; i < DnpArr; i++) std::cout << " " << NnpArr[i]; std::cout << std::endl; // Strides std::cout << "strides:"; for (int i = 0; i < DnpArr; i++) std::cout << " " << SnpArr[i]; std::cout << std::endl; // Access to data as a three dimensional array std::cout << "npArr[1, 1, 3]: " << NPARR3(1, 1, 3) << std::endl; """ weave.inline(code, [u'npArr'])このメソッド内では、まず2×3×4の形のすべての要素が0の3次元配列を作ります。確認の為に[1,1,3]の要素だけ1を代入しておきます。 データ型がuint16=2[bytes]で、3次元、C-contiguousのメモリ上のデータ配置で、2 * 3 * 4の形なので、上の3つのprintの結果は
(py) ndim: 3 (py) shape: (2, 3, 4) (py) strides: (24, 8, 2)となります。stridesのところとかよくわからない人はこの画像を見て理解するかググってください。
PyArrayObject* npArr_array = convert_to_numpy(py_npArr,"npArr");NumpyのC APIについては各自ぐぐって欲しいのですが、PyArrayObject構造体のメンバにstridesなどがあるので、
npy_intp* NnpArr = npArr_array->dimensions; npy_intp* SnpArr = npArr_array->strides; int DnpArr = npArr_array->nd;で値を取り出してくれています。inlineコードのndim, shape, stridesの出力は次のようになり、python側での出力と一致しています。
ndim: 3 shape: 2 3 4 strides: 24 8 2肝心のnpArrという名前は以下のように配列のデータへの先頭ポインタのアドレスを取り出したものとして宣言しています。
double* npArr = (double*) npArr_array->data;一次元配列としてアクセスする場合はnpArr[0]などとアクセスすれば値を取り出せますが、この例では3次元配列なので、stridesを使って要素にアクセス必要があります。たとえばnpArr[i, j, k]にアクセスしたい場合は、以下のようにする必要があります(PyArrayObject*->dataはchar*型)。
*((double*)(npArr_array->data + (i * SnpArr[0] + j * SnpArr[1] + k * SnpArr[2])))しかし、これはめんどくさい。実はこれをやるためのマクロ関数を最高4次元配列の場合まで定義してくれています。
#define NPARR1(i) (*((double*)(npArr_array->data + (i)*SnpArr[0]))) #define NPARR2(i,j) (*((double*)(npArr_array->data + (i)*SnpArr[0] + (j)*SnpArr[1]))) #define NPARR3(i,j,k) (*((double*)(npArr_array->data + (i)*SnpArr[0] + (j)*SnpArr[1] + (k)*SnpArr[2]))) #define NPARR4(i,j,k,l) (*((double*)(npArr_array->data + (i)*SnpArr[0] + (j)*SnpArr[1] + (k)*SnpArr[2] + (l)*SnpArr[3])3次元配列の場合はnpArrの名前を大文字にして後ろに3をつけた名前が付けられていますので、上のようにpython側でnpArr[1,1,3]=1で変更した値にNPARR3(1,1,3)でアクセスできています。
npArr[1, 1, 3]: 1今回はNumpyのweave.inlineへの受け渡しの基本を紹介しました。次回に実際計算してみます。