/qutip/qutip/rotation.py

http://qutip.googlecode.com/ · Python · 131 lines · 82 code · 25 blank · 24 comment · 16 complexity · 3c2e07464dfe541b40d302b136dba74d MD5 · raw file

  1. #This file is part of QuTIP.
  2. #
  3. # QuTIP is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation, either version 3 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # QuTIP is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with QuTIP. If not, see <http://www.gnu.org/licenses/>.
  15. #
  16. # Copyright (C) 2011-2012, Paul D. Nation & Robert J. Johansson
  17. #
  18. ###########################################################################
  19. from scipy import *
  20. import scipy.linalg as la
  21. def rotation(params,type):
  22. '''
  23. % ROTATION translates a 3-d rotation into various descriptions
  24. % [naxis,U,euler,R] = rotation(params,type) takes one of the following
  25. % inputs:
  26. %
  27. % params = [nx,ny,nz], type = 'axis':
  28. % is a rotation about (nx,ny,nz) by angle |(nx,ny,nz)| radians
  29. % params = 2x2 unitary matrix, type = 'SU(2)':
  30. % is a rotation specified in SU(2)
  31. % params = [alpha,beta,gamma], type = 'Euler':
  32. % is a rotation through Euler angles (alpha,beta,gamma)
  33. % params = 3x3 orthogonal matrix, type = 'SO(3)':
  34. % is a rotation specified in SO(3)
  35. %
  36. % Output is the rotation converted to all of the above descriptions.
  37. '''
  38. type=type.lower()
  39. if type=='euler':
  40. R=euler2so3axis(params)
  41. naxis=so32axis(R)
  42. U=axis2su2(naxis)
  43. euler=su22euler(U)
  44. elif type=='so(3)':
  45. naxis=so32axis(params)
  46. U=axis2su2(naxis)
  47. euler=su22euler(U)
  48. R=euler2so3(euler)
  49. elif type=='axis':
  50. U=axis2su2(params)
  51. euler=su22euler(U)
  52. R=euler2so3(euler)
  53. naxis=so32axis(R)
  54. elif type=='su(2)':
  55. euler=su22euler(params)
  56. R=euler2so3(euler)
  57. naxis=so32axis(R)
  58. U=axis2su2(naxis)
  59. else:
  60. raise TypeError('Type should be string of Euler, SO(3), SU(2), or Axis')
  61. return naxis,U,euler,R
  62. def euler2so3(euler):
  63. alpha=euler[0]
  64. beta=euler[1]
  65. gamma=euler[2]
  66. ca=cos(alpha)
  67. cb=cos(beta)
  68. cg=cos(gamma)
  69. sa=sin(alpha)
  70. sb=sin(beta)
  71. sg=sin(gamma)
  72. m1=array([[ca,-sa,0],[sa,ca,0],[0,0,1]])
  73. m2=array([[cb,0,sb],[0,1,0],[-sb,0,cb]])
  74. m3=array([[cg,-sg,0],[sg,cg,0],[0,0,1]])
  75. return dot(dot(m1,m2),m3)
  76. #not finished#################
  77. def su32axis(R):
  78. if size(R)!=(3,3) or la.norm(dot(R.T,R)-eye(3),inf)>1.0e-6 or la.det(R)<0:
  79. raise TypeError('Invalid rotation matrix in SO(3)')
  80. [V,D]=la.eig(R)
  81. D=la.diag(D)
  82. ind=nonzero(abs(D-1)<1.0e-6)
  83. ind=ind[0]
  84. n=V[:,ind]
  85. n=n/la.norm(n)
  86. nn=la.dot(n,n.T)
  87. rn=array([[0, -n[2],n[1]],[n[2],0,-n[0]],[-n[1],n[0],0]])
  88. enn=eye(3)-nn
  89. def axis2su2(naxis):
  90. if la.norm(naxis)==0:
  91. return eye(2)
  92. else:
  93. n=naxis/la.norm(naxis)
  94. s=sin(la.norm(naxis)/2.0)
  95. a=cos(la.norm(naxis)/2.0)-1j*n[2]*s
  96. b=-n[1]*s-1j*n[0]*s
  97. return array([[a,b],[-b.T,a.T]])
  98. def su22euler(U):
  99. if size(U)!=(2,2) or la.norm(la.dot(U.T,U)-eye(2),inf)>1.0e-6 or la.norm(la.dot(U,U.T)-eye(2),inf)>1.0e-6 or la.det(U)<0:
  100. raise TypeError('Invalid rotation matrix in SU(2)')
  101. a=U[0,0]
  102. b=U[0,1]
  103. am=abs(a)
  104. bm=abs(b)
  105. if am!=0 and bm!=0:
  106. beta=2*arctan