Compare commits

..

23 Commits

Author SHA1 Message Date
abdul124 dd00f9b460 src/lib: add features for non-std support 2024-07-18 14:19:11 +08:00
Sébastien Crozet 64e97c85d5
Release v0.32.6 2024-06-12 11:13:12 +02:00
Sébastien Crozet f8cb672280
Support conversion for glam 0.27 (#1390) 2024-06-12 11:11:53 +02:00
Sébastien Crozet 6b7305337f
Release v0.32.5 2024-03-28 15:30:06 +01:00
Sébastien Crozet 440d4a4681
chore: add comment providing details on the householder fix. 2024-03-28 15:07:05 +01:00
Vollkornaffe dd44414a8a chore: Add test that fails before fix 2024-03-08 18:19:41 +01:00
Vollkornaffe 4decc8003d fix: Normalize the column once more
The column may not be normalized if the `factor` is on a scale of 1e-40.
Possibly, f32 just runs out of precision.

There is likely a better solution to the problem.
2024-03-08 18:19:41 +01:00
Sébastien Crozet 4a5855a1c4
Merge pull request #1362 from dimforge/dev-0.32.4
Release v0.32.4
2024-02-19 11:00:54 +01:00
Sébastien Crozet e726b65fd7
Release v0.32.4 2024-02-19 10:55:01 +01:00
Sébastien Crozet 980dd68e68
Support Glam 0.25 type conversion 2024-02-19 10:53:08 +01:00
Sébastien Crozet d8ed277243
Merge pull request #1194 from dimforge/dev
Release v0.32.0
2023-01-14 17:52:41 +01:00
Sébastien Crozet 2adb4f0b26 Merge branch 'dev' 2022-10-09 22:16:43 +02:00
Sébastien Crozet 6eea643277
Merge pull request #1134 from dimforge/dev
Release v0.31.1
2022-07-31 10:01:46 +02:00
Sébastien Crozet b7d7b69777
Merge pull request #1104 from dimforge/dev
Release v0.31.0
2022-04-30 14:08:22 +02:00
Sébastien Crozet 7b6f4c6547
Merge pull request #1057 from dimforge/dev
Release v0.30.0
2022-01-02 15:40:03 +01:00
Sébastien Crozet e48169e234
Merge pull request #967 from dimforge/dev
Bump the version of nalgebra-glm, nalgebra-lapack, and nalgebra-sparse.
2021-08-08 18:08:25 +02:00
Sébastien Crozet fef43a6146
Merge pull request #966 from dimforge/dev
Release v0.29.0
2021-08-08 18:04:20 +02:00
Sébastien Crozet 944afe24e8
Merge pull request #945 from dimforge/dev
Release v0.28.0
2021-07-11 18:11:45 +02:00
Sébastien Crozet c04b087388
Merge pull request #901 from dimforge/dev
Release v0.27.0
2021-06-02 15:25:43 +02:00
Sébastien Crozet 156f292917
Merge pull request #869 from dimforge/dev
Release v0.26.0
2021-04-12 16:27:28 +02:00
Sébastien Crozet e9535d5cb5
Merge pull request #846 from dimforge/dev
Release v0.25.2
2021-03-06 14:17:31 +01:00
Sébastien Crozet e8fb1ab215
Merge pull request #842 from dimforge/dev
Release v0.25.1
2021-03-02 14:34:28 +01:00
Sébastien Crozet 39ef8b43cf
Merge pull request #839 from dimforge/dev
Release v0.25.0
2021-03-01 14:34:04 +01:00
211 changed files with 3073 additions and 4770 deletions

View File

@ -13,59 +13,52 @@ jobs:
check-fmt: check-fmt:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Check formatting - name: Check formatting
run: cargo fmt -- --check run: cargo fmt -- --check
clippy: clippy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Install clippy - name: Install clippy
run: rustup component add clippy run: rustup component add clippy
- name: Run clippy - name: Run clippy
run: cargo clippy run: cargo clippy
build-nalgebra: build-nalgebra:
runs-on: ubuntu-latest runs-on: ubuntu-latest
# env: # env:
# RUSTFLAGS: -D warnings # RUSTFLAGS: -D warnings
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Build --no-default-feature - name: Build --no-default-feature
run: cargo build --no-default-features; run: cargo build --no-default-features;
- name: Build (default features) - name: Build (default features)
run: cargo build; run: cargo build;
- name: Build --features serde-serialize - name: Build --features serde-serialize
run: cargo build --features serde-serialize run: cargo build --features serde-serialize
- name: Build nalgebra-lapack - name: Build nalgebra-lapack
run: cd nalgebra-lapack; cargo build; run: cd nalgebra-lapack; cargo build;
- name: Build nalgebra-sparse --no-default-features - name: Build nalgebra-sparse --no-default-features
run: cd nalgebra-sparse; cargo build --no-default-features; run: cd nalgebra-sparse; cargo build --no-default-features;
- name: Build nalgebra-sparse (default features) - name: Build nalgebra-sparse (default features)
run: cd nalgebra-sparse; cargo build; run: cd nalgebra-sparse; cargo build;
- name: Build nalgebra-sparse --all-features - name: Build nalgebra-sparse --all-features
run: cd nalgebra-sparse; cargo build --all-features; run: cd nalgebra-sparse; cargo build --all-features;
# Run this on its own job because it alone takes a lot of time. # Run this on its own job because it alone takes a lot of time.
# So its best to let it run in parallel to the other jobs. # So its best to let it run in parallel to the other jobs.
build-nalgebra-all-features: build-nalgebra-all-features:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# Needed because the --all-features build which enables cuda support.
- uses: Jimver/cuda-toolkit@v0.2.8
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- run: cargo build --all-features; - run: cargo build --all-features;
- run: cargo build -p nalgebra-glm --all-features; - run: cargo build -p nalgebra-glm --all-features;
test-nalgebra: test-nalgebra:
runs-on: ubuntu-latest runs-on: ubuntu-latest
# env: # env:
# RUSTFLAGS: -D warnings # RUSTFLAGS: -D warnings
steps: steps:
# Tests are run with a specific version of the compiler to avoid
# trybuild errors when a new compiler version is out. This can be
# bumped as needed after running the tests with TRYBUILD=overwrite
# to re-generate the error reference.
- name: Select rustc version
uses: actions-rs/toolchain@v1
with:
toolchain: 1.79.0
override: true
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: test - name: test
run: cargo test --features arbitrary,rand,serde-serialize,sparse,debug,io,compare,libm,proptest-support,slow-tests,rkyv-safe-deser,rayon; run: cargo test --features arbitrary,rand,serde-serialize,sparse,debug,io,compare,libm,proptest-support,slow-tests,rkyv-safe-deser,rayon;
@ -94,8 +87,8 @@ jobs:
run: cargo test -p nalgebra-macros run: cargo test -p nalgebra-macros
build-wasm: build-wasm:
runs-on: ubuntu-latest runs-on: ubuntu-latest
# env: # env:
# RUSTFLAGS: -D warnings # RUSTFLAGS: -D warnings
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- run: rustup target add wasm32-unknown-unknown - run: rustup target add wasm32-unknown-unknown
@ -127,9 +120,26 @@ jobs:
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=x86_64-unknown-linux-gnu; run: xargo build --verbose --no-default-features -p nalgebra-glm --target=x86_64-unknown-linux-gnu;
- name: build thumbv7em-none-eabihf nalgebra-glm - name: build thumbv7em-none-eabihf nalgebra-glm
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=thumbv7em-none-eabihf; run: xargo build --verbose --no-default-features -p nalgebra-glm --target=thumbv7em-none-eabihf;
build-cuda:
runs-on: ubuntu-latest
steps:
- uses: Jimver/cuda-toolkit@v0.2.8
with:
cuda: '11.5.0'
- name: Install nightly-2021-12-04
uses: actions-rs/toolchain@v1
with:
toolchain: nightly-2021-12-04
override: true
- uses: actions/checkout@v2
- run: rustup target add nvptx64-nvidia-cuda
- run: cargo build --no-default-features --features cuda
- run: cargo build --no-default-features --features cuda --target=nvptx64-nvidia-cuda
env:
CUDA_ARCH: "350"
docs: docs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Generate documentation - name: Generate documentation
run: cargo doc run: cargo doc

View File

@ -5,33 +5,13 @@ documented here.
This project adheres to [Semantic Versioning](https://semver.org/). This project adheres to [Semantic Versioning](https://semver.org/).
## [0.33.0] (23 June 2024) ## Unreleased
### Fixed
- Fix a memory leak in `Matrix::generic_resize`.
- Fix `glm::is_null` to check the vector magnitude instead of individual components.
- Ensure that inverting a 4x4 matrix leaves it unchanged if the inversion fails.
### Added
- Add the `glam-0.28` feature to enable conversion from/to types from `glam` v0.28.
- Add a `stack!` macro for concatenating matrices. See [#1375](https://github.com/dimforge/nalgebra/pull/1375).
### Modified
- The `cuda` feature has been removed, as the toolchain it depends on is long abandoned.
- Update to `simba` 0.9. See the [changelog](https://github.com/dimforge/simba/blob/master/CHANGELOG) of `simba` for
details.
- Update the `nalgebra-macros` crate to `syn` 2.0.
- Remove the scalar type `T` from the `Allocator` trait parameters. Instead of `Allocator<T, R, C>`, use the simpler
`Allocator<R, C>`.
## [0.32.6] (12 June 2024) ## [0.32.6] (12 June 2024)
### Added ### Added
- Add the `glam-0.27` feature to enable conversion from/to types from `glam` v0.27. - Add the `convert-glam027` feature to enable conversion from/to types from `glam` v0.27.
## [0.32.5] (28 March 2024) ## [0.32.5] (28 March 2024)
@ -59,7 +39,6 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Add the methods `Matrix1::as_scalar`, `::as_scalar_mut`, `::to_scalar`, `::into_scalar`. - Add the methods `Matrix1::as_scalar`, `::as_scalar_mut`, `::to_scalar`, `::into_scalar`.
- Add `Rotation3::euler_angles_ordered`, a generalized euler angles calculation. - Add `Rotation3::euler_angles_ordered`, a generalized euler angles calculation.
- Add the `glam-0.24` feature to enable conversion from/to types from `glam` v0.24. - Add the `glam-0.24` feature to enable conversion from/to types from `glam` v0.24.
- Add the `glam-0.25` feature to enable conversion from/to types from `glam` v0.25.
- Add the `lerp` method to points. - Add the `lerp` method to points.
- Implement `Clone` for `MatrixIter`. - Implement `Clone` for `MatrixIter`.

View File

@ -1,6 +1,6 @@
[package] [package]
name = "nalgebra" name = "nalgebra"
version = "0.33.0" version = "0.32.6"
authors = ["Sébastien Crozet <developer@crozet.re>"] authors = ["Sébastien Crozet <developer@crozet.re>"]
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices." description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."
@ -10,7 +10,7 @@ repository = "https://github.com/dimforge/nalgebra"
readme = "README.md" readme = "README.md"
categories = ["science", "mathematics", "wasm", "no-std"] categories = ["science", "mathematics", "wasm", "no-std"]
keywords = ["linear", "algebra", "matrix", "vector", "math"] keywords = ["linear", "algebra", "matrix", "vector", "math"]
license = "Apache-2.0" license = "BSD-3-Clause"
edition = "2018" edition = "2018"
exclude = ["/ci/*", "/.travis.yml", "/Makefile"] exclude = ["/ci/*", "/.travis.yml", "/Makefile"]
@ -23,7 +23,7 @@ path = "src/lib.rs"
[features] [features]
default = ["std", "macros"] default = ["std", "macros"]
std = ["matrixmultiply", "num-traits/std", "num-complex/std", "num-rational/std", "approx/std", "simba/std"] std = ["matrixmultiply", "simba/std"]
sparse = [] sparse = []
debug = ["approx/num-complex", "rand"] debug = ["approx/num-complex", "rand"]
alloc = [] alloc = []
@ -32,6 +32,8 @@ compare = ["matrixcompare-core"]
libm = ["simba/libm"] libm = ["simba/libm"]
libm-force = ["simba/libm_force"] libm-force = ["simba/libm_force"]
macros = ["nalgebra-macros"] macros = ["nalgebra-macros"]
cuda = ["cust_core", "simba/cuda"]
# Conversion # Conversion
convert-mint = ["mint"] convert-mint = ["mint"]
@ -49,7 +51,6 @@ convert-glam023 = ["glam023"]
convert-glam024 = ["glam024"] convert-glam024 = ["glam024"]
convert-glam025 = ["glam025"] convert-glam025 = ["glam025"]
convert-glam027 = ["glam027"] convert-glam027 = ["glam027"]
convert-glam028 = ["glam028"]
# Serialization # Serialization
## To use serde in a #[no-std] environment, enable the ## To use serde in a #[no-std] environment, enable the
@ -74,14 +75,14 @@ slow-tests = []
rkyv-safe-deser = ["rkyv-serialize", "rkyv/validation"] rkyv-safe-deser = ["rkyv-serialize", "rkyv/validation"]
[dependencies] [dependencies]
nalgebra-macros = { version = "0.2.2", path = "nalgebra-macros", optional = true } nalgebra-macros = { version = "0.2.1", path = "nalgebra-macros", optional = true }
typenum = "1.12" typenum = "1.12"
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false } rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
num-traits = { version = "0.2", default-features = false } num-traits = { version = "0.2", default-features = false }
num-complex = { version = "0.4", default-features = false } num-complex = { version = "0.4", default-features = false }
num-rational = { version = "0.4", default-features = false } num-rational = { version = "0.4", default-features = false }
approx = { version = "0.5", default-features = false } approx = { version = "0.5", default-features = false }
simba = { version = "0.9", default-features = false } simba = { version = "0.8", default-features = false }
alga = { version = "0.9", default-features = false, optional = true } alga = { version = "0.9", default-features = false, optional = true }
rand_distr = { version = "0.4", default-features = false, optional = true } rand_distr = { version = "0.4", default-features = false, optional = true }
matrixmultiply = { version = "0.3", optional = true } matrixmultiply = { version = "0.3", optional = true }
@ -107,7 +108,7 @@ glam023 = { package = "glam", version = "0.23", optional = true }
glam024 = { package = "glam", version = "0.24", optional = true } glam024 = { package = "glam", version = "0.24", optional = true }
glam025 = { package = "glam", version = "0.25", optional = true } glam025 = { package = "glam", version = "0.25", optional = true }
glam027 = { package = "glam", version = "0.27", optional = true } glam027 = { package = "glam", version = "0.27", optional = true }
glam028 = { package = "glam", version = "0.28", optional = true } cust_core = { version = "0.1", optional = true }
rayon = { version = "1.6", optional = true } rayon = { version = "1.6", optional = true }
[dev-dependencies] [dev-dependencies]
@ -119,12 +120,7 @@ nalgebra = { path = ".", features = ["debug", "compare", "rand", "macros"] }
# For matrix comparison macro # For matrix comparison macro
matrixcompare = "0.3.0" matrixcompare = "0.3.0"
itertools = "0.13" itertools = "0.10"
# For macro testing
trybuild = "1.0.90"
cool_asserts = "2.0.3"
[workspace] [workspace]
members = ["nalgebra-lapack", "nalgebra-glm", "nalgebra-sparse", "nalgebra-macros"] members = ["nalgebra-lapack", "nalgebra-glm", "nalgebra-sparse", "nalgebra-macros"]

View File

@ -5,6 +5,9 @@
<a href="https://discord.gg/vt9DJSW"> <a href="https://discord.gg/vt9DJSW">
<img src="https://img.shields.io/discord/507548572338880513.svg?logo=discord&colorB=7289DA"> <img src="https://img.shields.io/discord/507548572338880513.svg?logo=discord&colorB=7289DA">
</a> </a>
<a href="https://circleci.com/gh/dimforge/nalgebra">
<img src="https://circleci.com/gh/dimforge/nalgebra.svg?style=svg" alt="Build status">
</a>
<a href="https://crates.io/crates/nalgebra"> <a href="https://crates.io/crates/nalgebra">
<img src="https://img.shields.io/crates/v/nalgebra.svg?style=flat-square" alt="crates.io"> <img src="https://img.shields.io/crates/v/nalgebra.svg?style=flat-square" alt="crates.io">
</a> </a>
@ -14,7 +17,7 @@
</p> </p>
<p align = "center"> <p align = "center">
<strong> <strong>
<a href="https://nalgebra.org">Users guide</a> | <a href="https://docs.rs/nalgebra/latest/nalgebra/">Documentation</a> <a href="https://nalgebra.org">Users guide</a> | <a href="https://docs.rs/nalgebra/latest/nalgebra/">Documentation</a> | <a href="https://discourse.nphysics.org/c/nalgebra">Forum</a>
</strong> </strong>
</p> </p>

View File

@ -142,7 +142,7 @@ fn iter(bench: &mut criterion::Criterion) {
bench.bench_function("iter", move |bh| { bench.bench_function("iter", move |bh| {
bh.iter(|| { bh.iter(|| {
for value in a.iter() { for value in a.iter() {
std::hint::black_box(value); criterion::black_box(value);
} }
}) })
}); });
@ -154,7 +154,7 @@ fn iter_rev(bench: &mut criterion::Criterion) {
bench.bench_function("iter_rev", move |bh| { bench.bench_function("iter_rev", move |bh| {
bh.iter(|| { bh.iter(|| {
for value in a.iter().rev() { for value in a.iter().rev() {
std::hint::black_box(value); criterion::black_box(value);
} }
}) })
}); });

View File

@ -1,3 +1,4 @@
#![feature(bench_black_box)]
#![allow(unused_macros)] #![allow(unused_macros)]
extern crate nalgebra as na; extern crate nalgebra as na;

View File

@ -1,10 +1,10 @@
[package] [package]
name = "example-using-nalgebra" name = "example-using-nalgebra"
version = "0.0.0" version = "0.0.0"
authors = ["You"] authors = [ "You" ]
[dependencies] [dependencies]
nalgebra = "0.33.0" nalgebra = "0.32.0"
[[bin]] [[bin]]
name = "example" name = "example"

View File

@ -12,7 +12,7 @@ fn reflect_wrt_hyperplane_with_dimensional_genericity<T: RealField, D: Dim>(
where where
T: RealField, T: RealField,
D: Dim, D: Dim,
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<T, D>,
{ {
let n = plane_normal.as_ref(); // Get the underlying V. let n = plane_normal.as_ref(); // Get the underlying V.
vector - n * (n.dot(vector) * na::convert(2.0)) vector - n * (n.dot(vector) * na::convert(2.0))
@ -28,7 +28,7 @@ where
} }
/// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`. /// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`.
/// /!\ This is an exact replicate of `reflect_wrt_hyperplane2`, but for 3D. /// /!\ This is an exact replicate of `reflect_wrt_hyperplane2, but for 3D.
fn reflect_wrt_hyperplane3<T>(plane_normal: &Unit<Vector3<T>>, vector: &Vector3<T>) -> Vector3<T> fn reflect_wrt_hyperplane3<T>(plane_normal: &Unit<Vector3<T>>, vector: &Vector3<T>) -> Vector3<T>
where where
T: RealField, T: RealField,

View File

@ -1,6 +1,6 @@
[package] [package]
name = "nalgebra-glm" name = "nalgebra-glm"
version = "0.19.0" version = "0.18.0"
authors = ["sebcrozet <developer@crozet.re>"] authors = ["sebcrozet <developer@crozet.re>"]
description = "A computer-graphics oriented API for nalgebra, inspired by the C++ GLM library." description = "A computer-graphics oriented API for nalgebra, inspired by the C++ GLM library."
@ -8,31 +8,32 @@ documentation = "https://www.nalgebra.org/docs"
homepage = "https://nalgebra.org" homepage = "https://nalgebra.org"
repository = "https://github.com/dimforge/nalgebra" repository = "https://github.com/dimforge/nalgebra"
readme = "../README.md" readme = "../README.md"
categories = ["science", "mathematics", "wasm", "no standard library"] categories = [ "science", "mathematics", "wasm", "no standard library" ]
keywords = ["linear", "algebra", "matrix", "vector", "math"] keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
license = "Apache-2.0" license = "BSD-3-Clause"
edition = "2018" edition = "2018"
[badges] [badges]
maintenance = { status = "actively-developed" } maintenance = { status = "actively-developed" }
[features] [features]
default = ["std"] default = [ "std" ]
std = ["nalgebra/std", "simba/std"] std = [ "nalgebra/std", "simba/std" ]
arbitrary = ["nalgebra/arbitrary"] arbitrary = [ "nalgebra/arbitrary" ]
serde-serialize = ["nalgebra/serde-serialize-no-std"] serde-serialize = [ "nalgebra/serde-serialize-no-std" ]
cuda = [ "nalgebra/cuda" ]
# Conversion # Conversion
convert-mint = ["nalgebra/mint"] convert-mint = [ "nalgebra/mint" ]
convert-bytemuck = ["nalgebra/bytemuck"] convert-bytemuck = [ "nalgebra/bytemuck" ]
convert-glam014 = ["nalgebra/glam014"] convert-glam014 = [ "nalgebra/glam014" ]
convert-glam015 = ["nalgebra/glam015"] convert-glam015 = [ "nalgebra/glam015" ]
convert-glam016 = ["nalgebra/glam016"] convert-glam016 = [ "nalgebra/glam016" ]
convert-glam017 = ["nalgebra/glam017"] convert-glam017 = [ "nalgebra/glam017" ]
convert-glam018 = ["nalgebra/glam018"] convert-glam018 = [ "nalgebra/glam018" ]
[dependencies] [dependencies]
num-traits = { version = "0.2", default-features = false } num-traits = { version = "0.2", default-features = false }
approx = { version = "0.5", default-features = false } approx = { version = "0.5", default-features = false }
simba = { version = "0.9", default-features = false } simba = { version = "0.8", default-features = false }
nalgebra = { path = "..", version = "0.33", default-features = false } nalgebra = { path = "..", version = "0.32", default-features = false }

View File

@ -1 +0,0 @@
../LICENSE

View File

@ -5,38 +5,38 @@ use na::{
/// A matrix with components of type `T`. It has `R` rows, and `C` columns. /// A matrix with components of type `T`. It has `R` rows, and `C` columns.
/// ///
/// In this library, vectors, represented as [`TVec`] and /// In this library, vectors, represented as [`TVec`](type.TVec.html) and
/// friends, are also matrices. Operations that operate on a matrix will /// friends, are also matrices. Operations that operate on a matrix will
/// also work on a vector. /// also work on a vector.
/// ///
/// # See also: /// # See also:
/// ///
/// * [`TMat2`] /// * [`TMat2`](type.TMat2.html)
/// * [`TMat2x2`] /// * [`TMat2x2`](type.TMat2x2.html)
/// * [`TMat2x3`] /// * [`TMat2x3`](type.TMat2x3.html)
/// * [`TMat2x4`] /// * [`TMat2x4`](type.TMat2x4.html)
/// * [`TMat3`] /// * [`TMat3`](type.TMat3.html)
/// * [`TMat3x2`] /// * [`TMat3x2`](type.TMat3x2.html)
/// * [`TMat3x3`] /// * [`TMat3x3`](type.TMat3x3.html)
/// * [`TMat3x4`] /// * [`TMat3x4`](type.TMat3x4.html)
/// * [`TMat4`] /// * [`TMat4`](type.TMat4.html)
/// * [`TMat4x2`] /// * [`TMat4x2`](type.TMat4x2.html)
/// * [`TMat4x3`] /// * [`TMat4x3`](type.TMat4x3.html)
/// * [`TMat4x4`] /// * [`TMat4x4`](type.TMat4x4.html)
/// * [`TVec`] /// * [`TVec`](type.TVec.html)
pub type TMat<T, const R: usize, const C: usize> = SMatrix<T, R, C>; pub type TMat<T, const R: usize, const C: usize> = SMatrix<T, R, C>;
/// A column vector with components of type `T`. It has `D` rows (and one column). /// A column vector with components of type `T`. It has `D` rows (and one column).
/// ///
/// In this library, vectors are represented as a single column matrix, so /// In this library, vectors are represented as a single column matrix, so
/// operations on [`TMat`] are also valid on vectors. /// operations on [`TMat`](type.TMat.html) are also valid on vectors.
/// ///
/// # See also: /// # See also:
/// ///
/// * [`TMat`] /// * [`TMat`](type.TMat.html)
/// * [`TVec1`] /// * [`TVec1`](type.TVec1.html)
/// * [`TVec2`] /// * [`TVec2`](type.TVec2.html)
/// * [`TVec3`] /// * [`TVec3`](type.TVec3.html)
/// * [`TVec4`] /// * [`TVec4`](type.TVec4.html)
pub type TVec<T, const R: usize> = SVector<T, R>; pub type TVec<T, const R: usize> = SVector<T, R>;
/// A quaternion with components of type `T`. /// A quaternion with components of type `T`.
pub type Qua<T> = Quaternion<T>; pub type Qua<T> = Quaternion<T>;
@ -47,28 +47,28 @@ pub type Qua<T> = Quaternion<T>;
/// ///
/// ## Constructors: /// ## Constructors:
/// ///
/// * [`make_vec1()`](crate::make_vec1) /// * [`make_vec1`](fn.make_vec1.html)
/// * [`vec1()`](crate::vec1) /// * [`vec1`](fn.vec1.html)
/// * [`vec2_to_vec1()`](crate::vec2_to_vec1) /// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec3_to_vec1()`](crate::vec3_to_vec1) /// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec4_to_vec1()`](crate::vec4_to_vec1) /// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// ///
/// ## Related types: /// ## Related types:
/// ///
/// * [`BVec1`] /// * [`BVec1`](type.BVec1.html)
/// * [`DVec1`] /// * [`DVec1`](type.DVec1.html)
/// * [`IVec1`] /// * [`IVec1`](type.IVec1.html)
/// * [`I16Vec1`] /// * [`I16Vec1`](type.I16Vec1.html)
/// * [`I32Vec1`] /// * [`I32Vec1`](type.I32Vec1.html)
/// * [`I64Vec1`] /// * [`I64Vec1`](type.I64Vec1.html)
/// * [`I8Vec1`] /// * [`I8Vec1`](type.I8Vec1.html)
/// * [`TVec`] /// * [`TVec`](type.TVec.html)
/// * [`UVec1`] /// * [`UVec1`](type.UVec1.html)
/// * [`U16Vec1`] /// * [`U16Vec1`](type.U16Vec1.html)
/// * [`U32Vec1`] /// * [`U32Vec1`](type.U32Vec1.html)
/// * [`U64Vec1`] /// * [`U64Vec1`](type.U64Vec1.html)
/// * [`U8Vec1`] /// * [`U8Vec1`](type.U8Vec1.html)
/// * [`Vec1`] /// * [`Vec1`](type.Vec1.html)
pub type TVec1<T> = TVec<T, 1>; pub type TVec1<T> = TVec<T, 1>;
/// A 2D vector with components of type `T`. /// A 2D vector with components of type `T`.
/// ///
@ -76,28 +76,29 @@ pub type TVec1<T> = TVec<T, 1>;
/// ///
/// ## Constructors: /// ## Constructors:
/// ///
/// * [`make_vec2()`](crate::make_vec2) /// * [`make_vec2`](fn.make_vec2.html)
/// * [`vec2()`](crate::vec2) /// * [`vec2`](fn.vec2.html)
/// * [`vec1_to_vec2()`](crate::vec1_to_vec2) /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec3_to_vec2()`](crate::vec3_to_vec2) /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec4_to_vec2()`](crate::vec4_to_vec2) /// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// ///
/// ## Related types: /// ## Related types:
/// ///
/// * [`BVec2`] /// * [`vec2`](fn.vec2.html)
/// * [`DVec2`] /// * [`BVec2`](type.BVec2.html)
/// * [`IVec2`] /// * [`DVec2`](type.DVec2.html)
/// * [`I16Vec2`] /// * [`IVec2`](type.IVec2.html)
/// * [`I32Vec2`] /// * [`I16Vec2`](type.I16Vec2.html)
/// * [`I64Vec2`] /// * [`I32Vec2`](type.I32Vec2.html)
/// * [`I8Vec2`] /// * [`I64Vec2`](type.I64Vec2.html)
/// * [`TVec`] /// * [`I8Vec2`](type.I8Vec2.html)
/// * [`UVec2`] /// * [`TVec`](type.TVec.html)
/// * [`U16Vec2`] /// * [`UVec2`](type.UVec2.html)
/// * [`U32Vec2`] /// * [`U16Vec2`](type.U16Vec2.html)
/// * [`U64Vec2`] /// * [`U32Vec2`](type.U32Vec2.html)
/// * [`U8Vec2`] /// * [`U64Vec2`](type.U64Vec2.html)
/// * [`Vec2`] /// * [`U8Vec2`](type.U8Vec2.html)
/// * [`Vec2`](type.Vec2.html)
pub type TVec2<T> = TVec<T, 2>; pub type TVec2<T> = TVec<T, 2>;
/// A 3D vector with components of type `T`. /// A 3D vector with components of type `T`.
/// ///
@ -105,28 +106,29 @@ pub type TVec2<T> = TVec<T, 2>;
/// ///
/// ## Constructors: /// ## Constructors:
/// ///
/// * [`make_vec3()`](crate::make_vec3) /// * [`make_vec3`](fn.make_vec3.html)
/// * [`vec3()`](crate::vec3) /// * [`vec3`](fn.vec3.html)
/// * [`vec1_to_vec3()`](crate::vec1_to_vec3) /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec2_to_vec3()`](crate::vec2_to_vec3) /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec4_to_vec3()`](crate::vec4_to_vec3) /// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// ///
/// ## Related types: /// ## Related types:
/// ///
/// * [`BVec3`] /// * [`vec3`](fn.vec3.html)
/// * [`DVec3`] /// * [`BVec3`](type.BVec3.html)
/// * [`IVec3`] /// * [`DVec3`](type.DVec3.html)
/// * [`I16Vec3`] /// * [`IVec3`](type.IVec3.html)
/// * [`I32Vec3`] /// * [`I16Vec3`](type.I16Vec3.html)
/// * [`I64Vec3`] /// * [`I32Vec3`](type.I32Vec3.html)
/// * [`I8Vec3`] /// * [`I64Vec3`](type.I64Vec3.html)
/// * [`TVec`] /// * [`I8Vec3`](type.I8Vec3.html)
/// * [`UVec3`] /// * [`TVec`](type.TVec.html)
/// * [`U16Vec3`] /// * [`UVec3`](type.UVec3.html)
/// * [`U32Vec3`] /// * [`U16Vec3`](type.U16Vec3.html)
/// * [`U64Vec3`] /// * [`U32Vec3`](type.U32Vec3.html)
/// * [`U8Vec3`] /// * [`U64Vec3`](type.U64Vec3.html)
/// * [`Vec3`] /// * [`U8Vec3`](type.U8Vec3.html)
/// * [`Vec3`](type.Vec3.html)
pub type TVec3<T> = TVec<T, 3>; pub type TVec3<T> = TVec<T, 3>;
/// A 4D vector with components of type `T`. /// A 4D vector with components of type `T`.
/// ///
@ -134,27 +136,28 @@ pub type TVec3<T> = TVec<T, 3>;
/// ///
/// ## Constructors: /// ## Constructors:
/// ///
/// * [`make_vec4()`](crate::make_vec4) /// * [`make_vec4`](fn.make_vec4.html)
/// * [`vec4()`](crate::vec4) /// * [`vec4`](fn.vec4.html)
/// * [`vec1_to_vec4()`](crate::vec1_to_vec4) /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec4()`](crate::vec2_to_vec4) /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec3_to_vec4()`](crate::vec3_to_vec4) /// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// ///
/// ## Related types: /// ## Related types:
/// ///
/// * [`BVec4`] /// * [`vec4`](fn.vec4.html)
/// * [`DVec4`] /// * [`BVec4`](type.BVec4.html)
/// * [`IVec4`] /// * [`DVec4`](type.DVec4.html)
/// * [`I16Vec4`] /// * [`IVec4`](type.IVec4.html)
/// * [`I32Vec4`] /// * [`I16Vec4`](type.I16Vec4.html)
/// * [`I64Vec4`] /// * [`I32Vec4`](type.I32Vec4.html)
/// * [`I8Vec4`] /// * [`I64Vec4`](type.I64Vec4.html)
/// * [`UVec4`] /// * [`I8Vec4`](type.I8Vec4.html)
/// * [`U16Vec4`] /// * [`UVec4`](type.UVec4.html)
/// * [`U32Vec4`] /// * [`U16Vec4`](type.U16Vec4.html)
/// * [`U64Vec4`] /// * [`U32Vec4`](type.U32Vec4.html)
/// * [`U8Vec4`] /// * [`U64Vec4`](type.U64Vec4.html)
/// * [`Vec4`] /// * [`U8Vec4`](type.U8Vec4.html)
/// * [`Vec4`](type.Vec4.html)
pub type TVec4<T> = TVec<T, 4>; pub type TVec4<T> = TVec<T, 4>;
/// A 1D vector with boolean components. /// A 1D vector with boolean components.
pub type BVec1 = TVec1<bool>; pub type BVec1 = TVec1<bool>;

View File

@ -1,4 +1,5 @@
use core::mem; use core::mem;
use na;
use crate::aliases::{TMat, TVec}; use crate::aliases::{TMat, TVec};
use crate::traits::Number; use crate::traits::Number;
@ -19,7 +20,7 @@ use crate::RealNumber;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`sign()`] /// * [`sign`](fn.sign.html)
pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat<T, R, C> { pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat<T, R, C> {
x.abs() x.abs()
} }
@ -36,11 +37,11 @@ pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ceil()`] /// * [`ceil`](fn.ceil.html)
/// * [`floor()`] /// * [`floor`](fn.floor.html)
/// * [`fract()`] /// * [`fract`](fn.fract.html)
/// * [`round()`] /// * [`round`](fn.round.html)
/// * [`trunc()`] /// * [`trunc`](fn.trunc.html)
pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| x.ceil()) x.map(|x| x.ceil())
} }
@ -64,8 +65,8 @@ pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`clamp()`] /// * [`clamp`](fn.clamp.html)
/// * [`clamp_vec()`] /// * [`clamp_vec`](fn.clamp_vec.html)
pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T { pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
na::clamp(x, min_val, max_val) na::clamp(x, min_val, max_val)
} }
@ -88,8 +89,8 @@ pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`clamp_scalar()`] /// * [`clamp_scalar`](fn.clamp_scalar.html)
/// * [`clamp_vec()`] /// * [`clamp_vec`](fn.clamp_vec.html)
pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T) -> TVec<T, D> { pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T) -> TVec<T, D> {
x.map(|x| na::clamp(x, min_val, max_val)) x.map(|x| na::clamp(x, min_val, max_val))
} }
@ -119,8 +120,8 @@ pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T)
/// ///
/// # See also: /// # See also:
/// ///
/// * [`clamp_scalar()`] /// * [`clamp_scalar`](fn.clamp_scalar.html)
/// * [`clamp()`] /// * [`clamp`](fn.clamp.html)
pub fn clamp_vec<T: Number, const D: usize>( pub fn clamp_vec<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
min_val: &TVec<T, D>, min_val: &TVec<T, D>,
@ -135,13 +136,13 @@ pub fn clamp_vec<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int_vec()`] /// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint()`] /// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec()`] /// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float()`] /// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec()`] /// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float()`] /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar()`] /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn float_bits_to_int(v: f32) -> i32 { pub fn float_bits_to_int(v: f32) -> i32 {
unsafe { mem::transmute(v) } unsafe { mem::transmute(v) }
} }
@ -152,13 +153,13 @@ pub fn float_bits_to_int(v: f32) -> i32 {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int()`] /// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_uint()`] /// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec()`] /// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float()`] /// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec()`] /// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float()`] /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar()`] /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> { pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
v.map(float_bits_to_int) v.map(float_bits_to_int)
} }
@ -169,13 +170,13 @@ pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int()`] /// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec()`] /// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint_vec()`] /// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float()`] /// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec()`] /// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float()`] /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar()`] /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn float_bits_to_uint(v: f32) -> u32 { pub fn float_bits_to_uint(v: f32) -> u32 {
unsafe { mem::transmute(v) } unsafe { mem::transmute(v) }
} }
@ -186,13 +187,13 @@ pub fn float_bits_to_uint(v: f32) -> u32 {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int()`] /// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec()`] /// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint()`] /// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`int_bits_to_float()`] /// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec()`] /// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float()`] /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar()`] /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D> { pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D> {
v.map(float_bits_to_uint) v.map(float_bits_to_uint)
} }
@ -209,10 +210,10 @@ pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D>
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ceil()`] /// * [`ceil`](fn.ceil.html)
/// * [`fract()`] /// * [`fract`](fn.fract.html)
/// * [`round()`] /// * [`round`](fn.round.html)
/// * [`trunc()`] /// * [`trunc`](fn.trunc.html)
pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| x.floor()) x.map(|x| x.floor())
} }
@ -235,10 +236,10 @@ pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ceil()`] /// * [`ceil`](fn.ceil.html)
/// * [`floor()`] /// * [`floor`](fn.floor.html)
/// * [`round()`] /// * [`round`](fn.round.html)
/// * [`trunc()`] /// * [`trunc`](fn.trunc.html)
pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| x.fract()) x.map(|x| x.fract())
} }
@ -257,13 +258,13 @@ pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int()`] /// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec()`] /// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint()`] /// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec()`] /// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float_vec()`] /// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float()`] /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar()`] /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn int_bits_to_float(v: i32) -> f32 { pub fn int_bits_to_float(v: i32) -> f32 {
f32::from_bits(v as u32) f32::from_bits(v as u32)
} }
@ -274,13 +275,13 @@ pub fn int_bits_to_float(v: i32) -> f32 {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int()`] /// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec()`] /// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint()`] /// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec()`] /// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float()`] /// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`uint_bits_to_float()`] /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar()`] /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> { pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
v.map(int_bits_to_float) v.map(int_bits_to_float)
} }
@ -314,8 +315,8 @@ pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`mix()`] /// * [`mix`](fn.mix.html)
/// * [`mix_vec()`] /// * [`mix_vec`](fn.mix_vec.html)
pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T { pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
x * (T::one() - a) + y * a x * (T::one() - a) + y * a
} }
@ -335,8 +336,8 @@ pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`mix_scalar()`] /// * [`mix_scalar`](fn.mix_scalar.html)
/// * [`mix_vec()`] /// * [`mix_vec`](fn.mix_vec.html)
pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> { pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
x * (T::one() - a) + y * a x * (T::one() - a) + y * a
} }
@ -358,14 +359,14 @@ pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`mix_scalar()`] /// * [`mix_scalar`](fn.mix_scalar.html)
/// * [`mix()`] /// * [`mix`](fn.mix.html)
pub fn mix_vec<T: Number, const D: usize>( pub fn mix_vec<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
a: &TVec<T, D>, a: &TVec<T, D>,
) -> TVec<T, D> { ) -> TVec<T, D> {
x.component_mul(&(TVec::<T, D>::repeat(T::one()) - a)) + y.component_mul(a) x.component_mul(&(TVec::<T, D>::repeat(T::one()) - a)) + y.component_mul(&a)
} }
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a. /// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a.
@ -382,8 +383,8 @@ pub fn mix_vec<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`lerp()`] /// * [`lerp`](fn.lerp.html)
/// * [`lerp_vec()`] /// * [`lerp_vec`](fn.lerp_vec.html)
pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T { pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
mix_scalar(x, y, a) mix_scalar(x, y, a)
} }
@ -404,8 +405,8 @@ pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`lerp_scalar()`] /// * [`lerp_scalar`](fn.lerp_scalar.html)
/// * [`lerp_vec()`] /// * [`lerp_vec`](fn.lerp_vec.html)
pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> { pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
mix(x, y, a) mix(x, y, a)
} }
@ -428,8 +429,8 @@ pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) ->
/// ///
/// # See also: /// # See also:
/// ///
/// * [`lerp_scalar()`] /// * [`lerp_scalar`](fn.lerp_scalar.html)
/// * [`lerp()`] /// * [`lerp`](fn.lerp.html)
pub fn lerp_vec<T: Number, const D: usize>( pub fn lerp_vec<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
@ -444,7 +445,7 @@ pub fn lerp_vec<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`modf()`] /// * [`modf`](fn.modf.html)
pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> { pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
x.zip_map(y, |x, y| x % y) x.zip_map(y, |x, y| x % y)
} }
@ -453,7 +454,7 @@ pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TV
/// ///
/// # See also: /// # See also:
/// ///
/// * [`modf_vec()`] /// * [`modf_vec`](fn.modf_vec.html)
pub fn modf<T: Number>(x: T, i: T) -> T { pub fn modf<T: Number>(x: T, i: T) -> T {
x % i x % i
} }
@ -472,10 +473,10 @@ pub fn modf<T: Number>(x: T, i: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ceil()`] /// * [`ceil`](fn.ceil.html)
/// * [`floor()`] /// * [`floor`](fn.floor.html)
/// * [`fract()`] /// * [`fract`](fn.fract.html)
/// * [`trunc()`] /// * [`trunc`](fn.trunc.html)
pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| x.round()) x.map(|x| x.round())
} }
@ -496,7 +497,7 @@ pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`abs()`] /// * [`abs`](fn.abs.html)
/// ///
pub fn sign<T: Number, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn sign<T: Number, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| if x.is_zero() { T::zero() } else { x.signum() }) x.map(|x| if x.is_zero() { T::zero() } else { x.signum() })
@ -544,10 +545,10 @@ pub fn step_vec<T: Number, const D: usize>(edge: &TVec<T, D>, x: &TVec<T, D>) ->
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ceil()`] /// * [`ceil`](fn.ceil.html)
/// * [`floor()`] /// * [`floor`](fn.floor.html)
/// * [`fract()`] /// * [`fract`](fn.fract.html)
/// * [`round()`] /// * [`round`](fn.round.html)
pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| x.trunc()) x.map(|x| x.trunc())
} }
@ -558,13 +559,13 @@ pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int()`] /// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec()`] /// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint()`] /// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec()`] /// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float()`] /// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec()`] /// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float()`] /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
pub fn uint_bits_to_float_scalar(v: u32) -> f32 { pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
f32::from_bits(v) f32::from_bits(v)
} }
@ -575,13 +576,13 @@ pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int()`] /// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec()`] /// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint()`] /// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec()`] /// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float()`] /// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec()`] /// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float_scalar()`] /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn uint_bits_to_float<const D: usize>(v: &TVec<u32, D>) -> TVec<f32, D> { pub fn uint_bits_to_float<const D: usize>(v: &TVec<u32, D>) -> TVec<f32, D> {
v.map(uint_bits_to_float_scalar) v.map(uint_bits_to_float_scalar)
} }

View File

@ -91,7 +91,6 @@ pub fn mat2x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
/// ); /// );
/// ``` /// ```
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat3<T: Scalar>(m11: T, m12: T, m13: T, pub fn mat3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: T, m21: T, m22: T, m23: T,
m31: T, m32: T, m33: T) -> TMat3<T> { m31: T, m32: T, m33: T) -> TMat3<T> {
@ -116,7 +115,6 @@ pub fn mat3x2<T: Scalar>(m11: T, m12: T,
/// Create a new 3x3 matrix. /// Create a new 3x3 matrix.
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T, pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: T, m21: T, m22: T, m23: T,
m31: T, m32: T, m33: T) -> TMat3<T> { m31: T, m32: T, m33: T) -> TMat3<T> {
@ -129,7 +127,6 @@ pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T,
/// Create a new 3x4 matrix. /// Create a new 3x4 matrix.
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat3x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T, pub fn mat3x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: T, m21: T, m22: T, m23: T, m24: T,
m31: T, m32: T, m33: T, m34: T) -> TMat3x4<T> { m31: T, m32: T, m33: T, m34: T) -> TMat3x4<T> {
@ -156,7 +153,6 @@ pub fn mat4x2<T: Scalar>(m11: T, m12: T,
/// Create a new 4x3 matrix. /// Create a new 4x3 matrix.
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T, pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: T, m21: T, m22: T, m23: T,
m31: T, m32: T, m33: T, m31: T, m32: T, m33: T,
@ -171,7 +167,6 @@ pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T,
/// Create a new 4x4 matrix. /// Create a new 4x4 matrix.
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T, pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: T, m21: T, m22: T, m23: T, m24: T,
m31: T, m32: T, m33: T, m34: T, m31: T, m32: T, m33: T, m34: T,
@ -186,7 +181,6 @@ pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
/// Create a new 4x4 matrix. /// Create a new 4x4 matrix.
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4<T: Scalar>(m11: T, m12: T, m13: T, m14: T, pub fn mat4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: T, m21: T, m22: T, m23: T, m24: T,
m31: T, m32: T, m33: T, m34: T, m31: T, m32: T, m33: T, m34: T,

View File

@ -5,7 +5,7 @@ use crate::RealNumber;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`exp2()`] /// * [`exp2`](fn.exp2.html)
pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.exp()) v.map(|x| x.exp())
} }
@ -14,7 +14,7 @@ pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`exp()`] /// * [`exp`](fn.exp.html)
pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.exp2()) v.map(|x| x.exp2())
} }
@ -23,7 +23,7 @@ pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`sqrt()`] /// * [`sqrt`](fn.sqrt.html)
pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| T::one() / x.sqrt()) v.map(|x| T::one() / x.sqrt())
} }
@ -32,7 +32,7 @@ pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D>
/// ///
/// # See also: /// # See also:
/// ///
/// * [`log2()`] /// * [`log2`](fn.log2.html)
pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.ln()) v.map(|x| x.ln())
} }
@ -41,7 +41,7 @@ pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`log()`] /// * [`log`](fn.log.html)
pub fn log2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn log2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.log2()) v.map(|x| x.log2())
} }
@ -55,10 +55,10 @@ pub fn pow<T: RealNumber, const D: usize>(base: &TVec<T, D>, exponent: &TVec<T,
/// ///
/// # See also: /// # See also:
/// ///
/// * [`exp()`] /// * [`exp`](fn.exp.html)
/// * [`exp2()`] /// * [`exp2`](fn.exp2.html)
/// * [`inversesqrt()`] /// * [`inversesqrt`](fn.inversesqrt.html)
/// * [`pow`] /// * [`pow`](fn.pow.html)
pub fn sqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn sqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.sqrt()) v.map(|x| x.sqrt())
} }

View File

@ -1,3 +1,5 @@
use na;
use crate::aliases::{TMat4, TVec2, TVec3, TVec4}; use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
use crate::RealNumber; use crate::RealNumber;
@ -39,11 +41,11 @@ pub fn pick_matrix<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project_no()`] /// * [`project_no`](fn.project_no.html)
/// * [`project_zo()`] /// * [`project_zo`](fn.project_zo.html)
/// * [`unproject()`] /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no()`] /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo()`] /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn project<T: RealNumber>( pub fn project<T: RealNumber>(
obj: &TVec3<T>, obj: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,
@ -66,11 +68,11 @@ pub fn project<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project()`] /// * [`project`](fn.project.html)
/// * [`project_zo()`] /// * [`project_zo`](fn.project_zo.html)
/// * [`unproject()`] /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no()`] /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo()`] /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn project_no<T: RealNumber>( pub fn project_no<T: RealNumber>(
obj: &TVec3<T>, obj: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,
@ -94,11 +96,11 @@ pub fn project_no<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project()`] /// * [`project`](fn.project.html)
/// * [`project_no()`] /// * [`project_no`](fn.project_no.html)
/// * [`unproject()`] /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no()`] /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo()`] /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn project_zo<T: RealNumber>( pub fn project_zo<T: RealNumber>(
obj: &TVec3<T>, obj: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,
@ -127,11 +129,11 @@ pub fn project_zo<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project()`] /// * [`project`](fn.project.html)
/// * [`project_no()`] /// * [`project_no`](fn.project_no.html)
/// * [`project_zo()`] /// * [`project_zo`](fn.project_zo.html)
/// * [`unproject_no()`] /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo()`] /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn unproject<T: RealNumber>( pub fn unproject<T: RealNumber>(
win: &TVec3<T>, win: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,
@ -154,11 +156,11 @@ pub fn unproject<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project()`] /// * [`project`](fn.project.html)
/// * [`project_no()`] /// * [`project_no`](fn.project_no.html)
/// * [`project_zo()`] /// * [`project_zo`](fn.project_zo.html)
/// * [`unproject()`] /// * [`unproject`](fn.unproject.html)
/// * [`unproject_zo()`] /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn unproject_no<T: RealNumber>( pub fn unproject_no<T: RealNumber>(
win: &TVec3<T>, win: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,
@ -191,11 +193,11 @@ pub fn unproject_no<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project()`] /// * [`project`](fn.project.html)
/// * [`project_no()`] /// * [`project_no`](fn.project_no.html)
/// * [`project_zo()`] /// * [`project_zo`](fn.project_zo.html)
/// * [`unproject()`] /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no()`] /// * [`unproject_no`](fn.unproject_no.html)
pub fn unproject_zo<T: RealNumber>( pub fn unproject_zo<T: RealNumber>(
win: &TVec3<T>, win: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,

View File

@ -18,8 +18,8 @@ pub fn identity<T: Number, const D: usize>() -> TMat<T, D, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`look_at_lh()`] /// * [`look_at_lh`](fn.look_at_lh.html)
/// * [`look_at_rh()`] /// * [`look_at_rh`](fn.look_at_rh.html)
pub fn look_at<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> { pub fn look_at<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
look_at_rh(eye, center, up) look_at_rh(eye, center, up)
} }
@ -34,8 +34,8 @@ pub fn look_at<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>)
/// ///
/// # See also: /// # See also:
/// ///
/// * [`look_at()`] /// * [`look_at`](fn.look_at.html)
/// * [`look_at_rh()`] /// * [`look_at_rh`](fn.look_at_rh.html)
pub fn look_at_lh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> { pub fn look_at_lh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up) TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up)
} }
@ -50,8 +50,8 @@ pub fn look_at_lh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`look_at()`] /// * [`look_at`](fn.look_at.html)
/// * [`look_at_lh()`] /// * [`look_at_lh`](fn.look_at_lh.html)
pub fn look_at_rh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> { pub fn look_at_rh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up) TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up)
} }
@ -66,11 +66,11 @@ pub fn look_at_rh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate_x()`] /// * [`rotate_x`](fn.rotate_x.html)
/// * [`rotate_y()`] /// * [`rotate_y`](fn.rotate_y.html)
/// * [`rotate_z()`] /// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale()`] /// * [`scale`](fn.scale.html)
/// * [`translate()`] /// * [`translate`](fn.translate.html)
pub fn rotate<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> { pub fn rotate<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous() m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous()
} }
@ -84,11 +84,11 @@ pub fn rotate<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate()`] /// * [`rotate`](fn.rotate.html)
/// * [`rotate_y()`] /// * [`rotate_y`](fn.rotate_y.html)
/// * [`rotate_z()`] /// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale()`] /// * [`scale`](fn.scale.html)
/// * [`translate()`] /// * [`translate`](fn.translate.html)
pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> { pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::x()) rotate(m, angle, &TVec::x())
} }
@ -102,11 +102,11 @@ pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate()`] /// * [`rotate`](fn.rotate.html)
/// * [`rotate_x()`] /// * [`rotate_x`](fn.rotate_x.html)
/// * [`rotate_z()`] /// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale()`] /// * [`scale`](fn.scale.html)
/// * [`translate()`] /// * [`translate`](fn.translate.html)
pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> { pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::y()) rotate(m, angle, &TVec::y())
} }
@ -120,11 +120,11 @@ pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate()`] /// * [`rotate`](fn.rotate.html)
/// * [`rotate_x()`] /// * [`rotate_x`](fn.rotate_x.html)
/// * [`rotate_y()`] /// * [`rotate_y`](fn.rotate_y.html)
/// * [`scale()`] /// * [`scale`](fn.scale.html)
/// * [`translate()`] /// * [`translate`](fn.translate.html)
pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> { pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::z()) rotate(m, angle, &TVec::z())
} }
@ -138,11 +138,11 @@ pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate()`] /// * [`rotate`](fn.rotate.html)
/// * [`rotate_x()`] /// * [`rotate_x`](fn.rotate_x.html)
/// * [`rotate_y()`] /// * [`rotate_y`](fn.rotate_y.html)
/// * [`rotate_z()`] /// * [`rotate_z`](fn.rotate_z.html)
/// * [`translate()`] /// * [`translate`](fn.translate.html)
pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> { pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
m.prepend_nonuniform_scaling(v) m.prepend_nonuniform_scaling(v)
} }
@ -156,11 +156,11 @@ pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate()`] /// * [`rotate`](fn.rotate.html)
/// * [`rotate_x()`] /// * [`rotate_x`](fn.rotate_x.html)
/// * [`rotate_y()`] /// * [`rotate_y`](fn.rotate_y.html)
/// * [`rotate_z()`] /// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale()`] /// * [`scale`](fn.scale.html)
pub fn translate<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> { pub fn translate<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
m.prepend_translation(v) m.prepend_translation(v)
} }

View File

@ -1,4 +1,4 @@
use na::Unit; use na::{self, Unit};
use crate::aliases::Qua; use crate::aliases::Qua;
use crate::RealNumber; use crate::RealNumber;

View File

@ -12,9 +12,9 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max4_scalar()`] /// * [`max4_scalar`](fn.max4_scalar.html)
/// * [`min3_scalar()`] /// * [`min3_scalar`](fn.min3_scalar.html)
/// * [`min4_scalar()`] /// * [`min4_scalar`](fn.min4_scalar.html)
pub fn max2_scalar<T: Number>(a: T, b: T) -> T { pub fn max2_scalar<T: Number>(a: T, b: T) -> T {
if a >= b { if a >= b {
a a
@ -35,9 +35,9 @@ pub fn max2_scalar<T: Number>(a: T, b: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max4_scalar()`] /// * [`max4_scalar`](fn.max4_scalar.html)
/// * [`min3_scalar()`] /// * [`min3_scalar`](fn.min3_scalar.html)
/// * [`min4_scalar()`] /// * [`min4_scalar`](fn.min4_scalar.html)
pub fn min2_scalar<T: Number>(a: T, b: T) -> T { pub fn min2_scalar<T: Number>(a: T, b: T) -> T {
if a <= b { if a <= b {
a a
@ -58,9 +58,9 @@ pub fn min2_scalar<T: Number>(a: T, b: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max4_scalar()`] /// * [`max4_scalar`](fn.max4_scalar.html)
/// * [`min3_scalar()`] /// * [`min3_scalar`](fn.min3_scalar.html)
/// * [`min4_scalar()`] /// * [`min4_scalar`](fn.min4_scalar.html)
pub fn max3_scalar<T: Number>(a: T, b: T, c: T) -> T { pub fn max3_scalar<T: Number>(a: T, b: T, c: T) -> T {
max2_scalar(max2_scalar(a, b), c) max2_scalar(max2_scalar(a, b), c)
} }
@ -77,9 +77,9 @@ pub fn max3_scalar<T: Number>(a: T, b: T, c: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max3_scalar()`] /// * [`max3_scalar`](fn.max3_scalar.html)
/// * [`min3_scalar()`] /// * [`min3_scalar`](fn.min3_scalar.html)
/// * [`min4_scalar()`] /// * [`min4_scalar`](fn.min4_scalar.html)
pub fn max4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T { pub fn max4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
max2_scalar(max2_scalar(a, b), max2_scalar(c, d)) max2_scalar(max2_scalar(a, b), max2_scalar(c, d))
} }
@ -96,9 +96,9 @@ pub fn max4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max3_scalar()`] /// * [`max3_scalar`](fn.max3_scalar.html)
/// * [`max4_scalar()`] /// * [`max4_scalar`](fn.max4_scalar.html)
/// * [`min4_scalar()`] /// * [`min4_scalar`](fn.min4_scalar.html)
pub fn min3_scalar<T: Number>(a: T, b: T, c: T) -> T { pub fn min3_scalar<T: Number>(a: T, b: T, c: T) -> T {
min2_scalar(min2_scalar(a, b), c) min2_scalar(min2_scalar(a, b), c)
} }
@ -115,9 +115,9 @@ pub fn min3_scalar<T: Number>(a: T, b: T, c: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max3_scalar()`] /// * [`max3_scalar`](fn.max3_scalar.html)
/// * [`max4_scalar()`] /// * [`max4_scalar`](fn.max4_scalar.html)
/// * [`min3_scalar()`] /// * [`min3_scalar`](fn.min3_scalar.html)
pub fn min4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T { pub fn min4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
min2_scalar(min2_scalar(a, b), min2_scalar(c, d)) min2_scalar(min2_scalar(a, b), min2_scalar(c, d))
} }

View File

@ -10,18 +10,18 @@ pub fn epsilon<T: AbsDiffEq<Epsilon = T>>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`](crate::four_over_pi) /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`half_pi()`](crate::half_pi) /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_pi()`](crate::one_over_pi) /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`one_over_two_pi()`](crate::one_over_two_pi) /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`quarter_pi()`](crate::quarter_pi) /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`root_half_pi()`](crate::root_half_pi) /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_pi()`](crate::root_pi) /// * [`root_pi`](fn.root_pi.html)
/// * [`root_two_pi()`](crate::root_two_pi) /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`three_over_two_pi()`](crate::three_over_two_pi) /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi()`](crate::two_over_pi) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi()`](crate::two_over_root_pi) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi()`](crate::two_pi) /// * [`two_pi`](fn.two_pi.html)
pub fn pi<T: RealNumber>() -> T { pub fn pi<T: RealNumber>() -> T {
T::pi() T::pi()
} }

View File

@ -5,15 +5,15 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max()`](crate::comp_max) /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min()`](crate::comp_min) /// * [`comp_min`](fn.comp_min.html)
/// * [`max2()`] /// * [`max2`](fn.max2.html)
/// * [`max3()`] /// * [`max3`](fn.max3.html)
/// * [`max4()`] /// * [`max4`](fn.max4.html)
/// * [`min()`] /// * [`min`](fn.min.html)
/// * [`min2()`] /// * [`min2`](fn.min2.html)
/// * [`min3()`] /// * [`min3`](fn.min3.html)
/// * [`min4()`] /// * [`min4`](fn.min4.html)
pub fn max<T: Number, const D: usize>(a: &TVec<T, D>, b: T) -> TVec<T, D> { pub fn max<T: Number, const D: usize>(a: &TVec<T, D>, b: T) -> TVec<T, D> {
a.map(|a| crate::max2_scalar(a, b)) a.map(|a| crate::max2_scalar(a, b))
} }
@ -22,15 +22,15 @@ pub fn max<T: Number, const D: usize>(a: &TVec<T, D>, b: T) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max()`](crate::comp_max) /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min()`](crate::comp_min) /// * [`comp_min`](fn.comp_min.html)
/// * [`max()`] /// * [`max`](fn.max.html)
/// * [`max3()`] /// * [`max3`](fn.max3.html)
/// * [`max4()`] /// * [`max4`](fn.max4.html)
/// * [`min()`] /// * [`min`](fn.min.html)
/// * [`min2()`] /// * [`min2`](fn.min2.html)
/// * [`min3()`] /// * [`min3`](fn.min3.html)
/// * [`min4()`] /// * [`min4`](fn.min4.html)
pub fn max2<T: Number, const D: usize>(a: &TVec<T, D>, b: &TVec<T, D>) -> TVec<T, D> { pub fn max2<T: Number, const D: usize>(a: &TVec<T, D>, b: &TVec<T, D>) -> TVec<T, D> {
a.zip_map(b, |a, b| crate::max2_scalar(a, b)) a.zip_map(b, |a, b| crate::max2_scalar(a, b))
} }
@ -39,15 +39,15 @@ pub fn max2<T: Number, const D: usize>(a: &TVec<T, D>, b: &TVec<T, D>) -> TVec<T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max()`](crate::comp_max) /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min()`](crate::comp_min) /// * [`comp_min`](fn.comp_min.html)
/// * [`max()`] /// * [`max`](fn.max.html)
/// * [`max2()`] /// * [`max2`](fn.max2.html)
/// * [`max4()`] /// * [`max4`](fn.max4.html)
/// * [`min()`] /// * [`min`](fn.min.html)
/// * [`min2()`] /// * [`min2`](fn.min2.html)
/// * [`min3()`] /// * [`min3`](fn.min3.html)
/// * [`min4()`] /// * [`min4`](fn.min4.html)
pub fn max3<T: Number, const D: usize>( pub fn max3<T: Number, const D: usize>(
a: &TVec<T, D>, a: &TVec<T, D>,
b: &TVec<T, D>, b: &TVec<T, D>,
@ -60,15 +60,15 @@ pub fn max3<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max()`](crate::comp_max) /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min()`](crate::comp_min) /// * [`comp_min`](fn.comp_min.html)
/// * [`max()`] /// * [`max`](fn.max.html)
/// * [`max2()`] /// * [`max2`](fn.max2.html)
/// * [`max3()`] /// * [`max3`](fn.max3.html)
/// * [`min()`] /// * [`min`](fn.min.html)
/// * [`min2()`] /// * [`min2`](fn.min2.html)
/// * [`min3()`] /// * [`min3`](fn.min3.html)
/// * [`min4()`] /// * [`min4`](fn.min4.html)
pub fn max4<T: Number, const D: usize>( pub fn max4<T: Number, const D: usize>(
a: &TVec<T, D>, a: &TVec<T, D>,
b: &TVec<T, D>, b: &TVec<T, D>,
@ -82,15 +82,15 @@ pub fn max4<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max()`](crate::comp_max) /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min()`](crate::comp_min) /// * [`comp_min`](fn.comp_min.html)
/// * [`max()`] /// * [`max`](fn.max.html)
/// * [`max2()`] /// * [`max2`](fn.max2.html)
/// * [`max3()`] /// * [`max3`](fn.max3.html)
/// * [`max4()`] /// * [`max4`](fn.max4.html)
/// * [`min2()`] /// * [`min2`](fn.min2.html)
/// * [`min3()`] /// * [`min3`](fn.min3.html)
/// * [`min4()`] /// * [`min4`](fn.min4.html)
pub fn min<T: Number, const D: usize>(x: &TVec<T, D>, y: T) -> TVec<T, D> { pub fn min<T: Number, const D: usize>(x: &TVec<T, D>, y: T) -> TVec<T, D> {
x.map(|x| crate::min2_scalar(x, y)) x.map(|x| crate::min2_scalar(x, y))
} }
@ -99,15 +99,15 @@ pub fn min<T: Number, const D: usize>(x: &TVec<T, D>, y: T) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max()`](crate::comp_max) /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min()`](crate::comp_min) /// * [`comp_min`](fn.comp_min.html)
/// * [`max()`] /// * [`max`](fn.max.html)
/// * [`max2()`] /// * [`max2`](fn.max2.html)
/// * [`max3()`] /// * [`max3`](fn.max3.html)
/// * [`max4()`] /// * [`max4`](fn.max4.html)
/// * [`min()`] /// * [`min`](fn.min.html)
/// * [`min3()`] /// * [`min3`](fn.min3.html)
/// * [`min4()`] /// * [`min4`](fn.min4.html)
pub fn min2<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> { pub fn min2<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
x.zip_map(y, |a, b| crate::min2_scalar(a, b)) x.zip_map(y, |a, b| crate::min2_scalar(a, b))
} }
@ -116,15 +116,15 @@ pub fn min2<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max()`](crate::comp_max) /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min()`](crate::comp_min) /// * [`comp_min`](fn.comp_min.html)
/// * [`max()`] /// * [`max`](fn.max.html)
/// * [`max2()`] /// * [`max2`](fn.max2.html)
/// * [`max3()`] /// * [`max3`](fn.max3.html)
/// * [`max4()`] /// * [`max4`](fn.max4.html)
/// * [`min()`] /// * [`min`](fn.min.html)
/// * [`min2()`] /// * [`min2`](fn.min2.html)
/// * [`min4()`] /// * [`min4`](fn.min4.html)
pub fn min3<T: Number, const D: usize>( pub fn min3<T: Number, const D: usize>(
a: &TVec<T, D>, a: &TVec<T, D>,
b: &TVec<T, D>, b: &TVec<T, D>,
@ -137,15 +137,15 @@ pub fn min3<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max()`](crate::comp_max) /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min()`](crate::comp_min) /// * [`comp_min`](fn.comp_min.html)
/// * [`max()`] /// * [`max`](fn.max.html)
/// * [`max2()`] /// * [`max2`](fn.max2.html)
/// * [`max3()`] /// * [`max3`](fn.max3.html)
/// * [`max4()`] /// * [`max4`](fn.max4.html)
/// * [`min()`] /// * [`min`](fn.min.html)
/// * [`min2()`] /// * [`min2`](fn.min2.html)
/// * [`min3()`] /// * [`min3`](fn.min3.html)
pub fn min4<T: Number, const D: usize>( pub fn min4<T: Number, const D: usize>(
a: &TVec<T, D>, a: &TVec<T, D>,
b: &TVec<T, D>, b: &TVec<T, D>,

View File

@ -5,9 +5,9 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal_eps_vec()`] /// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps()`] /// * [`not_equal_eps`](fn.not_equal_eps.html)
/// * [`not_equal_eps_vec()`] /// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn equal_eps<T: Number, const D: usize>( pub fn equal_eps<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
@ -20,9 +20,9 @@ pub fn equal_eps<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal_eps()`] /// * [`equal_eps`](fn.equal_eps.html)
/// * [`not_equal_eps()`] /// * [`not_equal_eps`](fn.not_equal_eps.html)
/// * [`not_equal_eps_vec()`] /// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn equal_eps_vec<T: Number, const D: usize>( pub fn equal_eps_vec<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
@ -35,9 +35,9 @@ pub fn equal_eps_vec<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal_eps()`] /// * [`equal_eps`](fn.equal_eps.html)
/// * [`equal_eps_vec()`] /// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps_vec()`] /// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn not_equal_eps<T: Number, const D: usize>( pub fn not_equal_eps<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
@ -50,9 +50,9 @@ pub fn not_equal_eps<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal_eps()`] /// * [`equal_eps`](fn.equal_eps.html)
/// * [`equal_eps_vec()`] /// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps()`] /// * [`not_equal_eps`](fn.not_equal_eps.html)
pub fn not_equal_eps_vec<T: Number, const D: usize>( pub fn not_equal_eps_vec<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,

View File

@ -12,7 +12,7 @@ pub fn cross<T: Number>(x: &TVec3<T>, y: &TVec3<T>) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`distance2()`](crate::distance2) /// * [`distance2`](fn.distance2.html)
pub fn distance<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T { pub fn distance<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
(p1 - p0).norm() (p1 - p0).norm()
} }
@ -37,13 +37,13 @@ pub fn faceforward<T: Number, const D: usize>(
/// The magnitude of a vector. /// The magnitude of a vector.
/// ///
/// A synonym for [`magnitude()`]. /// A synonym for [`magnitude`](fn.magnitude.html).
/// ///
/// # See also: /// # See also:
/// ///
/// * [`length2()`](crate::length2) /// * [`length2`](fn.length2.html)
/// * [`magnitude()`] /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2()`](crate::magnitude2) /// * [`magnitude2`](fn.magnitude2.html)
pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T { pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm() x.norm()
} }
@ -54,8 +54,8 @@ pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`length()`] /// * [`length`](fn.length.html)
/// * [`magnitude2()`](crate::magnitude2) /// * [`magnitude2`](fn.magnitude2.html)
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html) /// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
pub fn magnitude<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T { pub fn magnitude<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm() x.norm()

View File

@ -1,8 +1,9 @@
use crate::RealNumber; use crate::RealNumber;
use na;
/// The Euler constant. /// The Euler constant.
/// ///
/// This is a shorthand alias for [`euler()`]. /// This is a shorthand alias for [`euler`](fn.euler.html).
pub fn e<T: RealNumber>() -> T { pub fn e<T: RealNumber>() -> T {
T::e() T::e()
} }
@ -16,18 +17,18 @@ pub fn euler<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`half_pi()`] /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_pi()`] /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`one_over_two_pi()`] /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`pi()`](crate::pi) /// * [`pi`](fn.pi.html)
/// * [`quarter_pi()`] /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`root_half_pi()`] /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_pi()`] /// * [`root_pi`](fn.root_pi.html)
/// * [`root_two_pi()`] /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`three_over_two_pi()`] /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi()`] /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi()`] /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi()`] /// * [`two_pi`](fn.two_pi.html)
pub fn four_over_pi<T: RealNumber>() -> T { pub fn four_over_pi<T: RealNumber>() -> T {
na::convert::<_, T>(4.0) / T::pi() na::convert::<_, T>(4.0) / T::pi()
} }
@ -41,18 +42,18 @@ pub fn golden_ratio<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`] /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`one_over_pi()`] /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`one_over_two_pi()`] /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`pi()`](crate::pi) /// * [`pi`](fn.pi.html)
/// * [`quarter_pi()`] /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`root_half_pi()`] /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_pi()`] /// * [`root_pi`](fn.root_pi.html)
/// * [`root_two_pi()`] /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`three_over_two_pi()`] /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi()`] /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi()`] /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi()`] /// * [`two_pi`](fn.two_pi.html)
pub fn half_pi<T: RealNumber>() -> T { pub fn half_pi<T: RealNumber>() -> T {
T::frac_pi_2() T::frac_pi_2()
} }
@ -61,8 +62,8 @@ pub fn half_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ln_ten()`] /// * [`ln_ten`](fn.ln_ten.html)
/// * [`ln_two()`] /// * [`ln_two`](fn.ln_two.html)
pub fn ln_ln_two<T: RealNumber>() -> T { pub fn ln_ln_two<T: RealNumber>() -> T {
T::ln_2().ln() T::ln_2().ln()
} }
@ -71,8 +72,8 @@ pub fn ln_ln_two<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ln_ln_two()`] /// * [`ln_ln_two`](fn.ln_ln_two.html)
/// * [`ln_two()`] /// * [`ln_two`](fn.ln_two.html)
pub fn ln_ten<T: RealNumber>() -> T { pub fn ln_ten<T: RealNumber>() -> T {
T::ln_10() T::ln_10()
} }
@ -81,8 +82,8 @@ pub fn ln_ten<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ln_ln_two()`] /// * [`ln_ln_two`](fn.ln_ln_two.html)
/// * [`ln_ten()`] /// * [`ln_ten`](fn.ln_ten.html)
pub fn ln_two<T: RealNumber>() -> T { pub fn ln_two<T: RealNumber>() -> T {
T::ln_2() T::ln_2()
} }
@ -94,18 +95,18 @@ pub use na::one;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`] /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`half_pi()`] /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_two_pi()`] /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`pi()`](crate::pi) /// * [`pi`](fn.pi.html)
/// * [`quarter_pi()`] /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`root_half_pi()`] /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_pi()`] /// * [`root_pi`](fn.root_pi.html)
/// * [`root_two_pi()`] /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`three_over_two_pi()`] /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi()`] /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi()`] /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi()`] /// * [`two_pi`](fn.two_pi.html)
pub fn one_over_pi<T: RealNumber>() -> T { pub fn one_over_pi<T: RealNumber>() -> T {
T::frac_1_pi() T::frac_1_pi()
} }
@ -119,18 +120,18 @@ pub fn one_over_root_two<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`] /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`half_pi()`] /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_pi()`] /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`pi()`](crate::pi) /// * [`pi`](fn.pi.html)
/// * [`quarter_pi()`] /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`root_half_pi()`] /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_pi()`] /// * [`root_pi`](fn.root_pi.html)
/// * [`root_two_pi()`] /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`three_over_two_pi()`] /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi()`] /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi()`] /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi()`] /// * [`two_pi`](fn.two_pi.html)
pub fn one_over_two_pi<T: RealNumber>() -> T { pub fn one_over_two_pi<T: RealNumber>() -> T {
T::frac_1_pi() * na::convert(0.5) T::frac_1_pi() * na::convert(0.5)
} }
@ -139,18 +140,18 @@ pub fn one_over_two_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`] /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`half_pi()`] /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_pi()`] /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`one_over_two_pi()`] /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`pi()`](crate::pi) /// * [`pi`](fn.pi.html)
/// * [`root_half_pi()`] /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_pi()`] /// * [`root_pi`](fn.root_pi.html)
/// * [`root_two_pi()`] /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`three_over_two_pi()`] /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi()`] /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi()`] /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi()`] /// * [`two_pi`](fn.two_pi.html)
pub fn quarter_pi<T: RealNumber>() -> T { pub fn quarter_pi<T: RealNumber>() -> T {
T::frac_pi_4() T::frac_pi_4()
} }
@ -159,8 +160,8 @@ pub fn quarter_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`root_three()`] /// * [`root_three`](fn.root_three.html)
/// * [`root_two()`] /// * [`root_two`](fn.root_two.html)
pub fn root_five<T: RealNumber>() -> T { pub fn root_five<T: RealNumber>() -> T {
na::convert::<_, T>(5.0).sqrt() na::convert::<_, T>(5.0).sqrt()
} }
@ -169,18 +170,18 @@ pub fn root_five<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`] /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`half_pi()`] /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_pi()`] /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`one_over_two_pi()`] /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`pi()`](crate::pi) /// * [`pi`](fn.pi.html)
/// * [`quarter_pi()`] /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`root_pi()`] /// * [`root_pi`](fn.root_pi.html)
/// * [`root_two_pi()`] /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`three_over_two_pi()`] /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi()`] /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi()`] /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi()`] /// * [`two_pi`](fn.two_pi.html)
pub fn root_half_pi<T: RealNumber>() -> T { pub fn root_half_pi<T: RealNumber>() -> T {
(T::pi() / na::convert(2.0)).sqrt() (T::pi() / na::convert(2.0)).sqrt()
} }
@ -194,18 +195,18 @@ pub fn root_ln_four<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`] /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`half_pi()`] /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_pi()`] /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`one_over_two_pi()`] /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`pi()`](crate::pi) /// * [`pi`](fn.pi.html)
/// * [`quarter_pi()`] /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`root_half_pi()`] /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_two_pi()`] /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`three_over_two_pi()`] /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi()`] /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi()`] /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi()`] /// * [`two_pi`](fn.two_pi.html)
pub fn root_pi<T: RealNumber>() -> T { pub fn root_pi<T: RealNumber>() -> T {
T::pi().sqrt() T::pi().sqrt()
} }
@ -214,8 +215,8 @@ pub fn root_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`root_five()`] /// * [`root_five`](fn.root_five.html)
/// * [`root_two()`] /// * [`root_two`](fn.root_two.html)
pub fn root_three<T: RealNumber>() -> T { pub fn root_three<T: RealNumber>() -> T {
na::convert::<_, T>(3.0).sqrt() na::convert::<_, T>(3.0).sqrt()
} }
@ -224,8 +225,8 @@ pub fn root_three<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`root_five()`] /// * [`root_five`](fn.root_five.html)
/// * [`root_three()`] /// * [`root_three`](fn.root_three.html)
pub fn root_two<T: RealNumber>() -> T { pub fn root_two<T: RealNumber>() -> T {
// TODO: there should be a crate::sqrt_2() on the RealNumber trait. // TODO: there should be a crate::sqrt_2() on the RealNumber trait.
na::convert::<_, T>(2.0).sqrt() na::convert::<_, T>(2.0).sqrt()
@ -235,18 +236,18 @@ pub fn root_two<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`] /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`half_pi()`] /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_pi()`] /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`one_over_two_pi()`] /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`pi()`](crate::pi) /// * [`pi`](fn.pi.html)
/// * [`quarter_pi()`] /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`root_half_pi()`] /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_pi()`] /// * [`root_pi`](fn.root_pi.html)
/// * [`three_over_two_pi()`] /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi()`] /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi()`] /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi()`] /// * [`two_pi`](fn.two_pi.html)
pub fn root_two_pi<T: RealNumber>() -> T { pub fn root_two_pi<T: RealNumber>() -> T {
T::two_pi().sqrt() T::two_pi().sqrt()
} }
@ -255,7 +256,7 @@ pub fn root_two_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`two_thirds()`] /// * [`two_thirds`](fn.two_thirds.html)
pub fn third<T: RealNumber>() -> T { pub fn third<T: RealNumber>() -> T {
na::convert(1.0 / 3.0) na::convert(1.0 / 3.0)
} }
@ -264,18 +265,18 @@ pub fn third<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`] /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`half_pi()`] /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_pi()`] /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`one_over_two_pi()`] /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`pi()`](crate::pi) /// * [`pi`](fn.pi.html)
/// * [`quarter_pi()`] /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`root_half_pi()`] /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_pi()`] /// * [`root_pi`](fn.root_pi.html)
/// * [`root_two_pi()`] /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`two_over_pi()`] /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi()`] /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi()`] /// * [`two_pi`](fn.two_pi.html)
pub fn three_over_two_pi<T: RealNumber>() -> T { pub fn three_over_two_pi<T: RealNumber>() -> T {
na::convert::<_, T>(3.0) / T::two_pi() na::convert::<_, T>(3.0) / T::two_pi()
} }
@ -284,18 +285,17 @@ pub fn three_over_two_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`] /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`half_pi()`] /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_pi()`] /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`one_over_two_pi()`] /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`pi()`](crate::pi) /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`quarter_pi()`] /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_half_pi()`] /// * [`root_pi`](fn.root_pi.html)
/// * [`root_pi()`] /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`root_two_pi()`] /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`three_over_two_pi()`] /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_over_root_pi()`] /// * [`two_pi`](fn.two_pi.html)
/// * [`two_pi()`]
pub fn two_over_pi<T: RealNumber>() -> T { pub fn two_over_pi<T: RealNumber>() -> T {
T::frac_2_pi() T::frac_2_pi()
} }
@ -304,18 +304,18 @@ pub fn two_over_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`] /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`half_pi()`] /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_pi()`] /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`one_over_two_pi()`] /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`pi()`](crate::pi) /// * [`pi`](fn.pi.html)
/// * [`quarter_pi()`] /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`root_half_pi()`] /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_pi()`] /// * [`root_pi`](fn.root_pi.html)
/// * [`root_two_pi()`] /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`three_over_two_pi()`] /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi()`] /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_pi()`] /// * [`two_pi`](fn.two_pi.html)
pub fn two_over_root_pi<T: RealNumber>() -> T { pub fn two_over_root_pi<T: RealNumber>() -> T {
T::frac_2_sqrt_pi() T::frac_2_sqrt_pi()
} }
@ -324,18 +324,18 @@ pub fn two_over_root_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi()`] /// * [`four_over_pi`](fn.four_over_pi.html)
/// * [`half_pi()`] /// * [`half_pi`](fn.half_pi.html)
/// * [`one_over_pi()`] /// * [`one_over_pi`](fn.one_over_pi.html)
/// * [`one_over_two_pi()`] /// * [`one_over_two_pi`](fn.one_over_two_pi.html)
/// * [`pi()`](crate::pi) /// * [`pi`](fn.pi.html)
/// * [`quarter_pi()`] /// * [`quarter_pi`](fn.quarter_pi.html)
/// * [`root_half_pi()`] /// * [`root_half_pi`](fn.root_half_pi.html)
/// * [`root_pi()`] /// * [`root_pi`](fn.root_pi.html)
/// * [`root_two_pi()`] /// * [`root_two_pi`](fn.root_two_pi.html)
/// * [`three_over_two_pi()`] /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi()`] /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi()`] /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
pub fn two_pi<T: RealNumber>() -> T { pub fn two_pi<T: RealNumber>() -> T {
T::two_pi() T::two_pi()
} }
@ -344,7 +344,7 @@ pub fn two_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`third()`] /// * [`third`](fn.third.html)
pub fn two_thirds<T: RealNumber>() -> T { pub fn two_thirds<T: RealNumber>() -> T {
na::convert(2.0 / 3.0) na::convert(2.0 / 3.0)
} }

View File

@ -6,9 +6,9 @@ use crate::aliases::{TMat, TVec};
/// ///
/// # See also: /// # See also:
/// ///
/// * [`row()`] /// * [`row`](fn.row.html)
/// * [`set_column()`] /// * [`set_column`](fn.set_column.html)
/// * [`set_row()`] /// * [`set_row`](fn.set_row.html)
pub fn column<T: Scalar, const R: usize, const C: usize>( pub fn column<T: Scalar, const R: usize, const C: usize>(
m: &TMat<T, R, C>, m: &TMat<T, R, C>,
index: usize, index: usize,
@ -20,9 +20,9 @@ pub fn column<T: Scalar, const R: usize, const C: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`column()`] /// * [`column`](fn.column.html)
/// * [`row()`] /// * [`row`](fn.row.html)
/// * [`set_row()`] /// * [`set_row`](fn.set_row.html)
pub fn set_column<T: Scalar, const R: usize, const C: usize>( pub fn set_column<T: Scalar, const R: usize, const C: usize>(
m: &TMat<T, R, C>, m: &TMat<T, R, C>,
index: usize, index: usize,
@ -37,9 +37,9 @@ pub fn set_column<T: Scalar, const R: usize, const C: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`column()`] /// * [`column`](fn.column.html)
/// * [`set_column()`] /// * [`set_column`](fn.set_column.html)
/// * [`set_row()`] /// * [`set_row`](fn.set_row.html)
pub fn row<T: Scalar, const R: usize, const C: usize>( pub fn row<T: Scalar, const R: usize, const C: usize>(
m: &TMat<T, R, C>, m: &TMat<T, R, C>,
index: usize, index: usize,
@ -51,9 +51,9 @@ pub fn row<T: Scalar, const R: usize, const C: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`column()`] /// * [`column`](fn.column.html)
/// * [`row()`] /// * [`row`](fn.row.html)
/// * [`set_column()`] /// * [`set_column`](fn.set_column.html)
pub fn set_row<T: Scalar, const R: usize, const C: usize>( pub fn set_row<T: Scalar, const R: usize, const C: usize>(
m: &TMat<T, R, C>, m: &TMat<T, R, C>,
index: usize, index: usize,

View File

@ -128,9 +128,9 @@ pub fn make_quat<T: RealNumber>(ptr: &[T]) -> Qua<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`make_vec2()`] /// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec3()`] /// * [`make_vec3`](fn.make_vec3.html)
/// * [`make_vec4()`] /// * [`make_vec4`](fn.make_vec4.html)
pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> { pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
v.clone() v.clone()
} }
@ -139,11 +139,12 @@ pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec3_to_vec1()`] /// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
/// * [`vec4_to_vec1()`] /// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec1_to_vec2()`] /// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// * [`vec1_to_vec3()`] /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec4()`] /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> { pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
TVec1::new(v.x.clone()) TVec1::new(v.x.clone())
} }
@ -152,11 +153,12 @@ pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec2_to_vec1()`] /// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
/// * [`vec4_to_vec1()`] /// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec1_to_vec2()`] /// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// * [`vec1_to_vec3()`] /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec4()`] /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> { pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
TVec1::new(v.x.clone()) TVec1::new(v.x.clone())
} }
@ -165,11 +167,12 @@ pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec2_to_vec1()`] /// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
/// * [`vec3_to_vec1()`] /// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec1_to_vec2()`] /// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec1_to_vec3()`] /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec4()`] /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> { pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
TVec1::new(v.x.clone()) TVec1::new(v.x.clone())
} }
@ -180,12 +183,12 @@ pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec3_to_vec2()`] /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec4_to_vec2()`] /// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1()`] /// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2()`] /// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3()`] /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4()`] /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> { pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
TVec2::new(v.x.clone(), T::zero()) TVec2::new(v.x.clone(), T::zero())
} }
@ -194,13 +197,13 @@ pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec2()`] /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec3_to_vec2()`] /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec4_to_vec2()`] /// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1()`] /// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2()`] /// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3()`] /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4()`] /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> { pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
v.clone() v.clone()
} }
@ -209,12 +212,12 @@ pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec2()`] /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec4_to_vec2()`] /// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1()`] /// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2()`] /// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3()`] /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4()`] /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> { pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
TVec2::new(v.x.clone(), v.y.clone()) TVec2::new(v.x.clone(), v.y.clone())
} }
@ -223,12 +226,12 @@ pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec2()`] /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec3_to_vec2()`] /// * [`vec3_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1()`] /// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2()`] /// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3()`] /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4()`] /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> { pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
TVec2::new(v.x.clone(), v.y.clone()) TVec2::new(v.x.clone(), v.y.clone())
} }
@ -237,9 +240,9 @@ pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`make_vec1()`] /// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec3()`] /// * [`make_vec3`](fn.make_vec3.html)
/// * [`make_vec4()`] /// * [`make_vec4`](fn.make_vec4.html)
pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> { pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
TVec2::from_column_slice(ptr) TVec2::from_column_slice(ptr)
} }
@ -250,11 +253,11 @@ pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec2_to_vec3()`] /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec3_to_vec3()`] /// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
/// * [`vec4_to_vec3()`] /// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`vec1_to_vec2()`] /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec4()`] /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> { pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
TVec3::new(v.x.clone(), T::zero(), T::zero()) TVec3::new(v.x.clone(), T::zero(), T::zero())
} }
@ -265,12 +268,12 @@ pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec3()`] /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec3_to_vec3()`] /// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
/// * [`vec4_to_vec3()`] /// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`vec3_to_vec1()`] /// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2()`] /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4()`] /// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> { pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
TVec3::new(v.x.clone(), v.y.clone(), T::zero()) TVec3::new(v.x.clone(), v.y.clone(), T::zero())
} }
@ -279,12 +282,12 @@ pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec3()`] /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec2_to_vec3()`] /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec4_to_vec3()`] /// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`vec3_to_vec1()`] /// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2()`] /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4()`] /// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> { pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
v.clone() v.clone()
} }
@ -293,12 +296,12 @@ pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec3()`] /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec2_to_vec3()`] /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec3_to_vec3()`] /// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
/// * [`vec3_to_vec1()`] /// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2()`] /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4()`] /// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> { pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
TVec3::new(v.x.clone(), v.y.clone(), v.z.clone()) TVec3::new(v.x.clone(), v.y.clone(), v.z.clone())
} }
@ -307,9 +310,9 @@ pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`make_vec1()`] /// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec2()`] /// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec4()`] /// * [`make_vec4`](fn.make_vec4.html)
pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> { pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
TVec3::from_column_slice(ptr) TVec3::from_column_slice(ptr)
} }
@ -320,12 +323,12 @@ pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec2_to_vec4()`] /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec3_to_vec4()`] /// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec4_to_vec4()`] /// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
/// * [`vec1_to_vec2()`] /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec3()`] /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4()`] /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> { pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> {
TVec4::new(v.x, T::zero(), T::zero(), T::zero()) TVec4::new(v.x, T::zero(), T::zero(), T::zero())
} }
@ -336,12 +339,12 @@ pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec4()`] /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec3_to_vec4()`] /// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec4_to_vec4()`] /// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
/// * [`vec2_to_vec1()`] /// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2()`] /// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3()`] /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> { pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> {
TVec4::new(v.x, v.y, T::zero(), T::zero()) TVec4::new(v.x, v.y, T::zero(), T::zero())
} }
@ -352,12 +355,12 @@ pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec4()`] /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec4()`] /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec4_to_vec4()`] /// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
/// * [`vec3_to_vec1()`] /// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2()`] /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec3()`] /// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> { pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> {
TVec4::new(v.x, v.y, v.z, T::zero()) TVec4::new(v.x, v.y, v.z, T::zero())
} }
@ -366,12 +369,12 @@ pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec4()`] /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec4()`] /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec3_to_vec4()`] /// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec4_to_vec1()`] /// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// * [`vec4_to_vec2()`] /// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec4_to_vec3()`] /// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> { pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
v.clone() v.clone()
} }
@ -380,9 +383,9 @@ pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`make_vec1()`] /// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec2()`] /// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec3()`] /// * [`make_vec3`](fn.make_vec3.html)
pub fn make_vec4<T: Scalar>(ptr: &[T]) -> TVec4<T> { pub fn make_vec4<T: Scalar>(ptr: &[T]) -> TVec4<T> {
TVec4::from_column_slice(ptr) TVec4::from_column_slice(ptr)
} }

View File

@ -16,9 +16,9 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max()`] /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min()`] /// * [`comp_min`](fn.comp_min.html)
/// * [`comp_mul()`] /// * [`comp_mul`](fn.comp_mul.html)
pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T { pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter().fold(T::zero(), |x, y| x + *y) m.iter().fold(T::zero(), |x, y| x + *y)
} }
@ -38,13 +38,13 @@ pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) ->
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_add()`] /// * [`comp_add`](fn.comp_add.html)
/// * [`comp_max()`] /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min()`] /// * [`comp_min`](fn.comp_min.html)
/// * [`max()`](crate::max) /// * [`max`](fn.max.html)
/// * [`max2()`](crate::max2) /// * [`max2`](fn.max2.html)
/// * [`max3()`](crate::max3) /// * [`max3`](fn.max3.html)
/// * [`max4()`](crate::max4) /// * [`max4`](fn.max4.html)
pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T { pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter() m.iter()
.fold(T::min_value(), |x, y| crate::max2_scalar(x, *y)) .fold(T::min_value(), |x, y| crate::max2_scalar(x, *y))
@ -65,13 +65,13 @@ pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) ->
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_add()`] /// * [`comp_add`](fn.comp_add.html)
/// * [`comp_max()`] /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_mul()`] /// * [`comp_mul`](fn.comp_mul.html)
/// * [`min()`](crate::min) /// * [`min`](fn.min.html)
/// * [`min2()`](crate::min2) /// * [`min2`](fn.min2.html)
/// * [`min3()`](crate::min3) /// * [`min3`](fn.min3.html)
/// * [`min4()`](crate::min4) /// * [`min4`](fn.min4.html)
pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T { pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter() m.iter()
.fold(T::max_value(), |x, y| crate::min2_scalar(x, *y)) .fold(T::max_value(), |x, y| crate::min2_scalar(x, *y))
@ -92,9 +92,9 @@ pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) ->
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_add()`] /// * [`comp_add`](fn.comp_add.html)
/// * [`comp_max()`] /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min()`] /// * [`comp_min`](fn.comp_min.html)
pub fn comp_mul<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T { pub fn comp_mul<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter().fold(T::one(), |x, y| x * *y) m.iter().fold(T::one(), |x, y| x * *y)
} }

View File

@ -5,7 +5,7 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`right_handed()`] /// * [`right_handed`](fn.right_handed.html)
pub fn left_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool { pub fn left_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
a.cross(b).dot(c) < T::zero() a.cross(b).dot(c) < T::zero()
} }
@ -14,7 +14,7 @@ pub fn left_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool
/// ///
/// # See also: /// # See also:
/// ///
/// * [`left_handed()`] /// * [`left_handed`](fn.left_handed.html)
pub fn right_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool { pub fn right_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
a.cross(b).dot(c) > T::zero() a.cross(b).dot(c) > T::zero()
} }

View File

@ -5,7 +5,7 @@ use crate::RealNumber;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`matrix_cross()`] /// * [`matrix_cross`](fn.matrix_cross.html)
pub fn matrix_cross3<T: RealNumber>(x: &TVec3<T>) -> TMat3<T> { pub fn matrix_cross3<T: RealNumber>(x: &TVec3<T>) -> TMat3<T> {
x.cross_matrix() x.cross_matrix()
} }
@ -14,7 +14,7 @@ pub fn matrix_cross3<T: RealNumber>(x: &TVec3<T>) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`matrix_cross3()`] /// * [`matrix_cross3`](fn.matrix_cross3.html)
pub fn matrix_cross<T: RealNumber>(x: &TVec3<T>) -> TMat4<T> { pub fn matrix_cross<T: RealNumber>(x: &TVec3<T>) -> TMat4<T> {
crate::mat3_to_mat4(&x.cross_matrix()) crate::mat3_to_mat4(&x.cross_matrix())
} }

View File

@ -7,14 +7,14 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x3()`] /// * [`diagonal2x3`](fn.diagonal2x3.html)
/// * [`diagonal2x4()`] /// * [`diagonal2x4`](fn.diagonal2x4.html)
/// * [`diagonal3x2()`] /// * [`diagonal3x2`](fn.diagonal3x2.html)
/// * [`diagonal3x3()`] /// * [`diagonal3x3`](fn.diagonal3x3.html)
/// * [`diagonal3x4()`] /// * [`diagonal3x4`](fn.diagonal3x4.html)
/// * [`diagonal4x2()`] /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3()`] /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4()`] /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal2x2<T: Number>(v: &TVec2<T>) -> TMat2<T> { pub fn diagonal2x2<T: Number>(v: &TVec2<T>) -> TMat2<T> {
TMat2::from_diagonal(v) TMat2::from_diagonal(v)
} }
@ -23,14 +23,14 @@ pub fn diagonal2x2<T: Number>(v: &TVec2<T>) -> TMat2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2()`] /// * [`diagonal2x2`](fn.diagonal2x2.html)
/// * [`diagonal2x4()`] /// * [`diagonal2x4`](fn.diagonal2x4.html)
/// * [`diagonal3x2()`] /// * [`diagonal3x2`](fn.diagonal3x2.html)
/// * [`diagonal3x3()`] /// * [`diagonal3x3`](fn.diagonal3x3.html)
/// * [`diagonal3x4()`] /// * [`diagonal3x4`](fn.diagonal3x4.html)
/// * [`diagonal4x2()`] /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3()`] /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4()`] /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal2x3<T: Number>(v: &TVec2<T>) -> TMat2x3<T> { pub fn diagonal2x3<T: Number>(v: &TVec2<T>) -> TMat2x3<T> {
TMat2x3::from_partial_diagonal(v.as_slice()) TMat2x3::from_partial_diagonal(v.as_slice())
} }
@ -39,14 +39,14 @@ pub fn diagonal2x3<T: Number>(v: &TVec2<T>) -> TMat2x3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2()`] /// * [`diagonal2x2`](fn.diagonal2x2.html)
/// * [`diagonal2x3()`] /// * [`diagonal2x3`](fn.diagonal2x3.html)
/// * [`diagonal3x2()`] /// * [`diagonal3x2`](fn.diagonal3x2.html)
/// * [`diagonal3x3()`] /// * [`diagonal3x3`](fn.diagonal3x3.html)
/// * [`diagonal3x4()`] /// * [`diagonal3x4`](fn.diagonal3x4.html)
/// * [`diagonal4x2()`] /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3()`] /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4()`] /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal2x4<T: Number>(v: &TVec2<T>) -> TMat2x4<T> { pub fn diagonal2x4<T: Number>(v: &TVec2<T>) -> TMat2x4<T> {
TMat2x4::from_partial_diagonal(v.as_slice()) TMat2x4::from_partial_diagonal(v.as_slice())
} }
@ -55,14 +55,14 @@ pub fn diagonal2x4<T: Number>(v: &TVec2<T>) -> TMat2x4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2()`] /// * [`diagonal2x2`](fn.diagonal2x2.html)
/// * [`diagonal2x3()`] /// * [`diagonal2x3`](fn.diagonal2x3.html)
/// * [`diagonal2x4()`] /// * [`diagonal2x4`](fn.diagonal2x4.html)
/// * [`diagonal3x3()`] /// * [`diagonal3x3`](fn.diagonal3x3.html)
/// * [`diagonal3x4()`] /// * [`diagonal3x4`](fn.diagonal3x4.html)
/// * [`diagonal4x2()`] /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3()`] /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4()`] /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal3x2<T: Number>(v: &TVec2<T>) -> TMat3x2<T> { pub fn diagonal3x2<T: Number>(v: &TVec2<T>) -> TMat3x2<T> {
TMat3x2::from_partial_diagonal(v.as_slice()) TMat3x2::from_partial_diagonal(v.as_slice())
} }
@ -71,14 +71,14 @@ pub fn diagonal3x2<T: Number>(v: &TVec2<T>) -> TMat3x2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2()`] /// * [`diagonal2x2`](fn.diagonal2x2.html)
/// * [`diagonal2x3()`] /// * [`diagonal2x3`](fn.diagonal2x3.html)
/// * [`diagonal2x4()`] /// * [`diagonal2x4`](fn.diagonal2x4.html)
/// * [`diagonal3x2()`] /// * [`diagonal3x2`](fn.diagonal3x2.html)
/// * [`diagonal3x4()`] /// * [`diagonal3x4`](fn.diagonal3x4.html)
/// * [`diagonal4x2()`] /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3()`] /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4()`] /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal3x3<T: Number>(v: &TVec3<T>) -> TMat3<T> { pub fn diagonal3x3<T: Number>(v: &TVec3<T>) -> TMat3<T> {
TMat3::from_diagonal(v) TMat3::from_diagonal(v)
} }
@ -87,14 +87,14 @@ pub fn diagonal3x3<T: Number>(v: &TVec3<T>) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2()`] /// * [`diagonal2x2`](fn.diagonal2x2.html)
/// * [`diagonal2x3()`] /// * [`diagonal2x3`](fn.diagonal2x3.html)
/// * [`diagonal2x4()`] /// * [`diagonal2x4`](fn.diagonal2x4.html)
/// * [`diagonal3x2()`] /// * [`diagonal3x2`](fn.diagonal3x2.html)
/// * [`diagonal3x3()`] /// * [`diagonal3x3`](fn.diagonal3x3.html)
/// * [`diagonal4x2()`] /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3()`] /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4()`] /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal3x4<T: Number>(v: &TVec3<T>) -> TMat3x4<T> { pub fn diagonal3x4<T: Number>(v: &TVec3<T>) -> TMat3x4<T> {
TMat3x4::from_partial_diagonal(v.as_slice()) TMat3x4::from_partial_diagonal(v.as_slice())
} }
@ -103,14 +103,14 @@ pub fn diagonal3x4<T: Number>(v: &TVec3<T>) -> TMat3x4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2()`] /// * [`diagonal2x2`](fn.diagonal2x2.html)
/// * [`diagonal2x3()`] /// * [`diagonal2x3`](fn.diagonal2x3.html)
/// * [`diagonal2x4()`] /// * [`diagonal2x4`](fn.diagonal2x4.html)
/// * [`diagonal3x2()`] /// * [`diagonal3x2`](fn.diagonal3x2.html)
/// * [`diagonal3x3()`] /// * [`diagonal3x3`](fn.diagonal3x3.html)
/// * [`diagonal3x4()`] /// * [`diagonal3x4`](fn.diagonal3x4.html)
/// * [`diagonal4x3()`] /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4()`] /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal4x2<T: Number>(v: &TVec2<T>) -> TMat4x2<T> { pub fn diagonal4x2<T: Number>(v: &TVec2<T>) -> TMat4x2<T> {
TMat4x2::from_partial_diagonal(v.as_slice()) TMat4x2::from_partial_diagonal(v.as_slice())
} }
@ -119,14 +119,14 @@ pub fn diagonal4x2<T: Number>(v: &TVec2<T>) -> TMat4x2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2()`] /// * [`diagonal2x2`](fn.diagonal2x2.html)
/// * [`diagonal2x3()`] /// * [`diagonal2x3`](fn.diagonal2x3.html)
/// * [`diagonal2x4()`] /// * [`diagonal2x4`](fn.diagonal2x4.html)
/// * [`diagonal3x2()`] /// * [`diagonal3x2`](fn.diagonal3x2.html)
/// * [`diagonal3x3()`] /// * [`diagonal3x3`](fn.diagonal3x3.html)
/// * [`diagonal3x4()`] /// * [`diagonal3x4`](fn.diagonal3x4.html)
/// * [`diagonal4x2()`] /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x4()`] /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal4x3<T: Number>(v: &TVec3<T>) -> TMat4x3<T> { pub fn diagonal4x3<T: Number>(v: &TVec3<T>) -> TMat4x3<T> {
TMat4x3::from_partial_diagonal(v.as_slice()) TMat4x3::from_partial_diagonal(v.as_slice())
} }
@ -135,14 +135,14 @@ pub fn diagonal4x3<T: Number>(v: &TVec3<T>) -> TMat4x3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2()`] /// * [`diagonal2x2`](fn.diagonal2x2.html)
/// * [`diagonal2x3()`] /// * [`diagonal2x3`](fn.diagonal2x3.html)
/// * [`diagonal2x4()`] /// * [`diagonal2x4`](fn.diagonal2x4.html)
/// * [`diagonal3x2()`] /// * [`diagonal3x2`](fn.diagonal3x2.html)
/// * [`diagonal3x3()`] /// * [`diagonal3x3`](fn.diagonal3x3.html)
/// * [`diagonal3x4()`] /// * [`diagonal3x4`](fn.diagonal3x4.html)
/// * [`diagonal4x2()`] /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3()`] /// * [`diagonal4x3`](fn.diagonal4x3.html)
pub fn diagonal4x4<T: Number>(v: &TVec4<T>) -> TMat4<T> { pub fn diagonal4x4<T: Number>(v: &TVec4<T>) -> TMat4<T> {
TMat4::from_diagonal(v) TMat4::from_diagonal(v)
} }

View File

@ -5,7 +5,7 @@ use crate::RealNumber;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`distance()`](crate::distance) /// * [`distance`](fn.distance.html)
pub fn distance2<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T { pub fn distance2<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
(p1 - p0).norm_squared() (p1 - p0).norm_squared()
} }
@ -14,9 +14,9 @@ pub fn distance2<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>
/// ///
/// # See also: /// # See also:
/// ///
/// * [`l1_norm()`] /// * [`l1_norm`](fn.l1_norm.html)
/// * [`l2_distance()`] /// * [`l2_distance`](fn.l2_distance.html)
/// * [`l2_norm()`] /// * [`l2_norm`](fn.l2_norm.html)
pub fn l1_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T { pub fn l1_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
l1_norm(&(y - x)) l1_norm(&(y - x))
} }
@ -28,27 +28,27 @@ pub fn l1_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>
/// ///
/// # See also: /// # See also:
/// ///
/// * [`l1_distance()`] /// * [`l1_distance`](fn.l1_distance.html)
/// * [`l2_distance()`] /// * [`l2_distance`](fn.l2_distance.html)
/// * [`l2_norm()`] /// * [`l2_norm`](fn.l2_norm.html)
pub fn l1_norm<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> T { pub fn l1_norm<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> T {
crate::comp_add(&v.abs()) crate::comp_add(&v.abs())
} }
/// The l2-norm of `x - y`. /// The l2-norm of `x - y`.
/// ///
/// This is the same value as returned by [`length2()`] and /// This is the same value as returned by [`length2`](fn.length2.html) and
/// [`magnitude2()`]. /// [`magnitude2`](fn.magnitude2.html).
/// ///
/// # See also: /// # See also:
/// ///
/// * [`l1_distance()`] /// * [`l1_distance`](fn.l1_distance.html)
/// * [`l1_norm()`] /// * [`l1_norm`](fn.l1_norm.html)
/// * [`l2_norm()`] /// * [`l2_norm`](fn.l2_norm.html)
/// * [`length()`](crate::length) /// * [`length`](fn.length.html)
/// * [`length2()`] /// * [`length2`](fn.length2.html)
/// * [`magnitude()`](crate::magnitude) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2()`] /// * [`magnitude2`](fn.magnitude2.html)
pub fn l2_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T { pub fn l2_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
l2_norm(&(y - x)) l2_norm(&(y - x))
} }
@ -57,33 +57,33 @@ pub fn l2_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>
/// ///
/// This is also known as the Euclidean norm. /// This is also known as the Euclidean norm.
/// ///
/// This is the same value as returned by [`length()`](crate::length) and /// This is the same value as returned by [`length`](fn.length.html) and
/// [`magnitude()`](crate::magnitude). /// [`magnitude`](fn.magnitude.html).
/// ///
/// # See also: /// # See also:
/// ///
/// * [`l1_distance()`] /// * [`l1_distance`](fn.l1_distance.html)
/// * [`l1_norm()`] /// * [`l1_norm`](fn.l1_norm.html)
/// * [`l2_distance()`] /// * [`l2_distance`](fn.l2_distance.html)
/// * [`length()`](crate::length) /// * [`length`](fn.length.html)
/// * [`length2()`] /// * [`length2`](fn.length2.html)
/// * [`magnitude()`](crate::magnitude) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2()`] /// * [`magnitude2`](fn.magnitude2.html)
pub fn l2_norm<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T { pub fn l2_norm<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm() x.norm()
} }
/// The squared magnitude of `x`. /// The squared magnitude of `x`.
/// ///
/// A synonym for [`magnitude2()`]. /// A synonym for [`magnitude2`](fn.magnitude2.html).
/// ///
/// # See also: /// # See also:
/// ///
/// * [`distance()`](crate::distance) /// * [`distance`](fn.distance.html)
/// * [`distance2()`] /// * [`distance2`](fn.distance2.html)
/// * [`length()`](crate::length) /// * [`length`](fn.length.html)
/// * [`magnitude()`](crate::magnitude) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2()`] /// * [`magnitude2`](fn.magnitude2.html)
pub fn length2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T { pub fn length2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm_squared() x.norm_squared()
} }
@ -94,10 +94,10 @@ pub fn length2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`distance()`](crate::distance) /// * [`distance`](fn.distance.html)
/// * [`distance2()`] /// * [`distance2`](fn.distance2.html)
/// * [`length2()`] /// * [`length2`](fn.length2.html)
/// * [`magnitude()`](crate::magnitude) /// * [`magnitude`](fn.magnitude.html)
/// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html) /// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html)
pub fn magnitude2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T { pub fn magnitude2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm_squared() x.norm_squared()

View File

@ -4,11 +4,11 @@ use crate::aliases::TVec;
/// The dot product of the normalized version of `x` and `y`. /// The dot product of the normalized version of `x` and `y`.
/// ///
/// This is currently the same as [`normalize_dot()`] /// This is currently the same as [`normalize_dot`](fn.normalize_dot.html).
/// ///
/// # See also: /// # See also:
/// ///
/// * [`normalize_dot()`] /// * [`normalize_dot`](fn.normalize_dot.html`)
pub fn fast_normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T { pub fn fast_normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
// XXX: improve those. // XXX: improve those.
x.normalize().dot(&y.normalize()) x.normalize().dot(&y.normalize())
@ -18,7 +18,7 @@ pub fn fast_normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVe
/// ///
/// # See also: /// # See also:
/// ///
/// * [`fast_normalize_dot()`] /// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`)
pub fn normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T { pub fn normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
// XXX: improve those. // XXX: improve those.
x.normalize().dot(&y.normalize()) x.normalize().dot(&y.normalize())

View File

@ -7,11 +7,11 @@ use crate::traits::{Number, RealNumber};
/// ///
/// # See also: /// # See also:
/// ///
/// * [`scaling()`] /// * [`scaling`](fn.scaling.html)
/// * [`translation()`] /// * [`translation`](fn.translation.html)
/// * [`rotation2d()`] /// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d()`] /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d()`] /// * [`translation2d`](fn.translation2d.html)
pub fn rotation<T: RealNumber>(angle: T, v: &TVec3<T>) -> TMat4<T> { pub fn rotation<T: RealNumber>(angle: T, v: &TVec3<T>) -> TMat4<T> {
Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous() Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous()
} }
@ -20,11 +20,11 @@ pub fn rotation<T: RealNumber>(angle: T, v: &TVec3<T>) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation()`] /// * [`rotation`](fn.rotation.html)
/// * [`translation()`] /// * [`translation`](fn.translation.html)
/// * [`rotation2d()`] /// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d()`] /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d()`] /// * [`translation2d`](fn.translation2d.html)
pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> { pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> {
TMat4::new_nonuniform_scaling(v) TMat4::new_nonuniform_scaling(v)
} }
@ -33,11 +33,11 @@ pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation()`] /// * [`rotation`](fn.rotation.html)
/// * [`scaling()`] /// * [`scaling`](fn.scaling.html)
/// * [`rotation2d()`] /// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d()`] /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d()`] /// * [`translation2d`](fn.translation2d.html)
pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> { pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
TMat4::new_translation(v) TMat4::new_translation(v)
} }
@ -46,11 +46,11 @@ pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation()`] /// * [`rotation`](fn.rotation.html)
/// * [`scaling()`] /// * [`scaling`](fn.scaling.html)
/// * [`translation()`] /// * [`translation`](fn.translation.html)
/// * [`scaling2d()`] /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d()`] /// * [`translation2d`](fn.translation2d.html)
pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> { pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> {
Rotation2::new(angle).to_homogeneous() Rotation2::new(angle).to_homogeneous()
} }
@ -59,11 +59,11 @@ pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation()`] /// * [`rotation`](fn.rotation.html)
/// * [`scaling()`] /// * [`scaling`](fn.scaling.html)
/// * [`translation()`] /// * [`translation`](fn.translation.html)
/// * [`rotation2d()`] /// * [`rotation2d`](fn.rotation2d.html)
/// * [`translation2d()`] /// * [`translation2d`](fn.translation2d.html)
pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> { pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
TMat3::new_nonuniform_scaling(v) TMat3::new_nonuniform_scaling(v)
} }
@ -72,11 +72,11 @@ pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation()`] /// * [`rotation`](fn.rotation.html)
/// * [`scaling()`] /// * [`scaling`](fn.scaling.html)
/// * [`translation()`] /// * [`translation`](fn.translation.html)
/// * [`rotation2d()`] /// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d()`] /// * [`scaling2d`](fn.scaling2d.html)
pub fn translation2d<T: Number>(v: &TVec2<T>) -> TMat3<T> { pub fn translation2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
TMat3::new_translation(v) TMat3::new_translation(v)
} }

View File

@ -7,11 +7,11 @@ use crate::traits::{Number, RealNumber};
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation2d()`](crate::rotation2d) /// * [`rotation2d`](fn.rotation2d.html)
/// * [`scale2d()`] /// * [`scale2d`](fn.scale2d.html)
/// * [`scaling2d()`](crate::scaling2d) /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translate2d()`] /// * [`translate2d`](fn.translate2d.html)
/// * [`translation2d()`](crate::translation2d) /// * [`translation2d`](fn.translation2d.html)
pub fn rotate2d<T: RealNumber>(m: &TMat3<T>, angle: T) -> TMat3<T> { pub fn rotate2d<T: RealNumber>(m: &TMat3<T>, angle: T) -> TMat3<T> {
m * UnitComplex::new(angle).to_homogeneous() m * UnitComplex::new(angle).to_homogeneous()
} }
@ -20,11 +20,11 @@ pub fn rotate2d<T: RealNumber>(m: &TMat3<T>, angle: T) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate2d()`] /// * [`rotate2d`](fn.rotate2d.html)
/// * [`rotation2d()`](crate::rotation2d) /// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d()`](crate::scaling2d) /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translate2d()`] /// * [`translate2d`](fn.translate2d.html)
/// * [`translation2d()`](crate::translation2d) /// * [`translation2d`](fn.translation2d.html)
pub fn scale2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> { pub fn scale2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
m.prepend_nonuniform_scaling(v) m.prepend_nonuniform_scaling(v)
} }
@ -33,11 +33,11 @@ pub fn scale2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate2d()`] /// * [`rotate2d`](fn.rotate2d.html)
/// * [`rotation2d()`](crate::rotation2d) /// * [`rotation2d`](fn.rotation2d.html)
/// * [`scale2d()`] /// * [`scale2d`](fn.scale2d.html)
/// * [`scaling2d()`](crate::scaling2d) /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d()`](crate::translation2d) /// * [`translation2d`](fn.translation2d.html)
pub fn translate2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> { pub fn translate2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
m.prepend_translation(v) m.prepend_translation(v)
} }

View File

@ -7,16 +7,16 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`are_collinear2d()`] /// * [`are_collinear2d`](fn.are_collinear2d.html)
pub fn are_collinear<T: Number>(v0: &TVec3<T>, v1: &TVec3<T>, epsilon: T) -> bool { pub fn are_collinear<T: Number>(v0: &TVec3<T>, v1: &TVec3<T>, epsilon: T) -> bool {
abs_diff_eq!(v0.cross(v1), TVec3::<T>::zeros(), epsilon = epsilon) is_null(&v0.cross(v1), epsilon)
} }
/// Returns `true` if two 2D vectors are collinear (up to an epsilon). /// Returns `true` if two 2D vectors are collinear (up to an epsilon).
/// ///
/// # See also: /// # See also:
/// ///
/// * [`are_collinear()`] /// * [`are_collinear`](fn.are_collinear.html)
pub fn are_collinear2d<T: Number>(v0: &TVec2<T>, v1: &TVec2<T>, epsilon: T) -> bool { pub fn are_collinear2d<T: Number>(v0: &TVec2<T>, v1: &TVec2<T>, epsilon: T) -> bool {
abs_diff_eq!(v0.perp(v1), T::zero(), epsilon = epsilon) abs_diff_eq!(v0.perp(v1), T::zero(), epsilon = epsilon)
} }
@ -41,13 +41,10 @@ pub fn is_comp_null<T: Number, const D: usize>(v: &TVec<T, D>, epsilon: T) -> TV
/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon). /// Returns `true` if `v` has a magnitude of 1 (up to an epsilon).
pub fn is_normalized<T: RealNumber, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool { pub fn is_normalized<T: RealNumber, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
// sqrt(1 + epsilon_{norm²} = 1 + epsilon_{norm} abs_diff_eq!(v.norm_squared(), T::one(), epsilon = epsilon * epsilon)
// ==> epsilon_{norm²} = epsilon_{norm}² + 2*epsilon_{norm}
// For small epsilon, epsilon² is basically zero, so use 2*epsilon.
abs_diff_eq!(v.norm_squared(), T::one(), epsilon = epsilon + epsilon)
} }
/// Returns `true` if `v` is zero (up to an epsilon). /// Returns `true` if `v` is zero (up to an epsilon).
pub fn is_null<T: RealNumber, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool { pub fn is_null<T: Number, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
abs_diff_eq!(v.norm_squared(), T::zero(), epsilon = epsilon * epsilon) abs_diff_eq!(*v, TVec::<T, D>::zeros(), epsilon = epsilon)
} }

View File

@ -38,7 +38,7 @@
* All function names use `snake_case`, which is the Rust convention. * All function names use `snake_case`, which is the Rust convention.
* All type names use `CamelCase`, which is the Rust convention. * All type names use `CamelCase`, which is the Rust convention.
* All function arguments, except for scalars, are all passed by-reference. * All function arguments, except for scalars, are all passed by-reference.
* The most generic vector and matrix types are [`TMat`] and [`TVec`] instead of `mat` and `vec`. * The most generic vector and matrix types are [`TMat`](type.TMat.html) and [`TVec`](type.TVec.html) instead of `mat` and `vec`.
* Some feature are not yet implemented and should be added in the future. In particular, no packing * Some feature are not yet implemented and should be added in the future. In particular, no packing
functions are available. functions are available.
* A few features are not implemented and will never be. This includes functions related to color * A few features are not implemented and will never be. This includes functions related to color
@ -47,17 +47,17 @@
In addition, because Rust does not allows function overloading, all functions must be given a unique name. In addition, because Rust does not allows function overloading, all functions must be given a unique name.
Here are a few rules chosen arbitrarily for **nalgebra-glm**: Here are a few rules chosen arbitrarily for **nalgebra-glm**:
* Functions operating in 2d will usually end with the `2d` suffix, e.g., [`glm::rotate2d()`](crate::rotate2d) is for 2D while [`glm::rotate()`](crate::rotate) is for 3D. * Functions operating in 2d will usually end with the `2d` suffix, e.g., [`glm::rotate2d`](fn.rotate2d.html) is for 2D while [`glm::rotate`](fn.rotate.html) is for 3D.
* Functions operating on vectors will often end with the `_vec` suffix, possibly followed by the dimension of vector, e.g., [`glm::rotate_vec2()`](crate::rotate_vec2). * Functions operating on vectors will often end with the `_vec` suffix, possibly followed by the dimension of vector, e.g., [`glm::rotate_vec2`](fn.rotate_vec2.html).
* Every function related to quaternions start with the `quat_` prefix, e.g., [`glm::quat_dot(q1, q2)`](crate::quat_dot). * Every function related to quaternions start with the `quat_` prefix, e.g., [`glm::quat_dot(q1, q2)`](fn.quat_dot.html).
* All the conversion functions have unique names as described [below](#conversions). * All the conversion functions have unique names as described [below](#conversions).
### Vector and matrix construction ### Vector and matrix construction
Vectors, matrices, and quaternions can be constructed using several approaches: Vectors, matrices, and quaternions can be constructed using several approaches:
* Using functions with the same name as their type in lower-case. For example [`glm::vec3(x, y, z)`](crate::vec3) will create a 3D vector. * Using functions with the same name as their type in lower-case. For example [`glm::vec3(x, y, z)`](fn.vec3.html) will create a 3D vector.
* Using the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.OMatrix.html#method.new-27) will create a 3D vector. * Using the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.OMatrix.html#method.new-27) will create a 3D vector.
* Using the functions prefixed by `make_` to build a vector a matrix from a slice. For example [`glm::make_vec3(&[x, y, z])`](crate::make_vec3) will create a 3D vector. * Using the functions prefixed by `make_` to build a vector a matrix from a slice. For example [`glm::make_vec3(&[x, y, z])`](fn.make_vec3.html) will create a 3D vector.
Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice. Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice.
* Using a geometric construction function. For example [`glm::rotation(angle, axis)`](crate::rotation) will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis. * Using a geometric construction function. For example [`glm::rotation(angle, axis)`](fn.rotation.html) will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis.
* Using swizzling and conversions as described in the next sections. * Using swizzling and conversions as described in the next sections.
### Swizzling ### Swizzling
Vector swizzling is a native feature of **nalgebra** itself. Therefore, you can use it with all Vector swizzling is a native feature of **nalgebra** itself. Therefore, you can use it with all
@ -75,9 +75,9 @@
It is often useful to convert one algebraic type to another. There are two main approaches for converting It is often useful to convert one algebraic type to another. There are two main approaches for converting
between types in `nalgebra-glm`: between types in `nalgebra-glm`:
* Using function with the form `type1_to_type2` in order to convert an instance of `type1` into an instance of `type2`. * Using function with the form `type1_to_type2` in order to convert an instance of `type1` into an instance of `type2`.
For example [`glm::mat3_to_mat4(m)`](crate::mat3_to_mat4) will convert the 3x3 matrix `m` to a 4x4 matrix by appending one column on the right For example [`glm::mat3_to_mat4(m)`](fn.mat3_to_mat4.html) will convert the 3x3 matrix `m` to a 4x4 matrix by appending one column on the right
and one row on the left. Those now row and columns are filled with 0 except for the diagonal element which is set to 1. and one row on the left. Those now row and columns are filled with 0 except for the diagonal element which is set to 1.
* Using one of the [`convert`](crate::convert), [`try_convert`](crate::try_convert), or [`convert_unchecked`](crate::convert_unchecked) functions. * Using one of the [`convert`](fn.convert.html), [`try_convert`](fn.try_convert.html), or [`convert_unchecked`](fn.convert_unchecked.html) functions.
These functions are directly re-exported from nalgebra and are extremely versatile: These functions are directly re-exported from nalgebra and are extremely versatile:
1. The `convert` function can convert any type (especially geometric types from nalgebra like `Isometry3`) into another algebraic type which is equivalent but more general. For example, 1. The `convert` function can convert any type (especially geometric types from nalgebra like `Isometry3`) into another algebraic type which is equivalent but more general. For example,
`let sim: Similarity3<_> = na::convert(isometry)` will convert an `Isometry3` into a `Similarity3`. `let sim: Similarity3<_> = na::convert(isometry)` will convert an `Isometry3` into a `Similarity3`.

View File

@ -1,17 +1,18 @@
use approx::AbsDiffEq; use approx::AbsDiffEq;
use num::{Bounded, Signed}; use num::{Bounded, Signed};
use core::cmp::PartialOrd;
use na::Scalar; use na::Scalar;
use simba::scalar::{ClosedAddAssign, ClosedMulAssign, ClosedSubAssign, RealField}; use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, RealField};
/// A number that can either be an integer or a float. /// A number that can either be an integer or a float.
pub trait Number: pub trait Number:
Scalar Scalar
+ Copy + Copy
+ PartialOrd + PartialOrd
+ ClosedAddAssign + ClosedAdd
+ ClosedSubAssign + ClosedSub
+ ClosedMulAssign + ClosedMul
+ AbsDiffEq<Epsilon = Self> + AbsDiffEq<Epsilon = Self>
+ Signed + Signed
+ Bounded + Bounded
@ -22,9 +23,9 @@ impl<
T: Scalar T: Scalar
+ Copy + Copy
+ PartialOrd + PartialOrd
+ ClosedAddAssign + ClosedAdd
+ ClosedSubAssign + ClosedSub
+ ClosedMulAssign + ClosedMul
+ AbsDiffEq<Epsilon = Self> + AbsDiffEq<Epsilon = Self>
+ Signed + Signed
+ Bounded, + Bounded,

View File

@ -1,3 +1,5 @@
use na;
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::RealNumber; use crate::RealNumber;

View File

@ -16,8 +16,8 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`any()`] /// * [`any`](fn.any.html)
/// * [`not()`] /// * [`not`](fn.not.html)
pub fn all<const D: usize>(v: &TVec<bool, D>) -> bool { pub fn all<const D: usize>(v: &TVec<bool, D>) -> bool {
v.iter().all(|x| *x) v.iter().all(|x| *x)
} }
@ -40,8 +40,8 @@ pub fn all<const D: usize>(v: &TVec<bool, D>) -> bool {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`all()`] /// * [`all`](fn.all.html)
/// * [`not()`] /// * [`not`](fn.not.html)
pub fn any<const D: usize>(v: &TVec<bool, D>) -> bool { pub fn any<const D: usize>(v: &TVec<bool, D>) -> bool {
v.iter().any(|x| *x) v.iter().any(|x| *x)
} }
@ -59,12 +59,12 @@ pub fn any<const D: usize>(v: &TVec<bool, D>) -> bool {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`greater_than()`] /// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal()`] /// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than()`] /// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal()`] /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not()`] /// * [`not`](fn.not.html)
/// * [`not_equal()`] /// * [`not_equal`](fn.not_equal.html)
pub fn equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> { pub fn equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
x.zip_map(y, |x, y| x == y) x.zip_map(y, |x, y| x == y)
} }
@ -82,12 +82,12 @@ pub fn equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal()`] /// * [`equal`](fn.equal.html)
/// * [`greater_than_equal()`] /// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than()`] /// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal()`] /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not()`] /// * [`not`](fn.not.html)
/// * [`not_equal()`] /// * [`not_equal`](fn.not_equal.html)
pub fn greater_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> { pub fn greater_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
x.zip_map(y, |x, y| x > y) x.zip_map(y, |x, y| x > y)
} }
@ -105,12 +105,12 @@ pub fn greater_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal()`] /// * [`equal`](fn.equal.html)
/// * [`greater_than()`] /// * [`greater_than`](fn.greater_than.html)
/// * [`less_than()`] /// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal()`] /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not()`] /// * [`not`](fn.not.html)
/// * [`not_equal()`] /// * [`not_equal`](fn.not_equal.html)
pub fn greater_than_equal<T: Number, const D: usize>( pub fn greater_than_equal<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
@ -131,17 +131,17 @@ pub fn greater_than_equal<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal()`] /// * [`equal`](fn.equal.html)
/// * [`greater_than()`] /// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal()`] /// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than_equal()`] /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not()`] /// * [`not`](fn.not.html)
/// * [`not_equal()`] /// * [`not_equal`](fn.not_equal.html)
pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> { pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
x.zip_map(y, |x, y| x < y) x.zip_map(y, |x, y| x < y)
} }
/// Component-wise `<=` comparison. /// Component-wise `>=` comparison.
/// ///
/// # Examples: /// # Examples:
/// ///
@ -154,12 +154,12 @@ pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal()`] /// * [`equal`](fn.equal.html)
/// * [`greater_than()`] /// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal()`] /// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than()`] /// * [`less_than`](fn.less_than.html)
/// * [`not()`] /// * [`not`](fn.not.html)
/// * [`not_equal()`] /// * [`not_equal`](fn.not_equal.html)
pub fn less_than_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> { pub fn less_than_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
x.zip_map(y, |x, y| x <= y) x.zip_map(y, |x, y| x <= y)
} }
@ -176,14 +176,14 @@ pub fn less_than_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>
/// ///
/// # See also: /// # See also:
/// ///
/// * [`all()`] /// * [`all`](fn.all.html)
/// * [`any()`] /// * [`any`](fn.any.html)
/// * [`equal()`] /// * [`equal`](fn.equal.html)
/// * [`greater_than()`] /// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal()`] /// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than()`] /// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal()`] /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not_equal()`] /// * [`not_equal`](fn.not_equal.html)
pub fn not<const D: usize>(v: &TVec<bool, D>) -> TVec<bool, D> { pub fn not<const D: usize>(v: &TVec<bool, D>) -> TVec<bool, D> {
v.map(|x| !x) v.map(|x| !x)
} }
@ -201,12 +201,12 @@ pub fn not<const D: usize>(v: &TVec<bool, D>) -> TVec<bool, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal()`] /// * [`equal`](fn.equal.html)
/// * [`greater_than()`] /// * [`greater_than`](fn.greater_than.html)
/// * [`greater_than_equal()`] /// * [`greater_than_equal`](fn.greater_than_equal.html)
/// * [`less_than()`] /// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal()`] /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not()`] /// * [`not`](fn.not.html)
pub fn not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> { pub fn not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
x.zip_map(y, |x, y| x != y) x.zip_map(y, |x, y| x != y)
} }

View File

@ -1,47 +1,47 @@
[package] [package]
name = "nalgebra-lapack" name = "nalgebra-lapack"
version = "0.25.0" version = "0.24.0"
authors = ["Sébastien Crozet <developer@crozet.re>", "Andrew Straw <strawman@astraw.com>"] authors = [ "Sébastien Crozet <developer@crozet.re>", "Andrew Straw <strawman@astraw.com>" ]
description = "Matrix decompositions using nalgebra matrices and Lapack bindings." description = "Matrix decompositions using nalgebra matrices and Lapack bindings."
documentation = "https://www.nalgebra.org/docs" documentation = "https://www.nalgebra.org/docs"
homepage = "https://nalgebra.org" homepage = "https://nalgebra.org"
repository = "https://github.com/dimforge/nalgebra" repository = "https://github.com/dimforge/nalgebra"
readme = "../README.md" readme = "../README.md"
categories = ["science", "mathematics"] categories = [ "science", "mathematics" ]
keywords = ["linear", "algebra", "matrix", "vector", "lapack"] keywords = [ "linear", "algebra", "matrix", "vector", "lapack" ]
license = "MIT" license = "BSD-3-Clause"
edition = "2018" edition = "2018"
[badges] [badges]
maintenance = { status = "actively-developed" } maintenance = { status = "actively-developed" }
[features] [features]
serde-serialize = ["serde", "nalgebra/serde-serialize"] serde-serialize = [ "serde", "nalgebra/serde-serialize" ]
proptest-support = ["nalgebra/proptest-support"] proptest-support = [ "nalgebra/proptest-support" ]
arbitrary = ["nalgebra/arbitrary"] arbitrary = [ "nalgebra/arbitrary" ]
# For BLAS/LAPACK # For BLAS/LAPACK
default = ["netlib"] default = ["netlib"]
openblas = ["lapack-src/openblas"] openblas = ["lapack-src/openblas"]
netlib = ["lapack-src/netlib"] netlib = ["lapack-src/netlib"]
accelerate = ["lapack-src/accelerate"] accelerate = ["lapack-src/accelerate"]
intel-mkl = ["lapack-src/intel-mkl"] intel-mkl = ["lapack-src/intel-mkl"]
[dependencies] [dependencies]
nalgebra = { version = "0.33", path = ".." } nalgebra = { version = "0.32", path = ".." }
num-traits = "0.2" num-traits = "0.2"
num-complex = { version = "0.4", default-features = false } num-complex = { version = "0.4", default-features = false }
simba = "0.9" simba = "0.8"
serde = { version = "1.0", features = ["derive"], optional = true } serde = { version = "1.0", features = [ "derive" ], optional = true }
lapack = { version = "0.19", default-features = false } lapack = { version = "0.19", default-features = false }
lapack-src = { version = "0.8", default-features = false } lapack-src = { version = "0.8", default-features = false }
# clippy = "*" # clippy = "*"
[dev-dependencies] [dev-dependencies]
nalgebra = { version = "0.33", features = ["arbitrary", "rand"], path = ".." } nalgebra = { version = "0.32", features = [ "arbitrary", "rand" ], path = ".." }
proptest = { version = "1", default-features = false, features = ["std"] } proptest = { version = "1", default-features = false, features = ["std"] }
quickcheck = "1" quickcheck = "1"
approx = "0.5" approx = "0.5"
rand = "0.8" rand = "0.8"

View File

@ -15,32 +15,32 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<D>, serde(bound(serialize = "DefaultAllocator: Allocator<T, D>,
OMatrix<T, D, D>: Serialize")) OMatrix<T, D, D>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<D>, serde(bound(deserialize = "DefaultAllocator: Allocator<T, D>,
OMatrix<T, D, D>: Deserialize<'de>")) OMatrix<T, D, D>: Deserialize<'de>"))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Cholesky<T: Scalar, D: Dim> pub struct Cholesky<T: Scalar, D: Dim>
where where
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
l: OMatrix<T, D, D>, l: OMatrix<T, D, D>,
} }
impl<T: Scalar + Copy, D: Dim> Copy for Cholesky<T, D> impl<T: Scalar + Copy, D: Dim> Copy for Cholesky<T, D>
where where
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
OMatrix<T, D, D>: Copy, OMatrix<T, D, D>: Copy,
{ {
} }
impl<T: CholeskyScalar + Zero, D: Dim> Cholesky<T, D> impl<T: CholeskyScalar + Zero, D: Dim> Cholesky<T, D>
where where
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
/// Computes the cholesky decomposition of the given symmetric-definite-positive square /// Computes the cholesky decomposition of the given symmetric-definite-positive square
/// matrix. /// matrix.
@ -105,7 +105,7 @@ where
) -> Option<OMatrix<T, R2, C2>> ) -> Option<OMatrix<T, R2, C2>>
where where
S2: Storage<T, R2, C2>, S2: Storage<T, R2, C2>,
DefaultAllocator: Allocator<R2, C2>, DefaultAllocator: Allocator<T, R2, C2>,
{ {
let mut res = b.clone_owned(); let mut res = b.clone_owned();
if self.solve_mut(&mut res) { if self.solve_mut(&mut res) {
@ -119,7 +119,7 @@ where
/// the unknown to be determined. /// the unknown to be determined.
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
where where
DefaultAllocator: Allocator<R2, C2>, DefaultAllocator: Allocator<T, R2, C2>,
{ {
let dim = self.l.nrows(); let dim = self.l.nrows();

View File

@ -16,20 +16,24 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<D, D> + Allocator<D>, serde(
bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Serialize, OVector<T, D>: Serialize,
OMatrix<T, D, D>: Serialize")) OMatrix<T, D, D>: Serialize")
)
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<D, D> + Allocator<D>, serde(
bound(deserialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Serialize, OVector<T, D>: Serialize,
OMatrix<T, D, D>: Deserialize<'de>")) OMatrix<T, D, D>: Deserialize<'de>")
)
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Eigen<T: Scalar, D: Dim> pub struct Eigen<T: Scalar, D: Dim>
where where
DefaultAllocator: Allocator<D> + Allocator<D, D>, DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{ {
/// The real parts of eigenvalues of the decomposed matrix. /// The real parts of eigenvalues of the decomposed matrix.
pub eigenvalues_re: OVector<T, D>, pub eigenvalues_re: OVector<T, D>,
@ -43,7 +47,7 @@ where
impl<T: Scalar + Copy, D: Dim> Copy for Eigen<T, D> impl<T: Scalar + Copy, D: Dim> Copy for Eigen<T, D>
where where
DefaultAllocator: Allocator<D> + Allocator<D, D>, DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
OVector<T, D>: Copy, OVector<T, D>: Copy,
OMatrix<T, D, D>: Copy, OMatrix<T, D, D>: Copy,
{ {
@ -51,7 +55,7 @@ where
impl<T: EigenScalar + RealField, D: Dim> Eigen<T, D> impl<T: EigenScalar + RealField, D: Dim> Eigen<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
{ {
/// Computes the eigenvalues and eigenvectors of the square matrix `m`. /// Computes the eigenvalues and eigenvectors of the square matrix `m`.
/// ///
@ -173,7 +177,7 @@ where
Option<Vec<OVector<T, D>>>, Option<Vec<OVector<T, D>>>,
) )
where where
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<T, D>,
{ {
let (number_of_elements, _) = self.eigenvalues_re.shape_generic(); let (number_of_elements, _) = self.eigenvalues_re.shape_generic();
let number_of_elements_value = number_of_elements.value(); let number_of_elements_value = number_of_elements.value();
@ -196,16 +200,17 @@ where
eigenvalues.push(self.eigenvalues_re[c].clone()); eigenvalues.push(self.eigenvalues_re[c].clone());
if eigenvectors.is_some() { if eigenvectors.is_some() {
eigenvectors eigenvectors.as_mut().unwrap().push(
.as_mut() (&self.eigenvectors.as_ref())
.unwrap() .unwrap()
.push(self.eigenvectors.as_ref().unwrap().column(c).into_owned()); .column(c)
.into_owned(),
);
} }
if left_eigenvectors.is_some() { if left_eigenvectors.is_some() {
left_eigenvectors.as_mut().unwrap().push( left_eigenvectors.as_mut().unwrap().push(
self.left_eigenvectors (&self.left_eigenvectors.as_ref())
.as_ref()
.unwrap() .unwrap()
.column(c) .column(c)
.into_owned(), .into_owned(),
@ -230,7 +235,7 @@ where
Option<Vec<OVector<Complex<T>, D>>>, Option<Vec<OVector<Complex<T>, D>>>,
) )
where where
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<Complex<T>, D>,
{ {
match self.eigenvalues_are_real() { match self.eigenvalues_are_real() {
true => (None, None, None), true => (None, None, None),
@ -280,12 +285,12 @@ where
for r in 0..number_of_elements_value { for r in 0..number_of_elements_value {
vec[r] = Complex::<T>::new( vec[r] = Complex::<T>::new(
self.eigenvectors.as_ref().unwrap()[(r, c)].clone(), (&self.eigenvectors.as_ref()).unwrap()[(r, c)].clone(),
self.eigenvectors.as_ref().unwrap()[(r, c + 1)].clone(), (&self.eigenvectors.as_ref()).unwrap()[(r, c + 1)].clone(),
); );
vec_conj[r] = Complex::<T>::new( vec_conj[r] = Complex::<T>::new(
self.eigenvectors.as_ref().unwrap()[(r, c)].clone(), (&self.eigenvectors.as_ref()).unwrap()[(r, c)].clone(),
self.eigenvectors.as_ref().unwrap()[(r, c + 1)].clone(), (&self.eigenvectors.as_ref()).unwrap()[(r, c + 1)].clone(),
); );
} }
@ -305,12 +310,12 @@ where
for r in 0..number_of_elements_value { for r in 0..number_of_elements_value {
vec[r] = Complex::<T>::new( vec[r] = Complex::<T>::new(
self.left_eigenvectors.as_ref().unwrap()[(r, c)].clone(), (&self.left_eigenvectors.as_ref()).unwrap()[(r, c)].clone(),
self.left_eigenvectors.as_ref().unwrap()[(r, c + 1)].clone(), (&self.left_eigenvectors.as_ref()).unwrap()[(r, c + 1)].clone(),
); );
vec_conj[r] = Complex::<T>::new( vec_conj[r] = Complex::<T>::new(
self.left_eigenvectors.as_ref().unwrap()[(r, c)].clone(), (&self.left_eigenvectors.as_ref()).unwrap()[(r, c)].clone(),
self.left_eigenvectors.as_ref().unwrap()[(r, c + 1)].clone(), (&self.left_eigenvectors.as_ref()).unwrap()[(r, c + 1)].clone(),
); );
} }

View File

@ -30,20 +30,24 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<D, D> + Allocator<D>, serde(
bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Serialize, OVector<T, D>: Serialize,
OMatrix<T, D, D>: Serialize")) OMatrix<T, D, D>: Serialize")
)
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<D, D> + Allocator<D>, serde(
bound(deserialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Deserialize<'de>, OVector<T, D>: Deserialize<'de>,
OMatrix<T, D, D>: Deserialize<'de>")) OMatrix<T, D, D>: Deserialize<'de>")
)
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct GeneralizedEigen<T: Scalar, D: Dim> pub struct GeneralizedEigen<T: Scalar, D: Dim>
where where
DefaultAllocator: Allocator<D> + Allocator<D, D>, DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{ {
alphar: OVector<T, D>, alphar: OVector<T, D>,
alphai: OVector<T, D>, alphai: OVector<T, D>,
@ -54,7 +58,7 @@ where
impl<T: Scalar + Copy, D: Dim> Copy for GeneralizedEigen<T, D> impl<T: Scalar + Copy, D: Dim> Copy for GeneralizedEigen<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OMatrix<T, D, D>: Copy, OMatrix<T, D, D>: Copy,
OVector<T, D>: Copy, OVector<T, D>: Copy,
{ {
@ -62,7 +66,7 @@ where
impl<T: GeneralizedEigenScalar + RealField + Copy, D: Dim> GeneralizedEigen<T, D> impl<T: GeneralizedEigenScalar + RealField + Copy, D: Dim> GeneralizedEigen<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
{ {
/// Attempts to compute the generalized eigenvalues, and left and right associated eigenvectors /// Attempts to compute the generalized eigenvalues, and left and right associated eigenvectors
/// via the raw returns from LAPACK's dggev and sggev routines /// via the raw returns from LAPACK's dggev and sggev routines
@ -158,7 +162,8 @@ where
/// as columns. /// as columns.
pub fn eigenvectors(&self) -> (OMatrix<Complex<T>, D, D>, OMatrix<Complex<T>, D, D>) pub fn eigenvectors(&self) -> (OMatrix<Complex<T>, D, D>, OMatrix<Complex<T>, D, D>)
where where
DefaultAllocator: Allocator<D, D> + Allocator<D>, DefaultAllocator:
Allocator<Complex<T>, D, D> + Allocator<Complex<T>, D> + Allocator<(Complex<T>, T), D>,
{ {
/* /*
How the eigenvectors are built up: How the eigenvectors are built up:
@ -225,7 +230,7 @@ where
#[must_use] #[must_use]
pub fn raw_eigenvalues(&self) -> OVector<(Complex<T>, T), D> pub fn raw_eigenvalues(&self) -> OVector<(Complex<T>, T), D>
where where
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<(Complex<T>, T), D>,
{ {
let mut out = Matrix::from_element_generic( let mut out = Matrix::from_element_generic(
self.vsl.shape_generic().0, self.vsl.shape_generic().0,

View File

@ -12,22 +12,22 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<D, D> + serde(bound(serialize = "DefaultAllocator: Allocator<T, D, D> +
Allocator<DimDiff<D, U1>>, Allocator<T, DimDiff<D, U1>>,
OMatrix<T, D, D>: Serialize, OMatrix<T, D, D>: Serialize,
OVector<T, DimDiff<D, U1>>: Serialize")) OVector<T, DimDiff<D, U1>>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<D, D> + serde(bound(deserialize = "DefaultAllocator: Allocator<T, D, D> +
Allocator<DimDiff<D, U1>>, Allocator<T, DimDiff<D, U1>>,
OMatrix<T, D, D>: Deserialize<'de>, OMatrix<T, D, D>: Deserialize<'de>,
OVector<T, DimDiff<D, U1>>: Deserialize<'de>")) OVector<T, DimDiff<D, U1>>: Deserialize<'de>"))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Hessenberg<T: Scalar, D: DimSub<U1>> pub struct Hessenberg<T: Scalar, D: DimSub<U1>>
where where
DefaultAllocator: Allocator<D, D> + Allocator<DimDiff<D, U1>>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
{ {
h: OMatrix<T, D, D>, h: OMatrix<T, D, D>,
tau: OVector<T, DimDiff<D, U1>>, tau: OVector<T, DimDiff<D, U1>>,
@ -35,7 +35,7 @@ where
impl<T: Scalar + Copy, D: DimSub<U1>> Copy for Hessenberg<T, D> impl<T: Scalar + Copy, D: DimSub<U1>> Copy for Hessenberg<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<DimDiff<D, U1>>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
OMatrix<T, D, D>: Copy, OMatrix<T, D, D>: Copy,
OVector<T, DimDiff<D, U1>>: Copy, OVector<T, DimDiff<D, U1>>: Copy,
{ {
@ -43,7 +43,7 @@ where
impl<T: HessenbergScalar + Zero, D: DimSub<U1>> Hessenberg<T, D> impl<T: HessenbergScalar + Zero, D: DimSub<U1>> Hessenberg<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<DimDiff<D, U1>>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
{ {
/// Computes the hessenberg decomposition of the matrix `m`. /// Computes the hessenberg decomposition of the matrix `m`.
pub fn new(mut m: OMatrix<T, D, D>) -> Self { pub fn new(mut m: OMatrix<T, D, D>) -> Self {
@ -97,7 +97,7 @@ where
impl<T: HessenbergReal + Zero, D: DimSub<U1>> Hessenberg<T, D> impl<T: HessenbergReal + Zero, D: DimSub<U1>> Hessenberg<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<DimDiff<D, U1>>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
{ {
/// Computes the matrices `(Q, H)` of this decomposition. /// Computes the matrices `(Q, H)` of this decomposition.
#[inline] #[inline]

View File

@ -20,22 +20,22 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<R, C> + serde(bound(serialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<DimMinimum<R, C>>, Allocator<i32, DimMinimum<R, C>>,
OMatrix<T, R, C>: Serialize, OMatrix<T, R, C>: Serialize,
PermutationSequence<DimMinimum<R, C>>: Serialize")) PermutationSequence<DimMinimum<R, C>>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<R, C> + serde(bound(deserialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<DimMinimum<R, C>>, Allocator<i32, DimMinimum<R, C>>,
OMatrix<T, R, C>: Deserialize<'de>, OMatrix<T, R, C>: Deserialize<'de>,
PermutationSequence<DimMinimum<R, C>>: Deserialize<'de>")) PermutationSequence<DimMinimum<R, C>>: Deserialize<'de>"))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct LU<T: Scalar, R: DimMin<C>, C: Dim> pub struct LU<T: Scalar, R: DimMin<C>, C: Dim>
where where
DefaultAllocator: Allocator<DimMinimum<R, C>> + Allocator<R, C>, DefaultAllocator: Allocator<i32, DimMinimum<R, C>> + Allocator<T, R, C>,
{ {
lu: OMatrix<T, R, C>, lu: OMatrix<T, R, C>,
p: OVector<i32, DimMinimum<R, C>>, p: OVector<i32, DimMinimum<R, C>>,
@ -43,7 +43,7 @@ where
impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for LU<T, R, C> impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for LU<T, R, C>
where where
DefaultAllocator: Allocator<R, C> + Allocator<DimMinimum<R, C>>, DefaultAllocator: Allocator<T, R, C> + Allocator<i32, DimMinimum<R, C>>,
OMatrix<T, R, C>: Copy, OMatrix<T, R, C>: Copy,
OVector<i32, DimMinimum<R, C>>: Copy, OVector<i32, DimMinimum<R, C>>: Copy,
{ {
@ -53,11 +53,11 @@ impl<T: LUScalar, R: Dim, C: Dim> LU<T, R, C>
where where
T: Zero + One, T: Zero + One,
R: DimMin<C>, R: DimMin<C>,
DefaultAllocator: Allocator<R, C> DefaultAllocator: Allocator<T, R, C>
+ Allocator<R, R> + Allocator<T, R, R>
+ Allocator<R, DimMinimum<R, C>> + Allocator<T, R, DimMinimum<R, C>>
+ Allocator<DimMinimum<R, C>, C> + Allocator<T, DimMinimum<R, C>, C>
+ Allocator<DimMinimum<R, C>>, + Allocator<i32, DimMinimum<R, C>>,
{ {
/// Computes the LU decomposition with partial (row) pivoting of `matrix`. /// Computes the LU decomposition with partial (row) pivoting of `matrix`.
pub fn new(mut m: OMatrix<T, R, C>) -> Self { pub fn new(mut m: OMatrix<T, R, C>) -> Self {
@ -136,7 +136,7 @@ where
#[inline] #[inline]
pub fn permute<C2: Dim>(&self, rhs: &mut OMatrix<T, R, C2>) pub fn permute<C2: Dim>(&self, rhs: &mut OMatrix<T, R, C2>)
where where
DefaultAllocator: Allocator<R, C2>, DefaultAllocator: Allocator<T, R, C2>,
{ {
let (nrows, ncols) = rhs.shape(); let (nrows, ncols) = rhs.shape();
@ -153,7 +153,7 @@ where
fn generic_solve_mut<R2: Dim, C2: Dim>(&self, trans: u8, b: &mut OMatrix<T, R2, C2>) -> bool fn generic_solve_mut<R2: Dim, C2: Dim>(&self, trans: u8, b: &mut OMatrix<T, R2, C2>) -> bool
where where
DefaultAllocator: Allocator<R2, C2> + Allocator<R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
let dim = self.lu.nrows(); let dim = self.lu.nrows();
@ -192,7 +192,7 @@ where
) -> Option<OMatrix<T, R2, C2>> ) -> Option<OMatrix<T, R2, C2>>
where where
S2: Storage<T, R2, C2>, S2: Storage<T, R2, C2>,
DefaultAllocator: Allocator<R2, C2> + Allocator<R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
let mut res = b.clone_owned(); let mut res = b.clone_owned();
if self.generic_solve_mut(b'T', &mut res) { if self.generic_solve_mut(b'T', &mut res) {
@ -210,7 +210,7 @@ where
) -> Option<OMatrix<T, R2, C2>> ) -> Option<OMatrix<T, R2, C2>>
where where
S2: Storage<T, R2, C2>, S2: Storage<T, R2, C2>,
DefaultAllocator: Allocator<R2, C2> + Allocator<R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
let mut res = b.clone_owned(); let mut res = b.clone_owned();
if self.generic_solve_mut(b'T', &mut res) { if self.generic_solve_mut(b'T', &mut res) {
@ -228,7 +228,7 @@ where
) -> Option<OMatrix<T, R2, C2>> ) -> Option<OMatrix<T, R2, C2>>
where where
S2: Storage<T, R2, C2>, S2: Storage<T, R2, C2>,
DefaultAllocator: Allocator<R2, C2> + Allocator<R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
let mut res = b.clone_owned(); let mut res = b.clone_owned();
if self.generic_solve_mut(b'T', &mut res) { if self.generic_solve_mut(b'T', &mut res) {
@ -243,7 +243,7 @@ where
/// Returns `false` if no solution was found (the decomposed matrix is singular). /// Returns `false` if no solution was found (the decomposed matrix is singular).
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
where where
DefaultAllocator: Allocator<R2, C2> + Allocator<R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
self.generic_solve_mut(b'T', b) self.generic_solve_mut(b'T', b)
} }
@ -254,7 +254,7 @@ where
/// Returns `false` if no solution was found (the decomposed matrix is singular). /// Returns `false` if no solution was found (the decomposed matrix is singular).
pub fn solve_transpose_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool pub fn solve_transpose_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
where where
DefaultAllocator: Allocator<R2, C2> + Allocator<R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
self.generic_solve_mut(b'T', b) self.generic_solve_mut(b'T', b)
} }
@ -265,7 +265,7 @@ where
/// Returns `false` if no solution was found (the decomposed matrix is singular). /// Returns `false` if no solution was found (the decomposed matrix is singular).
pub fn solve_adjoint_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool pub fn solve_adjoint_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
where where
DefaultAllocator: Allocator<R2, C2> + Allocator<R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
self.generic_solve_mut(b'T', b) self.generic_solve_mut(b'T', b)
} }
@ -275,7 +275,7 @@ impl<T: LUScalar, D: Dim> LU<T, D, D>
where where
T: Zero + One, T: Zero + One,
D: DimMin<D, Output = D>, D: DimMin<D, Output = D>,
DefaultAllocator: Allocator<D, D> + Allocator<D>, DefaultAllocator: Allocator<T, D, D> + Allocator<i32, D>,
{ {
/// Computes the inverse of the decomposed matrix. /// Computes the inverse of the decomposed matrix.
pub fn inverse(mut self) -> Option<OMatrix<T, D, D>> { pub fn inverse(mut self) -> Option<OMatrix<T, D, D>> {

View File

@ -15,22 +15,22 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<R, C> + serde(bound(serialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<DimMinimum<R, C>>, Allocator<T, DimMinimum<R, C>>,
OMatrix<T, R, C>: Serialize, OMatrix<T, R, C>: Serialize,
OVector<T, DimMinimum<R, C>>: Serialize")) OVector<T, DimMinimum<R, C>>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<R, C> + serde(bound(deserialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<DimMinimum<R, C>>, Allocator<T, DimMinimum<R, C>>,
OMatrix<T, R, C>: Deserialize<'de>, OMatrix<T, R, C>: Deserialize<'de>,
OVector<T, DimMinimum<R, C>>: Deserialize<'de>")) OVector<T, DimMinimum<R, C>>: Deserialize<'de>"))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct QR<T: Scalar, R: DimMin<C>, C: Dim> pub struct QR<T: Scalar, R: DimMin<C>, C: Dim>
where where
DefaultAllocator: Allocator<R, C> + Allocator<DimMinimum<R, C>>, DefaultAllocator: Allocator<T, R, C> + Allocator<T, DimMinimum<R, C>>,
{ {
qr: OMatrix<T, R, C>, qr: OMatrix<T, R, C>,
tau: OVector<T, DimMinimum<R, C>>, tau: OVector<T, DimMinimum<R, C>>,
@ -38,7 +38,7 @@ where
impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for QR<T, R, C> impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for QR<T, R, C>
where where
DefaultAllocator: Allocator<R, C> + Allocator<DimMinimum<R, C>>, DefaultAllocator: Allocator<T, R, C> + Allocator<T, DimMinimum<R, C>>,
OMatrix<T, R, C>: Copy, OMatrix<T, R, C>: Copy,
OVector<T, DimMinimum<R, C>>: Copy, OVector<T, DimMinimum<R, C>>: Copy,
{ {
@ -46,10 +46,10 @@ where
impl<T: QRScalar + Zero, R: DimMin<C>, C: Dim> QR<T, R, C> impl<T: QRScalar + Zero, R: DimMin<C>, C: Dim> QR<T, R, C>
where where
DefaultAllocator: Allocator<R, C> DefaultAllocator: Allocator<T, R, C>
+ Allocator<R, DimMinimum<R, C>> + Allocator<T, R, DimMinimum<R, C>>
+ Allocator<DimMinimum<R, C>, C> + Allocator<T, DimMinimum<R, C>, C>
+ Allocator<DimMinimum<R, C>>, + Allocator<T, DimMinimum<R, C>>,
{ {
/// Computes the QR decomposition of the matrix `m`. /// Computes the QR decomposition of the matrix `m`.
pub fn new(mut m: OMatrix<T, R, C>) -> Self { pub fn new(mut m: OMatrix<T, R, C>) -> Self {
@ -98,10 +98,10 @@ where
impl<T: QRReal + Zero, R: DimMin<C>, C: Dim> QR<T, R, C> impl<T: QRReal + Zero, R: DimMin<C>, C: Dim> QR<T, R, C>
where where
DefaultAllocator: Allocator<R, C> DefaultAllocator: Allocator<T, R, C>
+ Allocator<R, DimMinimum<R, C>> + Allocator<T, R, DimMinimum<R, C>>
+ Allocator<DimMinimum<R, C>, C> + Allocator<T, DimMinimum<R, C>, C>
+ Allocator<DimMinimum<R, C>>, + Allocator<T, DimMinimum<R, C>>,
{ {
/// Retrieves the matrices `(Q, R)` of this decompositions. /// Retrieves the matrices `(Q, R)` of this decompositions.
pub fn unpack( pub fn unpack(

View File

@ -22,20 +22,24 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<D, D> + Allocator<D>, serde(
bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Serialize, OVector<T, D>: Serialize,
OMatrix<T, D, D>: Serialize")) OMatrix<T, D, D>: Serialize")
)
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<D, D> + Allocator<D>, serde(
bound(deserialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Deserialize<'de>, OVector<T, D>: Deserialize<'de>,
OMatrix<T, D, D>: Deserialize<'de>")) OMatrix<T, D, D>: Deserialize<'de>")
)
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct QZ<T: Scalar, D: Dim> pub struct QZ<T: Scalar, D: Dim>
where where
DefaultAllocator: Allocator<D> + Allocator<D, D>, DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{ {
alphar: OVector<T, D>, alphar: OVector<T, D>,
alphai: OVector<T, D>, alphai: OVector<T, D>,
@ -48,7 +52,7 @@ where
impl<T: Scalar + Copy, D: Dim> Copy for QZ<T, D> impl<T: Scalar + Copy, D: Dim> Copy for QZ<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OMatrix<T, D, D>: Copy, OMatrix<T, D, D>: Copy,
OVector<T, D>: Copy, OVector<T, D>: Copy,
{ {
@ -56,7 +60,7 @@ where
impl<T: QZScalar + RealField, D: Dim> QZ<T, D> impl<T: QZScalar + RealField, D: Dim> QZ<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
{ {
/// Attempts to compute the QZ decomposition of input real square matrices `a` and `b`. /// Attempts to compute the QZ decomposition of input real square matrices `a` and `b`.
/// ///
@ -178,7 +182,7 @@ where
#[must_use] #[must_use]
pub fn raw_eigenvalues(&self) -> OVector<(Complex<T>, T), D> pub fn raw_eigenvalues(&self) -> OVector<(Complex<T>, T), D>
where where
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<(Complex<T>, T), D>,
{ {
let mut out = Matrix::from_element_generic( let mut out = Matrix::from_element_generic(
self.vsl.shape_generic().0, self.vsl.shape_generic().0,

View File

@ -17,20 +17,24 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<D, D> + Allocator<D>, serde(
bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Serialize, OVector<T, D>: Serialize,
OMatrix<T, D, D>: Serialize")) OMatrix<T, D, D>: Serialize")
)
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<D, D> + Allocator<D>, serde(
bound(deserialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Serialize, OVector<T, D>: Serialize,
OMatrix<T, D, D>: Deserialize<'de>")) OMatrix<T, D, D>: Deserialize<'de>")
)
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Schur<T: Scalar, D: Dim> pub struct Schur<T: Scalar, D: Dim>
where where
DefaultAllocator: Allocator<D> + Allocator<D, D>, DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{ {
re: OVector<T, D>, re: OVector<T, D>,
im: OVector<T, D>, im: OVector<T, D>,
@ -40,7 +44,7 @@ where
impl<T: Scalar + Copy, D: Dim> Copy for Schur<T, D> impl<T: Scalar + Copy, D: Dim> Copy for Schur<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OMatrix<T, D, D>: Copy, OMatrix<T, D, D>: Copy,
OVector<T, D>: Copy, OVector<T, D>: Copy,
{ {
@ -48,7 +52,7 @@ where
impl<T: SchurScalar + RealField, D: Dim> Schur<T, D> impl<T: SchurScalar + RealField, D: Dim> Schur<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
{ {
/// Computes the eigenvalues and real Schur form of the matrix `m`. /// Computes the eigenvalues and real Schur form of the matrix `m`.
/// ///
@ -146,7 +150,7 @@ where
#[must_use] #[must_use]
pub fn complex_eigenvalues(&self) -> OVector<Complex<T>, D> pub fn complex_eigenvalues(&self) -> OVector<Complex<T>, D>
where where
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<Complex<T>, D>,
{ {
let mut out = Matrix::zeros_generic(self.t.shape_generic().0, Const::<1>); let mut out = Matrix::zeros_generic(self.t.shape_generic().0, Const::<1>);

View File

@ -14,18 +14,18 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<DimMinimum<R, C>> + serde(bound(serialize = "DefaultAllocator: Allocator<T, DimMinimum<R, C>> +
Allocator<R, R> + Allocator<T, R, R> +
Allocator<C, C>, Allocator<T, C, C>,
OMatrix<T, R>: Serialize, OMatrix<T, R>: Serialize,
OMatrix<T, C>: Serialize, OMatrix<T, C>: Serialize,
OVector<T, DimMinimum<R, C>>: Serialize")) OVector<T, DimMinimum<R, C>>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<DimMinimum<R, C>> + serde(bound(serialize = "DefaultAllocator: Allocator<T, DimMinimum<R, C>> +
Allocator<R, R> + Allocator<T, R, R> +
Allocator<C, C>, Allocator<T, C, C>,
OMatrix<T, R>: Deserialize<'de>, OMatrix<T, R>: Deserialize<'de>,
OMatrix<T, C>: Deserialize<'de>, OMatrix<T, C>: Deserialize<'de>,
OVector<T, DimMinimum<R, C>>: Deserialize<'de>")) OVector<T, DimMinimum<R, C>>: Deserialize<'de>"))
@ -33,7 +33,7 @@ use lapack;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SVD<T: Scalar, R: DimMin<C>, C: Dim> pub struct SVD<T: Scalar, R: DimMin<C>, C: Dim>
where where
DefaultAllocator: Allocator<R, R> + Allocator<DimMinimum<R, C>> + Allocator<C, C>, DefaultAllocator: Allocator<T, R, R> + Allocator<T, DimMinimum<R, C>> + Allocator<T, C, C>,
{ {
/// The left-singular vectors `U` of this SVD. /// The left-singular vectors `U` of this SVD.
pub u: OMatrix<T, R, R>, // TODO: should be OMatrix<T, R, DimMinimum<R, C>> pub u: OMatrix<T, R, R>, // TODO: should be OMatrix<T, R, DimMinimum<R, C>>
@ -45,7 +45,7 @@ where
impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for SVD<T, R, C> impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for SVD<T, R, C>
where where
DefaultAllocator: Allocator<C, C> + Allocator<R, R> + Allocator<DimMinimum<R, C>>, DefaultAllocator: Allocator<T, C, C> + Allocator<T, R, R> + Allocator<T, DimMinimum<R, C>>,
OMatrix<T, R, R>: Copy, OMatrix<T, R, R>: Copy,
OMatrix<T, C, C>: Copy, OMatrix<T, C, C>: Copy,
OVector<T, DimMinimum<R, C>>: Copy, OVector<T, DimMinimum<R, C>>: Copy,
@ -56,8 +56,10 @@ where
/// supported by the Singular Value Decompotition. /// supported by the Singular Value Decompotition.
pub trait SVDScalar<R: DimMin<C>, C: Dim>: Scalar pub trait SVDScalar<R: DimMin<C>, C: Dim>: Scalar
where where
DefaultAllocator: DefaultAllocator: Allocator<Self, R, R>
Allocator<R, R> + Allocator<R, C> + Allocator<DimMinimum<R, C>> + Allocator<C, C>, + Allocator<Self, R, C>
+ Allocator<Self, DimMinimum<R, C>>
+ Allocator<Self, C, C>,
{ {
/// Computes the SVD decomposition of `m`. /// Computes the SVD decomposition of `m`.
fn compute(m: OMatrix<Self, R, C>) -> Option<SVD<Self, R, C>>; fn compute(m: OMatrix<Self, R, C>) -> Option<SVD<Self, R, C>>;
@ -65,8 +67,10 @@ where
impl<T: SVDScalar<R, C>, R: DimMin<C>, C: Dim> SVD<T, R, C> impl<T: SVDScalar<R, C>, R: DimMin<C>, C: Dim> SVD<T, R, C>
where where
DefaultAllocator: DefaultAllocator: Allocator<T, R, R>
Allocator<R, R> + Allocator<R, C> + Allocator<DimMinimum<R, C>> + Allocator<C, C>, + Allocator<T, R, C>
+ Allocator<T, DimMinimum<R, C>>
+ Allocator<T, C, C>,
{ {
/// Computes the Singular Value Decomposition of `matrix`. /// Computes the Singular Value Decomposition of `matrix`.
pub fn new(m: OMatrix<T, R, C>) -> Option<Self> { pub fn new(m: OMatrix<T, R, C>) -> Option<Self> {
@ -78,10 +82,10 @@ macro_rules! svd_impl(
($t: ty, $lapack_func: path) => ( ($t: ty, $lapack_func: path) => (
impl<R: Dim, C: Dim> SVDScalar<R, C> for $t impl<R: Dim, C: Dim> SVDScalar<R, C> for $t
where R: DimMin<C>, where R: DimMin<C>,
DefaultAllocator: Allocator<R, C> + DefaultAllocator: Allocator<$t, R, C> +
Allocator<R, R> + Allocator<$t, R, R> +
Allocator<C, C> + Allocator<$t, C, C> +
Allocator<DimMinimum<R, C>> { Allocator<$t, DimMinimum<R, C>> {
fn compute(mut m: OMatrix<$t, R, C>) -> Option<SVD<$t, R, C>> { fn compute(mut m: OMatrix<$t, R, C>) -> Option<SVD<$t, R, C>> {
let (nrows, ncols) = m.shape_generic(); let (nrows, ncols) = m.shape_generic();
@ -130,16 +134,16 @@ macro_rules! svd_impl(
impl<R: DimMin<C>, C: Dim> SVD<$t, R, C> impl<R: DimMin<C>, C: Dim> SVD<$t, R, C>
// TODO: All those bounds… // TODO: All those bounds…
where DefaultAllocator: Allocator<R, C> + where DefaultAllocator: Allocator<$t, R, C> +
Allocator<C, R> + Allocator<$t, C, R> +
Allocator<U1, R> + Allocator<$t, U1, R> +
Allocator<U1, C> + Allocator<$t, U1, C> +
Allocator<R, R> + Allocator<$t, R, R> +
Allocator<DimMinimum<R, C>> + Allocator<$t, DimMinimum<R, C>> +
Allocator<DimMinimum<R, C>, R> + Allocator<$t, DimMinimum<R, C>, R> +
Allocator<DimMinimum<R, C>, C> + Allocator<$t, DimMinimum<R, C>, C> +
Allocator<R, DimMinimum<R, C>> + Allocator<$t, R, DimMinimum<R, C>> +
Allocator<C, C> { Allocator<$t, C, C> {
/// Reconstructs the matrix from its decomposition. /// Reconstructs the matrix from its decomposition.
/// ///
/// Useful if some components (e.g. some singular values) of this decomposition have /// Useful if some components (e.g. some singular values) of this decomposition have
@ -233,9 +237,9 @@ macro_rules! svd_complex_impl(
where R: DimMin<C>, where R: DimMin<C>,
S: ContiguousStorage<Complex<$t>, R, C>, S: ContiguousStorage<Complex<$t>, R, C>,
S::Alloc: OwnedAllocator<Complex<$t>, R, C, S> + S::Alloc: OwnedAllocator<Complex<$t>, R, C, S> +
Allocator<R, R> + Allocator<Complex<$t>, R, R> +
Allocator<C, C> + Allocator<Complex<$t>, C, C> +
Allocator<DimMinimum<R, C>> { Allocator<$t, DimMinimum<R, C>> {
let (nrows, ncols) = m.shape_generic(); let (nrows, ncols) = m.shape_generic();
if nrows.value() == 0 || ncols.value() == 0 { if nrows.value() == 0 || ncols.value() == 0 {

View File

@ -17,22 +17,22 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<D, D> + serde(bound(serialize = "DefaultAllocator: Allocator<T, D, D> +
Allocator<D>, Allocator<T, D>,
OVector<T, D>: Serialize, OVector<T, D>: Serialize,
OMatrix<T, D, D>: Serialize")) OMatrix<T, D, D>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<D, D> + serde(bound(deserialize = "DefaultAllocator: Allocator<T, D, D> +
Allocator<D>, Allocator<T, D>,
OVector<T, D>: Deserialize<'de>, OVector<T, D>: Deserialize<'de>,
OMatrix<T, D, D>: Deserialize<'de>")) OMatrix<T, D, D>: Deserialize<'de>"))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SymmetricEigen<T: Scalar, D: Dim> pub struct SymmetricEigen<T: Scalar, D: Dim>
where where
DefaultAllocator: Allocator<D> + Allocator<D, D>, DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{ {
/// The eigenvectors of the decomposed matrix. /// The eigenvectors of the decomposed matrix.
pub eigenvectors: OMatrix<T, D, D>, pub eigenvectors: OMatrix<T, D, D>,
@ -43,7 +43,7 @@ where
impl<T: Scalar + Copy, D: Dim> Copy for SymmetricEigen<T, D> impl<T: Scalar + Copy, D: Dim> Copy for SymmetricEigen<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OMatrix<T, D, D>: Copy, OMatrix<T, D, D>: Copy,
OVector<T, D>: Copy, OVector<T, D>: Copy,
{ {
@ -51,7 +51,7 @@ where
impl<T: SymmetricEigenScalar + RealField, D: Dim> SymmetricEigen<T, D> impl<T: SymmetricEigenScalar + RealField, D: Dim> SymmetricEigen<T, D>
where where
DefaultAllocator: Allocator<D, D> + Allocator<D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
{ {
/// Computes the eigenvalues and eigenvectors of the symmetric matrix `m`. /// Computes the eigenvalues and eigenvectors of the symmetric matrix `m`.
/// ///

View File

@ -1,24 +1,25 @@
[package] [package]
name = "nalgebra-macros" name = "nalgebra-macros"
version = "0.2.2" version = "0.2.1"
authors = ["Andreas Longva", "Sébastien Crozet <developer@crozet.re>"] authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
edition = "2018" edition = "2018"
description = "Procedural macros for nalgebra" description = "Procedural macros for nalgebra"
documentation = "https://www.nalgebra.org/docs" documentation = "https://www.nalgebra.org/docs"
homepage = "https://nalgebra.org" homepage = "https://nalgebra.org"
repository = "https://github.com/dimforge/nalgebra" repository = "https://github.com/dimforge/nalgebra"
readme = "../README.md" readme = "../README.md"
categories = ["science", "mathematics"] categories = [ "science", "mathematics" ]
keywords = ["linear", "algebra", "matrix", "vector", "math"] keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
license = "Apache-2.0" license = "Apache-2.0"
[lib] [lib]
proc-macro = true proc-macro = true
[dependencies] [dependencies]
syn = { version = "2.0", features = ["full"] } syn = { version="1.0", features = ["full"] }
quote = "1.0" quote = "1.0"
proc-macro2 = "1.0" proc-macro2 = "1.0"
[dev-dependencies] [dev-dependencies]
nalgebra = { version = "0.33", path = ".." } nalgebra = { version = "0.32.0", path = ".." }
trybuild = "1.0.42"

View File

@ -1 +0,0 @@
../LICENSE

View File

@ -12,19 +12,102 @@
future_incompatible, future_incompatible,
missing_copy_implementations, missing_copy_implementations,
missing_debug_implementations, missing_debug_implementations,
clippy::all clippy::all,
clippy::pedantic
)] )]
mod matrix_vector_impl;
mod stack_impl;
use matrix_vector_impl::{Matrix, Vector};
use crate::matrix_vector_impl::{dmatrix_impl, dvector_impl, matrix_impl, vector_impl};
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::quote; use quote::{quote, ToTokens, TokenStreamExt};
use stack_impl::stack_impl; use syn::parse::{Error, Parse, ParseStream, Result};
use syn::parse_macro_input; use syn::punctuated::Punctuated;
use syn::Expr;
use syn::{parse_macro_input, Token};
use proc_macro2::{Delimiter, Spacing, TokenStream as TokenStream2, TokenTree};
use proc_macro2::{Group, Punct};
struct Matrix {
// Represent the matrix as a row-major vector of vectors of expressions
rows: Vec<Vec<Expr>>,
ncols: usize,
}
impl Matrix {
fn nrows(&self) -> usize {
self.rows.len()
}
fn ncols(&self) -> usize {
self.ncols
}
/// Produces a stream of tokens representing this matrix as a column-major nested array.
fn to_col_major_nested_array_tokens(&self) -> TokenStream2 {
let mut result = TokenStream2::new();
for j in 0..self.ncols() {
let mut col = TokenStream2::new();
let col_iter = (0..self.nrows()).map(move |i| &self.rows[i][j]);
col.append_separated(col_iter, Punct::new(',', Spacing::Alone));
result.append(Group::new(Delimiter::Bracket, col));
result.append(Punct::new(',', Spacing::Alone));
}
TokenStream2::from(TokenTree::Group(Group::new(Delimiter::Bracket, result)))
}
/// Produces a stream of tokens representing this matrix as a column-major flat array
/// (suitable for representing e.g. a `DMatrix`).
fn to_col_major_flat_array_tokens(&self) -> TokenStream2 {
let mut data = TokenStream2::new();
for j in 0..self.ncols() {
for i in 0..self.nrows() {
self.rows[i][j].to_tokens(&mut data);
data.append(Punct::new(',', Spacing::Alone));
}
}
TokenStream2::from(TokenTree::Group(Group::new(Delimiter::Bracket, data)))
}
}
type MatrixRowSyntax = Punctuated<Expr, Token![,]>;
impl Parse for Matrix {
fn parse(input: ParseStream<'_>) -> Result<Self> {
let mut rows = Vec::new();
let mut ncols = None;
while !input.is_empty() {
let row_span = input.span();
let row = MatrixRowSyntax::parse_separated_nonempty(input)?;
if let Some(ncols) = ncols {
if row.len() != ncols {
let row_idx = rows.len();
let error_msg = format!(
"Unexpected number of entries in row {}. Expected {}, found {} entries.",
row_idx,
ncols,
row.len()
);
return Err(Error::new(row_span, error_msg));
}
} else {
ncols = Some(row.len());
}
rows.push(row.into_iter().collect());
// We've just read a row, so if there are more tokens, there must be a semi-colon,
// otherwise the input is malformed
if !input.is_empty() {
input.parse::<Token![;]>()?;
}
}
Ok(Self {
rows,
ncols: ncols.unwrap_or(0),
})
}
}
/// Construct a fixed-size matrix directly from data. /// Construct a fixed-size matrix directly from data.
/// ///
@ -62,7 +145,20 @@ use syn::parse_macro_input;
/// ``` /// ```
#[proc_macro] #[proc_macro]
pub fn matrix(stream: TokenStream) -> TokenStream { pub fn matrix(stream: TokenStream) -> TokenStream {
matrix_impl(stream) let matrix = parse_macro_input!(stream as Matrix);
let row_dim = matrix.nrows();
let col_dim = matrix.ncols();
let array_tokens = matrix.to_col_major_nested_array_tokens();
// TODO: Use quote_spanned instead??
let output = quote! {
nalgebra::SMatrix::<_, #row_dim, #col_dim>
::from_array_storage(nalgebra::ArrayStorage(#array_tokens))
};
proc_macro::TokenStream::from(output)
} }
/// Construct a dynamic matrix directly from data. /// Construct a dynamic matrix directly from data.
@ -84,7 +180,55 @@ pub fn matrix(stream: TokenStream) -> TokenStream {
/// ``` /// ```
#[proc_macro] #[proc_macro]
pub fn dmatrix(stream: TokenStream) -> TokenStream { pub fn dmatrix(stream: TokenStream) -> TokenStream {
dmatrix_impl(stream) let matrix = parse_macro_input!(stream as Matrix);
let row_dim = matrix.nrows();
let col_dim = matrix.ncols();
let array_tokens = matrix.to_col_major_flat_array_tokens();
// TODO: Use quote_spanned instead??
let output = quote! {
nalgebra::DMatrix::<_>
::from_vec_storage(nalgebra::VecStorage::new(
nalgebra::Dyn(#row_dim),
nalgebra::Dyn(#col_dim),
vec!#array_tokens))
};
proc_macro::TokenStream::from(output)
}
struct Vector {
elements: Vec<Expr>,
}
impl Vector {
fn to_array_tokens(&self) -> TokenStream2 {
let mut data = TokenStream2::new();
data.append_separated(&self.elements, Punct::new(',', Spacing::Alone));
TokenStream2::from(TokenTree::Group(Group::new(Delimiter::Bracket, data)))
}
fn len(&self) -> usize {
self.elements.len()
}
}
impl Parse for Vector {
fn parse(input: ParseStream<'_>) -> Result<Self> {
// The syntax of a vector is just the syntax of a single matrix row
if input.is_empty() {
Ok(Self {
elements: Vec::new(),
})
} else {
let elements = MatrixRowSyntax::parse_terminated(input)?
.into_iter()
.collect();
Ok(Self { elements })
}
}
} }
/// Construct a fixed-size column vector directly from data. /// Construct a fixed-size column vector directly from data.
@ -108,7 +252,14 @@ pub fn dmatrix(stream: TokenStream) -> TokenStream {
/// ``` /// ```
#[proc_macro] #[proc_macro]
pub fn vector(stream: TokenStream) -> TokenStream { pub fn vector(stream: TokenStream) -> TokenStream {
vector_impl(stream) let vector = parse_macro_input!(stream as Vector);
let len = vector.len();
let array_tokens = vector.to_array_tokens();
let output = quote! {
nalgebra::SVector::<_, #len>
::from_array_storage(nalgebra::ArrayStorage([#array_tokens]))
};
proc_macro::TokenStream::from(output)
} }
/// Construct a dynamic column vector directly from data. /// Construct a dynamic column vector directly from data.
@ -128,7 +279,17 @@ pub fn vector(stream: TokenStream) -> TokenStream {
/// ``` /// ```
#[proc_macro] #[proc_macro]
pub fn dvector(stream: TokenStream) -> TokenStream { pub fn dvector(stream: TokenStream) -> TokenStream {
dvector_impl(stream) let vector = parse_macro_input!(stream as Vector);
let len = vector.len();
let array_tokens = vector.to_array_tokens();
let output = quote! {
nalgebra::DVector::<_>
::from_vec_storage(nalgebra::VecStorage::new(
nalgebra::Dyn(#len),
nalgebra::Const::<1>,
vec!#array_tokens))
};
proc_macro::TokenStream::from(output)
} }
/// Construct a fixed-size point directly from data. /// Construct a fixed-size point directly from data.
@ -160,100 +321,3 @@ pub fn point(stream: TokenStream) -> TokenStream {
}; };
proc_macro::TokenStream::from(output) proc_macro::TokenStream::from(output)
} }
/// Construct a new matrix by stacking matrices in a block matrix.
///
/// **Note: Requires the `macros` feature to be enabled (enabled by default)**.
///
/// This macro facilitates the construction of
/// [block matrices](https://en.wikipedia.org/wiki/Block_matrix)
/// by stacking blocks (matrices) using the same MATLAB-like syntax as the [`matrix!`] and
/// [`dmatrix!`] macros:
///
/// ```rust
/// # use nalgebra::stack;
/// #
/// # fn main() {
/// # let [a, b, c, d] = std::array::from_fn(|_| nalgebra::Matrix1::new(0));
/// // a, b, c and d are matrices
/// let block_matrix = stack![ a, b;
/// c, d ];
/// # }
/// ```
///
/// The resulting matrix is stack-allocated if the dimension of each block row and column
/// can be determined at compile-time, otherwise it is heap-allocated.
/// This is the case if, for every row, there is at least one matrix with a fixed number of rows,
/// and, for every column, there is at least one matrix with a fixed number of columns.
///
/// [`stack!`] also supports special syntax to indicate zero blocks in a matrix:
///
/// ```rust
/// # use nalgebra::stack;
/// #
/// # fn main() {
/// # let [a, b, c, d] = std::array::from_fn(|_| nalgebra::Matrix1::new(0));
/// // a and d are matrices
/// let block_matrix = stack![ a, 0;
/// 0, d ];
/// # }
/// ```
/// Here, the `0` literal indicates a zero matrix of implicitly defined size.
/// In order to infer the size of the zero blocks, there must be at least one matrix
/// in every row and column of the matrix.
/// In other words, no row or column can consist entirely of implicit zero blocks.
///
/// # Panics
///
/// Panics if dimensions are inconsistent and it cannot be determined at compile-time.
///
/// # Examples
///
/// ```
/// use nalgebra::{matrix, SMatrix, stack};
///
/// let a = matrix![1, 2;
/// 3, 4];
/// let b = matrix![5, 6;
/// 7, 8];
/// let c = matrix![9, 10];
///
/// let block_matrix = stack![ a, b;
/// c, 0 ];
///
/// assert_eq!(block_matrix, matrix![1, 2, 5, 6;
/// 3, 4, 7, 8;
/// 9, 10, 0, 0]);
///
/// // Verify that the resulting block matrix is stack-allocated
/// let _: SMatrix<_, 3, 4> = block_matrix;
/// ```
///
/// The example above shows how stacking stack-allocated matrices results in a stack-allocated
/// block matrix. If all row and column dimensions can not be determined at compile-time,
/// the result is instead a dynamically allocated matrix:
///
/// ```
/// use nalgebra::{dmatrix, DMatrix, Dyn, matrix, OMatrix, SMatrix, stack, U3};
///
/// # let a = matrix![1, 2; 3, 4]; let c = matrix![9, 10];
/// // a and c as before, but b is a dynamic matrix this time
/// let b = dmatrix![5, 6;
/// 7, 8];
///
/// // In this case, the number of rows can be statically inferred to be 3 (U3),
/// // but the number of columns cannot, hence it is dynamic
/// let block_matrix: OMatrix<_, U3, Dyn> = stack![ a, b;
/// c, 0 ];
///
/// // If necessary, a fully dynamic matrix (DMatrix) can be obtained by reshaping
/// let dyn_block_matrix: DMatrix<_> = block_matrix.reshape_generic(Dyn(3), Dyn(4));
/// ```
/// Note that explicitly annotating the types of `block_matrix` and `dyn_block_matrix` is
/// only made for illustrative purposes, and is not generally necessary.
///
#[proc_macro]
pub fn stack(stream: TokenStream) -> TokenStream {
let matrix = parse_macro_input!(stream as Matrix);
proc_macro::TokenStream::from(stack_impl(matrix).unwrap_or_else(syn::Error::into_compile_error))
}

View File

@ -1,201 +0,0 @@
use proc_macro::TokenStream;
use quote::{quote, ToTokens, TokenStreamExt};
use std::ops::Index;
use syn::parse::{Error, Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::Expr;
use syn::{parse_macro_input, Token};
use proc_macro2::{Delimiter, Spacing, TokenStream as TokenStream2, TokenTree};
use proc_macro2::{Group, Punct};
/// A matrix of expressions
pub struct Matrix {
// Represent the matrix data in row-major format
data: Vec<Expr>,
nrows: usize,
ncols: usize,
}
impl Index<(usize, usize)> for Matrix {
type Output = Expr;
fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
let linear_idx = self.ncols * row + col;
&self.data[linear_idx]
}
}
impl Matrix {
pub fn nrows(&self) -> usize {
self.nrows
}
pub fn ncols(&self) -> usize {
self.ncols
}
/// Produces a stream of tokens representing this matrix as a column-major nested array.
pub fn to_col_major_nested_array_tokens(&self) -> TokenStream2 {
let mut result = TokenStream2::new();
for j in 0..self.ncols() {
let mut col = TokenStream2::new();
let col_iter = (0..self.nrows()).map(|i| &self[(i, j)]);
col.append_separated(col_iter, Punct::new(',', Spacing::Alone));
result.append(Group::new(Delimiter::Bracket, col));
result.append(Punct::new(',', Spacing::Alone));
}
TokenStream2::from(TokenTree::Group(Group::new(Delimiter::Bracket, result)))
}
/// Produces a stream of tokens representing this matrix as a column-major flat array
/// (suitable for representing e.g. a `DMatrix`).
pub fn to_col_major_flat_array_tokens(&self) -> TokenStream2 {
let mut data = TokenStream2::new();
for j in 0..self.ncols() {
for i in 0..self.nrows() {
self[(i, j)].to_tokens(&mut data);
data.append(Punct::new(',', Spacing::Alone));
}
}
TokenStream2::from(TokenTree::Group(Group::new(Delimiter::Bracket, data)))
}
}
type MatrixRowSyntax = Punctuated<Expr, Token![,]>;
impl Parse for Matrix {
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
let mut data = Vec::new();
let mut ncols = None;
let mut nrows = 0;
while !input.is_empty() {
let row = MatrixRowSyntax::parse_separated_nonempty(input)?;
let row_span = row.span();
if let Some(ncols) = ncols {
if row.len() != ncols {
let error_msg = format!(
"Unexpected number of entries in row {}. Expected {}, found {} entries.",
nrows,
ncols,
row.len()
);
return Err(Error::new(row_span, error_msg));
}
} else {
ncols = Some(row.len());
}
data.extend(row.into_iter());
nrows += 1;
// We've just read a row, so if there are more tokens, there must be a semi-colon,
// otherwise the input is malformed
if !input.is_empty() {
input.parse::<Token![;]>()?;
}
}
Ok(Self {
data,
nrows,
ncols: ncols.unwrap_or(0),
})
}
}
pub struct Vector {
elements: Vec<Expr>,
}
impl Vector {
pub fn to_array_tokens(&self) -> TokenStream2 {
let mut data = TokenStream2::new();
data.append_separated(&self.elements, Punct::new(',', Spacing::Alone));
TokenStream2::from(TokenTree::Group(Group::new(Delimiter::Bracket, data)))
}
pub fn len(&self) -> usize {
self.elements.len()
}
}
impl Parse for Vector {
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
// The syntax of a vector is just the syntax of a single matrix row
if input.is_empty() {
Ok(Self {
elements: Vec::new(),
})
} else {
let elements = MatrixRowSyntax::parse_terminated(input)?
.into_iter()
.collect();
Ok(Self { elements })
}
}
}
pub fn matrix_impl(stream: TokenStream) -> TokenStream {
let matrix = parse_macro_input!(stream as Matrix);
let row_dim = matrix.nrows();
let col_dim = matrix.ncols();
let array_tokens = matrix.to_col_major_nested_array_tokens();
// TODO: Use quote_spanned instead??
let output = quote! {
nalgebra::SMatrix::<_, #row_dim, #col_dim>
::from_array_storage(nalgebra::ArrayStorage(#array_tokens))
};
proc_macro::TokenStream::from(output)
}
pub fn dmatrix_impl(stream: TokenStream) -> TokenStream {
let matrix = parse_macro_input!(stream as Matrix);
let row_dim = matrix.nrows();
let col_dim = matrix.ncols();
let array_tokens = matrix.to_col_major_flat_array_tokens();
// TODO: Use quote_spanned instead??
let output = quote! {
nalgebra::DMatrix::<_>
::from_vec_storage(nalgebra::VecStorage::new(
nalgebra::Dyn(#row_dim),
nalgebra::Dyn(#col_dim),
vec!#array_tokens))
};
proc_macro::TokenStream::from(output)
}
pub fn vector_impl(stream: TokenStream) -> TokenStream {
let vector = parse_macro_input!(stream as Vector);
let len = vector.len();
let array_tokens = vector.to_array_tokens();
let output = quote! {
nalgebra::SVector::<_, #len>
::from_array_storage(nalgebra::ArrayStorage([#array_tokens]))
};
proc_macro::TokenStream::from(output)
}
pub fn dvector_impl(stream: TokenStream) -> TokenStream {
let vector = parse_macro_input!(stream as Vector);
let len = vector.len();
let array_tokens = vector.to_array_tokens();
let output = quote! {
nalgebra::DVector::<_>
::from_vec_storage(nalgebra::VecStorage::new(
nalgebra::Dyn(#len),
nalgebra::Const::<1>,
vec!#array_tokens))
};
proc_macro::TokenStream::from(output)
}

View File

@ -1,302 +0,0 @@
use crate::Matrix;
use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::{format_ident, quote, quote_spanned};
use syn::spanned::Spanned;
use syn::{Error, Expr, Lit};
#[allow(clippy::too_many_lines)]
pub fn stack_impl(matrix: Matrix) -> syn::Result<TokenStream2> {
// The prefix is used to construct variable names
// that are extremely unlikely to collide with variable names used in e.g. expressions
// by the user. Although we could use a long, pseudo-random string, this makes the generated
// code very painful to parse, so we settle for something more semantic that is still
// very unlikely to collide
let prefix = "___na";
let n_block_rows = matrix.nrows();
let n_block_cols = matrix.ncols();
let mut output = quote! {};
// First assign data and shape for each matrix entry to variables
// (this is important so that we, for example, don't evaluate an expression more than once)
for i in 0..n_block_rows {
for j in 0..n_block_cols {
let expr = &matrix[(i, j)];
if !is_literal_zero(expr) {
let ident_block = format_ident!("{prefix}_stack_{i}_{j}_block");
let ident_shape = format_ident!("{prefix}_stack_{i}_{j}_shape");
output.extend(std::iter::once(quote_spanned! {expr.span()=>
let ref #ident_block = #expr;
let #ident_shape = #ident_block.shape_generic();
}));
}
}
}
// Determine the number of rows (dimension) in each block row,
// and write out variables that define block row dimensions and offsets into the
// output matrix
for i in 0..n_block_rows {
// The dimension of the block row is the result of trying to unify the row shape of
// all blocks in the block row
let dim = (0 ..n_block_cols)
.filter_map(|j| {
let expr = &matrix[(i, j)];
if !is_literal_zero(expr) {
let mut ident_shape = format_ident!("{prefix}_stack_{i}_{j}_shape");
ident_shape.set_span(ident_shape.span().located_at(expr.span()));
Some(quote_spanned!{expr.span()=> #ident_shape.0 })
} else {
None
}
}).reduce(|a, b| {
let expect_msg = format!("All blocks in block row {i} must have the same number of rows");
quote_spanned!{b.span()=>
<nalgebra::constraint::ShapeConstraint as nalgebra::constraint::SameNumberOfRows<_, _>>::representative(#a, #b)
.expect(#expect_msg)
}
}).ok_or(Error::new(Span::call_site(), format!("Block row {i} cannot consist entirely of implicit zero blocks.")))?;
let dim_ident = format_ident!("{prefix}_stack_row_{i}_dim");
let offset_ident = format_ident!("{prefix}_stack_row_{i}_offset");
let offset = if i == 0 {
quote! { 0 }
} else {
let prev_offset_ident = format_ident!("{prefix}_stack_row_{}_offset", i - 1);
let prev_dim_ident = format_ident!("{prefix}_stack_row_{}_dim", i - 1);
quote! { #prev_offset_ident + <_ as nalgebra::Dim>::value(&#prev_dim_ident) }
};
output.extend(std::iter::once(quote! {
let #dim_ident = #dim;
let #offset_ident = #offset;
}));
}
// Do the same thing for the block columns
for j in 0..n_block_cols {
let dim = (0 ..n_block_rows)
.filter_map(|i| {
let expr = &matrix[(i, j)];
if !is_literal_zero(expr) {
let mut ident_shape = format_ident!("{prefix}_stack_{i}_{j}_shape");
ident_shape.set_span(ident_shape.span().located_at(expr.span()));
Some(quote_spanned!{expr.span()=> #ident_shape.1 })
} else {
None
}
}).reduce(|a, b| {
let expect_msg = format!("All blocks in block column {j} must have the same number of columns");
quote_spanned!{b.span()=>
<nalgebra::constraint::ShapeConstraint as nalgebra::constraint::SameNumberOfColumns<_, _>>::representative(#a, #b)
.expect(#expect_msg)
}
}).ok_or(Error::new(Span::call_site(), format!("Block column {j} cannot consist entirely of implicit zero blocks.")))?;
let dim_ident = format_ident!("{prefix}_stack_col_{j}_dim");
let offset_ident = format_ident!("{prefix}_stack_col_{j}_offset");
let offset = if j == 0 {
quote! { 0 }
} else {
let prev_offset_ident = format_ident!("{prefix}_stack_col_{}_offset", j - 1);
let prev_dim_ident = format_ident!("{prefix}_stack_col_{}_dim", j - 1);
quote! { #prev_offset_ident + <_ as nalgebra::Dim>::value(&#prev_dim_ident) }
};
output.extend(std::iter::once(quote! {
let #dim_ident = #dim;
let #offset_ident = #offset;
}));
}
// Determine number of rows and cols in output matrix,
// by adding together dimensions of all block rows/cols
let num_rows = (0..n_block_rows)
.map(|i| {
let ident = format_ident!("{prefix}_stack_row_{i}_dim");
quote! { #ident }
})
.reduce(|a, b| {
quote! {
<_ as nalgebra::DimAdd<_>>::add(#a, #b)
}
})
.unwrap_or(quote! { nalgebra::dimension::U0 });
let num_cols = (0..n_block_cols)
.map(|j| {
let ident = format_ident!("{prefix}_stack_col_{j}_dim");
quote! { #ident }
})
.reduce(|a, b| {
quote! {
<_ as nalgebra::DimAdd<_>>::add(#a, #b)
}
})
.unwrap_or(quote! { nalgebra::dimension::U0 });
// It should be possible to use `uninitialized_generic` here instead
// however that would mean that the macro needs to generate unsafe code
// which does not seem like a great idea.
output.extend(std::iter::once(quote! {
let mut matrix = nalgebra::Matrix::zeros_generic(#num_rows, #num_cols);
}));
for i in 0..n_block_rows {
for j in 0..n_block_cols {
let row_dim = format_ident!("{prefix}_stack_row_{i}_dim");
let col_dim = format_ident!("{prefix}_stack_col_{j}_dim");
let row_offset = format_ident!("{prefix}_stack_row_{i}_offset");
let col_offset = format_ident!("{prefix}_stack_col_{j}_offset");
let expr = &matrix[(i, j)];
if !is_literal_zero(expr) {
let expr_ident = format_ident!("{prefix}_stack_{i}_{j}_block");
output.extend(std::iter::once(quote! {
let start = (#row_offset, #col_offset);
let shape = (#row_dim, #col_dim);
let input_view = #expr_ident.generic_view((0, 0), shape);
let mut output_view = matrix.generic_view_mut(start, shape);
output_view.copy_from(&input_view);
}));
}
}
}
Ok(quote! {
{
#output
matrix
}
})
}
fn is_literal_zero(expr: &Expr) -> bool {
matches!(expr,
Expr::Lit(syn::ExprLit { lit: Lit::Int(integer_literal), .. })
if integer_literal.base10_digits() == "0")
}
#[cfg(test)]
mod tests {
use crate::stack_impl::stack_impl;
use crate::Matrix;
use quote::quote;
#[test]
fn stack_simple_generation() {
let input: Matrix = syn::parse_quote![
a, 0;
0, b;
];
let result = stack_impl(input).unwrap();
let expected = quote! {{
let ref ___na_stack_0_0_block = a;
let ___na_stack_0_0_shape = ___na_stack_0_0_block.shape_generic();
let ref ___na_stack_1_1_block = b;
let ___na_stack_1_1_shape = ___na_stack_1_1_block.shape_generic();
let ___na_stack_row_0_dim = ___na_stack_0_0_shape.0;
let ___na_stack_row_0_offset = 0;
let ___na_stack_row_1_dim = ___na_stack_1_1_shape.0;
let ___na_stack_row_1_offset = ___na_stack_row_0_offset + <_ as nalgebra::Dim>::value(&___na_stack_row_0_dim);
let ___na_stack_col_0_dim = ___na_stack_0_0_shape.1;
let ___na_stack_col_0_offset = 0;
let ___na_stack_col_1_dim = ___na_stack_1_1_shape.1;
let ___na_stack_col_1_offset = ___na_stack_col_0_offset + <_ as nalgebra::Dim>::value(&___na_stack_col_0_dim);
let mut matrix = nalgebra::Matrix::zeros_generic(
<_ as nalgebra::DimAdd<_>>::add(___na_stack_row_0_dim, ___na_stack_row_1_dim),
<_ as nalgebra::DimAdd<_>>::add(___na_stack_col_0_dim, ___na_stack_col_1_dim)
);
let start = (___na_stack_row_0_offset, ___na_stack_col_0_offset);
let shape = (___na_stack_row_0_dim, ___na_stack_col_0_dim);
let input_view = ___na_stack_0_0_block.generic_view((0,0), shape);
let mut output_view = matrix.generic_view_mut(start, shape);
output_view.copy_from(&input_view);
let start = (___na_stack_row_1_offset, ___na_stack_col_1_offset);
let shape = (___na_stack_row_1_dim, ___na_stack_col_1_dim);
let input_view = ___na_stack_1_1_block.generic_view((0,0), shape);
let mut output_view = matrix.generic_view_mut(start, shape);
output_view.copy_from(&input_view);
matrix
}};
assert_eq!(format!("{result}"), format!("{}", expected));
}
#[test]
fn stack_complex_generation() {
let input: Matrix = syn::parse_quote![
a, 0, b;
0, c, d;
e, 0, 0;
];
let result = stack_impl(input).unwrap();
let expected = quote! {{
let ref ___na_stack_0_0_block = a;
let ___na_stack_0_0_shape = ___na_stack_0_0_block.shape_generic();
let ref ___na_stack_0_2_block = b;
let ___na_stack_0_2_shape = ___na_stack_0_2_block.shape_generic();
let ref ___na_stack_1_1_block = c;
let ___na_stack_1_1_shape = ___na_stack_1_1_block.shape_generic();
let ref ___na_stack_1_2_block = d;
let ___na_stack_1_2_shape = ___na_stack_1_2_block.shape_generic();
let ref ___na_stack_2_0_block = e;
let ___na_stack_2_0_shape = ___na_stack_2_0_block.shape_generic();
let ___na_stack_row_0_dim = < nalgebra :: constraint :: ShapeConstraint as nalgebra :: constraint :: SameNumberOfRows < _ , _ >> :: representative (___na_stack_0_0_shape . 0 , ___na_stack_0_2_shape . 0) . expect ("All blocks in block row 0 must have the same number of rows") ;
let ___na_stack_row_0_offset = 0;
let ___na_stack_row_1_dim = < nalgebra :: constraint :: ShapeConstraint as nalgebra :: constraint :: SameNumberOfRows < _ , _ >> :: representative (___na_stack_1_1_shape . 0 , ___na_stack_1_2_shape . 0) . expect ("All blocks in block row 1 must have the same number of rows") ;
let ___na_stack_row_1_offset = ___na_stack_row_0_offset + <_ as nalgebra::Dim>::value(&___na_stack_row_0_dim);
let ___na_stack_row_2_dim = ___na_stack_2_0_shape.0;
let ___na_stack_row_2_offset = ___na_stack_row_1_offset + <_ as nalgebra::Dim>::value(&___na_stack_row_1_dim);
let ___na_stack_col_0_dim = < nalgebra :: constraint :: ShapeConstraint as nalgebra :: constraint :: SameNumberOfColumns < _ , _ >> :: representative (___na_stack_0_0_shape . 1 , ___na_stack_2_0_shape . 1) . expect ("All blocks in block column 0 must have the same number of columns") ;
let ___na_stack_col_0_offset = 0;
let ___na_stack_col_1_dim = ___na_stack_1_1_shape.1;
let ___na_stack_col_1_offset = ___na_stack_col_0_offset + <_ as nalgebra::Dim>::value(&___na_stack_col_0_dim);
let ___na_stack_col_2_dim = < nalgebra :: constraint :: ShapeConstraint as nalgebra :: constraint :: SameNumberOfColumns < _ , _ >> :: representative (___na_stack_0_2_shape . 1 , ___na_stack_1_2_shape . 1) . expect ("All blocks in block column 2 must have the same number of columns") ;
let ___na_stack_col_2_offset = ___na_stack_col_1_offset + <_ as nalgebra::Dim>::value(&___na_stack_col_1_dim);
let mut matrix = nalgebra::Matrix::zeros_generic(
<_ as nalgebra::DimAdd<_>>::add(
<_ as nalgebra::DimAdd<_>>::add(___na_stack_row_0_dim, ___na_stack_row_1_dim),
___na_stack_row_2_dim
),
<_ as nalgebra::DimAdd<_>>::add(
<_ as nalgebra::DimAdd<_>>::add(___na_stack_col_0_dim, ___na_stack_col_1_dim),
___na_stack_col_2_dim
)
);
let start = (___na_stack_row_0_offset, ___na_stack_col_0_offset);
let shape = (___na_stack_row_0_dim, ___na_stack_col_0_dim);
let input_view = ___na_stack_0_0_block.generic_view((0,0), shape);
let mut output_view = matrix.generic_view_mut(start, shape);
output_view.copy_from(&input_view);
let start = (___na_stack_row_0_offset, ___na_stack_col_2_offset);
let shape = (___na_stack_row_0_dim, ___na_stack_col_2_dim);
let input_view = ___na_stack_0_2_block.generic_view((0,0), shape);
let mut output_view = matrix.generic_view_mut(start, shape);
output_view.copy_from(&input_view);
let start = (___na_stack_row_1_offset, ___na_stack_col_1_offset);
let shape = (___na_stack_row_1_dim, ___na_stack_col_1_dim);
let input_view = ___na_stack_1_1_block.generic_view((0,0), shape);
let mut output_view = matrix.generic_view_mut(start, shape);
output_view.copy_from(&input_view);
let start = (___na_stack_row_1_offset, ___na_stack_col_2_offset);
let shape = (___na_stack_row_1_dim, ___na_stack_col_2_dim);
let input_view = ___na_stack_1_2_block.generic_view((0,0), shape);
let mut output_view = matrix.generic_view_mut(start, shape);
output_view.copy_from(&input_view);
let start = (___na_stack_row_2_offset, ___na_stack_col_0_offset);
let shape = (___na_stack_row_2_dim, ___na_stack_col_0_dim);
let input_view = ___na_stack_2_0_block.generic_view((0,0), shape);
let mut output_view = matrix.generic_view_mut(start, shape);
output_view.copy_from(&input_view);
matrix
}};
assert_eq!(format!("{result}"), format!("{}", expected));
}
}

View File

@ -1,4 +1,3 @@
use crate::macros::assert_eq_and_type;
use nalgebra::{ use nalgebra::{
DMatrix, DVector, Matrix1x2, Matrix1x3, Matrix1x4, Matrix2, Matrix2x1, Matrix2x3, Matrix2x4, DMatrix, DVector, Matrix1x2, Matrix1x3, Matrix1x4, Matrix2, Matrix2x1, Matrix2x3, Matrix2x4,
Matrix3, Matrix3x1, Matrix3x2, Matrix3x4, Matrix4, Matrix4x1, Matrix4x2, Matrix4x3, Point, Matrix3, Matrix3x1, Matrix3x2, Matrix3x4, Matrix4, Matrix4x1, Matrix4x2, Matrix4x3, Point,
@ -7,6 +6,16 @@ use nalgebra::{
}; };
use nalgebra_macros::{dmatrix, dvector, matrix, point, vector}; use nalgebra_macros::{dmatrix, dvector, matrix, point, vector};
fn check_statically_same_type<T>(_: &T, _: &T) {}
/// Wrapper for `assert_eq` that also asserts that the types are the same
macro_rules! assert_eq_and_type {
($left:expr, $right:expr $(,)?) => {
check_statically_same_type(&$left, &$right);
assert_eq!($left, $right);
};
}
// Skip rustfmt because it just makes the test bloated without making it more readable // Skip rustfmt because it just makes the test bloated without making it more readable
#[rustfmt::skip] #[rustfmt::skip]
#[test] #[test]
@ -160,7 +169,7 @@ fn matrix_trybuild_tests() {
let t = trybuild::TestCases::new(); let t = trybuild::TestCases::new();
// Verify error message when we give a matrix with mismatched dimensions // Verify error message when we give a matrix with mismatched dimensions
t.compile_fail("tests/macros/trybuild/matrix_mismatched_dimensions.rs"); t.compile_fail("tests/trybuild/matrix_mismatched_dimensions.rs");
} }
#[test] #[test]
@ -168,7 +177,7 @@ fn dmatrix_trybuild_tests() {
let t = trybuild::TestCases::new(); let t = trybuild::TestCases::new();
// Verify error message when we give a matrix with mismatched dimensions // Verify error message when we give a matrix with mismatched dimensions
t.compile_fail("tests/macros/trybuild/dmatrix_mismatched_dimensions.rs"); t.compile_fail("tests/trybuild/dmatrix_mismatched_dimensions.rs");
} }
#[test] #[test]
@ -279,7 +288,7 @@ fn dmatrix_arbitrary_expressions() {
let a = dmatrix![1 + 2 , 2 * 3; let a = dmatrix![1 + 2 , 2 * 3;
4 * f(5 + 6), 7 - 8 * 9]; 4 * f(5 + 6), 7 - 8 * 9];
let a_expected = DMatrix::from_row_slice(2, 2, &[1 + 2 , 2 * 3, let a_expected = DMatrix::from_row_slice(2, 2, &[1 + 2 , 2 * 3,
4 * f(5 + 6), 7 - 8 * 9]); 4 * f(5 + 6), 7 - 8 * 9]);
assert_eq_and_type!(a, a_expected); assert_eq_and_type!(a, a_expected);
} }

View File

@ -1,4 +1,4 @@
use nalgebra::dmatrix; use nalgebra_macros::dmatrix;
fn main() { fn main() {
dmatrix![1, 2, 3; dmatrix![1, 2, 3;

View File

@ -1,5 +1,5 @@
error: Unexpected number of entries in row 1. Expected 3, found 2 entries. error: Unexpected number of entries in row 1. Expected 3, found 2 entries.
--> tests/macros/trybuild/dmatrix_mismatched_dimensions.rs:5:13 --> $DIR/dmatrix_mismatched_dimensions.rs:5:13
| |
5 | 4, 5]; 5 | 4, 5];
| ^ | ^

View File

@ -1,4 +1,4 @@
use nalgebra::matrix; use nalgebra_macros::matrix;
fn main() { fn main() {
matrix![1, 2, 3; matrix![1, 2, 3;

View File

@ -1,5 +1,5 @@
error: Unexpected number of entries in row 1. Expected 3, found 2 entries. error: Unexpected number of entries in row 1. Expected 3, found 2 entries.
--> tests/macros/trybuild/matrix_mismatched_dimensions.rs:5:13 --> $DIR/matrix_mismatched_dimensions.rs:5:13
| |
5 | 4, 5]; 5 | 4, 5];
| ^ | ^

View File

@ -1,44 +1,44 @@
[package] [package]
name = "nalgebra-sparse" name = "nalgebra-sparse"
version = "0.10.0" version = "0.9.0"
authors = ["Andreas Longva", "Sébastien Crozet <developer@crozet.re>"] authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
edition = "2018" edition = "2018"
description = "Sparse matrix computation based on nalgebra." description = "Sparse matrix computation based on nalgebra."
documentation = "https://www.nalgebra.org/docs" documentation = "https://www.nalgebra.org/docs"
homepage = "https://nalgebra.org" homepage = "https://nalgebra.org"
repository = "https://github.com/dimforge/nalgebra" repository = "https://github.com/dimforge/nalgebra"
readme = "../README.md" readme = "../README.md"
categories = ["science", "mathematics", "wasm", "no-std"] categories = [ "science", "mathematics", "wasm", "no-std" ]
keywords = ["linear", "algebra", "matrix", "vector", "math"] keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
license = "Apache-2.0" license = "Apache-2.0"
[features] [features]
proptest-support = ["proptest", "nalgebra/proptest-support"] proptest-support = ["proptest", "nalgebra/proptest-support"]
compare = ["matrixcompare-core"] compare = [ "matrixcompare-core" ]
serde-serialize = ["serde/std"] serde-serialize = [ "serde/std" ]
# Enable matrix market I/O # Enable matrix market I/O
io = ["pest", "pest_derive"] io = [ "pest", "pest_derive" ]
# Enable to enable running some tests that take a lot of time to run # Enable to enable running some tests that take a lot of time to run
slow-tests = [] slow-tests = []
[dependencies] [dependencies]
nalgebra = { version = "0.33", path = "../" } nalgebra = { version="0.32", path = "../" }
num-traits = { version = "0.2", default-features = false } num-traits = { version = "0.2", default-features = false }
proptest = { version = "1.0", optional = true } proptest = { version = "1.0", optional = true }
matrixcompare-core = { version = "0.1.0", optional = true } matrixcompare-core = { version = "0.1.0", optional = true }
pest = { version = "2", optional = true } pest = { version = "2", optional = true }
pest_derive = { version = "2", optional = true } pest_derive = { version = "2", optional = true }
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } serde = { version = "1.0", default-features = false, features = [ "derive" ], optional = true }
[dev-dependencies] [dev-dependencies]
itertools = "0.13" itertools = "0.10"
matrixcompare = { version = "0.3.0", features = ["proptest-support"] } matrixcompare = { version = "0.3.0", features = [ "proptest-support" ] }
nalgebra = { version = "0.33", path = "../", features = ["compare"] } nalgebra = { version="0.32", path = "../", features = ["compare"] }
tempfile = "3.3" tempfile = "3.3"
serde_json = "1.0" serde_json = "1.0"
[package.metadata.docs.rs] [package.metadata.docs.rs]
# Enable certain features when building docs for docs.rs # Enable certain features when building docs for docs.rs
features = ["proptest-support", "compare", "io"] features = [ "proptest-support", "compare", "io"]

View File

@ -1 +0,0 @@
../LICENSE

View File

@ -3,7 +3,7 @@ use crate::coo::CooMatrix;
use crate::csc::CscMatrix; use crate::csc::CscMatrix;
use crate::csr::CsrMatrix; use crate::csr::CsrMatrix;
use nalgebra::storage::RawStorage; use nalgebra::storage::RawStorage;
use nalgebra::{ClosedAddAssign, DMatrix, Dim, Matrix, Scalar}; use nalgebra::{ClosedAdd, DMatrix, Dim, Matrix, Scalar};
use num_traits::Zero; use num_traits::Zero;
impl<'a, T, R, C, S> From<&'a Matrix<T, R, C, S>> for CooMatrix<T> impl<'a, T, R, C, S> From<&'a Matrix<T, R, C, S>> for CooMatrix<T>
@ -20,7 +20,7 @@ where
impl<'a, T> From<&'a CooMatrix<T>> for DMatrix<T> impl<'a, T> From<&'a CooMatrix<T>> for DMatrix<T>
where where
T: Scalar + Zero + ClosedAddAssign, T: Scalar + Zero + ClosedAdd,
{ {
fn from(coo: &'a CooMatrix<T>) -> Self { fn from(coo: &'a CooMatrix<T>) -> Self {
convert_coo_dense(coo) convert_coo_dense(coo)
@ -29,7 +29,7 @@ where
impl<'a, T> From<&'a CooMatrix<T>> for CsrMatrix<T> impl<'a, T> From<&'a CooMatrix<T>> for CsrMatrix<T>
where where
T: Scalar + Zero + ClosedAddAssign, T: Scalar + Zero + ClosedAdd,
{ {
fn from(matrix: &'a CooMatrix<T>) -> Self { fn from(matrix: &'a CooMatrix<T>) -> Self {
convert_coo_csr(matrix) convert_coo_csr(matrix)
@ -38,7 +38,7 @@ where
impl<'a, T> From<&'a CsrMatrix<T>> for CooMatrix<T> impl<'a, T> From<&'a CsrMatrix<T>> for CooMatrix<T>
where where
T: Scalar + Zero + ClosedAddAssign, T: Scalar + Zero + ClosedAdd,
{ {
fn from(matrix: &'a CsrMatrix<T>) -> Self { fn from(matrix: &'a CsrMatrix<T>) -> Self {
convert_csr_coo(matrix) convert_csr_coo(matrix)
@ -59,7 +59,7 @@ where
impl<'a, T> From<&'a CsrMatrix<T>> for DMatrix<T> impl<'a, T> From<&'a CsrMatrix<T>> for DMatrix<T>
where where
T: Scalar + Zero + ClosedAddAssign, T: Scalar + Zero + ClosedAdd,
{ {
fn from(matrix: &'a CsrMatrix<T>) -> Self { fn from(matrix: &'a CsrMatrix<T>) -> Self {
convert_csr_dense(matrix) convert_csr_dense(matrix)
@ -68,7 +68,7 @@ where
impl<'a, T> From<&'a CooMatrix<T>> for CscMatrix<T> impl<'a, T> From<&'a CooMatrix<T>> for CscMatrix<T>
where where
T: Scalar + Zero + ClosedAddAssign, T: Scalar + Zero + ClosedAdd,
{ {
fn from(matrix: &'a CooMatrix<T>) -> Self { fn from(matrix: &'a CooMatrix<T>) -> Self {
convert_coo_csc(matrix) convert_coo_csc(matrix)
@ -98,7 +98,7 @@ where
impl<'a, T> From<&'a CscMatrix<T>> for DMatrix<T> impl<'a, T> From<&'a CscMatrix<T>> for DMatrix<T>
where where
T: Scalar + Zero + ClosedAddAssign, T: Scalar + Zero + ClosedAdd,
{ {
fn from(matrix: &'a CscMatrix<T>) -> Self { fn from(matrix: &'a CscMatrix<T>) -> Self {
convert_csc_dense(matrix) convert_csc_dense(matrix)

View File

@ -8,7 +8,7 @@ use std::ops::Add;
use num_traits::Zero; use num_traits::Zero;
use nalgebra::storage::RawStorage; use nalgebra::storage::RawStorage;
use nalgebra::{ClosedAddAssign, DMatrix, Dim, Matrix, Scalar}; use nalgebra::{ClosedAdd, DMatrix, Dim, Matrix, Scalar};
use crate::coo::CooMatrix; use crate::coo::CooMatrix;
use crate::cs; use crate::cs;
@ -41,7 +41,7 @@ where
/// Converts a [`CooMatrix`] to a dense matrix. /// Converts a [`CooMatrix`] to a dense matrix.
pub fn convert_coo_dense<T>(coo: &CooMatrix<T>) -> DMatrix<T> pub fn convert_coo_dense<T>(coo: &CooMatrix<T>) -> DMatrix<T>
where where
T: Scalar + Zero + ClosedAddAssign, T: Scalar + Zero + ClosedAdd,
{ {
let mut output = DMatrix::repeat(coo.nrows(), coo.ncols(), T::zero()); let mut output = DMatrix::repeat(coo.nrows(), coo.ncols(), T::zero());
for (i, j, v) in coo.triplet_iter() { for (i, j, v) in coo.triplet_iter() {
@ -80,7 +80,7 @@ pub fn convert_csr_coo<T: Scalar>(csr: &CsrMatrix<T>) -> CooMatrix<T> {
/// Converts a [`CsrMatrix`] to a dense matrix. /// Converts a [`CsrMatrix`] to a dense matrix.
pub fn convert_csr_dense<T>(csr: &CsrMatrix<T>) -> DMatrix<T> pub fn convert_csr_dense<T>(csr: &CsrMatrix<T>) -> DMatrix<T>
where where
T: Scalar + ClosedAddAssign + Zero, T: Scalar + ClosedAdd + Zero,
{ {
let mut output = DMatrix::zeros(csr.nrows(), csr.ncols()); let mut output = DMatrix::zeros(csr.nrows(), csr.ncols());
@ -157,7 +157,7 @@ where
/// Converts a [`CscMatrix`] to a dense matrix. /// Converts a [`CscMatrix`] to a dense matrix.
pub fn convert_csc_dense<T>(csc: &CscMatrix<T>) -> DMatrix<T> pub fn convert_csc_dense<T>(csc: &CscMatrix<T>) -> DMatrix<T>
where where
T: Scalar + ClosedAddAssign + Zero, T: Scalar + ClosedAdd + Zero,
{ {
let mut output = DMatrix::zeros(csc.nrows(), csc.ncols()); let mut output = DMatrix::zeros(csc.nrows(), csc.ncols());
@ -306,7 +306,7 @@ where
|val| sorted_vals.push(val), |val| sorted_vals.push(val),
&idx_workspace[..count], &idx_workspace[..count],
&values_workspace[..count], &values_workspace[..count],
Add::add, &Add::add,
); );
let new_col_count = sorted_minor_idx.len() - sorted_ja_current_len; let new_col_count = sorted_minor_idx.len() - sorted_ja_current_len;

View File

@ -160,25 +160,6 @@ impl<T> CooMatrix<T> {
} }
} }
/// Try to construct a COO matrix from the given dimensions and a finite iterator of
/// (i, j, v) triplets.
///
/// Returns an error if either row or column indices contain indices out of bounds.
/// Note that the COO format inherently supports duplicate entries, but they are not
/// eagerly summed.
///
/// Implementation note:
/// Calls try_from_triplets so each value is scanned twice.
pub fn try_from_triplets_iter(
nrows: usize,
ncols: usize,
triplets: impl IntoIterator<Item = (usize, usize, T)>,
) -> Result<Self, SparseFormatError> {
let (row_indices, (col_indices, values)) =
triplets.into_iter().map(|(r, c, v)| (r, (c, v))).unzip();
Self::try_from_triplets(nrows, ncols, row_indices, col_indices, values)
}
/// An iterator over triplets (i, j, v). /// An iterator over triplets (i, j, v).
// TODO: Consider giving the iterator a concrete type instead of impl trait...? // TODO: Consider giving the iterator a concrete type instead of impl trait...?
pub fn triplet_iter(&self) -> impl Iterator<Item = (usize, usize, &T)> { pub fn triplet_iter(&self) -> impl Iterator<Item = (usize, usize, &T)> {

View File

@ -1,3 +1,4 @@
use std::mem::replace;
use std::ops::Range; use std::ops::Range;
use num_traits::One; use num_traits::One;
@ -225,15 +226,6 @@ impl<T> CsMatrix<T> {
} }
} }
impl<T> Default for CsMatrix<T> {
fn default() -> Self {
Self {
sparsity_pattern: Default::default(),
values: vec![],
}
}
}
impl<T: Scalar + One> CsMatrix<T> { impl<T: Scalar + One> CsMatrix<T> {
#[inline] #[inline]
pub fn identity(n: usize) -> Self { pub fn identity(n: usize) -> Self {
@ -368,7 +360,7 @@ where
if let Some(minor_indices) = lane { if let Some(minor_indices) = lane {
let count = minor_indices.len(); let count = minor_indices.len();
let remaining = std::mem::take(&mut self.remaining_values); let remaining = replace(&mut self.remaining_values, &mut []);
let (values_in_lane, remaining) = remaining.split_at_mut(count); let (values_in_lane, remaining) = remaining.split_at_mut(count);
self.remaining_values = remaining; self.remaining_values = remaining;
self.current_lane_idx += 1; self.current_lane_idx += 1;
@ -577,7 +569,7 @@ where
} else if sort { } else if sort {
unreachable!("Internal error: Sorting currently not supported if no values are present."); unreachable!("Internal error: Sorting currently not supported if no values are present.");
} }
if major_offsets.is_empty() { if major_offsets.len() == 0 {
return Err(SparseFormatError::from_kind_and_msg( return Err(SparseFormatError::from_kind_and_msg(
SparseFormatErrorKind::InvalidStructure, SparseFormatErrorKind::InvalidStructure,
"Number of offsets should be greater than 0.", "Number of offsets should be greater than 0.",
@ -623,12 +615,12 @@ where
)); ));
} }
let minor_idx_in_lane = minor_indices.get(range_start..range_end).ok_or_else(|| { let minor_idx_in_lane = minor_indices.get(range_start..range_end).ok_or(
SparseFormatError::from_kind_and_msg( SparseFormatError::from_kind_and_msg(
SparseFormatErrorKind::IndexOutOfBounds, SparseFormatErrorKind::IndexOutOfBounds,
"A major offset is out of bounds.", "A major offset is out of bounds.",
) ),
})?; )?;
// We test for in-bounds, uniqueness and monotonicity at the same time // We test for in-bounds, uniqueness and monotonicity at the same time
// to ensure that we only visit each minor index once // to ensure that we only visit each minor index once
@ -661,9 +653,9 @@ where
if !monotonic && sort { if !monotonic && sort {
let range_size = range_end - range_start; let range_size = range_end - range_start;
minor_index_permutation.resize(range_size, 0); minor_index_permutation.resize(range_size, 0);
compute_sort_permutation(&mut minor_index_permutation, minor_idx_in_lane); compute_sort_permutation(&mut minor_index_permutation, &minor_idx_in_lane);
minor_idx_buffer.clear(); minor_idx_buffer.clear();
minor_idx_buffer.extend_from_slice(minor_idx_in_lane); minor_idx_buffer.extend_from_slice(&minor_idx_in_lane);
apply_permutation( apply_permutation(
&mut minor_indices[range_start..range_end], &mut minor_indices[range_start..range_end],
&minor_idx_buffer, &minor_idx_buffer,

View File

@ -158,7 +158,7 @@ impl<T> CscMatrix<T> {
/// an error is returned to indicate the failure. /// an error is returned to indicate the failure.
/// ///
/// An error is returned if the data given does not conform to the CSC storage format. /// An error is returned if the data given does not conform to the CSC storage format.
/// See the documentation for [`CscMatrix`] for more information. /// See the documentation for [CscMatrix](struct.CscMatrix.html) for more information.
pub fn try_from_csc_data( pub fn try_from_csc_data(
num_rows: usize, num_rows: usize,
num_cols: usize, num_cols: usize,
@ -184,7 +184,7 @@ impl<T> CscMatrix<T> {
/// ///
/// An error is returned if the data given does not conform to the CSC storage format /// An error is returned if the data given does not conform to the CSC storage format
/// with the exception of having unsorted row indices and values. /// with the exception of having unsorted row indices and values.
/// See the documentation for [`CscMatrix`] for more information. /// See the documentation for [CscMatrix](struct.CscMatrix.html) for more information.
pub fn try_from_unsorted_csc_data( pub fn try_from_unsorted_csc_data(
num_rows: usize, num_rows: usize,
num_cols: usize, num_cols: usize,
@ -574,14 +574,6 @@ impl<T> CscMatrix<T> {
} }
} }
impl<T> Default for CscMatrix<T> {
fn default() -> Self {
Self {
cs: Default::default(),
}
}
}
/// Convert pattern format errors into more meaningful CSC-specific errors. /// Convert pattern format errors into more meaningful CSC-specific errors.
/// ///
/// This ensures that the terminology is consistent: we are talking about rows and columns, /// This ensures that the terminology is consistent: we are talking about rows and columns,
@ -625,15 +617,6 @@ pub struct CscTripletIter<'a, T> {
values_iter: Iter<'a, T>, values_iter: Iter<'a, T>,
} }
impl<'a, T> Clone for CscTripletIter<'a, T> {
fn clone(&self) -> Self {
CscTripletIter {
pattern_iter: self.pattern_iter.clone(),
values_iter: self.values_iter.clone(),
}
}
}
impl<'a, T: Clone> CscTripletIter<'a, T> { impl<'a, T: Clone> CscTripletIter<'a, T> {
/// Adapts the triplet iterator to return owned values. /// Adapts the triplet iterator to return owned values.
/// ///
@ -765,7 +748,7 @@ impl<'a, T> CscColMut<'a, T> {
} }
} }
/// Column iterator for [`CscMatrix`]. /// Column iterator for [CscMatrix](struct.CscMatrix.html).
pub struct CscColIter<'a, T> { pub struct CscColIter<'a, T> {
lane_iter: CsLaneIter<'a, T>, lane_iter: CsLaneIter<'a, T>,
} }
@ -778,7 +761,7 @@ impl<'a, T> Iterator for CscColIter<'a, T> {
} }
} }
/// Mutable column iterator for [`CscMatrix`]. /// Mutable column iterator for [CscMatrix](struct.CscMatrix.html).
pub struct CscColIterMut<'a, T> { pub struct CscColIterMut<'a, T> {
lane_iter: CsLaneIterMut<'a, T>, lane_iter: CsLaneIterMut<'a, T>,
} }

View File

@ -159,7 +159,7 @@ impl<T> CsrMatrix<T> {
/// an error is returned to indicate the failure. /// an error is returned to indicate the failure.
/// ///
/// An error is returned if the data given does not conform to the CSR storage format. /// An error is returned if the data given does not conform to the CSR storage format.
/// See the documentation for [`CsrMatrix`] for more information. /// See the documentation for [CsrMatrix](struct.CsrMatrix.html) for more information.
pub fn try_from_csr_data( pub fn try_from_csr_data(
num_rows: usize, num_rows: usize,
num_cols: usize, num_cols: usize,
@ -185,7 +185,7 @@ impl<T> CsrMatrix<T> {
/// ///
/// An error is returned if the data given does not conform to the CSR storage format /// An error is returned if the data given does not conform to the CSR storage format
/// with the exception of having unsorted column indices and values. /// with the exception of having unsorted column indices and values.
/// See the documentation for [`CsrMatrix`] for more information. /// See the documentation for [CsrMatrix](struct.CsrMatrix.html) for more information.
pub fn try_from_unsorted_csr_data( pub fn try_from_unsorted_csr_data(
num_rows: usize, num_rows: usize,
num_cols: usize, num_cols: usize,
@ -575,14 +575,6 @@ impl<T> CsrMatrix<T> {
} }
} }
impl<T> Default for CsrMatrix<T> {
fn default() -> Self {
Self {
cs: Default::default(),
}
}
}
/// Convert pattern format errors into more meaningful CSR-specific errors. /// Convert pattern format errors into more meaningful CSR-specific errors.
/// ///
/// This ensures that the terminology is consistent: we are talking about rows and columns, /// This ensures that the terminology is consistent: we are talking about rows and columns,
@ -626,15 +618,6 @@ pub struct CsrTripletIter<'a, T> {
values_iter: Iter<'a, T>, values_iter: Iter<'a, T>,
} }
impl<'a, T> Clone for CsrTripletIter<'a, T> {
fn clone(&self) -> Self {
CsrTripletIter {
pattern_iter: self.pattern_iter.clone(),
values_iter: self.values_iter.clone(),
}
}
}
impl<'a, T: Clone> CsrTripletIter<'a, T> { impl<'a, T: Clone> CsrTripletIter<'a, T> {
/// Adapts the triplet iterator to return owned values. /// Adapts the triplet iterator to return owned values.
/// ///
@ -770,7 +753,7 @@ impl<'a, T> CsrRowMut<'a, T> {
} }
} }
/// Row iterator for [`CsrMatrix`]. /// Row iterator for [CsrMatrix](struct.CsrMatrix.html).
pub struct CsrRowIter<'a, T> { pub struct CsrRowIter<'a, T> {
lane_iter: CsLaneIter<'a, T>, lane_iter: CsLaneIter<'a, T>,
} }
@ -783,7 +766,7 @@ impl<'a, T> Iterator for CsrRowIter<'a, T> {
} }
} }
/// Mutable row iterator for [`CsrMatrix`]. /// Mutable row iterator for [CsrMatrix](struct.CsrMatrix.html).
pub struct CsrRowIterMut<'a, T> { pub struct CsrRowIterMut<'a, T> {
lane_iter: CsLaneIterMut<'a, T>, lane_iter: CsLaneIterMut<'a, T>,
} }

View File

@ -199,7 +199,7 @@ impl SparseFormatError {
} }
} }
/// The type of format error described by a [`SparseFormatError`]. /// The type of format error described by a [SparseFormatError](struct.SparseFormatError.html).
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SparseFormatErrorKind { pub enum SparseFormatErrorKind {

View File

@ -10,8 +10,8 @@ use nalgebra::allocator::Allocator;
use nalgebra::base::storage::RawStorage; use nalgebra::base::storage::RawStorage;
use nalgebra::constraint::{DimEq, ShapeConstraint}; use nalgebra::constraint::{DimEq, ShapeConstraint};
use nalgebra::{ use nalgebra::{
ClosedAddAssign, ClosedDivAssign, ClosedMulAssign, ClosedSubAssign, DefaultAllocator, Dim, Dyn, ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dyn, Matrix, OMatrix,
Matrix, OMatrix, Scalar, U1, Scalar, U1,
}; };
use num_traits::{One, Zero}; use num_traits::{One, Zero};
use std::ops::{Add, Div, DivAssign, Mul, MulAssign, Neg, Sub}; use std::ops::{Add, Div, DivAssign, Mul, MulAssign, Neg, Sub};
@ -28,7 +28,7 @@ macro_rules! impl_bin_op {
// Note: The Neg bound is currently required because we delegate e.g. // Note: The Neg bound is currently required because we delegate e.g.
// Sub to SpAdd with negative coefficients. This is not well-defined for // Sub to SpAdd with negative coefficients. This is not well-defined for
// unsigned data types. // unsigned data types.
$($scalar_type: $($bounds + )? Scalar + ClosedAddAssign + ClosedSubAssign + ClosedMulAssign + Zero + One + Neg<Output=T>)? $($scalar_type: $($bounds + )? Scalar + ClosedAdd + ClosedSub + ClosedMul + Zero + One + Neg<Output=T>)?
{ {
type Output = $ret; type Output = $ret;
fn $method(self, $b: $b_type) -> Self::Output { fn $method(self, $b: $b_type) -> Self::Output {
@ -59,7 +59,7 @@ macro_rules! impl_sp_plus_minus {
let mut result = $matrix_type::try_from_pattern_and_values(pattern, values) let mut result = $matrix_type::try_from_pattern_and_values(pattern, values)
.unwrap(); .unwrap();
$spadd_fn(T::zero(), &mut result, T::one(), Op::NoOp(&a)).unwrap(); $spadd_fn(T::zero(), &mut result, T::one(), Op::NoOp(&a)).unwrap();
$spadd_fn(T::one(), &mut result, $factor, Op::NoOp(&b)).unwrap(); $spadd_fn(T::one(), &mut result, $factor * T::one(), Op::NoOp(&b)).unwrap();
result result
}); });
@ -164,7 +164,7 @@ macro_rules! impl_scalar_mul {
impl<T> MulAssign<T> for $matrix_type<T> impl<T> MulAssign<T> for $matrix_type<T>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One T: Scalar + ClosedAdd + ClosedMul + Zero + One
{ {
fn mul_assign(&mut self, scalar: T) { fn mul_assign(&mut self, scalar: T) {
for val in self.values_mut() { for val in self.values_mut() {
@ -175,7 +175,7 @@ macro_rules! impl_scalar_mul {
impl<'a, T> MulAssign<&'a T> for $matrix_type<T> impl<'a, T> MulAssign<&'a T> for $matrix_type<T>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One T: Scalar + ClosedAdd + ClosedMul + Zero + One
{ {
fn mul_assign(&mut self, scalar: &'a T) { fn mul_assign(&mut self, scalar: &'a T) {
for val in self.values_mut() { for val in self.values_mut() {
@ -227,15 +227,15 @@ impl_neg!(CscMatrix);
macro_rules! impl_div { macro_rules! impl_div {
($matrix_type:ident) => { ($matrix_type:ident) => {
impl_bin_op!(Div, div, <T: ClosedDivAssign>(matrix: $matrix_type<T>, scalar: T) -> $matrix_type<T> { impl_bin_op!(Div, div, <T: ClosedDiv>(matrix: $matrix_type<T>, scalar: T) -> $matrix_type<T> {
let mut matrix = matrix; let mut matrix = matrix;
matrix /= scalar; matrix /= scalar;
matrix matrix
}); });
impl_bin_op!(Div, div, <'a, T: ClosedDivAssign>(matrix: $matrix_type<T>, scalar: &T) -> $matrix_type<T> { impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: $matrix_type<T>, scalar: &T) -> $matrix_type<T> {
matrix / scalar.clone() matrix / scalar.clone()
}); });
impl_bin_op!(Div, div, <'a, T: ClosedDivAssign>(matrix: &'a $matrix_type<T>, scalar: T) -> $matrix_type<T> { impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: &'a $matrix_type<T>, scalar: T) -> $matrix_type<T> {
let new_values = matrix.values() let new_values = matrix.values()
.iter() .iter()
.map(|v_i| v_i.clone() / scalar.clone()) .map(|v_i| v_i.clone() / scalar.clone())
@ -243,12 +243,12 @@ macro_rules! impl_div {
$matrix_type::try_from_pattern_and_values(matrix.pattern().clone(), new_values) $matrix_type::try_from_pattern_and_values(matrix.pattern().clone(), new_values)
.unwrap() .unwrap()
}); });
impl_bin_op!(Div, div, <'a, T: ClosedDivAssign>(matrix: &'a $matrix_type<T>, scalar: &'a T) -> $matrix_type<T> { impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: &'a $matrix_type<T>, scalar: &'a T) -> $matrix_type<T> {
matrix / scalar.clone() matrix / scalar.clone()
}); });
impl<T> DivAssign<T> for $matrix_type<T> impl<T> DivAssign<T> for $matrix_type<T>
where T : Scalar + ClosedAddAssign + ClosedMulAssign + ClosedDivAssign + Zero + One where T : Scalar + ClosedAdd + ClosedMul + ClosedDiv + Zero + One
{ {
fn div_assign(&mut self, scalar: T) { fn div_assign(&mut self, scalar: T) {
self.values_mut().iter_mut().for_each(|v_i| *v_i /= scalar.clone()); self.values_mut().iter_mut().for_each(|v_i| *v_i /= scalar.clone());
@ -256,7 +256,7 @@ macro_rules! impl_div {
} }
impl<'a, T> DivAssign<&'a T> for $matrix_type<T> impl<'a, T> DivAssign<&'a T> for $matrix_type<T>
where T : Scalar + ClosedAddAssign + ClosedMulAssign + ClosedDivAssign + Zero + One where T : Scalar + ClosedAdd + ClosedMul + ClosedDiv + Zero + One
{ {
fn div_assign(&mut self, scalar: &'a T) { fn div_assign(&mut self, scalar: &'a T) {
*self /= scalar.clone(); *self /= scalar.clone();
@ -298,17 +298,17 @@ macro_rules! impl_spmm_cs_dense {
{ {
impl<'a, T, R, C, S> Mul<$dense_matrix_type> for $sparse_matrix_type impl<'a, T, R, C, S> Mul<$dense_matrix_type> for $sparse_matrix_type
where where
T: Scalar + ClosedMulAssign + ClosedAddAssign + ClosedSubAssign + ClosedDivAssign + Neg + Zero + One, T: Scalar + ClosedMul + ClosedAdd + ClosedSub + ClosedDiv + Neg + Zero + One,
R: Dim, R: Dim,
C: Dim, C: Dim,
S: RawStorage<T, R, C>, S: RawStorage<T, R, C>,
DefaultAllocator: Allocator<Dyn, C>, DefaultAllocator: Allocator<T, Dyn, C>,
// TODO: Is it possible to simplify these bounds? // TODO: Is it possible to simplify these bounds?
ShapeConstraint: ShapeConstraint:
// Bounds so that we can turn OMatrix<T, Dyn, C> into a DMatrixSliceMut // Bounds so that we can turn OMatrix<T, Dyn, C> into a DMatrixSliceMut
DimEq<U1, <<DefaultAllocator as Allocator<Dyn, C>>::Buffer<T> as RawStorage<T, Dyn, C>>::RStride> DimEq<U1, <<DefaultAllocator as Allocator<T, Dyn, C>>::Buffer as RawStorage<T, Dyn, C>>::RStride>
+ DimEq<C, Dyn> + DimEq<C, Dyn>
+ DimEq<Dyn, <<DefaultAllocator as Allocator<Dyn, C>>::Buffer<T> as RawStorage<T, Dyn, C>>::CStride> + DimEq<Dyn, <<DefaultAllocator as Allocator<T, Dyn, C>>::Buffer as RawStorage<T, Dyn, C>>::CStride>
// Bounds so that we can turn &Matrix<T, R, C, S> into a DMatrixSlice // Bounds so that we can turn &Matrix<T, R, C, S> into a DMatrixSlice
+ DimEq<U1, S::RStride> + DimEq<U1, S::RStride>
+ DimEq<R, Dyn> + DimEq<R, Dyn>

View File

@ -149,8 +149,8 @@ impl<T> Op<T> {
#[must_use] #[must_use]
pub fn as_ref(&self) -> Op<&T> { pub fn as_ref(&self) -> Op<&T> {
match self { match self {
Op::NoOp(obj) => Op::NoOp(obj), Op::NoOp(obj) => Op::NoOp(&obj),
Op::Transpose(obj) => Op::Transpose(obj), Op::Transpose(obj) => Op::Transpose(&obj),
} }
} }

View File

@ -2,7 +2,7 @@ use crate::cs::CsMatrix;
use crate::ops::serial::{OperationError, OperationErrorKind}; use crate::ops::serial::{OperationError, OperationErrorKind};
use crate::ops::Op; use crate::ops::Op;
use crate::SparseEntryMut; use crate::SparseEntryMut;
use nalgebra::{ClosedAddAssign, ClosedMulAssign, DMatrixView, DMatrixViewMut, Scalar}; use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, Scalar};
use num_traits::{One, Zero}; use num_traits::{One, Zero};
fn spmm_cs_unexpected_entry() -> OperationError { fn spmm_cs_unexpected_entry() -> OperationError {
@ -28,7 +28,7 @@ pub fn spmm_cs_prealloc_unchecked<T>(
b: &CsMatrix<T>, b: &CsMatrix<T>,
) -> Result<(), OperationError> ) -> Result<(), OperationError>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
assert_eq!(c.pattern().major_dim(), a.pattern().major_dim()); assert_eq!(c.pattern().major_dim(), a.pattern().major_dim());
assert_eq!(c.pattern().minor_dim(), b.pattern().minor_dim()); assert_eq!(c.pattern().minor_dim(), b.pattern().minor_dim());
@ -73,7 +73,7 @@ pub fn spmm_cs_prealloc<T>(
b: &CsMatrix<T>, b: &CsMatrix<T>,
) -> Result<(), OperationError> ) -> Result<(), OperationError>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
for i in 0..c.pattern().major_dim() { for i in 0..c.pattern().major_dim() {
let a_lane_i = a.get_lane(i).unwrap(); let a_lane_i = a.get_lane(i).unwrap();
@ -119,7 +119,7 @@ pub fn spadd_cs_prealloc<T>(
a: Op<&CsMatrix<T>>, a: Op<&CsMatrix<T>>,
) -> Result<(), OperationError> ) -> Result<(), OperationError>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
match a { match a {
Op::NoOp(a) => { Op::NoOp(a) => {
@ -181,7 +181,7 @@ pub fn spmm_cs_dense<T>(
a: Op<&CsMatrix<T>>, a: Op<&CsMatrix<T>>,
b: Op<DMatrixView<'_, T>>, b: Op<DMatrixView<'_, T>>,
) where ) where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
match a { match a {
Op::NoOp(a) => { Op::NoOp(a) => {

View File

@ -4,7 +4,7 @@ use crate::ops::serial::cs::{
}; };
use crate::ops::serial::{OperationError, OperationErrorKind}; use crate::ops::serial::{OperationError, OperationErrorKind};
use crate::ops::Op; use crate::ops::Op;
use nalgebra::{ClosedAddAssign, ClosedMulAssign, DMatrixView, DMatrixViewMut, RealField, Scalar}; use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, RealField, Scalar};
use num_traits::{One, Zero}; use num_traits::{One, Zero};
use std::borrow::Cow; use std::borrow::Cow;
@ -21,7 +21,7 @@ pub fn spmm_csc_dense<'a, T>(
a: Op<&CscMatrix<T>>, a: Op<&CscMatrix<T>>,
b: Op<impl Into<DMatrixView<'a, T>>>, b: Op<impl Into<DMatrixView<'a, T>>>,
) where ) where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
let b = b.convert(); let b = b.convert();
spmm_csc_dense_(beta, c.into(), alpha, a, b) spmm_csc_dense_(beta, c.into(), alpha, a, b)
@ -34,7 +34,7 @@ fn spmm_csc_dense_<T>(
a: Op<&CscMatrix<T>>, a: Op<&CscMatrix<T>>,
b: Op<DMatrixView<'_, T>>, b: Op<DMatrixView<'_, T>>,
) where ) where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
assert_compatible_spmm_dims!(c, a, b); assert_compatible_spmm_dims!(c, a, b);
// Need to interpret matrix as transposed since the spmm_cs_dense function assumes CSR layout // Need to interpret matrix as transposed since the spmm_cs_dense function assumes CSR layout
@ -57,7 +57,7 @@ pub fn spadd_csc_prealloc<T>(
a: Op<&CscMatrix<T>>, a: Op<&CscMatrix<T>>,
) -> Result<(), OperationError> ) -> Result<(), OperationError>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
assert_compatible_spadd_dims!(c, a); assert_compatible_spadd_dims!(c, a);
spadd_cs_prealloc(beta, &mut c.cs, alpha, a.map_same_op(|a| &a.cs)) spadd_cs_prealloc(beta, &mut c.cs, alpha, a.map_same_op(|a| &a.cs))
@ -81,14 +81,14 @@ pub fn spmm_csc_prealloc<T>(
b: Op<&CscMatrix<T>>, b: Op<&CscMatrix<T>>,
) -> Result<(), OperationError> ) -> Result<(), OperationError>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
assert_compatible_spmm_dims!(c, a, b); assert_compatible_spmm_dims!(c, a, b);
use Op::NoOp; use Op::NoOp;
match (&a, &b) { match (&a, &b) {
(NoOp(a), NoOp(b)) => { (NoOp(ref a), NoOp(ref b)) => {
// Note: We have to reverse the order for CSC matrices // Note: We have to reverse the order for CSC matrices
spmm_cs_prealloc(beta, &mut c.cs, alpha, &b.cs, &a.cs) spmm_cs_prealloc(beta, &mut c.cs, alpha, &b.cs, &a.cs)
} }
@ -109,14 +109,14 @@ pub fn spmm_csc_prealloc_unchecked<T>(
b: Op<&CscMatrix<T>>, b: Op<&CscMatrix<T>>,
) -> Result<(), OperationError> ) -> Result<(), OperationError>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
assert_compatible_spmm_dims!(c, a, b); assert_compatible_spmm_dims!(c, a, b);
use Op::NoOp; use Op::NoOp;
match (&a, &b) { match (&a, &b) {
(NoOp(a), NoOp(b)) => { (NoOp(ref a), NoOp(ref b)) => {
// Note: We have to reverse the order for CSC matrices // Note: We have to reverse the order for CSC matrices
spmm_cs_prealloc_unchecked(beta, &mut c.cs, alpha, &b.cs, &a.cs) spmm_cs_prealloc_unchecked(beta, &mut c.cs, alpha, &b.cs, &a.cs)
} }
@ -133,7 +133,7 @@ fn spmm_csc_transposed<T, F>(
spmm_kernel: F, spmm_kernel: F,
) -> Result<(), OperationError> ) -> Result<(), OperationError>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
F: Fn( F: Fn(
T, T,
&mut CscMatrix<T>, &mut CscMatrix<T>,
@ -152,9 +152,9 @@ where
use Cow::*; use Cow::*;
match (&a, &b) { match (&a, &b) {
(NoOp(_), NoOp(_)) => unreachable!(), (NoOp(_), NoOp(_)) => unreachable!(),
(Transpose(a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)), (Transpose(ref a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
(NoOp(_), Transpose(b)) => (Borrowed(a_ref), Owned(b.transpose())), (NoOp(_), Transpose(ref b)) => (Borrowed(a_ref), Owned(b.transpose())),
(Transpose(a), Transpose(b)) => (Owned(a.transpose()), Owned(b.transpose())), (Transpose(ref a), Transpose(ref b)) => (Owned(a.transpose()), Owned(b.transpose())),
} }
}; };
spmm_kernel(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref())) spmm_kernel(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))

View File

@ -4,7 +4,7 @@ use crate::ops::serial::cs::{
}; };
use crate::ops::serial::OperationError; use crate::ops::serial::OperationError;
use crate::ops::Op; use crate::ops::Op;
use nalgebra::{ClosedAddAssign, ClosedMulAssign, DMatrixView, DMatrixViewMut, Scalar}; use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, Scalar};
use num_traits::{One, Zero}; use num_traits::{One, Zero};
use std::borrow::Cow; use std::borrow::Cow;
@ -16,7 +16,7 @@ pub fn spmm_csr_dense<'a, T>(
a: Op<&CsrMatrix<T>>, a: Op<&CsrMatrix<T>>,
b: Op<impl Into<DMatrixView<'a, T>>>, b: Op<impl Into<DMatrixView<'a, T>>>,
) where ) where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
let b = b.convert(); let b = b.convert();
spmm_csr_dense_(beta, c.into(), alpha, a, b) spmm_csr_dense_(beta, c.into(), alpha, a, b)
@ -29,7 +29,7 @@ fn spmm_csr_dense_<T>(
a: Op<&CsrMatrix<T>>, a: Op<&CsrMatrix<T>>,
b: Op<DMatrixView<'_, T>>, b: Op<DMatrixView<'_, T>>,
) where ) where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
assert_compatible_spmm_dims!(c, a, b); assert_compatible_spmm_dims!(c, a, b);
spmm_cs_dense(beta, c, alpha, a.map_same_op(|a| &a.cs), b) spmm_cs_dense(beta, c, alpha, a.map_same_op(|a| &a.cs), b)
@ -52,7 +52,7 @@ pub fn spadd_csr_prealloc<T>(
a: Op<&CsrMatrix<T>>, a: Op<&CsrMatrix<T>>,
) -> Result<(), OperationError> ) -> Result<(), OperationError>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
assert_compatible_spadd_dims!(c, a); assert_compatible_spadd_dims!(c, a);
spadd_cs_prealloc(beta, &mut c.cs, alpha, a.map_same_op(|a| &a.cs)) spadd_cs_prealloc(beta, &mut c.cs, alpha, a.map_same_op(|a| &a.cs))
@ -75,14 +75,14 @@ pub fn spmm_csr_prealloc<T>(
b: Op<&CsrMatrix<T>>, b: Op<&CsrMatrix<T>>,
) -> Result<(), OperationError> ) -> Result<(), OperationError>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
assert_compatible_spmm_dims!(c, a, b); assert_compatible_spmm_dims!(c, a, b);
use Op::NoOp; use Op::NoOp;
match (&a, &b) { match (&a, &b) {
(NoOp(a), NoOp(b)) => spmm_cs_prealloc(beta, &mut c.cs, alpha, &a.cs, &b.cs), (NoOp(ref a), NoOp(ref b)) => spmm_cs_prealloc(beta, &mut c.cs, alpha, &a.cs, &b.cs),
_ => spmm_csr_transposed(beta, c, alpha, a, b, spmm_csr_prealloc), _ => spmm_csr_transposed(beta, c, alpha, a, b, spmm_csr_prealloc),
} }
} }
@ -100,14 +100,16 @@ pub fn spmm_csr_prealloc_unchecked<T>(
b: Op<&CsrMatrix<T>>, b: Op<&CsrMatrix<T>>,
) -> Result<(), OperationError> ) -> Result<(), OperationError>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
assert_compatible_spmm_dims!(c, a, b); assert_compatible_spmm_dims!(c, a, b);
use Op::NoOp; use Op::NoOp;
match (&a, &b) { match (&a, &b) {
(NoOp(a), NoOp(b)) => spmm_cs_prealloc_unchecked(beta, &mut c.cs, alpha, &a.cs, &b.cs), (NoOp(ref a), NoOp(ref b)) => {
spmm_cs_prealloc_unchecked(beta, &mut c.cs, alpha, &a.cs, &b.cs)
}
_ => spmm_csr_transposed(beta, c, alpha, a, b, spmm_csr_prealloc_unchecked), _ => spmm_csr_transposed(beta, c, alpha, a, b, spmm_csr_prealloc_unchecked),
} }
} }
@ -121,7 +123,7 @@ fn spmm_csr_transposed<T, F>(
spmm_kernel: F, spmm_kernel: F,
) -> Result<(), OperationError> ) -> Result<(), OperationError>
where where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
F: Fn( F: Fn(
T, T,
&mut CsrMatrix<T>, &mut CsrMatrix<T>,
@ -140,9 +142,9 @@ where
use Cow::*; use Cow::*;
match (&a, &b) { match (&a, &b) {
(NoOp(_), NoOp(_)) => unreachable!(), (NoOp(_), NoOp(_)) => unreachable!(),
(Transpose(a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)), (Transpose(ref a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
(NoOp(_), Transpose(b)) => (Borrowed(a_ref), Owned(b.transpose())), (NoOp(_), Transpose(ref b)) => (Borrowed(a_ref), Owned(b.transpose())),
(Transpose(a), Transpose(b)) => (Owned(a.transpose()), Owned(b.transpose())), (Transpose(ref a), Transpose(ref b)) => (Owned(a.transpose()), Owned(b.transpose())),
} }
}; };
spmm_kernel(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref())) spmm_kernel(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))

View File

@ -125,22 +125,18 @@ fn iterate_union<'a>(
) -> impl Iterator<Item = usize> + 'a { ) -> impl Iterator<Item = usize> + 'a {
iter::from_fn(move || { iter::from_fn(move || {
if let (Some(a_item), Some(b_item)) = (sorted_a.first(), sorted_b.first()) { if let (Some(a_item), Some(b_item)) = (sorted_a.first(), sorted_b.first()) {
let item = match a_item.cmp(b_item) { let item = if a_item < b_item {
std::cmp::Ordering::Less => { sorted_a = &sorted_a[1..];
sorted_a = &sorted_a[1..]; a_item
a_item } else if b_item < a_item {
} sorted_b = &sorted_b[1..];
std::cmp::Ordering::Greater => { b_item
sorted_b = &sorted_b[1..]; } else {
b_item // Both lists contain the same element, advance both slices to avoid
} // duplicate entries in the result
std::cmp::Ordering::Equal => { sorted_a = &sorted_a[1..];
// Both lists contain the same element, advance both slices to avoid sorted_b = &sorted_b[1..];
// duplicate entries in the result a_item
sorted_a = &sorted_a[1..];
sorted_b = &sorted_b[1..];
a_item
}
}; };
Some(*item) Some(*item)
} else if let Some(a_item) = sorted_a.first() { } else if let Some(a_item) = sorted_a.first() {

View File

@ -80,7 +80,7 @@ impl SparsityPattern {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn major_dim(&self) -> usize { pub fn major_dim(&self) -> usize {
assert!(!self.major_offsets.is_empty()); assert!(self.major_offsets.len() > 0);
self.major_offsets.len() - 1 self.major_offsets.len() - 1
} }
@ -162,7 +162,7 @@ impl SparsityPattern {
// We test for in-bounds, uniqueness and monotonicity at the same time // We test for in-bounds, uniqueness and monotonicity at the same time
// to ensure that we only visit each minor index once // to ensure that we only visit each minor index once
let mut iter = minor_indices.iter(); let mut iter = minor_indices.iter();
let mut prev: Option<usize> = None; let mut prev = None;
while let Some(next) = iter.next().copied() { while let Some(next) = iter.next().copied() {
if next >= minor_dim { if next >= minor_dim {
@ -170,10 +170,10 @@ impl SparsityPattern {
} }
if let Some(prev) = prev { if let Some(prev) = prev {
match prev.cmp(&next) { if prev > next {
std::cmp::Ordering::Greater => return Err(NonmonotonicMinorIndices), return Err(NonmonotonicMinorIndices);
std::cmp::Ordering::Equal => return Err(DuplicateEntry), } else if prev == next {
std::cmp::Ordering::Less => {} return Err(DuplicateEntry);
} }
} }
prev = Some(next); prev = Some(next);
@ -195,14 +195,6 @@ impl SparsityPattern {
/// ///
/// Panics if the number of major offsets is not exactly one greater than the major dimension /// Panics if the number of major offsets is not exactly one greater than the major dimension
/// or if major offsets do not start with 0 and end with the number of minor indices. /// or if major offsets do not start with 0 and end with the number of minor indices.
///
/// # Safety
///
/// Assumes that the major offsets and indices adhere to the requirements of being a valid
/// sparsity pattern.
/// Specifically, that major offsets is monotonically increasing, and
/// `major_offsets[i]..major_offsets[i+1]` refers to a major lane in the sparsity pattern,
/// and `minor_indices[major_offsets[i]..major_offsets[i+1]]` is monotonically increasing.
pub unsafe fn from_offset_and_indices_unchecked( pub unsafe fn from_offset_and_indices_unchecked(
major_dim: usize, major_dim: usize,
minor_dim: usize, minor_dim: usize,
@ -299,16 +291,6 @@ impl SparsityPattern {
} }
} }
impl Default for SparsityPattern {
fn default() -> Self {
Self {
major_offsets: vec![0],
minor_indices: vec![],
minor_dim: 0,
}
}
}
/// Error type for `SparsityPattern` format errors. /// Error type for `SparsityPattern` format errors.
#[non_exhaustive] #[non_exhaustive]
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]

View File

@ -184,31 +184,6 @@ fn coo_try_from_triplets_reports_out_of_bounds_indices() {
} }
} }
#[test]
fn coo_try_from_triplets_iter() {
// Check that try_from_triplets_iter panics when the triplet vectors have different lengths
macro_rules! assert_errs {
($result:expr) => {
assert!(matches!(
$result.unwrap_err().kind(),
SparseFormatErrorKind::IndexOutOfBounds
))
};
}
assert_errs!(CooMatrix::<f32>::try_from_triplets_iter(
3,
5,
vec![(0, 6, 3.0)].into_iter(),
));
assert!(CooMatrix::<f32>::try_from_triplets_iter(
3,
5,
vec![(0, 3, 3.0), (1, 2, 2.0), (0, 3, 1.0),].into_iter(),
)
.is_ok());
}
#[test] #[test]
fn coo_try_from_triplets_panics_on_mismatched_vectors() { fn coo_try_from_triplets_panics_on_mismatched_vectors() {
// Check that try_from_triplets panics when the triplet vectors have different lengths // Check that try_from_triplets panics when the triplet vectors have different lengths

View File

@ -12,18 +12,6 @@ use crate::common::csc_strategy;
use std::collections::HashSet; use std::collections::HashSet;
#[test]
fn csc_matrix_default() {
let matrix: CscMatrix<f32> = CscMatrix::default();
assert_eq!(matrix.nrows(), 0);
assert_eq!(matrix.ncols(), 0);
assert_eq!(matrix.nnz(), 0);
assert_eq!(matrix.values(), &[]);
assert!(matrix.get_entry(0, 0).is_none());
}
#[test] #[test]
fn csc_matrix_valid_data() { fn csc_matrix_valid_data() {
// Construct matrix from valid data and check that selected methods return results // Construct matrix from valid data and check that selected methods return results

View File

@ -12,18 +12,6 @@ use crate::common::csr_strategy;
use std::collections::HashSet; use std::collections::HashSet;
#[test]
fn csr_matrix_default() {
let matrix: CsrMatrix<f32> = CsrMatrix::default();
assert_eq!(matrix.nrows(), 0);
assert_eq!(matrix.ncols(), 0);
assert_eq!(matrix.nnz(), 0);
assert_eq!(matrix.values(), &[]);
assert!(matrix.get_entry(0, 0).is_none());
}
#[test] #[test]
fn csr_matrix_valid_data() { fn csr_matrix_valid_data() {
// Construct matrix from valid data and check that selected methods return results // Construct matrix from valid data and check that selected methods return results

View File

@ -1,19 +1,5 @@
use nalgebra_sparse::pattern::{SparsityPattern, SparsityPatternFormatError}; use nalgebra_sparse::pattern::{SparsityPattern, SparsityPatternFormatError};
#[test]
fn sparsity_pattern_default() {
// Check that the pattern created with `Default::default()` is equivalent to a zero-sized pattern.
let pattern = SparsityPattern::default();
let zero = SparsityPattern::zeros(0, 0);
assert_eq!(pattern.major_dim(), zero.major_dim());
assert_eq!(pattern.minor_dim(), zero.minor_dim());
assert_eq!(pattern.major_offsets(), zero.major_offsets());
assert_eq!(pattern.minor_indices(), zero.minor_indices());
assert_eq!(pattern.nnz(), 0);
}
#[test] #[test]
fn sparsity_pattern_valid_data() { fn sparsity_pattern_valid_data() {
// Construct pattern from valid data and check that selected methods return results // Construct pattern from valid data and check that selected methods return results

View File

@ -10,429 +10,285 @@ use crate::base::{Const, Matrix};
* *
*/ */
// NOTE: we can't provide defaults for the strides because it's not supported yet by min_const_generics. // NOTE: we can't provide defaults for the strides because it's not supported yet by min_const_generics.
/// An immutable column-major matrix view with dimensions known at compile-time. /// A column-major matrix view with dimensions known at compile-time.
///
/// See [`SMatrixViewMut`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type SMatrixView<'a, T, const R: usize, const C: usize> = pub type SMatrixView<'a, T, const R: usize, const C: usize> =
Matrix<T, Const<R>, Const<C>, ViewStorage<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>; Matrix<T, Const<R>, Const<C>, ViewStorage<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
/// An immutable column-major matrix view dynamic numbers of rows and columns. /// A column-major matrix view dynamic numbers of rows and columns.
///
/// See [`DMatrixViewMut`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DMatrixView<'a, T, RStride = U1, CStride = Dyn> = pub type DMatrixView<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, Dyn, ViewStorage<'a, T, Dyn, Dyn, RStride, CStride>>; Matrix<T, Dyn, Dyn, ViewStorage<'a, T, Dyn, Dyn, RStride, CStride>>;
/// An immutable column-major 1x1 matrix view. /// A column-major 1x1 matrix view.
///
/// See [`MatrixViewMut1`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1<'a, T, RStride = U1, CStride = U1> = pub type MatrixView1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>;
/// An immutable column-major 2x2 matrix view. /// A column-major 2x2 matrix view.
///
/// See [`MatrixViewMut2`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2<'a, T, RStride = U1, CStride = U2> = pub type MatrixView2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U2, ViewStorage<'a, T, U2, U2, RStride, CStride>>; Matrix<T, U2, U2, ViewStorage<'a, T, U2, U2, RStride, CStride>>;
/// An immutable column-major 3x3 matrix view. /// A column-major 3x3 matrix view.
///
/// See [`MatrixViewMut3`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3<'a, T, RStride = U1, CStride = U3> = pub type MatrixView3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U3, ViewStorage<'a, T, U3, U3, RStride, CStride>>; Matrix<T, U3, U3, ViewStorage<'a, T, U3, U3, RStride, CStride>>;
/// An immutable column-major 4x4 matrix view. /// A column-major 4x4 matrix view.
///
/// See [`MatrixViewMut4`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4<'a, T, RStride = U1, CStride = U4> = pub type MatrixView4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U4, ViewStorage<'a, T, U4, U4, RStride, CStride>>; Matrix<T, U4, U4, ViewStorage<'a, T, U4, U4, RStride, CStride>>;
/// An immutable column-major 5x5 matrix view. /// A column-major 5x5 matrix view.
///
/// See [`MatrixViewMut5`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5<'a, T, RStride = U1, CStride = U5> = pub type MatrixView5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U5, ViewStorage<'a, T, U5, U5, RStride, CStride>>; Matrix<T, U5, U5, ViewStorage<'a, T, U5, U5, RStride, CStride>>;
/// An immutable column-major 6x6 matrix view. /// A column-major 6x6 matrix view.
///
/// See [`MatrixViewMut6`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6<'a, T, RStride = U1, CStride = U6> = pub type MatrixView6<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U6, ViewStorage<'a, T, U6, U6, RStride, CStride>>; Matrix<T, U6, U6, ViewStorage<'a, T, U6, U6, RStride, CStride>>;
/// An immutable column-major 1x2 matrix view. /// A column-major 1x2 matrix view.
///
/// See [`MatrixViewMut1x2`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1x2<'a, T, RStride = U1, CStride = U1> = pub type MatrixView1x2<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U2, ViewStorage<'a, T, U1, U2, RStride, CStride>>; Matrix<T, U1, U2, ViewStorage<'a, T, U1, U2, RStride, CStride>>;
/// An immutable column-major 1x3 matrix view. /// A column-major 1x3 matrix view.
///
/// See [`MatrixViewMut1x3`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1x3<'a, T, RStride = U1, CStride = U1> = pub type MatrixView1x3<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U3, ViewStorage<'a, T, U1, U3, RStride, CStride>>; Matrix<T, U1, U3, ViewStorage<'a, T, U1, U3, RStride, CStride>>;
/// An immutable column-major 1x4 matrix view. /// A column-major 1x4 matrix view.
///
/// See [`MatrixViewMut1x4`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1x4<'a, T, RStride = U1, CStride = U1> = pub type MatrixView1x4<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U4, ViewStorage<'a, T, U1, U4, RStride, CStride>>; Matrix<T, U1, U4, ViewStorage<'a, T, U1, U4, RStride, CStride>>;
/// An immutable column-major 1x5 matrix view. /// A column-major 1x5 matrix view.
///
/// See [`MatrixViewMut1x5`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1x5<'a, T, RStride = U1, CStride = U1> = pub type MatrixView1x5<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U5, ViewStorage<'a, T, U1, U5, RStride, CStride>>; Matrix<T, U1, U5, ViewStorage<'a, T, U1, U5, RStride, CStride>>;
/// An immutable column-major 1x6 matrix view. /// A column-major 1x6 matrix view.
///
/// See [`MatrixViewMut1x6`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1x6<'a, T, RStride = U1, CStride = U1> = pub type MatrixView1x6<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U6, ViewStorage<'a, T, U1, U6, RStride, CStride>>; Matrix<T, U1, U6, ViewStorage<'a, T, U1, U6, RStride, CStride>>;
/// An immutable column-major 2x1 matrix view. /// A column-major 2x1 matrix view.
///
/// See [`MatrixViewMut2x1`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2x1<'a, T, RStride = U1, CStride = U2> = pub type MatrixView2x1<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>;
/// An immutable column-major 2x3 matrix view. /// A column-major 2x3 matrix view.
///
/// See [`MatrixViewMut2x3`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2x3<'a, T, RStride = U1, CStride = U2> = pub type MatrixView2x3<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U3, ViewStorage<'a, T, U2, U3, RStride, CStride>>; Matrix<T, U2, U3, ViewStorage<'a, T, U2, U3, RStride, CStride>>;
/// An immutable column-major 2x4 matrix view. /// A column-major 2x4 matrix view.
///
/// See [`MatrixViewMut2x4`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2x4<'a, T, RStride = U1, CStride = U2> = pub type MatrixView2x4<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U4, ViewStorage<'a, T, U2, U4, RStride, CStride>>; Matrix<T, U2, U4, ViewStorage<'a, T, U2, U4, RStride, CStride>>;
/// An immutable column-major 2x5 matrix view. /// A column-major 2x5 matrix view.
///
/// See [`MatrixViewMut2x5`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2x5<'a, T, RStride = U1, CStride = U2> = pub type MatrixView2x5<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U5, ViewStorage<'a, T, U2, U5, RStride, CStride>>; Matrix<T, U2, U5, ViewStorage<'a, T, U2, U5, RStride, CStride>>;
/// An immutable column-major 2x6 matrix view. /// A column-major 2x6 matrix view.
///
/// See [`MatrixViewMut2x6`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2x6<'a, T, RStride = U1, CStride = U2> = pub type MatrixView2x6<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U6, ViewStorage<'a, T, U2, U6, RStride, CStride>>; Matrix<T, U2, U6, ViewStorage<'a, T, U2, U6, RStride, CStride>>;
/// An immutable column-major 3x1 matrix view. /// A column-major 3x1 matrix view.
///
/// See [`MatrixViewMut3x1`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3x1<'a, T, RStride = U1, CStride = U3> = pub type MatrixView3x1<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>;
/// An immutable column-major 3x2 matrix view. /// A column-major 3x2 matrix view.
///
/// See [`MatrixViewMut3x2`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3x2<'a, T, RStride = U1, CStride = U3> = pub type MatrixView3x2<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U2, ViewStorage<'a, T, U3, U2, RStride, CStride>>; Matrix<T, U3, U2, ViewStorage<'a, T, U3, U2, RStride, CStride>>;
/// An immutable column-major 3x4 matrix view. /// A column-major 3x4 matrix view.
///
/// See [`MatrixViewMut3x4`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3x4<'a, T, RStride = U1, CStride = U3> = pub type MatrixView3x4<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U4, ViewStorage<'a, T, U3, U4, RStride, CStride>>; Matrix<T, U3, U4, ViewStorage<'a, T, U3, U4, RStride, CStride>>;
/// An immutable column-major 3x5 matrix view. /// A column-major 3x5 matrix view.
///
/// See [`MatrixViewMut3x5`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3x5<'a, T, RStride = U1, CStride = U3> = pub type MatrixView3x5<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U5, ViewStorage<'a, T, U3, U5, RStride, CStride>>; Matrix<T, U3, U5, ViewStorage<'a, T, U3, U5, RStride, CStride>>;
/// An immutable column-major 3x6 matrix view. /// A column-major 3x6 matrix view.
///
/// See [`MatrixViewMut3x6`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3x6<'a, T, RStride = U1, CStride = U3> = pub type MatrixView3x6<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U6, ViewStorage<'a, T, U3, U6, RStride, CStride>>; Matrix<T, U3, U6, ViewStorage<'a, T, U3, U6, RStride, CStride>>;
/// An immutable column-major 4x1 matrix view. /// A column-major 4x1 matrix view.
///
/// See [`MatrixViewMut4x1`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4x1<'a, T, RStride = U1, CStride = U4> = pub type MatrixView4x1<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>;
/// An immutable column-major 4x2 matrix view. /// A column-major 4x2 matrix view.
///
/// See [`MatrixViewMut4x2`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4x2<'a, T, RStride = U1, CStride = U4> = pub type MatrixView4x2<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U2, ViewStorage<'a, T, U4, U2, RStride, CStride>>; Matrix<T, U4, U2, ViewStorage<'a, T, U4, U2, RStride, CStride>>;
/// An immutable column-major 4x3 matrix view. /// A column-major 4x3 matrix view.
///
/// See [`MatrixViewMut4x3`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4x3<'a, T, RStride = U1, CStride = U4> = pub type MatrixView4x3<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U3, ViewStorage<'a, T, U4, U3, RStride, CStride>>; Matrix<T, U4, U3, ViewStorage<'a, T, U4, U3, RStride, CStride>>;
/// An immutable column-major 4x5 matrix view. /// A column-major 4x5 matrix view.
///
/// See [`MatrixViewMut4x5`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4x5<'a, T, RStride = U1, CStride = U4> = pub type MatrixView4x5<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U5, ViewStorage<'a, T, U4, U5, RStride, CStride>>; Matrix<T, U4, U5, ViewStorage<'a, T, U4, U5, RStride, CStride>>;
/// An immutable column-major 4x6 matrix view. /// A column-major 4x6 matrix view.
///
/// See [`MatrixViewMut4x6`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4x6<'a, T, RStride = U1, CStride = U4> = pub type MatrixView4x6<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U6, ViewStorage<'a, T, U4, U6, RStride, CStride>>; Matrix<T, U4, U6, ViewStorage<'a, T, U4, U6, RStride, CStride>>;
/// An immutable column-major 5x1 matrix view. /// A column-major 5x1 matrix view.
///
/// See [`MatrixViewMut5x1`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5x1<'a, T, RStride = U1, CStride = U5> = pub type MatrixView5x1<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>;
/// An immutable column-major 5x2 matrix view. /// A column-major 5x2 matrix view.
///
/// See [`MatrixViewMut5x2`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5x2<'a, T, RStride = U1, CStride = U5> = pub type MatrixView5x2<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U2, ViewStorage<'a, T, U5, U2, RStride, CStride>>; Matrix<T, U5, U2, ViewStorage<'a, T, U5, U2, RStride, CStride>>;
/// An immutable column-major 5x3 matrix view. /// A column-major 5x3 matrix view.
///
/// See [`MatrixViewMut5x3`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5x3<'a, T, RStride = U1, CStride = U5> = pub type MatrixView5x3<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U3, ViewStorage<'a, T, U5, U3, RStride, CStride>>; Matrix<T, U5, U3, ViewStorage<'a, T, U5, U3, RStride, CStride>>;
/// An immutable column-major 5x4 matrix view. /// A column-major 5x4 matrix view.
///
/// See [`MatrixViewMut5x4`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5x4<'a, T, RStride = U1, CStride = U5> = pub type MatrixView5x4<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U4, ViewStorage<'a, T, U5, U4, RStride, CStride>>; Matrix<T, U5, U4, ViewStorage<'a, T, U5, U4, RStride, CStride>>;
/// An immutable column-major 5x6 matrix view. /// A column-major 5x6 matrix view.
///
/// See [`MatrixViewMut5x6`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5x6<'a, T, RStride = U1, CStride = U5> = pub type MatrixView5x6<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U6, ViewStorage<'a, T, U5, U6, RStride, CStride>>; Matrix<T, U5, U6, ViewStorage<'a, T, U5, U6, RStride, CStride>>;
/// An immutable column-major 6x1 matrix view. /// A column-major 6x1 matrix view.
///
/// See [`MatrixViewMut6x1`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6x1<'a, T, RStride = U1, CStride = U6> = pub type MatrixView6x1<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U1, ViewStorage<'a, T, U6, U1, RStride, CStride>>; Matrix<T, U6, U1, ViewStorage<'a, T, U6, U1, RStride, CStride>>;
/// An immutable column-major 6x2 matrix view. /// A column-major 6x2 matrix view.
///
/// See [`MatrixViewMut6x2`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6x2<'a, T, RStride = U1, CStride = U6> = pub type MatrixView6x2<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U2, ViewStorage<'a, T, U6, U2, RStride, CStride>>; Matrix<T, U6, U2, ViewStorage<'a, T, U6, U2, RStride, CStride>>;
/// An immutable column-major 6x3 matrix view. /// A column-major 6x3 matrix view.
///
/// See [`MatrixViewMut6x3`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6x3<'a, T, RStride = U1, CStride = U6> = pub type MatrixView6x3<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U3, ViewStorage<'a, T, U6, U3, RStride, CStride>>; Matrix<T, U6, U3, ViewStorage<'a, T, U6, U3, RStride, CStride>>;
/// An immutable column-major 6x4 matrix view. /// A column-major 6x4 matrix view.
///
/// See [`MatrixViewMut6x4`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6x4<'a, T, RStride = U1, CStride = U6> = pub type MatrixView6x4<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U4, ViewStorage<'a, T, U6, U4, RStride, CStride>>; Matrix<T, U6, U4, ViewStorage<'a, T, U6, U4, RStride, CStride>>;
/// An immutable column-major 6x5 matrix view. /// A column-major 6x5 matrix view.
///
/// See [`MatrixViewMut6x5`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6x5<'a, T, RStride = U1, CStride = U6> = pub type MatrixView6x5<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U5, ViewStorage<'a, T, U6, U5, RStride, CStride>>; Matrix<T, U6, U5, ViewStorage<'a, T, U6, U5, RStride, CStride>>;
/// An immutable column-major matrix view with 1 row and a number of columns chosen at runtime. /// A column-major matrix view with 1 row and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut1xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1xX<'a, T, RStride = U1, CStride = U1> = pub type MatrixView1xX<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, Dyn, ViewStorage<'a, T, U1, Dyn, RStride, CStride>>; Matrix<T, U1, Dyn, ViewStorage<'a, T, U1, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with 2 rows and a number of columns chosen at runtime. /// A column-major matrix view with 2 rows and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut2xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2xX<'a, T, RStride = U1, CStride = U2> = pub type MatrixView2xX<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, Dyn, ViewStorage<'a, T, U2, Dyn, RStride, CStride>>; Matrix<T, U2, Dyn, ViewStorage<'a, T, U2, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with 3 rows and a number of columns chosen at runtime. /// A column-major matrix view with 3 rows and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut3xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3xX<'a, T, RStride = U1, CStride = U3> = pub type MatrixView3xX<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, Dyn, ViewStorage<'a, T, U3, Dyn, RStride, CStride>>; Matrix<T, U3, Dyn, ViewStorage<'a, T, U3, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with 4 rows and a number of columns chosen at runtime. /// A column-major matrix view with 4 rows and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut4xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4xX<'a, T, RStride = U1, CStride = U4> = pub type MatrixView4xX<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, Dyn, ViewStorage<'a, T, U4, Dyn, RStride, CStride>>; Matrix<T, U4, Dyn, ViewStorage<'a, T, U4, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with 5 rows and a number of columns chosen at runtime. /// A column-major matrix view with 5 rows and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut5xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5xX<'a, T, RStride = U1, CStride = U5> = pub type MatrixView5xX<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, Dyn, ViewStorage<'a, T, U5, Dyn, RStride, CStride>>; Matrix<T, U5, Dyn, ViewStorage<'a, T, U5, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with 6 rows and a number of columns chosen at runtime. /// A column-major matrix view with 6 rows and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut6xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6xX<'a, T, RStride = U1, CStride = U6> = pub type MatrixView6xX<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, Dyn, ViewStorage<'a, T, U6, Dyn, RStride, CStride>>; Matrix<T, U6, Dyn, ViewStorage<'a, T, U6, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 1 column. /// A column-major matrix view with a number of rows chosen at runtime and 1 column.
///
/// See [`MatrixViewMutXx1`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx1<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewXx1<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorage<'a, T, Dyn, U1, RStride, CStride>>; Matrix<T, Dyn, U1, ViewStorage<'a, T, Dyn, U1, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 2 columns. /// A column-major matrix view with a number of rows chosen at runtime and 2 columns.
///
/// See [`MatrixViewMutXx2`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx2<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewXx2<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U2, ViewStorage<'a, T, Dyn, U2, RStride, CStride>>; Matrix<T, Dyn, U2, ViewStorage<'a, T, Dyn, U2, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 3 columns. /// A column-major matrix view with a number of rows chosen at runtime and 3 columns.
///
/// See [`MatrixViewMutXx3`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx3<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewXx3<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U3, ViewStorage<'a, T, Dyn, U3, RStride, CStride>>; Matrix<T, Dyn, U3, ViewStorage<'a, T, Dyn, U3, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 4 columns. /// A column-major matrix view with a number of rows chosen at runtime and 4 columns.
///
/// See [`MatrixViewMutXx4`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx4<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewXx4<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U4, ViewStorage<'a, T, Dyn, U4, RStride, CStride>>; Matrix<T, Dyn, U4, ViewStorage<'a, T, Dyn, U4, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 5 columns. /// A column-major matrix view with a number of rows chosen at runtime and 5 columns.
///
/// See [`MatrixViewMutXx5`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx5<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewXx5<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U5, ViewStorage<'a, T, Dyn, U5, RStride, CStride>>; Matrix<T, Dyn, U5, ViewStorage<'a, T, Dyn, U5, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 6 columns. /// A column-major matrix view with a number of rows chosen at runtime and 6 columns.
///
/// See [`MatrixViewMutXx6`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx6<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewXx6<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U6, ViewStorage<'a, T, Dyn, U6, RStride, CStride>>; Matrix<T, Dyn, U6, ViewStorage<'a, T, Dyn, U6, RStride, CStride>>;
/// An immutable column vector view with dimensions known at compile-time. /// A column vector view with dimensions known at compile-time.
///
/// See [`VectorViewMut`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView<'a, T, D, RStride = U1, CStride = D> = pub type VectorView<'a, T, D, RStride = U1, CStride = D> =
Matrix<T, D, U1, ViewStorage<'a, T, D, U1, RStride, CStride>>; Matrix<T, D, U1, ViewStorage<'a, T, D, U1, RStride, CStride>>;
/// An immutable column vector view with dimensions known at compile-time. /// A column vector view with dimensions known at compile-time.
///
/// See [`SVectorViewMut`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type SVectorView<'a, T, const D: usize> = pub type SVectorView<'a, T, const D: usize> =
Matrix<T, Const<D>, Const<1>, ViewStorage<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>; Matrix<T, Const<D>, Const<1>, ViewStorage<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
/// An immutable column vector view dynamic numbers of rows and columns. /// A column vector view dynamic numbers of rows and columns.
///
/// See [`DVectorViewMut`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DVectorView<'a, T, RStride = U1, CStride = Dyn> = pub type DVectorView<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorage<'a, T, Dyn, U1, RStride, CStride>>; Matrix<T, Dyn, U1, ViewStorage<'a, T, Dyn, U1, RStride, CStride>>;
/// An immutable 1D column vector view. /// A 1D column vector view.
///
/// See [`VectorViewMut1`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView1<'a, T, RStride = U1, CStride = U1> = pub type VectorView1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>;
/// An immutable 2D column vector view. /// A 2D column vector view.
///
/// See [`VectorViewMut2`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView2<'a, T, RStride = U1, CStride = U2> = pub type VectorView2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>;
/// An immutable 3D column vector view. /// A 3D column vector view.
///
/// See [`VectorViewMut3`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView3<'a, T, RStride = U1, CStride = U3> = pub type VectorView3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>;
/// An immutable 4D column vector view. /// A 4D column vector view.
///
/// See [`VectorViewMut4`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView4<'a, T, RStride = U1, CStride = U4> = pub type VectorView4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>;
/// An immutable 5D column vector view. /// A 5D column vector view.
///
/// See [`VectorViewMut5`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView5<'a, T, RStride = U1, CStride = U5> = pub type VectorView5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>;
/// An immutable 6D column vector view. /// A 6D column vector view.
///
/// See [`VectorViewMut6`] for a mutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView6<'a, T, RStride = U1, CStride = U6> = pub type VectorView6<'a, T, RStride = U1, CStride = U6> =
@ -446,429 +302,287 @@ pub type VectorView6<'a, T, RStride = U1, CStride = U6> =
* *
*/ */
/// A mutable column-major matrix view with dimensions known at compile-time. /// A column-major matrix view with dimensions known at compile-time.
///
/// See [`SMatrixView`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type SMatrixViewMut<'a, T, const R: usize, const C: usize> = pub type SMatrixViewMut<'a, T, const R: usize, const C: usize> =
Matrix<T, Const<R>, Const<C>, ViewStorageMut<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>; Matrix<T, Const<R>, Const<C>, ViewStorageMut<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
/// A mutable column-major matrix view dynamic numbers of rows and columns. /// A column-major matrix view dynamic numbers of rows and columns.
///
/// See [`DMatrixView`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DMatrixViewMut<'a, T, RStride = U1, CStride = Dyn> = pub type DMatrixViewMut<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, Dyn, ViewStorageMut<'a, T, Dyn, Dyn, RStride, CStride>>; Matrix<T, Dyn, Dyn, ViewStorageMut<'a, T, Dyn, Dyn, RStride, CStride>>;
/// A mutable column-major 1x1 matrix view. /// A column-major 1x1 matrix view.
///
/// See [`MatrixView1`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1<'a, T, RStride = U1, CStride = U1> = pub type MatrixViewMut1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>;
/// A mutable column-major 2x2 matrix view. /// A column-major 2x2 matrix view.
///
/// See [`MatrixView2`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2<'a, T, RStride = U1, CStride = U2> = pub type MatrixViewMut2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U2, ViewStorageMut<'a, T, U2, U2, RStride, CStride>>; Matrix<T, U2, U2, ViewStorageMut<'a, T, U2, U2, RStride, CStride>>;
/// A mutable column-major 3x3 matrix view. /// A column-major 3x3 matrix view.
///
/// See [`MatrixView3`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3<'a, T, RStride = U1, CStride = U3> = pub type MatrixViewMut3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U3, ViewStorageMut<'a, T, U3, U3, RStride, CStride>>; Matrix<T, U3, U3, ViewStorageMut<'a, T, U3, U3, RStride, CStride>>;
/// A mutable column-major 4x4 matrix view. /// A column-major 4x4 matrix view.
///
/// See [`MatrixView4`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4<'a, T, RStride = U1, CStride = U4> = pub type MatrixViewMut4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U4, ViewStorageMut<'a, T, U4, U4, RStride, CStride>>; Matrix<T, U4, U4, ViewStorageMut<'a, T, U4, U4, RStride, CStride>>;
/// A mutable column-major 5x5 matrix view. /// A column-major 5x5 matrix view.
///
/// See [`MatrixView5`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5<'a, T, RStride = U1, CStride = U5> = pub type MatrixViewMut5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U5, ViewStorageMut<'a, T, U5, U5, RStride, CStride>>; Matrix<T, U5, U5, ViewStorageMut<'a, T, U5, U5, RStride, CStride>>;
/// A mutable column-major 6x6 matrix view. /// A column-major 6x6 matrix view.
///
/// See [`MatrixView6`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6<'a, T, RStride = U1, CStride = U6> = pub type MatrixViewMut6<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U6, ViewStorageMut<'a, T, U6, U6, RStride, CStride>>; Matrix<T, U6, U6, ViewStorageMut<'a, T, U6, U6, RStride, CStride>>;
/// A mutable column-major 1x2 matrix view. /// A column-major 1x2 matrix view.
///
/// See [`MatrixView1x2`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1x2<'a, T, RStride = U1, CStride = U1> = pub type MatrixViewMut1x2<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U2, ViewStorageMut<'a, T, U1, U2, RStride, CStride>>; Matrix<T, U1, U2, ViewStorageMut<'a, T, U1, U2, RStride, CStride>>;
/// A mutable column-major 1x3 matrix view. /// A column-major 1x3 matrix view.
///
/// See [`MatrixView1x3`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1x3<'a, T, RStride = U1, CStride = U1> = pub type MatrixViewMut1x3<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U3, ViewStorageMut<'a, T, U1, U3, RStride, CStride>>; Matrix<T, U1, U3, ViewStorageMut<'a, T, U1, U3, RStride, CStride>>;
/// A mutable column-major 1x4 matrix view. /// A column-major 1x4 matrix view.
///
/// See [`MatrixView1x4`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1x4<'a, T, RStride = U1, CStride = U1> = pub type MatrixViewMut1x4<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U4, ViewStorageMut<'a, T, U1, U4, RStride, CStride>>; Matrix<T, U1, U4, ViewStorageMut<'a, T, U1, U4, RStride, CStride>>;
/// A mutable column-major 1x5 matrix view. /// A column-major 1x5 matrix view.
///
/// See [`MatrixView1x5`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1x5<'a, T, RStride = U1, CStride = U1> = pub type MatrixViewMut1x5<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U5, ViewStorageMut<'a, T, U1, U5, RStride, CStride>>; Matrix<T, U1, U5, ViewStorageMut<'a, T, U1, U5, RStride, CStride>>;
/// A mutable column-major 1x6 matrix view. /// A column-major 1x6 matrix view.
///
/// See [`MatrixView1x6`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1x6<'a, T, RStride = U1, CStride = U1> = pub type MatrixViewMut1x6<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U6, ViewStorageMut<'a, T, U1, U6, RStride, CStride>>; Matrix<T, U1, U6, ViewStorageMut<'a, T, U1, U6, RStride, CStride>>;
/// A mutable column-major 2x1 matrix view. /// A column-major 2x1 matrix view.
///
/// See [`MatrixView2x1`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2x1<'a, T, RStride = U1, CStride = U2> = pub type MatrixViewMut2x1<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>;
/// A mutable column-major 2x3 matrix view. /// A column-major 2x3 matrix view.
///
/// See [`MatrixView2x3`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2x3<'a, T, RStride = U1, CStride = U2> = pub type MatrixViewMut2x3<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U3, ViewStorageMut<'a, T, U2, U3, RStride, CStride>>; Matrix<T, U2, U3, ViewStorageMut<'a, T, U2, U3, RStride, CStride>>;
/// A mutable column-major 2x4 matrix view. /// A column-major 2x4 matrix view.
///
/// See [`MatrixView2x4`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2x4<'a, T, RStride = U1, CStride = U2> = pub type MatrixViewMut2x4<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U4, ViewStorageMut<'a, T, U2, U4, RStride, CStride>>; Matrix<T, U2, U4, ViewStorageMut<'a, T, U2, U4, RStride, CStride>>;
/// A mutable column-major 2x5 matrix view. /// A column-major 2x5 matrix view.
///
/// See [`MatrixView2x5`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2x5<'a, T, RStride = U1, CStride = U2> = pub type MatrixViewMut2x5<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U5, ViewStorageMut<'a, T, U2, U5, RStride, CStride>>; Matrix<T, U2, U5, ViewStorageMut<'a, T, U2, U5, RStride, CStride>>;
/// A mutable column-major 2x6 matrix view. /// A column-major 2x6 matrix view.
///
/// See [`MatrixView2x6`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2x6<'a, T, RStride = U1, CStride = U2> = pub type MatrixViewMut2x6<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U6, ViewStorageMut<'a, T, U2, U6, RStride, CStride>>; Matrix<T, U2, U6, ViewStorageMut<'a, T, U2, U6, RStride, CStride>>;
/// A mutable column-major 3x1 matrix view. /// A column-major 3x1 matrix view.
///
/// See [`MatrixView3x1`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3x1<'a, T, RStride = U1, CStride = U3> = pub type MatrixViewMut3x1<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>;
/// A mutable column-major 3x2 matrix view. /// A column-major 3x2 matrix view.
///
/// See [`MatrixView3x2`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3x2<'a, T, RStride = U1, CStride = U3> = pub type MatrixViewMut3x2<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U2, ViewStorageMut<'a, T, U3, U2, RStride, CStride>>; Matrix<T, U3, U2, ViewStorageMut<'a, T, U3, U2, RStride, CStride>>;
/// A mutable column-major 3x4 matrix view. /// A column-major 3x4 matrix view.
///
/// See [`MatrixView3x4`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3x4<'a, T, RStride = U1, CStride = U3> = pub type MatrixViewMut3x4<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U4, ViewStorageMut<'a, T, U3, U4, RStride, CStride>>; Matrix<T, U3, U4, ViewStorageMut<'a, T, U3, U4, RStride, CStride>>;
/// A mutable column-major 3x5 matrix view. /// A column-major 3x5 matrix view.
///
/// See [`MatrixView3x5`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3x5<'a, T, RStride = U1, CStride = U3> = pub type MatrixViewMut3x5<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U5, ViewStorageMut<'a, T, U3, U5, RStride, CStride>>; Matrix<T, U3, U5, ViewStorageMut<'a, T, U3, U5, RStride, CStride>>;
/// A mutable column-major 3x6 matrix view. /// A column-major 3x6 matrix view.
///
/// See [`MatrixView3x6`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3x6<'a, T, RStride = U1, CStride = U3> = pub type MatrixViewMut3x6<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U6, ViewStorageMut<'a, T, U3, U6, RStride, CStride>>; Matrix<T, U3, U6, ViewStorageMut<'a, T, U3, U6, RStride, CStride>>;
/// A mutable column-major 4x1 matrix view. /// A column-major 4x1 matrix view.
///
/// See [`MatrixView4x1`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4x1<'a, T, RStride = U1, CStride = U4> = pub type MatrixViewMut4x1<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>;
/// A mutable column-major 4x2 matrix view. /// A column-major 4x2 matrix view.
///
/// See [`MatrixView4x2`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4x2<'a, T, RStride = U1, CStride = U4> = pub type MatrixViewMut4x2<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U2, ViewStorageMut<'a, T, U4, U2, RStride, CStride>>; Matrix<T, U4, U2, ViewStorageMut<'a, T, U4, U2, RStride, CStride>>;
/// A mutable column-major 4x3 matrix view. /// A column-major 4x3 matrix view.
///
/// See [`MatrixView4x3`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4x3<'a, T, RStride = U1, CStride = U4> = pub type MatrixViewMut4x3<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U3, ViewStorageMut<'a, T, U4, U3, RStride, CStride>>; Matrix<T, U4, U3, ViewStorageMut<'a, T, U4, U3, RStride, CStride>>;
/// A mutable column-major 4x5 matrix view. /// A column-major 4x5 matrix view.
///
/// See [`MatrixView4x5`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4x5<'a, T, RStride = U1, CStride = U4> = pub type MatrixViewMut4x5<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U5, ViewStorageMut<'a, T, U4, U5, RStride, CStride>>; Matrix<T, U4, U5, ViewStorageMut<'a, T, U4, U5, RStride, CStride>>;
/// A mutable column-major 4x6 matrix view. /// A column-major 4x6 matrix view.
///
/// See [`MatrixView4x6`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4x6<'a, T, RStride = U1, CStride = U4> = pub type MatrixViewMut4x6<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U6, ViewStorageMut<'a, T, U4, U6, RStride, CStride>>; Matrix<T, U4, U6, ViewStorageMut<'a, T, U4, U6, RStride, CStride>>;
/// A mutable column-major 5x1 matrix view. /// A column-major 5x1 matrix view.
///
/// See [`MatrixView5x1`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5x1<'a, T, RStride = U1, CStride = U5> = pub type MatrixViewMut5x1<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>;
/// A mutable column-major 5x2 matrix view. /// A column-major 5x2 matrix view.
///
/// See [`MatrixView5x2`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5x2<'a, T, RStride = U1, CStride = U5> = pub type MatrixViewMut5x2<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U2, ViewStorageMut<'a, T, U5, U2, RStride, CStride>>; Matrix<T, U5, U2, ViewStorageMut<'a, T, U5, U2, RStride, CStride>>;
/// A mutable column-major 5x3 matrix view. /// A column-major 5x3 matrix view.
///
/// See [`MatrixView5x3`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5x3<'a, T, RStride = U1, CStride = U5> = pub type MatrixViewMut5x3<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U3, ViewStorageMut<'a, T, U5, U3, RStride, CStride>>; Matrix<T, U5, U3, ViewStorageMut<'a, T, U5, U3, RStride, CStride>>;
/// A mutable column-major 5x4 matrix view. /// A column-major 5x4 matrix view.
///
/// See [`MatrixView5x4`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5x4<'a, T, RStride = U1, CStride = U5> = pub type MatrixViewMut5x4<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U4, ViewStorageMut<'a, T, U5, U4, RStride, CStride>>; Matrix<T, U5, U4, ViewStorageMut<'a, T, U5, U4, RStride, CStride>>;
/// A mutable column-major 5x6 matrix view. /// A column-major 5x6 matrix view.
///
/// See [`MatrixView5x6`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5x6<'a, T, RStride = U1, CStride = U5> = pub type MatrixViewMut5x6<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U6, ViewStorageMut<'a, T, U5, U6, RStride, CStride>>; Matrix<T, U5, U6, ViewStorageMut<'a, T, U5, U6, RStride, CStride>>;
/// A mutable column-major 6x1 matrix view. /// A column-major 6x1 matrix view.
///
/// See [`MatrixView6x1`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6x1<'a, T, RStride = U1, CStride = U6> = pub type MatrixViewMut6x1<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U1, ViewStorageMut<'a, T, U6, U1, RStride, CStride>>; Matrix<T, U6, U1, ViewStorageMut<'a, T, U6, U1, RStride, CStride>>;
/// A mutable column-major 6x2 matrix view. /// A column-major 6x2 matrix view.
///
/// See [`MatrixView6x2`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6x2<'a, T, RStride = U1, CStride = U6> = pub type MatrixViewMut6x2<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U2, ViewStorageMut<'a, T, U6, U2, RStride, CStride>>; Matrix<T, U6, U2, ViewStorageMut<'a, T, U6, U2, RStride, CStride>>;
/// A mutable column-major 6x3 matrix view. /// A column-major 6x3 matrix view.
///
/// See [`MatrixView6x3`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6x3<'a, T, RStride = U1, CStride = U6> = pub type MatrixViewMut6x3<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U3, ViewStorageMut<'a, T, U6, U3, RStride, CStride>>; Matrix<T, U6, U3, ViewStorageMut<'a, T, U6, U3, RStride, CStride>>;
/// A mutable column-major 6x4 matrix view. /// A column-major 6x4 matrix view.
///
/// See [`MatrixView6x4`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6x4<'a, T, RStride = U1, CStride = U6> = pub type MatrixViewMut6x4<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U4, ViewStorageMut<'a, T, U6, U4, RStride, CStride>>; Matrix<T, U6, U4, ViewStorageMut<'a, T, U6, U4, RStride, CStride>>;
/// A mutable column-major 6x5 matrix view. /// A column-major 6x5 matrix view.
///
/// See [`MatrixView6x5`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6x5<'a, T, RStride = U1, CStride = U6> = pub type MatrixViewMut6x5<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U5, ViewStorageMut<'a, T, U6, U5, RStride, CStride>>; Matrix<T, U6, U5, ViewStorageMut<'a, T, U6, U5, RStride, CStride>>;
/// A mutable column-major matrix view with 1 row and a number of columns chosen at runtime. /// A column-major matrix view with 1 row and a number of columns chosen at runtime.
///
/// See [`MatrixView1xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1xX<'a, T, RStride = U1, CStride = U1> = pub type MatrixViewMut1xX<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, Dyn, ViewStorageMut<'a, T, U1, Dyn, RStride, CStride>>; Matrix<T, U1, Dyn, ViewStorageMut<'a, T, U1, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with 2 rows and a number of columns chosen at runtime. /// A column-major matrix view with 2 rows and a number of columns chosen at runtime.
///
/// See [`MatrixView2xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2xX<'a, T, RStride = U1, CStride = U2> = pub type MatrixViewMut2xX<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, Dyn, ViewStorageMut<'a, T, U2, Dyn, RStride, CStride>>; Matrix<T, U2, Dyn, ViewStorageMut<'a, T, U2, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with 3 rows and a number of columns chosen at runtime. /// A column-major matrix view with 3 rows and a number of columns chosen at runtime.
///
/// See [`MatrixView3xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3xX<'a, T, RStride = U1, CStride = U3> = pub type MatrixViewMut3xX<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, Dyn, ViewStorageMut<'a, T, U3, Dyn, RStride, CStride>>; Matrix<T, U3, Dyn, ViewStorageMut<'a, T, U3, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with 4 rows and a number of columns chosen at runtime. /// A column-major matrix view with 4 rows and a number of columns chosen at runtime.
///
/// See [`MatrixView4xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4xX<'a, T, RStride = U1, CStride = U4> = pub type MatrixViewMut4xX<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, Dyn, ViewStorageMut<'a, T, U4, Dyn, RStride, CStride>>; Matrix<T, U4, Dyn, ViewStorageMut<'a, T, U4, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with 5 rows and a number of columns chosen at runtime. /// A column-major matrix view with 5 rows and a number of columns chosen at runtime.
///
/// See [`MatrixView5xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5xX<'a, T, RStride = U1, CStride = U5> = pub type MatrixViewMut5xX<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, Dyn, ViewStorageMut<'a, T, U5, Dyn, RStride, CStride>>; Matrix<T, U5, Dyn, ViewStorageMut<'a, T, U5, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with 6 rows and a number of columns chosen at runtime. /// A column-major matrix view with 6 rows and a number of columns chosen at runtime.
///
/// See [`MatrixView6xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6xX<'a, T, RStride = U1, CStride = U6> = pub type MatrixViewMut6xX<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, Dyn, ViewStorageMut<'a, T, U6, Dyn, RStride, CStride>>; Matrix<T, U6, Dyn, ViewStorageMut<'a, T, U6, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 1 column. /// A column-major matrix view with a number of rows chosen at runtime and 1 column.
///
/// See [`MatrixViewXx1`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx1<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewMutXx1<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorageMut<'a, T, Dyn, U1, RStride, CStride>>; Matrix<T, Dyn, U1, ViewStorageMut<'a, T, Dyn, U1, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 2 columns. /// A column-major matrix view with a number of rows chosen at runtime and 2 columns.
///
/// See [`MatrixViewXx2`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx2<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewMutXx2<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U2, ViewStorageMut<'a, T, Dyn, U2, RStride, CStride>>; Matrix<T, Dyn, U2, ViewStorageMut<'a, T, Dyn, U2, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 3 columns. /// A column-major matrix view with a number of rows chosen at runtime and 3 columns.
///
/// See [`MatrixViewXx3`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx3<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewMutXx3<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U3, ViewStorageMut<'a, T, Dyn, U3, RStride, CStride>>; Matrix<T, Dyn, U3, ViewStorageMut<'a, T, Dyn, U3, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 4 columns. /// A column-major matrix view with a number of rows chosen at runtime and 4 columns.
///
/// See [`MatrixViewXx4`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx4<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewMutXx4<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U4, ViewStorageMut<'a, T, Dyn, U4, RStride, CStride>>; Matrix<T, Dyn, U4, ViewStorageMut<'a, T, Dyn, U4, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 5 columns. /// A column-major matrix view with a number of rows chosen at runtime and 5 columns.
///
/// See [`MatrixViewXx5`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx5<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewMutXx5<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U5, ViewStorageMut<'a, T, Dyn, U5, RStride, CStride>>; Matrix<T, Dyn, U5, ViewStorageMut<'a, T, Dyn, U5, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 6 columns. /// A column-major matrix view with a number of rows chosen at runtime and 6 columns.
///
/// See [`MatrixViewXx6`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx6<'a, T, RStride = U1, CStride = Dyn> = pub type MatrixViewMutXx6<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U6, ViewStorageMut<'a, T, Dyn, U6, RStride, CStride>>; Matrix<T, Dyn, U6, ViewStorageMut<'a, T, Dyn, U6, RStride, CStride>>;
/// A mutable column vector view with dimensions known at compile-time. /// A column vector view with dimensions known at compile-time.
///
/// See [`VectorView`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut<'a, T, D, RStride = U1, CStride = D> = pub type VectorViewMut<'a, T, D, RStride = U1, CStride = D> =
Matrix<T, D, U1, ViewStorageMut<'a, T, D, U1, RStride, CStride>>; Matrix<T, D, U1, ViewStorageMut<'a, T, D, U1, RStride, CStride>>;
/// A mutable column vector view with dimensions known at compile-time. /// A column vector view with dimensions known at compile-time.
///
/// See [`SVectorView`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type SVectorViewMut<'a, T, const D: usize> = pub type SVectorViewMut<'a, T, const D: usize> =
Matrix<T, Const<D>, Const<1>, ViewStorageMut<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>; Matrix<T, Const<D>, Const<1>, ViewStorageMut<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
/// A mutable column vector view dynamic numbers of rows and columns. /// A column vector view dynamic numbers of rows and columns.
///
/// See [`DVectorView`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DVectorViewMut<'a, T, RStride = U1, CStride = Dyn> = pub type DVectorViewMut<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorageMut<'a, T, Dyn, U1, RStride, CStride>>; Matrix<T, Dyn, U1, ViewStorageMut<'a, T, Dyn, U1, RStride, CStride>>;
/// A mutable 1D column vector view. /// A 1D column vector view.
///
/// See [`VectorView1`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut1<'a, T, RStride = U1, CStride = U1> = pub type VectorViewMut1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>;
/// A mutable 2D column vector view. /// A 2D column vector view.
///
/// See [`VectorView2`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut2<'a, T, RStride = U1, CStride = U2> = pub type VectorViewMut2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>;
/// A mutable 3D column vector view. /// A 3D column vector view.
///
/// See [`VectorView3`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut3<'a, T, RStride = U1, CStride = U3> = pub type VectorViewMut3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>;
/// A mutable 4D column vector view. /// A 4D column vector view.
///
/// See [`VectorView4`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut4<'a, T, RStride = U1, CStride = U4> = pub type VectorViewMut4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>;
/// A mutable 5D column vector view. /// A 5D column vector view.
///
/// See [`VectorView5`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut5<'a, T, RStride = U1, CStride = U5> = pub type VectorViewMut5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>;
/// A mutable 6D column vector view. /// A 6D column vector view.
///
/// See [`VectorView6`] for an immutable version of this type.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut6<'a, T, RStride = U1, CStride = U6> = pub type VectorViewMut6<'a, T, RStride = U1, CStride = U6> =

View File

@ -19,36 +19,36 @@ use std::mem::MaybeUninit;
/// ///
/// Every allocator must be both static and dynamic. Though not all implementations may share the /// Every allocator must be both static and dynamic. Though not all implementations may share the
/// same `Buffer` type. /// same `Buffer` type.
pub trait Allocator<R: Dim, C: Dim = U1>: Any + Sized { pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized {
/// The type of buffer this allocator can instantiate. /// The type of buffer this allocator can instantiate.
type Buffer<T: Scalar>: StorageMut<T, R, C> + IsContiguous + Clone + Debug; type Buffer: StorageMut<T, R, C> + IsContiguous + Clone + Debug;
/// The type of buffer with uninitialized components this allocator can instantiate. /// The type of buffer with uninitialized components this allocator can instantiate.
type BufferUninit<T: Scalar>: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous; type BufferUninit: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous;
/// Allocates a buffer with the given number of rows and columns without initializing its content. /// Allocates a buffer with the given number of rows and columns without initializing its content.
fn allocate_uninit<T: Scalar>(nrows: R, ncols: C) -> Self::BufferUninit<T>; fn allocate_uninit(nrows: R, ncols: C) -> Self::BufferUninit;
/// Assumes a data buffer to be initialized. /// Assumes a data buffer to be initialized.
/// ///
/// # Safety /// # Safety
/// The user must make sure that every single entry of the buffer has been initialized, /// The user must make sure that every single entry of the buffer has been initialized,
/// or Undefined Behavior will immediately occur. /// or Undefined Behavior will immediately occur.
unsafe fn assume_init<T: Scalar>(uninit: Self::BufferUninit<T>) -> Self::Buffer<T>; unsafe fn assume_init(uninit: Self::BufferUninit) -> Self::Buffer;
/// Allocates a buffer initialized with the content of the given iterator. /// Allocates a buffer initialized with the content of the given iterator.
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>( fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: R, nrows: R,
ncols: C, ncols: C,
iter: I, iter: I,
) -> Self::Buffer<T>; ) -> Self::Buffer;
#[inline] #[inline]
/// Allocates a buffer initialized with the content of the given row-major order iterator. /// Allocates a buffer initialized with the content of the given row-major order iterator.
fn allocate_from_row_iterator<T: Scalar, I: IntoIterator<Item = T>>( fn allocate_from_row_iterator<I: IntoIterator<Item = T>>(
nrows: R, nrows: R,
ncols: C, ncols: C,
iter: I, iter: I,
) -> Self::Buffer<T> { ) -> Self::Buffer {
let mut res = Self::allocate_uninit(nrows, ncols); let mut res = Self::allocate_uninit(nrows, ncols);
let mut count = 0; let mut count = 0;
@ -73,7 +73,7 @@ pub trait Allocator<R: Dim, C: Dim = U1>: Any + Sized {
"Matrix init. from row iterator: iterator not long enough." "Matrix init. from row iterator: iterator not long enough."
); );
<Self as Allocator<R, C>>::assume_init(res) <Self as Allocator<T, R, C>>::assume_init(res)
} }
} }
} }
@ -81,7 +81,7 @@ pub trait Allocator<R: Dim, C: Dim = U1>: Any + Sized {
/// A matrix reallocator. Changes the size of the memory buffer that initially contains (`RFrom` × /// A matrix reallocator. Changes the size of the memory buffer that initially contains (`RFrom` ×
/// `CFrom`) elements to a smaller or larger size (`RTo`, `CTo`). /// `CFrom`) elements to a smaller or larger size (`RTo`, `CTo`).
pub trait Reallocator<T: Scalar, RFrom: Dim, CFrom: Dim, RTo: Dim, CTo: Dim>: pub trait Reallocator<T: Scalar, RFrom: Dim, CFrom: Dim, RTo: Dim, CTo: Dim>:
Allocator<RFrom, CFrom> + Allocator<RTo, CTo> Allocator<T, RFrom, CFrom> + Allocator<T, RTo, CTo>
{ {
/// Reallocates a buffer of shape `(RTo, CTo)`, possibly reusing a previously allocated buffer /// Reallocates a buffer of shape `(RTo, CTo)`, possibly reusing a previously allocated buffer
/// `buf`. Data stored by `buf` are linearly copied to the output: /// `buf`. Data stored by `buf` are linearly copied to the output:
@ -94,8 +94,8 @@ pub trait Reallocator<T: Scalar, RFrom: Dim, CFrom: Dim, RTo: Dim, CTo: Dim>:
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
nrows: RTo, nrows: RTo,
ncols: CTo, ncols: CTo,
buf: <Self as Allocator<RFrom, CFrom>>::Buffer<T>, buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer,
) -> <Self as Allocator<RTo, CTo>>::BufferUninit<T>; ) -> <Self as Allocator<T, RTo, CTo>>::BufferUninit;
} }
/// The number of rows of the result of a componentwise operation on two matrices. /// The number of rows of the result of a componentwise operation on two matrices.
@ -106,8 +106,8 @@ pub type SameShapeC<C1, C2> = <ShapeConstraint as SameNumberOfColumns<C1, C2>>::
// TODO: Bad name. // TODO: Bad name.
/// Restricts the given number of rows and columns to be respectively the same. /// Restricts the given number of rows and columns to be respectively the same.
pub trait SameShapeAllocator<R1, C1, R2, C2>: pub trait SameShapeAllocator<T, R1, C1, R2, C2>:
Allocator<R1, C1> + Allocator<SameShapeR<R1, R2>, SameShapeC<C1, C2>> Allocator<T, R1, C1> + Allocator<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>
where where
R1: Dim, R1: Dim,
R2: Dim, R2: Dim,
@ -117,21 +117,21 @@ where
{ {
} }
impl<R1, R2, C1, C2> SameShapeAllocator<R1, C1, R2, C2> for DefaultAllocator impl<T, R1, R2, C1, C2> SameShapeAllocator<T, R1, C1, R2, C2> for DefaultAllocator
where where
R1: Dim, R1: Dim,
R2: Dim, R2: Dim,
C1: Dim, C1: Dim,
C2: Dim, C2: Dim,
DefaultAllocator: Allocator<R1, C1> + Allocator<SameShapeR<R1, R2>, SameShapeC<C1, C2>>, DefaultAllocator: Allocator<T, R1, C1> + Allocator<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>, ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
{ {
} }
// XXX: Bad name. // XXX: Bad name.
/// Restricts the given number of rows to be equal. /// Restricts the given number of rows to be equal.
pub trait SameShapeVectorAllocator<R1, R2>: pub trait SameShapeVectorAllocator<T, R1, R2>:
Allocator<R1> + Allocator<SameShapeR<R1, R2>> + SameShapeAllocator<R1, U1, R2, U1> Allocator<T, R1> + Allocator<T, SameShapeR<R1, R2>> + SameShapeAllocator<T, R1, U1, R2, U1>
where where
R1: Dim, R1: Dim,
R2: Dim, R2: Dim,
@ -139,11 +139,11 @@ where
{ {
} }
impl<R1, R2> SameShapeVectorAllocator<R1, R2> for DefaultAllocator impl<T, R1, R2> SameShapeVectorAllocator<T, R1, R2> for DefaultAllocator
where where
R1: Dim, R1: Dim,
R2: Dim, R2: Dim,
DefaultAllocator: Allocator<R1, U1> + Allocator<SameShapeR<R1, R2>>, DefaultAllocator: Allocator<T, R1, U1> + Allocator<T, SameShapeR<R1, R2>>,
ShapeConstraint: SameNumberOfRows<R1, R2>, ShapeConstraint: SameNumberOfRows<R1, R2>,
{ {
} }

View File

@ -27,7 +27,7 @@ use std::mem;
* Static RawStorage. * Static RawStorage.
* *
*/ */
/// An array-based statically sized matrix data storage. /// A array-based statically sized matrix data storage.
#[repr(transparent)] #[repr(transparent)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr( #[cfg_attr(
@ -42,6 +42,7 @@ use std::mem;
) )
)] )]
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]); pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]);
impl<T, const R: usize, const C: usize> ArrayStorage<T, R, C> { impl<T, const R: usize, const C: usize> ArrayStorage<T, R, C> {
@ -113,12 +114,12 @@ unsafe impl<T, const R: usize, const C: usize> RawStorage<T, Const<R>, Const<C>>
unsafe impl<T: Scalar, const R: usize, const C: usize> Storage<T, Const<R>, Const<C>> unsafe impl<T: Scalar, const R: usize, const C: usize> Storage<T, Const<R>, Const<C>>
for ArrayStorage<T, R, C> for ArrayStorage<T, R, C>
where where
DefaultAllocator: Allocator<Const<R>, Const<C>, Buffer<T> = Self>, DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
{ {
#[inline] #[inline]
fn into_owned(self) -> Owned<T, Const<R>, Const<C>> fn into_owned(self) -> Owned<T, Const<R>, Const<C>>
where where
DefaultAllocator: Allocator<Const<R>, Const<C>>, DefaultAllocator: Allocator<T, Const<R>, Const<C>>,
{ {
self self
} }
@ -126,16 +127,10 @@ where
#[inline] #[inline]
fn clone_owned(&self) -> Owned<T, Const<R>, Const<C>> fn clone_owned(&self) -> Owned<T, Const<R>, Const<C>>
where where
DefaultAllocator: Allocator<Const<R>, Const<C>>, DefaultAllocator: Allocator<T, Const<R>, Const<C>>,
{ {
self.clone() self.clone()
} }
#[inline]
fn forget_elements(self) {
// No additional cleanup required.
std::mem::forget(self);
}
} }
unsafe impl<T, const R: usize, const C: usize> RawStorageMut<T, Const<R>, Const<C>> unsafe impl<T, const R: usize, const C: usize> RawStorageMut<T, Const<R>, Const<C>>
@ -256,7 +251,7 @@ where
V: SeqAccess<'a>, V: SeqAccess<'a>,
{ {
let mut out: ArrayStorage<core::mem::MaybeUninit<T>, R, C> = let mut out: ArrayStorage<core::mem::MaybeUninit<T>, R, C> =
<DefaultAllocator as Allocator<_, _>>::allocate_uninit(Const::<R>, Const::<C>); DefaultAllocator::allocate_uninit(Const::<R>, Const::<C>);
let mut curr = 0; let mut curr = 0;
while let Some(value) = visitor.next_element()? { while let Some(value) = visitor.next_element()? {
@ -269,7 +264,7 @@ where
if curr == R * C { if curr == R * C {
// Safety: all the elements have been initialized. // Safety: all the elements have been initialized.
unsafe { Ok(<DefaultAllocator as Allocator<Const<R>, Const<C>>>::assume_init(out)) } unsafe { Ok(<DefaultAllocator as Allocator<T, Const<R>, Const<C>>>::assume_init(out)) }
} else { } else {
for i in 0..curr { for i in 0..curr {
// Safety: // Safety:

View File

@ -1,6 +1,6 @@
use crate::{RawStorage, SimdComplexField}; use crate::{RawStorage, SimdComplexField};
use num::{One, Zero}; use num::{One, Zero};
use simba::scalar::{ClosedAddAssign, ClosedMulAssign}; use simba::scalar::{ClosedAdd, ClosedMul};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::blas_uninit::{axcpy_uninit, gemm_uninit, gemv_uninit}; use crate::base::blas_uninit::{axcpy_uninit, gemm_uninit, gemv_uninit};
@ -17,7 +17,7 @@ use crate::base::{
/// # Dot/scalar product /// # Dot/scalar product
impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S>
where where
T: Scalar + Zero + ClosedAddAssign + ClosedMulAssign, T: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
#[inline(always)] #[inline(always)]
fn dotx<R2: Dim, C2: Dim, SB>( fn dotx<R2: Dim, C2: Dim, SB>(
@ -275,7 +275,7 @@ where
/// # BLAS functions /// # BLAS functions
impl<T, D: Dim, S> Vector<T, D, S> impl<T, D: Dim, S> Vector<T, D, S>
where where
T: Scalar + Zero + ClosedAddAssign + ClosedMulAssign, T: Scalar + Zero + ClosedAdd + ClosedMul,
S: StorageMut<T, D>, S: StorageMut<T, D>,
{ {
/// Computes `self = a * x * c + b * self`. /// Computes `self = a * x * c + b * self`.
@ -609,7 +609,7 @@ where
impl<T, R1: Dim, C1: Dim, S: StorageMut<T, R1, C1>> Matrix<T, R1, C1, S> impl<T, R1: Dim, C1: Dim, S: StorageMut<T, R1, C1>> Matrix<T, R1, C1, S>
where where
T: Scalar + Zero + ClosedAddAssign + ClosedMulAssign, T: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
#[inline(always)] #[inline(always)]
fn gerx<D2: Dim, D3: Dim, SB, SC>( fn gerx<D2: Dim, D3: Dim, SB, SC>(
@ -862,7 +862,7 @@ where
impl<T, R1: Dim, C1: Dim, S: StorageMut<T, R1, C1>> Matrix<T, R1, C1, S> impl<T, R1: Dim, C1: Dim, S: StorageMut<T, R1, C1>> Matrix<T, R1, C1, S>
where where
T: Scalar + Zero + ClosedAddAssign + ClosedMulAssign, T: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
#[inline(always)] #[inline(always)]
fn xxgerx<D2: Dim, D3: Dim, SB, SC>( fn xxgerx<D2: Dim, D3: Dim, SB, SC>(
@ -1010,7 +1010,7 @@ where
impl<T, D1: Dim, S: StorageMut<T, D1, D1>> SquareMatrix<T, D1, S> impl<T, D1: Dim, S: StorageMut<T, D1, D1>> SquareMatrix<T, D1, S>
where where
T: Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, T: Scalar + Zero + One + ClosedAdd + ClosedMul,
{ {
/// Computes the quadratic form `self = alpha * lhs * mid * lhs.transpose() + beta * self`. /// Computes the quadratic form `self = alpha * lhs * mid * lhs.transpose() + beta * self`.
/// ///
@ -1098,7 +1098,7 @@ where
S3: Storage<T, R3, C3>, S3: Storage<T, R3, C3>,
S4: Storage<T, D4, D4>, S4: Storage<T, D4, D4>,
ShapeConstraint: DimEq<D1, D1> + DimEq<D1, R3> + DimEq<C3, D4>, ShapeConstraint: DimEq<D1, D1> + DimEq<D1, R3> + DimEq<C3, D4>,
DefaultAllocator: Allocator<D1>, DefaultAllocator: Allocator<T, D1>,
{ {
// TODO: would it be useful to avoid the zero-initialization of the workspace data? // TODO: would it be useful to avoid the zero-initialization of the workspace data?
let mut work = Matrix::zeros_generic(self.shape_generic().0, Const::<1>); let mut work = Matrix::zeros_generic(self.shape_generic().0, Const::<1>);
@ -1196,7 +1196,7 @@ where
S2: Storage<T, D2, D2>, S2: Storage<T, D2, D2>,
S3: Storage<T, R3, C3>, S3: Storage<T, R3, C3>,
ShapeConstraint: DimEq<D2, R3> + DimEq<D1, C3> + AreMultipliable<C3, R3, D2, U1>, ShapeConstraint: DimEq<D2, R3> + DimEq<D1, C3> + AreMultipliable<C3, R3, D2, U1>,
DefaultAllocator: Allocator<D2>, DefaultAllocator: Allocator<T, D2>,
{ {
// TODO: would it be useful to avoid the zero-initialization of the workspace data? // TODO: would it be useful to avoid the zero-initialization of the workspace data?
let mut work = Vector::zeros_generic(mid.shape_generic().0, Const::<1>); let mut work = Vector::zeros_generic(mid.shape_generic().0, Const::<1>);

View File

@ -11,19 +11,18 @@
#[cfg(feature = "std")] #[cfg(feature = "std")]
use matrixmultiply; use matrixmultiply;
use num::{One, Zero}; use num::{One, Zero};
use simba::scalar::{ClosedAddAssign, ClosedMulAssign}; use simba::scalar::{ClosedAdd, ClosedMul};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::{any::TypeId, mem}; use std::mem;
use crate::base::constraint::{ use crate::base::constraint::{
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint, AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
}; };
#[cfg(feature = "std")] use crate::base::dimension::{Dim, Dyn, U1};
use crate::base::dimension::Dyn;
use crate::base::dimension::{Dim, U1};
use crate::base::storage::{RawStorage, RawStorageMut}; use crate::base::storage::{RawStorage, RawStorageMut};
use crate::base::uninit::InitStatus; use crate::base::uninit::InitStatus;
use crate::base::{Matrix, Scalar, Vector}; use crate::base::{Matrix, Scalar, Vector};
use std::any::TypeId;
// # Safety // # Safety
// The content of `y` must only contain values for which // The content of `y` must only contain values for which
@ -41,7 +40,7 @@ unsafe fn array_axcpy<Status, T>(
len: usize, len: usize,
) where ) where
Status: InitStatus<T>, Status: InitStatus<T>,
T: Scalar + Zero + ClosedAddAssign + ClosedMulAssign, T: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
for i in 0..len { for i in 0..len {
let y = Status::assume_init_mut(y.get_unchecked_mut(i * stride1)); let y = Status::assume_init_mut(y.get_unchecked_mut(i * stride1));
@ -61,7 +60,7 @@ fn array_axc<Status, T>(
len: usize, len: usize,
) where ) where
Status: InitStatus<T>, Status: InitStatus<T>,
T: Scalar + Zero + ClosedAddAssign + ClosedMulAssign, T: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
for i in 0..len { for i in 0..len {
unsafe { unsafe {
@ -89,7 +88,7 @@ pub unsafe fn axcpy_uninit<Status, T, D1: Dim, D2: Dim, SA, SB>(
c: T, c: T,
b: T, b: T,
) where ) where
T: Scalar + Zero + ClosedAddAssign + ClosedMulAssign, T: Scalar + Zero + ClosedAdd + ClosedMul,
SA: RawStorageMut<Status::Value, D1>, SA: RawStorageMut<Status::Value, D1>,
SB: RawStorage<T, D2>, SB: RawStorage<T, D2>,
ShapeConstraint: DimEq<D1, D2>, ShapeConstraint: DimEq<D1, D2>,
@ -129,7 +128,7 @@ pub unsafe fn gemv_uninit<Status, T, D1: Dim, R2: Dim, C2: Dim, D3: Dim, SA, SB,
beta: T, beta: T,
) where ) where
Status: InitStatus<T>, Status: InitStatus<T>,
T: Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, T: Scalar + Zero + One + ClosedAdd + ClosedMul,
SA: RawStorageMut<Status::Value, D1>, SA: RawStorageMut<Status::Value, D1>,
SB: RawStorage<T, R2, C2>, SB: RawStorage<T, R2, C2>,
SC: RawStorage<T, D3>, SC: RawStorage<T, D3>,
@ -199,7 +198,7 @@ pub unsafe fn gemm_uninit<
beta: T, beta: T,
) where ) where
Status: InitStatus<T>, Status: InitStatus<T>,
T: Scalar + Zero + One + ClosedAddAssign + ClosedMulAssign, T: Scalar + Zero + One + ClosedAdd + ClosedMul,
SA: RawStorageMut<Status::Value, R1, C1>, SA: RawStorageMut<Status::Value, R1, C1>,
SB: RawStorage<T, R2, C2>, SB: RawStorage<T, R2, C2>,
SC: RawStorage<T, R3, C3>, SC: RawStorage<T, R3, C3>,

View File

@ -19,13 +19,13 @@ use crate::geometry::{
Rotation3, Rotation3,
}; };
use simba::scalar::{ClosedAddAssign, ClosedMulAssign, RealField}; use simba::scalar::{ClosedAdd, ClosedMul, RealField};
/// # Translation and scaling in any dimension /// # Translation and scaling in any dimension
impl<T, D: DimName> OMatrix<T, D, D> impl<T, D: DimName> OMatrix<T, D, D>
where where
T: Scalar + Zero + One, T: Scalar + Zero + One,
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
/// Creates a new homogeneous matrix that applies the same scaling factor on each dimension. /// Creates a new homogeneous matrix that applies the same scaling factor on each dimension.
#[inline] #[inline]
@ -207,11 +207,8 @@ impl<T: RealField> Matrix4<T> {
} }
/// # Append/prepend translation and scaling /// # Append/prepend translation and scaling
impl< impl<T: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<T, D, D>>
T: Scalar + Zero + One + ClosedMulAssign + ClosedAddAssign, SquareMatrix<T, D, S>
D: DimName,
S: Storage<T, D, D>,
> SquareMatrix<T, D, S>
{ {
/// Computes the transformation equal to `self` followed by an uniform scaling factor. /// Computes the transformation equal to `self` followed by an uniform scaling factor.
#[inline] #[inline]
@ -219,7 +216,7 @@ impl<
pub fn append_scaling(&self, scaling: T) -> OMatrix<T, D, D> pub fn append_scaling(&self, scaling: T) -> OMatrix<T, D, D>
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.append_scaling_mut(scaling); res.append_scaling_mut(scaling);
@ -232,7 +229,7 @@ impl<
pub fn prepend_scaling(&self, scaling: T) -> OMatrix<T, D, D> pub fn prepend_scaling(&self, scaling: T) -> OMatrix<T, D, D>
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.prepend_scaling_mut(scaling); res.prepend_scaling_mut(scaling);
@ -249,7 +246,7 @@ impl<
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<T, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.append_nonuniform_scaling_mut(scaling); res.append_nonuniform_scaling_mut(scaling);
@ -266,7 +263,7 @@ impl<
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<T, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.prepend_nonuniform_scaling_mut(scaling); res.prepend_nonuniform_scaling_mut(scaling);
@ -283,7 +280,7 @@ impl<
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<T, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.append_translation_mut(shift); res.append_translation_mut(shift);
@ -300,7 +297,7 @@ impl<
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<T, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
DefaultAllocator: Allocator<D, D> + Allocator<DimNameDiff<D, U1>>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimNameDiff<D, U1>>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.prepend_translation_mut(shift); res.prepend_translation_mut(shift);
@ -382,7 +379,7 @@ impl<
D: DimNameSub<U1>, D: DimNameSub<U1>,
S: StorageMut<T, D, D>, S: StorageMut<T, D, D>,
SB: Storage<T, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
DefaultAllocator: Allocator<DimNameDiff<D, U1>>, DefaultAllocator: Allocator<T, DimNameDiff<D, U1>>,
{ {
let scale = self let scale = self
.generic_view( .generic_view(
@ -408,9 +405,9 @@ impl<
/// # Transformation of vectors and points /// # Transformation of vectors and points
impl<T: RealField, D: DimNameSub<U1>, S: Storage<T, D, D>> SquareMatrix<T, D, S> impl<T: RealField, D: DimNameSub<U1>, S: Storage<T, D, D>> SquareMatrix<T, D, S>
where where
DefaultAllocator: Allocator<D, D> DefaultAllocator: Allocator<T, D, D>
+ Allocator<DimNameDiff<D, U1>> + Allocator<T, DimNameDiff<D, U1>>
+ Allocator<DimNameDiff<D, U1>, DimNameDiff<D, U1>>, + Allocator<T, DimNameDiff<D, U1>, DimNameDiff<D, U1>>,
{ {
/// Transforms the given vector, assuming the matrix `self` uses homogeneous coordinates. /// Transforms the given vector, assuming the matrix `self` uses homogeneous coordinates.
#[inline] #[inline]

View File

@ -3,7 +3,7 @@
use num::{Signed, Zero}; use num::{Signed, Zero};
use std::ops::{Add, Mul}; use std::ops::{Add, Mul};
use simba::scalar::{ClosedDivAssign, ClosedMulAssign}; use simba::scalar::{ClosedDiv, ClosedMul};
use simba::simd::SimdPartialOrd; use simba::simd::SimdPartialOrd;
use crate::base::allocator::{Allocator, SameShapeAllocator}; use crate::base::allocator::{Allocator, SameShapeAllocator};
@ -11,7 +11,7 @@ use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstr
use crate::base::dimension::Dim; use crate::base::dimension::Dim;
use crate::base::storage::{Storage, StorageMut}; use crate::base::storage::{Storage, StorageMut};
use crate::base::{DefaultAllocator, Matrix, MatrixSum, OMatrix, Scalar}; use crate::base::{DefaultAllocator, Matrix, MatrixSum, OMatrix, Scalar};
use crate::ClosedAddAssign; use crate::ClosedAdd;
/// The type of the result of a matrix component-wise operation. /// The type of the result of a matrix component-wise operation.
pub type MatrixComponentOp<T, R1, C1, R2, C2> = MatrixSum<T, R1, C1, R2, C2>; pub type MatrixComponentOp<T, R1, C1, R2, C2> = MatrixSum<T, R1, C1, R2, C2>;
@ -32,7 +32,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
pub fn abs(&self) -> OMatrix<T, R, C> pub fn abs(&self) -> OMatrix<T, R, C>
where where
T: Signed, T: Signed,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
@ -55,7 +55,7 @@ macro_rules! component_binop_impl(
where T: $Trait, where T: $Trait,
R2: Dim, C2: Dim, R2: Dim, C2: Dim,
SB: Storage<T, R2, C2>, SB: Storage<T, R2, C2>,
DefaultAllocator: SameShapeAllocator<R1, C1, R2, C2>, DefaultAllocator: SameShapeAllocator<T, R1, C1, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> { ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions."); assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
@ -148,7 +148,7 @@ macro_rules! component_binop_impl(
/// # Componentwise operations /// # Componentwise operations
impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA> { impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA> {
component_binop_impl!( component_binop_impl!(
component_mul, component_mul_mut, component_mul_assign, cmpy, ClosedMulAssign.mul.mul_assign, component_mul, component_mul_mut, component_mul_assign, cmpy, ClosedMul.mul.mul_assign,
r" r"
Componentwise matrix or vector multiplication. Componentwise matrix or vector multiplication.
@ -193,7 +193,7 @@ impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
assert_eq!(a, expected); assert_eq!(a, expected);
``` ```
"; ";
component_div, component_div_mut, component_div_assign, cdpy, ClosedDivAssign.div.div_assign, component_div, component_div_mut, component_div_assign, cdpy, ClosedDiv.div.div_assign,
r" r"
Componentwise matrix or vector division. Componentwise matrix or vector division.
@ -257,7 +257,7 @@ impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
pub fn inf(&self, other: &Self) -> OMatrix<T, R1, C1> pub fn inf(&self, other: &Self) -> OMatrix<T, R1, C1>
where where
T: SimdPartialOrd, T: SimdPartialOrd,
DefaultAllocator: Allocator<R1, C1>, DefaultAllocator: Allocator<T, R1, C1>,
{ {
self.zip_map(other, |a, b| a.simd_min(b)) self.zip_map(other, |a, b| a.simd_min(b))
} }
@ -278,7 +278,7 @@ impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
pub fn sup(&self, other: &Self) -> OMatrix<T, R1, C1> pub fn sup(&self, other: &Self) -> OMatrix<T, R1, C1>
where where
T: SimdPartialOrd, T: SimdPartialOrd,
DefaultAllocator: Allocator<R1, C1>, DefaultAllocator: Allocator<T, R1, C1>,
{ {
self.zip_map(other, |a, b| a.simd_max(b)) self.zip_map(other, |a, b| a.simd_max(b))
} }
@ -299,7 +299,7 @@ impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
pub fn inf_sup(&self, other: &Self) -> (OMatrix<T, R1, C1>, OMatrix<T, R1, C1>) pub fn inf_sup(&self, other: &Self) -> (OMatrix<T, R1, C1>, OMatrix<T, R1, C1>)
where where
T: SimdPartialOrd, T: SimdPartialOrd,
DefaultAllocator: Allocator<R1, C1>, DefaultAllocator: Allocator<T, R1, C1>,
{ {
// TODO: can this be optimized? // TODO: can this be optimized?
(self.inf(other), self.sup(other)) (self.inf(other), self.sup(other))
@ -320,8 +320,8 @@ impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
#[must_use = "Did you mean to use add_scalar_mut()?"] #[must_use = "Did you mean to use add_scalar_mut()?"]
pub fn add_scalar(&self, rhs: T) -> OMatrix<T, R1, C1> pub fn add_scalar(&self, rhs: T) -> OMatrix<T, R1, C1>
where where
T: ClosedAddAssign, T: ClosedAdd,
DefaultAllocator: Allocator<R1, C1>, DefaultAllocator: Allocator<T, R1, C1>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.add_scalar_mut(rhs); res.add_scalar_mut(rhs);
@ -343,7 +343,7 @@ impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
#[inline] #[inline]
pub fn add_scalar_mut(&mut self, rhs: T) pub fn add_scalar_mut(&mut self, rhs: T)
where where
T: ClosedAddAssign, T: ClosedAdd,
SA: StorageMut<T, R1, C1>, SA: StorageMut<T, R1, C1>,
{ {
for e in self.iter_mut() { for e in self.iter_mut() {

View File

@ -6,7 +6,7 @@ use crate::base::dimension::{Dim, DimName, Dyn};
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct ShapeConstraint; pub struct ShapeConstraint;
/// Constrains `C1` and `R2` to be equivalent. /// Constraints `C1` and `R2` to be equivalent.
pub trait AreMultipliable<R1: Dim, C1: Dim, R2: Dim, C2: Dim>: DimEq<C1, R2> {} pub trait AreMultipliable<R1: Dim, C1: Dim, R2: Dim, C2: Dim>: DimEq<C1, R2> {}
impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for ShapeConstraint where impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for ShapeConstraint where
@ -14,21 +14,11 @@ impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for Sha
{ {
} }
/// Constrains `D1` and `D2` to be equivalent. /// Constraints `D1` and `D2` to be equivalent.
pub trait DimEq<D1: Dim, D2: Dim> { pub trait DimEq<D1: Dim, D2: Dim> {
/// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level /// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level
/// constant. /// constant.
type Representative: Dim; type Representative: Dim;
/// This constructs a value of type `Representative` with the
/// correct value
fn representative(d1: D1, d2: D2) -> Option<Self::Representative> {
if d1.value() != d2.value() {
None
} else {
Some(Self::Representative::from_usize(d1.value()))
}
}
} }
impl<D: Dim> DimEq<D, D> for ShapeConstraint { impl<D: Dim> DimEq<D, D> for ShapeConstraint {
@ -45,19 +35,12 @@ impl<D: DimName> DimEq<Dyn, D> for ShapeConstraint {
macro_rules! equality_trait_decl( macro_rules! equality_trait_decl(
($($doc: expr, $Trait: ident),* $(,)*) => {$( ($($doc: expr, $Trait: ident),* $(,)*) => {$(
// XXX: we can't do something like `DimEq<D1> for D2` because we would require a blanket impl… // XXX: we can't do something like `DimEq<D1> for D2` because we would require a blancket impl…
#[doc = $doc] #[doc = $doc]
pub trait $Trait<D1: Dim, D2: Dim>: DimEq<D1, D2> + DimEq<D2, D1> { pub trait $Trait<D1: Dim, D2: Dim>: DimEq<D1, D2> + DimEq<D2, D1> {
/// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level /// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level
/// constant. /// constant.
type Representative: Dim; type Representative: Dim;
/// Returns a representative dimension instance if the two are equal,
/// otherwise `None`.
fn representative(d1: D1, d2: D2) -> Option<<Self as $Trait<D1, D2>>::Representative> {
<Self as DimEq<D1, D2>>::representative(d1, d2)
.map(|common_dim| <Self as $Trait<D1, D2>>::Representative::from_usize(common_dim.value()))
}
} }
impl<D: Dim> $Trait<D, D> for ShapeConstraint { impl<D: Dim> $Trait<D, D> for ShapeConstraint {
@ -75,17 +58,17 @@ macro_rules! equality_trait_decl(
); );
equality_trait_decl!( equality_trait_decl!(
"Constrains `D1` and `D2` to be equivalent. \ "Constraints `D1` and `D2` to be equivalent. \
They are both assumed to be the number of \ They are both assumed to be the number of \
rows of a matrix.", rows of a matrix.",
SameNumberOfRows, SameNumberOfRows,
"Constrains `D1` and `D2` to be equivalent. \ "Constraints `D1` and `D2` to be equivalent. \
They are both assumed to be the number of \ They are both assumed to be the number of \
columns of a matrix.", columns of a matrix.",
SameNumberOfColumns SameNumberOfColumns
); );
/// Constrains D1 and D2 to be equivalent, where they both designate dimensions of algebraic /// Constraints D1 and D2 to be equivalent, where they both designate dimensions of algebraic
/// entities (e.g. square matrices). /// entities (e.g. square matrices).
pub trait SameDimension<D1: Dim, D2: Dim>: pub trait SameDimension<D1: Dim, D2: Dim>:
SameNumberOfRows<D1, D2> + SameNumberOfColumns<D1, D2> SameNumberOfRows<D1, D2> + SameNumberOfColumns<D1, D2>

View File

@ -16,7 +16,7 @@ use rand::{
use std::iter; use std::iter;
use typenum::{self, Cmp, Greater}; use typenum::{self, Cmp, Greater};
use simba::scalar::{ClosedAddAssign, ClosedMulAssign}; use simba::scalar::{ClosedAdd, ClosedMul};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{Dim, DimName, Dyn, ToTypenum}; use crate::base::dimension::{Dim, DimName, Dyn, ToTypenum};
@ -29,7 +29,7 @@ use std::mem::MaybeUninit;
impl<T: Scalar, R: Dim, C: Dim> UninitMatrix<T, R, C> impl<T: Scalar, R: Dim, C: Dim> UninitMatrix<T, R, C>
where where
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
/// Builds a matrix with uninitialized elements of type `MaybeUninit<T>`. /// Builds a matrix with uninitialized elements of type `MaybeUninit<T>`.
#[inline(always)] #[inline(always)]
@ -50,7 +50,7 @@ where
/// These functions should only be used when working on dimension-generic code. /// These functions should only be used when working on dimension-generic code.
impl<T: Scalar, R: Dim, C: Dim> OMatrix<T, R, C> impl<T: Scalar, R: Dim, C: Dim> OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
/// Creates a matrix with all its elements set to `elem`. /// Creates a matrix with all its elements set to `elem`.
#[inline] #[inline]
@ -226,7 +226,7 @@ where
SB: RawStorage<T, Const<1>, C>, SB: RawStorage<T, Const<1>, C>,
{ {
assert!(!rows.is_empty(), "At least one row must be given."); assert!(!rows.is_empty(), "At least one row must be given.");
let nrows = R::try_to_usize().unwrap_or(rows.len()); let nrows = R::try_to_usize().unwrap_or_else(|| rows.len());
let ncols = rows[0].len(); let ncols = rows[0].len();
assert!( assert!(
rows.len() == nrows, rows.len() == nrows,
@ -268,7 +268,7 @@ where
SB: RawStorage<T, R>, SB: RawStorage<T, R>,
{ {
assert!(!columns.is_empty(), "At least one column must be given."); assert!(!columns.is_empty(), "At least one column must be given.");
let ncols = C::try_to_usize().unwrap_or(columns.len()); let ncols = C::try_to_usize().unwrap_or_else(|| columns.len());
let nrows = columns[0].len(); let nrows = columns[0].len();
assert!( assert!(
columns.len() == ncols, columns.len() == ncols,
@ -338,7 +338,7 @@ where
impl<T, D: Dim> OMatrix<T, D, D> impl<T, D: Dim> OMatrix<T, D, D>
where where
T: Scalar, T: Scalar,
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
/// Creates a square matrix with its diagonal set to `diag` and all other entries set to 0. /// Creates a square matrix with its diagonal set to `diag` and all other entries set to 0.
/// ///
@ -646,7 +646,7 @@ macro_rules! impl_constructors(
/// # Constructors of statically-sized vectors or statically-sized matrices /// # Constructors of statically-sized vectors or statically-sized matrices
impl<T: Scalar, R: DimName, C: DimName> OMatrix<T, R, C> impl<T: Scalar, R: DimName, C: DimName> OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
// TODO: this is not very pretty. We could find a better call syntax. // TODO: this is not very pretty. We could find a better call syntax.
impl_constructors!(R, C; // Arguments for Matrix<T, ..., S> impl_constructors!(R, C; // Arguments for Matrix<T, ..., S>
@ -658,7 +658,7 @@ where
/// # Constructors of matrices with a dynamic number of columns /// # Constructors of matrices with a dynamic number of columns
impl<T: Scalar, R: DimName> OMatrix<T, R, Dyn> impl<T: Scalar, R: DimName> OMatrix<T, R, Dyn>
where where
DefaultAllocator: Allocator<R, Dyn>, DefaultAllocator: Allocator<T, R, Dyn>,
{ {
impl_constructors!(R, Dyn; impl_constructors!(R, Dyn;
=> R: DimName; => R: DimName;
@ -669,7 +669,7 @@ where
/// # Constructors of dynamic vectors and matrices with a dynamic number of rows /// # Constructors of dynamic vectors and matrices with a dynamic number of rows
impl<T: Scalar, C: DimName> OMatrix<T, Dyn, C> impl<T: Scalar, C: DimName> OMatrix<T, Dyn, C>
where where
DefaultAllocator: Allocator<Dyn, C>, DefaultAllocator: Allocator<T, Dyn, C>,
{ {
impl_constructors!(Dyn, C; impl_constructors!(Dyn, C;
=> C: DimName; => C: DimName;
@ -678,10 +678,9 @@ where
} }
/// # Constructors of fully dynamic matrices /// # Constructors of fully dynamic matrices
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar> OMatrix<T, Dyn, Dyn> impl<T: Scalar> OMatrix<T, Dyn, Dyn>
where where
DefaultAllocator: Allocator<Dyn, Dyn>, DefaultAllocator: Allocator<T, Dyn, Dyn>,
{ {
impl_constructors!(Dyn, Dyn; impl_constructors!(Dyn, Dyn;
; ;
@ -698,7 +697,7 @@ where
macro_rules! impl_constructors_from_data( macro_rules! impl_constructors_from_data(
($data: ident; $($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => { ($data: ident; $($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
impl<T: Scalar, $($DimIdent: $DimBound, )*> OMatrix<T $(, $Dims)*> impl<T: Scalar, $($DimIdent: $DimBound, )*> OMatrix<T $(, $Dims)*>
where DefaultAllocator: Allocator<$($Dims),*> { where DefaultAllocator: Allocator<T $(, $Dims)*> {
/// Creates a matrix with its elements filled with the components provided by a slice /// Creates a matrix with its elements filled with the components provided by a slice
/// in row-major order. /// in row-major order.
/// ///
@ -801,7 +800,6 @@ impl_constructors_from_data!(data; Dyn, C;
Dyn(data.len() / C::dim()), C::name(); Dyn(data.len() / C::dim()), C::name();
); );
#[cfg(any(feature = "std", feature = "alloc"))]
impl_constructors_from_data!(data; Dyn, Dyn; impl_constructors_from_data!(data; Dyn, Dyn;
; ;
Dyn(nrows), Dyn(ncols); Dyn(nrows), Dyn(ncols);
@ -814,8 +812,8 @@ impl_constructors_from_data!(data; Dyn, Dyn;
*/ */
impl<T, R: DimName, C: DimName> Zero for OMatrix<T, R, C> impl<T, R: DimName, C: DimName> Zero for OMatrix<T, R, C>
where where
T: Scalar + Zero + ClosedAddAssign, T: Scalar + Zero + ClosedAdd,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
#[inline] #[inline]
fn zero() -> Self { fn zero() -> Self {
@ -830,8 +828,8 @@ where
impl<T, D: DimName> One for OMatrix<T, D, D> impl<T, D: DimName> One for OMatrix<T, D, D>
where where
T: Scalar + Zero + One + ClosedMulAssign + ClosedAddAssign, T: Scalar + Zero + One + ClosedMul + ClosedAdd,
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
#[inline] #[inline]
fn one() -> Self { fn one() -> Self {
@ -842,7 +840,7 @@ where
impl<T, R: DimName, C: DimName> Bounded for OMatrix<T, R, C> impl<T, R: DimName, C: DimName> Bounded for OMatrix<T, R, C>
where where
T: Scalar + Bounded, T: Scalar + Bounded,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
#[inline] #[inline]
fn max_value() -> Self { fn max_value() -> Self {
@ -858,7 +856,7 @@ where
#[cfg(feature = "rand-no-std")] #[cfg(feature = "rand-no-std")]
impl<T: Scalar, R: Dim, C: Dim> Distribution<OMatrix<T, R, C>> for Standard impl<T: Scalar, R: Dim, C: Dim> Distribution<OMatrix<T, R, C>> for Standard
where where
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
Standard: Distribution<T>, Standard: Distribution<T>,
{ {
#[inline] #[inline]
@ -876,7 +874,7 @@ where
R: Dim, R: Dim,
C: Dim, C: Dim,
T: Scalar + Arbitrary + Send, T: Scalar + Arbitrary + Send,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
Owned<T, R, C>: Clone + Send, Owned<T, R, C>: Clone + Send,
{ {
#[inline] #[inline]
@ -894,7 +892,7 @@ where
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
impl<T: crate::RealField, D: DimName> Distribution<Unit<OVector<T, D>>> for Standard impl<T: crate::RealField, D: DimName> Distribution<Unit<OVector<T, D>>> for Standard
where where
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<T, D>,
rand_distr::StandardNormal: Distribution<T>, rand_distr::StandardNormal: Distribution<T>,
{ {
/// Generate a uniformly distributed random unit vector. /// Generate a uniformly distributed random unit vector.
@ -1113,7 +1111,7 @@ impl<T, R: DimName> OVector<T, R>
where where
R: ToTypenum, R: ToTypenum,
T: Scalar + Zero + One, T: Scalar + Zero + One,
DefaultAllocator: Allocator<R>, DefaultAllocator: Allocator<T, R>,
{ {
/// The column vector with `val` as its i-th component. /// The column vector with `val` as its i-th component.
#[inline] #[inline]

View File

@ -97,8 +97,6 @@ macro_rules! impl_constructors(
} }
/// Creates, without bound checking, a new matrix view from the given data array. /// Creates, without bound checking, a new matrix view from the given data array.
/// # Safety
/// `data[start..start+rstride * cstride]` must be within bounds.
#[inline] #[inline]
pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self { pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self {
Self::from_slice_generic_unchecked(data, start, $($gargs),*) Self::from_slice_generic_unchecked(data, start, $($gargs),*)
@ -115,11 +113,6 @@ macro_rules! impl_constructors(
} }
/// Creates, without bound checking, a new matrix view with the specified strides from the given data array. /// Creates, without bound checking, a new matrix view with the specified strides from the given data array.
///
/// # Safety
///
/// `start`, `rstride`, and `cstride`, with the given matrix size will not index
/// outside of `data`.
#[inline] #[inline]
pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self { pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dyn(rstride), Dyn(cstride)) Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dyn(rstride), Dyn(cstride))
@ -264,10 +257,6 @@ macro_rules! impl_constructors_mut(
} }
/// Creates, without bound checking, a new mutable matrix view from the given data array. /// Creates, without bound checking, a new mutable matrix view from the given data array.
///
/// # Safety
///
/// `data[start..start+(R * C)]` must be within bounds.
#[inline] #[inline]
pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self { pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self {
Self::from_slice_generic_unchecked(data, start, $($gargs),*) Self::from_slice_generic_unchecked(data, start, $($gargs),*)
@ -285,8 +274,6 @@ macro_rules! impl_constructors_mut(
} }
/// Creates, without bound checking, a new mutable matrix view with the specified strides from the given data array. /// Creates, without bound checking, a new mutable matrix view with the specified strides from the given data array.
/// # Safety
/// `data[start..start+rstride * cstride]` must be within bounds.
#[inline] #[inline]
pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self { pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
Self::from_slice_with_strides_generic_unchecked( Self::from_slice_with_strides_generic_unchecked(

View File

@ -8,11 +8,11 @@ use simba::simd::{PrimitiveSimdValue, SimdValue};
use crate::base::allocator::{Allocator, SameShapeAllocator}; use crate::base::allocator::{Allocator, SameShapeAllocator};
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
use crate::base::dimension::{
Const, Dim, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::dimension::{DimName, Dyn}; use crate::base::dimension::Dyn;
use crate::base::dimension::{
Const, Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
};
use crate::base::iter::{MatrixIter, MatrixIterMut}; use crate::base::iter::{MatrixIter, MatrixIterMut};
use crate::base::storage::{IsContiguous, RawStorage, RawStorageMut}; use crate::base::storage::{IsContiguous, RawStorage, RawStorageMut};
use crate::base::{ use crate::base::{
@ -35,7 +35,8 @@ where
C2: Dim, C2: Dim,
T1: Scalar, T1: Scalar,
T2: Scalar + SupersetOf<T1>, T2: Scalar + SupersetOf<T1>,
DefaultAllocator: Allocator<R2, C2> + Allocator<R1, C1> + SameShapeAllocator<R1, C1, R2, C2>, DefaultAllocator:
Allocator<T2, R2, C2> + Allocator<T1, R1, C1> + SameShapeAllocator<T1, R1, C1, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>, ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
{ {
#[inline] #[inline]
@ -97,18 +98,6 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> IntoIterator
} }
} }
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> IntoIterator
for Matrix<T, R, C, ViewStorage<'a, T, R, C, RStride, CStride>>
{
type Item = &'a T;
type IntoIter = MatrixIter<'a, T, R, C, ViewStorage<'a, T, R, C, RStride, CStride>>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
MatrixIter::new_owned(self.data)
}
}
impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> IntoIterator impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> IntoIterator
for &'a mut Matrix<T, R, C, S> for &'a mut Matrix<T, R, C, S>
{ {
@ -121,18 +110,6 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> IntoIterator
} }
} }
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> IntoIterator
for Matrix<T, R, C, ViewStorageMut<'a, T, R, C, RStride, CStride>>
{
type Item = &'a mut T;
type IntoIter = MatrixIterMut<'a, T, R, C, ViewStorageMut<'a, T, R, C, RStride, CStride>>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
MatrixIterMut::new_owned_mut(self.data)
}
}
impl<T: Scalar, const D: usize> From<[T; D]> for SVector<T, D> { impl<T: Scalar, const D: usize> From<[T; D]> for SVector<T, D> {
#[inline] #[inline]
fn from(arr: [T; D]) -> Self { fn from(arr: [T; D]) -> Self {
@ -496,7 +473,7 @@ where
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar> From<Vec<T>> for DVector<T> { impl<'a, T: Scalar> From<Vec<T>> for DVector<T> {
#[inline] #[inline]
fn from(vec: Vec<T>) -> Self { fn from(vec: Vec<T>) -> Self {
Self::from_vec(vec) Self::from_vec(vec)
@ -504,7 +481,7 @@ impl<T: Scalar> From<Vec<T>> for DVector<T> {
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar> From<Vec<T>> for RowDVector<T> { impl<'a, T: Scalar> From<Vec<T>> for RowDVector<T> {
#[inline] #[inline]
fn from(vec: Vec<T>) -> Self { fn from(vec: Vec<T>) -> Self {
Self::from_vec(vec) Self::from_vec(vec)
@ -560,7 +537,7 @@ impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R
where where
T: From<[<T as SimdValue>::Element; 2]>, T: From<[<T as SimdValue>::Element; 2]>,
T::Element: Scalar + SimdValue, T::Element: Scalar + SimdValue,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
#[inline] #[inline]
fn from(arr: [OMatrix<T::Element, R, C>; 2]) -> Self { fn from(arr: [OMatrix<T::Element, R, C>; 2]) -> Self {
@ -577,7 +554,7 @@ impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R
where where
T: From<[<T as SimdValue>::Element; 4]>, T: From<[<T as SimdValue>::Element; 4]>,
T::Element: Scalar + SimdValue, T::Element: Scalar + SimdValue,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
#[inline] #[inline]
fn from(arr: [OMatrix<T::Element, R, C>; 4]) -> Self { fn from(arr: [OMatrix<T::Element, R, C>; 4]) -> Self {
@ -600,7 +577,7 @@ impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R
where where
T: From<[<T as SimdValue>::Element; 8]>, T: From<[<T as SimdValue>::Element; 8]>,
T::Element: Scalar + SimdValue, T::Element: Scalar + SimdValue,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
#[inline] #[inline]
fn from(arr: [OMatrix<T::Element, R, C>; 8]) -> Self { fn from(arr: [OMatrix<T::Element, R, C>; 8]) -> Self {
@ -627,7 +604,7 @@ impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R
where where
T: From<[<T as SimdValue>::Element; 16]>, T: From<[<T as SimdValue>::Element; 16]>,
T::Element: Scalar + SimdValue, T::Element: Scalar + SimdValue,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
fn from(arr: [OMatrix<T::Element, R, C>; 16]) -> Self { fn from(arr: [OMatrix<T::Element, R, C>; 16]) -> Self {
let (nrows, ncols) = arr[0].shape_generic(); let (nrows, ncols) = arr[0].shape_generic();

View File

@ -12,16 +12,14 @@ use alloc::vec::Vec;
use super::Const; use super::Const;
use crate::base::allocator::{Allocator, Reallocator}; use crate::base::allocator::{Allocator, Reallocator};
use crate::base::array_storage::ArrayStorage; use crate::base::array_storage::ArrayStorage;
use crate::base::dimension::Dim;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
use crate::base::dimension::{DimName, Dyn}; use crate::base::dimension::Dyn;
use crate::base::storage::{RawStorage, RawStorageMut, Storage}; use crate::base::dimension::{Dim, DimName};
use crate::base::storage::{RawStorage, RawStorageMut};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::vec_storage::VecStorage; use crate::base::vec_storage::VecStorage;
use crate::base::Scalar; use crate::base::Scalar;
#[cfg(any(feature = "std", feature = "alloc"))] use std::mem::{ManuallyDrop, MaybeUninit};
use std::mem::ManuallyDrop;
use std::mem::MaybeUninit;
/* /*
* *
@ -34,21 +32,21 @@ use std::mem::MaybeUninit;
pub struct DefaultAllocator; pub struct DefaultAllocator;
// Static - Static // Static - Static
impl<const R: usize, const C: usize> Allocator<Const<R>, Const<C>> for DefaultAllocator { impl<T: Scalar, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>>
type Buffer<T: Scalar> = ArrayStorage<T, R, C>; for DefaultAllocator
type BufferUninit<T: Scalar> = ArrayStorage<MaybeUninit<T>, R, C>; {
type Buffer = ArrayStorage<T, R, C>;
type BufferUninit = ArrayStorage<MaybeUninit<T>, R, C>;
#[inline(always)] #[inline(always)]
fn allocate_uninit<T: Scalar>(_: Const<R>, _: Const<C>) -> ArrayStorage<MaybeUninit<T>, R, C> { fn allocate_uninit(_: Const<R>, _: Const<C>) -> ArrayStorage<MaybeUninit<T>, R, C> {
// SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid. // SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid.
let array: [[MaybeUninit<T>; R]; C] = unsafe { MaybeUninit::uninit().assume_init() }; let array: [[MaybeUninit<T>; R]; C] = unsafe { MaybeUninit::uninit().assume_init() };
ArrayStorage(array) ArrayStorage(array)
} }
#[inline(always)] #[inline(always)]
unsafe fn assume_init<T: Scalar>( unsafe fn assume_init(uninit: ArrayStorage<MaybeUninit<T>, R, C>) -> ArrayStorage<T, R, C> {
uninit: ArrayStorage<MaybeUninit<T>, R, C>,
) -> ArrayStorage<T, R, C> {
// Safety: // Safety:
// * The caller guarantees that all elements of the array are initialized // * The caller guarantees that all elements of the array are initialized
// * `MaybeUninit<T>` and T are guaranteed to have the same layout // * `MaybeUninit<T>` and T are guaranteed to have the same layout
@ -58,11 +56,11 @@ impl<const R: usize, const C: usize> Allocator<Const<R>, Const<C>> for DefaultAl
} }
#[inline] #[inline]
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>( fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: Const<R>, nrows: Const<R>,
ncols: Const<C>, ncols: Const<C>,
iter: I, iter: I,
) -> Self::Buffer<T> { ) -> Self::Buffer {
let mut res = Self::allocate_uninit(nrows, ncols); let mut res = Self::allocate_uninit(nrows, ncols);
let mut count = 0; let mut count = 0;
@ -80,19 +78,19 @@ impl<const R: usize, const C: usize> Allocator<Const<R>, Const<C>> for DefaultAl
// Safety: the assertion above made sure that the iterator // Safety: the assertion above made sure that the iterator
// yielded enough elements to initialize our matrix. // yielded enough elements to initialize our matrix.
unsafe { <Self as Allocator<Const<R>, Const<C>>>::assume_init(res) } unsafe { <Self as Allocator<T, Const<R>, Const<C>>>::assume_init(res) }
} }
} }
// Dyn - Static // Dyn - Static
// Dyn - Dyn // Dyn - Dyn
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<C: Dim> Allocator<Dyn, C> for DefaultAllocator { impl<T: Scalar, C: Dim> Allocator<T, Dyn, C> for DefaultAllocator {
type Buffer<T: Scalar> = VecStorage<T, Dyn, C>; type Buffer = VecStorage<T, Dyn, C>;
type BufferUninit<T: Scalar> = VecStorage<MaybeUninit<T>, Dyn, C>; type BufferUninit = VecStorage<MaybeUninit<T>, Dyn, C>;
#[inline] #[inline]
fn allocate_uninit<T: Scalar>(nrows: Dyn, ncols: C) -> VecStorage<MaybeUninit<T>, Dyn, C> { fn allocate_uninit(nrows: Dyn, ncols: C) -> VecStorage<MaybeUninit<T>, Dyn, C> {
let mut data = Vec::new(); let mut data = Vec::new();
let length = nrows.value() * ncols.value(); let length = nrows.value() * ncols.value();
data.reserve_exact(length); data.reserve_exact(length);
@ -101,9 +99,7 @@ impl<C: Dim> Allocator<Dyn, C> for DefaultAllocator {
} }
#[inline] #[inline]
unsafe fn assume_init<T: Scalar>( unsafe fn assume_init(uninit: VecStorage<MaybeUninit<T>, Dyn, C>) -> VecStorage<T, Dyn, C> {
uninit: VecStorage<MaybeUninit<T>, Dyn, C>,
) -> VecStorage<T, Dyn, C> {
// Avoids a double-drop. // Avoids a double-drop.
let (nrows, ncols) = uninit.shape(); let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into(); let vec: Vec<_> = uninit.into();
@ -118,11 +114,11 @@ impl<C: Dim> Allocator<Dyn, C> for DefaultAllocator {
} }
#[inline] #[inline]
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>( fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: Dyn, nrows: Dyn,
ncols: C, ncols: C,
iter: I, iter: I,
) -> Self::Buffer<T> { ) -> Self::Buffer {
let it = iter.into_iter(); let it = iter.into_iter();
let res: Vec<T> = it.collect(); let res: Vec<T> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(), assert!(res.len() == nrows.value() * ncols.value(),
@ -134,12 +130,12 @@ impl<C: Dim> Allocator<Dyn, C> for DefaultAllocator {
// Static - Dyn // Static - Dyn
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<R: DimName> Allocator<R, Dyn> for DefaultAllocator { impl<T: Scalar, R: DimName> Allocator<T, R, Dyn> for DefaultAllocator {
type Buffer<T: Scalar> = VecStorage<T, R, Dyn>; type Buffer = VecStorage<T, R, Dyn>;
type BufferUninit<T: Scalar> = VecStorage<MaybeUninit<T>, R, Dyn>; type BufferUninit = VecStorage<MaybeUninit<T>, R, Dyn>;
#[inline] #[inline]
fn allocate_uninit<T: Scalar>(nrows: R, ncols: Dyn) -> VecStorage<MaybeUninit<T>, R, Dyn> { fn allocate_uninit(nrows: R, ncols: Dyn) -> VecStorage<MaybeUninit<T>, R, Dyn> {
let mut data = Vec::new(); let mut data = Vec::new();
let length = nrows.value() * ncols.value(); let length = nrows.value() * ncols.value();
data.reserve_exact(length); data.reserve_exact(length);
@ -149,9 +145,7 @@ impl<R: DimName> Allocator<R, Dyn> for DefaultAllocator {
} }
#[inline] #[inline]
unsafe fn assume_init<T: Scalar>( unsafe fn assume_init(uninit: VecStorage<MaybeUninit<T>, R, Dyn>) -> VecStorage<T, R, Dyn> {
uninit: VecStorage<MaybeUninit<T>, R, Dyn>,
) -> VecStorage<T, R, Dyn> {
// Avoids a double-drop. // Avoids a double-drop.
let (nrows, ncols) = uninit.shape(); let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into(); let vec: Vec<_> = uninit.into();
@ -166,11 +160,11 @@ impl<R: DimName> Allocator<R, Dyn> for DefaultAllocator {
} }
#[inline] #[inline]
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>( fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: R, nrows: R,
ncols: Dyn, ncols: Dyn,
iter: I, iter: I,
) -> Self::Buffer<T> { ) -> Self::Buffer {
let it = iter.into_iter(); let it = iter.into_iter();
let res: Vec<T> = it.collect(); let res: Vec<T> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(), assert!(res.len() == nrows.value() * ncols.value(),
@ -191,15 +185,15 @@ impl<T: Scalar, RFrom, CFrom, const RTO: usize, const CTO: usize>
where where
RFrom: Dim, RFrom: Dim,
CFrom: Dim, CFrom: Dim,
Self: Allocator<RFrom, CFrom>, Self: Allocator<T, RFrom, CFrom>,
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: Const<RTO>, rto: Const<RTO>,
cto: Const<CTO>, cto: Const<CTO>,
buf: <Self as Allocator<RFrom, CFrom>>::Buffer<T>, buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer,
) -> ArrayStorage<MaybeUninit<T>, RTO, CTO> { ) -> ArrayStorage<MaybeUninit<T>, RTO, CTO> {
let mut res = <Self as Allocator<Const<RTO>, Const<CTO>>>::allocate_uninit(rto, cto); let mut res = <Self as Allocator<T, Const<RTO>, Const<CTO>>>::allocate_uninit(rto, cto);
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -210,8 +204,8 @@ where
// Safety: // Safety:
// - We dont care about dropping elements because the caller is responsible for dropping things. // - We dont care about dropping elements because the caller is responsible for dropping things.
// - We forget `buf` so that we dont drop the other elements, but ensure the buffer itself is cleaned up. // - We forget `buf` so that we dont drop the other elements.
buf.forget_elements(); std::mem::forget(buf);
res res
} }
@ -230,7 +224,7 @@ where
cto: CTo, cto: CTo,
buf: ArrayStorage<T, RFROM, CFROM>, buf: ArrayStorage<T, RFROM, CFROM>,
) -> VecStorage<MaybeUninit<T>, Dyn, CTo> { ) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
let mut res = <Self as Allocator<Dyn, CTo>>::allocate_uninit(rto, cto); let mut res = <Self as Allocator<T, Dyn, CTo>>::allocate_uninit(rto, cto);
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -241,8 +235,8 @@ where
// Safety: // Safety:
// - We dont care about dropping elements because the caller is responsible for dropping things. // - We dont care about dropping elements because the caller is responsible for dropping things.
// - We forget `buf` so that we dont drop the other elements, but ensure the buffer itself is cleaned up. // - We forget `buf` so that we dont drop the other elements.
buf.forget_elements(); std::mem::forget(buf);
res res
} }
@ -261,7 +255,7 @@ where
cto: Dyn, cto: Dyn,
buf: ArrayStorage<T, RFROM, CFROM>, buf: ArrayStorage<T, RFROM, CFROM>,
) -> VecStorage<MaybeUninit<T>, RTo, Dyn> { ) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
let mut res = <Self as Allocator<RTo, Dyn>>::allocate_uninit(rto, cto); let mut res = <Self as Allocator<T, RTo, Dyn>>::allocate_uninit(rto, cto);
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -272,8 +266,8 @@ where
// Safety: // Safety:
// - We dont care about dropping elements because the caller is responsible for dropping things. // - We dont care about dropping elements because the caller is responsible for dropping things.
// - We forget `buf` so that we dont drop the other elements, but ensure the buffer itself is cleaned up. // - We forget `buf` so that we dont drop the other elements.
buf.forget_elements(); std::mem::forget(buf);
res res
} }

View File

@ -23,6 +23,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
feature = "rkyv-serialize", feature = "rkyv-serialize",
archive_attr(derive(bytecheck::CheckBytes)) archive_attr(derive(bytecheck::CheckBytes))
)] )]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
pub struct Dyn(pub usize); pub struct Dyn(pub usize);
#[deprecated(note = "use Dyn instead.")] #[deprecated(note = "use Dyn instead.")]
@ -67,10 +68,6 @@ impl IsNotStaticOne for Dyn {}
/// Trait implemented by any type that can be used as a dimension. This includes type-level /// Trait implemented by any type that can be used as a dimension. This includes type-level
/// integers and `Dyn` (for dimensions not known at compile-time). /// integers and `Dyn` (for dimensions not known at compile-time).
///
/// # Safety
///
/// Hoists integers to the type level, including binary operations.
pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync { pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {
#[inline(always)] #[inline(always)]
fn is<D: Dim>() -> bool { fn is<D: Dim>() -> bool {
@ -219,6 +216,7 @@ dim_ops!(
archive(as = "Self") archive(as = "Self")
)] )]
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
pub struct Const<const R: usize>; pub struct Const<const R: usize>;
/// Trait implemented exclusively by type-level integers. /// Trait implemented exclusively by type-level integers.

View File

@ -21,7 +21,7 @@ impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
#[must_use] #[must_use]
pub fn upper_triangle(&self) -> OMatrix<T, R, C> pub fn upper_triangle(&self) -> OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.fill_lower_triangle(T::zero(), 1); res.fill_lower_triangle(T::zero(), 1);
@ -34,7 +34,7 @@ impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
#[must_use] #[must_use]
pub fn lower_triangle(&self) -> OMatrix<T, R, C> pub fn lower_triangle(&self) -> OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.fill_upper_triangle(T::zero(), 1); res.fill_upper_triangle(T::zero(), 1);
@ -52,7 +52,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
where where
I: IntoIterator<Item = &'a usize>, I: IntoIterator<Item = &'a usize>,
I::IntoIter: ExactSizeIterator + Clone, I::IntoIter: ExactSizeIterator + Clone,
DefaultAllocator: Allocator<Dyn, C>, DefaultAllocator: Allocator<T, Dyn, C>,
{ {
let irows = irows.into_iter(); let irows = irows.into_iter();
let ncols = self.shape_generic().1; let ncols = self.shape_generic().1;
@ -89,7 +89,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
where where
I: IntoIterator<Item = &'a usize>, I: IntoIterator<Item = &'a usize>,
I::IntoIter: ExactSizeIterator, I::IntoIter: ExactSizeIterator,
DefaultAllocator: Allocator<R, Dyn>, DefaultAllocator: Allocator<T, R, Dyn>,
{ {
let icols = icols.into_iter(); let icols = icols.into_iter();
let nrows = self.shape_generic().0; let nrows = self.shape_generic().0;
@ -598,7 +598,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
if nremove.value() != 0 { if nremove.value() != 0 {
unsafe { unsafe {
compress_rows( compress_rows(
m.as_mut_slice(), &mut m.as_mut_slice(),
nrows.value(), nrows.value(),
ncols.value(), ncols.value(),
i, i,
@ -796,7 +796,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
if ninsert.value() != 0 { if ninsert.value() != 0 {
extend_rows( extend_rows(
res.as_mut_slice(), &mut res.as_mut_slice(),
nrows.value(), nrows.value(),
ncols.value(), ncols.value(),
i, i,
@ -909,7 +909,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
unsafe { unsafe {
if new_nrows.value() < nrows { if new_nrows.value() < nrows {
compress_rows( compress_rows(
data.as_mut_slice(), &mut data.as_mut_slice(),
nrows, nrows,
ncols, ncols,
new_nrows.value(), new_nrows.value(),
@ -923,7 +923,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
new_nrows, new_ncols, data.data, new_nrows, new_ncols, data.data,
)); ));
extend_rows( extend_rows(
res.as_mut_slice(), &mut res.as_mut_slice(),
nrows, nrows,
new_ncols.value(), new_ncols.value(),
nrows, nrows,
@ -1037,7 +1037,7 @@ impl<T: Scalar> OMatrix<T, Dyn, Dyn> {
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, C: Dim> OMatrix<T, Dyn, C> impl<T: Scalar, C: Dim> OMatrix<T, Dyn, C>
where where
DefaultAllocator: Allocator<Dyn, C>, DefaultAllocator: Allocator<T, Dyn, C>,
{ {
/// Changes the number of rows of this matrix in-place. /// Changes the number of rows of this matrix in-place.
/// ///
@ -1058,7 +1058,7 @@ where
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, R: Dim> OMatrix<T, R, Dyn> impl<T: Scalar, R: Dim> OMatrix<T, R, Dyn>
where where
DefaultAllocator: Allocator<R, Dyn>, DefaultAllocator: Allocator<T, R, Dyn>,
{ {
/// Changes the number of column of this matrix in-place. /// Changes the number of column of this matrix in-place.
/// ///

View File

@ -519,10 +519,6 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
/// Produces a view of the data at the given index, without doing /// Produces a view of the data at the given index, without doing
/// any bounds checking. /// any bounds checking.
///
/// # Safety
///
/// `index` must within bounds of the array.
#[inline] #[inline]
#[must_use] #[must_use]
pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output
@ -534,9 +530,6 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
/// Returns a mutable view of the data at the given index, without doing /// Returns a mutable view of the data at the given index, without doing
/// any bounds checking. /// any bounds checking.
/// # Safety
///
/// `index` must within bounds of the array.
#[inline] #[inline]
#[must_use] #[must_use]
pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut

View File

@ -2,14 +2,11 @@ use crate::storage::Storage;
use crate::{ use crate::{
Allocator, DefaultAllocator, Dim, OVector, One, RealField, Scalar, Unit, Vector, Zero, Allocator, DefaultAllocator, Dim, OVector, One, RealField, Scalar, Unit, Vector, Zero,
}; };
use simba::scalar::{ClosedAddAssign, ClosedMulAssign, ClosedSubAssign}; use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub};
/// # Interpolation /// # Interpolation
impl< impl<T: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Storage<T, D>>
T: Scalar + Zero + One + ClosedAddAssign + ClosedSubAssign + ClosedMulAssign, Vector<T, D, S>
D: Dim,
S: Storage<T, D>,
> Vector<T, D, S>
{ {
/// Returns `self * (1.0 - t) + rhs * t`, i.e., the linear blend of the vectors x and y using the scalar value a. /// Returns `self * (1.0 - t) + rhs * t`, i.e., the linear blend of the vectors x and y using the scalar value a.
/// ///
@ -26,7 +23,7 @@ impl<
#[must_use] #[must_use]
pub fn lerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D> pub fn lerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D>
where where
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<T, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.axpy(t.clone(), rhs, T::one() - t); res.axpy(t.clone(), rhs, T::one() - t);
@ -53,7 +50,7 @@ impl<
pub fn slerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D> pub fn slerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D>
where where
T: RealField, T: RealField,
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<T, D>,
{ {
let me = Unit::new_normalize(self.clone_owned()); let me = Unit::new_normalize(self.clone_owned());
let rhs = Unit::new_normalize(rhs.clone_owned()); let rhs = Unit::new_normalize(rhs.clone_owned());
@ -84,7 +81,7 @@ impl<T: RealField, D: Dim, S: Storage<T, D>> Unit<Vector<T, D, S>> {
t: T, t: T,
) -> Unit<OVector<T, D>> ) -> Unit<OVector<T, D>>
where where
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<T, D>,
{ {
// TODO: the result is wrong when self and rhs are collinear with opposite direction. // TODO: the result is wrong when self and rhs are collinear with opposite direction.
self.try_slerp(rhs, t, T::default_epsilon()) self.try_slerp(rhs, t, T::default_epsilon())
@ -103,7 +100,7 @@ impl<T: RealField, D: Dim, S: Storage<T, D>> Unit<Vector<T, D, S>> {
epsilon: T, epsilon: T,
) -> Option<Unit<OVector<T, D>>> ) -> Option<Unit<OVector<T, D>>>
where where
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<T, D>,
{ {
let c_hang = self.dot(rhs); let c_hang = self.dot(rhs);

View File

@ -12,29 +12,26 @@ use std::mem;
use crate::base::dimension::{Dim, U1}; use crate::base::dimension::{Dim, U1};
use crate::base::storage::{RawStorage, RawStorageMut}; use crate::base::storage::{RawStorage, RawStorageMut};
use crate::base::{Matrix, MatrixView, MatrixViewMut, Scalar, ViewStorage, ViewStorageMut}; use crate::base::{Matrix, MatrixView, MatrixViewMut, Scalar};
#[derive(Clone, Debug)]
struct RawIter<Ptr, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> {
ptr: Ptr,
inner_ptr: Ptr,
inner_end: Ptr,
size: usize,
strides: (RStride, CStride),
_phantoms: PhantomData<(fn() -> T, R, C)>,
}
macro_rules! iterator { macro_rules! iterator {
(struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty, $($derives:ident),* $(,)?) => { (struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty, $($derives:ident),* $(,)?) => {
/// An iterator through a dense matrix with arbitrary strides matrix.
#[derive($($derives),*)]
pub struct $Name<'a, T, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> {
ptr: $Ptr,
inner_ptr: $Ptr,
inner_end: $Ptr,
size: usize, // We can't use an end pointer here because a stride might be zero.
strides: (S::RStride, S::CStride),
_phantoms: PhantomData<($Ref, R, C, S)>,
}
// TODO: we need to specialize for the case where the matrix storage is owned (in which // TODO: we need to specialize for the case where the matrix storage is owned (in which
// case the iterator is trivial because it does not have any stride). // case the iterator is trivial because it does not have any stride).
impl<T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> impl<'a, T, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> $Name<'a, T, R, C, S> {
RawIter<$Ptr, T, R, C, RStride, CStride>
{
/// Creates a new iterator for the given matrix storage. /// Creates a new iterator for the given matrix storage.
fn new<'a, S: $Storage<T, R, C, RStride = RStride, CStride = CStride>>( pub fn new(storage: $SRef) -> $Name<'a, T, R, C, S> {
storage: $SRef,
) -> Self {
let shape = storage.shape(); let shape = storage.shape();
let strides = storage.strides(); let strides = storage.strides();
let inner_offset = shape.0.value() * strides.0.value(); let inner_offset = shape.0.value() * strides.0.value();
@ -58,7 +55,7 @@ macro_rules! iterator {
unsafe { ptr.add(inner_offset) } unsafe { ptr.add(inner_offset) }
}; };
RawIter { $Name {
ptr, ptr,
inner_ptr: ptr, inner_ptr: ptr,
inner_end, inner_end,
@ -69,13 +66,11 @@ macro_rules! iterator {
} }
} }
impl<T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Iterator impl<'a, T, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> Iterator for $Name<'a, T, R, C, S> {
for RawIter<$Ptr, T, R, C, RStride, CStride> type Item = $Ref;
{
type Item = $Ptr;
#[inline] #[inline]
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<$Ref> {
unsafe { unsafe {
if self.size == 0 { if self.size == 0 {
None None
@ -107,7 +102,10 @@ macro_rules! iterator {
self.ptr = self.ptr.add(stride); self.ptr = self.ptr.add(stride);
} }
Some(old) // We want either `& *last` or `&mut *last` here, depending
// on the mutability of `$Ref`.
#[allow(clippy::transmute_ptr_to_ref)]
Some(mem::transmute(old))
} }
} }
} }
@ -123,11 +121,11 @@ macro_rules! iterator {
} }
} }
impl<T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> DoubleEndedIterator impl<'a, T, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> DoubleEndedIterator
for RawIter<$Ptr, T, R, C, RStride, CStride> for $Name<'a, T, R, C, S>
{ {
#[inline] #[inline]
fn next_back(&mut self) -> Option<Self::Item> { fn next_back(&mut self) -> Option<$Ref> {
unsafe { unsafe {
if self.size == 0 { if self.size == 0 {
None None
@ -154,85 +152,21 @@ macro_rules! iterator {
.ptr .ptr
.add((outer_remaining * outer_stride + inner_remaining * inner_stride)); .add((outer_remaining * outer_stride + inner_remaining * inner_stride));
Some(last) // We want either `& *last` or `&mut *last` here, depending
// on the mutability of `$Ref`.
#[allow(clippy::transmute_ptr_to_ref)]
Some(mem::transmute(last))
} }
} }
} }
} }
impl<T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> ExactSizeIterator
for RawIter<$Ptr, T, R, C, RStride, CStride>
{
#[inline]
fn len(&self) -> usize {
self.size
}
}
impl<T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> FusedIterator
for RawIter<$Ptr, T, R, C, RStride, CStride>
{
}
/// An iterator through a dense matrix with arbitrary strides matrix.
#[derive($($derives),*)]
pub struct $Name<'a, T, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> {
inner: RawIter<$Ptr, T, R, C, S::RStride, S::CStride>,
_marker: PhantomData<$Ref>,
}
impl<'a, T, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> $Name<'a, T, R, C, S> {
/// Creates a new iterator for the given matrix storage.
pub fn new(storage: $SRef) -> Self {
Self {
inner: RawIter::<$Ptr, T, R, C, S::RStride, S::CStride>::new(storage),
_marker: PhantomData,
}
}
}
impl<'a, T, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> Iterator for $Name<'a, T, R, C, S> {
type Item = $Ref;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
// We want either `& *last` or `&mut *last` here, depending
// on the mutability of `$Ref`.
#[allow(clippy::transmute_ptr_to_ref)]
self.inner.next().map(|ptr| unsafe { mem::transmute(ptr) })
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
#[inline(always)]
fn count(self) -> usize {
self.inner.count()
}
}
impl<'a, T, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> DoubleEndedIterator
for $Name<'a, T, R, C, S>
{
#[inline(always)]
fn next_back(&mut self) -> Option<Self::Item> {
// We want either `& *last` or `&mut *last` here, depending
// on the mutability of `$Ref`.
#[allow(clippy::transmute_ptr_to_ref)]
self.inner
.next_back()
.map(|ptr| unsafe { mem::transmute(ptr) })
}
}
impl<'a, T, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> ExactSizeIterator impl<'a, T, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> ExactSizeIterator
for $Name<'a, T, R, C, S> for $Name<'a, T, R, C, S>
{ {
#[inline(always)] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
self.inner.len() self.size
} }
} }
@ -246,30 +180,6 @@ macro_rules! iterator {
iterator!(struct MatrixIter for RawStorage.ptr -> *const T, &'a T, &'a S, Clone, Debug); iterator!(struct MatrixIter for RawStorage.ptr -> *const T, &'a T, &'a S, Clone, Debug);
iterator!(struct MatrixIterMut for RawStorageMut.ptr_mut -> *mut T, &'a mut T, &'a mut S, Debug); iterator!(struct MatrixIterMut for RawStorageMut.ptr_mut -> *mut T, &'a mut T, &'a mut S, Debug);
impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
MatrixIter<'a, T, R, C, ViewStorage<'a, T, R, C, RStride, CStride>>
{
/// Creates a new iterator for the given matrix storage view.
pub fn new_owned(storage: ViewStorage<'a, T, R, C, RStride, CStride>) -> Self {
Self {
inner: RawIter::<*const T, T, R, C, RStride, CStride>::new(&storage),
_marker: PhantomData,
}
}
}
impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
MatrixIterMut<'a, T, R, C, ViewStorageMut<'a, T, R, C, RStride, CStride>>
{
/// Creates a new iterator for the given matrix storage view.
pub fn new_owned_mut(mut storage: ViewStorageMut<'a, T, R, C, RStride, CStride>) -> Self {
Self {
inner: RawIter::<*mut T, T, R, C, RStride, CStride>::new(&mut storage),
_marker: PhantomData,
}
}
}
/* /*
* *
* Row iterators. * Row iterators.
@ -403,9 +313,8 @@ impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorage<T, R, C>> ColumnIter<'a, T, R, C,
} }
} }
#[cfg(feature = "rayon")]
pub(crate) fn split_at(self, index: usize) -> (Self, Self) { pub(crate) fn split_at(self, index: usize) -> (Self, Self) {
// SAFETY: this makes sure the generated ranges are valid. // SAFETY: this makes sur the generated ranges are valid.
let split_pos = (self.range.start + index).min(self.range.end); let split_pos = (self.range.start + index).min(self.range.end);
let left_iter = ColumnIter { let left_iter = ColumnIter {
@ -492,9 +401,8 @@ impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorageMut<T, R, C>> ColumnIterMut<'a, T,
} }
} }
#[cfg(feature = "rayon")]
pub(crate) fn split_at(self, index: usize) -> (Self, Self) { pub(crate) fn split_at(self, index: usize) -> (Self, Self) {
// SAFETY: this makes sure the generated ranges are valid. // SAFETY: this makes sur the generated ranges are valid.
let split_pos = (self.range.start + index).min(self.range.end); let split_pos = (self.range.start + index).min(self.range.end);
let left_iter = ColumnIterMut { let left_iter = ColumnIterMut {

View File

@ -18,7 +18,7 @@ use rkyv::bytecheck;
#[cfg(feature = "rkyv-serialize-no-std")] #[cfg(feature = "rkyv-serialize-no-std")]
use rkyv::{with::With, Archive, Archived}; use rkyv::{with::With, Archive, Archived};
use simba::scalar::{ClosedAddAssign, ClosedMulAssign, ClosedSubAssign, Field, SupersetOf}; use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, Field, SupersetOf};
use simba::simd::SimdPartialOrd; use simba::simd::SimdPartialOrd;
use crate::base::allocator::{Allocator, SameShapeAllocator, SameShapeC, SameShapeR}; use crate::base::allocator::{Allocator, SameShapeAllocator, SameShapeC, SameShapeR};
@ -171,6 +171,7 @@ pub type MatrixCross<T, R1, C1, R2, C2> =
) )
)] )]
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
pub struct Matrix<T, R, C, S> { pub struct Matrix<T, R, C, S> {
/// The data storage that contains all the matrix components. Disappointed? /// The data storage that contains all the matrix components. Disappointed?
/// ///
@ -312,10 +313,6 @@ where
impl<T, R, C, S> Matrix<T, R, C, S> { impl<T, R, C, S> Matrix<T, R, C, S> {
/// Creates a new matrix with the given data without statically checking that the matrix /// Creates a new matrix with the given data without statically checking that the matrix
/// dimension matches the storage dimension. /// dimension matches the storage dimension.
///
/// # Safety
///
/// The storage dimension must match the given dimensions.
#[inline(always)] #[inline(always)]
pub const unsafe fn from_data_statically_unchecked(data: S) -> Matrix<T, R, C, S> { pub const unsafe fn from_data_statically_unchecked(data: S) -> Matrix<T, R, C, S> {
Matrix { Matrix {
@ -383,9 +380,9 @@ impl<T> RowDVector<T> {
} }
} }
impl<T: Scalar, R: Dim, C: Dim> UninitMatrix<T, R, C> impl<T, R: Dim, C: Dim> UninitMatrix<T, R, C>
where where
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
/// Assumes a matrix's entries to be initialized. This operation should be near zero-cost. /// Assumes a matrix's entries to be initialized. This operation should be near zero-cost.
/// ///
@ -394,7 +391,7 @@ where
/// or Undefined Behavior will immediately occur. /// or Undefined Behavior will immediately occur.
#[inline(always)] #[inline(always)]
pub unsafe fn assume_init(self) -> OMatrix<T, R, C> { pub unsafe fn assume_init(self) -> OMatrix<T, R, C> {
OMatrix::from_data(<DefaultAllocator as Allocator<R, C>>::assume_init( OMatrix::from_data(<DefaultAllocator as Allocator<T, R, C>>::assume_init(
self.data, self.data,
)) ))
} }
@ -533,7 +530,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
max_relative: T::Epsilon, max_relative: T::Epsilon,
) -> bool ) -> bool
where where
T: RelativeEq + Scalar, T: RelativeEq,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
SB: Storage<T, R2, C2>, SB: Storage<T, R2, C2>,
@ -568,7 +565,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
where where
T: Scalar, T: Scalar,
S: Storage<T, R, C>, S: Storage<T, R, C>,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
Matrix::from_data(self.data.into_owned()) Matrix::from_data(self.data.into_owned())
} }
@ -584,7 +581,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
S: Storage<T, R, C>, S: Storage<T, R, C>,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
DefaultAllocator: SameShapeAllocator<R, C, R2, C2>, DefaultAllocator: SameShapeAllocator<T, R, C, R2, C2>,
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>, ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
{ {
if TypeId::of::<SameShapeStorage<T, R, C, R2, C2>>() == TypeId::of::<Owned<T, R, C>>() { if TypeId::of::<SameShapeStorage<T, R, C, R2, C2>>() == TypeId::of::<Owned<T, R, C>>() {
@ -609,7 +606,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
where where
T: Scalar, T: Scalar,
S: Storage<T, R, C>, S: Storage<T, R, C>,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
Matrix::from_data(self.data.clone_owned()) Matrix::from_data(self.data.clone_owned())
} }
@ -624,7 +621,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
S: Storage<T, R, C>, S: Storage<T, R, C>,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
DefaultAllocator: SameShapeAllocator<R, C, R2, C2>, DefaultAllocator: SameShapeAllocator<T, R, C, R2, C2>,
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>, ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
{ {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
@ -700,7 +697,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
pub fn transpose(&self) -> OMatrix<T, C, R> pub fn transpose(&self) -> OMatrix<T, C, R>
where where
T: Scalar, T: Scalar,
DefaultAllocator: Allocator<C, R>, DefaultAllocator: Allocator<T, C, R>,
{ {
let (nrows, ncols) = self.shape_generic(); let (nrows, ncols) = self.shape_generic();
@ -719,7 +716,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
pub fn map<T2: Scalar, F: FnMut(T) -> T2>(&self, mut f: F) -> OMatrix<T2, R, C> pub fn map<T2: Scalar, F: FnMut(T) -> T2>(&self, mut f: F) -> OMatrix<T2, R, C>
where where
T: Scalar, T: Scalar,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T2, R, C>,
{ {
let (nrows, ncols) = self.shape_generic(); let (nrows, ncols) = self.shape_generic();
let mut res = Matrix::uninit(nrows, ncols); let mut res = Matrix::uninit(nrows, ncols);
@ -751,7 +748,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
where where
T: Scalar, T: Scalar,
OMatrix<T2, R, C>: SupersetOf<Self>, OMatrix<T2, R, C>: SupersetOf<Self>,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T2, R, C>,
{ {
crate::convert(self) crate::convert(self)
} }
@ -769,7 +766,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
where where
T: Scalar, T: Scalar,
Self: SupersetOf<OMatrix<T2, R, C>>, Self: SupersetOf<OMatrix<T2, R, C>>,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T2, R, C>,
{ {
crate::try_convert(self) crate::try_convert(self)
} }
@ -806,7 +803,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
) -> OMatrix<T2, R, C> ) -> OMatrix<T2, R, C>
where where
T: Scalar, T: Scalar,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T2, R, C>,
{ {
let (nrows, ncols) = self.shape_generic(); let (nrows, ncols) = self.shape_generic();
let mut res = Matrix::uninit(nrows, ncols); let mut res = Matrix::uninit(nrows, ncols);
@ -836,7 +833,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
N3: Scalar, N3: Scalar,
S2: RawStorage<T2, R, C>, S2: RawStorage<T2, R, C>,
F: FnMut(T, T2) -> N3, F: FnMut(T, T2) -> N3,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<N3, R, C>,
{ {
let (nrows, ncols) = self.shape_generic(); let (nrows, ncols) = self.shape_generic();
let mut res = Matrix::uninit(nrows, ncols); let mut res = Matrix::uninit(nrows, ncols);
@ -880,7 +877,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
S2: RawStorage<T2, R, C>, S2: RawStorage<T2, R, C>,
S3: RawStorage<N3, R, C>, S3: RawStorage<N3, R, C>,
F: FnMut(T, T2, N3) -> N4, F: FnMut(T, T2, N3) -> N4,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<N4, R, C>,
{ {
let (nrows, ncols) = self.shape_generic(); let (nrows, ncols) = self.shape_generic();
let mut res = Matrix::uninit(nrows, ncols); let mut res = Matrix::uninit(nrows, ncols);
@ -1197,10 +1194,6 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
} }
/// Swaps two entries without bound-checking. /// Swaps two entries without bound-checking.
///
/// # Safety
///
/// Both `(r, c)` must have `r < nrows(), c < ncols()`.
#[inline] #[inline]
pub unsafe fn swap_unchecked(&mut self, row_cols1: (usize, usize), row_cols2: (usize, usize)) { pub unsafe fn swap_unchecked(&mut self, row_cols1: (usize, usize), row_cols2: (usize, usize)) {
debug_assert!(row_cols1.0 < self.nrows() && row_cols1.1 < self.ncols()); debug_assert!(row_cols1.0 < self.nrows() && row_cols1.1 < self.ncols());
@ -1307,8 +1300,6 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
impl<T, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> { impl<T, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
/// Gets a reference to the i-th element of this column vector without bound checking. /// Gets a reference to the i-th element of this column vector without bound checking.
/// # Safety
/// `i` must be less than `D`.
#[inline] #[inline]
#[must_use] #[must_use]
pub unsafe fn vget_unchecked(&self, i: usize) -> &T { pub unsafe fn vget_unchecked(&self, i: usize) -> &T {
@ -1320,8 +1311,6 @@ impl<T, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
impl<T, D: Dim, S: RawStorageMut<T, D>> Vector<T, D, S> { impl<T, D: Dim, S: RawStorageMut<T, D>> Vector<T, D, S> {
/// Gets a mutable reference to the i-th element of this column vector without bound checking. /// Gets a mutable reference to the i-th element of this column vector without bound checking.
/// # Safety
/// `i` must be less than `D`.
#[inline] #[inline]
#[must_use] #[must_use]
pub unsafe fn vget_unchecked_mut(&mut self, i: usize) -> &mut T { pub unsafe fn vget_unchecked_mut(&mut self, i: usize) -> &mut T {
@ -1420,7 +1409,7 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C
#[must_use = "Did you mean to use adjoint_mut()?"] #[must_use = "Did you mean to use adjoint_mut()?"]
pub fn adjoint(&self) -> OMatrix<T, C, R> pub fn adjoint(&self) -> OMatrix<T, C, R>
where where
DefaultAllocator: Allocator<C, R>, DefaultAllocator: Allocator<T, C, R>,
{ {
let (nrows, ncols) = self.shape_generic(); let (nrows, ncols) = self.shape_generic();
@ -1449,7 +1438,7 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C
#[inline] #[inline]
pub fn conjugate_transpose(&self) -> OMatrix<T, C, R> pub fn conjugate_transpose(&self) -> OMatrix<T, C, R>
where where
DefaultAllocator: Allocator<C, R>, DefaultAllocator: Allocator<T, C, R>,
{ {
self.adjoint() self.adjoint()
} }
@ -1459,7 +1448,7 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C
#[must_use = "Did you mean to use conjugate_mut()?"] #[must_use = "Did you mean to use conjugate_mut()?"]
pub fn conjugate(&self) -> OMatrix<T, R, C> pub fn conjugate(&self) -> OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
self.map(|e| e.simd_conjugate()) self.map(|e| e.simd_conjugate())
} }
@ -1469,7 +1458,7 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C
#[must_use = "Did you mean to use unscale_mut()?"] #[must_use = "Did you mean to use unscale_mut()?"]
pub fn unscale(&self, real: T::SimdRealField) -> OMatrix<T, R, C> pub fn unscale(&self, real: T::SimdRealField) -> OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
self.map(|e| e.simd_unscale(real.clone())) self.map(|e| e.simd_unscale(real.clone()))
} }
@ -1479,7 +1468,7 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C
#[must_use = "Did you mean to use scale_mut()?"] #[must_use = "Did you mean to use scale_mut()?"]
pub fn scale(&self, real: T::SimdRealField) -> OMatrix<T, R, C> pub fn scale(&self, real: T::SimdRealField) -> OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
self.map(|e| e.simd_scale(real.clone())) self.map(|e| e.simd_scale(real.clone()))
} }
@ -1547,7 +1536,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D, D>> SquareMatrix<T, D, S> {
#[must_use] #[must_use]
pub fn diagonal(&self) -> OVector<T, D> pub fn diagonal(&self) -> OVector<T, D>
where where
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<T, D>,
{ {
self.map_diagonal(|e| e) self.map_diagonal(|e| e)
} }
@ -1559,7 +1548,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D, D>> SquareMatrix<T, D, S> {
#[must_use] #[must_use]
pub fn map_diagonal<T2: Scalar>(&self, mut f: impl FnMut(T) -> T2) -> OVector<T2, D> pub fn map_diagonal<T2: Scalar>(&self, mut f: impl FnMut(T) -> T2) -> OVector<T2, D>
where where
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<T2, D>,
{ {
assert!( assert!(
self.is_square(), self.is_square(),
@ -1586,7 +1575,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D, D>> SquareMatrix<T, D, S> {
#[must_use] #[must_use]
pub fn trace(&self) -> T pub fn trace(&self) -> T
where where
T: Scalar + Zero + ClosedAddAssign, T: Scalar + Zero + ClosedAdd,
{ {
assert!( assert!(
self.is_square(), self.is_square(),
@ -1610,7 +1599,7 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
#[must_use] #[must_use]
pub fn symmetric_part(&self) -> OMatrix<T, D, D> pub fn symmetric_part(&self) -> OMatrix<T, D, D>
where where
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
assert!( assert!(
self.is_square(), self.is_square(),
@ -1627,7 +1616,7 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
#[must_use] #[must_use]
pub fn hermitian_part(&self) -> OMatrix<T, D, D> pub fn hermitian_part(&self) -> OMatrix<T, D, D>
where where
DefaultAllocator: Allocator<D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
assert!( assert!(
self.is_square(), self.is_square(),
@ -1650,7 +1639,7 @@ impl<T: Scalar + Zero + One, D: DimAdd<U1> + IsNotStaticOne, S: RawStorage<T, D,
#[must_use] #[must_use]
pub fn to_homogeneous(&self) -> OMatrix<T, DimSum<D, U1>, DimSum<D, U1>> pub fn to_homogeneous(&self) -> OMatrix<T, DimSum<D, U1>, DimSum<D, U1>>
where where
DefaultAllocator: Allocator<DimSum<D, U1>, DimSum<D, U1>>, DefaultAllocator: Allocator<T, DimSum<D, U1>, DimSum<D, U1>>,
{ {
assert!( assert!(
self.is_square(), self.is_square(),
@ -1671,7 +1660,7 @@ impl<T: Scalar + Zero, D: DimAdd<U1>, S: RawStorage<T, D>> Vector<T, D, S> {
#[must_use] #[must_use]
pub fn to_homogeneous(&self) -> OVector<T, DimSum<D, U1>> pub fn to_homogeneous(&self) -> OVector<T, DimSum<D, U1>>
where where
DefaultAllocator: Allocator<DimSum<D, U1>>, DefaultAllocator: Allocator<T, DimSum<D, U1>>,
{ {
self.push(T::zero()) self.push(T::zero())
} }
@ -1682,7 +1671,7 @@ impl<T: Scalar + Zero, D: DimAdd<U1>, S: RawStorage<T, D>> Vector<T, D, S> {
pub fn from_homogeneous<SB>(v: Vector<T, DimSum<D, U1>, SB>) -> Option<OVector<T, D>> pub fn from_homogeneous<SB>(v: Vector<T, DimSum<D, U1>, SB>) -> Option<OVector<T, D>>
where where
SB: RawStorage<T, DimSum<D, U1>>, SB: RawStorage<T, DimSum<D, U1>>,
DefaultAllocator: Allocator<D>, DefaultAllocator: Allocator<T, D>,
{ {
if v[v.len() - 1].is_zero() { if v[v.len() - 1].is_zero() {
let nrows = D::from_usize(v.len() - 1); let nrows = D::from_usize(v.len() - 1);
@ -1699,7 +1688,7 @@ impl<T: Scalar, D: DimAdd<U1>, S: RawStorage<T, D>> Vector<T, D, S> {
#[must_use] #[must_use]
pub fn push(&self, element: T) -> OVector<T, DimSum<D, U1>> pub fn push(&self, element: T) -> OVector<T, DimSum<D, U1>>
where where
DefaultAllocator: Allocator<DimSum<D, U1>>, DefaultAllocator: Allocator<T, DimSum<D, U1>>,
{ {
let len = self.len(); let len = self.len();
let hnrows = DimSum::<D, U1>::from_usize(len + 1); let hnrows = DimSum::<D, U1>::from_usize(len + 1);
@ -2002,12 +1991,8 @@ mod tests {
} }
/// # Cross product /// # Cross product
impl< impl<T: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: RawStorage<T, R, C>>
T: Scalar + ClosedAddAssign + ClosedSubAssign + ClosedMulAssign, Matrix<T, R, C, S>
R: Dim,
C: Dim,
S: RawStorage<T, R, C>,
> Matrix<T, R, C, S>
{ {
/// The perpendicular product between two 2D column vectors, i.e. `a.x * b.y - a.y * b.x`. /// The perpendicular product between two 2D column vectors, i.e. `a.x * b.y - a.y * b.x`.
#[inline] #[inline]
@ -2056,7 +2041,7 @@ impl<
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
SB: RawStorage<T, R2, C2>, SB: RawStorage<T, R2, C2>,
DefaultAllocator: SameShapeAllocator<R, C, R2, C2>, DefaultAllocator: SameShapeAllocator<T, R, C, R2, C2>,
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>, ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
{ {
let shape = self.shape(); let shape = self.shape();
@ -2256,7 +2241,7 @@ where
where where
T: Scalar, T: Scalar,
OVector<T2, D>: SupersetOf<Vector<T, D, S>>, OVector<T2, D>: SupersetOf<Vector<T, D, S>>,
DefaultAllocator: Allocator<D, U1>, DefaultAllocator: Allocator<T2, D, U1>,
{ {
Unit::new_unchecked(crate::convert_ref(self.as_ref())) Unit::new_unchecked(crate::convert_ref(self.as_ref()))
} }

View File

@ -15,12 +15,16 @@ where
R: Dim, R: Dim,
C: Dim, C: Dim,
T::Element: Scalar, T::Element: Scalar,
DefaultAllocator: Allocator<R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
const LANES: usize = T::LANES;
type Element = OMatrix<T::Element, R, C>; type Element = OMatrix<T::Element, R, C>;
type SimdBool = T::SimdBool; type SimdBool = T::SimdBool;
#[inline]
fn lanes() -> usize {
T::lanes()
}
#[inline] #[inline]
fn splat(val: Self::Element) -> Self { fn splat(val: Self::Element) -> Self {
val.map(T::splat) val.map(T::splat)

View File

@ -43,10 +43,6 @@ macro_rules! view_storage_impl (
impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, T, R, C, RStride, CStride> { impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, T, R, C, RStride, CStride> {
/// Create a new matrix view without bounds checking and from a raw pointer. /// Create a new matrix view without bounds checking and from a raw pointer.
///
/// # Safety
///
/// `*ptr` must point to memory that is valid `[T; R * C]`.
#[inline] #[inline]
pub unsafe fn from_raw_parts(ptr: $Ptr, pub unsafe fn from_raw_parts(ptr: $Ptr,
shape: (R, C), shape: (R, C),
@ -67,11 +63,6 @@ macro_rules! view_storage_impl (
// Dyn is arbitrary. It's just to be able to call the constructors with `Slice::` // Dyn is arbitrary. It's just to be able to call the constructors with `Slice::`
impl<'a, T, R: Dim, C: Dim> $T<'a, T, R, C, Dyn, Dyn> { impl<'a, T, R: Dim, C: Dim> $T<'a, T, R, C, Dyn, Dyn> {
/// Create a new matrix view without bounds checking. /// Create a new matrix view without bounds checking.
///
/// # Safety
///
/// `storage` contains sufficient elements beyond `start + R * C` such that all
/// accesses are within bounds.
#[inline] #[inline]
pub unsafe fn new_unchecked<RStor, CStor, S>(storage: $SRef, start: (usize, usize), shape: (R, C)) pub unsafe fn new_unchecked<RStor, CStor, S>(storage: $SRef, start: (usize, usize), shape: (R, C))
-> $T<'a, T, R, C, S::RStride, S::CStride> -> $T<'a, T, R, C, S::RStride, S::CStride>
@ -84,10 +75,6 @@ macro_rules! view_storage_impl (
} }
/// Create a new matrix view without bounds checking. /// Create a new matrix view without bounds checking.
///
/// # Safety
///
/// `strides` must be a valid stride indexing.
#[inline] #[inline]
pub unsafe fn new_with_strides_unchecked<S, RStor, CStor, RStride, CStride>(storage: $SRef, pub unsafe fn new_with_strides_unchecked<S, RStor, CStor, RStride, CStride>(storage: $SRef,
start: (usize, usize), start: (usize, usize),
@ -141,7 +128,12 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Clone
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
*self Self {
ptr: self.ptr,
shape: self.shape,
strides: self.strides,
_phantoms: PhantomData,
}
} }
} }
@ -218,22 +210,17 @@ macro_rules! storage_impl(
for $T<'a, T, R, C, RStride, CStride> { for $T<'a, T, R, C, RStride, CStride> {
#[inline] #[inline]
fn into_owned(self) -> Owned<T, R, C> fn into_owned(self) -> Owned<T, R, C>
where DefaultAllocator: Allocator<R, C> { where DefaultAllocator: Allocator<T, R, C> {
self.clone_owned() self.clone_owned()
} }
#[inline] #[inline]
fn clone_owned(&self) -> Owned<T, R, C> fn clone_owned(&self) -> Owned<T, R, C>
where DefaultAllocator: Allocator<R, C> { where DefaultAllocator: Allocator<T, R, C> {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
let it = MatrixIter::new(self).cloned(); let it = MatrixIter::new(self).cloned();
DefaultAllocator::allocate_from_iterator(nrows, ncols, it) DefaultAllocator::allocate_from_iterator(nrows, ncols, it)
} }
#[inline]
fn forget_elements(self) {
// No cleanup required.
}
} }
)*} )*}
); );
@ -551,8 +538,8 @@ macro_rules! matrix_view_impl (
$me.$generic_view_with_steps(start, shape, steps) $me.$generic_view_with_steps(start, shape, steps)
} }
/// Slices this matrix starting at its component `(irow, icol)` and with `(RVIEW, CVIEW)` /// Slices this matrix starting at its component `(irow, icol)` and with `(R::dim(),
/// consecutive components. /// CView::dim())` consecutive components.
#[inline] #[inline]
#[deprecated = slice_deprecation_note!($fixed_view)] #[deprecated = slice_deprecation_note!($fixed_view)]
pub fn $fixed_slice<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize) pub fn $fixed_slice<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize)
@ -560,8 +547,8 @@ macro_rules! matrix_view_impl (
$me.$fixed_view(irow, icol) $me.$fixed_view(irow, icol)
} }
/// Return a view of this matrix starting at its component `(irow, icol)` and with /// Return a view of this matrix starting at its component `(irow, icol)` and with `(R::dim(),
/// `(RVIEW, CVIEW)` consecutive components. /// CView::dim())` consecutive components.
#[inline] #[inline]
pub fn $fixed_view<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize) pub fn $fixed_view<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize)
-> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, S::RStride, S::CStride> { -> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, S::RStride, S::CStride> {

Some files were not shown because too many files have changed in this diff Show More