波動関数の崩壊アルゴリズム

昨日のTOWNSCAPERの記事「Wave Function Collapse Algorithm(波動関数の崩壊アルゴリズム)」の事に触れました。なにやら小難しい物理の計算をする手法かと思っていましたが、どうやらそうでは無いようです。

とある条件を満たすと浮遊城の出来上がり

波動関数とは

量子(素粒子とか)の状態を表す式です。量子とは原子核を構成している中性子や陽子をさらに分解してこれ以上は壊せませんって感じの最小単位のツブツブです。電子や光子もこれに含まれます。これらツブツブが今どこにどんな状態で存在するかを表す式が波動関数です。

原子核に束縛されていない電子を例に、乱暴に説明すると、今だいたいこの辺にこんな確率で存在するんじゃない?って答えを波動関数で表すことが出来ます。放物運動の方程式のようにある時点の位置と速度が分かっていて、何秒後にはこの位置をこの速度で飛んでるといった事を確定できないのが量子力学の世界です。

崩壊

でも、電子も通さない壁を置くことが出来、そこに電子が衝突して痕(あと)が残れば電子は確かにそこにあったと知る事が出来ます。「シュレーディンガーの猫」で有名ですね。箱を開けるまで猫の生死は五分五分の確立の状態のままってやつです。確率でしか分からなかった状態が観測によって確定される。このことを『波動方程式の崩壊』と呼びます。

で、

続きを読む “波動関数の崩壊アルゴリズム”

Euclidean Rhythm

Basic paper: The Euclidean Algorithm Generates Traditional Musical Rhythms

Python code

# Making Euclidean Rhythm with Bjorklund's distribution
# by hTaka
import sys

class EuclideanRhythm:
    def getRhythm(self,steps,hit,shift):
        self.result = ""
        if hit > steps:
            raise NameError("Number of hit must less than steps")
        pause = steps - hit
        leftUnit = "X"
        rightUnit = "."
        print "process>{0}|{1} / left:{2} right:{3}".format(("["+leftUnit+"]") * hit , ("["+rightUnit+"]") * pause , hit , pause)
        self.makeEuclidRhythm(hit,pause,leftUnit,rightUnit)
        if abs(shift)%steps != 0:
            print "Result> Steps:{0} hit:{1} shift:{2} [{3}] (before shift)".format(steps,hit,shift,self.result)
            self.shiftRhythm(steps,shift)
        return self.result
    
    def makeEuclidRhythm(self,numL,numR,leftUnit,rightUnit):
        unitBuffer = leftUnit
        if numR==0 or numR == 1:
            self.result = leftUnit * numL+ rightUnit * numR
            return
        if numR > numL:
            m,k = numR,numL
            isRightRemain = True
            leftUnit += (rightUnit * (m // k))
        else:
            m,k = numL,numR
            isRightRemain = False
            leftUnit += rightUnit
        if isRightRemain:
            print "process>{0}|{1}  / left:{2} right:{3} {4} {5}".format(("["+leftUnit+"]") * k, ("["+rightUnit+"]") * (m % k), k , m%k ,"RightUnit Remain with" , "[" + rightUnit + "]")
            self.makeEuclidRhythm(k,m%k,leftUnit,rightUnit)
        else:
            print "process>{0}|{1}  / left:{2} right:{3} {4} {5}".format(("["+leftUnit+"]") * k, ("["+unitBuffer+"]") * (m - k), k, m-k,"RightUnit Replace with Left" , "[" + unitBuffer + "]")
            self.makeEuclidRhythm(k,m-k,leftUnit,unitBuffer)

    def shiftRhythm(self,steps,shift):
        if shift > 0:
            shift = shift % steps
            self.result = "{0}{1}".format(self.result[steps - shift :],self.result[0 : -1 * shift])
        if shift < 0:
            shift = (abs(shift) % steps)
            self.result = "{0}{1}".format(self.result[shift :],self.result[0 : shift])
        return


def main(arg):
    try:
        steps = int(arg[1])
        hit = int(arg[2])
        shift = int(arg[3])
    except:
        print "Args error! usage: python EuclideanRhythms.py <STEPS> <HIT> <SHIFT>"
        print "using hard coded params."
        steps,hit,shift = 16,7,0
    rhythm = EuclideanRhythm()
    print "Result> Steps:{0} hit:{1} shift:{2} [{3}]".format(steps,hit,shift,rhythm.getRhythm(steps,hit,shift))

if __name__ == '__main__':
    main(sys.argv)

Result

process>[X][X][X][X][X][X][X]|[.][.][.][.][.][.][.][.][.] / left:7 right:9
process>[X.][X.][X.][X.][X.][X.][X.]|[.][.]  / left:7 right:2 RightUnit Remain with [.]
process>[X..][X..]|[X.][X.][X.][X.][X.]  / left:2 right:5 RightUnit Replace with Left [X.]
process>[X..X.X.][X..X.X.]|[X.]  / left:2 right:1 RightUnit Remain with [X.]
Result> Steps:16 hit:7 shift:0 [X..X.X.X..X.X.X.]