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矩阵变换,最终得到输出光的偏振态。整个体系围绕「部分偏振光」这个核心展开。

Mueller矩阵与Stokes矢量知识体系 Mueller矩阵与Stokes矢量知识体系 Stokes参数 S₀:总光强 S₁:水平-垂直 S₂:+45°- -45° S₃:右旋-左旋 偏振度 DoP DoP=1:完全偏振 0<DoP<1:部分偏振 DoP=0:非偏振 Mueller矩阵:4×4实数变换 核心公式:S_out = M · S_in | 可处理部分偏振光 | 与Jones矩阵可互相转换(非退偏系统)

4.8 实战要点总结

聊了这么多,我总结几个关键点:

  1. Stokes参数是基础:四个实数,描述任何偏振态。记住S₀是总光强,其他三个是差值。
  2. DoP是核心指标:一个数字告诉你光有多「纯」。做实验时先测DoP,心里就有底了。
  3. Mueller矩阵是万能工具:4×4实数矩阵,能处理部分偏振光。Jones矩阵搞不定的,它都能搞定。
  4. 转换有条件:Jones→Mueller的转换只适用于非退偏系统。如果系统有退偏效应,直接测Mueller矩阵吧。

我的建议:刚开始学的时候,先用手算几个简单例子。比如自然光通过偏振片,输出应该是半强度、完全偏振光。算熟了再用代码实现。这样遇到bug时,你能快速判断是代码问题还是物理概念问题。