public static T NormFrobenius <T>(this Matrix <T> matrix) where T : unmanaged { T result = default; for (int i = 0; i < matrix.Rows; i++) { for (int j = 0; j < matrix.Columns; j++) { result = MathUnsafe <T> .Add(result, MathUnsafe <T> .Mul(matrix[i, j], matrix[i, j])); } } return(MathGeneric <T> .Sqrt(result)); }
/// <summary> /// Gets sample dispersion of matrix. /// </summary> /// <returns></returns> public T GetSampleDispersion() { T mean = GetSampleMeanByTable(TableVariations.Xi); T[] xi = Matrix[GetIndexColumn(TableVariations.Xi), State.Column]; T sum = default; for (int i = 0; i < Matrix.Rows; i++) { var operation = MathUnsafe <T> .Sub(xi[i], mean); sum = MathUnsafe <T> .Add(sum, MathUnsafe <T> .Mul(operation, operation)); } return(MathGeneric <T, int, T> .Divide(sum, Matrix.Rows)); }
/// <summary> /// Gets lower upper permutation with matrix C which calculate by formula: /// <c>C=L+U-E</c> /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static void GetLowerUpperPermutation <T>(this Matrix <T> matrix, out Matrix <T> matrixC, out Matrix <T> matrixP) where T : unmanaged { int n = matrix.Rows; matrixC = matrix.Clone() as Matrix <T>; if (matrixC is null) { throw new NullReferenceException(); } // load to P identity matrix. matrixP = BuildMatrix.CreateIdentityMatrix <T>(matrix.Rows, matrix.Columns); var comparer = Comparer <T> .Default; for (int i = 0; i < n; i++) { T pivotValue = default; int pivot = -1; for (int j = i; j < n; j++) { if (comparer.Compare(MathGeneric <T> .Abs(matrixC[j, i]), pivotValue) > 0) { pivotValue = MathGeneric <T> .Abs(matrixC[j, i]); pivot = j; } } if (pivot != 0) { matrixP.SwapRows(pivot, i); matrixC.SwapRows(pivot, i); for (int j = i + 1; j < n; j++) { matrixC[j, i] = MathGeneric <T> .Divide(matrixC[j, i], matrixC[i, i]); for (int k = i + 1; k < n; k++) { matrixC[j, k] = MathUnsafe <T> .Sub(matrixC[j, k], MathUnsafe <T> .Mul(matrixC[j, i], matrix[i, k])); } } } } }
/// <summary> /// Gets determinant of matrix. /// </summary> /// <param name="matrix">matrix.</param> /// <typeparam name="T">unmanaged type</typeparam> /// <returns>double.</returns> /// <exception cref="MatrixDotNetException"></exception> public static T GetDeterminant <T>(this Matrix <T> matrix) where T : unmanaged { if (!matrix.IsSquare) { throw new MatrixNotSquareException(); } if (matrix.Length == 4) { return(MathUnsafe <T> .Sub( MathUnsafe <T> .Mul(matrix[0, 0], matrix[1, 1]), MathUnsafe <T> .Mul(matrix[0, 1], matrix[1, 0]))); } T result = default; var sign = MathGeneric <T> .Increment(default);
/// <summary> /// Gets matrix after tensor product of two vectors /// </summary> /// <param name="va">the left vector</param> /// <param name="vb">the right vector(transpose)</param> /// <typeparam name="T">unmanaged type</typeparam> /// <returns><see cref="Matrix{T}"/></returns> /// <exception cref="MatrixDotNetException">left vector is not equal right</exception> public static unsafe Matrix <T> TensorProduct <T>(Vector <T> va, Vector <T> vb) where T : unmanaged { int n = va.Length; if (n != vb.Length) { throw new MatrixDotNetException("vector length is not equal"); } int size = System.Numerics.Vector <T> .Count; var mr = new Matrix <T>(n, n); int lastIndexBlock = n - n % size; int j = 0; fixed(T *ptr = mr._Matrix) { for (int i = 0; i < mr.Rows; i++) { for (j = 0; j < lastIndexBlock; j += size) { var vd = new System.Numerics.Vector <T>(vb.Array, j); var vc = Vector.Multiply(va[i], vd); var res = (T *)Unsafe.AsPointer(ref vc); Unsafe.CopyBlock(ptr + i * mr.Columns + j, res, (uint)(sizeof(T) * size)); } } for (int i = 0; i < mr.Rows; i++) { for (int k = j; k < n; k++) { mr[i, k] = MathUnsafe <T> .Mul(va[i], vb[k]); } } } return(mr); }