{"id":6740,"library":"nfoursid","title":"NFoursID","description":"NFoursID is a Python library that implements the N4SID algorithm for subspace identification, along with Kalman filtering and state-space models. State-space models are versatile tools for representing multi-dimensional time series, encompassing models like ARMAX. The current version is 1.0.2. The project appears active, with its latest release (1.0.2) showing an unusual future publication date of July 24, 2025, on PyPI.","status":"active","version":"1.0.2","language":"en","source_language":"en","source_url":"https://github.com/spmvg/nfoursid","tags":["state-space models","kalman filter","subspace identification","timeseries","system identification","control systems"],"install":[{"cmd":"pip install nfoursid","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Numerical operations and array handling.","package":"numpy","optional":false},{"reason":"Dataframe manipulation for input/output.","package":"pandas","optional":false},{"reason":"Plotting functionalities for analysis and visualization.","package":"matplotlib","optional":false}],"imports":[{"symbol":"NFourSID","correct":"from nfoursid.nfoursid import NFourSID"},{"symbol":"Kalman","correct":"from nfoursid.kalman import Kalman"},{"symbol":"StateSpace","correct":"from nfoursid.state_space import StateSpace"}],"quickstart":{"code":"import numpy as np\nimport pandas as pd\nfrom nfoursid.nfoursid import NFourSID\nfrom nfoursid.state_space import StateSpace\nfrom nfoursid.kalman import Kalman\n\n# 1. Define a state-space model (example parameters)\nA = np.array([[0.9, 0.1], [0, 0.9]])\nB = np.array([[1], [0]])\nC = np.array([[0.5, 0.5]])\nD = np.array([[0]])\n\nstate_space_true = StateSpace(A, B, C, D)\n\n# 2. Simulate some data\nnum_datapoints = 100\ninputs = np.random.randn(num_datapoints, 1) * 0.1 # Small random inputs\noutputs = []\n\nfor i in range(num_datapoints):\n    output_step = state_space_true.step(inputs[i].reshape(-1, 1), noise=np.random.randn(1, 1) * 0.05)\n    outputs.append(output_step.flatten())\n\ndata = pd.DataFrame({\n    'input_0': inputs.flatten(),\n    'output_0': np.array(outputs).flatten()\n})\n\n# 3. Perform N4SID identification\noutput_columns = ['output_0']\ninput_columns = ['input_0']\nnum_block_rows = 2 # See warnings regarding this parameter\n\nnfoursid_estimator = NFourSID(\n    dataframe=data,\n    output_columns=output_columns,\n    input_columns=input_columns,\n    num_block_rows=num_block_rows\n)\n\nnfoursid_estimator.subspace_identification() # Essential before system_identification for proper order detection\n\n# Determine system order (e.g., from eigenvalue plot, assume 2 for this example)\nrank = 2\n\nstate_space_identified, covariance_matrix = nfoursid_estimator.system_identification(rank=rank)\n\nprint(\"Identified State-Space A matrix:\\n\", state_space_identified.a)\nprint(\"Identified State-Space C matrix:\\n\", state_space_identified.c)\n\n# 4. Use a Kalman filter for prediction/estimation\nkalman_filter = Kalman(state_space_identified, covariance_matrix)\n\n# Simulate a few steps with the Kalman filter\nfiltered_outputs = []\nfor i in range(num_datapoints):\n    kalman_filter.step(data[output_columns].iloc[i].values.reshape(-1,1),\n                       data[input_columns].iloc[i].values.reshape(-1,1))\n    filtered_outputs.append(kalman_filter.to_dataframe()['output_0']['filtered'].iloc[-1])\n\nprint(\"First 5 actual outputs:\", data['output_0'].head().tolist())\nprint(\"First 5 filtered outputs:\", filtered_outputs[:5])","lang":"python","description":"This quickstart demonstrates the core workflow of `nfoursid`: defining a true state-space model, simulating data, using the `NFourSID` class for system identification to recover a model from data, and then applying a `Kalman` filter for state estimation."},"warnings":[{"fix":"Experiment with `num_block_rows` values, typically starting with values related to expected system order and data length. Refer to subspace identification literature (e.g., the cited references [1] for guidance). The `plot_eigenvalues` method can help in assessing the choice.","message":"The `num_block_rows` parameter in the `NFourSID` constructor significantly impacts both computational complexity and the ability to correctly determine the system order. Choosing it too large increases computation, while choosing it too small may prevent accurate order determination or violate theoretical assumptions.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always perform `subspace_identification()` first, then analyze `nfoursid_estimator.plot_eigenvalues()` to visually confirm the appropriate `rank` before calling `system_identification(rank=...)`.","message":"For effective system order determination, it's generally recommended to call `nfoursid_estimator.subspace_identification()` before `nfoursid_estimator.system_identification()` and inspect the eigenvalues using `plot_eigenvalues`. Skipping `subspace_identification` might lead to an incorrect system order if the `rank` parameter is not chosen carefully in `system_identification`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Familiarize yourself with the theoretical background of N4SID and Kalman filters (e.g., through the references provided in the documentation [1, 2]). Carefully review the example notebooks and documentation to understand how to correctly define models and interpret outputs.","message":"The `nfoursid` library assumes a foundational understanding of subspace identification, Kalman filtering, and state-space models. Users new to these concepts may struggle with model setup, parameter interpretation, and result validation, leading to potential misapplication.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z","problems":[]}