Skip to main content
  1. Projects/
  2. ChatGPT slop/

Implementing a 1D Filter

·469 words·3 mins
Kalman Filter - This article is part of a series.
Part 2: This Article

Simple 1D Example
#

Let’s implement a Kalman filter for the simplest case: estimating a constant value from noisy measurements.

Problem Setup
#

We want to estimate the temperature of a room:

  • True temperature is constant
  • Thermometer gives noisy readings
  • Noise has standard deviation of 2°C

Code Implementation
#

import numpy as np
import matplotlib.pyplot as plt

class KalmanFilter1D:
    def __init__(self, initial_state, initial_uncertainty, 
                 process_noise, measurement_noise):
        """
        Simple 1D Kalman filter
        
        Args:
            initial_state: Initial estimate
            initial_uncertainty: Initial estimate uncertainty
            process_noise: Process noise variance (Q)
            measurement_noise: Measurement noise variance (R)
        """
        self.x = initial_state  # State estimate
        self.P = initial_uncertainty  # Estimate uncertainty
        self.Q = process_noise
        self.R = measurement_noise
    
    def predict(self):
        """Prediction step - for constant value, state doesn't change"""
        # x_k|k-1 = x_{k-1|k-1} (constant value)
        # P_k|k-1 = P_{k-1|k-1} + Q
        self.P = self.P + self.Q
    
    def update(self, measurement):
        """Update step - incorporate new measurement"""
        # Kalman gain
        K = self.P / (self.P + self.R)
        
        # Update estimate with measurement
        self.x = self.x + K * (measurement - self.x)
        
        # Update uncertainty
        self.P = (1 - K) * self.P
        
        return self.x

# Simulation
true_temperature = 22.0  # True room temperature
measurement_noise = 2.0  # Thermometer noise std dev

# Create filter
kf = KalmanFilter1D(
    initial_state=20.0,      # Start with guess of 20°C
    initial_uncertainty=10.0, # High initial uncertainty
    process_noise=0.01,       # Temperature changes slowly
    measurement_noise=measurement_noise**2  # Convert std dev to variance
)

# Generate noisy measurements
num_measurements = 50
measurements = true_temperature + np.random.normal(0, measurement_noise, num_measurements)

# Run filter
estimates = []
for z in measurements:
    kf.predict()
    estimate = kf.update(z)
    estimates.append(estimate)

# Plot results
plt.figure(figsize=(12, 6))
plt.plot(measurements, 'r.', label='Noisy Measurements', alpha=0.5)
plt.plot(estimates, 'b-', label='Kalman Filter Estimate', linewidth=2)
plt.axhline(true_temperature, color='g', linestyle='--', label='True Value')
plt.xlabel('Measurement Number')
plt.ylabel('Temperature (°C)')
plt.legend()
plt.title('1D Kalman Filter: Temperature Estimation')
plt.grid(True)
plt.show()

Results
#

The filter quickly converges to the true value despite noisy measurements!

After just 10 measurements:

  • Raw measurement error: ±2°C
  • Filter estimate error: ±0.3°C
  • 6.7x improvement in accuracy!

Understanding the Code
#

Predict Step
#

self.P = self.P + self.Q

Uncertainty increases slightly (we’re less sure over time).

Update Step
#

K = self.P / (self.P + self.R)

Kalman gain balances prediction vs. measurement.

self.x = self.x + K * (measurement - self.x)

Move estimate toward measurement, weighted by gain.

self.P = (1 - K) * self.P

Uncertainty decreases (we’re more confident after measurement).

Key Observations
#

  1. Initial convergence: Filter starts uncertain, quickly converges
  2. Noise reduction: Estimates are much smoother than raw measurements
  3. Optimal fusion: Automatically balances prediction and measurement

Tuning Parameters
#

Process Noise (Q)
#

  • Higher Q → trust measurements more
  • Lower Q → trust predictions more

Measurement Noise (R)
#

  • Should match actual sensor noise
  • Higher R → slower convergence
  • Lower R → faster convergence (but assumes better sensor)

Next Steps
#

This 1D filter is simple but limited. Next, we’ll extend to multi-dimensional tracking!

Kalman Filter - This article is part of a series.
Part 2: This Article