forked from SciSharp/Tensor.NET
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMatrixInverse.cs
More file actions
86 lines (85 loc) · 3.84 KB
/
Copy pathMatrixInverse.cs
File metadata and controls
86 lines (85 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using Tensornet.Common;
using Tensornet.Native;
using Tensornet.Exceptions;
using Tensornet.Native.Param;
namespace Tensornet{
public static class InverseExtension{
/// <summary>
/// Get the inverse of the tensor. For the details of the manipulation, please refer to https://numpy.org/doc/stable/reference/generated/numpy.linalg.inv.html
/// </summary>
/// <param name="src"></param>
/// <returns></returns>
public static Tensor<double> Inverse(this Tensor<int> src)
{
Tensor<double> res = new Tensor<double>(DeduceLayout(src.TLayout));
res.TLayout.InitContiguousLayout();
InverseInternal<double>(src.ToTensor<double>(), res);
return res;
}
/// <summary>
/// Get the inverse of the tensor. For the details of the manipulation, please refer to https://numpy.org/doc/stable/reference/generated/numpy.linalg.inv.html
/// </summary>
/// <param name="src"></param>
/// <returns></returns>
public static Tensor<double> Inverse(this Tensor<long> src)
{
Tensor<double> res = new Tensor<double>(DeduceLayout(src.TLayout));
res.TLayout.InitContiguousLayout();
InverseInternal<double>(src.ToTensor<double>(), res);
return res;
}
/// <summary>
/// Get the inverse of the tensor. For the details of the manipulation, please refer to https://numpy.org/doc/stable/reference/generated/numpy.linalg.inv.html
/// </summary>
/// <param name="src"></param>
/// <returns></returns>
public static Tensor<double> Inverse(this Tensor<double> src)
{
Tensor<double> res = new Tensor<double>(DeduceLayout(src.TLayout));
res.TLayout.InitContiguousLayout();
if(src.TLayout.IsContiguous()){
InverseInternal<double>(src, res);
}
else{
InverseInternal<double>(src.ToContiguousTensor(), res);
}
return res;
}
/// <summary>
/// Get the inverse of the tensor. For the details of the manipulation, please refer to https://numpy.org/doc/stable/reference/generated/numpy.linalg.inv.html
/// </summary>
/// <param name="src"></param>
/// <returns></returns>
public static Tensor<float> Inverse(this Tensor<float> src)
{
Tensor<float> res = new Tensor<float>(DeduceLayout(src.TLayout));
res.TLayout.InitContiguousLayout();
if(src.TLayout.IsContiguous()){
InverseInternal<float>(src, res);
}
else{
InverseInternal<float>(src.ToContiguousTensor(), res);
}
return res;
}
private unsafe static void InverseInternal<T>(Tensor<T> src, Tensor<T> dst) where T : struct, IEquatable<T>, IConvertible{
IntPtr status = NativeExecutor.Execute(NativeApi.MatrixInverse, src.TMemory, dst.TMemory, src.TLayout, dst.TLayout, IntPtr.Zero, Tensor<T>.Provider);
NativeStatus.AssertOK(status);
}
private static TensorLayout DeduceLayout(TensorLayout src){
TensorLayout res = new TensorLayout();
if (src.NDim < 2) {
throw new MismatchedShapeException("The tensor to calculate inverse must has at least two dims.");
}
if (src.Shape[src.NDim - 1] != src.Shape[src.NDim - 2]) {
throw new MismatchedShapeException("The tensor to calculate inverse must has its last two dims square.");
}
res.DType = (src.DType is DType.Float32 or DType.Float64) ? src.DType : DType.Float64;
res.NDim = src.NDim;
for (int i = 0; i < src.NDim; i++) {
res.Shape[i] = src.Shape[i];
}
return res;
}
}
}