vectrix 0.4.0

A stack-allocated matrix type implemented with const generics
Documentation
<!-- Generated by cargo-onedoc v0.2.2. DO NOT EDIT. -->

# vectrix

[![Crates.io Version](https://badgers.space/crates/version/vectrix)](https://crates.io/crates/vectrix)
[![Docs.rs Latest](https://badgers.space/badge/docs.rs/latest/blue)](https://docs.rs/vectrix)
[![Build Status](https://badgers.space/github/checks/rossmacarthur/vectrix?label=build)](https://github.com/rossmacarthur/vectrix/actions/workflows/build.yaml)

This crate provides a stack-allocated, constant-size [`Matrix<T, M, N>`][Matrix]
type implemented using const generics.

## 🚀 Getting started

Add this crate to your Cargo manifest.

```sh
cargo add vectrix
```

`no_std` is also supported by disabling the default std feature.

```sh
cargo add vectrix --no-default-features --features=macro
```

## 🤸 Usage

### Types

The base [`Matrix<T, M, N>`][Matrix] type represents a matrix with `M` rows and `N`
columns. This type is a backed by an array of arrays. The data is stored in
column-major order. Some convenient aliases are provided for common
matrices, like vectors.

- [`Matrix<T, M, N>`][Matrix] → a generic matrix type with `M` rows and `N` columns.
- [`Vector<T, M>`][Vector] → a column vector with `M` rows.
- [`RowVector<T, N>`][RowVector] → a row vector with `N` columns.

### Macros

Macros are provided for easy construction of the provided types. These
macros will also work in `const` contexts.

- The [`matrix!`][matrix] macro can be used to construct a new [`Matrix`][Matrix] of any
  size.
  
  ```rust
  let m = matrix![
      1, 3, 5;
      2, 4, 6;
  ];
  ```
  
  In the above example `matrix` is a `Matrix<_, 2, 3>` type, having 2 rows and
  3 columns.

- The [`vector!`][vector] and [`row_vector!`][row_vector] macros can be used to to construct
  column and row vectors respectively.
  
  ```rust
  let v = vector![1, 3, 3, 7];
  //  ^ type `Vector<_, 4>`
  assert_eq!(v, matrix![1; 3; 3; 7]);
  
  let v = row_vector![1, 3, 3, 7];
  //  ^^^^^^ type `RowVector<_, 4>`
  assert_eq!(v, matrix![1, 3, 3, 7]);
  ```

### Constructors

Commonly used constructors are listed below.

- [`::zero()`][::zero] → constructs a new matrix filled with
  [`T::zero()`][T::zero].
- [`::identity()`][::identity] → constructs a new identity matrix.
- [`::repeat(..)`][::repeat] → constructs a new matrix filled with
  the provided value.
- [`::repeat_with(..)`][::repeat_with] → constructs a new matrix
  filled with values computed by the provided closure.
- [`::from_iter(..)`][::from_iter] → constructs a
  new matrix from an iterator.
- [`::new(..)`][::new] → constructs a new vector using the
  provided components.

### Accessing elements

Three types of element access are available.

- `usize` indexing selects the nth element in the matrix as viewed in
  column-major order.
  
  ```rust
  let m = matrix![
      1, 2, 3;
      4, 5, 6;
  ];
  assert_eq!(m[1], 4);
  ```

- `(usize, usize)` indexing selects the element at a particular row and
  column position.
  
  ```rust
  let m = matrix![
      1, 2, 3;
      4, 5, 6;
  ];
  assert_eq!(m[(1, 0)], 4);
  ```

- Component accessors are available for small vectors using traditional
  names.
  
  ```rust
  let mut v = vector![1, 2, 3, 4, 0, 0];
  v.y = 3;
  v.w = 7;
  assert_eq!(v.x, 1);
  assert_eq!(v.y, 3);
  assert_eq!(v.z, 3);
  assert_eq!(v.w, 7);
  assert_eq!(v.a, 0);
  assert_eq!(v.b, 0);
  ```

### Accessing a row or column

You can get a reference to particular row or column using the
[`.row()`][row] or [`.column()`][column] methods. You
can get a mutable reference using the `_mut` variants.

```rust
let mut m = matrix![
    1, 2, 3;
    4, 7, 6;
];
let row = m.row_mut(1);
row[1] = 5;
assert_eq!(m.column(1), &[2, 5]);
```

### Iteration

Element-wise, column-major order iteration is provided using the following
methods.

- [`.into_iter()`][into_iter] → consumes the matrix and returns
  an owned iterator over each element.
- [`.iter()`][iter] → returns an iterator over a reference to
  each element.
- [`.iter_mut()`][iter_mut] → returns an iterator over a mutable
  reference to each element.

Iteration over rows and columns is provide using the following methods.

- [`.iter_rows()`][iter_rows] → returns an iterator over a
  reference to each row.
- [`.iter_rows_mut()`][iter_rows_mut] → returns an iterator over
  mutable reference to each row.
- [`.iter_columns()`][iter_columns] → returns an iterator over a
  reference to each column.
- [`.iter_columns_mut()`][iter_columns_mut] → returns an
  iterator over a mutable reference to each column.

#### Slice representation

A slice view of the underlying data is provided using
[`.as_slice()`][as_slice] and
[`.as_mut_slice()`][as_mut_slice].

```rust
let mut m = matrix![
    1, 3, 5;
    2, 3, 6;
];
m.as_mut_slice()[3] = 4;
assert_eq!(m.as_slice(), &[1, 2, 3, 4, 5, 6]);
```

### Debug

The [`Debug`][Debug] implementation will print out vectors as
lists and matrices as a list of lists in column-major order.

```rust
let v = vector![1.1, 2.0];
let m = matrix![1, 2; 3, 4];
println!("vector: {:.2?}", v);
println!("matrix: {:?}", m);
```

This will output:

```text
vector: [1.10, 2.00]
matrix: [[1, 3], [2, 4]]
```

### Display

The [`Display`][Display] implementation will print out the
matrix in the traditional box bracket format. Precision is supported as well
as most of the other formatting traits like
[`LowerHex`][LowerHex].

```rust
let cv = vector![1.1, 2.0];
let rv = row_vector![1.1, 2.0];
let m = matrix![1, 2; 3, 4];
println!("column vector: {:.2}", cv);
println!("row vector: {:.1}", rv);
println!("matrix: {:b}", m);
```

This will output:

```text
column vector:
 ┌      ┐
 │ 1.10 │
 │ 2.00 │
 └      ┘

row vector:
 ┌          ┐
 │ 1.1  2.0 │
 └          ┘

matrix:
 ┌         ┐
 │  1   10 │
 │ 11  100 │
 └         ┘
```

### Operations

[`Matrix`][Matrix] implements many built-in operators. With scalar operands almost
all operators are implemented and they simply apply the operation to each
element in the matrix. Unary operators will do the equivalent. In the
following example each element in the matrix is multiplied by 2.

```rust
let m = matrix![
    1, -3;
    3, -7;
];
let exp = matrix![
    2, -6;
    6, -14;
];
assert_eq!(m * 2, exp);
```

[`Matrix`][Matrix] supports addition and subtraction with same size matrices for
element-wise addition and subtraction. In the following example a matrix
is added to itself.

```rust
let m = matrix![
    1, -3;
    3, -7;
];
let exp = matrix![
    2, -6;
    6, -14;
];
assert_eq!(m + m, exp);
```

## License

This project is distributed under the terms of both the MIT license and the Apache License (Version 2.0).

See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details.


[::from_iter]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.from_iter
[::identity]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.identity
[::new]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.new
[::repeat]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.repeat
[::repeat_with]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.repeat_with
[::zero]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.zero
[Debug]: https://doc.rust-lang.org/stable/std/fmt/trait.Debug.html
[Display]: https://doc.rust-lang.org/stable/std/fmt/trait.Display.html
[LowerHex]: https://doc.rust-lang.org/stable/std/fmt/trait.LowerHex.html
[Matrix]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html
[RowVector]: https://docs.rs/vectrix/latest/vectrix/type.RowVector.html
[T::zero]: https://docs.rs/vectrix/latest/vectrix/trait.Zero.html#tymethod.zero
[Vector]: https://docs.rs/vectrix/latest/vectrix/type.Vector.html
[as_mut_slice]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.as_mut_slice
[as_slice]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.as_slice
[column]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.column
[into_iter]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.into_iter
[iter]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.iter
[iter_columns]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.iter_columns
[iter_columns_mut]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.iter_columns_mut
[iter_mut]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.iter_mut
[iter_rows]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.iter_rows
[iter_rows_mut]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.iter_rows_mut
[matrix]: https://docs.rs/vectrix/latest/vectrix/macro.matrix.html
[row]: https://docs.rs/vectrix/latest/vectrix/struct.Matrix.html#method.row
[row_vector]: https://docs.rs/vectrix/latest/vectrix/macro.row_vector.html
[vector]: https://docs.rs/vectrix/latest/vectrix/macro.vector.html