mmulStrassen(y) {
                var x = this.clone();
                var r1 = x.rows;
                var c1 = x.columns;
                var r2 = y.rows;
                var c2 = y.columns;
                if (c1 !== r2) {
                    // eslint-disable-next-line no-console
                    console.warn(`Multiplying ${r1} x ${c1} and ${r2} x ${c2} matrix: dimensions do not match.`);
                }

                // Put a matrix into the top left of a matrix of zeros.
                // `rows` and `cols` are the dimensions of the output matrix.
                function embed(mat, rows, cols) {
                    var r = mat.rows;
                    var c = mat.columns;
                    if ((r === rows) && (c === cols)) {
                        return mat;
                    } else {
                        var resultat = Matrix.zeros(rows, cols);
                        resultat = resultat.setSubMatrix(mat, 0, 0);
                        return resultat;
                    }
                }


                // Make sure both matrices are the same size.
                // This is exclusively for simplicity:
                // this algorithm can be implemented with matrices of different sizes.

                var r = Math.max(r1, r2);
                var c = Math.max(c1, c2);
                x = embed(x, r, c);
                y = embed(y, r, c);

                // Our recursive multiplication function.
                function blockMult(a, b, rows, cols) {
                    // For small matrices, resort to naive multiplication.
                    if (rows <= 512 || cols <= 512) {
                        return a.mmul(b); // a is equivalent to this
                    }

                    // Apply dynamic padding.
                    if ((rows % 2 === 1) && (cols % 2 === 1)) {
                        a = embed(a, rows + 1, cols + 1);
                        b = embed(b, rows + 1, cols + 1);
                    } else if (rows % 2 === 1) {
                        a = embed(a, rows + 1, cols);
                        b = embed(b, rows + 1, cols);
                    } else if (cols % 2 === 1) {
                        a = embed(a, rows, cols + 1);
                        b = embed(b, rows, cols + 1);
                    }

                    var halfRows = parseInt(a.rows / 2);
                    var halfCols = parseInt(a.columns / 2);
                    // Subdivide input matrices.
                    var a11 = a.subMatrix(0, halfRows - 1, 0, halfCols - 1);
                    var b11 = b.subMatrix(0, halfRows - 1, 0, halfCols - 1);

                    var a12 = a.subMatrix(0, halfRows - 1, halfCols, a.columns - 1);
                    var b12 = b.subMatrix(0, halfRows - 1, halfCols, b.columns - 1);

                    var a21 = a.subMatrix(halfRows, a.rows - 1, 0, halfCols - 1);
                    var b21 = b.subMatrix(halfRows, b.rows - 1, 0, halfCols - 1);

                    var a22 = a.subMatrix(halfRows, a.rows - 1, halfCols, a.columns - 1);
                    var b22 = b.subMatrix(halfRows, b.rows - 1, halfCols, b.columns - 1);

                    // Compute intermediate values.
                    var m1 = blockMult(Matrix.add(a11, a22), Matrix.add(b11, b22), halfRows, halfCols);
                    var m2 = blockMult(Matrix.add(a21, a22), b11, halfRows, halfCols);
                    var m3 = blockMult(a11, Matrix.sub(b12, b22), halfRows, halfCols);
                    var m4 = blockMult(a22, Matrix.sub(b21, b11), halfRows, halfCols);
                    var m5 = blockMult(Matrix.add(a11, a12), b22, halfRows, halfCols);
                    var m6 = blockMult(Matrix.sub(a21, a11), Matrix.add(b11, b12), halfRows, halfCols);
                    var m7 = blockMult(Matrix.sub(a12, a22), Matrix.add(b21, b22), halfRows, halfCols);

                    // Combine intermediate values into the output.
                    var c11 = Matrix.add(m1, m4);
                    c11.sub(m5);
                    c11.add(m7);
                    var c12 = Matrix.add(m3, m5);
                    var c21 = Matrix.add(m2, m4);
                    var c22 = Matrix.sub(m1, m2);
                    c22.add(m3);
                    c22.add(m6);

                    //Crop output to the desired size (undo dynamic padding).
                    var resultat = Matrix.zeros(2 * c11.rows, 2 * c11.columns);
                    resultat = resultat.setSubMatrix(c11, 0, 0);
                    resultat = resultat.setSubMatrix(c12, c11.rows, 0);
                    resultat = resultat.setSubMatrix(c21, 0, c11.columns);
                    resultat = resultat.setSubMatrix(c22, c11.rows, c11.columns);
                    return resultat.subMatrix(0, rows - 1, 0, cols - 1);
                }
                return blockMult(x, y, r, c);
            }
Returns the matrix product between x and y. More efficient than mmul(other) only when we multiply squared matrix and when the size of the matrix is > 1000.
@param {Matrix} y
@return {Matrix}