m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

713 lines
21 KiB

7 months ago
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. The module implements routines to model the polarization of optical fields
  5. and can be used to calculate the effects of polarization optical elements on
  6. the fields.
  7. - Jones vectors.
  8. - Stokes vectors.
  9. - Jones matrices.
  10. - Mueller matrices.
  11. Examples
  12. ========
  13. We calculate a generic Jones vector:
  14. >>> from sympy import symbols, pprint, zeros, simplify
  15. >>> from sympy.physics.optics.polarization import (jones_vector, stokes_vector,
  16. ... half_wave_retarder, polarizing_beam_splitter, jones_2_stokes)
  17. >>> psi, chi, p, I0 = symbols("psi, chi, p, I0", real=True)
  18. >>> x0 = jones_vector(psi, chi)
  19. >>> pprint(x0, use_unicode=True)
  20. -sin(χ)sin(ψ) + cos(χ)cos(ψ)
  21. sin(χ)cos(ψ) + sin(ψ)cos(χ)
  22. And the more general Stokes vector:
  23. >>> s0 = stokes_vector(psi, chi, p, I0)
  24. >>> pprint(s0, use_unicode=True)
  25. I
  26. Ipcos(2χ)cos(2ψ)
  27. Ipsin(2ψ)cos(2χ)
  28. Ipsin(2χ)
  29. We calculate how the Jones vector is modified by a half-wave plate:
  30. >>> alpha = symbols("alpha", real=True)
  31. >>> HWP = half_wave_retarder(alpha)
  32. >>> x1 = simplify(HWP*x0)
  33. We calculate the very common operation of passing a beam through a half-wave
  34. plate and then through a polarizing beam-splitter. We do this by putting this
  35. Jones vector as the first entry of a two-Jones-vector state that is transformed
  36. by a 4x4 Jones matrix modelling the polarizing beam-splitter to get the
  37. transmitted and reflected Jones vectors:
  38. >>> PBS = polarizing_beam_splitter()
  39. >>> X1 = zeros(4, 1)
  40. >>> X1[:2, :] = x1
  41. >>> X2 = PBS*X1
  42. >>> transmitted_port = X2[:2, :]
  43. >>> reflected_port = X2[2:, :]
  44. This allows us to calculate how the power in both ports depends on the initial
  45. polarization:
  46. >>> transmitted_power = jones_2_stokes(transmitted_port)[0]
  47. >>> reflected_power = jones_2_stokes(reflected_port)[0]
  48. >>> print(transmitted_power)
  49. cos(-2*alpha + chi + psi)**2/2 + cos(2*alpha + chi - psi)**2/2
  50. >>> print(reflected_power)
  51. sin(-2*alpha + chi + psi)**2/2 + sin(2*alpha + chi - psi)**2/2
  52. Please see the description of the individual functions for further
  53. details and examples.
  54. References
  55. ==========
  56. .. [1] https://en.wikipedia.org/wiki/Jones_calculus
  57. .. [2] https://en.wikipedia.org/wiki/Mueller_calculus
  58. .. [3] https://en.wikipedia.org/wiki/Stokes_parameters
  59. """
  60. from sympy.core.numbers import (I, pi)
  61. from sympy.functions.elementary.complexes import (Abs, im, re)
  62. from sympy.functions.elementary.exponential import exp
  63. from sympy.functions.elementary.miscellaneous import sqrt
  64. from sympy.functions.elementary.trigonometric import (cos, sin)
  65. from sympy.matrices.dense import Matrix
  66. from sympy.simplify.simplify import simplify
  67. from sympy.physics.quantum import TensorProduct
  68. def jones_vector(psi, chi):
  69. """A Jones vector corresponding to a polarization ellipse with `psi` tilt,
  70. and `chi` circularity.
  71. Parameters
  72. ==========
  73. ``psi`` : numeric type or SymPy Symbol
  74. The tilt of the polarization relative to the `x` axis.
  75. ``chi`` : numeric type or SymPy Symbol
  76. The angle adjacent to the mayor axis of the polarization ellipse.
  77. Returns
  78. =======
  79. Matrix :
  80. A Jones vector.
  81. Examples
  82. ========
  83. The axes on the Poincaré sphere.
  84. >>> from sympy import pprint, symbols, pi
  85. >>> from sympy.physics.optics.polarization import jones_vector
  86. >>> psi, chi = symbols("psi, chi", real=True)
  87. A general Jones vector.
  88. >>> pprint(jones_vector(psi, chi), use_unicode=True)
  89. -sin(χ)sin(ψ) + cos(χ)cos(ψ)
  90. sin(χ)cos(ψ) + sin(ψ)cos(χ)
  91. Horizontal polarization.
  92. >>> pprint(jones_vector(0, 0), use_unicode=True)
  93. 1
  94. 0
  95. Vertical polarization.
  96. >>> pprint(jones_vector(pi/2, 0), use_unicode=True)
  97. 0
  98. 1
  99. Diagonal polarization.
  100. >>> pprint(jones_vector(pi/4, 0), use_unicode=True)
  101. 2
  102. 2
  103. 2
  104. 2
  105. Anti-diagonal polarization.
  106. >>> pprint(jones_vector(-pi/4, 0), use_unicode=True)
  107. 2
  108. 2
  109. -2
  110. 2
  111. Right-hand circular polarization.
  112. >>> pprint(jones_vector(0, pi/4), use_unicode=True)
  113. 2
  114. 2
  115. 2
  116. 2
  117. Left-hand circular polarization.
  118. >>> pprint(jones_vector(0, -pi/4), use_unicode=True)
  119. 2
  120. 2
  121. -2
  122. 2
  123. """
  124. return Matrix([-I*sin(chi)*sin(psi) + cos(chi)*cos(psi),
  125. I*sin(chi)*cos(psi) + sin(psi)*cos(chi)])
  126. def stokes_vector(psi, chi, p=1, I=1):
  127. """A Stokes vector corresponding to a polarization ellipse with ``psi``
  128. tilt, and ``chi`` circularity.
  129. Parameters
  130. ==========
  131. ``psi`` : numeric type or SymPy Symbol
  132. The tilt of the polarization relative to the ``x`` axis.
  133. ``chi`` : numeric type or SymPy Symbol
  134. The angle adjacent to the mayor axis of the polarization ellipse.
  135. ``p`` : numeric type or SymPy Symbol
  136. The degree of polarization.
  137. ``I`` : numeric type or SymPy Symbol
  138. The intensity of the field.
  139. Returns
  140. =======
  141. Matrix :
  142. A Stokes vector.
  143. Examples
  144. ========
  145. The axes on the Poincaré sphere.
  146. >>> from sympy import pprint, symbols, pi
  147. >>> from sympy.physics.optics.polarization import stokes_vector
  148. >>> psi, chi, p, I = symbols("psi, chi, p, I", real=True)
  149. >>> pprint(stokes_vector(psi, chi, p, I), use_unicode=True)
  150. I
  151. Ipcos(2χ)cos(2ψ)
  152. Ipsin(2ψ)cos(2χ)
  153. Ipsin(2χ)
  154. Horizontal polarization
  155. >>> pprint(stokes_vector(0, 0), use_unicode=True)
  156. 1
  157. 1
  158. 0
  159. 0
  160. Vertical polarization
  161. >>> pprint(stokes_vector(pi/2, 0), use_unicode=True)
  162. 1
  163. -1
  164. 0
  165. 0
  166. Diagonal polarization
  167. >>> pprint(stokes_vector(pi/4, 0), use_unicode=True)
  168. 1
  169. 0
  170. 1
  171. 0
  172. Anti-diagonal polarization
  173. >>> pprint(stokes_vector(-pi/4, 0), use_unicode=True)
  174. 1
  175. 0
  176. -1
  177. 0
  178. Right-hand circular polarization
  179. >>> pprint(stokes_vector(0, pi/4), use_unicode=True)
  180. 1
  181. 0
  182. 0
  183. 1
  184. Left-hand circular polarization
  185. >>> pprint(stokes_vector(0, -pi/4), use_unicode=True)
  186. 1
  187. 0
  188. 0
  189. -1
  190. Unpolarized light
  191. >>> pprint(stokes_vector(0, 0, 0), use_unicode=True)
  192. 1
  193. 0
  194. 0
  195. 0
  196. """
  197. S0 = I
  198. S1 = I*p*cos(2*psi)*cos(2*chi)
  199. S2 = I*p*sin(2*psi)*cos(2*chi)
  200. S3 = I*p*sin(2*chi)
  201. return Matrix([S0, S1, S2, S3])
  202. def jones_2_stokes(e):
  203. """Return the Stokes vector for a Jones vector `e`.
  204. Parameters
  205. ==========
  206. ``e`` : SymPy Matrix
  207. A Jones vector.
  208. Returns
  209. =======
  210. SymPy Matrix
  211. A Jones vector.
  212. Examples
  213. ========
  214. The axes on the Poincaré sphere.
  215. >>> from sympy import pprint, pi
  216. >>> from sympy.physics.optics.polarization import jones_vector
  217. >>> from sympy.physics.optics.polarization import jones_2_stokes
  218. >>> H = jones_vector(0, 0)
  219. >>> V = jones_vector(pi/2, 0)
  220. >>> D = jones_vector(pi/4, 0)
  221. >>> A = jones_vector(-pi/4, 0)
  222. >>> R = jones_vector(0, pi/4)
  223. >>> L = jones_vector(0, -pi/4)
  224. >>> pprint([jones_2_stokes(e) for e in [H, V, D, A, R, L]],
  225. ... use_unicode=True)
  226. 1 1 1 1 1 1
  227. 1 -1 0 0 0 0
  228. , , , , ,
  229. 0 0 1 -1 0 0
  230. 0 0 0 0 1 -1
  231. """
  232. ex, ey = e
  233. return Matrix([Abs(ex)**2 + Abs(ey)**2,
  234. Abs(ex)**2 - Abs(ey)**2,
  235. 2*re(ex*ey.conjugate()),
  236. -2*im(ex*ey.conjugate())])
  237. def linear_polarizer(theta=0):
  238. """A linear polarizer Jones matrix with transmission axis at
  239. an angle ``theta``.
  240. Parameters
  241. ==========
  242. ``theta`` : numeric type or SymPy Symbol
  243. The angle of the transmission axis relative to the horizontal plane.
  244. Returns
  245. =======
  246. SymPy Matrix
  247. A Jones matrix representing the polarizer.
  248. Examples
  249. ========
  250. A generic polarizer.
  251. >>> from sympy import pprint, symbols
  252. >>> from sympy.physics.optics.polarization import linear_polarizer
  253. >>> theta = symbols("theta", real=True)
  254. >>> J = linear_polarizer(theta)
  255. >>> pprint(J, use_unicode=True)
  256. 2
  257. cos (θ) sin(θ)cos(θ)
  258. 2
  259. sin(θ)cos(θ) sin (θ)
  260. """
  261. M = Matrix([[cos(theta)**2, sin(theta)*cos(theta)],
  262. [sin(theta)*cos(theta), sin(theta)**2]])
  263. return M
  264. def phase_retarder(theta=0, delta=0):
  265. """A phase retarder Jones matrix with retardance `delta` at angle `theta`.
  266. Parameters
  267. ==========
  268. ``theta`` : numeric type or SymPy Symbol
  269. The angle of the fast axis relative to the horizontal plane.
  270. ``delta`` : numeric type or SymPy Symbol
  271. The phase difference between the fast and slow axes of the
  272. transmitted light.
  273. Returns
  274. =======
  275. SymPy Matrix :
  276. A Jones matrix representing the retarder.
  277. Examples
  278. ========
  279. A generic retarder.
  280. >>> from sympy import pprint, symbols
  281. >>> from sympy.physics.optics.polarization import phase_retarder
  282. >>> theta, delta = symbols("theta, delta", real=True)
  283. >>> R = phase_retarder(theta, delta)
  284. >>> pprint(R, use_unicode=True)
  285. -δ -δ
  286. δ 2 2 2 δ 2
  287. sin (θ) + cos (θ) 1 - sin(θ)cos(θ)
  288. -δ -δ
  289. δ 2 δ 2 2 2
  290. 1 - sin(θ)cos(θ) cos (θ) + sin (θ)
  291. """
  292. R = Matrix([[cos(theta)**2 + exp(I*delta)*sin(theta)**2,
  293. (1-exp(I*delta))*cos(theta)*sin(theta)],
  294. [(1-exp(I*delta))*cos(theta)*sin(theta),
  295. sin(theta)**2 + exp(I*delta)*cos(theta)**2]])
  296. return R*exp(-I*delta/2)
  297. def half_wave_retarder(theta):
  298. """A half-wave retarder Jones matrix at angle `theta`.
  299. Parameters
  300. ==========
  301. ``theta`` : numeric type or SymPy Symbol
  302. The angle of the fast axis relative to the horizontal plane.
  303. Returns
  304. =======
  305. SymPy Matrix
  306. A Jones matrix representing the retarder.
  307. Examples
  308. ========
  309. A generic half-wave plate.
  310. >>> from sympy import pprint, symbols
  311. >>> from sympy.physics.optics.polarization import half_wave_retarder
  312. >>> theta= symbols("theta", real=True)
  313. >>> HWP = half_wave_retarder(theta)
  314. >>> pprint(HWP, use_unicode=True)
  315. 2 2
  316. -- sin (θ) + cos (θ) -2sin(θ)cos(θ)
  317. 2 2
  318. -2sin(θ)cos(θ) -sin (θ) - cos (θ)
  319. """
  320. return phase_retarder(theta, pi)
  321. def quarter_wave_retarder(theta):
  322. """A quarter-wave retarder Jones matrix at angle `theta`.
  323. Parameters
  324. ==========
  325. ``theta`` : numeric type or SymPy Symbol
  326. The angle of the fast axis relative to the horizontal plane.
  327. Returns
  328. =======
  329. SymPy Matrix
  330. A Jones matrix representing the retarder.
  331. Examples
  332. ========
  333. A generic quarter-wave plate.
  334. >>> from sympy import pprint, symbols
  335. >>> from sympy.physics.optics.polarization import quarter_wave_retarder
  336. >>> theta= symbols("theta", real=True)
  337. >>> QWP = quarter_wave_retarder(theta)
  338. >>> pprint(QWP, use_unicode=True)
  339. -π -π
  340. 2 2 4 4
  341. sin (θ) + cos (θ) (1 - ) sin(θ)cos(θ)
  342. -π -π
  343. 4 2 2 4
  344. (1 - ) sin(θ)cos(θ) sin (θ) + cos (θ)
  345. """
  346. return phase_retarder(theta, pi/2)
  347. def transmissive_filter(T):
  348. """An attenuator Jones matrix with transmittance `T`.
  349. Parameters
  350. ==========
  351. ``T`` : numeric type or SymPy Symbol
  352. The transmittance of the attenuator.
  353. Returns
  354. =======
  355. SymPy Matrix
  356. A Jones matrix representing the filter.
  357. Examples
  358. ========
  359. A generic filter.
  360. >>> from sympy import pprint, symbols
  361. >>> from sympy.physics.optics.polarization import transmissive_filter
  362. >>> T = symbols("T", real=True)
  363. >>> NDF = transmissive_filter(T)
  364. >>> pprint(NDF, use_unicode=True)
  365. T 0
  366. 0 T
  367. """
  368. return Matrix([[sqrt(T), 0], [0, sqrt(T)]])
  369. def reflective_filter(R):
  370. """A reflective filter Jones matrix with reflectance `R`.
  371. Parameters
  372. ==========
  373. ``R`` : numeric type or SymPy Symbol
  374. The reflectance of the filter.
  375. Returns
  376. =======
  377. SymPy Matrix
  378. A Jones matrix representing the filter.
  379. Examples
  380. ========
  381. A generic filter.
  382. >>> from sympy import pprint, symbols
  383. >>> from sympy.physics.optics.polarization import reflective_filter
  384. >>> R = symbols("R", real=True)
  385. >>> pprint(reflective_filter(R), use_unicode=True)
  386. R 0
  387. 0 -R
  388. """
  389. return Matrix([[sqrt(R), 0], [0, -sqrt(R)]])
  390. def mueller_matrix(J):
  391. """The Mueller matrix corresponding to Jones matrix `J`.
  392. Parameters
  393. ==========
  394. ``J`` : SymPy Matrix
  395. A Jones matrix.
  396. Returns
  397. =======
  398. SymPy Matrix
  399. The corresponding Mueller matrix.
  400. Examples
  401. ========
  402. Generic optical components.
  403. >>> from sympy import pprint, symbols
  404. >>> from sympy.physics.optics.polarization import (mueller_matrix,
  405. ... linear_polarizer, half_wave_retarder, quarter_wave_retarder)
  406. >>> theta = symbols("theta", real=True)
  407. A linear_polarizer
  408. >>> pprint(mueller_matrix(linear_polarizer(theta)), use_unicode=True)
  409. cos(2θ) sin(2θ)
  410. 1/2 0
  411. 2 2
  412. cos(2θ) cos(4θ) 1 sin(4θ)
  413. + 0
  414. 2 4 4 4
  415. sin(2θ) sin(4θ) 1 cos(4θ)
  416. - 0
  417. 2 4 4 4
  418. 0 0 0 0
  419. A half-wave plate
  420. >>> pprint(mueller_matrix(half_wave_retarder(theta)), use_unicode=True)
  421. 1 0 0 0
  422. 4 2
  423. 0 8sin (θ) - 8sin (θ) + 1 sin(4θ) 0
  424. 4 2
  425. 0 sin(4θ) - 8sin (θ) + 8sin (θ) - 1 0
  426. 0 0 0 -1
  427. A quarter-wave plate
  428. >>> pprint(mueller_matrix(quarter_wave_retarder(theta)), use_unicode=True)
  429. 1 0 0 0
  430. cos(4θ) 1 sin(4θ)
  431. 0 + -sin(2θ)
  432. 2 2 2
  433. sin(4θ) 1 cos(4θ)
  434. 0 - cos(2θ)
  435. 2 2 2
  436. 0 sin(2θ) -cos(2θ) 0
  437. """
  438. A = Matrix([[1, 0, 0, 1],
  439. [1, 0, 0, -1],
  440. [0, 1, 1, 0],
  441. [0, -I, I, 0]])
  442. return simplify(A*TensorProduct(J, J.conjugate())*A.inv())
  443. def polarizing_beam_splitter(Tp=1, Rs=1, Ts=0, Rp=0, phia=0, phib=0):
  444. r"""A polarizing beam splitter Jones matrix at angle `theta`.
  445. Parameters
  446. ==========
  447. ``J`` : SymPy Matrix
  448. A Jones matrix.
  449. ``Tp`` : numeric type or SymPy Symbol
  450. The transmissivity of the P-polarized component.
  451. ``Rs`` : numeric type or SymPy Symbol
  452. The reflectivity of the S-polarized component.
  453. ``Ts`` : numeric type or SymPy Symbol
  454. The transmissivity of the S-polarized component.
  455. ``Rp`` : numeric type or SymPy Symbol
  456. The reflectivity of the P-polarized component.
  457. ``phia`` : numeric type or SymPy Symbol
  458. The phase difference between transmitted and reflected component for
  459. output mode a.
  460. ``phib`` : numeric type or SymPy Symbol
  461. The phase difference between transmitted and reflected component for
  462. output mode b.
  463. Returns
  464. =======
  465. SymPy Matrix
  466. A 4x4 matrix representing the PBS. This matrix acts on a 4x1 vector
  467. whose first two entries are the Jones vector on one of the PBS ports,
  468. and the last two entries the Jones vector on the other port.
  469. Examples
  470. ========
  471. Generic polarizing beam-splitter.
  472. >>> from sympy import pprint, symbols
  473. >>> from sympy.physics.optics.polarization import polarizing_beam_splitter
  474. >>> Ts, Rs, Tp, Rp = symbols(r"Ts, Rs, Tp, Rp", positive=True)
  475. >>> phia, phib = symbols("phi_a, phi_b", real=True)
  476. >>> PBS = polarizing_beam_splitter(Tp, Rs, Ts, Rp, phia, phib)
  477. >>> pprint(PBS, use_unicode=False)
  478. [ ____ ____ ]
  479. [ \/ Tp 0 I*\/ Rp 0 ]
  480. [ ]
  481. [ ____ ____ I*phi_a]
  482. [ 0 \/ Ts 0 -I*\/ Rs *e ]
  483. [ ]
  484. [ ____ ____ ]
  485. [I*\/ Rp 0 \/ Tp 0 ]
  486. [ ]
  487. [ ____ I*phi_b ____ ]
  488. [ 0 -I*\/ Rs *e 0 \/ Ts ]
  489. """
  490. PBS = Matrix([[sqrt(Tp), 0, I*sqrt(Rp), 0],
  491. [0, sqrt(Ts), 0, -I*sqrt(Rs)*exp(I*phia)],
  492. [I*sqrt(Rp), 0, sqrt(Tp), 0],
  493. [0, -I*sqrt(Rs)*exp(I*phib), 0, sqrt(Ts)]])
  494. return PBS