rlabbe / filterpy

Python Kalman filtering and optimal estimation library. Implements Kalman filter, particle filter, Extended Kalman filter, Unscented Kalman filter, g-h (alpha-beta), least squares, H Infinity, smoothers, and more. Has companion book 'Kalman and Bayesian Filters in Python'.
MIT License
3.3k stars 615 forks source link

LinAlgError: 1-th leading minor of the array is not positive definite #296

Open Mahdi22223 opened 11 months ago

Mahdi22223 commented 11 months ago

Dear Friends,

I am a beginner in using the Unscented Kalman Filter (UKF) and would greatly appreciate your assistance with an issue I'm encountering. Despite my efforts, I consistently receive the error: LinAlgError: 1-th leading minor of the array is not positive definite.

I've tried to mitigate this issue by adding a regularization term to relax the condition when the state covariance matrix P becomes non-positive definite after the prediction step. However, despite numerous adjustments to the parameters, the error persists.

Currently, I'm working with a simple degradation model that incorporates a Wiener process. My goal is to understand and resolve this issue before further refining the model.

Any guidance or suggestions would be immensely helpful.

from filterpy.kalman import UnscentedKalmanFilter as UKF from filterpy.kalman import MerweScaledSigmaPoints import numpy as np import matplotlib.pyplot as plt degradation_rate = 0.1 # Set this to your desired degradation rate

Define the state transition function

def f(x, dt): degradation_rate = 0.1 # Set this to your desired degradation rate w = np.random.normal(0, 1) # Wiener process return np.abs(x - dt * degradation_rate + w) # Use absolute value to ensure the state is non-negative

def h(x): return x

dt = 0.1 # time step

points = MerweScaledSigmaPoints(1, alpha=0.001, beta=2., kappa=0)

ukf = UKF(dim_x=1, dim_z=1, dt=dt, fx=f, hx=h, points=points)

ukf.x = np.array([1.]) # initial RUL

ukf.P = np.eye(1) * 10.0 # Set P to be a diagonal matrix

regularization_value = 1e-3

ukf.Q = np.eye(1) * 10.0 + regularization_value # Set Q to be a diagonal matrix and add regularization

ukf.R = np.array([[0.1]])+ regularization_value

Generate ground truth and observations

t = np.arange(0, 10, dt) ground_truth = 100 - t * degradation_rate observations = ground_truth + np.random.normal(0, np.sqrt(ukf.R[0, 0]), size=t.shape)

Apply the UKF and collect predictions

predictions = [] for z in observations: ukf.predict() ukf.update(np.array([z])) predictions.append(ukf.x[0])

Plot ground truth, UKF predictions, and observations

plt.figure(figsize=(10, 6)) plt.plot(t, ground_truth, 'g-', label='Ground Truth') plt.plot(t, predictions, 'r-', label='UKF Predictions') plt.scatter(t, observations, c='b', label='Observations') plt.legend() plt.xlabel('Time') plt.ylabel('RUL') plt.title('UKF for RUL Estimation') plt.grid(True) plt.show()

efeerdogannn commented 5 months ago

Hello,

I have the same problem as you when using the UKF. Did you make any progress onsolving the issue?

ariel-m-s commented 1 month ago

Did you try playing around with different values for Q and R?