-
Notifications
You must be signed in to change notification settings - Fork 5
Add Linear System Operators to Bonsai.ML.Torch
#83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
01b3ed0
93adfcb
a37c8c4
ace5c1f
244ea28
c82c661
6ceedd1
6aa9dbd
06d81b6
99f73aa
e29465e
f95495d
25b6f6d
f0dd68c
a7fcd4d
7c4e69c
b6c26b3
b060952
80f53df
e8fb927
aabfdec
357fb3e
aea5210
6912521
9bc86a8
a68138a
596498f
d5c7279
8e125cc
c6a361f
7646fc2
2912207
5591b3d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,26 +1,24 @@ | ||
| using System; | ||
| using System; | ||
| using System.ComponentModel; | ||
| using System.Reactive.Linq; | ||
| using static TorchSharp.torch; | ||
|
|
||
| namespace Bonsai.ML.Torch.LinearAlgebra | ||
| namespace Bonsai.ML.Torch.LinearAlgebra; | ||
|
|
||
| /// <summary> | ||
| /// Represents an operator that computes the Cholesky decomposition of a complex Hermitian or real symmetric | ||
| /// positive-definite matrix. | ||
| /// </summary> | ||
| [Combinator] | ||
| [Description("Computes the Cholesky decomposition of a complex Hermitian or real symmetric positive-definite matrix.")] | ||
| [WorkflowElementCategory(ElementCategory.Transform)] | ||
| public class CholeskyDecomposition | ||
| { | ||
| /// <summary> | ||
| /// Computes the Cholesky decomposition of a complex Hermitian or real symmetric positive-definite matrix. | ||
| /// </summary> | ||
| [Combinator] | ||
| [Description("Computes the Cholesky decomposition of a complex Hermitian or real symmetric positive-definite matrix.")] | ||
| [WorkflowElementCategory(ElementCategory.Transform)] | ||
| public class CholeskyDecomposition | ||
| public IObservable<Tensor> Process(IObservable<Tensor> source) | ||
| { | ||
| /// <summary> | ||
| /// Computes the Cholesky decomposition of a complex Hermitian or real symmetric positive-definite matrix. | ||
| /// </summary> | ||
| /// <param name="source"></param> | ||
| /// <returns></returns> | ||
| public IObservable<Tensor> Process(IObservable<Tensor> source) | ||
| { | ||
| return source.Select(linalg.cholesky); | ||
| } | ||
| return source.Select(linalg.cholesky); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| using System; | ||
| using System.ComponentModel; | ||
| using System.Reactive.Linq; | ||
| using static TorchSharp.torch; | ||
| using static TorchSharp.torch.linalg; | ||
|
|
||
| namespace Bonsai.ML.Torch.LinearAlgebra; | ||
|
|
||
| /// <summary> | ||
| /// Represents an operator that computes the cross product of 2 tensors. | ||
| /// </summary> | ||
| [Combinator] | ||
| [Description("Computes the cross product of 2 tensors.")] | ||
| [WorkflowElementCategory(ElementCategory.Transform)] | ||
| public class CrossProduct | ||
| { | ||
| /// <summary> | ||
| /// Gets or sets the dimension along which to perform the operation. | ||
| /// </summary> | ||
| [Description("The dimension along which to perform the operation.")] | ||
| public long Dimension { get; set; } = -1; | ||
|
|
||
| /// <summary> | ||
| /// Computes the cross product of 2 tensors. | ||
| /// </summary> | ||
| public IObservable<Tensor> Process(IObservable<Tuple<Tensor, Tensor>> source) | ||
| { | ||
| return source.Select(value => | ||
| { | ||
| return cross(value.Item1, value.Item2, Dimension); | ||
| }); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,26 +1,23 @@ | ||
| using System; | ||
| using System; | ||
| using System.ComponentModel; | ||
| using System.Reactive.Linq; | ||
| using static TorchSharp.torch; | ||
|
|
||
| namespace Bonsai.ML.Torch.LinearAlgebra | ||
| namespace Bonsai.ML.Torch.LinearAlgebra; | ||
|
|
||
| /// <summary> | ||
| /// Represents an operator that computes the determinant of a square matrix. | ||
| /// </summary> | ||
| [Combinator] | ||
| [Description("Computes the determinant of a square matrix.")] | ||
| [WorkflowElementCategory(ElementCategory.Transform)] | ||
| public class Determinant | ||
| { | ||
| /// <summary> | ||
| /// Computes the determinant of a square matrix. | ||
| /// </summary> | ||
| [Combinator] | ||
| [Description("Computes the determinant of a square matrix.")] | ||
| [WorkflowElementCategory(ElementCategory.Transform)] | ||
| public class Determinant | ||
| public IObservable<Tensor> Process(IObservable<Tensor> source) | ||
| { | ||
| /// <summary> | ||
| /// Computes the determinant of a square matrix. | ||
| /// </summary> | ||
| /// <param name="source"></param> | ||
| /// <returns></returns> | ||
| public IObservable<Tensor> Process(IObservable<Tensor> source) | ||
| { | ||
| return source.Select(linalg.det); | ||
| } | ||
| return source.Select(linalg.det); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,26 +1,24 @@ | ||
| using System; | ||
| using System; | ||
| using System.ComponentModel; | ||
| using System.Reactive.Linq; | ||
| using static TorchSharp.torch; | ||
| using static TorchSharp.torch.linalg; | ||
|
|
||
| namespace Bonsai.ML.Torch.LinearAlgebra | ||
| namespace Bonsai.ML.Torch.LinearAlgebra; | ||
|
|
||
| /// <summary> | ||
| /// Represents an operator that computes the eigenvalue decomposition of a square matrix if it exists. | ||
| /// </summary> | ||
| [Combinator] | ||
| [Description("Computes the eigenvalue decomposition of a square matrix if it exists.")] | ||
| [WorkflowElementCategory(ElementCategory.Transform)] | ||
| public class EigenvalueDecomposition | ||
| { | ||
| /// <summary> | ||
| /// Computes the eigenvalue decomposition of a square matrix if it exists. | ||
| /// </summary> | ||
| [Combinator] | ||
| [Description("Computes the eigenvalue decomposition of a square matrix if it exists.")] | ||
| [WorkflowElementCategory(ElementCategory.Transform)] | ||
| public class EigenvalueDecomposition | ||
| public IObservable<EigenvalueDecompositionResult> Process(IObservable<Tensor> source) | ||
| { | ||
| /// <summary> | ||
| /// Computes the eigenvalue decomposition of a square matrix if it exists. | ||
| /// </summary> | ||
| /// <param name="source"></param> | ||
| /// <returns></returns> | ||
| public IObservable<Tuple<Tensor, Tensor>> Process(IObservable<Tensor> source) | ||
| { | ||
| return source.Select(tensor => linalg.eig(tensor).ToTuple()); | ||
| } | ||
| return source.Select(tensor => new EigenvalueDecompositionResult(eig(tensor))); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| using static TorchSharp.torch; | ||
|
|
||
| namespace Bonsai.ML.Torch.LinearAlgebra; | ||
|
|
||
| /// <summary> | ||
| /// Represents the result of an eigenvalue decomposition. | ||
| /// </summary> | ||
| /// <param name="result">The tuple containing the eigenvalues and eigenvectors.</param> | ||
| public readonly struct EigenvalueDecompositionResult((Tensor eigenvalues, Tensor eigenvectors) result) | ||
| { | ||
| /// <summary> | ||
| /// The eigenvalues of the decomposition. | ||
| /// </summary> | ||
| public Tensor Eigenvalues => result.eigenvalues; | ||
|
|
||
| /// <summary> | ||
| /// The eigenvectors of the decomposition. | ||
| /// </summary> | ||
| public Tensor Eigenvectors => result.eigenvectors; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,27 +1,24 @@ | ||
| using System; | ||
| using System; | ||
| using System.ComponentModel; | ||
| using System.Reactive.Linq; | ||
| using static TorchSharp.torch; | ||
| using static TorchSharp.torch.linalg; | ||
|
|
||
| namespace Bonsai.ML.Torch.LinearAlgebra | ||
| namespace Bonsai.ML.Torch.LinearAlgebra; | ||
|
|
||
| /// <summary> | ||
| /// Represents an operator that computes the inverse of the input matrix. | ||
| /// </summary> | ||
| [Combinator] | ||
| [Description("Computes the inverse of the input matrix.")] | ||
| [WorkflowElementCategory(ElementCategory.Transform)] | ||
| public class Inverse | ||
| { | ||
| /// <summary> | ||
| /// Computes the inverse of the input matrix. | ||
| /// </summary> | ||
| [Combinator] | ||
| [Description("Computes the inverse of the input matrix.")] | ||
| [WorkflowElementCategory(ElementCategory.Transform)] | ||
| public class Inverse | ||
| public IObservable<Tensor> Process(IObservable<Tensor> source) | ||
| { | ||
| /// <summary> | ||
| /// Computes the inverse of the input matrix. | ||
| /// </summary> | ||
| /// <param name="source"></param> | ||
| /// <returns></returns> | ||
| public IObservable<Tensor> Process(IObservable<Tensor> source) | ||
| { | ||
| return source.Select(inv); | ||
| } | ||
| return source.Select(inv); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| using System; | ||
| using System.ComponentModel; | ||
| using System.Reactive.Linq; | ||
| using static TorchSharp.torch; | ||
|
|
||
| namespace Bonsai.ML.Torch.LinearAlgebra; | ||
|
|
||
| /// <summary> | ||
| /// Represents an operator that computes the solution to the least squares and least norm problems for a full rank | ||
| /// matrix A of size m*n and a matrix B of size m*k. | ||
| /// </summary> | ||
| [Combinator] | ||
| [Description("Computes the solution to the least squares and least norm problems for a full rank matrix A of size m*n and a matrix B of size m*k.")] | ||
| [WorkflowElementCategory(ElementCategory.Transform)] | ||
| public class LeastSquares | ||
| { | ||
| /// <summary> | ||
| /// Computes the solution to the least squares and least norm problems for a full rank matrix A of size m*n and a | ||
| /// matrix B of size m*k. | ||
| /// </summary> | ||
| public IObservable<LeastSquaresResult> Process(IObservable<Tuple<Tensor, Tensor>> source) | ||
| { | ||
| return source.Select(value => new LeastSquaresResult(linalg.lstsq(value.Item1, value.Item2))); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| using static TorchSharp.torch; | ||
|
|
||
| namespace Bonsai.ML.Torch.LinearAlgebra; | ||
|
|
||
| /// <summary> | ||
| /// Represents the result of solving of linear equations using the least squares method. | ||
| /// </summary> | ||
| public readonly struct LeastSquaresResult(( | ||
| Tensor solution, | ||
| Tensor residuals, | ||
| Tensor rank, | ||
| Tensor singularValues | ||
| ) result) | ||
| { | ||
| /// <summary> | ||
| /// The solution to the system of equations. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The member docs lead with "The" here and in |
||
| /// </summary> | ||
| public Tensor Solution => result.solution; | ||
|
|
||
| /// <summary> | ||
| /// The residual error. | ||
| /// </summary> | ||
| public Tensor Residuals => result.residuals; | ||
|
|
||
| /// <summary> | ||
| /// The effective rank of the solution. | ||
| /// </summary> | ||
| public Tensor Rank => result.rank; | ||
|
|
||
| /// <summary> | ||
| /// The singular values of the solution. | ||
| /// </summary> | ||
| public Tensor SingularValues => result.singularValues; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| using System; | ||
| using System.ComponentModel; | ||
| using System.Reactive.Linq; | ||
| using static TorchSharp.torch; | ||
| using static TorchSharp.torch.linalg; | ||
|
|
||
| namespace Bonsai.ML.Torch.LinearAlgebra; | ||
|
|
||
| /// <summary> | ||
| /// Represents an operator that computes the numerical rank of a matrix. | ||
| /// </summary> | ||
| [Combinator] | ||
| [Description("Computes the numerical rank of a matrix.")] | ||
| [WorkflowElementCategory(ElementCategory.Transform)] | ||
| public class MatrixRank | ||
| { | ||
| /// <summary> | ||
| /// Gets or sets the absolute tolerance for singular values to be considered non-zero. | ||
| /// </summary> | ||
| [Description("The absolute tolerance for singular values to be considered non-zero.")] | ||
| public double? AbsoluteTolerance { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the relative tolerance for singular values to be considered non-zero. | ||
| /// </summary> | ||
| [Description("The relative tolerance for singular values to be considered non-zero.")] | ||
| public double? RelativeTolerance { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets whether to treat the input matrix as Hermitian if input is complex or symmetric if real. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// True indicates that the input matrix is Hermitian if complex or symmetric if real; otherwise, the input matrix | ||
| /// is treated as a generic matrix. | ||
| /// </remarks> | ||
| [Description("True indicates that the input matrix is Hermitian if complex or symmetric if real; otherwise, the input matrix is treated as a generic matrix.")] | ||
| public bool Hermitian { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Computes the numerical rank of a matrix. | ||
| /// </summary> | ||
| public IObservable<Tensor> Process(IObservable<Tensor> source) | ||
| { | ||
| return source.Select(tensor => matrix_rank(tensor, atol: AbsoluteTolerance, rtol: RelativeTolerance, hermitian: Hermitian)); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only new property without a
[Description], so it will not get a tooltip in the property grid, and the PR adds one toNormandSingularValueDecomposition. The wording followsConcat.DimensionandStack.Dimension, which both read "The dimension along which to concatenate the tensors."The
<summary>voice is also mixed across the PR.MatrixRank,QRDecompositionandSolveTriangularlead with "Gets or sets", while this file,Norm,SingularValueDecompositionandTensorSolvelead with "The" or "Whether". "Gets or sets" is the form I would settle on for the summaries.TensorSolve.cs:18also reads "The dimensions to perform the operation", which is missing a preposition.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated it for this PR but it's worth another PR to update this across the entire codebase.