/// <summary> /// Gets range of variations by table column in matrix. /// </summary> /// <param name="table">the table.</param> /// <returns>range of variations by table column of matrix.</returns> public T GetRangeVariation(TableVariations table) { var a = Matrix.MaxByColumn(GetIndexColumn(table)); var b = Matrix.MinByColumn(GetIndexColumn(table)); return(MathUnsafe <T> .Sub(a, b)); }
/// <summary> /// Gets m-norm. /// </summary> /// <param name="matrix">the matrix.</param> /// <typeparam name="T">unmanaged type.</typeparam> /// <returns>m-norm.</returns> /// <exception cref="NullReferenceException"></exception> public static T MNorm <T>(this Matrix <T> matrix) where T : unmanaged { int rows = matrix.Rows; int columns = matrix.Columns; var array = new T[rows]; for (int i = 0; i < rows; i++) { T sum = default; for (int j = 0; j < columns; j++) { sum = MathUnsafe <T> .Add(sum, MathGeneric <T> .Abs(matrix[i, j])); } array[i] = sum; } Comparer <T> comparer = Comparer <T> .Default; T max = array[0]; for (int i = 0; i < rows; i++) { T reg = array[i]; if (comparer.Compare(max, array[i]) < 0) { max = reg; } } return(max); }
/// <summary> /// Gets range of variations by index column in matrix. /// </summary> /// <param name="index"></param> /// <returns>range of variations by column index of matrix.</returns> public T GetRangeVariation(int index) { var a = Matrix.MaxByColumn(index); var b = Matrix.MinByColumn(index); return(MathUnsafe <T> .Sub(a, b)); }
public static T GetKahanSum <T>(this Matrix <T> matrix, int dimension, State state = State.Row) where T : unmanaged { T sum = default; T error = default; if (state == State.Row) { for (int i = 0; i < matrix.Columns; i++) { T y = MathUnsafe <T> .Sub(matrix[dimension, i], error); T t = MathUnsafe <T> .Add(sum, y); error = MathUnsafe <T> .Sub(MathUnsafe <T> .Sub(t, sum), matrix[dimension, i]); sum = t; } } else { for (int i = 0; i < matrix.Rows; i++) { T y = MathUnsafe <T> .Sub(matrix[i, dimension], error); T t = MathUnsafe <T> .Add(sum, y); error = MathUnsafe <T> .Sub(MathUnsafe <T> .Sub(t, sum), matrix[i, dimension]); sum = t; } } return(sum); }
/// <summary> /// Gets distance between two points. /// </summary> /// <param name="va">vector A</param> /// <param name="vb">vector B</param> /// <typeparam name="T">unmanaged type</typeparam> /// <returns>new vector with distance between of two points</returns> /// <exception cref="MatrixDotNetException">length of vector A not equal length of vector B</exception> public static Vector <T> GetDistancePoint <T>(Vector <T> va, Vector <T> vb) where T : unmanaged { int len = va.Length; if (len != vb.Length) { throw new SizeNotEqualException(ExceptionArgument.VectorLength); } Vector <T> vc = new Vector <T>(len); int i = 0; int size = System.Numerics.Vector <T> .Count; int lastIndexBlock = len - len % size; for (; i < lastIndexBlock; i += size) { var vectorA = new System.Numerics.Vector <T>(va.Array, i); var vectorB = new System.Numerics.Vector <T>(vb.Array, i); var vectorC = Vector.Subtract(vectorB, vectorA); vectorC.CopyTo(vc.Array, i); } for (; i < vc.Length; i++) { vc[i] = MathUnsafe <T> .Sub(vb[i], va[i]); } return(vc); }
/// <summary> /// Gets vector direct cosines /// </summary> /// <param name="va">vector A</param> /// <typeparam name="T">unmanaged type</typeparam> /// <returns>direct cos's</returns> /// <exception cref="MatrixDotNetException"> /// throw if data type is not floating type /// </exception> public static T[] GetDirectCos <T>(Vector <T> va) where T : unmanaged { if (!MathGeneric.IsFloatingPoint <T>()) { throw new NotSupportedException(); } int length = va.Length; T[] cos = new T[length]; T mod = va.GetLengthVec(); Array.Fill(cos, mod); int i = 0; int size = System.Numerics.Vector <T> .Count; int lastIndexBlock = length - length % size; for (; i < lastIndexBlock; i += size) { var vt = new System.Numerics.Vector <T>(va.Array, i); var vf = new System.Numerics.Vector <T>(cos); var vc = Vector.Divide(vt, vf); vc.CopyTo(cos, i); } for (; i < length; i++) { cos[i] = MathUnsafe <T> .Div(va[i], cos[i]); } return(cos); }
/// <summary> /// Gets determinant matrix by Kramer algorithm. /// </summary> /// <param name="matrix">matrix.</param> /// <param name="arr">array.</param> /// <typeparam name="T">unmanaged type.</typeparam> /// <returns>Gets array x.</returns> /// <exception cref="MatrixDotNetException"> /// array length not equal matrix rows. /// </exception> public static Vectorization.Vector <T> KramerSolve <T>(this Matrix <T> matrix, Vectorization.Vector <T> arr) where T : unmanaged { if (matrix.Rows != arr.Length) { throw new SizeNotEqualException(ExceptionArgument.RowSizeOfMatrixIsNotEqualSizeOfVector); } var det = matrix.GetDeterminant(); var vr = new Vectorization.Vector <T>(matrix.Columns); if (!(matrix.Clone() is Matrix <T> temp)) { throw new NullReferenceException(); } for (int i = 0; i < matrix.Columns; i++) { for (int j = 0; j < matrix.Rows; j++) { temp[j, i] = arr[j]; } vr[i] = MathUnsafe <T> .Div(temp.GetDeterminant(), det); } return(vr); }
/// <summary> /// Gets swing of variations. /// </summary> /// <returns></returns> public T GetRangeVariation() { var a = Matrix.Max(); var b = Matrix.Min(); return(MathUnsafe <T> .Sub(a, b)); }
internal static T SumVector(Vector128 <T> a) { var sum = default(T); for (var i = 0; i < Vector128 <T> .Count; i++) { sum = MathUnsafe <T> .Add(sum, a.GetElement(i)); } return(sum); }
public static T Sum <T>(this Vector256 <T> a) where T : unmanaged { var sum = default(T); for (var i = 0; i < Vector256 <T> .Count; i++) { sum = MathUnsafe <T> .Add(sum, a.GetElement(i)); } return(sum); }
/// <summary> /// Gets sum by column of matrix. /// </summary> /// <param name="matrix">the matrix.</param> /// <param name="dimension">column index.</param> /// <typeparam name="T">unmanaged type.</typeparam> /// <returns>Sum column by index</returns> /// <exception cref="NullReferenceException"></exception> public static T SumByColumn <T>(this Matrix <T> matrix, int dimension) where T : unmanaged { T sum = default; for (int i = 0; i < matrix.Rows; i++) { sum = MathUnsafe <T> .Add(sum, matrix[i, dimension]); } return(sum); }
/// <summary> /// Gets sum by diagonal. /// </summary> /// <param name="matrix"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> /// <exception cref="NullReferenceException"></exception> public static T SumByDiagonal <T>(this Matrix <T> matrix) where T : unmanaged { T sum = default; for (int i = 0; i < matrix.Rows; i++) { sum = MathUnsafe <T> .Add(sum, matrix[i, i]); } return(sum); }
/// <summary> /// Gets mean linear deviation. /// </summary> /// <returns>mean linear deviation.</returns> public T GetMeanLinearDeviation() { T sum = default; T[] arr = GetModulesDevMean(); for (int i = 0; i < Matrix.Rows; i++) { sum = MathUnsafe <T> .Add(sum, arr[i]); } return(MathGeneric <T, int, T> .Divide(sum, Matrix.Rows)); }
public static T GetKleinSum <T>(this Matrix <T> matrix) where T : unmanaged { if (!MathGeneric.IsFloatingPoint <T>()) { throw new MatrixDotNetException($"{typeof(T)} is not supported type must be floating type"); } T sum = default; T cs = default; T ccs = default; var comparer = Comparer <T> .Default; for (int i = 0; i < matrix.Rows; i++) { for (int j = 0; j < matrix.Columns; j++) { T t = MathUnsafe <T> .Add(sum, matrix[i, j]); T error; if (comparer.Compare(MathGeneric <T> .Abs(sum), matrix[i, j]) >= 0) { error = MathUnsafe <T> .Add(MathUnsafe <T> .Sub(sum, t), matrix[i, j]); } else { error = MathUnsafe <T> .Add(MathUnsafe <T> .Sub(matrix[i, j], t), sum); } sum = t; t = MathUnsafe <T> .Add(cs, cs); T error2; if (comparer.Compare(MathGeneric <T> .Abs(cs), error) >= 0) { error2 = MathUnsafe <T> .Add(MathUnsafe <T> .Sub(error, t), cs); } else { error2 = MathUnsafe <T> .Add(MathUnsafe <T> .Sub(cs, t), error); } cs = t; ccs = MathUnsafe <T> .Add(ccs, error2); } } return(MathUnsafe <T> .Add(MathUnsafe <T> .Add(sum, cs), ccs)); }
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 modules of deviations from the mean. /// </summary> /// <returns>Modules of deviations from the mean.</returns> public T[] GetModulesDevMean() { T[] arr = new T[Matrix.Rows]; T[] xi = Matrix[GetIndexColumn(TableVariations.Xi), State.Column]; T mean = GetSampleMeanByTable(TableVariations.Xi); for (int i = 0; i < arr.Length; i++) { arr[i] = MathGeneric <T> .Abs(MathUnsafe <T> .Sub(xi[i], mean)); } return(arr); }
public Point <T> Offset(PointOffset offset, T count) { return(offset switch { PointOffset.None => this, PointOffset.Up => this - new Point <T>(0, count), PointOffset.Down => this + new Point <T>(0, count), PointOffset.Left => this - new Point <T>(count, 0), PointOffset.Right => this + new Point <T>(count, 0), PointOffset.UpLeft => this - new Point <T>(count, count), PointOffset.DownLeft => this + new Point <T>(MathUnsafe.Negative(count), count), PointOffset.UpRight => this - new Point <T>(MathUnsafe.Negative(count), count), PointOffset.DownRight => this + new Point <T>(count, count), _ => throw new ArgumentOutOfRangeException(nameof(offset), offset, null) });
/// <summary> /// The trace <c>Tr</c> of a square matrix A is defined to be the sum of elements on the main diagonal. /// </summary> /// <param name="matrix">the matrix.</param> /// <typeparam name="T">unmanaged type.</typeparam> /// <returns>Traceless of matrix.</returns> public static T Traceless <T>(this Matrix <T> matrix) where T : unmanaged { if (!matrix.IsSquare) { throw new MatrixNotSquareException(); } T sum = default; for (int i = 0; i < matrix.Rows; i++) { sum = MathUnsafe <T> .Add(sum, matrix[i, i]); } return(sum); }
/// <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);
public static void EigenVectorQrIterative <T>(this Matrix <T> matrix, double accuracy, int maxIterations, out Matrix <T> iter, out Matrix <T> qIter) where T : unmanaged { iter = matrix.Clone() as Matrix <T>; qIter = null; for (int i = 0; i < maxIterations; i++) { iter.QrDecomposition(out var q, out var r); iter = r * q; if (qIter is null) { qIter = q; } else { var qNew = qIter * q; bool isAchieved = true; // checks accuracy for (int j = 0; j < q.Columns; j++) { for (int k = 0; k < q.Rows; k++) { var sub = MathUnsafe <T> .Sub(MathGeneric <T> .Abs(qNew[j, k]), MathGeneric <T> .Abs(qIter[j, k])); if (accuracy.CompareTo(MathGeneric <T> .Abs(sub)) <= 0) { continue; } isAchieved = false; break; } if (!isAchieved) { break; } } qIter = qNew; if (isAchieved) { break; } } } }
private static T GetKleinSumByColumns <T>(this Matrix <T> matrix, int dimension) where T : unmanaged { T sum = default; T cs = default; T ccs = default; var comparer = Comparer <T> .Default; for (int j = 0; j < matrix.Rows; j++) { T t = MathUnsafe <T> .Add(sum, matrix[j, dimension]); T error; if (comparer.Compare(MathGeneric <T> .Abs(sum), matrix[j, dimension]) >= 0) { error = MathUnsafe <T> .Add(MathUnsafe <T> .Sub(sum, t), matrix[j, dimension]); } else { error = MathUnsafe <T> .Add(MathUnsafe <T> .Sub(matrix[j, dimension], t), sum); } sum = t; t = MathUnsafe <T> .Add(cs, cs); T error2; if (comparer.Compare(MathGeneric <T> .Abs(cs), error) >= 0) { error2 = MathUnsafe <T> .Add(MathUnsafe <T> .Sub(error, t), cs); } else { error2 = MathUnsafe <T> .Add(MathUnsafe <T> .Sub(cs, t), error); } cs = t; ccs = MathUnsafe <T> .Add(ccs, error2); } return(MathUnsafe <T> .Add(MathUnsafe <T> .Add(sum, cs), ccs)); }
/// <summary> /// Gets array of sum columns. /// </summary> /// <param name="matrix">the matrix.</param> /// <typeparam name="T">unmanaged type.</typeparam> /// <returns></returns> /// <exception cref="NullReferenceException"></exception> public static T[] SumByColumns <T>(this Matrix <T> matrix) where T : unmanaged { var array = new T[matrix.Columns]; for (int i = 0; i < matrix.Columns; i++) { T sum = default; for (int j = 0; j < matrix.Rows; j++) { sum = MathUnsafe <T> .Add(sum, matrix[j, i]); } array[i] = sum; } return(array); }
/// <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); }
public static T GetKahanSum <T>(this Matrix <T> matrix) where T : unmanaged { T sum = default; T error = default; for (int i = 0; i < matrix.Rows; i++) { for (int j = 0; j < matrix.Columns; j++) { T y = MathUnsafe <T> .Sub(matrix[i, j], error); T t = MathUnsafe <T> .Add(sum, y); error = MathUnsafe <T> .Sub(MathUnsafe <T> .Sub(t, sum), matrix[i, j]); sum = t; } } return(sum); }
public static Point <T> operator %(Point <T> first, Point <T> second) { return(new Point <T>(MathUnsafe.Modulo(first.X, second.X), MathUnsafe.Modulo(first.Y, second.Y))); }
public static Point <T> operator -(Point <T> first, Point <T> second) { return(new Point <T>(MathUnsafe.Substract(first.X, second.X), MathUnsafe.Substract(first.Y, second.Y))); }
public static Point <T> operator /(Point <T> pos1, Point <T> pos2) { return(new Point <T>(MathUnsafe.Divide(pos1.X, pos2.X), MathUnsafe.Divide(pos1.Y, pos2.Y))); }
public static Point <T> operator %(Point <T> pos1, Point <T> pos2) { return(new Point <T>(MathUnsafe.Modulo(pos1.X, pos2.X), MathUnsafe.Modulo(pos1.Y, pos2.Y))); }