---
id: wiki-2026-0508-particle-filter-algorithms
title: Particle Filter Algorithms
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Sequential Monte Carlo, SMC, Bootstrap Filter]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [bayesian, state-estimation, monte-carlo, robotics]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: Python
  framework: NumPy/PyTorch
---

# Particle Filter Algorithms

## 매 한 줄
> **"매 nonlinear non-Gaussian state estimation 매 weighted samples로"**. 매 PF는 매 1993 Gordon-Salmond-Smith bootstrap filter에서 출발, 매 Kalman/EKF가 매 fail하는 multimodal posterior을 매 resampling으로 track, 매 2026 SLAM·target tracking·option pricing·epidemiology·neural state-space modeling에서 매 standard SMC tool.

## 매 핵심

### 매 problem
- State-space: xₜ = f(xₜ₋₁) + wₜ, yₜ = h(xₜ) + vₜ.
- Goal: posterior p(xₜ | y₁:ₜ).
- Bayes filter recursion (predict, update).

### 매 PF idea
- p(xₜ | y₁:ₜ) ≈ Σᵢ wₜ⁽ⁱ⁾ δ(xₜ - xₜ⁽ⁱ⁾).
- N particles xₜ⁽ⁱ⁾ with weights wₜ⁽ⁱ⁾.
- Predict: sample xₜ⁽ⁱ⁾ ~ q(xₜ | xₜ₋₁⁽ⁱ⁾, yₜ).
- Update: wₜ⁽ⁱ⁾ ∝ wₜ₋₁⁽ⁱ⁾ p(yₜ|xₜ⁽ⁱ⁾) p(xₜ⁽ⁱ⁾|xₜ₋₁⁽ⁱ⁾) / q(...).
- Resample when ESS < threshold.

### 매 변형
- **Bootstrap filter**: q = transition prior; simplest.
- **Auxiliary PF**: 매 informative proposal using yₜ.
- **Rao-Blackwellized PF**: marginalize linear-Gaussian sub-state analytically.
- **Differentiable PF (2026)**: end-to-end with relaxed resampling.
- **PMCMC**: PF inside MCMC for parameter inference.

### 매 응용
1. Robot localization (Monte Carlo Localization, MCL).
2. Visual / multi-target tracking.
3. Stochastic volatility estimation.
4. Epidemic forecasting (SEIR with noise).
5. Neural state-space models for time series (2026 Mamba-PF hybrids).

## 💻 패턴

### Bootstrap Particle Filter
```python
import numpy as np

def bootstrap_pf(y, f, h, q_noise, r_noise, N=1000, x0_sampler=None):
    T = len(y)
    x = x0_sampler(N)
    w = np.ones(N) / N
    means = np.zeros(T)
    for t in range(T):
        x = f(x) + q_noise(N)            # predict
        lik = np.exp(-0.5 * ((y[t] - h(x))/r_noise)**2)
        w = w * lik
        w /= w.sum()
        means[t] = np.sum(w * x)
        ess = 1.0 / np.sum(w*w)
        if ess < N/2:                     # systematic resample
            idx = systematic_resample(w)
            x = x[idx]; w = np.ones(N) / N
    return means
```

### Systematic resampling
```python
def systematic_resample(w):
    N = len(w)
    positions = (np.arange(N) + np.random.uniform()) / N
    cumw = np.cumsum(w)
    idx = np.zeros(N, dtype=int)
    i = j = 0
    while i < N:
        if positions[i] < cumw[j]:
            idx[i] = j; i += 1
        else:
            j += 1
    return idx
```

### Auxiliary PF
```python
def apf_step(x, w, y_next, f_mean, h, r_noise):
    mu = f_mean(x)                                     # predicted mean
    pred_lik = np.exp(-0.5*((y_next - h(mu))/r_noise)**2)
    aux_w = w * pred_lik
    aux_w /= aux_w.sum()
    idx = systematic_resample(aux_w)
    x_new = f(x[idx]) + q_noise(len(x))
    lik = np.exp(-0.5*((y_next - h(x_new))/r_noise)**2)
    new_w = lik / pred_lik[idx]
    new_w /= new_w.sum()
    return x_new, new_w
```

### Robot MCL (2D)
```python
# state: [x, y, theta], obs: distance to landmarks
def motion_model(particles, u, sigma):
    dx = u[0]*np.cos(particles[:,2]) + sigma*np.random.randn(len(particles))
    dy = u[0]*np.sin(particles[:,2]) + sigma*np.random.randn(len(particles))
    dtheta = u[1] + 0.05*np.random.randn(len(particles))
    return particles + np.column_stack([dx, dy, dtheta])

def sensor_model(particles, landmarks, obs, sigma):
    dists = np.linalg.norm(particles[:,None,:2] - landmarks[None,:,:], axis=2)
    return np.exp(-0.5*((dists - obs[None,:])/sigma)**2).prod(axis=1)
```

### Differentiable PF (PyTorch, 2026 style)
```python
import torch
def soft_resample(w, alpha=0.5):
    N = len(w)
    soft_w = alpha*w + (1-alpha)/N
    idx = torch.multinomial(soft_w, N, replacement=True)
    return idx, w[idx] / soft_w[idx]   # importance correction, differentiable
```

## 매 결정 기준
| 상황 | Approach |
|---|---|
| Linear Gaussian | Kalman Filter (exact, no PF needed) |
| Mildly nonlinear, unimodal | EKF / UKF |
| Nonlinear or multimodal | Particle Filter |
| High-dim state (>10) | RBPF or PF + structured proposal |
| Need parameter inference too | PMCMC / SMC² |
| End-to-end learning | Differentiable PF |

**기본값**: Bootstrap PF with systematic resampling (ESS<N/2 trigger), N=1000-10000.

## 🔗 Graph
- 부모: [[Sequential-Monte-Carlo]]
- 변형: [[Bootstrap-Filter]]
- 응용: [[SLAM]]
- Adjacent: [[Kalman-Filter-and-State-Tracking|Kalman-Filter]]

## 🤖 LLM 활용
**언제**: PF tuning rationale (N choice, resample threshold), proposal design discussion, debug degenerate weights.
**언제 X**: 실제 sampling/resampling computation.

## ❌ 안티패턴
- **No resampling**: 매 weights collapse → 1 particle dominates (degeneracy).
- **Resample every step**: 매 sample impoverishment — 매 ESS-based trigger 매 사용.
- **Bootstrap in high-dim**: 매 prior proposal 매 explodes — 매 informative proposal 매 필수.
- **Too few particles**: 매 N<500 매 high-dim에 매 useless.
- **Non-systematic resample**: 매 multinomial 매 high-variance — 매 systematic/stratified 매 사용.

## 🧪 검증 / 중복
- Verified (Doucet et al "Sequential Monte Carlo Methods", Thrun "Probabilistic Robotics").
- 신뢰도 A.

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — bootstrap/APF/RBPF + differentiable PF (2026) |
