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

投稿

多項式 in Rust

環 R 上の多項式 R[x] とは, 有限個の R の元の組の全体 R[x] に以下の代数構造を入れたもの. 多項式 p(x) in R[x] と元 r in R の和 p(x) + r 多項式 p(x), q(x) in R[x] の和 p(x) q(x) 多項式 p(x) in R[x] と元 r in R の積 r p(x) 多項式 p(x), q(x) in R[x] の和 p(x) + q(x) 多項式 p(x) in R[x] に元 r in R を代入する: p(r) 多項式 p(x) in R[x] に多項式 q in R[x] を代入する: f(q(x)) R[x] はこの和と積に関して環をなす. より詳細な多項式環の性質については wikipedia 参照. これを Rust で実装する. ジェネリクスとトレイト境界のよい練習になった. 特に多項式への代入として環 R の元と多項式 R[x] のどちらをも許す部分で手間取った. 若干 clone を使い過ぎた気もするけど, 他にどうしようもなさそう. /// 多項式を表す構造体. #[derive(Clone, Debug, PartialEq, Eq)] pub struct Polynomial<T> {     coef: Vec<T>, } extern crate num_traits; use num_traits::Zero; use std::ops::{Add, Sub, Neg, Mul}; impl<T> Polynomial<T> where T: Clone + Zero + PartialEq {     /// 係数の配列から新しく多項式を生成する. 係数はタプルでもベクトルでもよい.     /// 係数 [ a_0, a_1, ... ] の $n$ 番目の要素が $n$ 次項の係数となる.     ///     /// 引数の配列が要素を持たない可能性を考慮し, `Polynomial::new` 関数の戻り値  ...

Rust でテキストファイルのインデントを整形

インデントが不揃いなテキストファイルを整形したくなったので Rust コードを書いたお話。 いつかまた使えそうだけど保管するのが面倒なので、ここに放流しておく。 use std::fs::File; use std::io::{BufReader, BufRead, BufWriter, Write}; fn main() { // ファイル読み込み let file = File::open("input.md").unwrap(); let mut reader = BufReader::new(file); // 出力ファイルの確保 let file = File::create("output.md").unwrap(); let mut writer = BufWriter::new(file); // メインループ (各行ごとに処理) loop { // 一行ずつ読み出す let mut buf = String::new(); let num_bytes = reader.read_line(&mut buf).unwrap(); if num_bytes == 0 { // EOF に到達したらループを抜ける break; } else { // そうでないとき, 整形してファイルに書き出す. let output = format_text( buf ); writer.write(output.as_bytes()).unwrap(); } } } // 先頭が " " のとき 4 文字インデントに整形して返し, // そうでなければ入力を返す関数. fn format_text( buf: String ) -> String { if buf.chars().next() == Some(' ') { format!(...

Python 3.7.2 のソースビルド

Debian 9.7 2019-02-04 依存パッケージの導入 build-essential は当然として sudo apt install libreadline-dev libncursesw5-dev libssl-dev libsqlite3-dev libgdbm-dev libbz2-dev liblzma-dev zlib1g-dev uuid-dev libffi-dev libdb-dev tk-dev コンパイル ユーザー環境に pip つきでインストールする例. ./configure --prefix=/home/name/.local --with-ensurepip --enable-optimizations make -j4 make altinstall ただし手元の WSL 環境ではなぜかいくつかのテスト (signal 等) が終了しない (ファイアウォールのせいかと思うけれども切っても失敗した) ので, その場合フル最適化は諦めて --with-lto でリンク時の最適化だけ行う.

Emacs 26.1のソースビルド

環境: Debian 9.5 stretch x86_64 インストール先をホームディレクトリ内にすればビルド自体には管理者権限は不要. ただし必要なライブラリをインストールするためにsudoを使った. ソースのダウンロード: http://ftp.jaist.ac.jp/pub/GNU/emacs/ 依存ライブラリの導入 他に足りないライブラリがある場合は次節でconfigureしたときに教えてくれるから適宜インストールする. 手元の環境ではlibncurses5-devとlibgnutls28-devが足りないと怒られたので sudo apt install libgnutls28-dev libncurses5-dev を実行. 最近はもっぱらCUI版しか使ってないからGUIは放棄したけど, GUI版をインストールする場合は下記参照. インストール 別段難しいことはなく ./configure --prefix=/home/name/.local/ --without-x make make install でオッケー. 10分もかからなかった. これでインストール時に指定したディレクトリ (上の例だと/home/name/.local/bin) に実行ファイルが生成されるから, 普通に実行すればいい. GUI版のインストール フル機能のGUI版には追加で libgtk-3-dev , libtiff5-dev , libgif-dev , libgd-dev が必要. 適宜インストールしてconfigure時に without-x オプションを外せばよい. ただしGTK+3にディスク容量190MBくらい必要. emacsの実行ファイル自体は49MB->54MBでGUIつけてもそんなに大きくなる訳ではない.

Emacs on WSLのクリップボード

問題 手元の環境 (Debian 9.5 on Win10 1803) だけかもしれないけれども、cmdのコピペ機能(つまり右クリック)を使って Emacs on WSL にペーストしようとすると、非常に重い、とてつもなく思い。短文ならともかく500行とかコピペしようとすると数分固まる。20行くらいでも時間がかかる。そのうえ、インデントが妙なことになる。最悪。 解決策 PowerShellの Get-Clipboard コマンドを使えば、Win10のクリップボードの中身を取り出せる。そこで、PowerShellコマンドを呼び出して出力をバッファに書き込むようにすればいい。 reddit に書いてあったスクリプトを修正したものがこちら。 (defun wsl-paste () (interactive) (insert (shell-command-to-string "powershell.exe -command 'Get-Clipboard'"))) (global-set-key (kbd "C-c C-v") 'wsl-paste) これで C-c C-v でWin10のクリップボードからペーストする。 いまいち検証しきれてないけれども、 (setq x-select-enable-clipboard t) 設定と相性が悪い模様。このところGUIはほぼ使わなくなってたので、こちらを消すことで対処した。 コメント これで爆速でペーストできるようになって一件落着。VS Codeに移行するかと本気で考えたけど、やっぱりEmacsのが使いやすい。

Rustで科学技術計算 (4) Vec型の操作まとめ

https://doc.rust-lang.org/std/vec/struct.Vec.html 新しいベクタの作り方 let mut vec: Vec<f64> = Vec::new(); let mut vec: Vec<f64> = Vec::with_capacity(1024); let mut vec: Vec<f64> = vec![ 0., 1., 2., 3. ]; let mut vec: Vec<f64> = vec![ 0.; 16 ]; let mut vec = (0..16).map(|x| x as f64).collect::<Vec<f64>>(); // 連続する数字を要素とするベクタをイテレータを経由して生成 // mapの部分をいじるか, イテレータアダプタを使えばもっといろいろなことができる // https://rust-lang-ja.github.io/the-rust-programming-language-ja/1.6/book/iterators.html 要素の挿入 vec.push( 3.14 ); // ベクタの最後に要素3.14を追加する vec.insert( 2, 3.14 ); // vec[2] = 3.14となるように要素を挿入し, その後ろの要素を一個ずつずらす // メソッドinsert( index, element ) はindex > vec.len()のときパニックを引き起こす vec.append( vec2 ); // ふたつのベクタを連結する (Pythonでいうリストのextend) 要素の除去 vec.remove(4); // 4番目の要素vec[3]を除去し, 後ろの要素を一個ずつ詰める vec.swap_remove(4); //4番目の要素vec[3]を除去し, 最後の要素vec[vec.len()-1]をvec[3]に入れる // メソッドswap_removeはO(1)で動作するのに対して, removeの方が時間がかかる let x: f64 = vec.pop(); // 最後の要素を取り出し, それを返す (従ってこの処理によりvec.len()...

制限三体問題シミュレータ by Rust

// 制限三体問題シミュレータ // // 座標系は連星系の重心を原点とし, 平均運動nで回転する系. // 従ってe=0のとき連星は静止するが, e \neq 0も計算できる. // 連星の長半径aと平均運動nが1となる単位系を用いる. // // 必要なパラメータは // 連星の質量比 q = M_2 / M_1 // 連星の離心率 e // 計算終了時刻 t_end // と初期条件 x: [f64;3], v: [f64;3] の計九つ. 上ふたつを // コマンドライン引数としてセットすることもできる. // // use std::env; // コマンドライン引数を使用する場合はコメントアウトを外す use std::f64::consts::PI; fn main() { // パラメータの設定 // let args: Vec = env::args().collect(); // let q: f64 = args[1].parse:: ().unwrap(); // let e: f64 = args[1].parse:: ().unwrap(); let q: f64 = 0.01; let e: f64 = 0.; let t_end: f64 = 128.*PI; // 初期条件 let mut t: f64 = 0.; let mut x: [f64;3] = [ 0.5-q/(1.+q), 3f64.sqrt()/2., 0. ]; let mut v: [f64;3] = [ 0., 0., 0. ]; println!("{} {} {} {}", t, x[0], x[1], x[2] ); // アウトプット間隔 let t_output: f64 = 0.0625; let mut t_record: f64 = t_output; // 数値積分 while t = t_record { println!("{} {} {} {}", t, x[0], x[1], x[2] ); t_record += t_output; }; }; } fn true_anomaly ( t: f64, ...

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が使用可能. ※向きを指定する前にスペースを入れるとエラーになる. 関連ページ...

物理学のためのTeX・プログラミング環境 for Windows (2017年4月版)

自分用メモとして, 2017年4月27日時点での手元のPC環境を記録しておきます. この環境を整えてからひと月も経っていないので, 今後いろいろと変更する可能性がありますが. 主としてTeXによる文書作成, たまにC言語/Fortran 90によるちょっとした数値計算を想定しています. 要するに, Bash on Windows万歳! という記事です.

一般相対論の教科書

手当たり次第にGRの教科書を集めたリストです. なんとなく難易度順だけどかなり適当. 須藤靖「一般相対論入門」日本評論社 (2005) https://www.amazon.co.jp/dp/4535784221 須藤靖「もうひとつの一般相対論入門」日本評論社 (2010) https://www.amazon.co.jp/dp/4535786348 内山龍雄「相対性理論」岩波書店 (1987) https://www.amazon.co.jp/dp/4000077481 藤井保憲「時空と重力」産業図書 (1979) https://www.amazon.co.jp/dp/4782811020 P.A.M.ディラック「一般相対性理論」ちくま学芸文庫 (2005) https://www.amazon.co.jp/dp/4480089500 J.B.Hartle "Gravity: An Introduction to Einstein's General Relativity" Benjamin Cummings (2002)] https://www.amazon.co.jp/dp/0805386629 Ray D'Inverno "Introducing Einstein's Relativity" Clarendon Press (1992) https://www.amazon.co.jp/dp/0198596537 内山龍雄「一般相対性理論」裳華房 (1978) https://www.amazon.co.jp/dp/4785323159 B.シュッツ「相対論入門」丸善 (2010) https://www.amazon.co.jp/dp/4621083090 ランダウ&リフシッツ「場の古典論」東京図書 (1978) https://www.amazon.co.jp/dp/448901161X S.Weinberg "Gravitation and Cosmology" Wiley (1972) https://www.amazon.co.jp/dp/0471925...

源ノ明朝/源ノ角ゴシックをLuaLaTeXで使用する (Windows)

源ノ明朝 (Source Han Serif), 源ノ角ゴシック (Source Han Sans) はAdobeとGoogleが作成したCJKフォントで, オープンソースフォントとして公開されています (ライセンスはSIL Open Source License 1.1). 以下では, LuaTeXエンジンでこのフォントを (日本語で) 使用する方法を説明します. あるいは, otfファイルがダウンロードできれば, どのようなフォントにも適用可能です (PDFにフォント埋め込みすることに関してライセンスに注意が必要ですが). Windows10を前提としますが, 他の環境 (Linux/Mac) でもほぼ同じ方法で導入できるんじゃないでしょうか. 使用したのはTeX Live 2016 (LuaTeX-0.95) です.