Fork me on GitHub

src/arraymancer/linear_algebra/special_matrices

Search:
Group by:
  Source Edit

Types

MeshGridIndexing = enum
  xygrid, ijgrid
  Source Edit

Procs

proc circulant[T](t: Tensor[T]; axis = -1; step = 1): Tensor[T] {.noInit.}

Construct a circulant matrix from a rank-1 tensor

A circulant matrix is a square matrix in which each column (or row) is a cyclic shift of the previous column (or row).

By default this function cirulates over the columns of the output which are rotated down by 1 element over the previous column, but this behavior can be changed by using the axis and step arguments.

Inputs:

  • A rank-1 Tensor
  • axis: The axis along which the circulant matrix will be constructed. Defaults to -1 (i.e. the columns, which are the last axis).
  • step: The number of elements by which the input tensor will be shifted each time. Defaults to 1.

Result:

  • The constructed circulant matrix

Example:

echo circulant([1, 3, 6])
Tensor[system.int] of shape "[3, 3]" on backend "Cpu"
# |1      6     3|
# |3      1     6|
# |6      3     1|

  Source Edit
proc diag[T](d: Tensor[T]; k = 0; anti = false): Tensor[T] {.noInit.}

Creates a new square diagonal matrix from an rank-1 input tensor

Input:

- Rank-1 tensor containing the elements of the diagonal
- k: The index of the diagonal that will be set. The default is 0.
  Use k>0 for diagonals above the main diagonal, and k<0 for diagonals below the main diagonal.
- anti: If true, set the k-th "anti-diagonal" instead of the k-th regular diagonal.

Result:

- The constructed, square diagonal matrix
  Source Edit
proc diagonal[T](a: Tensor[T]; k = 0; anti = false): Tensor[T] {.noInit.}

Gets the k-th diagonal (or anti-diagonal) of a matrix

Input:

- A matrix (which can be rectangular)
- k: The index k of the diagonal that will be extracted. The default is 0 (i.e. the main diagonal).
  Use k>0 for diagonals above the main diagonal, and k<0 for diagonals below the main diagonal.
- anti: If true, get the k-th "anti-diagonal" instead of the k-th regular diagonal.

Result:

- A copy of the diagonal elements as a rank-1 tensor
  Source Edit
proc eye[T](shape: varargs[int]): Tensor[T] {.noInit.}

Return a 2-D tensor with ones on the diagonal and zeros elsewhere

Input:

- The shape of the output matrix

Result:

- The constructed, rank-2 diagonal tensor
  Source Edit
proc hankel[T](c, r: Tensor[T]): Tensor[T] {.noInit.}

Construct a Hankel matrix.

A Hankel matrix has constant anti-diagonals, with c as its first column and r as its last row (note that r[0] is ignored but _should be the same as c[^1]). This is similar to a Toeplitz matrix, which has constant diagonals instead.

Inputs:

  • c: The first column of the Hankel matrix
  • r: The last row of the Hankel matrix (note that r[0] is ignored)

Result:

  • The constructed Hankel matrix

Notes:

  • There is a version of this procedure that takes a single argument c, in which case r is set to all zeroes, resulting in a "triangular" Hankel matrix.
  • Use the toeplitz procedure to generate a Toeplitz matrix instead.

Example:

echo hankel([1, 3, 6], [9, 10, 11, 12])
# Tensor[system.int] of shape "[3, 4]" on backend "Cpu"
# |1      3     6    10|
# |3      6    10    11|
# |6     10    11    12|

  Source Edit
proc hankel[T](c: Tensor[T]): Tensor[T] {.noInit, inline.}

Construct a "triangular" Hankel matrix (i.e. with zeros on its last row)

The "triangular" Hankel matrix is a Hankel matrix in which all the items below the main anti-diagonal are set to 0. This is equivalent to creating a regular Hankel metrix in which the c argument is set to all zeros.

Inputs:

  • c: The first column of the Hankel matrix

Result:

  • The constructed "triangular" Hankel matrix

Notes:

  • There is a version of this procedure that takes two arguments (c and r),
  • While there is also a single input toeplitz procedure, its behavior is quite different, since it sets r to the complex conjugate of c.

Example:

echo hankel([1, 3, 6], [9, 10, 11, 12])
# Tensor[system.int] of shape "[3, 3]" on backend "Cpu"
# |1      3     6|
# |3      6     0|
# |6      0     0|

  Source Edit
proc hilbert(n: int; T: typedesc[SomeFloat]): Tensor[T]
Generates an Hilbert matrix of shape N, N   Source Edit
proc identity[T](n: int): Tensor[T] {.noInit.}

Return an identity matrix (i.e. 2-D tensor) of size n

The identity matrix is a square 2-D tensor with ones on the main diagonal and zeros elsewhere. This is basically the same as calling eye(n, n).

Input:

- Number of rows / columns in the output.

Result:

- The constructed indentity 2-D tensor
  Source Edit
proc int2bit(value: int; n: int; msbfirst = true): Tensor[bool] {....raises: [],
    tags: [], forbids: [].}

Convert an integer into a "bit" tensor of size n

A "binary" tensor is a tensor containing the bits that represent the input integer.

Inputs:

  • value: The input integer
  • n: The size of the output tensor. No check is done to ensure that n is large enough to represent value.
  • msbfirst: If true (the default), the first element will be the most significant bit (i.e. the msb will be first). Otherwise the least significant bit will be first.

Result:

  • The constructed "bit" tensor

Notes: This is similar to Matlab's int2bit (except that Matlab's version fills the bit tensors column-wise, while this fills them row-wise). It is also similar to (but more flexible than) numpy's unpackbits. Examples: .. code:: nim echo int2bit(12, 5) # Tensorsystem.bool of shape "5" on backend "Cpu" # false true true false false echo int2bit(12, 5, msbfirst = false) # Tensorsystem.bool of shape "5" on backend "Cpu" # false false true true false

  Source Edit
proc int2bit[T: SomeInteger](t: Tensor[T]; n: int; msbfirst = true): Tensor[bool] {.
    noinit.}

Convert an integer tensor of rank-X into a "bit" tensor of rank X+1

The "bit" tensor corresponding to an integer tensor is a tensor in which each integer element is replaced with its binary representation (of size n). This requires increasing the rank of the output tensor by 1, making the size of its last axis equal to n.

Inputs:

  • value: The input tensor (of rank X)
  • n: The size of the output tensor. No check is done to ensure that n is large enough to represent value.
  • msbfirst: If true (the default), elements of the input tensor will be converted to bits by placing the most significant bit first. Otherwise the least significant bit will be first.

Result:

  • The constructed "bit" tensor (of rank X+1 and shape t.shape + n)

Notes: This is similar to Matlab's int2bit (except that Matlab's version fills the bit tensors column-wise, while this fills them row-wise). It is also similar to (but more flexible than) numpy's unpackbits. Examples: .. code:: nim echo int2bit(12, 6, 5) # Tensorsystem.bool of shape "2, 5" on backend "Cpu" # |false true true false false| # |false false true true false| echo int2bit(12, 6, msbfirst = false) # Tensorsystem.bool of shape "2, 5" on backend "Cpu" # |false false true true false| # |false true true false false|

  Source Edit
proc meshgrid[T](t_list: varargs[Tensor[T]]; indexing = MeshGridIndexing.xygrid): seq[
    Tensor[T]] {.noinit.}

Return a sequence of coordinate matrices from coordinate vectors.

Make N-D coordinate tensors for vectorized evaluations of N-D scalar/vector fields over N-D grids, given one-dimensional coordinate tensors x1, x2,..., xn.

Inputs:

  • xi: The coordinate tensors. Each vector must be a rank-1 tensor.
  • indexing: Cartesian (xygrid, default) or matrix (ijgrid) indexing of the output. The indexing mode only affects the first 2 output Tensors. In the 2-D case with inputs of length M and N, the outputs are of shape (N, M) for xygrid indexing and (M, N) for ijgrid indexing. In the 3-D case with inputs of length M, N and P, outputs are of shape (N, M, P) for xygrid indexing and (M, N, P) for ijgrid indexing.

Result:

  • List of N meshgrid N-dimensional Tensors For tensors x1, x2,..., xn with lengths Ni=len(xi), returns (N1, N2, N3,..., Nn) shaped tensors if indexing=ijgrid or (N2, N1, N3,..., Nn) shaped tensors if indexing=xygrid with the elements of xi repeated to fill the matrix along the first dimension for x1, the second for x2 and so on.

Notes:

  • This function follows and implements the numpy.meshgrid API.
  Source Edit
proc set_diagonal[T](a: var Tensor[T]; d: Tensor[T]; k = 0; anti = false)

Sets a diagonal of a matrix (in place)

Input:

- The matrix that will be changed in place.
- Rank-1 tensor containg the elements that will be copied into the selected diagonal.
- k: The index k of the diagonal that will be changed. The default is 0 (i.e. the main diagonal).
  Use k>0 for diagonals above the main diagonal, and k<0 for diagonals below the main diagonal.
- anti: If true, set the k-th "anti-diagonal" instead of the k-th regular diagonal.
  Source Edit
proc toeplitz[T](c, r: Tensor[T]): Tensor[T] {.noInit.}

Construct a Toeplitz matrix

A Toeplitz matrix has constant diagonals, with c as its first column and r as its last row (note that r[0] is ignored but _should be the same as c[^1]). This is similar to (but different than) a Hankel matrix, which has constant anti-diagonals instead.

Inputs:

  • c: The first column of the Toeplitz matrix
  • r: The last row of the Toeplitz matrix (note that r[0] is ignored)

Result:

  • The constructed Toeplitz matrix

Notes:

  • There is a version of this procedure that takes a single argument c, in which case r is set to c.conjugate.
  • Use the hankel procedure to generate a Hankel matrix instead.

Example:

echo toeplitz([1, 3, 6], [9, 10, 11, 12])
# Tensor[system.int] of shape "[3, 4]" on backend "Cpu"
# |1     10    11    12|
# |3      1    10    11|
# |6      3     1    10|

  Source Edit
proc toeplitz[T](c: Tensor[T]): Tensor[T] {.noInit, inline.}

Construct a square Toeplitz matrix from a single tensor

A Toeplitz matrix has constant diagonals. This version of this procedure gets a single tensor as its input. The input tensor is used as-is to set the first column of the Toeplitz matrix, and is conjugated to set the first row of the Toeplitz matrix.

Inputs:

  • c: The first column of the Toeplitz matrix. It is also the complex conjugate of the first row of the Toeplitz matrix.

Result:

  • The constructed square Toeplitz matrix

Notes:

  • There is a version of this procedure that takes two arguments (c and r),
  • While there is also a single input hankel procedure, its behavior is quite different, since it sets r to an all zeros tensor instead.

Examples:

echo toeplitz([1, 3, 6])
# Tensor[system.int] of shape "[3, 3]" on backend "Cpu"
# |1      3     6|
# |3      1     3|
# |6      3     1|

echo toeplitz([1.0+2.0.im, 3.0+4.0.im, 6.0+7.0.im].toTensor)
# Tensor[complex.Complex64] of shape "[3, 3]" on backend "Cpu"
# |(1.0, 2.0)     (3.0, -4.0)    (6.0, -7.0)|
# |(3.0, 4.0)      (1.0, 2.0)    (3.0, -4.0)|
# |(6.0, 7.0)      (3.0, 4.0)     (1.0, 2.0)|

  Source Edit
proc tri[T](shape: Metadata; k: static int = 0; upper: static bool = false): Tensor[
    T] {.noInit.}

Return a 2-D tensor with ones at and below the given diagonal and zeros elsewhere

Inputs:

- The (rank-2) shape of the output matrix.
- k: The sub-diagonal at and below which the tensor will be filled with ones.
     The default is 0.
- upper: If true, the tensor will be filled with ones at and above the given
         diagonal. The default is false.

Result:

- The constructed, rank-2 triangular tensor.
  Source Edit
proc tri[T](shape_ax1, shape_ax0: int; k: static int = 0;
            upper: static bool = false): Tensor[T] {.noInit, inline.}

Return a 2-D tensor with ones at and below the given diagonal and zeros elsewhere

Inputs:

- The shape of the output matrix.
- k: The sub-diagonal at and below which the tensor will be filled with ones.
     The default is 0.
- upper: If true, the tensor will be filled with ones at and above the given
         diagonal. The default is false.

Result:

- The constructed, rank-2 triangular tensor
  Source Edit
proc vander(order: int = -1; increasing = false): Tensor[float] {.inline,
    ...raises: [ValueError], tags: [], forbids: [].}

Same as the square vandermonde but with increasing set to false by default

This procedure is meant for compatibility with numpy, whose vander() function defaults to increasing = false (as opposed to Arraymancer's vandermonde, which defaults to increasing = true).

See also: vandermonde

  Source Edit
proc vander[T](x: Tensor[T]; order: int = -1; increasing = false): Tensor[float] {.
    inline.}

Same as vandermonde but with increasing set to false by default

This procedure is meant for compatibility with numpy, whose vander() function defaults to increasing = false (as opposed to Arraymancer's vandermonde, which defaults to increasing = true).

See also: vandermonde

  Source Edit
proc vandermonde(order: int; increasing = true): Tensor[float] {.inline,
    ...raises: [ValueError], tags: [], forbids: [].}

Returns a "square" Vandermonde matrix of the given order

A square Vandermonde matrix is a Vandermonde matrix of the given order whose input tensor is arange(order).

V_ij = x_i ^ order_j

where order_j runs from 0 to order-1 or from order-1 down to 0.

Inputs:

  • order: the order of the Vandermonde matrix.
  • increasing: If true, the powers of x_i will run from 0 to order-1, otherwise they will run from order-1 down to 0.

Result:

  • The constructed Vandermonde matrix
  Source Edit
proc vandermonde[T](x: Tensor[T]; order: int = -1; increasing = true): Tensor[
    float]

Returns a Vandermonde matrix of the input x up to the given order

A Vandermonde matrix consists of the input x split into multiple rows where each row contains all powers of x_i from 0 to order-1 (by default) or from order-1 down to 0 (if increasing is set to false).

V_ij = x_i ^ order_j

where order_j runs from 0 to order-1 or from order-1 down to 0.

Inputs:

  • x: The input tensor x (which must be a rank-1 tensor)
  • order: the order of the Vandermonde matrix. If not provided, (or non positive) the order is set to the size of x.
  • increasing: If true, the powers of x_i will run from 0 to order-1, otherwise they will run from order-1 down to 0.

Result:

  • The constructed Vandermonde matrix
  Source Edit
proc vandermonde[T](x: Tensor[T]; orders: Tensor[SomeNumber]): Tensor[float]

Returns a "Generalized" Vandermonde matrix of the input x over the given orders

A "generalized" Vandermonde matrix consists of the input x split into multiple rows where each row contains the powers of x_i elevated to each of the elements of the orders tensor.

V_ij = x_i ^ order_j

Inputs:

  • x: The input tensor x (which must be a rank-1 tensor)
  • orders: The "exponents" tensor (which must also be a rank-1 tensor)

Result:

  • The constructed Vandermonde matrix
  Source Edit
proc with_diagonal[T](a: Tensor[T]; d: Tensor[T]; k = 0; anti = false): Tensor[T] {.
    noInit.}

Copy the input matrix, changing one of its diagonals into the elements of the rank-1 input tensor d

Input:

- The matrix that will copied into the output.
- Rank-1 tensor containg the elements that will be copied into the selected diagonal.
- k: The index k of the diagonal that will be changed. The default is 0 (i.e. the main diagonal).
  Use k>0 for diagonals above the main diagonal, and k<0 for diagonals below the main diagonal.
- anti: If true, set the k-th "anti-diagonal" instead of the k-th regular diagonal.
  Source Edit
Arraymancer Technical reference Tutorial Spellbook (How-To's) Under the hood