/// <summary> /// Strassen`s multiply, use when matrix rows > 32. /// </summary> /// <param name="a">the matrix a.</param> /// <param name="b">the matrix b.</param> /// <typeparam name="T">unmanaged type.</typeparam> /// <returns>the new matrix from multiply of two matrices.</returns> public static Matrix <T> MultiplyStrassen <T>(Matrix <T> a, Matrix <T> b) where T : unmanaged { if (a.Rows < 32) { return(a * b); } a.SplitMatrix(out var a11, out var a12, out var a21, out var a22); b.SplitMatrix(out var b11, out var b12, out var b21, out var b22); Matrix <T> p1 = MultiplyStrassen(a11 + a22, b11 + b22); Matrix <T> p2 = MultiplyStrassen(a21 + a22, b11); Matrix <T> p3 = MultiplyStrassen(a11, b12 - b22); Matrix <T> p4 = MultiplyStrassen(a22, b21 - b11); Matrix <T> p5 = MultiplyStrassen(a11 + a12, b22); Matrix <T> p6 = MultiplyStrassen(a21 - a22, b11 + b12); Matrix <T> p7 = MultiplyStrassen(a12 - a22, b21 + b22); Matrix <T> c11 = p1 + p4 - p5 + p7; Matrix <T> c12 = p3 + p5; Matrix <T> c21 = p2 + p4; Matrix <T> c22 = p1 + p3 - p2 + p6; return(MatrixConverter.CollectMatrix(c11, c12, c21, c22)); }
private static ValueTask <Matrix <T> > MultiplyStrassenParallel <T>(Matrix <T> a, Matrix <T> b) where T : unmanaged { if (a.Rows <= 64) { return(new ValueTask <Matrix <T> >(a * b)); } a.SplitMatrix(out var a11, out var a12, out var a21, out var a22); b.SplitMatrix(out var b11, out var b12, out var b21, out var b22); var p1 = Task.Run(() => MultiplyStrassen(a11 + a22, b11 + b22)); var p2 = Task.Run(() => MultiplyStrassen(a21 + a22, b11)); var p3 = Task.Run(() => MultiplyStrassen(a11, b12 - b22)); var p4 = Task.Run(() => MultiplyStrassen(a22, b21 - b11)); var p5 = Task.Run(() => MultiplyStrassen(a11 + a12, b22)); var p6 = Task.Run(() => MultiplyStrassen(a21 - a11, b11 + b12)); var p7 = MultiplyStrassen(a12 - a22, b21 + b22); Task.WhenAll(p1, p2, p3, p4, p5, p6); var c11 = p1.Result + p4.Result - p5.Result + p7; var c12 = p3.Result + p5.Result; var c21 = p2.Result + p4.Result; var c22 = p1.Result + p3.Result - p2.Result + p6.Result; return(new ValueTask <Matrix <T> >(MatrixConverter.CollectMatrix(c11, c12, c21, c22))); }