スキップしてメイン コンテンツに移動

投稿

Rustで科学計算 (3) 関数を別ファイルで定義する

main.rcの中ですべての関数を定義しようとすると, 往々にしてだらだらと長くなって可読性が損なわれます. そのような場合, Rustでは別ファイルを用意してその中で関数を定義することができます (関数のモジュール化). ここではメイン関数は ./src/main.rc に含まれるものとします. 関数を定義する別ファイルは ./src/sample.rc とし, その中で定義された関数は main.rc 中で mod sample; とした上で sample::(関数名) と呼び出すことができます. ただしその際に ./src/sample 中の関数には pub 宣言が必要です. ./src/main.rc の記述 mod sample; fn main() { let mut x: f64 = 1.; x = sample::times2( x ); println!("{}", x ); } ./src/sample.rc の記述 pub fn times2( x: f64 ) -> f64 { 2. * x } なお, この別ファイルの名称は ./src/sample/mod.rs とすることもできます. この方が別ファイルを階層的に配置できるので, 大規模なプロジェクトでは有利かもしれません. 詳細は参考文献を見てください. 参考文献 クレートとモジュール - The Book

Rustで科学計算 (2) Vec型

1. 配列とVec型 Rustの配列は, その長さが コンパイル時に 既に固定されている必要があります. 従って, 最初から長さのわかっているベクトルを扱う場合には, 例えばその長さNを const N: usize = 128; とコンパイル時定数として導入することで, 素直に配列をつくることができます. const N: usize = 128; fn main() { let x: [ f64; N ] = [ 0.; N ]; } 一方, コンパイル時には長さが決まっておらず実行時に動的に決定される場合, または実行時にコマンドライン引数として長さを与えたい場合, コンパイル時には配列の長さが決まっていない訳なので, それを配列として実現することはできません. そのような状況ではVec型 (Vectorとも) を利用しましょう. 2. Vec型の宣言と要素の追加, 参照, 削除 例えば要素が既知のi32型を要素とするVec型変数 a は let a: Vec<i32> = vec![ 0, 1, 2, 3, 4 ]; により宣言できます. あるいは, f64型を要素として持つことのできる空のVec型変数 v を宣言するには let mut v: Vec<f64> = Vec::new(); とします. いま変数 v には何も要素がないので, そこに要素を追加するには v.push(0.0) とすればよいです. 要素をpushするためには変数がmutableであることが必要です. また, Vectorの要素の型はすべて共通でなければなりません. なお, あらかじめvectorの要素数が, 例えば上限128と見当がついているのならば let mut v: Vec<f64> = Vec::with_capacity(128); とした方が高速に動作します. もちろんこの場合でも128を超えて要素を追加することは可能です. Vector v の要素の値は配列と同じく v[i] によりアクセスできます. 要素数がNのとき, 引数 i は0からN-1までの値を取り, その範囲外の要素にアクセスしようとするとpanicが引き起こされます. vector v の i 番目の要素を削除したい...

matplotlib.histのnormedが変

以下の内容はPython 3.5.2 + matplotlib 1.5.1およびPython 3.6.2 + matplotlib 2.0.2で検証した. 作業日は2017年10月22日, 前者はUbuntu 16.04 on Win10 (WSL), 後者はDebian 8.9 (Anaconda). 規格化したいのにできない なにか数値の列 data があったとして, そのヒストグラムをmatplotlibでプロットしたいとする. 普通に plt.hist( data ) とすると, これは縦軸が各bin内に入るデータ点が何個あるかを表すことになる. これをデータ総数 len(data) で規格化したプロットにしようと思って plt.hist( data, normed=True ) または normed=1 とかやっちゃうと, 思った通りのアウトプットにならずに頭を傾げることになる. 例えば: import numpy as np import matplotlib.pyplot as plt data = np.random.normal(0,0.1,1000) weights = np.ones(len(data))/len(data) plt.hist( data, weights=weights ) plt.show() アウトプットは で, 縦軸が1を超えるとか, 意味がわからない. 原因 matplotlibのドキュメント を見ても何も書いてない. これは numpyのドキュメント に答えが書いてあるからで, 要するに normed オプションは事実上 density オプションと等しく, これは縦軸を確率分布関数と思って規格化するオプションである, と. 従って, normed=True オプションを指定すると, binの 面積 が1に規格化されることになる. いま欲しいものは値の 総和 が1に規格化されたアウトプットなのだから, binの幅が1でない限り, 欲しい結果は得られない. 対策 代わりに weights オプションを指定すればこの問題は解決できる. これは data の1つの値の重みを指定するパラメー...

Rustで科学計算 (1) データのasciiファイル書き出し

結論 use std::io::prelude::*; use std::fs::File; fn main() { /* この辺で計算 */ let s = format!("filename_{:03}.txt", i ); let mut buffer = File::create(s).unwrap(); write!(buffer, "{:.04} {:.04} {:.04} {:.04}\n", t, x, y, z ); } ファイルの書き出し 計算結果をファイルに書き出すためには, s をファイル名として let mut buffer = File::create(s).unwrap(); により出力ファイルを用意する. 既に同名のファイルが存在する場合には上書きされる (もとのデータは消去される). あとは write!(buffer, 文字列) により用意したバッファーに任意に書き込んでいけばよい. 本当は書き出し失敗用のエラーに対処するようにコードを書く必要がある (し, 上の例だとコンパイル時に警告される) が, 個人使用する上では必要性を感じないので, とりあえず放置してある. コードの可読性の方が大事. 数値出力のフォーマット 整数型の場合, "{}", i とかしておけばよい. 桁数をそろえてゼロ埋めするには, 例えば "{:04}", i で4桁になる. 実数型の場合, "{:.04}", t で小数点以下4桁まで. 指数表記は "{:e}" とか "{:.03e}" みたいな感じ.

gnuplotが使いたい! - BoWにGUIを導入

Bash on Windows (以下BoW) は事実上CUIのみのUbuntuなので, GUIアプリは使えない訳です. 大抵はそれで困らないけども, 科学計算の文脈では計算結果をgnuplotなりPythonなりでグラフにしたいので, フラストレーションが溜まります. それを解決する話. 1. とりあえずGUIを使えるようにする 1. VcXsrvをインストール: https://sourceforge.net/projects/vcxsrv/ からインストーラを落としてきて, いつも通り進めるだけです. 2. VcXsrvを起動 (いろいろ聞かれるかもしれませんがデフォルトでいいです) 3. BoWを起動して次のコマンドを実行 $ export DISPLAY=localhost:0.0 2. gnuplotでグラフ描画 以下の操作は上に続けて行ってください (BoWを再起動した場合は上の3をもう一度実行する必要があります. 第3節参照). 1. gnuplotをインストール $ sudo apt install gnuplot5 ※単なるgnuplotをインストールするとgnuplot 4.6が入りますが, gnuplot 5.0を使いましょう. 2. gnuplotを起動 $ gnuplot 3. グラフを描いてみる > plot sin(x) 4. 念のため. gnuplotを抜けてbashに戻るには > q または quit または exit を実行します. 5. デフォルトのターミナルをQtからwxtに変更する方法. まずgnuplotを起動した状態で > show loadpath を実行してgnuplotrcの場所を確認します. 私の場合, /usr/share/gnuplot5/gnuplot/5.0 でした. そこで (gnuplotを抜けてから) このディレクトリに移動すると, gnuplotrcが見つかります. $ cd /usr/share/gnuplot5/gnuplot/5.0 $ ls gnuplotrc ... (他は省略しました) そこで任意のエディタでこのファイルを開き, 任意の行 (最下段に加えるのがわかりやすいと...

UbuntuのPDF編集ツールの使い方まとめ

PDFtkやpoppler-utilsに含まれるツールを使ってPDFを編集するコマンドのまとめです. 0. インストール sudo apt install pdftk sudo apt install poppler-utils UbuntuあるいはBash on Windowsならaptコマンドで一発. 1. PDFの文書情報の表示 pdfinfo (ファイル名) 2. PDFの分割と結合 pdftk (入力ファイル) cat (ページの指定) output (出力ファイル) ページ数の指定は1-12 14-endみたいな形で書けばよい. 入力ファイルを複数指定してページ数の指定を省略すればPDFの結合ができる. 3. PDFをJPEG/PNGに変換 pdftoppm [オプション] (入力ファイル名) (出力ファイル名の接頭辞) JPEGが欲しい場合-jpegを, PNGが欲しい場合-pngをオプションに指定する. デフォルトの解像度はDPI150で粗すぎるのでオプションで-r 300ないし-r 600を指定すべき. 白黒画像にしたい場合は-monoないし-grayを指定 (個人的には-grayのが好み). 複数ページのPDFを変換すると, 出力ファイルは (出力ファイル名の接頭辞)-1.jpg (出力ファイル名の接頭辞)-2.jpg みたいな形で生成される. 4. PDFからテキストを抽出 pdftotext (入力ファイル名) (出力ファイル名) 出力ファイルの文字コードはUTF-8, 改行コードはLF. 出力ファイル名は省略可能. 5. PDFから画像を抽出 pdfimages [オプション] (入力ファイル名) (出力ファイル名の接頭辞) オプションについて: -pngでPNG, -jでJPEG, -tiffでTIFF形式で出力される (オプションなしだとPPM形式) 6. PDFを回転 pdftk (入力ファイル名) cat 1-end(向き) output (出力ファイル名) 向きとしてはleft, right, downまたはnorth, east, west, southが使用可能. ※向きを指定する前にスペースを入れるとエラーになる. 関連ページ...