Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
12f5a90
Added kalman filter neural latents package to the Bonsai.ML project
ncguilbeault Sep 12, 2025
79d48e3
Added `Bonsai.ML.Torch` project to references
ncguilbeault Sep 17, 2025
dd273a8
Added KalmanFilter class
ncguilbeault Sep 17, 2025
18bf162
Updated KalmanFilter class for better matrix, vector, and scalar vali…
ncguilbeault Sep 17, 2025
e17b252
Adding classes from original scripted demo
ncguilbeault Sep 17, 2025
5b88d0b
Added test repo for `Torch.LDS` to compare output with Python impleme…
ncguilbeault Sep 17, 2025
9f740cb
Updated Torch.LDS test for running test against Python script for est…
ncguilbeault Sep 17, 2025
22f7376
Added null checks to properties
ncguilbeault Sep 17, 2025
1740570
Updated target framework to include netstandard2.0
ncguilbeault Sep 18, 2025
d7dc4a1
Updated `CreateKalmanFilter` class to use `TensorConverter` for tenso…
ncguilbeault Sep 18, 2025
b4939f1
Refactored to use the KalmanFilterModelManager class
ncguilbeault Sep 18, 2025
3adfccf
Removed attempt to move EM algorithm to background process in favor o…
ncguilbeault Sep 18, 2025
408e93d
Removed extra properties of structs to streamline filter and smooth p…
ncguilbeault Sep 18, 2025
b4ad0ad
Refactored kalman filter class to support static methods, to streamli…
ncguilbeault Sep 18, 2025
91549b7
Added reserve method to model manager to support model creation from …
ncguilbeault Sep 18, 2025
22efde7
Added project references to tests
ncguilbeault Sep 18, 2025
30799b2
Removed unused variables that were previously there for plotting
ncguilbeault Sep 18, 2025
5c4adc6
Modified requirements.txt to use ssm from github instead of local
ncguilbeault Sep 18, 2025
e7a995b
Corrected bug with initialization of state and covariance
ncguilbeault Sep 19, 2025
0a68026
Refactored EM function for improved readability
ncguilbeault Sep 19, 2025
0d161e4
Updated test to correctly compare python and bonsai tensor results
ncguilbeault Sep 19, 2025
ef3d11a
Removed unused import
ncguilbeault Sep 29, 2025
5394bd3
Removed unused imports and added XML docs
ncguilbeault Sep 29, 2025
1bb1d45
Removed convoluted lock mechanism in favor of no lock
ncguilbeault Sep 29, 2025
b9f6880
Added cleanup to test
ncguilbeault Sep 29, 2025
a68f90e
Updated package installs and removed requirements
ncguilbeault Sep 29, 2025
91dea0c
Added the package to the documentation and included a basic article f…
ncguilbeault Sep 30, 2025
3b47e1c
Updated variable naming from state to mean to more accurately represe…
ncguilbeault Sep 30, 2025
3e3ca3b
Removed the line declaring requirements.txt is a deployment item
ncguilbeault Sep 30, 2025
7201ef9
Updated test workflow to use the variable name mean instead of state
ncguilbeault Sep 30, 2025
faff97e
Added functionality to allow fine grained control over which paramete…
ncguilbeault Sep 30, 2025
e647b4a
Updated package info with better description and shared package tags
ncguilbeault Oct 2, 2025
6a4ea9a
Added `Bonsai.ML.Torch.LDS.Design` package for visualizing latents
ncguilbeault Oct 6, 2025
567dae9
Moved color cycle class to shared `Bonsai.ML.Design` library
ncguilbeault Oct 6, 2025
174752c
Added keyword arguments to function call for precision
ncguilbeault Oct 6, 2025
3cbf26f
Added `StateVisualizer` class to design package to support visualizin…
ncguilbeault Oct 6, 2025
3d9c83b
Added explicit conversion to null for empty tensors
ncguilbeault Oct 6, 2025
4313d3b
Removed initial values from non-static Kalman smoother
ncguilbeault Oct 6, 2025
55dd7a6
Removed explicit null conversion from empty tensor
ncguilbeault Oct 6, 2025
0aab968
Updated `KalmanFilter` with to allow automatically populating null pa…
ncguilbeault Oct 6, 2025
2989912
Updated to allow parameters to contain null tensor values
ncguilbeault Oct 6, 2025
fdad188
Added XML docs to class
ncguilbeault Oct 6, 2025
9196517
Refactored to use autosize and expose plot control
ncguilbeault Oct 6, 2025
d65888a
Updated `NeuralLatentsTest` with default null values
ncguilbeault Oct 6, 2025
7c1c070
Added categories to class properties and renamed `ModelName` to just …
ncguilbeault Oct 6, 2025
f671f33
Added `ResetCombinator` to class attributes
ncguilbeault Oct 7, 2025
39897c1
Added generic class and interface to represent LDS state
ncguilbeault Oct 7, 2025
fcd19ad
Removed `ResetCombinator` attribute from classes where it is not needed
ncguilbeault Oct 7, 2025
ffac102
Changed naming from `xResult` to `xState` to for improved naming cons…
ncguilbeault Oct 7, 2025
8be2f91
Added property `Bonsai.ML.Torch.LDS.Design` project to ignore repacka…
ncguilbeault Oct 7, 2025
ae44889
Refactored `ExpectationMaximization` to emit values on each iteration…
ncguilbeault Oct 7, 2025
fd7a98b
Changed `ExpectationMaximization` operator to a type of `Combinator` …
ncguilbeault Oct 8, 2025
69fc383
Updated name of `Bonsai.ML.Torch.LDS` package to `Bonsai.ML.Lds.Torch…
ncguilbeault Oct 10, 2025
513feb7
Added `Bonsai.ML.Torch` using statements to classes that depend on th…
ncguilbeault Oct 10, 2025
cda33a3
Added operators to save and load the parameters of a Kalman filter model
ncguilbeault Oct 13, 2025
d9a1f46
Added Stochastic Subspace Identification method
ncguilbeault Oct 15, 2025
c0db6d4
Added method for `StochasticSubspaceIdentification` which is much fas…
ncguilbeault Oct 15, 2025
152875f
Refactored implementation to use explicit `KalmanFilter` property whi…
ncguilbeault Oct 15, 2025
c847d15
Ensure data are centered in SSID method
ncguilbeault Oct 17, 2025
3f55f63
Updated test workflow after changing packge to use explicit model pro…
ncguilbeault Oct 21, 2025
2f4c6fb
Refactored EM to avoid potential mismatch between numStates, numObser…
ncguilbeault Oct 21, 2025
4123370
Updated workflow to correctly update the parameters of the model
ncguilbeault Oct 21, 2025
b026f28
Modified python test script to install packages without caching packa…
ncguilbeault Oct 23, 2025
4cf1c76
Modified test case to download data and only run Bonsai script as opp…
ncguilbeault Oct 23, 2025
877d4a8
Removed redundant dependency
ncguilbeault Oct 23, 2025
4ec5828
Updated documentation with correct package naming
ncguilbeault Oct 28, 2025
a8f58c7
Changed struct and interface names from LdsState to full LinearDynami…
ncguilbeault Oct 28, 2025
4a9d64b
Removed redundant classes for orthogonalized and smoothed states in f…
ncguilbeault Oct 28, 2025
e3d51f6
Changed name from `UpdateParameters` to `UpdateKalmanFilterParameters…
ncguilbeault Oct 28, 2025
12b9422
Updated `StateVisualizer` to match changes in naming
ncguilbeault Oct 28, 2025
7b009de
Fixed test workflow after making changes
ncguilbeault Oct 28, 2025
a9d6079
Refactored `KalmanFilter` for improved parameter validation when `num…
ncguilbeault Oct 28, 2025
6b85e19
Added overload to create a `LinearDynamicalSystemState` from a stream…
ncguilbeault Oct 28, 2025
2b5c5ac
Refactored `SaveKalmanFilterParameters` class to save to a folder rat…
ncguilbeault Oct 28, 2025
d05077e
Refactored `KalmanFilterParameters` class to handle validation and mo…
ncguilbeault Oct 28, 2025
e68add5
Updated `LoadKalmanFilterParameters` operator to load parameters from…
ncguilbeault Oct 28, 2025
f89d750
Updated test to use `null` value in `NumStates` property
ncguilbeault Oct 28, 2025
1b51ae4
Removed unnecessary `PredictedState` struct and used `LinearDynamical…
ncguilbeault Oct 29, 2025
7e9bba8
Removed extra check when calling `Validate` on parameters
ncguilbeault Oct 29, 2025
92b36c6
Fixed issue with setting the incorrect number of iterations from the …
ncguilbeault Oct 29, 2025
7140980
Used tensorhelper method to extract float instead of explicitly movin…
ncguilbeault Oct 29, 2025
f32b653
Refactored `KalmanFilter` class to rely on device and scalar type pro…
ncguilbeault Oct 29, 2025
92a2175
Refactored `KalmanFilterParameters` to manage operations on tensors, …
ncguilbeault Oct 29, 2025
6898a64
Refactored `CreateKalmanFilter` operator to correctly pass in `Type` …
ncguilbeault Oct 29, 2025
40c1f52
Updated to allow specifying `Device` property when loading parameters
ncguilbeault Oct 29, 2025
7407cdf
Removed device and scalartype overrides in `Initialize` method
ncguilbeault Oct 29, 2025
a12b8d5
Refactored `LoadKalmanFilterParameters` operator to allow tensors to …
ncguilbeault Oct 29, 2025
36c6328
Updated filtering step to support missing nan values
ncguilbeault Oct 31, 2025
de2278a
Updated neural latents test to use new load/save tensor method
ncguilbeault Nov 10, 2025
50cc8c8
Updated to use `TensorOperatorConverter` class
ncguilbeault Nov 13, 2025
e326a85
Added default user-agent in request header when downloading test data…
ncguilbeault Jan 12, 2026
d306bc2
Added support in KF for estimating state and observation offset param…
ncguilbeault Jan 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion Bonsai.ML.sln
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Expand Down Expand Up @@ -40,6 +40,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{DEE5DD87
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bonsai.ML.Tests.Utilities", "tests\Bonsai.ML.Tests.Utilities\Bonsai.ML.Tests.Utilities.csproj", "{DB1090D3-38DD-404B-96DF-66BF3C39E508}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bonsai.ML.Lds.Torch", "src\Bonsai.ML.Lds.Torch\Bonsai.ML.Lds.Torch.csproj", "{41D4BEC7-AB1F-41E4-95FE-4DB23970FF4B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bonsai.ML.Lds.Torch.Tests", "tests\Bonsai.ML.Lds.Torch.Tests\Bonsai.ML.Lds.Torch.Tests.csproj", "{0B258929-0B07-4CE7-BE8D-A86BBC46AAD4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bonsai.ML.Lds.Torch.Design", "src\Bonsai.ML.Lds.Torch.Design\Bonsai.ML.Lds.Torch.Design.csproj", "{1F52DECD-1B2C-4F6C-996C-14C715283B80}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -102,6 +108,18 @@ Global
{DB1090D3-38DD-404B-96DF-66BF3C39E508}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB1090D3-38DD-404B-96DF-66BF3C39E508}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB1090D3-38DD-404B-96DF-66BF3C39E508}.Release|Any CPU.Build.0 = Release|Any CPU
{41D4BEC7-AB1F-41E4-95FE-4DB23970FF4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{41D4BEC7-AB1F-41E4-95FE-4DB23970FF4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{41D4BEC7-AB1F-41E4-95FE-4DB23970FF4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{41D4BEC7-AB1F-41E4-95FE-4DB23970FF4B}.Release|Any CPU.Build.0 = Release|Any CPU
{0B258929-0B07-4CE7-BE8D-A86BBC46AAD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B258929-0B07-4CE7-BE8D-A86BBC46AAD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0B258929-0B07-4CE7-BE8D-A86BBC46AAD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B258929-0B07-4CE7-BE8D-A86BBC46AAD4}.Release|Any CPU.Build.0 = Release|Any CPU
{1F52DECD-1B2C-4F6C-996C-14C715283B80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1F52DECD-1B2C-4F6C-996C-14C715283B80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1F52DECD-1B2C-4F6C-996C-14C715283B80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F52DECD-1B2C-4F6C-996C-14C715283B80}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
3 changes: 3 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ Interfaces with the [TorchSharp](https://github.com/dotnet/TorchSharp) package,
> [!NOTE]
> Bonsai.ML packages can be installed through Bonsai's integrated package manager and are generally ready for immediate use. However, some packages may require additional installation steps. Refer to the specific package section for detailed installation guides and documentation.

### Bonsai.ML.Lds.Torch
Linear dynamical systems implemented using the `Bonsai.ML.Torch` package for online filtering and smoothing of latent states and parameter estimation.

## Development Roadmap
The ultimate goal of the `Bonsai.ML` project is to bring powerful machine learning tools into Bonsai to enable intelligent experimental control. To achieve this, our plan is to incorporate several different packages, models, frameworks, and language integrations. You can follow our progress by going to the [Bonsai ML development roadmap](https://github.com/orgs/bonsai-rx/projects/7).

Expand Down
7 changes: 7 additions & 0 deletions docs/articles/Lds.Torch/lds-torch-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Bonsai.ML.Lds.Torch - Overview

This package provides an implementation of the Kalman filter, Rauch-Tung-Striebel (RTS) smoother, expectation maximization (EM) algorithm, and stochastic subspace identification, developed for online filtering, smoothing, and parameter estimation from data streams in Bonsai using the TorchSharp package.

## Installation Guide

Install the `Bonsai.ML.Lds.Torch` package from the Bonsai package manager. You will also need to follow the [instructions for setting up the Bonsai.ML.Torch package](../Torch/torch-overview.md) for running on the CPU or GPU.
4 changes: 3 additions & 1 deletion docs/articles/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@
href: PointProcessDecoder/ppd-overview.md
- name: Torch
- name: Overview
href: Torch/torch-overview.md
href: Torch/torch-overview.md
- name: Lds.Torch
href: Lds.Torch/lds-torch-overview.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

using OxyPlot;

namespace Bonsai.ML.PointProcessDecoder.Design
namespace Bonsai.ML.Design
{
/// <summary>
/// Enumerates the colors and provides a preset collection of colors to cycle through.
Expand Down
19 changes: 19 additions & 0 deletions src/Bonsai.ML.Lds.Torch.Design/Bonsai.ML.Lds.Torch.Design.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Visualizers for the Bonsai.ML.Lds.Torch library.</Description>
<PackageTags>$(PackageTags) Torch LDS Design</PackageTags>
<TargetFramework>net472</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Bonsai.Core" Version="2.9.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bonsai.ML.Lds.Torch\Bonsai.ML.Lds.Torch.csproj" />
<ProjectReference Include="..\Bonsai.ML.Design\Bonsai.ML.Design.csproj" />
</ItemGroup>
<PropertyGroup>
<!-- This property is needed to avoid repacking the native SkiaSharp libraries, which should already be included with the Bonsai.ML.Torch -->
<ShouldIncludeNativeSkiaSharp>false</ShouldIncludeNativeSkiaSharp>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System;
using System.Reactive;
using System.Linq;
using System.Windows.Forms;
using System.Collections.Generic;

using Bonsai;
using Bonsai.Design;
using Bonsai.ML.Design;

using OxyPlot;
using OxyPlot.Series;

using static TorchSharp.torch;

[assembly: TypeVisualizer(typeof(Bonsai.ML.Lds.Torch.Design.ExpectationMaximizationVisualizer),
Comment thread
glopesdev marked this conversation as resolved.
Target = typeof(Bonsai.ML.Lds.Torch.ExpectationMaximizationResult))]

namespace Bonsai.ML.Lds.Torch.Design;

/// <summary>
/// Provides a visualizer for the state means and covariances from a Kalman filter or smoother.
/// </summary>
public class ExpectationMaximizationVisualizer : BufferedVisualizer
{
private TimeSeriesOxyPlotBase _plot;
private LineSeries _lineSeries;

/// <summary>
/// Gets the underlying plot control.
/// </summary>
public TimeSeriesOxyPlotBase Plot => _plot;

/// <inheritdoc/>
public override void Load(IServiceProvider provider)
{
_plot = new TimeSeriesOxyPlotBase()
{
Dock = DockStyle.Fill,
StartTime = DateTime.Now,
BufferData = true,
ValueLabel = "Log Likelihood"
};

_lineSeries = _plot.AddNewLineSeries("Log Likelihood", OxyColors.Blue);

var visualizerService = (IDialogTypeVisualizerService)provider.GetService(typeof(IDialogTypeVisualizerService));
visualizerService?.AddControl(_plot);
}

/// <inheritdoc/>
public override void Show(object value)
{
}

/// <inheritdoc/>
protected override void Show(DateTime time, object value)
{
if (value is null) return;

if (value is not ExpectationMaximizationResult result) return;

var logLikelihood = result.LogLikelihood;
if (logLikelihood is null) return;

var ll = logLikelihood[-1].to_type(ScalarType.Float64).item<double>();

_plot.AddToLineSeries(
lineSeries: _lineSeries,
time: time,
value: ll
);
}

/// <inheritdoc/>
protected override void ShowBuffer(IList<Timestamped<object>> values)
{
base.ShowBuffer(values);
if (values.Count > 0)
{
_plot.UpdatePlot();
}
}

/// <inheritdoc/>
public override void Unload()
{
if (!_plot.IsDisposed) _plot.Dispose();
}
}
6 changes: 6 additions & 0 deletions src/Bonsai.ML.Lds.Torch.Design/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using Bonsai;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: XmlNamespacePrefix("clr-namespace:Bonsai.ML.Lds.Torch.Design", null)]
10 changes: 10 additions & 0 deletions src/Bonsai.ML.Lds.Torch.Design/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"profiles": {
"Bonsai": {
"commandName": "Executable",
"executablePath": "$(BonsaiExecutablePath)",
"commandLineArgs": "--lib:\"$(TargetDir).\"",
"nativeDebugging": true
}
}
}
Loading
Loading