/* (non-Javadoc)
@see org.joml.Matrix4x3dc#mulOrtho(org.joml.Matrix4x3dc, org.joml.Matrix4x3d)
431863
public Matrix4x3d mulOrtho(Matrix4x3dc view, Matrix4x3d dest) {
        double nm00 = m00 * view.m00();
        double nm01 = m11 * view.m01();
        double nm02 = m22 * view.m02();
        double nm10 = m00 * view.m10();
        double nm11 = m11 * view.m11();
        double nm12 = m22 * view.m12();
        double nm20 = m00 * view.m20();
        double nm21 = m11 * view.m21();
        double nm22 = m22 * view.m22();
        double nm30 = m00 * view.m30() + m30;
        double nm31 = m11 * view.m31() + m31;
        double nm32 = m22 * view.m32() + m32;
        dest.m00 = nm00;
        dest.m01 = nm01;
        dest.m02 = nm02;
        dest.m10 = nm10;
        dest.m11 = nm11;
        dest.m12 = nm12;
        dest.m20 = nm20;
        dest.m21 = nm21;
        dest.m22 = nm22;
        dest.m30 = nm30;
        dest.m31 = nm31;
        dest.m32 = nm32;
        dest.properties = 0;
        return dest;
    }
118284
public Vector3f mul(Matrix3fc mat, Vector3f dest) {
        float rx = mat.m00() * x + mat.m10() * y + mat.m20() * z;
        float ry = mat.m01() * x + mat.m11() * y + mat.m21() * z;
        float rz = mat.m02() * x + mat.m12() * y + mat.m22() * z;
        dest.x = rx;
        dest.y = ry;
        dest.z = rz;
        return dest;
    }
244015
public static void checkMatrixMultiplication() {

        DoubleMatrix A = new DoubleMatrix(new double[][]{
                    {1.0, 2.0, 3.0},
                    {4.0, 5.0, 6.0},
                    {7.0, 8.0, 9.0}
                });
        DoubleMatrix E = new DoubleMatrix(new double[][]{
                    {0.0, 0.0, 1.0},
                    {0.0, 1.0, 0.0},
                    {1.0, 0.0, 0.0}
                });
        DoubleMatrix B = new DoubleMatrix(new double[][]{
                    {3.0, 2.0, 1.0},
                    {6.0, 5.0, 4.0},
                    {9.0, 8.0, 7.0}
                });

        check("checking matrix multiplication", A.mmul(E).equals(B));
    }
367879
public void multT(DoubleMatrix bMat, DoubleMatrix cMat, boolean transposeA, boolean transposeB) {
        if (!transposeA) {            
            throw new IllegalArgumentException("Multiplication where this matrix NOT transposed is not implemented.");
        }
        
        SparseRowDoubleMatrix.checkMultDimensions(this.viewTranspose(), transposeB ? bMat.viewTranspose() : bMat, cMat);

        int numRowsC = cMat.getNumRows();
        int numColsC = cMat.getNumColumns();
        
        if (bMat instanceof DenseDoubleMatrix) {
            DenseDoubleMatrix denseBMat = (DenseDoubleMatrix) bMat;
            for (int row = 0; row < numRowsC; row++) {
                for (int col = 0; col < numColsC; col++) {
                    if (transposeB) {
                        cMat.set(row, col, this.cols[row].dot(denseBMat.matrix[col]));
                    } else {
                        cMat.set(row, col, this.cols[row].dot(denseBMat.matrix, col));
                    }
                }
            }
        } else if (bMat instanceof SparseColDoubleMatrix && !transposeB) {
            SparseColDoubleMatrix sparseBMat = (SparseColDoubleMatrix) bMat;
            for (int row = 0; row < numRowsC; row++) {
                for (int col = 0; col < numColsC; col++) {
                    cMat.set(row, col, this.cols[row].dot(sparseBMat.cols[col]));
                }
            }
        } else if (bMat instanceof SparseRowDoubleMatrix && transposeB) {
            SparseRowDoubleMatrix sparseBMat = (SparseRowDoubleMatrix) bMat;
            for (int row = 0; row < numRowsC; row++) {
                for (int col = 0; col < numColsC; col++) {
                    cMat.set(row, col, this.cols[row].dot(sparseBMat.rows[col]));
                }
            }
        } else {
            throw new IllegalArgumentException("unhandled type: " + bMat.getClass().getCanonicalName());
        }
    }
178847
public Vector2d mulDirection(Matrix3x2dc mat, Vector2d dest) {
        double rx = mat.m00() * x + mat.m10() * y;
        double ry = mat.m01() * x + mat.m11() * y;
        dest.x = rx;
        dest.y = ry;
        return dest;
    }
729055
public Vector3d mul(double scalar, Vector3d dest) {
        dest.x = x * scalar;
        dest.y = y * scalar;
        dest.z = z * scalar;
        return dest;
    }
517220
public static INDArray toMmulCompatible(INDArray input) {
        if (input.rank() != 2)
            throw new IllegalArgumentException("Input must be rank 2 (matrix)");
        //Same conditions as GemmParams.copyIfNecessary()
        boolean doCopy = false;
        if (input.ordering() == 'c' && (input.stride(0) != input.size(1) || input.stride(1) != 1))
            doCopy = true;
        else if (input.ordering() == 'f' && (input.stride(0) != 1 || input.stride(1) != input.size(0)))
            doCopy = true;

        if (doCopy)
            return Shape.toOffsetZeroCopyAnyOrder(input);
        else
            return input;
    }
504830
public static void multAddOuter( double alpha , DMatrix5x5 A , double beta , DMatrix5 u , DMatrix5 v , DMatrix5x5 C ) {
        C.a11 = alpha*A.a11 + beta*u.a1*v.a1;
        C.a12 = alpha*A.a12 + beta*u.a1*v.a2;
        C.a13 = alpha*A.a13 + beta*u.a1*v.a3;
        C.a14 = alpha*A.a14 + beta*u.a1*v.a4;
        C.a15 = alpha*A.a15 + beta*u.a1*v.a5;
        C.a21 = alpha*A.a21 + beta*u.a2*v.a1;
        C.a22 = alpha*A.a22 + beta*u.a2*v.a2;
        C.a23 = alpha*A.a23 + beta*u.a2*v.a3;
        C.a24 = alpha*A.a24 + beta*u.a2*v.a4;
        C.a25 = alpha*A.a25 + beta*u.a2*v.a5;
        C.a31 = alpha*A.a31 + beta*u.a3*v.a1;
        C.a32 = alpha*A.a32 + beta*u.a3*v.a2;
        C.a33 = alpha*A.a33 + beta*u.a3*v.a3;
        C.a34 = alpha*A.a34 + beta*u.a3*v.a4;
        C.a35 = alpha*A.a35 + beta*u.a3*v.a5;
        C.a41 = alpha*A.a41 + beta*u.a4*v.a1;
        C.a42 = alpha*A.a42 + beta*u.a4*v.a2;
        C.a43 = alpha*A.a43 + beta*u.a4*v.a3;
        C.a44 = alpha*A.a44 + beta*u.a4*v.a4;
        C.a45 = alpha*A.a45 + beta*u.a4*v.a5;
        C.a51 = alpha*A.a51 + beta*u.a5*v.a1;
        C.a52 = alpha*A.a52 + beta*u.a5*v.a2;
        C.a53 = alpha*A.a53 + beta*u.a5*v.a3;
        C.a54 = alpha*A.a54 + beta*u.a5*v.a4;
        C.a55 = alpha*A.a55 + beta*u.a5*v.a5;
    }
1144070
public Matrix4d mulLocal(Matrix4dc left, Matrix4d dest) {
        if ((properties & PROPERTY_IDENTITY) != 0)
            return dest.set(left);
        else if ((left.properties() & PROPERTY_IDENTITY) != 0)
            return dest.set(this);
        else if ((properties & PROPERTY_AFFINE) != 0 && (left.properties() & PROPERTY_AFFINE) != 0)
            return mulLocalAffine(left, dest);
        return mulLocalGeneric(left, dest);
    }
535211
public Vector2d mulPosition(Matrix3x2dc mat, Vector2d dest) {
        double rx = mat.m00() * x + mat.m10() * y + mat.m20();
        double ry = mat.m01() * x + mat.m11() * y + mat.m21();
        dest.x = rx;
        dest.y = ry;
        return dest;
    }
1059044
public static DMatrixRMaj concatColumnsMulti(DMatrixRMaj ...m ) {
        int rows = 0;
        int cols = 0;

        for (int i = 0; i < m.length; i++) {
            rows = Math.max(rows,m[i].numRows);
            cols += m[i].numCols;
        }
        DMatrixRMaj R = new DMatrixRMaj(rows,cols);

        int col = 0;
        for (int i = 0; i < m.length; i++) {
            insert(m[i],R,0,col);
            col += m[i].numCols;
        }

        return R;
    }
249991
public Vector3i mul(int x, int y, int z, Vector3i dest) {
        dest.x = this.x * x;
        dest.y = this.y * y;
        dest.z = this.z * z;
        return dest;
    }
1075488
public Matrix4f mulPerspectiveAffine(Matrix4fc view, Matrix4f dest) {
        float nm00 = m00 * view.m00();
        float nm01 = m11 * view.m01();
        float nm02 = m22 * view.m02();
        float nm03 = m23 * view.m02();
        float nm10 = m00 * view.m10();
        float nm11 = m11 * view.m11();
        float nm12 = m22 * view.m12();
        float nm13 = m23 * view.m12();
        float nm20 = m00 * view.m20();
        float nm21 = m11 * view.m21();
        float nm22 = m22 * view.m22();
        float nm23 = m23 * view.m22();
        float nm30 = m00 * view.m30();
        float nm31 = m11 * view.m31();
        float nm32 = m22 * view.m32() + m32;
        float nm33 = m23 * view.m32();
        dest._m00(nm00);
        dest._m01(nm01);
        dest._m02(nm02);
        dest._m03(nm03);
        dest._m10(nm10);
        dest._m11(nm11);
        dest._m12(nm12);
        dest._m13(nm13);
        dest._m20(nm20);
        dest._m21(nm21);
        dest._m22(nm22);
        dest._m23(nm23);
        dest._m30(nm30);
        dest._m31(nm31);
        dest._m32(nm32);
        dest._m33(nm33);
        dest._properties(0);
        return dest;
    }
1234912
public void mutableMultiply(double c, double d)
    {
        double newR = this.real*c-this.imag*d;
        double newI = this.imag*c+this.real*d;
        this.real = newR;
        this.imag = newI;
    }
294839
public Vector2d mul(double scalar, Vector2d dest) {
        dest.x = x * scalar;
        dest.y = y * scalar;
        return dest;
    }
109927
public static void multCol(Matrix A, int j, double c)
    {
        multCol(A, j, 0, A.rows(), c);
    }
201410
public static void multAddOuter( double alpha , DMatrix4x4 A , double beta , DMatrix4 u , DMatrix4 v , DMatrix4x4 C ) {
        C.a11 = alpha*A.a11 + beta*u.a1*v.a1;
        C.a12 = alpha*A.a12 + beta*u.a1*v.a2;
        C.a13 = alpha*A.a13 + beta*u.a1*v.a3;
        C.a14 = alpha*A.a14 + beta*u.a1*v.a4;
        C.a21 = alpha*A.a21 + beta*u.a2*v.a1;
        C.a22 = alpha*A.a22 + beta*u.a2*v.a2;
        C.a23 = alpha*A.a23 + beta*u.a2*v.a3;
        C.a24 = alpha*A.a24 + beta*u.a2*v.a4;
        C.a31 = alpha*A.a31 + beta*u.a3*v.a1;
        C.a32 = alpha*A.a32 + beta*u.a3*v.a2;
        C.a33 = alpha*A.a33 + beta*u.a3*v.a3;
        C.a34 = alpha*A.a34 + beta*u.a3*v.a4;
        C.a41 = alpha*A.a41 + beta*u.a4*v.a1;
        C.a42 = alpha*A.a42 + beta*u.a4*v.a2;
        C.a43 = alpha*A.a43 + beta*u.a4*v.a3;
        C.a44 = alpha*A.a44 + beta*u.a4*v.a4;
    }