-
Notifications
You must be signed in to change notification settings - Fork 75
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
Matrix operators #398
Matrix operators #398
Changes from all commits
75c7aa8
fb38e96
26150cf
ee4a769
7d33b51
ab73ffa
a8a4441
4a2b2e9
ba2651f
d45a7c5
4043999
78fd180
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 |
---|---|---|
|
@@ -194,35 +194,32 @@ public Entity AsScalar() | |
/// <summary> | ||
/// Finds the symbolical determinant via Laplace's method | ||
/// </summary> | ||
public Entity Determinant => determinant.GetValue( | ||
static @this => @this.InnerMatrix.DeterminantGaussianSafeDivision().InnerSimplified, | ||
public Entity? Determinant => determinant.GetValue( | ||
static @this => | ||
{ | ||
if ([email protected]) | ||
return null; | ||
return @this.InnerMatrix.DeterminantGaussianSafeDivision().InnerSimplified; | ||
}, | ||
this | ||
); | ||
private FieldCache<Entity> determinant; | ||
private FieldCache<Entity?> determinant; | ||
|
||
// The reason it's not cached is because it throws exceptions. | ||
/// <summary>Inverts the matrix</summary> | ||
public Matrix ComputeInverse() | ||
/// <summary>Returns an inverse matrix if it exists</summary> | ||
public Matrix? Inverse => inverse.GetValue(static @this => | ||
{ | ||
var cp = InnerMatrix.Copy(false); | ||
try | ||
{ | ||
cp.InvertMatrix(); | ||
} | ||
catch (InvalidShapeException) | ||
{ | ||
throw new InvalidMatrixOperationException("Cannot inverse a non-square matrix!"); | ||
} | ||
catch (InvalidDeterminantException) | ||
{ | ||
throw new InvalidMatrixOperationException("Cannot inverse a singular matrix!"); | ||
} | ||
var cp = @this.InnerMatrix.Copy(false); | ||
if ([email protected]) | ||
return null; | ||
if (@this.Determinant is null) | ||
return null; | ||
if (@this.Determinant == 0) | ||
Comment on lines
+212
to
+216
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. Shouldn't these checks be in GenericTensor? 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. Same thing, we want to return null to avoid an exception 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. Then don't throw exceptions in GenericTensor! 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. Hmmmmmmmmmmmmmmmmmmmmmmmmmmm. We can have 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. @MomoDeve would love this |
||
return null; | ||
cp.InvertMatrix(); | ||
return ToMatrix(new Matrix(cp).InnerSimplified); | ||
} | ||
}, this); | ||
private FieldCache<Matrix?> inverse; | ||
|
||
/// <summary>Inverts the matrix</summary> | ||
[Obsolete("Use ComputeInverse() instead")] | ||
public Matrix Inverse() => ComputeInverse(); | ||
|
||
/// <summary> | ||
/// The Add operator. Performs an active operation | ||
|
@@ -270,22 +267,6 @@ public Matrix ComputeInverse() | |
} | ||
} | ||
|
||
/// <summary> | ||
/// The Multiply operator. Performs an active operation. | ||
/// 1. Finds the inverse of the divisor | ||
/// 2. Multiplies the dividend by the inverse of the divisor | ||
/// and then applies inner simplification. | ||
/// The operator only works with square matrices of the same size | ||
/// </summary> | ||
/// <exception cref="InvalidMatrixOperationException"> | ||
/// May be thrown if no inverse was found. | ||
/// </exception> | ||
public static Matrix operator /(Matrix m1, Matrix m2) | ||
{ | ||
var inv = m2.ComputeInverse(); | ||
return m1 * inv; | ||
} | ||
|
||
/// <summary> | ||
/// Performs a binary power of the matrix. | ||
/// The matrix must be a square matrix. | ||
|
@@ -369,11 +350,16 @@ public IEnumerator<Entity> GetEnumerator() | |
/// <summary> | ||
/// Adjugate form of a matrix | ||
/// </summary> | ||
public Matrix Adjugate => | ||
public Matrix? Adjugate => | ||
adjugate.GetValue(static @this => | ||
(Matrix)new Matrix(@this.InnerMatrix.Adjoint()).InnerSimplified, | ||
{ | ||
if ([email protected]) | ||
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. Shouldn't this check be in GenericTensor? 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. 🦆 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. 🦆 |
||
return null; | ||
var innerSimplified = new Matrix(@this.InnerMatrix.Adjoint()).InnerSimplified; | ||
return ToMatrix(innerSimplified); | ||
}, | ||
this); | ||
private FieldCache<Matrix> adjugate; | ||
private FieldCache<Matrix?> adjugate; | ||
|
||
/// <summary> | ||
/// Returns a vector, where the i-th element | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
module MatrixOperatorsTest | ||
|
||
open AngouriMath | ||
open AngouriMath.FSharp.Functions | ||
open AngouriMath.FSharp.MatrixOperators | ||
open Xunit | ||
|
||
(* | ||
|
||
Matrix and matrix operators | ||
M = matrix | ||
|
||
*) | ||
|
||
[<Fact>] | ||
let ``M+M`` () = | ||
Assert.Equal<Entity.Matrix>(vector [11; 32], vector [10; 30] |+ vector [1; 2]) | ||
|
||
[<Fact>] | ||
let ``M-M`` () = | ||
Assert.Equal<Entity.Matrix>(vector [9; 28], vector [10; 30] |- vector [1; 2]) | ||
|
||
[<Fact>] | ||
let ``M*M`` () = | ||
Assert.Equal<Entity.Matrix>(vector [2; 4], "[[2, 0], [0, 2]]" |* "[1, 2]") | ||
|
||
(* | ||
|
||
Matrix and scalar operators | ||
Scalar and matrix operators | ||
M = matrix | ||
S = scalar | ||
|
||
*) | ||
|
||
[<Fact>] | ||
let ``M+S`` () = | ||
Assert.Equal<Entity.Matrix>(vector [11; 31], vector [10; 30] |+ 1) | ||
|
||
[<Fact>] | ||
let ``S+M`` () = | ||
Assert.Equal<Entity.Matrix>(vector [11; 31], 1 |+ vector [10; 30]) | ||
|
||
[<Fact>] | ||
let ``M-S`` () = | ||
Assert.Equal<Entity.Matrix>(vector [9; 29], vector [10; 30] |- 1) | ||
|
||
[<Fact>] | ||
let ``S-M`` () = | ||
Assert.Equal<Entity.Matrix>(vector [90; 70], 100 |- vector [10; 30]) | ||
|
||
[<Fact>] | ||
let ``M*S`` () = | ||
Assert.Equal<Entity.Matrix>(vector [3; 6], vector [1; 2] |* 3) | ||
|
||
[<Fact>] | ||
let ``S*M`` () = | ||
Assert.Equal<Entity.Matrix>(vector [3; 6], 3 |* vector [1; 2]) | ||
|
||
[<Fact>] | ||
let ``M/S`` () = | ||
Assert.Equal<Entity.Matrix>(vector [5; 15], vector [10; 30] |/ 2) | ||
|
||
[<Fact>] | ||
let ``M**S`` () = | ||
Assert.Equal<Entity.Matrix>(matrix [[37; 54]; [81; 118]], matrix [[1; 2]; [3; 4]] |** 3) |
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.
Shouldn't this check be in GenericTensor?
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.
Yes, but it is exception-based. Here we want to return a null in that case. (sure we can catch exceptions, but... quack. Maybe we will after the
GenericTensorBaseException
implemented)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.
Then don't throw exceptions in GenericTensor!
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.
asc-community/GenericTensor#23