2016-10-02 9 views

答えて

0

シングルキュービット演算は基本的にはちょうどunit quaternionsですが、余分な位相係数があります。類似点は、Pauli matrices、時刻sqrt(-1)が、クォータニオンを定義するi^2=j^2=k^2=ijk=-1の関係を満たすためです。

結果として、変換方法の難しい部分は、すでに「四元数から軸の角度」のコードで処理されています。フェーズされたクォータニオン成分を取り出し、位相係数を計算し、次に四元数 - 角度軸法を適用します。

import math 
import cmath 

def toBlochAngleAxis(matrix): 
    """ 
    Breaksdown a matrix U into axis, angle, and phase_angle components satisfying 
    U = exp(i phase_angle) (I cos(angle/2) - axis sigma i sin(angle/2)) 

    :param matrix: The 2x2 unitary matrix U 
    :return: The breakdown (axis(x, y, z), angle, phase_angle) 
    """ 
    [[a, b], [c, d]] = matrix 

    # --- Part 1: convert to a quaternion --- 

    # Phased components of quaternion. 
    wp = (a + d)/2.0 
    xp = (b + c)/2.0j 
    yp = (b - c)/2.0 
    zp = (a - d)/2.0j 

    # Arbitrarily use largest value to determine the global phase factor. 
    phase = max([wp, xp, yp, zp], key=abs) 
    phase /= abs(phase) 

    # Cancel global phase factor, recovering quaternion components. 
    w = complex(wp/phase).real 
    x = complex(xp/phase).real 
    y = complex(yp/phase).real 
    z = complex(zp/phase).real 

    # --- Part 2: convert from quaternion to angle-axis --- 

    # Floating point error may have pushed w outside of [-1, +1]. Fix that. 
    w = min(max(w, -1), +1) 

    # Recover angle. 
    angle = -2*math.acos(w) 

    # Normalize axis. 
    n = math.sqrt(x*x + y*y + z*z); 
    if n < 0.000001: 
     # There's an axis singularity near angle=0. 
     # Just default to no rotation around the Z axis in this case. 
     angle = 0 
     x = 0 
     y = 0 
     z = 1 
     n = 1 
    x /= n 
    y /= n 
    z /= n 

    # --- Part 3: (optional) canonicalize --- 

    # Prefer angle in [-pi, pi] 
    if angle <= -math.pi: 
     angle += 2*math.pi 
     phase *= -1 

    # Prefer axes that point positive-ward. 
    if x + y + z < 0: 
     x *= -1 
     y *= -1 
     z *= -1 
     angle *= -1 

    phase_angle = cmath.polar(phase)[1] 

    return (x, y, z), angle, phase_angle 

テストそれアウト:

print(toBlochAngleAxis([[1, 0], [0, 1]])) # Identity 
# ([0, 0, 1], 0, 0.0) 

print(toBlochAngleAxis([[0, 1], [1, 0]])) # Pauli X, 180 deg around X 
# ([1.0, -0.0, -0.0], 3.141592653589793, 1.5707963267948966) 

print(toBlochAngleAxis([[0, -1j], [1j, 0]])) # Pauli Y, 180 deg around Y 
# ([-0.0, 1.0, -0.0], 3.141592653589793, 1.5707963267948966) 

print(toBlochAngleAxis([[1, 0], [0, -1]])) # Pauli Z, 180 deg around Z 
# ([-0.0, -0.0, 1.0], 3.141592653589793, 1.5707963267948966) 

s = math.sqrt(0.5) 
print(toBlochAngleAxis([[s, s], [s, -s]])) # Hadamard, 180 deg around X+Z 
# ([0.7071067811865476, -0.0, 0.7071067811865476], 3.141592653589793, 1.5707963267948966) 

print(toBlochAngleAxis([[s, s*1j], [s*1j, s]])) # -90 deg X axis, no phase 
# ((1.0, 0.0, 0.0), -1.5707963267948966, 0.0) 
関連する問題