/// <summary>
        /// Performs the matrix-vector multiplication: oper(this) * <paramref name="vector"/>.
        /// To multiply this * columnVector, set <paramref name="transposeThis"/> to false.
        /// To multiply rowVector * this, set <paramref name="transposeThis"/> to true.
        /// The resulting vector will be written in a new vector and returned.
        /// </summary>
        /// <param name="vector">
        /// A vector with Length being equal to the <see cref="IIndexable2D.NumColumns"/> of oper(this).
        /// </param>
        /// <param name="transposeThis">If true, oper(this) = transpose(this). Otherwise oper(this) = this.</param>
        /// <exception cref="NonMatchingDimensionsException">
        /// Thrown if <paramref name="vector"/>.Length is different than the <see cref="IIndexable2D.NumColumns"/> of oper(this).
        /// </exception>
        public static double[] Multiply(this IMatrixView matrix, double[] vector, bool transposeThis = false)
        {
            var result = new double[transposeThis ? matrix.NumColumns : matrix.NumRows];

            matrix.MultiplyIntoResult(Vector.CreateFromArray(vector), Vector.CreateFromArray(result), transposeThis);
            return(result);
        }
 /// <summary>
 /// Performs the matrix-vector multiplication: <paramref name="rhsVector"/> = oper(this) * <paramref name="lhsVector"/>.
 /// To multiply this * columnVector, set <paramref name="transposeThis"/> to false.
 /// To multiply rowVector * this, set <paramref name="transposeThis"/> to true.
 /// The resulting vector will overwrite the entries of <paramref name="rhsVector"/>.
 /// </summary>
 /// <param name="lhsVector">
 /// The vector that will be multiplied by this matrix. It sits on the left hand side of the equation y = oper(A) * x.
 /// Constraints: <paramref name="lhsVector"/>.Length == oper(this).<see cref="IIndexable2D.NumColumns"/>.
 /// </param>
 /// <param name="rhsVector">
 /// The vector that will be overwritten by the result of the multiplication. It sits on the right hand side of the
 /// equation y = oper(A) * x. Constraints: <paramref name="rhsVector"/>.Length
 /// == oper(this).<see cref="IIndexable2D.NumRows"/>.
 /// </param>
 /// <param name="transposeThis">If true, oper(this) = transpose(this). Otherwise oper(this) = this.</param>
 /// <exception cref="NonMatchingDimensionsException">
 /// Thrown if the <paramref name="lhsVector"/>.Length or <paramref name="rhsVector"/>.Length violate the described
 /// constraints.
 /// </exception>
 /// <exception cref="PatternModifiedException">
 /// Thrown if the storage format of <paramref name="rhsVector"/> does not support overwritting the entries that this
 /// method will try to.
 /// </exception>
 public static void MultiplyIntoResult(this IMatrixView matrix, double[] lhsVector, double[] rhsVector,
                                       bool transposeThis = false)
 => matrix.MultiplyIntoResult(Vector.CreateFromArray(lhsVector), Vector.CreateFromArray(rhsVector), transposeThis);