2022年
11月
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

setup diary

2007|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|06|08|11|
2015|01|02|03|04|05|06|07|08|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|

2022-11-21 Rとjuliaとpythonとrubyで

_ 様々な言語で角運動量演算子

角運動量演算子の行列を求めるプログラムを4つの言語で書いてみたので,メモがてら公開しておこうと思う.言語名と角運動量演算子で検索してもあまりヒットしないので,誰かの役に立つかもしれないし. Rについては,以前もブログに書いたことがあるが,j=0の場合にも対応できるように一部を書き直した.
mjz<-function(j) diag(j:-j,2*j+1)
mjp<-function(j) matrix(diag(sqrt(diffinv(j:-j)*2))[-1,-2*j-2],2*j+1)
mjm<-function(j) t(mjp(j))
mjx<-function(j) (mjp(j)+mjm(j))/2
mjy<-function(j) (mjp(j)-mjm(j))/2i
me<-function(j) diag(2*j+1)
juliaは,比較的新しい言語だが,数値計算には便利かも知れないので,書いてみた.いつかこのルーチンを使ってみたい.
using LinearAlgebra 
mjz(j)=diagm(j:-1:-j)
mjp(j)=diagm(1=>2j:-2:2-2j|>cumsum.|>sqrt)
mjm(j)=mjp(j)'
mjx(j)=(mjp(j)+mjm(j))/2
mjy(j)=(mjp(j)-mjm(j))/2im
me(j)=I(2j+1)
pythonはなぜか人気が衰えない言語で,書きにくいけど需要があるかも知れないので,書いてみた.
import numpy as np 
def mjz(j):return np.diag(j-np.arange(2*j+1))
def mjp(j):return np.diag(np.sqrt(np.cumsum((j-np.arange(2*j))*2)),1)
def mjm(j):return mjp(j).T
def mjx(j):return (mjp(j)+mjm(j))/2
def mjy(j):return (mjp(j)-mjm(j))/2j
def me(j):return np.identity(int(2*j+1))
rubyは数値計算にはあまり向かない言語だと思っていたが,numoを使えば数値計算もできそうなので,書いてみた.
require "numo/linalg"
def mjz(j) (j-Numo::DFloat[0..2*j]).diag end
def mjp(j) Numo::NMath.sqrt((j-Numo::DFloat[0...2*j]).cumsum*2).diag(1) end
def mjm(j) mjp(j).transpose end
def mjx(j) (mjp(j)+mjm(j))/2 end
def mjy(j) (mjp(j)-mjm(j))/2i end
def me(j) Numo::DFloat.eye(2*j+1) end
Rはそのままで実行可能だが,それ以外の3つの言語では,何らかのライブラリを組み込まないといけないのが,少し面倒だ.Rやjuliaは半整数をあまり意識しなくても動くが,pythonとrubyは,rangeが半整数だと動かないので,2*jが整数であることを生かして少し工夫しないといけなかった.R以外の3つの言語では,対角要素の一つ上に成分を並んだ行列を簡単に作れるので,上昇演算子を簡単に書けるが,Rだとそこに工夫が必要で,もう少し良い手法もあるかも知れない.