## `Dom::Matrix` -- matrices

#### Introduction

`Dom::Matrix``(R)` creates a domain of matrices over the component ring R.

#### Domain

`Dom::Matrix( <R>)`

#### Parameters

`R` | - | a ring, i.e., a domain of category `Cat::Rng`; default is `Dom::ExpressionField()`

#### Details

- `Dom::Matrix``(R)` creates domains of matrices over a component domain `R` of category `Cat::Rng` (a ring, possibly without unit).

  If the optional parameter `R` is not given, the domain `Dom::ExpressionField()` is used.

- A vector with n entries is either an n x 1 matrix (a column vector), or a 1 x n matrix (a row vector).
- Arithmetical operations with matrices can be performed by using the standard arithmetical operators of MuPAD.

  E.g., if `A` and `B` are two matrices defined by `Dom::Matrix``(R)`, `A + B` computes the sum, and `A * B` computes the product of the two matrices, provided that the dimensions are correct.

  Similarly, `A^(-1)` or `1/A` computes the inverse of a square matrix `A` if it exists, and returns `FAIL` otherwise. See example 1.

- Many system functions have been overloaded for matrices, such as `map`, `subs`, `has`, `zip`, `conjugate` to compute the complex conjugate of a matrix, `norm` to compute matrix norms, or `exp` to compute the exponential of a matrix.
- Most of the functions in MuPAD's linear algebra package `linalg` work with matrices. For example, to compute the determinant of a square matrix `A`, call `linalg::det(A)`. The command `linalg::gaussJordan(A)` performs Gauss-Jordan elimination on `A` to transform `A` to its reduced row echelon form.

  See the documentation of `linalg` for a list of available functions of this package.

- The domain `Dom::Matrix``(R)` represents matrices over `R` of arbitrary size, and it therefore does not have any algebraic structure (other than being a set of matrices).

  The domain `Dom::SquareMatrix(n, R)` represents the ring of n x n matrices over R. The domain `Dom::MatrixGroup(m, n, R)` represents the Abelian group of m x n matrices over R.

- We use the following notations for a matrix A (an element of `Dom::Matrix``(R)`):
  - nrows(A) denotes the number of rows of A.
  - ncols(A) denotes the number of columns of A.
  - A row index is an integer in the range from 1 to nrows(A).
  - A column index is an integer in the range from 1 to ncols(A).

#### Creating Elements

``Dom::Matrix`(R)(Array)`
``Dom::Matrix`(R)(List)`
``Dom::Matrix`(R)(ListOfRows)`
``Dom::Matrix`(R)(Matrix)`
``Dom::Matrix`(R)(m, n)`
``Dom::Matrix`(R)(m, n, ListOfRows)`
``Dom::Matrix`(R)(m, n, f)`
``Dom::Matrix`(R)(m, n, List, Diagonal)`
``Dom::Matrix`(R)(m, n, g, Diagonal)`
``Dom::Matrix`(R)(m, n, List, Banded)`
``Dom::Matrix`(R)(1, n, List)`
``Dom::Matrix`(R)(m, 1, List)`

#### Parameters

`Array` | - | a one- or two-dimensional array
`Matrix` | - | a matrix, i.e., an element of a domain of category `Cat::Matrix`
`m, n` | - | matrix dimension (positive integers)
`List` | - | a list of matrix components
`ListOfRows` | - | a list of at most `m` rows; each row given as a list of at most `n` matrix components
`f` | - | a function or a functional expression with two parameters (the row and column index)
`g` | - | a function or a functional expression with one parameter (the row index)

#### Options

`Diagonal` | - | create a diagonal matrix
`Banded` | - | create a banded Toeplitz matrix

#### Categories

`Cat::Matrix(R)`

#### Related Domains

`Dom::SquareMatrix`, `Dom::MatrixGroup`

#### Details

- `Dom::Matrix``(R)(Array)` and `Dom::Matrix``(R)(Matrix)` create a new matrix with the dimension and the components of `Array` and `Matrix`, respectively.

  The components of `Array` or `Matrix` are converted into elements of the domain `R`. An error message is issued if one of these conversions fails.

- `Dom::Matrix``(R)(List)` creates an m x 1 column vector with components taken from the nonempty list, where m is the number of entries of `List`.
- `Dom::Matrix``(R)(ListOfRows)` creates an m x n matrix with components taken from the nested list `ListOfRows`, where m is the number of inner lists of `ListOfRows`, and n is the maximal number of elements of an inner list. Each inner list corresponds to a row of the matrix. Both m and n must be nonzero.

  If an inner list has less than n entries, then the remaining components in the corresponding row of the matrix are set to zero.

  The entries of the inner lists are converted into elements of the domain `R`. An error message is issued if one of these conversions fails.

- The call `Dom::Matrix``(R)(m, n)` returns the m x n zero matrix.

  Use the method `"identity"` to create the n x n identity matrix.

- `Dom::Matrix``(R)(m, n, ListOfRows)` creates an m x n matrix with components taken from the list `ListOfRows`.

  If m >= 2 and n >= 2, then `ListOfRows` must consist of at most `m` inner lists, each having at most `n` entries. The inner lists correspond to the rows of the returned matrix.

  If an inner list has less than `n` entries, then the remaining components of the corresponding row of the matrix are set to zero. If there are less than `m` inner lists, then the remaining lower rows of the matrix are filled with zeroes.

- `Dom::Matrix``(R)(m, n, f)` returns the matrix whose (i,j)th component is the value of the function call `f(i,j)`. The row index i ranges from 1 to m and the column index j from 1 to n.

  The function values are converted into elements of the domain `R`. An error message is issued if one of these conversions fails.

- `Dom::Matrix``(R)(1, n, List)` returns the 1 x n row vector with components taken from `List`. The list `List` must have at most `n` entries. If there are fewer entries, then the remaining vector components are set to zero.

  The entries of the list are converted into elements of the domain `R`. An error message is issued if one of these conversions fails.

- `Dom::Matrix``(R)(m, 1, List)` returns the m x 1 column vector with components taken from `List`. The list `List` must have at most `m` entries. If there are fewer entries, then the remaining vector components are set to zero.

  The entries of the list are converted into elements of the domain `R`. An error message is issued if one of these conversions fails.

#### Option: Diagonal

- With the option Diagonal, diagonal matrices can be created with diagonal elements taken from a list, or computed by a function or a functional expression.
- `Dom::Matrix``(R)(m, n, List, Diagonal)` creates the m x n diagonal matrix whose diagonal elements are the entries of `List`.

  `List` must have at most min(m, n) entries. If it has fewer elements, the remaining diagonal elements are set to zero.

  The entries of `List` are converted into elements of the domain `R`. An error message is issued if one of these conversions fails.

- `Dom::Matrix``(R)(m, n, g, Diagonal)` returns the matrix whose ith diagonal element is `g(i)`, where the index i runs from 1 to min(n,m).

  The function values are converted into elements of the domain `R`. An error message is issued if one of these conversions fails.

#### Option: Banded

- `Dom::Matrix``(R)(m, n, List, Banded)` creates an m x n banded Toeplitz matrix with the elements of `List` as entries. The number of entries of `List` must be odd, say 2h+1, and must not exceed `n`. The resulting matrix has bandwidth at most 2h+1.

  A Toeplitz matrix is a matrix where the elements of each band are identical. See also example 7.

  All elements of the main diagonal of the created matrix are initialized with the middle element of `List`. All elements of the ith subdiagonal are initialized with the (h+1-i)th element of `List`. All elements of the ith superdiagonal are initialized with the (h+1+i)th element of `List`. All entries on the remaining sub- and superdiagonals are set to zero.

  The entries of `List` are converted into elements of the domain `R`. An error message is issued if one of these conversions fails.

#### Entries

isSparse

  is always `FALSE`, as elements of `Dom::Matrix``(R)` use a dense representation of their matrix components.

randomDimen

  is set to `[10,10]`. See the method `"random"` below for details.

#### Method _divide: divides matrices

- `_divide(dom A, dom B)`
- - This method computes the product A * B^(-1). The matrix `B` must be nonsingular, otherwise `FAIL` is returned.
  - An error message is issued if the dimensions of `A` and `B` do not match.
  - This method only exists if `R` is an integral domain, i.e., a domain of category `Cat::IntegralDomain`.
  - This method overloads the function `_divide` for matrices, i.e., one may use it in the form `A / B`, or in functional notation: `_divide(A, B)`.

#### Method _invert: computes the inverse of a matrix

- `_invert(dom A)`
- - This method computes the inverse of the matrix `A`. If `A` is singular, `FAIL` is returned.
  - If the component ring `R` is the domain `Dom::Float`, a floating-point approximation of the inverse matrix is computed by the function `numeric::inverse`.
  - This method only exists if `R` is a domain of category `Cat::IntegralDomain`.
  - This method overloads the function `_invert` for matrices, i.e., one may use it in the form `1/A` or `A^(-1)`, or in functional notation: `_invert(A)`.

#### Method _mult: multiplies matrices by matrices, vectors and scalars

- `_mult(dom x, any y)`
- - If `y` is a matrix of the same domain type as `x`, the matrix product x*y is computed. An error message is issued if the dimensions of the matrices do not match.
  - If `y` is of the domain type `R` or can be converted into such an element, the corresponding scalar multiplication is computed.

    Otherwise, `y` is converted into a matrix of the domain type of `x`. If this conversion fails, then this method calls the method `"_mult"` of the domain of `y` giving all arguments in the same order.

- `_mult(any x, dom y)`
- - If `x` is a matrix of the same domain type as `y`, then the matrix product x*y is computed. An error message is issued if the dimensions of the matrices do not match.
  - If `x` is of the domain type `R` or can be converted into such an element, the corresponding scalar multiplication is computed.

    Otherwise, `x` is converted into a matrix of the domain type of `y`. If this conversion fails, then `FAIL` is returned.

  - This method handles more than two arguments by calling itself recursively with the first half of all arguments and the last half of all arguments. Then the product of these two results is computed with the system function `_mult`.
  - This method overloads the function `_mult` for matrices, i.e., one may use it in the form `x * y`, or in functional notation: `_mult(x, y)`.

#### Method _negate: negates a matrix

- `_negate(dom A)`
- - The matrix -A is returned.
  - This method overloads the function `_negate` for matrices, i.e., one may use it in the form `-A`, or in functional notation: `_negate(A)`.

#### Method _plus: adds matrices

- `_plus(matrix A, matrix B...)`
- - Returns the matrix sum A + B + ....

    An error message is issued if the given matrices do not have the same dimensions.

  - The arguments `A,` B... are converted into matrices of the domain type `Dom::Matrix``(R)`. `FAIL` is returned if one of these conversions fails.
  - This method overloads the function `_plus` for matrices, i.e., one may use it in the form `A + B`, or in functional notation: `_plus(A, B)`.

#### Method _power: the integer power of a matrix

- `_power(dom A, integer n)`
- - This method computes A^n. If `A` is not square, `FAIL` is returned.
  - If the power `n` is a negative integer then `A` must be nonsingular and `R` must be a domain of category `Cat::IntegralDomain`. Otherwise `FAIL` is returned.
  - If `n` is zero and the component ring `R` is a ring with no unit (i.e., of category `Cat::Rng`, but not of category `Cat::Ring`), `FAIL` is returned.
  - This method overloads the function `_power` for matrices, i.e., one may use it in the form `A^n`, or in functional notation: `_power(A, n)`.

#### Method conjugate: the complex conjugate of a matrix

- `conjugate(dom A)`
- - The complex conjugate matrix of `A` is the matrix obtained by computing the complex conjugate of each component of `A`.
  - This method only exists if `R` implements the method `"conjugate"`, which computes the complex conjugate of an element of the domain `R`.
  - This method overloads the function `conjugate` for matrices, i.e., one may use it in the form `conjugate(A)`.

#### Method diff: differentiation of matrix components

- `diff(dom A...)`
- - This method differentiates each component of the matrix `A` using the method `"diff"` of the component ring `R`.

    Additional arguments are passed to the method `"diff"` of the domain `R`. See the system function `diff` for details.

  - This method only exists if `R` implements the method `"diff"`.
  - This method overloads the function `diff` for matrices, i.e., one may use it in the form `diff(A...)`.

#### Method equal: equality test of matrices

- `equal(dom A, dom B)`
- - This method tests if the two matrices `A` and `B` are equal and returns `TRUE`, `FALSE`, or `UNKNOWN`, respectively.
  - Note that if `R` has the axiom `Ax::systemRep` then `normal` is used to simplify the components of `A` and `B` before testing their equality.

#### Method exp: the exponential of a matrix

- `exp(dom A <, R t>)`
- - This method computes the matrix exponential of the n x n matrix `A`, defined by I + A*t + 1/2(A*t)^2 + ..., where I is the n x n identity matrix. The default value of `t` is 1.
  - If `A` is not square, an error message is issued.
  - This method uses the function `numeric::expMatrix` for a floating-point approximation of the exponential of `A` if `A` is defined over the domain `Dom::Float` and if t = 1.
  - If some eigenvalues of `A` do not exist in `R` or cannot be computed, then `FAIL` is returned.
  - In the symbolic case the function `linalg::jordanForm` is called, which may not be able to compute the Jordan form of `A`. In this case `FAIL` is returned. Increasing the level of information (see `setuserinfo`) can yield useful information.
  - This method only exists if `R` is a domain of category `Cat::Field`.
  - This method overloads the function `exp` for matrices, i.e., one may use it in the form `exp(A...)`.

#### Method expand: expand matrix components

- `expand(dom A)`
- - This method applies the function `expand` to each component of the matrix `A`.
  - This method only exists if `R` implements the method `"expand"`, or if `R` has the axiom `Ax::systemRep` (in this case, the system function `expand` is used).
  - This method overloads the function `expand` for matrices, i.e., one may use it in the form `expand(A)`.

#### Method factor: scalar-matrix factorization

- `factor(dom A)`
- - This method factorizes `A` into the form A = s*B, where s is a scalar of the component ring `R`.

    The result is a factored object, i.e., an element of the domain `Factored`. It has the factorization type `"unknown"`.

  - The factor s is the gcd of all components of the matrix `A`. Hence, this method only exists if `R` is of category `Cat::GcdDomain`.
  - This method overloads the function `factor` for matrices, i.e., one may use it in the form `factor(A)`.

#### Method float: floating-point approximation of the matrix components

- `float(dom A)`
- - This method maps the function `float` to the matrix components of `A`, i.e., it computes a floating-point approximation of the matrix components.
  - This method only exists if `R` implements the method `"float"`.

  - Usually the floating-point approximations are not elements of `R`! For example, `Dom::Integer` implements such a method, but the floating-point approximation of an integer cannot be re-converted into an integer.

    This method checks whether the resulting matrix can be converted into the domain type of `A` only if `testargs` returns `TRUE` (e.g., if one calls this method from the interactive level of MuPAD).

    Otherwise, one has to take care that the matrix returned is compatible to its component ring.

#### Method gaussElim: Gaussian elimination

- `gaussElim(dom A)`
- - This method performs the Gaussian elimination on `A` and reduces `A` to an upper row echelon form T.

    It returns a list containing the matrix T, the rank and determinant of `A`, and the set of characteristic column indices of T (in this order).

  - If the matrix is not square, i.e., the determinant of `A` is not defined, then the third entry of the list returned is the value `FAIL`.
  - This method only exists if the component ring `R` is an integral domain, i.e., a domain of category `Cat::IntegralDomain`.
  - If `R` has the method `"pivotSize"`, then the pivot element of smallest size is chosen at every pivoting step, whereby `pivotSize` must return a positive integer representing the ``size'' of an element.

    If no such method is defined, Gaussian elimination without a pivot strategy is applied to `A`.

  - If `R` has the axiom `Ax::efficientOperation``("_invert")` and is of category `Cat::Field`, then ordinary Gaussian elimination is used. Otherwise, fraction-free elimination is performed on `A`.
  - If `R` implements the method `"normal"`, it is used to simplify subsequent computations of the Gaussian elimination process.

    Note that if `R` does not implement the method `"normal"`, but the elements of `R` are represented by kernel domains, i.e., `R` has the axiom `Ax::systemRep`, the system function `normal` is used instead.

#### Method identity: identity matrix

- `identity(positive integer n)`
- - This method returns the n x n identity matrix.
  - This method only exists if the component ring `R` is of category `Cat::Ring`, i.e., a ring with unit.

#### Method iszero: test for zero matrices

- `iszero(dom A)`
- - This method checks whether `A` is a zero matrix.
  - Note that there may exist more than one representation of the zero matrix of a given dimension if `R` does not have `Ax::canonicalRep`.
  - If `R` implements the method `"normal"`, it is used to simplify the components of `A` for the zero-test.

    Note that if `R` does not implement such a method, but the elements of `R` are represented by kernel domains, i.e., `R` has the axiom `Ax::systemRep`, the system function `normal` is used instead.

  - This method overloads the function `iszero` for matrices, i.e., one may use it in the form `iszero(A)`.

#### Method matdim: matrix dimension

- `matdim(dom A)`
- - This method returns the number of rows and columns of the matrix `A` as a list of two positive integers.

#### Method norm: norm of matrices and vectors

- `norm(dom A <, Infinity>)`
- - Computes the infinity norm of the matrix `A`, which is the maximum row sum (the row sum is the sum of norms of each component in a row).

    If the domain `R` does not implement the methods `"max"` and `"norm"`, `FAIL` is returned.

- `norm(dom v <, Infinity>)`
- - For a vector `v` the maximum norm of all elements is returned.

    If the domain `R` does not implement the methods `"max"` and `"norm"`, `FAIL` is returned.

- `norm(dom A, Frobenius)`
- - Computes the Frobenius norm of `A`, which is the square root of the sum of the squares of the norms of each component.

    If the result is no longer an element of the domain `R`, or if `R` does not implement the method `"norm"`, `FAIL` is returned.

- `norm(dom A, 1)`
- - Computes the 1-norm of the matrix `A`, which is the maximum sum of the norms of the elements of each column. If `R` does not implement the methods `"max"` and `"norm"`, `FAIL` is returned.
- `norm(dom v, positive integer k)`
- - Computes the k-norm of the vector `v`, which is defined to be the kth root of the sum of the norms of the elements of `v` raised to the kth power.

    `FAIL` is returned if the result is no longer an element of the domain `R`. For k=2, the function `linalg::scalarProduct` is used to compute the 2-norm of `v`.

    If `R` does not implement the method `"norm"`, `FAIL` is returned.

  - This method overloads the function `norm` for matrices, i.e., one may use it in the form `norm(A <, k>)`, where `k` is either Infinity, Frobenius, or a positive integer. The default value of `k` is Infinity.

#### Method normal: simplification of matrix components

- `normal(dom A)`
- - The method `"normal"` of `R` is applied to the components of `A`.
  - If `R` does not implement the method `"normal"`, but the elements of `R` are represented by kernel domains, i.e., `R` has the axiom `Ax::systemRep`, then the system function `normal` is applied to the components of `A`. Otherwise `normal(A)` returns `A` without any changes.
  - This method overloads the function `normal` for matrices, i.e., one may use it in the form `normal(A)`.

#### Method nonZeros: number of non-zero components of a matrix

- `nonZeros(dom A)`
- - This method returns the number of components of `A` for which the method `"iszero"` of the component ring `R` returns `FALSE`.

#### Method random: random matrix generation

- `random()`
- - This method returns a random matrix. It uses the method `"random"` of the component ring `R` to randomly generate the components of the matrix.
  - This method only exists if `R` implements the method `"random"`.
  - The dimension of the matrix is also chosen randomly, but it is limited by the values given in `"randomDimen"` (see ``Entries'' above).
  - To change the value of the entry `"randomDimen"` for a domain `MatR` created with `Dom::Matrix`, one must first unprotect the domain `Dom` (see `unprotect` for details).

#### Method tr: trace of a square matrix

- `tr(dom A)`
- - This method computes the trace of the square matrix `A`, which is defined to be the sum of its diagonal entries.
  - If `A` is not square, then an error message is issued.

#### Method transpose: transpose of a matrix

- `transpose(dom A)`
- - This method returns the transpose matrix A^T of `A`.

#### Method _concat: horizontal concatenation of matrices

- `_concat(dom A, dom B...)`
- - This method appends the matrices `B`... to the right side of the matrix `A`.
  - An error message is issued if the given matrices do not have the same number of rows.
  - This method overloads the function `_concat` for matrices, i.e., one may use it in the form `A . B . ...`, or in functional notation: `_concat(A, B, ...)`.

#### Method _index: matrix indexing

- `_index(dom A, row index i, column index j)`
- - This method returns the (i,j)th entry of the matrix `A`.
- `_index(dom A, row-range r1..r2, column-range c1..c2)`
- - This method returns the submatrix of `A` created by the rows of `A` with indices from `r1` to `r2` and the columns of `A` with indices from `c1` to `c2`.
- `_index(dom v, index i)`
- - This method returns the ith entry of the vector `v`.
  - An error message is issued if `v` is not a vector.
- `_index(dom v, index-range i1..i2)`
- - This method returns the subvector of `v`, formed by the entries with index `i1` to `i2`. See also the method `"op"`.
  - An error message is issued if `v` is not a vector.
  - This method overloads the function `_index` for matrices, i.e., one may use it in the form `A[i, j]`, `A[r1..r2, c1..c2]`, `v[i]` and `v[i1..i2]`, respectively, or in functional notation: `_index(A...)`.

#### Method concatMatrix: horizontal concatenation of matrices

- `concatMatrix(dom A, dom B...)`
- - This method is identical to the method `"_concat"`.

#### Method col: extracting a column

- `col(dom A, column index c)`
- - This method extracts the column with index `c` of the matrix `A` and returns it as a column vector, i.e., as an element of type `Dom::Matrix``(R)`.
  - An error message is issued if `c` is less than one or greater than the number of columns of `A`.

#### Method delCol: deleting a column

- `delCol(dom A, column index c)`
- - This method returns the matrix obtained by deleting the column with index `c` of the matrix `A`.
  - `NIL` is returned if `A` consists of only one column.
  - An error message is issued if `c` is less than one or greater than the number of columns of `A`.

#### Method delRow: deleting a row

- `delRow(dom A, row index r)`
- - This method returns the matrix obtained by deleting the row with index `r` of the matrix `A`.
  - `NIL` is returned if `A` consists of only one row.
  - An error message is issued if `r` is less than one or greater than the number of rows of `A`.

#### Method evalp: evaluating matrices of polynomials at a certain point

- `evalp(dom A, equation x = a...)`
- - This method evaluates the polynomial components of `A` at the point `x = a`. See the system function `evalp` for details.

    The matrix returned is of the domain `Dom::Matrix``(R::coeffRing)` if the evaluation of all components leads to an element of the coefficient ring of the polynomial domain. Otherwise the matrix returned is of the domain of `A`.

  - This method is only defined if `R` is a polynomial ring of category `Cat::Polynomial`.
  - This method overloads the function `evalp` for matrices, i.e., one may use it in the form `evalp(A, x = a)`.

#### Method length: length of a matrix

- `length(dom A)`
- - This method returns the length of the matrix `A`, which is the length of the array holding the components of `A`. See the system function `length` for details.
  - This method overloads the function `length` for matrices, i.e., one may use it in the form `length(A)`.

#### Method map: apply a function to matrix components

- `map(dom A, function func <, any expr...>)`
- - This method maps the function `func` to the components of the matrix `A`, with the additional function parameters `expr...` passed to `func`, if given.

    See the system function `map` for details.

  - Note that the function values are converted into elements of the domain `R` only if `testargs` returns `TRUE` (e.g., if one calls this method from the interactive level of MuPAD).

    If `testargs` returns `FALSE`, then one must guarantee that the function calls return elements of the domain type `R`, otherwise the resulting matrix, which is of domain type `Dom::Matrix``(R)`, would have components which are not elements of the domain `R`!

  - This method overloads the function `map` for matrices, i.e., one may use it in the form `map(A, func...)`.

#### Method nops: number of components of a matrix

- `nops(dom A)`
- - This method returns the number of components of a matrix, which is m*n for an m x n matrix `A`.
  - This method overloads the function `nops` for matrices, i.e., one may use it in the form `nops(A)`.

#### Method op: components of a matrix

- `op(dom A, positive integer i)`
- - This method returns the ith component of the matrix `A`, where the components are numbered starting at row one from left to right and up to down.
- `op(dom A)`
- - This method returns an expression sequence of all components of `A`.
  - See also the method `"_index"`.
  - This method overloads the function `op` for matrices, i.e., one may use it in the form `op(A, i)` and `op(A)`, respectively.

#### Method row: extracting a row

- `row(dom A, row index r)`
- - This method extracts the row with index `r` of the matrix `A` and returns it as a row vector, i.e., as an element of type `Dom::Matrix``(R)`.
  - An error message is issued if `r` is less than one or greater than the number of rows of `A`.

#### Method setCol: replacing a column

- `setCol(dom A, column index c, dom v)`
- - This method replaces the column with index `c` of the matrix `A` by the column vector `v`. The vector `v` must have nrows(A) elements.
  - An error message is issued if `c` is less than one or greater than the number of rows of `A`.

#### Method setRow: replacing a row

- `setRow(dom A, row index r, dom v)`
- - This method replaces the row with index `r` of the matrix `A` by the row vector `v`. The vector `v` must have ncols(A) elements.
  - An error message is issued if `r` is less than one or greater than the number of rows of `A`.

#### Method stackMatrix: vertical concatenation of matrices

- `stackMatrix(dom A, dom B...)`
- - This method stacks the matrix `A` on the top of the matrix `B`. If further arguments are given, then the result is stacked on the top of the third matrix, and so on.
  - An error message is issued if the given matrices do not have the same number of columns.

#### Method subs: substitution of matrix components

- `subs(dom A...)`
- - This method maps the function `subs` with additionally given parameters to the components of the matrix `A`. See the system function `subs` for details.

  - Note that the function values are converted into elements of the domain `R` only if `testargs` returns `TRUE` (e.g., if one calls this method from the interactive level of MuPAD).

    If `testargs` returns `FALSE`, then one must guarantee that the function calls return elements of the domain type `R`, otherwise the resulting matrix, which is of domain type `Dom::Matrix``(R)`, would have components which are not elements of the domain `R`!

  - This method overloads the function `subs` for matrices, i.e., one may use it in the form `subs(A...)`.

#### Method subsex: extended substitution of matrix components

- `subsex(dom A...)`
- - This method maps the function `subsex` with additionally given parameters to the components of the matrix `A`. See the system function `subsex` for details.

  - Note that the results of the substitutions are converted into elements of the domain `R` only if `testargs` returns `TRUE` (e.g., if one calls this method from the interactive level of MuPAD).

    If `testargs` returns `FALSE`, then one must guarantee that the results of the substitutions are of the domain type `R`, otherwise the resulting matrix, which is of domain type `Dom::Matrix``(R)`, would have components which are not elements of the domain `R`!

  - This method overloads the function `subsex` for matrices, i.e., one may use it in the form `subsex(A...)`.

#### Method subsop: operand substitution of matrix components

- `subsop(dom A, equation i = x...)`
- - This method replaces the ith component of the matrix `A` by `x`.

  - Note that `x` is converted into the domain `R` only if `testargs` returns `TRUE` (e.g., if one calls this method from the interactive level of MuPAD).

    If `testargs` returns `FALSE`, then `x` must be an element of `R`, otherwise the resulting matrix, which is of domain type `Dom::Matrix``(R)`, would have components which are not elements of the domain `R`!

  - See also the method `"set_index"`.
  - This method overloads the function `subsop` for matrices, i.e., one may use it in the form `subsop(A...)`.

#### Method swapCol: swapping matrix columns

- `swapCol(dom A, column indices c1, c2)`
- - This method returns the matrix which results from swapping the column with index `c1` with the column with index `c2` of the matrix `A`.
  - An error message is issued if one of the column indices is less than one or greater than the number of columns of `A`.
- `swapCol(dom A, column indices c1, c2, row range r1..r2)`
- - This method swaps the column with index `c1` and the column with index `c2` of `A`, but by taking only those column components which lie in the rows with indices `r1` to `r2`.
  - An error message is issued if one of the column indices is less than one or greater than the number of columns of `A`, or if one of the row indices is less than one or greater than the number of rows of `A`.

#### Method swapRow: swapping matrix rows

- `swapRow(dom A, row indices r1, r2)`
- - This method returns the matrix which results from swapping the row with index `r1` with row with index `r2` of the matrix `A`.
  - An error message is issued if one of the row indices is less than one or greater than the number of rows of `A`.
- `swapRow(dom A, row indices r1, r2, column range c1..c2)`
- - This method swaps the row with index `r1` and the row with index `r2` of `A`, but by taking only those row components which lie in the columns with indices `c1` to `c2`.
  - An error message is issued if one of the row indices is less than one or greater than the number of rows of `A`, or if one of the column indices is less than one or greater than the number of columns of `A`.

#### Method set_index: setting matrix components

- `set_index(dom A, row index i, column index j, any x)`
- - Replaces the (i,j)th component of the matrix `A` by `x`.

  - Note that `x` is converted into an element of the domain `R` only if `testargs` returns `TRUE` (e.g., if one calls this method from the interactive level of MuPAD).

    Otherwise one has to take care that `x` is of domain type `R`.

  - See also the method `"subsop"`.
- `set_index(dom v, index i, any x)`
- - Replaces the ith entry of the vector `v` by `x`.
  - This method overloads the function `set_index` for matrices, i.e., one may use it in the form `A[i, j] := x` and `v[i] := x`, respectively, or in functional notation: `A := set_index(A, i, j, x)` or `v := set_index(v, i, x)`.

#### Method zip: combine matrices component-wise

- `zip(dom A, B, function func <, any expr...>)`
- - This method combines the matrices `A` and `B` component-wise, where the function `func(a, b <, expr...>)` is applied to each pair (A[i, j], B[i, j]) (for all i and j).
  - The row number of the matrix returned is the minimum of the row numbers of `A` and `B`, and its column number is the minimum of the column numbers of `A` and `B`.

  - Note that the function values are converted into elements of the domain `R` only if `testargs` returns `TRUE` (e.g., if one calls this method from the interactive level of MuPAD).

    If `testargs` returns `FALSE`, then one must guarantee that the function calls return elements of the domain type `R`, otherwise the resulting matrix, which is of domain type `Dom::Matrix``(R)`, would have components which are not elements of the domain `R`!

  - This method overloads the function `zip` for matrices, i.e., one may use it in the form `zip(A, B...)`.

#### Method convert: conversion to a matrix

- `convert(any x)`
- - This method tries to convert `x` into a matrix of type `Dom::Matrix``(R)`.
  - `FAIL` is returned if the conversion fails.
  - `x` may either be an array, a matrix, or a list (of sublists, see the parameter `ListOfRows` in ``Creating Elements'' above). Their entries must then be convertible into elements of the domain `R`.

#### Method convert_to: matrix conversion

- `convert_to(dom A, any T)`
- - This method tries to convert the matrix `A` into an element of domain type `T`. `FAIL` is returned if the conversion fails.
  - `T` may either be `DOM_ARRAY`, `DOM_LIST`, or a domain constructed by `Dom::Matrix` or `Dom::SquareMatrix`. The elements of `A` must be convertible into elements of the domain `R`.
  - Use the function `expr` to convert `A` into an object of a kernel domain (see below).

#### Method create: defining matrices without component conversions

- `create(any x...)`
- - This method creates a new matrix assuming that the components are of domain type `R`.

    See ``Creating Elements'' above for a complete description of the parameters, with one exception: one cannot use this method to create a matrix from a function or a functional expression.

  - This method works more efficient than if one creates matrices by calling the method `"new"` of the domain, because it avoids any conversion of the components. One must guarantee that the components have the correct domain type, otherwise run-time errors can be caused.

#### Method expr: matrix conversion into an object of a kernel domain

- `expr(dom A)`
- - This method converts `A` into an array, i.e., an object of type `DOM_ARRAY`, and applies the function `expr` to each component of `A`.
  - The result is an array representing the matrix `A` where each entry is an object of a kernel domain.
  - This method overloads the function `expr` for matrices, i.e., one may use it in the form `expr(A)`.

#### Method expr2text: matrix conversion to a string

- `expr2text(dom A)`
- - This method converts `A` into a string `s` such that the evaluation of the function call `text2expr(s)` gives the matrix `A`.
  - This method overloads the function `expr2text` for matrices, i.e., one may use it in the form `expr2text(A)`.

#### Method TeX: TeX formatting of a matrix

- `TeX(dom A)`
- - This method returns a TeX-formatted string for the matrix `A` in form of a TeX `array` environment.
  - The method `"TeX"` of the component ring `R` is used to get the TeX-representation of each component of `A`.
  - This method is used by the function `generate::TeX`.

#### Method assignElements: multiple assignment to matrices

- `assignElements(dom A...)`
- - This method performs multiple assignments to components of the matrix `A`.

    See the system function `assignElements` for details.

  - The assigned components must have the domain type `R`, an implicit conversion of the components into elements of domain type `R` is not performed.
  - This method overloads the function `assignElements` for matrices, i.e., one may use it in the form `assignElements(A...)`.

#### Method mkDense: conversion of a matrix to an array

- `mkDense(array Array)`
- - This method converts each operand of `Array` into an element of the component ring `R`. The result is either `FAIL` if one of these conversions is not possible, or the list `[r, c, Array]`, where the positive integers `r` and `c` give the dimension of `Array`.

- `mkDense(list List)`
- - This method tries to convert the list `List` into an array `a`. The result is either `FAIL` if this is not possible, or the list `[r, c, a]`, where the positive integers `r` and `c` give the dimension of `a`. See the parameters `List` and `ListOfRows` in ``Creating Elements'' above for admissible formats of `List`.

    The array `a` has dimension one if `r` or `c` is equal to one. The entries of `a` have been converted into elements of the domain `R`.

- `mkDense(positive integers r, c, list List)`
- - This method tries to convert the list `List` into an array `a` of the dimension `r` times `c`.

    The result is either `FAIL` if this is not possible, or the list `[r, c, a]`.

    The array `a` has dimension one if `r` or `c` is equal to one. The entries of `a` have been converted into elements of the domain `R`.

#### Method print: printing matrices

- `print(dom A)`
- - This method returns the array holding the components of `A`. Thus, matrices are printed like arrays.

#### Method unapply: create a procedure from a matrix

- `unapply(dom A <, identifier x...>)`
- - This method interprets the components of `A` as functions in `x`..., and returns a procedure representing this matrix function. See `fp::unapply` for details.
  - This method overloads the function `fp::unapply` for matrices, i.e., one may use it in the form `fp::unapply(A)`.

#### Example 1

First we create the domain of matrices over the field of rational numbers:

    >> MatQ := Dom::Matrix(Dom::Rational)

                            Dom::Matrix(Dom::Rational)

We assigned this domain to the identifier `MatQ`. Next we define the 2 x 2 matrix

    +-    -+
    | 1  5 |
    |      |
    | 2  0 |
    +-    -+

by a list of two rows, where each row is a list of two elements:

    >> A := MatQ([[1, 5], [2, 3]])

                                    +-      -+
                                    |  1, 5  |
                                    |        |
                                    |  2, 3  |
                                    +-      -+

In the same way we define the following 2 x 3 matrix:

    >> B := MatQ([[-1, 5/2, 3], [1/3, 0, 2/5]])

                                +-               -+
                                |   -1, 5/2,  3   |
                                |                 |
                                |  1/3,  0,  2/5  |
                                +-               -+

and perform matrix arithmetic using the standard arithmetical operators of MuPAD, e.g., the matrix product A * B, the 4th power of A as well as the scalar multiplication of A times 1/3:

    >> A * B, A ^ 4, 1/3 * A

               +-                -+  +-          -+  +-          -+
               |  2/3, 5/2,   5   |  |  281, 600  |  |  1/3, 5/3  |
               |                  |, |            |, |            |
               |   -1,  5,  36/5  |  |  240, 521  |  |  2/3,  1   |
               +-                -+  +-          -+  +-          -+

The matrices A and B have different dimensions, and therefore the sum of A and B is not defined. MuPAD issues an error message:

    >> A + B

          Error: dimensions don't match [(Dom::Matrix(Dom::Rational))\
          ::_plus]

To compute the inverse of A, just enter:

    >> 1/A

                                 +-            -+
                                 |  -3/7,  5/7  |
                                 |              |
                                 |   2/7, -1/7  |
                                 +-            -+

If a matrix is not invertible, `FAIL` is the result of this operation. For example, the matrix:

    >> C := matrix(2, 2, [[2]])

                                    +-      -+
                                    |  2, 0  |
                                    |        |
                                    |  0, 0  |
                                    +-      -+

is not invertible, hence:

    >> C^(-1)

                                       FAIL

#### Example 2

We create the domain of matrices over the reals:

    >> MatR := Dom::Matrix(Dom::Real)

                              Dom::Matrix(Dom::Real)

Beside standard matrix arithmetic, the library `linalg` offers a lot of functions dealing with matrices. For example, if one wants to compute the rank of a matrix, use `linalg::rank`:

    >> A := MatR([[1, 2], [2, 4]])

                                    +-      -+
                                    |  1, 2  |
                                    |        |
                                    |  2, 4  |
                                    +-      -+

    >> linalg::rank(A)

                                         1

Use `linalg::eigenvectors` to compute eigenvalues and eigenvectors of the matrix A:

    >> linalg::eigenvectors(A)

           -- --       -- +-    -+ -- --  --       -- +-     -+ -- -- --
           |  |        |  |  -2  |  |  |  |        |  |  1/2  |  |  |  |
           |  |  0, 1, |  |      |  |  |, |  5, 1, |  |       |  |  |  |
           |  |        |  |   1  |  |  |  |        |  |   1   |  |  |  |
           -- --       -- +-    -+ -- --  --       -- +-     -+ -- -- --

Try `info(linalg)` for a list of available functions, or enter `help(linalg)` for details about the library `linalg`.

Some of the functions in the `linalg` package simply serve as ``interface'' functions for methods of a matrix domain described above. For example, `linalg::transpose` uses the method `"transpose"` to get the transposed matrix. The function `linalg::gaussElim` applies Gaussian elimination to a matrix, such as:

    >> linalg::gaussElim(A)

                                    +-      -+
                                    |  1, 2  |
                                    |        |
                                    |  0, 0  |
                                    +-      -+

The computation is performed by the method `"gaussElim"` as described above. Such functions of the `linalg` packages, in contrast to the corresponding methods of the domain `Dom::Matrix``(R)`, check their incoming parameters, and some of them offer extended functionalities.

#### Example 3

In this example, we use the default matrix domain which is created by `Dom::Matrix()`. This domain represents matrices whose components can be arbitrary arithmetical expressions (i.e., the component ring is the domain `Dom::ExpressionField()`).

This domain is already known to MuPAD by the name `matrix`:

    >> A := matrix(
         [[1, 2, 3, 4], [2, 0, 4, 1], [-1, 0, 5, 2]]
       )

                                 +-             -+
                                 |   1, 2, 3, 4  |
                                 |               |
                                 |   2, 0, 4, 1  |
                                 |               |
                                 |  -1, 0, 5, 2  |
                                 +-             -+

    >> domtype(A)

                                   Dom::Matrix()

Matrix components can be extracted by the index operator `[]`:

    >> A[2, 1] * A[1, 2] - A[3, 1] * A[1, 3]

                                         7

If one of the indices is not in its valid range, an error message is issued. Assignments to matrix components are performed similarly:

    >> delete a:
       A[1, 2] := a^2: A

                                +-              -+
                                |       2        |
                                |   1, a , 3, 4  |
                                |                |
                                |   2,  0, 4, 1  |
                                |                |
                                |  -1,  0, 5, 2  |
                                +-              -+

Beside the usual indexing of matrix components, it is also possible to extract submatrices from a given matrix. The following call creates the submatrix of A which consists of the rows 2 to 3 and columns 1 to 3 of A:

    >> A[2..3, 1..3]

                                  +-          -+
                                  |   2, 0, 4  |
                                  |            |
                                  |  -1, 0, 5  |
                                  +-          -+

The index operator does not allow to insert submatrices into a given matrix. This is implemented by the function `linalg::substitute`.

#### Example 4

In the following examples, we demonstrate the different ways of creating matrices. We work with matrices defined over the field Z19, i.e., the field of integers modulo 19. This component ring can be created with the domain constructor `Dom::IntegerMod`.

We start by giving a list of rows, where each row is a list of row entries:

    >> MatZ19 := Dom::Matrix(Dom::IntegerMod(19)):
       MatZ19([[1, 2], [2]])

                             +-                    -+
                             |  1 mod 19, 2 mod 19  |
                             |                      |
                             |  2 mod 19, 0 mod 19  |
                             +-                    -+

The elements of the two inner lists, the row entries, were converted into elements of the domain `Dom::IntegerMod(19)`.

The number of rows is the number of sublists of the argument, i.e., m = 2. The number of columns is determined by the length of the inner list with the most entries, which is the first inner list with two entries. Missing entries in the other inner lists are treated as zero components. The call:

    >> MatZ19(4, 4, [[1, 2], [2]])

                   +-                                        -+
                   |  1 mod 19, 2 mod 19, 0 mod 19, 0 mod 19  |
                   |                                          |
                   |  2 mod 19, 0 mod 19, 0 mod 19, 0 mod 19  |
                   |                                          |
                   |  0 mod 19, 0 mod 19, 0 mod 19, 0 mod 19  |
                   |                                          |
                   |  0 mod 19, 0 mod 19, 0 mod 19, 0 mod 19  |
                   +-                                        -+

fixes the dimension of the matrix. Missing entries and inner lists are treated as zero components and zero rows, respectively.

An error message is issued if one of the given entries cannot be converted into an element over Z19:

    >> MatZ19([[2, 3], [-1, I]])

          Error: unable to define matrix over Dom::IntegerMod(19) \
          [(Dom::Matrix(Dom::IntegerMod(19)))::new]

#### Example 5

This example illustrates how to create a matrix with components given as values of an index function. First we create the 2 x 2 Hilbert matrix (see also the functions `linalg::hilbert` and `linalg::invhilbert`):

    >> matrix(2, 2, (i, j) -> 1/(i + j - 1))

                                  +-          -+
                                  |   1,  1/2  |
                                  |            |
                                  |  1/2, 1/3  |
                                  +-          -+

Note the difference when working with expressions and functions. If you give an expression it is treated as a function in the row and column indices:

    >> delete x:
       matrix(2, 2, x), matrix(2, 2, (i, j) -> x)

                        +-                  -+  +-      -+
                        |  x(1, 1), x(1, 2)  |  |  x, x  |
                        |                    |, |        |
                        |  x(2, 1), x(2, 2)  |  |  x, x  |
                        +-                  -+  +-      -+

#### Example 6

Diagonal matrices can be created with the option Diagonal and a list of diagonal components:

    >> MatC := Dom::Matrix(Dom::Complex):
       MatC(3, 4, [1, 2, 3], Diagonal)

                                 +-            -+
                                 |  1, 0, 0, 0  |
                                 |              |
                                 |  0, 2, 0, 0  |
                                 |              |
                                 |  0, 0, 3, 0  |
                                 +-            -+

Hence, to define the n x n identity matrix, you can enter:

    >> MatC(3, 3, [1 $ 3], Diagonal)

                                   +-         -+
                                   |  1, 0, 0  |
                                   |           |
                                   |  0, 1, 0  |
                                   |           |
                                   |  0, 0, 1  |
                                   +-         -+

or even call:

    >> MatC(3, 3, x -> 1, Diagonal)

                                   +-         -+
                                   |  1, 0, 0  |
                                   |           |
                                   |  0, 1, 0  |
                                   |           |
                                   |  0, 0, 1  |
                                   +-         -+

The easiest way to create the identity matrix, however, is to use the method `"identity"`:

    >> MatC::identity(3)

                                   +-         -+
                                   |  1, 0, 0  |
                                   |           |
                                   |  0, 1, 0  |
                                   |           |
                                   |  0, 0, 1  |
                                   +-         -+

#### Example 7

Toeplitz matrices can be defined with the option Banded. The following call defines a three-banded matrix with the component 2 on the main diagonal and the component -1 on the first subdiagonals:

    >> matrix(4, 4, [-1, 2, -1], Banded)

                               +-                -+
                               |   2, -1,  0,  0  |
                               |                  |
                               |  -1,  2, -1,  0  |
                               |                  |
                               |   0, -1,  2, -1  |
                               |                  |
                               |   0,  0, -1,  2  |
                               +-                -+

#### Example 8

Some system functions can be applied to matrices, such as `norm`, `expand`, `diff`, `conjugate`, or `exp`.

For example, to expand the components of the matrix:

    >> delete a, b:
       A := matrix(
         [[(a - b)^2, a^2 + b^2], [a^2 + b^2, (a - b)*(a + b)]]
       )

                          +-                           -+
                          |         2       2    2      |
                          |  (a - b) ,     a  + b       |
                          |                             |
                          |    2    2                   |
                          |   a  + b , (a + b) (a - b)  |
                          +-                           -+

enter:

    >> expand(A)

                         +-                            -+
                         |             2    2   2    2  |
                         |  - 2 a b + a  + b , a  + b   |
                         |                              |
                         |        2    2        2    2  |
                         |       a  + b ,      a  - b   |
                         +-                            -+

If you want to differentiate the matrix components, then call for example:

    >> diff(A, a)

                               +-                -+
                               |  2 a - 2 b, 2 a  |
                               |                  |
                               |     2 a,    2 a  |
                               +-                -+

To substitute matrix components by some values, enter:

    >> subs(A, a = 1, b = -1)

                                    +-      -+
                                    |  4, 2  |
                                    |        |
                                    |  2, 0  |
                                    +-      -+

The function `zip` can also be applied to matrices. The following call combines two matrices A and B by dividing each component of A by the corresponding component of B:

    >> A := matrix([[4, 2], [9, 3]]):
       B := matrix([[2, 1], [3,-1]]):
       zip(A, B, `/`)

                                    +-       -+
                                    |  2,  2  |
                                    |         |
                                    |  3, -3  |
                                    +-       -+

The quoted character ``/`` is another notation for the function `_divide`, the functional form of the division operator `/`.

If one needs to apply a function to the components of a matrix, then use the function `map`. For example, to simplify the components of the matrix:

    >> C := matrix(
         [[sin(x)^2 + cos(x)^2, exp(x) - exp(x/2)^2],
         [(a^2 - b^2)/(a + b), 1]]
       )

                    +-                                       -+
                    |        2         2              / x \2  |
                    |  cos(x)  + sin(x) , exp(x) - exp| - |   |
                    |                                 \ 2 /   |
                    |                                         |
                    |        2    2                           |
                    |       a  - b                            |
                    |       -------,               1          |
                    |        a + b                            |
                    +-                                       -+

call:

    >> map(C, simplify)

                                  +-          -+
                                  |    1,   0  |
                                  |            |
                                  |  a - b, 1  |
                                  +-          -+

#### Example 9

A column vector is represented as a 2 x 1 matrix:

    >> MatR := Dom::Matrix(Dom::Real):
       v := MatR(2, 1, [1, 2])

                                      +-   -+
                                      |  1  |
                                      |     |
                                      |  2  |
                                      +-   -+

The dimension of this vector is:

    >> MatR::matdim(v)

                                      [2, 1]

Use `linalg::vecdim`, or even call `nops(v)` to get the length of a vector:

    >> linalg::vecdim(v)

                                         2

The ith component of this vector can be extracted in two ways: either by `v[i,1]` or by `v[i]`:

    >> v[1], v[2]

                                       1, 2

We get the 2-norm of `v` by the following call:

    >> norm(v, 2)

                                        1/2
                                       5

#### Super-Domain

`Dom::BaseDomain`

#### Axioms

if `R` has `Ax::canonicalRep`
`Ax::canonicalRep`

#### Changes

- The method `"dimen"` was renamed to `"matdim"`.
- The method `"newThis"` was renamed to `"create"`.
- `"_invert"` now uses the function `numeric::inverse` for certain component rings `R`.
- New method `"diff"` which applies the function `diff` to the components of a matrix.
- New method `"evalp"` for matrices over polynomial rings.
- `exp` now uses the function `numeric::expMatrix` for a floating-point approximation of the exponential of a matrix, i.e., if the component ring `R` is the domain `Dom::Float`.
- New method `"expand"` which applies the function `expand` to the components of a matrix.
- New method `"factor"` for rewriting the matrix A in the form A = s B with a scalar s.
- New method `"float"` for computing a floating-point approximation of matrix components.
- New method `"identity"` to ease the construction of identity matrices.
- New method `"normal"` for simplification of matrix components.
- New method `"unapply"` for overloading the function `fp::unapply`.

Do you have questions or comments?
Copyright © SciFace Software GmbH & Co. KG 2000