Multiply this matrix by another matrix.
@param m the matrix multiplier
@return the product matrix
@throws numbercruncher.MatrixException for invalid size
320991
public Matrix multiply(Matrix m) throws MatrixException
    {
        // Validate m's dimensions.
        if (nCols != m.nRows) {
            throw new MatrixException(
                                MatrixException.INVALID_DIMENSIONS);
        }

        double pv[][] = new double[nRows][m.nCols];  // product values

        // Compute values of the product.
        for (int r = 0; r < nRows; ++r) {
            for (int c = 0; c < m.nCols; ++c) {
                double dot = 0;
                for (int k = 0; k < nCols; ++k) {
                    dot += values[r][k] * m.values[k][c];
                }
                pv[r][c] = dot;
            }
        }

        return new Matrix(pv);
    }
1067062
public Matrix times(Matrix B) {
        Matrix A = this;
        if (A.N != B.M) {
            throw new RuntimeException("Illegal matrix dimensions.");
        }
        Matrix C = new Matrix(A.M, B.N);
        for (int i = 0; i < C.M; i++) {
            for (int j = 0; j < C.N; j++) {
                for (int k = 0; k < A.N; k++) {
                    C.data[i][j] += A.data[i][k] * B.data[k][j];
                }
            }
        }
        return C;
    }
1179317
public Matrix4d m23(double m23) {
        this.m23 = m23;
        if (m23 != 0.0)
            properties &= ~(PROPERTY_IDENTITY | PROPERTY_AFFINE | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL);
        return this;
    }
920349
public static double[][] times(final double[][] m1, final double[][] m2) {
    final int rowdim1 = m1.length, coldim1 = getColumnDimensionality(m1);
    final int coldim2 = getColumnDimensionality(m2);
    // Optimized implementation, exploiting the storage layout
    assert m2.length == coldim1 : ERR_MATRIX_INNERDIM;
    final double[][] r2 = new double[rowdim1][coldim2];
    // Optimized ala Jama. jik order.
    final double[] Bcolj = new double[coldim1];
    for(int j = 0; j < coldim2; j++) {
      // Make a linear copy of column j from B
      for(int k = 0; k < coldim1; k++) {
        Bcolj[k] = m2[k][j];
      }
      // multiply it with each row from A
      for(int i = 0; i < rowdim1; i++) {
        final double[] Arowi = m1[i];
        double s = 0;
        for(int k = 0; k < coldim1; k++) {
          s += Arowi[k] * Bcolj[k];
        }
        r2[i][j] = s;
      }
    }
    return r2;
  }
7214
public Matrix4x3f m02(float m02) {
        this.m02 = m02;
        properties &= ~PROPERTY_ORTHONORMAL;
        if (m02 != 0.0f)
            properties &= ~(PROPERTY_IDENTITY | PROPERTY_TRANSLATION);
        return this;
    }
513538
public Matrix multiply(double c)
    {
        Matrix toReturn = getThisSideMatrix(null);
        toReturn.mutableMultiply(c);
        return toReturn;
    }
78155
public Matrix4x3f m00(float m00) {
        this.m00 = m00;
        properties &= ~PROPERTY_ORTHONORMAL;
        if (m00 != 1.0f)
            properties &= ~(PROPERTY_IDENTITY | PROPERTY_TRANSLATION);
        return this;
    }
1149485
public static <T extends Transform> T multiply (
        double m00, double m01, double m10, double m11, double tx, double ty, AffineTransform b, T into) {
        return multiply(m00, m01, m10, m11, tx, ty, b.m00, b.m01, b.m10, b.m11, b.tx, b.ty, into);
    }
117919
public Matrix transpose() {
        Matrix A = new Matrix(N, M);
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < N; j++) {
                A.data[j][i] = data[i][j];
            }
        }
        return A;
    }
276256
public static Matrix copy(Matrix m) {
		if (m==null) throw new NullPointerException();
		Matrix copy=createMatrix(m.getRowCount(), m.getColumnCount());
		for (int row=0; row<m.getRowCount(); row++) for (int col=0; col<m.getColumnCount(); col++)
			copy.set(row, col, m.getQuick(row, col));
		return copy;
	}

	/**
	 * Creates a copy of a matrix.
	 * @param m the matrix to copy
	 * @return a new matrix with the same dimensions and contents as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Matrix2 copy(Matrix2 m) {
		return (Matrix2) copy((Matrix)m);
	}

	/**
	 * Creates a copy of a matrix.
	 * @param m the matrix to copy
	 * @return a new matrix with the same dimensions and contents as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Matrix3 copy(Matrix3 m) {
		return (Matrix3) copy((Matrix)m);
	}

	/**
	 * Creates a copy of a matrix.
	 * @param m the matrix to copy
	 * @return a new matrix with the same dimensions and contents as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Vector copy(Vector m) {
		return (Vector) copy((Matrix)m);
	}

	/**
	 * Creates a copy of a matrix.
	 * @param m the matrix to copy
	 * @return a new matrix with the same dimensions and contents as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Vector2 copy(Vector2 m) {
		return (Vector2) copy((Matrix)m);
	}

	/**
	 * Creates a copy of a matrix.
	 * @param m the matrix to copy
	 * @return a new matrix with the same dimensions and contents as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Vector3 copy(Vector3 m) {
		return (Vector3) copy((Matrix)m);
	}

	/**
	 * Creates a copy of a matrix.
	 * @param m the matrix to copy
	 * @return a new matrix with the same dimensions and contents as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Vector4 copy(Vector4 m) {
		return (Vector4) copy((Matrix)m);
	}
	
	/**
	 * Creates a matrix with the same dimensions as the argument.
	 * @param matrix the template matrix
	 * @return a new zero matrix with the same dimensions as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Matrix createLike(Matrix matrix) {
		return createMatrix(matrix.getRowCount(), matrix.getColumnCount());
	}
	
	/**
	 * Creates a matrix with the same dimensions as the argument.
	 * @param matrix the template matrix
	 * @return a new zero matrix with the same dimensions as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Matrix2 createLike(Matrix2 matrix) {
		return (Matrix2) createMatrix(matrix.getRowCount(), matrix.getColumnCount());
	}
	
	/**
	 * Creates a matrix with the same dimensions as the argument.
	 * @param matrix the template matrix
	 * @return a new zero matrix with the same dimensions as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Matrix3 createLike(Matrix3 matrix) {
		return (Matrix3) createMatrix(matrix.getRowCount(), matrix.getColumnCount());
	}
	
	/**
	 * Creates a matrix with the same dimensions as the argument.
	 * @param matrix the template matrix
	 * @return a new zero matrix with the same dimensions as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Vector createLike(Vector matrix) {
		return (Vector) createMatrix(matrix.getRowCount(), matrix.getColumnCount());
	}
	
	/**
	 * Creates a matrix with the same dimensions as the argument.
	 * @param matrix the template matrix
	 * @return a new zero matrix with the same dimensions as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Vector2 createLike(Vector2 matrix) {
		return (Vector2) createMatrix(matrix.getRowCount(), matrix.getColumnCount());
	}
	
	/**
	 * Creates a matrix with the same dimensions as the argument.
	 * @param matrix the template matrix
	 * @return a new zero matrix with the same dimensions as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Vector3 createLike(Vector3 matrix) {
		return (Vector3) createMatrix(matrix.getRowCount(), matrix.getColumnCount());
	}
	
	/**
	 * Creates a matrix with the same dimensions as the argument.
	 * @param matrix the template matrix
	 * @return a new zero matrix with the same dimensions as the argument
	 * @throws NullPointerException if {@code matrix} is {@code null}
	 */
	public static Vector4 createLike(Vector4 matrix) {
		return (Vector4) createMatrix(matrix.getRowCount(), matrix.getColumnCount());
	}
	
	/**
	 * Creates an identity matrix of the specified dimension.
	 * @param size the dimension of the matrix
	 * @return a <code>size</code>×<code>size</code> identity matrix
	 * @throws IllegalArgumentException if the size is not positive
	 */
	public static Matrix identity(int size) {
		Matrix m = MatrixFactory.createMatrix(size, size);
		for (int i = 0; i < size; i++)
			m.set(i, i, 1);
		return m;
	}

	/**
	 * Creates a matrix of the specified size whose elements are all 1.
	 * @param rows the number of rows
	 * @param columns the number of columns
	 * @return a <code>rows</code>×<code>columns</code> matrix whose elements are all 1
	 * @throws IllegalArgumentException if either argument is non-positive
	 */
	public static Matrix ones(int rows, int columns) {
		Matrix m = MatrixFactory.createMatrix(rows, columns);
		for (int i = 0; i < m.getRowCount(); i++)
			for (int j = 0; j < m.getColumnCount(); j++)
				m.set(i, j, 1);
		return m;
	}

	/**
	 * Creates a matrix of the specified size whose elements are pseudorandom, uniformly distributed
	 * values between 0 (inclusive) and 1 (exclusive).
	 * @param rows the number of rows
	 * @param columns the number of columns
	 * @return a <code>rows</code>×<code>columns</code> matrix of random elements
	 * @throws IllegalArgumentException if either argument is non-positive
	 */
	public static Matrix random(int rows, int columns) {
		Matrix m = MatrixFactory.createMatrix(rows, columns);
		for (int i = 0; i < m.getRowCount(); i++)
			for (int j = 0; j < m.getColumnCount(); j++)
				m.set(i, j, Math.random());
		return m;
	}
	
	//
	// Matrix creation from arrays
	//
	
	/**
	 * Creates a matrix and initializes its elements from an array. The parameter should be a {@code double[r][c]}
	 * array with {@code r>0} and {@code c>0}. The matrix element at row {@code row} and column {@code col} will be
	 * {@code elements[row][col]}.
	 * @param elements the array containing the elements of the matrix
	 * @return the new matrix initialized from the array
	 * @throws NullPointerException if the array is {@code null}
	 * @throws IllegalArgumentException if the dimensions of the array are not valid
	 */
	public static Matrix createMatrix(double[][] elements) {
		Matrix m=createMatrix(elements.length, elements[0].length);
		for (int row=0; row<m.getRowCount(); row++) {
			double[] rowData=elements[row];
			if (rowData.length!=m.getColumnCount()) throw new IllegalArgumentException("Invalid array");
			for (int col=0; col<m.getColumnCount(); col++) {
				m.set(row, col, rowData[col]);
			}
		}
		return m;
	}
	
	/**
	 * Creates a matrix and initializes its elements from an array. The parameter should be a {@code double[2][2]}
	 * array. The matrix element at row {@code row} and column {@code col} will be
	 * {@code elements[row][col]}.
	 * @param elements the array containing the elements of the matrix
	 * @return the new matrix initialized from the array
	 * @throws NullPointerException if the array is {@code null}
	 * @throws IllegalArgumentException if the dimensions of the array are not correct
	 */
	public static Matrix2 createMatrix2(double[][] elements) {
		Matrix m=createMatrix(elements);
		if (m.getRowCount()!=2 || m.getColumnCount()!=2)
			throw new IllegalArgumentException("Array describes a matrix of size "+m.getRowCount()+"x"+m.getColumnCount()+" instead of 2x2");
		return (Matrix2)m;
	}
	
	/**
	 * Creates a matrix and initializes its elements from an array. The parameter should be a {@code double[3][3]}
	 * array. The matrix element at row {@code row} and column {@code col} will be
	 * {@code elements[row][col]}.
	 * @param elements the array containing the elements of the matrix
	 * @return the new matrix initialized from the array
	 * @throws NullPointerException if the array is {@code null}
	 * @throws IllegalArgumentException if the dimensions of the array are not correct
	 */
	public static Matrix3 createMatrix3(double[][] elements) {
		Matrix m=createMatrix(elements);
		if (m.getRowCount()!=3 || m.getColumnCount()!=3)
			throw new IllegalArgumentException("Array describes a matrix of size "+m.getRowCount()+"x"+m.getColumnCount()+" instead of 3x3");
		return (Matrix3)m;
	}
	
	/**
	 * Creates a vector and initializes its elements from an array.
	 * @param elements the array containing the elements of the vector
	 * @return the new vector initialized from the array
	 * @throws NullPointerException if the array is {@code null}
	 * @throws IllegalArgumentException if the length of the array is zero
	 */
	public static Vector createVector(double[] elements) {
		Vector v=createVector(elements.length);
		for (int i=0; i<elements.length; i++)
			v.setCoordQuick(i, elements[i]);
		return v;
	}
	
	/**
	 * Creates a matrix backed by the specified data structure.
	 * @param core the data structure for the new matrix
	 * @return a matrix of proper type using the specified matrix core for its implementation
	 * @throws NullPointerException if {@code core} is {@code null}
	 */
	public static Matrix create(MatrixCore core) {
		if (core.getColumnCount()==1) {
			switch (core.getRowCount()) {
				case 2: return new CoredVector2Impl(core);
				case 3: return new CoredVector3Impl(core);
				case 4: return new CoredVector4Impl(core);
				default: return new CoredVectorImpl(core);
			}
		} else {
			if (core.getRowCount()==2 && core.getColumnCount()==2)
				return new CoredMatrix2Impl(core);
			if (core.getRowCount()==3 && core.getColumnCount()==3)
				return new CoredMatrix3Impl(core);
			return new CoredMatrixImpl(core);
		}
	}
}
623048
public Matrix mtimes(Matrix m2) {
		if (m2 instanceof DenseDoubleMatrix2D) {
			final DenseDoubleMatrix2D result = new BlockDenseDoubleMatrix2D((int) getRowCount(),
					(int) m2.getColumnCount(), layout.blockStripe, BlockOrder.ROWMAJOR);
			Mtimes.DENSEDOUBLEMATRIX2D.calc(this, (DenseDoubleMatrix2D) m2, result);
			return result;
		} else {
			return super.mtimes(m2);
		}
	}
1356756
public Matrix4x3f m20(float m20) {
        this.m20 = m20;
        properties &= ~PROPERTY_ORTHONORMAL;
        if (m20 != 0.0f)
            properties &= ~(PROPERTY_IDENTITY | PROPERTY_TRANSLATION);
        return this;
    }
787181
public static double sum(double[][] matrix) {
        double sum = 0; 
        for (int i=0; i<matrix.length; i++) {
            sum += sum(matrix[i]);
        }
        return sum;
    }
1334511
public double compute( DMatrix1Row mat ) {
        if( width != mat.numCols || width != mat.numRows ) {
            throw new RuntimeException("Unexpected matrix dimension");
        }

        // make sure everything is in the proper state before it starts
        initStructures();

//        System.arraycopy(mat.data,0,minorMatrix[0],0,mat.data.length);

        int level = 0;
        while( true ) {
            int levelWidth = width-level;
            int levelIndex = levelIndexes[level];

            if( levelIndex == levelWidth ) {
                if( level == 0 ) {
                    return levelResults[0];
                }
                int prevLevelIndex = levelIndexes[level-1]++;

                double val = mat.get((level-1)*width+levelRemoved[level-1]);
                if( prevLevelIndex % 2 == 0 ) {
                    levelResults[level-1] += val * levelResults[level];
                } else {
                    levelResults[level-1] -= val * levelResults[level];
                }

                putIntoOpen(level-1);

                levelResults[level] = 0;
                levelIndexes[level] = 0;
                level--;
            } else {
                int excluded = openRemove( levelIndex );

                levelRemoved[level] = excluded;

                if( levelWidth == minWidth ) {
                    createMinor(mat);
                    double subresult = mat.get(level*width+levelRemoved[level]);

                    subresult *= UnrolledDeterminantFromMinor_DDRM.det(tempMat);

                    if( levelIndex % 2 == 0 ) {
                        levelResults[level] += subresult;
                    } else {
                        levelResults[level] -= subresult;
                    }

                    // put it back into the list
                    putIntoOpen(level);
                    levelIndexes[level]++;
                } else {
                    level++;
                }
            }
        }
    }
1298126
public static Matrix average(Matrix m, Dimension dim) {
        Matrix averageMatrix = null;

        if (dim == Dimension.ALL) {
            // Compute the average of all values in the matrix.
            double average = 0;
            for (int i = 0; i < m.rows(); ++i) {
                for (int j = 0; j < m.columns(); ++j)
                    average += m.get(i, j);
            }

            averageMatrix = new ArrayMatrix(1, 1);
            average = average / (double) (m.rows() * m.columns());
            averageMatrix.set(1, 1, average);
        } else if (dim == Dimension.ROW) {
            // Compute the average of each row in the matrix.
            averageMatrix = new ArrayMatrix(m.rows(), 1);
            for (int i = 0; i < m.rows(); ++i) {
                double average = 0;
                for (int j = 0; j < m.columns(); ++j)
                    average += m.get(i, j);

                average = average / (double) m.columns();
                averageMatrix.set(i, 0, average);
            }
        } else if (dim == Dimension.COLUMN) {
            // Compute the average of each column in the matrix.
            averageMatrix = new ArrayMatrix(1, m.columns());
            for (int i = 0; i < m.rows(); ++i) {
                for (int j = 0; j < m.columns(); ++j) {
                    double newValue = m.get(i, j) + averageMatrix.get(0, j);
                    averageMatrix.set(0, j, newValue);
                }
            }

            for (int i = 0; i < m.columns(); ++i) {
                double average = averageMatrix.get(0, i);
                average = average / (double) m.rows();
                averageMatrix.set(0, i, average);
            }
        }
        return averageMatrix;
    }
629219
public Matrix4d m21(double m21) {
        this.m21 = m21;
        properties &= ~PROPERTY_ORTHONORMAL;
        if (m21 != 0.0)
            properties &= ~(PROPERTY_IDENTITY | PROPERTY_PERSPECTIVE | PROPERTY_TRANSLATION);
        return this;
    }
368991
public Matrix3x2f set(Matrix3x2fc m) {
        if (m instanceof Matrix3x2f) {
            MemUtil.INSTANCE.copy((Matrix3x2f) m, this);
        } else {
            setMatrix3x2fc(m);
        }
        return this;
    }