4. Mueller矩阵与Stokes矢量:从琼斯到穆勒的跨越
前面我们聊了Jones矩阵,它确实好用。但有个问题——它只能处理完全偏振光。你想想看,现实世界哪有那么理想?自然光、部分偏振光,这些才是常态。我当年做激光雷达系统时,回波信号里混着大量非偏振成分,用Jones矩阵算出来的结果跟实测差了十万八千里。后来才意识到,得用Mueller矩阵和Stokes矢量这套工具。
说白了,Jones矩阵是「理想主义」,Mueller矩阵才是「现实主义」。它能处理部分偏振光、非偏振光,甚至能描述退偏效应。今天我们就把它讲透。
4.1 Stokes参数:四个数字描述偏振态
Stokes参数用四个实数描述一束光的偏振态。为什么是四个?因为光强、偏振度、偏振方向、椭圆率,这四个信息缺一不可。
定义如下:
- S₀:总光强(I)
- S₁:水平与垂直偏振分量之差(Q)
- S₂:+45°与-45°偏振分量之差(U)
- S₃:右旋与左旋圆偏振分量之差(V)
写成矢量形式:
S = [S₀, S₁, S₂, S₃]ᵀ
几个典型例子:
| 偏振态 | Stokes矢量 | 说明 |
|---|---|---|
| 自然光(非偏振) | [1, 0, 0, 0]ᵀ | 各方向均匀 |
| 水平线偏振 | [1, 1, 0, 0]ᵀ | S₁取最大值 |
| 垂直线偏振 | [1, -1, 0, 0]ᵀ | S₁取最小值 |
| +45°线偏振 | [1, 0, 1, 0]ᵀ | S₂取最大值 |
| 右旋圆偏振 | [1, 0, 0, 1]ᵀ | S₃取正值 |
| 左旋圆偏振 | [1, 0, 0, -1]ᵀ | S₃取负值 |
关键关系:对于完全偏振光,有 S₀² = S₁² + S₂² + S₃²。对于部分偏振光,S₀² > S₁² + S₂² + S₃²。这个不等式就是判断偏振程度的「试金石」。
4.2 偏振度:一个参数衡量偏振纯度
有了Stokes参数,偏振度(Degree of Polarization, DoP)就很好算了:
DoP = √(S₁² + S₂² + S₃²) / S₀
取值范围:
- DoP = 1:完全偏振光
- DoP = 0:完全非偏振光(自然光)
- 0 < DoP < 1:部分偏振光
我做过一个偏振成像项目,目标物体反射光DoP只有0.3左右。用Jones矩阵算出来的结果完全不对,换成Mueller矩阵才把目标从背景里分离出来。嗯,这就是现实和理想的差距。
4.3 Mueller矩阵:4×4的「万能变换器」
Mueller矩阵是一个4×4的实数矩阵,作用在Stokes矢量上:
S_out = M · S_in
展开形式:
| S₀_out | | m₀₀ m₀₁ m₀₂ m₀₃ | | S₀_in |
| S₁_out | = | m₁₀ m₁₁ m₁₂ m₁₃ | · | S₁_in |
| S₂_out | | m₂₀ m₂₁ m₂₂ m₂₃ | | S₂_in |
| S₃_out | | m₃₀ m₃₁ m₃₂ m₃₃ | | S₃_in |
每个矩阵元都有物理意义。比如m₀₀代表总光强的透过率,m₁₁代表水平偏振分量的衰减系数。我建议你把这个矩阵当成一个「黑箱」,输入是Stokes矢量,输出也是Stokes矢量,中间发生了什么?Mueller矩阵说了算。
4.4 Mueller矩阵与Jones矩阵的关系
这里有个容易混淆的点。Jones矩阵是2×2的复数矩阵,Mueller矩阵是4×4的实数矩阵。它们之间可以互相转换,但有个前提——系统必须是「非退偏」的。
从Jones矩阵J推导Mueller矩阵M的公式:
M = A · (J ⊗ J*) · A⁻¹
其中⊗表示Kronecker积,A是一个固定的4×4变换矩阵。具体实现:
import numpy as np
def jones_to_mueller(J):
"""
将Jones矩阵转换为Mueller矩阵
J: 2x2复数矩阵
返回: 4x4实数Mueller矩阵
"""
# 变换矩阵A
A = np.array([
[1, 0, 0, 1],
[1, 0, 0, -1],
[0, 1, 1, 0],
[0, 1j, -1j, 0]
])
# Kronecker积
J_kron = np.kron(J, J.conj())
# 变换
A_inv = np.linalg.inv(A)
M = A @ J_kron @ A_inv
return np.real(M) # 取实部
个人经验:我建议你在做转换时,先用一个已知的偏振元件验证。比如理想偏振片的Jones矩阵是[[1,0],[0,0]],转换后的Mueller矩阵应该是[[0.5,0.5,0,0],[0.5,0.5,0,0],[0,0,0,0],[0,0,0,0]]。如果对不上,检查一下A矩阵的符号。
4.5 部分偏振光的处理:Mueller矩阵的真正用武之地
处理部分偏振光,Mueller矩阵是唯一的选择。为什么?因为Jones矩阵只能处理相干叠加,而部分偏振光是非相干的。
举个例子。一束DoP=0.5的部分偏振光通过一个理想偏振片:
# 输入光:水平偏振成分占75%,垂直占25%
S_in = np.array([1.0, 0.5, 0.0, 0.0]) # DoP = 0.5
# 理想水平偏振片的Mueller矩阵
M_polarizer = 0.5 * np.array([
[1, 1, 0, 0],
[1, 1, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
])
# 计算输出
S_out = M_polarizer @ S_in
print(f"输出Stokes矢量: {S_out}")
print(f"输出DoP: {np.sqrt(S_out[1]**2 + S_out[2]**2 + S_out[3]**2) / S_out[0]:.3f}")
输出结果是:
输出Stokes矢量: [0.75 0.75 0. 0. ]
输出DoP: 1.000
看到了吗?经过偏振片后,部分偏振光变成了完全偏振光。这就是偏振片的「提纯」作用。我当年做偏振去雾时,就是利用这个原理把散射光中的非偏振成分滤掉的。
4.6 常见偏振元件的Mueller矩阵
| 元件 | Mueller矩阵 | 说明 |
|---|---|---|
| 理想水平偏振片 | 0.5×[[1,1,0,0],[1,1,0,0],[0,0,0,0],[0,0,0,0]] | 只透过水平分量 |
| 理想四分之一波片(快轴水平) | [[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,-1,0]] | 引入90°相位延迟 |
| 理想半波片(快轴水平) | [[1,0,0,0],[0,1,0,0],[0,0,-1,0],[0,0,0,-1]] | 引入180°相位延迟 |
| 旋转器(θ角) | [[1,0,0,0],[0,cos2θ,sin2θ,0],[0,-sin2θ,cos2θ,0],[0,0,0,1]] | 旋转偏振方向 |
避坑指南:我曾经在搭建偏振测量系统时,把波片的快轴方向搞反了。结果测出来的Mueller矩阵全是错的。记住,波片的快轴方向决定了相位延迟的符号。建议每次实验前先用标准样品校准一下。
4.7 知识结构图:Mueller矩阵与Stokes矢量体系
下面这张图展示了本章的核心逻辑:从Stokes参数出发,经过Mueller矩阵变换,最终得到输出光的偏振态。整个体系围绕「部分偏振光」这个核心展开。
4.8 实战要点总结
聊了这么多,我总结几个关键点:
- Stokes参数是基础:四个实数,描述任何偏振态。记住S₀是总光强,其他三个是差值。
- DoP是核心指标:一个数字告诉你光有多「纯」。做实验时先测DoP,心里就有底了。
- Mueller矩阵是万能工具:4×4实数矩阵,能处理部分偏振光。Jones矩阵搞不定的,它都能搞定。
- 转换有条件:Jones→Mueller的转换只适用于非退偏系统。如果系统有退偏效应,直接测Mueller矩阵吧。
我的建议:刚开始学的时候,先用手算几个简单例子。比如自然光通过偏振片,输出应该是半强度、完全偏振光。算熟了再用代码实现。这样遇到bug时,你能快速判断是代码问题还是物理概念问题。