Rで式量計算

ライブラリを使わずに

Rでデータ処理をしていたのだが、化学式の式量を計算する必要がある。以前はstringrというライブラリを使って計算するプログラムを書いたが、ライブラリのインストールが面倒だということで、ライブラリを使わずに式量を計算するプログラムを書いてみた。

fw<-function(fml){
 aw<-read.table("formula.dat",row.names=1)
 en<-gregexpr("([A-Z][a-z]?)([0-9.]*)",fml,perl=TRUE)[[1]]
 cs<-attr(en,"capture.start")
 cl<-attr(en,"capture.length")
 sum(apply( matrix(substring(fml,cs,cs+cl-1),,2),1,
   function(x) aw[x[1],]*ifelse(x[2]=="",1,as.numeric(x[2])) ))
}

以前書いたものとあまり変わらないが、attrを使ってキャプチャした文字列の場所を変数に入れて、substringで文字列を取り出している。substrを使うと、fmlを複数指定しないといけないので、一括で文字列を取り出す時には、substringの方が便利である。あとは、元素と数を行列の形にして、applyで掛け算をして、sumで足し合わせている。もう少し短く書けそうな気はするけど。

Read more...

原子形状因子

atomic form factor using R

使っているdebianで何気なく

aptitude search xray

としてみたら、

libxray-absorption-perl
libxray-scattering-perl
libxray-spacegroup-perl
python-aws-xray-sdk
python3-aws-xray-sdk

というパッケージが出てきた。二番目と三番目に興味を惹かれたが、まずは二番目をインストールしてみた。すると、/usr/share/perl5/Xray/Scattering/に原子形状を求めるperlスクリプトが入ったので、これをRに移植することにした。そこにあるcromann.dbから係数を読み込んでいるようだが、これをRで読めるようにするために、yaml形式に変更した。libyaml-perlとr-cran-yamlをインストールして、

use strict;
use Storable;
my $r_cromann = retrieve( "/usr/share/perl5/Xray/Scattering/cromann.db" );
use YAML ();
print YAML::Dump($r_cromann);
というスクリプトを実行して、その出力をcromann.yamlに入れた。後で分かったことだが、窒素NとイットリウムYはそのままではうまく動かないので、"n"と"y"に変える必要がある。そして、Rで
library("yaml")
crom<-yaml.load_file("cromann.yaml")
#s = sin(theta)/lambda, s = q/4/pi
f0 <- function(sym,s){ #atomic form factor
 cef<-crom[[tolower(sym)]]
 sapply(s^2,function(ss) sum( cef[1:4*2-1]*exp(-1*ss*cef[1:4*2]) ) + cef[9] ) }

と関数を定義した。ここで、sapplyを使っているのは、sとしてベクトルを与えても動くようにするためにである。これで、

for(ele in c("H","He","Li","Be","B","C","N","O","F","Ne")){
plot(0:100/4,f0(ele,0:100/4/4/pi),type='l',ylim=c(0,10))
par(new=TRUE)}

などとすると、原子形状因子をプロットできるようになった。

Read more...

MacでLinux

古いmac book airにLinuxを入れることにした。

ubuntuかdebianか迷ったが、手元にあったUSBメモリが2Gで、普通のubuntuが2.6Gだったので、まずはDebianを試してみることにした。2Gに収まるDebianとして、debian 10.6.0 xfceを選択した。

sudo cp debian-10.6.0-amd64-xfce-CD-1.iso /dev/sda

でUSBに書き込む。USBを挿して、optionを押しながら電源ボタンを押して離すと、USBから起動できるようになる。wifiがうまく認識できないようだが気にせずに進む。パーティションの選択では、recoveryを残して、custumにインストールした。日本語を選択したら、文字化けした。ほとんどのコメントが読めないし、wifiが認識できていないので、一旦あきらめて、ubuntuに挑戦することにした。

ubuntuにはいくつかのFlavoursがある。Budgieというのが新しくできたことを発見した。やはりlubuntuが一番軽いようである。しかし、lubuntuのサイトには20.04が無い。探してみたら、ubuntuのサイトにはあったので、これをダウンロードした。サイズはUSBメモリに入る1.7Gだった。Debianのパーティションを入れ替える形でインストールをしたが、キーボードモデルはApple Aluminium (JIS)の日本語 (Macintosh)を選択すると良いらしい。インストールは無事に終了して、こんどは文字化けも無いし、wifiも認識している。

少しmacらしくしたかったので、budgie-desktopを入れることにした。taskselを入れてから、それを使ってBudgie Desktopを入れると、少しmacっぽい見た目と操作になった。日本語入力がうまく行っていなかったので、fcitx-mozcを入れて少しいじったら無事に入力できるようになった。lubuntuとbudgieが混在してフォルダの構造が汚くなった気がしたので、ubuntu budgieのisoを調べたら2.4Gあったので、USBメモリに入らないので、今回は見送ることにした。

しかし、バックスラッシュを打とうとすると円マークになってしまうことに気がついて、いろいろといじっていたら、カタカナしか入力出来なくなってしまった。ログイン時にもカタカナしか打てないようで、入れなくなった。外付けのUSBキーボードをつなぐと英数字を打てるようになるが、これではどうしょうもないので、別のインストール方法を試すことに。

ubuntu20.04のminimal install用のisoを探したら、ここで見つけた。一度目のインストールではgrubがうまく行かなかったりして、grubのプロンプトからなんとかログインして、grub設定をやり直したが、直らない。二度目のインストールでは、DHCPがうまく行かないことが多く諦めた。

というわけで、もう一度lubuntu+budgieで入れ直して、キーボードの問題をいじっていたら、カタカナ問題の原因の一端を見つけた。fcitxには、「キーボード-日本語(Macintosh)」と「Mozc」を入れていたのだが、前者を入れるとカタカナしか打てなくなる。これを「キーボード-日本語」にすると、英数字が打てるようになった。また、バックスラッシュが打てない問題は、/usr/share/X11/xkb/symbols/macintosh_vndr/jpのyenをbackslashに変えることで対応した。

他にも不具合が出るかも知れないけど、しばらく様子をみてみよう。

Read more...

コマンドラインで圧縮

zipとrar

通常、ファイルを圧縮するのには、zipを使っている。コマンドラインからは、

zip temp.zip *.*

などとすれば良い。 パスワードをつけて圧縮しようと思い、zipよりもrarの方がパスワードの解析がされにくいと思ったので、rarを使ってみることにした。rarの場合には、ファイルの追加を指定するためにaを付けて、

rar a -hpPASSWORD temp.rar *.*
という感じで実行する。
Read more...

raspberry piの故障

故障の原因究明
測定に使っているraspberry piが動かなくなったと言われたので、原因を調べてみた。これまで、raspberry piは何台も使って来たが、その故障の多くがsdの問題だった。まだ本体が壊れたところには遭遇していないので、今回も本体以外の部分に原因があるのではと予想していた。 ログイン画面のところで、キーボードが打てなくなるということで、まずはキーボードを疑ったが、実はキーボードをつないでいるusbのハブが壊れていることが分かった。ハブを交換したら無事に直ったようだ。 測定用ということで、usbtmcとusb-gpibとusb-serialなどを使っていて、これにマウスとキーボードを加えると、usbポートの増設が必要で、そのためにusbハブを使用している。しかし、ハブを通すと問題がおきる場合もあるので、比較的負荷の軽いマウスとキーボードとusb-serialをハブを介して使っている。相性問題が生じるかと心配したが、今回は問題が無かったようだ。

Read more...

debianにg77

fortranのライブラリ

Debian busterで古いプログラムを動かそうと思ったら、libg2c.so.0が無いと言われた。調べてみたら、これはg77のライブラリらしい。しかし、今のdebianではg77はgfortranに置き換えられてしまっている。昔のubuntuのdebを使うと動かせるらしいので、試してみた。http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-3.4/から必要なdebファイルを取ってきて、以下のようにインストールする。

dpkg -i --force-depends cpp-3.4_3.4.6-6ubuntu5_i386.deb gcc-3.4_3.4.6-6ubuntu5_i386.deb gcc-3.4-base_3.4.6-6ubuntu5_i386.deb libg2c0_3.4.6-6ubuntu5_i386.deb libg2c0-dev_3.4.6-6ubuntu5_i386.deb g77-3.4_3.4.6-6ubuntu5_i386.deb
ln -s /usr/bin/g77-3.4 /usr/bin/g77

必要で無い操作もある気がするけど、とりあえず動いたので、それなりうまく行っている。しかし、upgradeするときには、文句を言われるので、以下のように、一旦uninstallしてからupgradeする必要がある。

dpkg -r cpp-3.4:i386 gcc-3.4:i386 gcc-3.4-base:i386 libg2c0:i386 libg2c0-dev:i386 g77-3.4:i386
Read more...

Rでsocket

Rとrubyの比較

LANを介してデータのやり取りをする必要があったので、rubyのsocketを使って、必要なプログラムを書いた。通常は一つのサーバーに複数のクライアントが何回も接続することが想定されるので、threadを使うことが多い。しかし、今回は一つのクライアントが一度だけ接続するというケースだったので、threadが必要が無いことに気がついたので、以下のように単純化した。

serv=TCPServer.open(2051)
cl=serv.accept
str=cl.readpartial(10)
cl.close
serv.close

acceptでclientが接続するまで待ってくれる。クライアント側は、TCPSocket.open("localhost",2051)で接続して、読み書きすれば良い。

ふと、これをRでできないかを考えてみた。クライアント側は、以下のように、socketを開けて、読み書きすれば良い。

tcp<-socketConnection("localhost",2051)
write("123",tcp)
cat("123",file=tcp)
readLines(tcp,n=1)
close(tcp)

サーバーもやってみたら簡単だった。

tcp<-socketConnection(port=2051,server=TRUE)
close(tcp)

定義するときに、クライアントが接続するまで待ってくれるので、クライアント側とほとんど同じ書き方で、サーバー側のプログラムも書けてしまう。ただ、複数のクライアントが接続する場合は面倒そうだ。

Rでrubyと同様にsocketを用いた通信ができそうだが、違いがある。rubyではreadpartialでは、データが来るまで待ってくれるが、RだとreadBinとかでは、データがなかったら読まずに終わってしまう。特定の長さのデータを読み込みたいときには、rubyではread(length)とすれば良いが、Rでは長さを指定しても、それよりも短いデータしか読み込まない可能性があるので、読み込んだデータを数えて、特定の長さになるまで繰り返さないといけない。これは面倒だが、何か楽に固定長を読み込む方法は無いのかな。

Read more...

Condon-Shortley係数

平方根の計算

球面調和関数を取り扱っていると、Condon-Shortley係数とかGaunt係数というものを使うことがある。この値は表になっているのだが、maximaを使って行列の形に表すプログラムを書いてみた。

load(clebsch_gordan);
ck(k,l1,m1,l2,m2):= rootscontract((-1)^m1*sqrt(2*l1+1)*sqrt(2*l2+1)*wigner_3j(l1,l2,k,0,0,0)*wigner_3j(l1,l2,k,-m1,m2,m1-m2))$
mck(k,l):=genmatrix(lambda([a,b],ck(k,l,l+1-a,l,l+1-b)),2*l+1,2*l+1)$

苦労したのは、平方根を単純化する部分である。sqrt(2)*sqrt(6)を2*sqrt(3)と変形するやり方が分からなくて、自乗してからsqrtしたりする関数を書いたりしていたが、rootscontractを使うと良いことがやっとわかった。

Read more...

Ryzen5にDebian10

first trial
AMDのRyzenはコストパフォーマンスがよいということで、興味を持っていたが、Linuxのインストールが難しいという噂を耳にしていた。最近、メインPCがいきなり電源が落ちることがあって、最初は電源ケーブルが抜けかかっているだけかと思っていたのだが、何度か再発するので、PCを更新することにした。そろそろRyzenにもLinuxのインストールが簡単にできるようになっているだろうということで、新しいPCはRyzen5にした。 今回は、CPUがryzen5になったことと、SSDとHDD両方載せていることが、今までのPCとは大きく異なる点である。パーティションを切るときに、SSDをルートに、HDDをhomeにして、インストールしようとしたが、EFIが無いと言われて進まない。よく分からなかったので、SSDのみに自動でパーティションを設定して、EFIを自動生成して、そこからSWAPを除いてルートに割り当てたあと、HDDにhomeを割り当てたら、進むことが出来た。 インストール自体は、うまく行ったようだが、再起動しても、画面が真っ黒なままである。今日は時間が無いので、後日に再挑戦しよう。

2020/6/1追記 とりあえず、前回はDebian10.3をUSBブートで試したが、最新は10.4だったので、それで試すことにした。しかし、同じような症状だったので、bootの設定がおかしいのかと思って、BIOSからいじってみた。Debianが二つあるように見えるけど、single user modeなのかと思っていたが、それだと画面が真っ黒なことの説明ができない。二つある方のどちらかを選ぶべきなのかと思って、いろいろ試していたら、grubが立ち上がるようになった。webの情報だと、ここからいろいろ設定しないといけないという話だったが、その後は問題無く動いているようである。まあ、しばらく使って試してみよう。

Read more...

コロナとlinux

古いPCにlubuntu
コロナウイルスの影響で,人と会う機会を減らすためにオンラインで様々なことをすることが求められるようになっている.いろいろな出先でネット環境を手軽に使えるようにするために,古いノートPCを発掘したので,これにlinuxを入れてみた.入れたOSはlubuntu18.04である.もう少ししたら20.04が出るはずなのだが.さらに,古いPCなので,amd64では無くi386である.インストール自体はうまくいったのだが,wifiとSDカードが認識できかった.前者に対しては,bmc-kernel-sourceを入れたらうまく行った.後者に関しては,/etc/modprobe.d/optionsにoptions sdhci debug_quirks=1を記述したら認識するようになった.

Read more...