filterpy icon indicating copy to clipboard operation
filterpy copied to clipboard

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

Open Mahdi22223 opened this issue 2 years ago • 2 comments

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()

Mahdi22223 avatar Nov 03 '23 06:11 Mahdi22223

Hello,

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

efeerdogannn avatar Apr 23 '24 12:04 efeerdogannn

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

ariel-m-s avatar Aug 30 '24 14:08 ariel-m-s