3. Mueller矩阵与Stokes-Mueller formalism

好,咱们进入第三章。前面我们聊了Stokes矢量,它像个快照,能告诉你一束光当前的偏振态。但光学系统是会改变偏振态的——透镜会引入应力双折射,反射镜会改变s和p分量的相位,散射介质会退偏。怎么描述这种「输入→输出」的变换关系?

答案就是Mueller矩阵。我个人觉得,这是偏振测量里最优雅的数学工具之一。它把整个光学系统当成一个黑盒子,你输入一个Stokes矢量,它输出另一个Stokes矢量,中间全靠一个4×4矩阵搞定。

3.1 Mueller矩阵的定义

定义其实很简单。假设入射光的Stokes矢量为 Sin,出射光的Stokes矢量为 Sout,那么:

S_out = M · S_in

展开写就是:

┌ S0_out ┐   ┌ m00  m01  m02  m03 ┐ ┌ S0_in ┐
│ S1_out │ = │ m10  m11  m12  m13 │ │ S1_in │
│ S2_out │   │ m20  m21  m22  m23 │ │ S2_in │
└ S3_out ┘   └ m30  m31  m32  m33 ┘ └ S3_in ┘

每个元素mij都有物理意义。m00是总透过率,第一行描述系统对光强的响应,第一列描述系统对非偏振光的响应。剩下的3×3子矩阵,才是真正处理偏振信息的部分。

关键点:Mueller矩阵可以处理部分偏振光和退偏效应。这是它比Jones矩阵更强大的地方——Jones矩阵只能处理完全偏振光。

嗯,这里要注意:不是随便一个4×4矩阵都能当Mueller矩阵用。它必须满足物理可实现条件——输出光的偏振度不能大于1,总光强不能为负。我在项目里见过有人拿测量数据硬凑矩阵,结果算出来的输出光偏振度1.3,明显是错的。

3.2 典型光学元件的Mueller矩阵

记住几个常用的,工作中会反复遇到。

3.2.1 理想线偏振器

透光轴沿水平方向(0°)的理想线偏振器:

M_pol(0°) = ½ ┌ 1  1  0  0 ┐
              │ 1  1  0  0 │
              │ 0  0  0  0 │
              └ 0  0  0  0 ┘

如果透光轴在θ角度,需要做旋转。旋转矩阵长这样:

M_pol(θ) = R(-θ) · M_pol(0°) · R(θ)

其中旋转矩阵R(θ)为:

R(θ) = ┌ 1     0        0       0 ┐
       │ 0  cos(2θ)  sin(2θ)   0 │
       │ 0 -sin(2θ)  cos(2θ)   0 │
       └ 0     0        0       1 ┘

为什么是2θ?因为偏振是二阶张量效应,旋转一次光学元件,偏振态变化两倍角度。我第一次推导时也卡在这儿,后来画了个Poincaré球才想明白。

3.2.2 波片(相位延迟器)

快轴沿水平方向、延迟量为δ的波片:

M_ret(δ, 0°) = ┌ 1  0      0       0    ┐
                │ 0  1      0       0    │
                │ 0  0  cos(δ)  sin(δ)  │
                │ 0  0 -sin(δ)  cos(δ)  │
                └ 0  0      0       1    ┘

常用的两个特例:

  • 四分之一波片(QWP):δ = 90°,cos(δ)=0,sin(δ)=1
  • 半波片(HWP):δ = 180°,cos(δ)=-1,sin(δ)=0

实战技巧:我在搭建Mueller矩阵成像系统时,习惯先用QWP和线偏振器做系统标定。QWP能把线偏振光变成圆偏振光,反过来也能把圆偏振光变成线偏振光——这个特性在测量中特别有用。

3.2.3 反射镜

理想反射镜的Mueller矩阵:

M_mirror = ┌ 1  0  0  0 ┐
           │ 0  1  0  0 │
           │ 0  0 -1  0 │
           └ 0  0  0 -1 ┘

注意S2和S3分量反号。这意味着右旋圆偏振光经反射后会变成左旋圆偏振光。如果你在光学系统中用了奇数个反射镜,记得补偿这个符号变化。

3.2.4 退偏器

理想退偏器把所有偏振光变成非偏振光:

M_depol = ┌ 1  0  0  0 ┐
          │ 0  0  0  0 │
          │ 0  0  0  0 │
          └ 0  0  0  0 ┘

实际退偏器做不到这么完美,但原理就是这个意思。

3.3 Stokes矢量与Mueller矩阵的运算规则

这部分其实不复杂,但有几个坑要避开。

3.3.1 级联系统

光依次经过多个元件时,总Mueller矩阵是各元件矩阵的乘积,顺序从右往左:

S_out = M_N · ... · M_2 · M_1 · S_in

光先经过M1,再经过M2,最后经过MN。写代码时最容易搞反顺序,我吃过这个亏——有一次仿真结果死活不对,查了两天才发现矩阵乘反了。

3.3.2 光强计算

出射光的总光强就是S0分量:

I_out = S0_out = m00·S0_in + m01·S1_in + m02·S2_in + m03·S3_in

如果入射光是非偏振光(Sin = [1, 0, 0, 0]T),那么I_out = m00。所以m00也叫「非偏振光透过率」。

3.3.3 偏振度计算

从输出Stokes矢量可以算出输出光的偏振度:

DoP = sqrt(S1² + S2² + S3²) / S0

如果DoP > 1,说明你的Mueller矩阵有问题,或者测量数据有噪声。我曾经用有噪声的数据算出一个DoP=1.08,后来发现是探测器饱和了。

避坑指南:我曾经在测量生物组织样本时,发现Mueller矩阵的m00元素异常大。排查了半天,原来是样本架有应力双折射,相当于额外串了一个波片。从那以后,我每次实验前都会先测一遍空载系统的Mueller矩阵做背景扣除。

3.4 知识结构总览

下面这张图把本章的核心逻辑串起来了:

Mueller矩阵与Stokes-Mueller formalism 知识结构图 Mueller矩阵与Stokes-Mueller formalism 知识结构 Mueller矩阵 M (4×4) 输入 Stokes 矢量 S_in 输出 Stokes 矢量 S_out S_out = M · S_in 线偏振器 波片 (QWP/HWP) 反射镜 退偏器 运算规则:级联乘法(右→左)| 光强 = S0 | DoP = √(S1²+S2²+S3²)/S0

3.5 典型元件Mueller矩阵速查表

元件 参数 Mueller矩阵(简化形式)
水平线偏振器 透光轴0° ½·diag(1,1,0,0) + ½·off(1,1,0,0)
四分之一波片 快轴0°, δ=90° diag(1,1,0,1) + off(0,0,1,0) 调整符号
半波片 快轴0°, δ=180° diag(1,1,-1,-1)
理想反射镜 垂直入射 diag(1,1,-1,-1)
理想退偏器 完全退偏 diag(1,0,0,0)

我的习惯:做实验前,我会先在Python里把整个光路的Mueller矩阵链算一遍。用numpy做矩阵乘法,几分钟就能跑完。如果仿真结果和实验对不上,至少能排除数学错误。代码大概长这样:

import numpy as np

def polarizer(theta):
    """返回透光轴在theta的线偏振器Mueller矩阵"""
    R = np.array([[1, 0, 0, 0],
                  [0, np.cos(2*theta), np.sin(2*theta), 0],
                  [0, -np.sin(2*theta), np.cos(2*theta), 0],
                  [0, 0, 0, 1]])
    M0 = 0.5 * np.array([[1, 1, 0, 0],
                         [1, 1, 0, 0],
                         [0, 0, 0, 0],
                         [0, 0, 0, 0]])
    return R.T @ M0 @ R

def qwp(fast_axis):
    """返回快轴在fast_axis的四分之一波片Mueller矩阵"""
    R = np.array([[1, 0, 0, 0],
                  [0, np.cos(2*fast_axis), np.sin(2*fast_axis), 0],
                  [0, -np.sin(2*fast_axis), np.cos(2*fast_axis), 0],
                  [0, 0, 0, 1]])
    M0 = np.array([[1, 0, 0, 0],
                   [0, 1, 0, 0],
                   [0, 0, 0, 1],
                   [0, 0, -1, 0]])
    return R.T @ M0 @ R

# 示例:光经过QWP(45°)再经过水平偏振器
M_total = polarizer(0) @ qwp(np.pi/4)
S_in = np.array([1, 0, 0, 1])  # 右旋圆偏振光
S_out = M_total @ S_in
print(f"输出Stokes矢量: {S_out}")

跑一下这段代码,你会发现右旋圆偏振光经过45°QWP变成水平线偏振光,再经过水平偏振器全部通过——这就是QWP的线偏振光→圆偏振光转换的逆过程。

好了,Mueller矩阵这块儿先到这儿。记住核心思想:一个4×4矩阵,搞定所有偏振变换。后面讲测量方法时,你会发现所有技术都是在想办法求解这个矩阵的16个元素。