Compare commits

..

22 Commits

Author SHA1 Message Date
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 3072 additions and 4770 deletions

View File

@ -13,59 +13,52 @@ jobs:
check-fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Check formatting
run: cargo fmt -- --check
- uses: actions/checkout@v2
- name: Check formatting
run: cargo fmt -- --check
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install clippy
run: rustup component add clippy
- name: Run clippy
run: cargo clippy
- uses: actions/checkout@v2
- name: Install clippy
run: rustup component add clippy
- name: Run clippy
run: cargo clippy
build-nalgebra:
runs-on: ubuntu-latest
# env:
# RUSTFLAGS: -D warnings
# env:
# RUSTFLAGS: -D warnings
steps:
- uses: actions/checkout@v2
- name: Build --no-default-feature
run: cargo build --no-default-features;
- name: Build (default features)
run: cargo build;
- name: Build --features serde-serialize
run: cargo build --features serde-serialize
- name: Build nalgebra-lapack
run: cd nalgebra-lapack; cargo build;
- name: Build nalgebra-sparse --no-default-features
run: cd nalgebra-sparse; cargo build --no-default-features;
- name: Build nalgebra-sparse (default features)
run: cd nalgebra-sparse; cargo build;
- name: Build nalgebra-sparse --all-features
run: cd nalgebra-sparse; cargo build --all-features;
- uses: actions/checkout@v2
- name: Build --no-default-feature
run: cargo build --no-default-features;
- name: Build (default features)
run: cargo build;
- name: Build --features serde-serialize
run: cargo build --features serde-serialize
- name: Build nalgebra-lapack
run: cd nalgebra-lapack; cargo build;
- name: Build nalgebra-sparse --no-default-features
run: cd nalgebra-sparse; cargo build --no-default-features;
- name: Build nalgebra-sparse (default features)
run: cd nalgebra-sparse; cargo build;
- name: Build nalgebra-sparse --all-features
run: cd nalgebra-sparse; cargo build --all-features;
# 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.
build-nalgebra-all-features:
runs-on: ubuntu-latest
steps:
# Needed because the --all-features build which enables cuda support.
- uses: Jimver/cuda-toolkit@v0.2.8
- uses: actions/checkout@v2
- run: cargo build --all-features;
- run: cargo build -p nalgebra-glm --all-features;
test-nalgebra:
runs-on: ubuntu-latest
# env:
# RUSTFLAGS: -D warnings
# env:
# RUSTFLAGS: -D warnings
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
- name: test
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
build-wasm:
runs-on: ubuntu-latest
# env:
# RUSTFLAGS: -D warnings
# env:
# RUSTFLAGS: -D warnings
steps:
- uses: actions/checkout@v2
- 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;
- name: build thumbv7em-none-eabihf nalgebra-glm
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:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Generate documentation
run: cargo doc
- uses: actions/checkout@v2
- name: Generate documentation
run: cargo doc

View File

@ -5,33 +5,13 @@ documented here.
This project adheres to [Semantic Versioning](https://semver.org/).
## [0.33.0] (23 June 2024)
### 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>`.
## Unreleased
## [0.32.6] (12 June 2024)
### 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)
@ -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 `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.25` feature to enable conversion from/to types from `glam` v0.25.
- Add the `lerp` method to points.
- Implement `Clone` for `MatrixIter`.

View File

@ -1,6 +1,6 @@
[package]
name = "nalgebra"
version = "0.33.0"
version = "0.32.6"
authors = ["Sébastien Crozet <developer@crozet.re>"]
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"
categories = ["science", "mathematics", "wasm", "no-std"]
keywords = ["linear", "algebra", "matrix", "vector", "math"]
license = "Apache-2.0"
license = "BSD-3-Clause"
edition = "2018"
exclude = ["/ci/*", "/.travis.yml", "/Makefile"]
@ -23,7 +23,7 @@ path = "src/lib.rs"
[features]
default = ["std", "macros"]
std = ["matrixmultiply", "num-traits/std", "num-complex/std", "num-rational/std", "approx/std", "simba/std"]
std = ["matrixmultiply", "simba/std"]
sparse = []
debug = ["approx/num-complex", "rand"]
alloc = []
@ -32,6 +32,8 @@ compare = ["matrixcompare-core"]
libm = ["simba/libm"]
libm-force = ["simba/libm_force"]
macros = ["nalgebra-macros"]
cuda = ["cust_core", "simba/cuda"]
# Conversion
convert-mint = ["mint"]
@ -49,7 +51,6 @@ convert-glam023 = ["glam023"]
convert-glam024 = ["glam024"]
convert-glam025 = ["glam025"]
convert-glam027 = ["glam027"]
convert-glam028 = ["glam028"]
# Serialization
## To use serde in a #[no-std] environment, enable the
@ -74,14 +75,14 @@ slow-tests = []
rkyv-safe-deser = ["rkyv-serialize", "rkyv/validation"]
[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"
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
num-traits = { version = "0.2", default-features = false }
num-complex = { version = "0.4", default-features = false }
num-rational = { version = "0.4", 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 }
rand_distr = { version = "0.4", default-features = false, 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 }
glam025 = { package = "glam", version = "0.25", 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 }
[dev-dependencies]
@ -119,12 +120,7 @@ nalgebra = { path = ".", features = ["debug", "compare", "rand", "macros"] }
# For matrix comparison macro
matrixcompare = "0.3.0"
itertools = "0.13"
# For macro testing
trybuild = "1.0.90"
cool_asserts = "2.0.3"
itertools = "0.10"
[workspace]
members = ["nalgebra-lapack", "nalgebra-glm", "nalgebra-sparse", "nalgebra-macros"]

View File

@ -5,6 +5,9 @@
<a href="https://discord.gg/vt9DJSW">
<img src="https://img.shields.io/discord/507548572338880513.svg?logo=discord&colorB=7289DA">
</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">
<img src="https://img.shields.io/crates/v/nalgebra.svg?style=flat-square" alt="crates.io">
</a>
@ -14,7 +17,7 @@
</p>
<p align = "center">
<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>
</p>

View File

@ -142,7 +142,7 @@ fn iter(bench: &mut criterion::Criterion) {
bench.bench_function("iter", move |bh| {
bh.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| {
bh.iter(|| {
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)]
extern crate nalgebra as na;

View File

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

View File

@ -12,7 +12,7 @@ fn reflect_wrt_hyperplane_with_dimensional_genericity<T: RealField, D: Dim>(
where
T: RealField,
D: Dim,
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<T, D>,
{
let n = plane_normal.as_ref(); // Get the underlying V.
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`.
/// /!\ 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>
where
T: RealField,

View File

@ -1,6 +1,6 @@
[package]
name = "nalgebra-glm"
version = "0.19.0"
version = "0.18.0"
authors = ["sebcrozet <developer@crozet.re>"]
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"
repository = "https://github.com/dimforge/nalgebra"
readme = "../README.md"
categories = ["science", "mathematics", "wasm", "no standard library"]
keywords = ["linear", "algebra", "matrix", "vector", "math"]
license = "Apache-2.0"
categories = [ "science", "mathematics", "wasm", "no standard library" ]
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
license = "BSD-3-Clause"
edition = "2018"
[badges]
maintenance = { status = "actively-developed" }
[features]
default = ["std"]
std = ["nalgebra/std", "simba/std"]
arbitrary = ["nalgebra/arbitrary"]
serde-serialize = ["nalgebra/serde-serialize-no-std"]
default = [ "std" ]
std = [ "nalgebra/std", "simba/std" ]
arbitrary = [ "nalgebra/arbitrary" ]
serde-serialize = [ "nalgebra/serde-serialize-no-std" ]
cuda = [ "nalgebra/cuda" ]
# Conversion
convert-mint = ["nalgebra/mint"]
convert-bytemuck = ["nalgebra/bytemuck"]
convert-glam014 = ["nalgebra/glam014"]
convert-glam015 = ["nalgebra/glam015"]
convert-glam016 = ["nalgebra/glam016"]
convert-glam017 = ["nalgebra/glam017"]
convert-glam018 = ["nalgebra/glam018"]
convert-mint = [ "nalgebra/mint" ]
convert-bytemuck = [ "nalgebra/bytemuck" ]
convert-glam014 = [ "nalgebra/glam014" ]
convert-glam015 = [ "nalgebra/glam015" ]
convert-glam016 = [ "nalgebra/glam016" ]
convert-glam017 = [ "nalgebra/glam017" ]
convert-glam018 = [ "nalgebra/glam018" ]
[dependencies]
num-traits = { version = "0.2", default-features = false }
approx = { version = "0.5", default-features = false }
simba = { version = "0.9", default-features = false }
nalgebra = { path = "..", version = "0.33", default-features = false }
simba = { version = "0.8", 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.
///
/// 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
/// also work on a vector.
///
/// # See also:
///
/// * [`TMat2`]
/// * [`TMat2x2`]
/// * [`TMat2x3`]
/// * [`TMat2x4`]
/// * [`TMat3`]
/// * [`TMat3x2`]
/// * [`TMat3x3`]
/// * [`TMat3x4`]
/// * [`TMat4`]
/// * [`TMat4x2`]
/// * [`TMat4x3`]
/// * [`TMat4x4`]
/// * [`TVec`]
/// * [`TMat2`](type.TMat2.html)
/// * [`TMat2x2`](type.TMat2x2.html)
/// * [`TMat2x3`](type.TMat2x3.html)
/// * [`TMat2x4`](type.TMat2x4.html)
/// * [`TMat3`](type.TMat3.html)
/// * [`TMat3x2`](type.TMat3x2.html)
/// * [`TMat3x3`](type.TMat3x3.html)
/// * [`TMat3x4`](type.TMat3x4.html)
/// * [`TMat4`](type.TMat4.html)
/// * [`TMat4x2`](type.TMat4x2.html)
/// * [`TMat4x3`](type.TMat4x3.html)
/// * [`TMat4x4`](type.TMat4x4.html)
/// * [`TVec`](type.TVec.html)
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).
///
/// 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:
///
/// * [`TMat`]
/// * [`TVec1`]
/// * [`TVec2`]
/// * [`TVec3`]
/// * [`TVec4`]
/// * [`TMat`](type.TMat.html)
/// * [`TVec1`](type.TVec1.html)
/// * [`TVec2`](type.TVec2.html)
/// * [`TVec3`](type.TVec3.html)
/// * [`TVec4`](type.TVec4.html)
pub type TVec<T, const R: usize> = SVector<T, R>;
/// A quaternion with components of type `T`.
pub type Qua<T> = Quaternion<T>;
@ -47,28 +47,28 @@ pub type Qua<T> = Quaternion<T>;
///
/// ## Constructors:
///
/// * [`make_vec1()`](crate::make_vec1)
/// * [`vec1()`](crate::vec1)
/// * [`vec2_to_vec1()`](crate::vec2_to_vec1)
/// * [`vec3_to_vec1()`](crate::vec3_to_vec1)
/// * [`vec4_to_vec1()`](crate::vec4_to_vec1)
/// * [`make_vec1`](fn.make_vec1.html)
/// * [`vec1`](fn.vec1.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
///
/// ## Related types:
///
/// * [`BVec1`]
/// * [`DVec1`]
/// * [`IVec1`]
/// * [`I16Vec1`]
/// * [`I32Vec1`]
/// * [`I64Vec1`]
/// * [`I8Vec1`]
/// * [`TVec`]
/// * [`UVec1`]
/// * [`U16Vec1`]
/// * [`U32Vec1`]
/// * [`U64Vec1`]
/// * [`U8Vec1`]
/// * [`Vec1`]
/// * [`BVec1`](type.BVec1.html)
/// * [`DVec1`](type.DVec1.html)
/// * [`IVec1`](type.IVec1.html)
/// * [`I16Vec1`](type.I16Vec1.html)
/// * [`I32Vec1`](type.I32Vec1.html)
/// * [`I64Vec1`](type.I64Vec1.html)
/// * [`I8Vec1`](type.I8Vec1.html)
/// * [`TVec`](type.TVec.html)
/// * [`UVec1`](type.UVec1.html)
/// * [`U16Vec1`](type.U16Vec1.html)
/// * [`U32Vec1`](type.U32Vec1.html)
/// * [`U64Vec1`](type.U64Vec1.html)
/// * [`U8Vec1`](type.U8Vec1.html)
/// * [`Vec1`](type.Vec1.html)
pub type TVec1<T> = TVec<T, 1>;
/// A 2D vector with components of type `T`.
///
@ -76,28 +76,29 @@ pub type TVec1<T> = TVec<T, 1>;
///
/// ## Constructors:
///
/// * [`make_vec2()`](crate::make_vec2)
/// * [`vec2()`](crate::vec2)
/// * [`vec1_to_vec2()`](crate::vec1_to_vec2)
/// * [`vec3_to_vec2()`](crate::vec3_to_vec2)
/// * [`vec4_to_vec2()`](crate::vec4_to_vec2)
/// * [`make_vec2`](fn.make_vec2.html)
/// * [`vec2`](fn.vec2.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
///
/// ## Related types:
///
/// * [`BVec2`]
/// * [`DVec2`]
/// * [`IVec2`]
/// * [`I16Vec2`]
/// * [`I32Vec2`]
/// * [`I64Vec2`]
/// * [`I8Vec2`]
/// * [`TVec`]
/// * [`UVec2`]
/// * [`U16Vec2`]
/// * [`U32Vec2`]
/// * [`U64Vec2`]
/// * [`U8Vec2`]
/// * [`Vec2`]
/// * [`vec2`](fn.vec2.html)
/// * [`BVec2`](type.BVec2.html)
/// * [`DVec2`](type.DVec2.html)
/// * [`IVec2`](type.IVec2.html)
/// * [`I16Vec2`](type.I16Vec2.html)
/// * [`I32Vec2`](type.I32Vec2.html)
/// * [`I64Vec2`](type.I64Vec2.html)
/// * [`I8Vec2`](type.I8Vec2.html)
/// * [`TVec`](type.TVec.html)
/// * [`UVec2`](type.UVec2.html)
/// * [`U16Vec2`](type.U16Vec2.html)
/// * [`U32Vec2`](type.U32Vec2.html)
/// * [`U64Vec2`](type.U64Vec2.html)
/// * [`U8Vec2`](type.U8Vec2.html)
/// * [`Vec2`](type.Vec2.html)
pub type TVec2<T> = TVec<T, 2>;
/// A 3D vector with components of type `T`.
///
@ -105,28 +106,29 @@ pub type TVec2<T> = TVec<T, 2>;
///
/// ## Constructors:
///
/// * [`make_vec3()`](crate::make_vec3)
/// * [`vec3()`](crate::vec3)
/// * [`vec1_to_vec3()`](crate::vec1_to_vec3)
/// * [`vec2_to_vec3()`](crate::vec2_to_vec3)
/// * [`vec4_to_vec3()`](crate::vec4_to_vec3)
/// * [`make_vec3`](fn.make_vec3.html)
/// * [`vec3`](fn.vec3.html)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
///
/// ## Related types:
///
/// * [`BVec3`]
/// * [`DVec3`]
/// * [`IVec3`]
/// * [`I16Vec3`]
/// * [`I32Vec3`]
/// * [`I64Vec3`]
/// * [`I8Vec3`]
/// * [`TVec`]
/// * [`UVec3`]
/// * [`U16Vec3`]
/// * [`U32Vec3`]
/// * [`U64Vec3`]
/// * [`U8Vec3`]
/// * [`Vec3`]
/// * [`vec3`](fn.vec3.html)
/// * [`BVec3`](type.BVec3.html)
/// * [`DVec3`](type.DVec3.html)
/// * [`IVec3`](type.IVec3.html)
/// * [`I16Vec3`](type.I16Vec3.html)
/// * [`I32Vec3`](type.I32Vec3.html)
/// * [`I64Vec3`](type.I64Vec3.html)
/// * [`I8Vec3`](type.I8Vec3.html)
/// * [`TVec`](type.TVec.html)
/// * [`UVec3`](type.UVec3.html)
/// * [`U16Vec3`](type.U16Vec3.html)
/// * [`U32Vec3`](type.U32Vec3.html)
/// * [`U64Vec3`](type.U64Vec3.html)
/// * [`U8Vec3`](type.U8Vec3.html)
/// * [`Vec3`](type.Vec3.html)
pub type TVec3<T> = TVec<T, 3>;
/// A 4D vector with components of type `T`.
///
@ -134,27 +136,28 @@ pub type TVec3<T> = TVec<T, 3>;
///
/// ## Constructors:
///
/// * [`make_vec4()`](crate::make_vec4)
/// * [`vec4()`](crate::vec4)
/// * [`vec1_to_vec4()`](crate::vec1_to_vec4)
/// * [`vec2_to_vec4()`](crate::vec2_to_vec4)
/// * [`vec3_to_vec4()`](crate::vec3_to_vec4)
/// * [`make_vec4`](fn.make_vec4.html)
/// * [`vec4`](fn.vec4.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
///
/// ## Related types:
///
/// * [`BVec4`]
/// * [`DVec4`]
/// * [`IVec4`]
/// * [`I16Vec4`]
/// * [`I32Vec4`]
/// * [`I64Vec4`]
/// * [`I8Vec4`]
/// * [`UVec4`]
/// * [`U16Vec4`]
/// * [`U32Vec4`]
/// * [`U64Vec4`]
/// * [`U8Vec4`]
/// * [`Vec4`]
/// * [`vec4`](fn.vec4.html)
/// * [`BVec4`](type.BVec4.html)
/// * [`DVec4`](type.DVec4.html)
/// * [`IVec4`](type.IVec4.html)
/// * [`I16Vec4`](type.I16Vec4.html)
/// * [`I32Vec4`](type.I32Vec4.html)
/// * [`I64Vec4`](type.I64Vec4.html)
/// * [`I8Vec4`](type.I8Vec4.html)
/// * [`UVec4`](type.UVec4.html)
/// * [`U16Vec4`](type.U16Vec4.html)
/// * [`U32Vec4`](type.U32Vec4.html)
/// * [`U64Vec4`](type.U64Vec4.html)
/// * [`U8Vec4`](type.U8Vec4.html)
/// * [`Vec4`](type.Vec4.html)
pub type TVec4<T> = TVec<T, 4>;
/// A 1D vector with boolean components.
pub type BVec1 = TVec1<bool>;

View File

@ -1,4 +1,5 @@
use core::mem;
use na;
use crate::aliases::{TMat, TVec};
use crate::traits::Number;
@ -19,7 +20,7 @@ use crate::RealNumber;
///
/// # 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> {
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:
///
/// * [`ceil()`]
/// * [`floor()`]
/// * [`fract()`]
/// * [`round()`]
/// * [`trunc()`]
/// * [`ceil`](fn.ceil.html)
/// * [`floor`](fn.floor.html)
/// * [`fract`](fn.fract.html)
/// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html)
pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`clamp()`]
/// * [`clamp_vec()`]
/// * [`clamp`](fn.clamp.html)
/// * [`clamp_vec`](fn.clamp_vec.html)
pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
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:
///
/// * [`clamp_scalar()`]
/// * [`clamp_vec()`]
/// * [`clamp_scalar`](fn.clamp_scalar.html)
/// * [`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> {
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:
///
/// * [`clamp_scalar()`]
/// * [`clamp()`]
/// * [`clamp_scalar`](fn.clamp_scalar.html)
/// * [`clamp`](fn.clamp.html)
pub fn clamp_vec<T: Number, const D: usize>(
x: &TVec<T, D>,
min_val: &TVec<T, D>,
@ -135,13 +136,13 @@ pub fn clamp_vec<T: Number, const D: usize>(
///
/// # See also:
///
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn float_bits_to_int(v: f32) -> i32 {
unsafe { mem::transmute(v) }
}
@ -152,13 +153,13 @@ pub fn float_bits_to_int(v: f32) -> i32 {
///
/// # See also:
///
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`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> {
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:
///
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn float_bits_to_uint(v: f32) -> u32 {
unsafe { mem::transmute(v) }
}
@ -186,13 +187,13 @@ pub fn float_bits_to_uint(v: f32) -> u32 {
///
/// # See also:
///
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`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> {
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:
///
/// * [`ceil()`]
/// * [`fract()`]
/// * [`round()`]
/// * [`trunc()`]
/// * [`ceil`](fn.ceil.html)
/// * [`fract`](fn.fract.html)
/// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html)
pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`ceil()`]
/// * [`floor()`]
/// * [`round()`]
/// * [`trunc()`]
/// * [`ceil`](fn.ceil.html)
/// * [`floor`](fn.floor.html)
/// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html)
pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn int_bits_to_float(v: i32) -> f32 {
f32::from_bits(v as u32)
}
@ -274,13 +275,13 @@ pub fn int_bits_to_float(v: i32) -> f32 {
///
/// # See also:
///
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`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> {
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:
///
/// * [`mix()`]
/// * [`mix_vec()`]
/// * [`mix`](fn.mix.html)
/// * [`mix_vec`](fn.mix_vec.html)
pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
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:
///
/// * [`mix_scalar()`]
/// * [`mix_vec()`]
/// * [`mix_scalar`](fn.mix_scalar.html)
/// * [`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> {
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:
///
/// * [`mix_scalar()`]
/// * [`mix()`]
/// * [`mix_scalar`](fn.mix_scalar.html)
/// * [`mix`](fn.mix.html)
pub fn mix_vec<T: Number, const D: usize>(
x: &TVec<T, D>,
y: &TVec<T, D>,
a: &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.
@ -382,8 +383,8 @@ pub fn mix_vec<T: Number, const D: usize>(
///
/// # See also:
///
/// * [`lerp()`]
/// * [`lerp_vec()`]
/// * [`lerp`](fn.lerp.html)
/// * [`lerp_vec`](fn.lerp_vec.html)
pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
mix_scalar(x, y, a)
}
@ -404,8 +405,8 @@ pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
///
/// # See also:
///
/// * [`lerp_scalar()`]
/// * [`lerp_vec()`]
/// * [`lerp_scalar`](fn.lerp_scalar.html)
/// * [`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> {
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:
///
/// * [`lerp_scalar()`]
/// * [`lerp()`]
/// * [`lerp_scalar`](fn.lerp_scalar.html)
/// * [`lerp`](fn.lerp.html)
pub fn lerp_vec<T: Number, const D: usize>(
x: &TVec<T, D>,
y: &TVec<T, D>,
@ -444,7 +445,7 @@ pub fn lerp_vec<T: Number, const D: usize>(
///
/// # 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> {
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:
///
/// * [`modf_vec()`]
/// * [`modf_vec`](fn.modf_vec.html)
pub fn modf<T: Number>(x: T, i: T) -> T {
x % i
}
@ -472,10 +473,10 @@ pub fn modf<T: Number>(x: T, i: T) -> T {
///
/// # See also:
///
/// * [`ceil()`]
/// * [`floor()`]
/// * [`fract()`]
/// * [`trunc()`]
/// * [`ceil`](fn.ceil.html)
/// * [`floor`](fn.floor.html)
/// * [`fract`](fn.fract.html)
/// * [`trunc`](fn.trunc.html)
pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`abs()`]
/// * [`abs`](fn.abs.html)
///
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() })
@ -544,10 +545,10 @@ pub fn step_vec<T: Number, const D: usize>(edge: &TVec<T, D>, x: &TVec<T, D>) ->
///
/// # See also:
///
/// * [`ceil()`]
/// * [`floor()`]
/// * [`fract()`]
/// * [`round()`]
/// * [`ceil`](fn.ceil.html)
/// * [`floor`](fn.floor.html)
/// * [`fract`](fn.fract.html)
/// * [`round`](fn.round.html)
pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
f32::from_bits(v)
}
@ -575,13 +576,13 @@ pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
///
/// # See also:
///
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float_scalar()`]
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`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> {
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]
#[allow(clippy::too_many_arguments)]
pub fn mat3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: 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.
#[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: 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.
#[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat3x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: 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.
#[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: 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.
#[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: 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.
#[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: T,
m31: T, m32: T, m33: T, m34: T,

View File

@ -5,7 +5,7 @@ use crate::RealNumber;
///
/// # See also:
///
/// * [`exp2()`]
/// * [`exp2`](fn.exp2.html)
pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`exp()`]
/// * [`exp`](fn.exp.html)
pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`sqrt()`]
/// * [`sqrt`](fn.sqrt.html)
pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`log2()`]
/// * [`log2`](fn.log2.html)
pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`log()`]
/// * [`log`](fn.log.html)
pub fn log2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`exp()`]
/// * [`exp2()`]
/// * [`inversesqrt()`]
/// * [`pow`]
/// * [`exp`](fn.exp.html)
/// * [`exp2`](fn.exp2.html)
/// * [`inversesqrt`](fn.inversesqrt.html)
/// * [`pow`](fn.pow.html)
pub fn sqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.sqrt())
}

View File

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

View File

@ -18,8 +18,8 @@ pub fn identity<T: Number, const D: usize>() -> TMat<T, D, D> {
///
/// # See also:
///
/// * [`look_at_lh()`]
/// * [`look_at_rh()`]
/// * [`look_at_lh`](fn.look_at_lh.html)
/// * [`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> {
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:
///
/// * [`look_at()`]
/// * [`look_at_rh()`]
/// * [`look_at`](fn.look_at.html)
/// * [`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> {
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:
///
/// * [`look_at()`]
/// * [`look_at_lh()`]
/// * [`look_at`](fn.look_at.html)
/// * [`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> {
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:
///
/// * [`rotate_x()`]
/// * [`rotate_y()`]
/// * [`rotate_z()`]
/// * [`scale()`]
/// * [`translate()`]
/// * [`rotate_x`](fn.rotate_x.html)
/// * [`rotate_y`](fn.rotate_y.html)
/// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale`](fn.scale.html)
/// * [`translate`](fn.translate.html)
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()
}
@ -84,11 +84,11 @@ pub fn rotate<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T
///
/// # See also:
///
/// * [`rotate()`]
/// * [`rotate_y()`]
/// * [`rotate_z()`]
/// * [`scale()`]
/// * [`translate()`]
/// * [`rotate`](fn.rotate.html)
/// * [`rotate_y`](fn.rotate_y.html)
/// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale`](fn.scale.html)
/// * [`translate`](fn.translate.html)
pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::x())
}
@ -102,11 +102,11 @@ pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
///
/// # See also:
///
/// * [`rotate()`]
/// * [`rotate_x()`]
/// * [`rotate_z()`]
/// * [`scale()`]
/// * [`translate()`]
/// * [`rotate`](fn.rotate.html)
/// * [`rotate_x`](fn.rotate_x.html)
/// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale`](fn.scale.html)
/// * [`translate`](fn.translate.html)
pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::y())
}
@ -120,11 +120,11 @@ pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
///
/// # See also:
///
/// * [`rotate()`]
/// * [`rotate_x()`]
/// * [`rotate_y()`]
/// * [`scale()`]
/// * [`translate()`]
/// * [`rotate`](fn.rotate.html)
/// * [`rotate_x`](fn.rotate_x.html)
/// * [`rotate_y`](fn.rotate_y.html)
/// * [`scale`](fn.scale.html)
/// * [`translate`](fn.translate.html)
pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::z())
}
@ -138,11 +138,11 @@ pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
///
/// # See also:
///
/// * [`rotate()`]
/// * [`rotate_x()`]
/// * [`rotate_y()`]
/// * [`rotate_z()`]
/// * [`translate()`]
/// * [`rotate`](fn.rotate.html)
/// * [`rotate_x`](fn.rotate_x.html)
/// * [`rotate_y`](fn.rotate_y.html)
/// * [`rotate_z`](fn.rotate_z.html)
/// * [`translate`](fn.translate.html)
pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
m.prepend_nonuniform_scaling(v)
}
@ -156,11 +156,11 @@ pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
///
/// # See also:
///
/// * [`rotate()`]
/// * [`rotate_x()`]
/// * [`rotate_y()`]
/// * [`rotate_z()`]
/// * [`scale()`]
/// * [`rotate`](fn.rotate.html)
/// * [`rotate_x`](fn.rotate_x.html)
/// * [`rotate_y`](fn.rotate_y.html)
/// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale`](fn.scale.html)
pub fn translate<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
m.prepend_translation(v)
}

View File

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

View File

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

View File

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

View File

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

View File

@ -5,9 +5,9 @@ use crate::traits::Number;
///
/// # See also:
///
/// * [`equal_eps_vec()`]
/// * [`not_equal_eps()`]
/// * [`not_equal_eps_vec()`]
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn equal_eps<T: Number, const D: usize>(
x: &TVec<T, D>,
y: &TVec<T, D>,
@ -20,9 +20,9 @@ pub fn equal_eps<T: Number, const D: usize>(
///
/// # See also:
///
/// * [`equal_eps()`]
/// * [`not_equal_eps()`]
/// * [`not_equal_eps_vec()`]
/// * [`equal_eps`](fn.equal_eps.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn equal_eps_vec<T: Number, const D: usize>(
x: &TVec<T, D>,
y: &TVec<T, D>,
@ -35,9 +35,9 @@ pub fn equal_eps_vec<T: Number, const D: usize>(
///
/// # See also:
///
/// * [`equal_eps()`]
/// * [`equal_eps_vec()`]
/// * [`not_equal_eps_vec()`]
/// * [`equal_eps`](fn.equal_eps.html)
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn not_equal_eps<T: Number, const D: usize>(
x: &TVec<T, D>,
y: &TVec<T, D>,
@ -50,9 +50,9 @@ pub fn not_equal_eps<T: Number, const D: usize>(
///
/// # See also:
///
/// * [`equal_eps()`]
/// * [`equal_eps_vec()`]
/// * [`not_equal_eps()`]
/// * [`equal_eps`](fn.equal_eps.html)
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html)
pub fn not_equal_eps_vec<T: Number, const D: usize>(
x: &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:
///
/// * [`distance2()`](crate::distance2)
/// * [`distance2`](fn.distance2.html)
pub fn distance<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
(p1 - p0).norm()
}
@ -37,13 +37,13 @@ pub fn faceforward<T: Number, const D: usize>(
/// The magnitude of a vector.
///
/// A synonym for [`magnitude()`].
/// A synonym for [`magnitude`](fn.magnitude.html).
///
/// # See also:
///
/// * [`length2()`](crate::length2)
/// * [`magnitude()`]
/// * [`magnitude2()`](crate::magnitude2)
/// * [`length2`](fn.length2.html)
/// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html)
pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm()
}
@ -54,8 +54,8 @@ pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
///
/// # See also:
///
/// * [`length()`]
/// * [`magnitude2()`](crate::magnitude2)
/// * [`length`](fn.length.html)
/// * [`magnitude2`](fn.magnitude2.html)
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
pub fn magnitude<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm()

View File

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

View File

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

View File

@ -128,9 +128,9 @@ pub fn make_quat<T: RealNumber>(ptr: &[T]) -> Qua<T> {
///
/// # See also:
///
/// * [`make_vec2()`]
/// * [`make_vec3()`]
/// * [`make_vec4()`]
/// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec3`](fn.make_vec3.html)
/// * [`make_vec4`](fn.make_vec4.html)
pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
v.clone()
}
@ -139,11 +139,12 @@ pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
///
/// # See also:
///
/// * [`vec3_to_vec1()`]
/// * [`vec4_to_vec1()`]
/// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec4()`]
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`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> {
TVec1::new(v.x.clone())
}
@ -152,11 +153,12 @@ pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
///
/// # See also:
///
/// * [`vec2_to_vec1()`]
/// * [`vec4_to_vec1()`]
/// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec4()`]
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`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> {
TVec1::new(v.x.clone())
}
@ -165,11 +167,12 @@ pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
///
/// # See also:
///
/// * [`vec2_to_vec1()`]
/// * [`vec3_to_vec1()`]
/// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec4()`]
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`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> {
TVec1::new(v.x.clone())
}
@ -180,12 +183,12 @@ pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
///
/// # See also:
///
/// * [`vec3_to_vec2()`]
/// * [`vec4_to_vec2()`]
/// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4()`]
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
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:
///
/// * [`vec1_to_vec2()`]
/// * [`vec3_to_vec2()`]
/// * [`vec4_to_vec2()`]
/// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4()`]
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
v.clone()
}
@ -209,12 +212,12 @@ pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
///
/// # See also:
///
/// * [`vec1_to_vec2()`]
/// * [`vec4_to_vec2()`]
/// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4()`]
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
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:
///
/// * [`vec1_to_vec2()`]
/// * [`vec3_to_vec2()`]
/// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4()`]
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec3_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
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:
///
/// * [`make_vec1()`]
/// * [`make_vec3()`]
/// * [`make_vec4()`]
/// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec3`](fn.make_vec3.html)
/// * [`make_vec4`](fn.make_vec4.html)
pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
TVec2::from_column_slice(ptr)
}
@ -250,11 +253,11 @@ pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
///
/// # See also:
///
/// * [`vec2_to_vec3()`]
/// * [`vec3_to_vec3()`]
/// * [`vec4_to_vec3()`]
/// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec4()`]
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
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:
///
/// * [`vec1_to_vec3()`]
/// * [`vec3_to_vec3()`]
/// * [`vec4_to_vec3()`]
/// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec4()`]
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
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:
///
/// * [`vec1_to_vec3()`]
/// * [`vec2_to_vec3()`]
/// * [`vec4_to_vec3()`]
/// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec4()`]
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
v.clone()
}
@ -293,12 +296,12 @@ pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
///
/// # See also:
///
/// * [`vec1_to_vec3()`]
/// * [`vec2_to_vec3()`]
/// * [`vec3_to_vec3()`]
/// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec4()`]
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
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:
///
/// * [`make_vec1()`]
/// * [`make_vec2()`]
/// * [`make_vec4()`]
/// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec4`](fn.make_vec4.html)
pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
TVec3::from_column_slice(ptr)
}
@ -320,12 +323,12 @@ pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
///
/// # See also:
///
/// * [`vec2_to_vec4()`]
/// * [`vec3_to_vec4()`]
/// * [`vec4_to_vec4()`]
/// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec4()`]
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> {
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:
///
/// * [`vec1_to_vec4()`]
/// * [`vec3_to_vec4()`]
/// * [`vec4_to_vec4()`]
/// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3()`]
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> {
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:
///
/// * [`vec1_to_vec4()`]
/// * [`vec2_to_vec4()`]
/// * [`vec4_to_vec4()`]
/// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec3()`]
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> {
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:
///
/// * [`vec1_to_vec4()`]
/// * [`vec2_to_vec4()`]
/// * [`vec3_to_vec4()`]
/// * [`vec4_to_vec1()`]
/// * [`vec4_to_vec2()`]
/// * [`vec4_to_vec3()`]
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
v.clone()
}
@ -380,9 +383,9 @@ pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
///
/// # See also:
///
/// * [`make_vec1()`]
/// * [`make_vec2()`]
/// * [`make_vec3()`]
/// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec3`](fn.make_vec3.html)
pub fn make_vec4<T: Scalar>(ptr: &[T]) -> TVec4<T> {
TVec4::from_column_slice(ptr)
}

View File

@ -16,9 +16,9 @@ use crate::traits::Number;
///
/// # See also:
///
/// * [`comp_max()`]
/// * [`comp_min()`]
/// * [`comp_mul()`]
/// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min`](fn.comp_min.html)
/// * [`comp_mul`](fn.comp_mul.html)
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)
}
@ -38,13 +38,13 @@ pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) ->
///
/// # See also:
///
/// * [`comp_add()`]
/// * [`comp_max()`]
/// * [`comp_min()`]
/// * [`max()`](crate::max)
/// * [`max2()`](crate::max2)
/// * [`max3()`](crate::max3)
/// * [`max4()`](crate::max4)
/// * [`comp_add`](fn.comp_add.html)
/// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min`](fn.comp_min.html)
/// * [`max`](fn.max.html)
/// * [`max2`](fn.max2.html)
/// * [`max3`](fn.max3.html)
/// * [`max4`](fn.max4.html)
pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter()
.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:
///
/// * [`comp_add()`]
/// * [`comp_max()`]
/// * [`comp_mul()`]
/// * [`min()`](crate::min)
/// * [`min2()`](crate::min2)
/// * [`min3()`](crate::min3)
/// * [`min4()`](crate::min4)
/// * [`comp_add`](fn.comp_add.html)
/// * [`comp_max`](fn.comp_max.html)
/// * [`comp_mul`](fn.comp_mul.html)
/// * [`min`](fn.min.html)
/// * [`min2`](fn.min2.html)
/// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html)
pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter()
.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:
///
/// * [`comp_add()`]
/// * [`comp_max()`]
/// * [`comp_min()`]
/// * [`comp_add`](fn.comp_add.html)
/// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min`](fn.comp_min.html)
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)
}

View File

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

View File

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

View File

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

View File

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

View File

@ -4,11 +4,11 @@ use crate::aliases::TVec;
/// 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:
///
/// * [`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 {
// XXX: improve those.
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:
///
/// * [`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 {
// XXX: improve those.
x.normalize().dot(&y.normalize())

View File

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

View File

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

View File

@ -7,16 +7,16 @@ use crate::traits::Number;
///
/// # 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 {
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).
///
/// # 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 {
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).
pub fn is_normalized<T: RealNumber, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
// sqrt(1 + epsilon_{norm²} = 1 + epsilon_{norm}
// ==> 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)
abs_diff_eq!(v.norm_squared(), T::one(), epsilon = epsilon * 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 {
abs_diff_eq!(v.norm_squared(), T::zero(), epsilon = epsilon * epsilon)
pub fn is_null<T: Number, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
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 type names use `CamelCase`, which is the Rust convention.
* 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
functions are available.
* 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.
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 on vectors will often end with the `_vec` suffix, possibly followed by the dimension of vector, e.g., [`glm::rotate_vec2()`](crate::rotate_vec2).
* Every function related to quaternions start with the `quat_` prefix, e.g., [`glm::quat_dot(q1, q2)`](crate::quat_dot).
* 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`](fn.rotate_vec2.html).
* 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).
### Vector and matrix construction
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 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.
* 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.
### Swizzling
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
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`.
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.
* 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:
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`.

View File

@ -1,17 +1,18 @@
use approx::AbsDiffEq;
use num::{Bounded, Signed};
use core::cmp::PartialOrd;
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.
pub trait Number:
Scalar
+ Copy
+ PartialOrd
+ ClosedAddAssign
+ ClosedSubAssign
+ ClosedMulAssign
+ ClosedAdd
+ ClosedSub
+ ClosedMul
+ AbsDiffEq<Epsilon = Self>
+ Signed
+ Bounded
@ -22,9 +23,9 @@ impl<
T: Scalar
+ Copy
+ PartialOrd
+ ClosedAddAssign
+ ClosedSubAssign
+ ClosedMulAssign
+ ClosedAdd
+ ClosedSub
+ ClosedMul
+ AbsDiffEq<Epsilon = Self>
+ Signed
+ Bounded,

View File

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

View File

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

View File

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

View File

@ -15,32 +15,32 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<D>,
serde(bound(serialize = "DefaultAllocator: Allocator<T, D>,
OMatrix<T, D, D>: Serialize"))
)]
#[cfg_attr(
feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<D>,
serde(bound(deserialize = "DefaultAllocator: Allocator<T, D>,
OMatrix<T, D, D>: Deserialize<'de>"))
)]
#[derive(Clone, Debug)]
pub struct Cholesky<T: Scalar, D: Dim>
where
DefaultAllocator: Allocator<D, D>,
DefaultAllocator: Allocator<T, D, D>,
{
l: OMatrix<T, D, D>,
}
impl<T: Scalar + Copy, D: Dim> Copy for Cholesky<T, D>
where
DefaultAllocator: Allocator<D, D>,
DefaultAllocator: Allocator<T, D, D>,
OMatrix<T, D, D>: Copy,
{
}
impl<T: CholeskyScalar + Zero, D: Dim> Cholesky<T, D>
where
DefaultAllocator: Allocator<D, D>,
DefaultAllocator: Allocator<T, D, D>,
{
/// Computes the cholesky decomposition of the given symmetric-definite-positive square
/// matrix.
@ -105,7 +105,7 @@ where
) -> Option<OMatrix<T, R2, C2>>
where
S2: Storage<T, R2, C2>,
DefaultAllocator: Allocator<R2, C2>,
DefaultAllocator: Allocator<T, R2, C2>,
{
let mut res = b.clone_owned();
if self.solve_mut(&mut res) {
@ -119,7 +119,7 @@ where
/// the unknown to be determined.
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
where
DefaultAllocator: Allocator<R2, C2>,
DefaultAllocator: Allocator<T, R2, C2>,
{
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",
serde(bound(serialize = "DefaultAllocator: Allocator<D, D> + Allocator<D>,
serde(
bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Serialize,
OMatrix<T, D, D>: Serialize"))
OMatrix<T, D, D>: Serialize")
)
)]
#[cfg_attr(
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,
OMatrix<T, D, D>: Deserialize<'de>"))
OMatrix<T, D, D>: Deserialize<'de>")
)
)]
#[derive(Clone, Debug)]
pub struct Eigen<T: Scalar, D: Dim>
where
DefaultAllocator: Allocator<D> + Allocator<D, D>,
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{
/// The real parts of eigenvalues of the decomposed matrix.
pub eigenvalues_re: OVector<T, D>,
@ -43,7 +47,7 @@ where
impl<T: Scalar + Copy, D: Dim> Copy for Eigen<T, D>
where
DefaultAllocator: Allocator<D> + Allocator<D, D>,
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
OVector<T, D>: Copy,
OMatrix<T, D, D>: Copy,
{
@ -51,7 +55,7 @@ where
impl<T: EigenScalar + RealField, D: Dim> Eigen<T, D>
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`.
///
@ -173,7 +177,7 @@ where
Option<Vec<OVector<T, D>>>,
)
where
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<T, D>,
{
let (number_of_elements, _) = self.eigenvalues_re.shape_generic();
let number_of_elements_value = number_of_elements.value();
@ -196,16 +200,17 @@ where
eigenvalues.push(self.eigenvalues_re[c].clone());
if eigenvectors.is_some() {
eigenvectors
.as_mut()
.unwrap()
.push(self.eigenvectors.as_ref().unwrap().column(c).into_owned());
eigenvectors.as_mut().unwrap().push(
(&self.eigenvectors.as_ref())
.unwrap()
.column(c)
.into_owned(),
);
}
if left_eigenvectors.is_some() {
left_eigenvectors.as_mut().unwrap().push(
self.left_eigenvectors
.as_ref()
(&self.left_eigenvectors.as_ref())
.unwrap()
.column(c)
.into_owned(),
@ -230,7 +235,7 @@ where
Option<Vec<OVector<Complex<T>, D>>>,
)
where
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<Complex<T>, D>,
{
match self.eigenvalues_are_real() {
true => (None, None, None),
@ -280,12 +285,12 @@ where
for r in 0..number_of_elements_value {
vec[r] = Complex::<T>::new(
self.eigenvectors.as_ref().unwrap()[(r, c)].clone(),
self.eigenvectors.as_ref().unwrap()[(r, c + 1)].clone(),
(&self.eigenvectors.as_ref()).unwrap()[(r, c)].clone(),
(&self.eigenvectors.as_ref()).unwrap()[(r, c + 1)].clone(),
);
vec_conj[r] = Complex::<T>::new(
self.eigenvectors.as_ref().unwrap()[(r, c)].clone(),
self.eigenvectors.as_ref().unwrap()[(r, c + 1)].clone(),
(&self.eigenvectors.as_ref()).unwrap()[(r, c)].clone(),
(&self.eigenvectors.as_ref()).unwrap()[(r, c + 1)].clone(),
);
}
@ -305,12 +310,12 @@ where
for r in 0..number_of_elements_value {
vec[r] = Complex::<T>::new(
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)].clone(),
(&self.left_eigenvectors.as_ref()).unwrap()[(r, c + 1)].clone(),
);
vec_conj[r] = Complex::<T>::new(
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)].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",
serde(bound(serialize = "DefaultAllocator: Allocator<D, D> + Allocator<D>,
serde(
bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Serialize,
OMatrix<T, D, D>: Serialize"))
OMatrix<T, D, D>: Serialize")
)
)]
#[cfg_attr(
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>,
OMatrix<T, D, D>: Deserialize<'de>"))
OMatrix<T, D, D>: Deserialize<'de>")
)
)]
#[derive(Clone, Debug)]
pub struct GeneralizedEigen<T: Scalar, D: Dim>
where
DefaultAllocator: Allocator<D> + Allocator<D, D>,
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{
alphar: OVector<T, D>,
alphai: OVector<T, D>,
@ -54,7 +58,7 @@ where
impl<T: Scalar + Copy, D: Dim> Copy for GeneralizedEigen<T, D>
where
DefaultAllocator: Allocator<D, D> + Allocator<D>,
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OMatrix<T, D, D>: Copy,
OVector<T, D>: Copy,
{
@ -62,7 +66,7 @@ where
impl<T: GeneralizedEigenScalar + RealField + Copy, D: Dim> GeneralizedEigen<T, D>
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
/// via the raw returns from LAPACK's dggev and sggev routines
@ -158,7 +162,8 @@ where
/// as columns.
pub fn eigenvectors(&self) -> (OMatrix<Complex<T>, D, D>, OMatrix<Complex<T>, D, D>)
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:
@ -225,7 +230,7 @@ where
#[must_use]
pub fn raw_eigenvalues(&self) -> OVector<(Complex<T>, T), D>
where
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<(Complex<T>, T), D>,
{
let mut out = Matrix::from_element_generic(
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",
serde(bound(serialize = "DefaultAllocator: Allocator<D, D> +
Allocator<DimDiff<D, U1>>,
serde(bound(serialize = "DefaultAllocator: Allocator<T, D, D> +
Allocator<T, DimDiff<D, U1>>,
OMatrix<T, D, D>: Serialize,
OVector<T, DimDiff<D, U1>>: Serialize"))
)]
#[cfg_attr(
feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<D, D> +
Allocator<DimDiff<D, U1>>,
serde(bound(deserialize = "DefaultAllocator: Allocator<T, D, D> +
Allocator<T, DimDiff<D, U1>>,
OMatrix<T, D, D>: Deserialize<'de>,
OVector<T, DimDiff<D, U1>>: Deserialize<'de>"))
)]
#[derive(Clone, Debug)]
pub struct Hessenberg<T: Scalar, D: DimSub<U1>>
where
DefaultAllocator: Allocator<D, D> + Allocator<DimDiff<D, U1>>,
DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
{
h: OMatrix<T, D, D>,
tau: OVector<T, DimDiff<D, U1>>,
@ -35,7 +35,7 @@ where
impl<T: Scalar + Copy, D: DimSub<U1>> Copy for Hessenberg<T, D>
where
DefaultAllocator: Allocator<D, D> + Allocator<DimDiff<D, U1>>,
DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
OMatrix<T, D, D>: Copy,
OVector<T, DimDiff<D, U1>>: Copy,
{
@ -43,7 +43,7 @@ where
impl<T: HessenbergScalar + Zero, D: DimSub<U1>> Hessenberg<T, D>
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`.
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>
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.
#[inline]

View File

@ -20,22 +20,22 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<R, C> +
Allocator<DimMinimum<R, C>>,
serde(bound(serialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<i32, DimMinimum<R, C>>,
OMatrix<T, R, C>: Serialize,
PermutationSequence<DimMinimum<R, C>>: Serialize"))
)]
#[cfg_attr(
feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<R, C> +
Allocator<DimMinimum<R, C>>,
serde(bound(deserialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<i32, DimMinimum<R, C>>,
OMatrix<T, R, C>: Deserialize<'de>,
PermutationSequence<DimMinimum<R, C>>: Deserialize<'de>"))
)]
#[derive(Clone, Debug)]
pub struct LU<T: Scalar, R: DimMin<C>, C: Dim>
where
DefaultAllocator: Allocator<DimMinimum<R, C>> + Allocator<R, C>,
DefaultAllocator: Allocator<i32, DimMinimum<R, C>> + Allocator<T, R, C>,
{
lu: OMatrix<T, 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>
where
DefaultAllocator: Allocator<R, C> + Allocator<DimMinimum<R, C>>,
DefaultAllocator: Allocator<T, R, C> + Allocator<i32, DimMinimum<R, C>>,
OMatrix<T, 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
T: Zero + One,
R: DimMin<C>,
DefaultAllocator: Allocator<R, C>
+ Allocator<R, R>
+ Allocator<R, DimMinimum<R, C>>
+ Allocator<DimMinimum<R, C>, C>
+ Allocator<DimMinimum<R, C>>,
DefaultAllocator: Allocator<T, R, C>
+ Allocator<T, R, R>
+ Allocator<T, R, DimMinimum<R, C>>
+ Allocator<T, DimMinimum<R, C>, C>
+ Allocator<i32, DimMinimum<R, C>>,
{
/// Computes the LU decomposition with partial (row) pivoting of `matrix`.
pub fn new(mut m: OMatrix<T, R, C>) -> Self {
@ -136,7 +136,7 @@ where
#[inline]
pub fn permute<C2: Dim>(&self, rhs: &mut OMatrix<T, R, C2>)
where
DefaultAllocator: Allocator<R, C2>,
DefaultAllocator: Allocator<T, R, C2>,
{
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
where
DefaultAllocator: Allocator<R2, C2> + Allocator<R2>,
DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{
let dim = self.lu.nrows();
@ -192,7 +192,7 @@ where
) -> Option<OMatrix<T, R2, C2>>
where
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();
if self.generic_solve_mut(b'T', &mut res) {
@ -210,7 +210,7 @@ where
) -> Option<OMatrix<T, R2, C2>>
where
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();
if self.generic_solve_mut(b'T', &mut res) {
@ -228,7 +228,7 @@ where
) -> Option<OMatrix<T, R2, C2>>
where
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();
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).
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
where
DefaultAllocator: Allocator<R2, C2> + Allocator<R2>,
DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{
self.generic_solve_mut(b'T', b)
}
@ -254,7 +254,7 @@ where
/// 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
where
DefaultAllocator: Allocator<R2, C2> + Allocator<R2>,
DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{
self.generic_solve_mut(b'T', b)
}
@ -265,7 +265,7 @@ where
/// 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
where
DefaultAllocator: Allocator<R2, C2> + Allocator<R2>,
DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{
self.generic_solve_mut(b'T', b)
}
@ -275,7 +275,7 @@ impl<T: LUScalar, D: Dim> LU<T, D, D>
where
T: Zero + One,
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.
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",
serde(bound(serialize = "DefaultAllocator: Allocator<R, C> +
Allocator<DimMinimum<R, C>>,
serde(bound(serialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<T, DimMinimum<R, C>>,
OMatrix<T, R, C>: Serialize,
OVector<T, DimMinimum<R, C>>: Serialize"))
)]
#[cfg_attr(
feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<R, C> +
Allocator<DimMinimum<R, C>>,
serde(bound(deserialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<T, DimMinimum<R, C>>,
OMatrix<T, R, C>: Deserialize<'de>,
OVector<T, DimMinimum<R, C>>: Deserialize<'de>"))
)]
#[derive(Clone, Debug)]
pub struct QR<T: Scalar, R: DimMin<C>, C: Dim>
where
DefaultAllocator: Allocator<R, C> + Allocator<DimMinimum<R, C>>,
DefaultAllocator: Allocator<T, R, C> + Allocator<T, DimMinimum<R, C>>,
{
qr: OMatrix<T, 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>
where
DefaultAllocator: Allocator<R, C> + Allocator<DimMinimum<R, C>>,
DefaultAllocator: Allocator<T, R, C> + Allocator<T, DimMinimum<R, C>>,
OMatrix<T, 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>
where
DefaultAllocator: Allocator<R, C>
+ Allocator<R, DimMinimum<R, C>>
+ Allocator<DimMinimum<R, C>, C>
+ Allocator<DimMinimum<R, C>>,
DefaultAllocator: Allocator<T, R, C>
+ Allocator<T, R, DimMinimum<R, C>>
+ Allocator<T, DimMinimum<R, C>, C>
+ Allocator<T, DimMinimum<R, C>>,
{
/// Computes the QR decomposition of the matrix `m`.
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>
where
DefaultAllocator: Allocator<R, C>
+ Allocator<R, DimMinimum<R, C>>
+ Allocator<DimMinimum<R, C>, C>
+ Allocator<DimMinimum<R, C>>,
DefaultAllocator: Allocator<T, R, C>
+ Allocator<T, R, DimMinimum<R, C>>
+ Allocator<T, DimMinimum<R, C>, C>
+ Allocator<T, DimMinimum<R, C>>,
{
/// Retrieves the matrices `(Q, R)` of this decompositions.
pub fn unpack(

View File

@ -22,20 +22,24 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
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,
OMatrix<T, D, D>: Serialize"))
OMatrix<T, D, D>: Serialize")
)
)]
#[cfg_attr(
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>,
OMatrix<T, D, D>: Deserialize<'de>"))
OMatrix<T, D, D>: Deserialize<'de>")
)
)]
#[derive(Clone, Debug)]
pub struct QZ<T: Scalar, D: Dim>
where
DefaultAllocator: Allocator<D> + Allocator<D, D>,
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{
alphar: OVector<T, D>,
alphai: OVector<T, D>,
@ -48,7 +52,7 @@ where
impl<T: Scalar + Copy, D: Dim> Copy for QZ<T, D>
where
DefaultAllocator: Allocator<D, D> + Allocator<D>,
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OMatrix<T, D, D>: Copy,
OVector<T, D>: Copy,
{
@ -56,7 +60,7 @@ where
impl<T: QZScalar + RealField, D: Dim> QZ<T, D>
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`.
///
@ -178,7 +182,7 @@ where
#[must_use]
pub fn raw_eigenvalues(&self) -> OVector<(Complex<T>, T), D>
where
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<(Complex<T>, T), D>,
{
let mut out = Matrix::from_element_generic(
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",
serde(bound(serialize = "DefaultAllocator: Allocator<D, D> + Allocator<D>,
serde(
bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Serialize,
OMatrix<T, D, D>: Serialize"))
OMatrix<T, D, D>: Serialize")
)
)]
#[cfg_attr(
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,
OMatrix<T, D, D>: Deserialize<'de>"))
OMatrix<T, D, D>: Deserialize<'de>")
)
)]
#[derive(Clone, Debug)]
pub struct Schur<T: Scalar, D: Dim>
where
DefaultAllocator: Allocator<D> + Allocator<D, D>,
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{
re: OVector<T, D>,
im: OVector<T, D>,
@ -40,7 +44,7 @@ where
impl<T: Scalar + Copy, D: Dim> Copy for Schur<T, D>
where
DefaultAllocator: Allocator<D, D> + Allocator<D>,
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OMatrix<T, D, D>: Copy,
OVector<T, D>: Copy,
{
@ -48,7 +52,7 @@ where
impl<T: SchurScalar + RealField, D: Dim> Schur<T, D>
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`.
///
@ -146,7 +150,7 @@ where
#[must_use]
pub fn complex_eigenvalues(&self) -> OVector<Complex<T>, D>
where
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<Complex<T>, D>,
{
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",
serde(bound(serialize = "DefaultAllocator: Allocator<DimMinimum<R, C>> +
Allocator<R, R> +
Allocator<C, C>,
serde(bound(serialize = "DefaultAllocator: Allocator<T, DimMinimum<R, C>> +
Allocator<T, R, R> +
Allocator<T, C, C>,
OMatrix<T, R>: Serialize,
OMatrix<T, C>: Serialize,
OVector<T, DimMinimum<R, C>>: Serialize"))
)]
#[cfg_attr(
feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<DimMinimum<R, C>> +
Allocator<R, R> +
Allocator<C, C>,
serde(bound(serialize = "DefaultAllocator: Allocator<T, DimMinimum<R, C>> +
Allocator<T, R, R> +
Allocator<T, C, C>,
OMatrix<T, R>: Deserialize<'de>,
OMatrix<T, C>: Deserialize<'de>,
OVector<T, DimMinimum<R, C>>: Deserialize<'de>"))
@ -33,7 +33,7 @@ use lapack;
#[derive(Clone, Debug)]
pub struct SVD<T: Scalar, R: DimMin<C>, C: Dim>
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.
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>
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, C, C>: Copy,
OVector<T, DimMinimum<R, C>>: Copy,
@ -56,8 +56,10 @@ where
/// supported by the Singular Value Decompotition.
pub trait SVDScalar<R: DimMin<C>, C: Dim>: Scalar
where
DefaultAllocator:
Allocator<R, R> + Allocator<R, C> + Allocator<DimMinimum<R, C>> + Allocator<C, C>,
DefaultAllocator: Allocator<Self, R, R>
+ Allocator<Self, R, C>
+ Allocator<Self, DimMinimum<R, C>>
+ Allocator<Self, C, C>,
{
/// Computes the SVD decomposition of `m`.
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>
where
DefaultAllocator:
Allocator<R, R> + Allocator<R, C> + Allocator<DimMinimum<R, C>> + Allocator<C, C>,
DefaultAllocator: Allocator<T, R, R>
+ Allocator<T, R, C>
+ Allocator<T, DimMinimum<R, C>>
+ Allocator<T, C, C>,
{
/// Computes the Singular Value Decomposition of `matrix`.
pub fn new(m: OMatrix<T, R, C>) -> Option<Self> {
@ -78,10 +82,10 @@ macro_rules! svd_impl(
($t: ty, $lapack_func: path) => (
impl<R: Dim, C: Dim> SVDScalar<R, C> for $t
where R: DimMin<C>,
DefaultAllocator: Allocator<R, C> +
Allocator<R, R> +
Allocator<C, C> +
Allocator<DimMinimum<R, C>> {
DefaultAllocator: Allocator<$t, R, C> +
Allocator<$t, R, R> +
Allocator<$t, C, C> +
Allocator<$t, DimMinimum<R, C>> {
fn compute(mut m: OMatrix<$t, R, C>) -> Option<SVD<$t, R, C>> {
let (nrows, ncols) = m.shape_generic();
@ -130,16 +134,16 @@ macro_rules! svd_impl(
impl<R: DimMin<C>, C: Dim> SVD<$t, R, C>
// TODO: All those bounds…
where DefaultAllocator: Allocator<R, C> +
Allocator<C, R> +
Allocator<U1, R> +
Allocator<U1, C> +
Allocator<R, R> +
Allocator<DimMinimum<R, C>> +
Allocator<DimMinimum<R, C>, R> +
Allocator<DimMinimum<R, C>, C> +
Allocator<R, DimMinimum<R, C>> +
Allocator<C, C> {
where DefaultAllocator: Allocator<$t, R, C> +
Allocator<$t, C, R> +
Allocator<$t, U1, R> +
Allocator<$t, U1, C> +
Allocator<$t, R, R> +
Allocator<$t, DimMinimum<R, C>> +
Allocator<$t, DimMinimum<R, C>, R> +
Allocator<$t, DimMinimum<R, C>, C> +
Allocator<$t, R, DimMinimum<R, C>> +
Allocator<$t, C, C> {
/// Reconstructs the matrix from its decomposition.
///
/// 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>,
S: ContiguousStorage<Complex<$t>, R, C>,
S::Alloc: OwnedAllocator<Complex<$t>, R, C, S> +
Allocator<R, R> +
Allocator<C, C> +
Allocator<DimMinimum<R, C>> {
Allocator<Complex<$t>, R, R> +
Allocator<Complex<$t>, C, C> +
Allocator<$t, DimMinimum<R, C>> {
let (nrows, ncols) = m.shape_generic();
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",
serde(bound(serialize = "DefaultAllocator: Allocator<D, D> +
Allocator<D>,
serde(bound(serialize = "DefaultAllocator: Allocator<T, D, D> +
Allocator<T, D>,
OVector<T, D>: Serialize,
OMatrix<T, D, D>: Serialize"))
)]
#[cfg_attr(
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>,
OMatrix<T, D, D>: Deserialize<'de>"))
)]
#[derive(Clone, Debug)]
pub struct SymmetricEigen<T: Scalar, D: Dim>
where
DefaultAllocator: Allocator<D> + Allocator<D, D>,
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{
/// The eigenvectors of the decomposed matrix.
pub eigenvectors: OMatrix<T, D, D>,
@ -43,7 +43,7 @@ where
impl<T: Scalar + Copy, D: Dim> Copy for SymmetricEigen<T, D>
where
DefaultAllocator: Allocator<D, D> + Allocator<D>,
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OMatrix<T, D, D>: Copy,
OVector<T, D>: Copy,
{
@ -51,7 +51,7 @@ where
impl<T: SymmetricEigenScalar + RealField, D: Dim> SymmetricEigen<T, D>
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`.
///

View File

@ -1,24 +1,25 @@
[package]
name = "nalgebra-macros"
version = "0.2.2"
authors = ["Andreas Longva", "Sébastien Crozet <developer@crozet.re>"]
version = "0.2.1"
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
edition = "2018"
description = "Procedural macros for nalgebra"
documentation = "https://www.nalgebra.org/docs"
homepage = "https://nalgebra.org"
repository = "https://github.com/dimforge/nalgebra"
readme = "../README.md"
categories = ["science", "mathematics"]
keywords = ["linear", "algebra", "matrix", "vector", "math"]
categories = [ "science", "mathematics" ]
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
license = "Apache-2.0"
[lib]
proc-macro = true
[dependencies]
syn = { version = "2.0", features = ["full"] }
syn = { version="1.0", features = ["full"] }
quote = "1.0"
proc-macro2 = "1.0"
[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,
missing_copy_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 quote::quote;
use stack_impl::stack_impl;
use syn::parse_macro_input;
use quote::{quote, ToTokens, TokenStreamExt};
use syn::parse::{Error, Parse, ParseStream, Result};
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.
///
@ -62,7 +145,20 @@ use syn::parse_macro_input;
/// ```
#[proc_macro]
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.
@ -84,7 +180,55 @@ pub fn matrix(stream: TokenStream) -> TokenStream {
/// ```
#[proc_macro]
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.
@ -108,7 +252,14 @@ pub fn dmatrix(stream: TokenStream) -> TokenStream {
/// ```
#[proc_macro]
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.
@ -128,7 +279,17 @@ pub fn vector(stream: TokenStream) -> TokenStream {
/// ```
#[proc_macro]
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.
@ -160,100 +321,3 @@ pub fn point(stream: TokenStream) -> TokenStream {
};
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::{
DMatrix, DVector, Matrix1x2, Matrix1x3, Matrix1x4, Matrix2, Matrix2x1, Matrix2x3, Matrix2x4,
Matrix3, Matrix3x1, Matrix3x2, Matrix3x4, Matrix4, Matrix4x1, Matrix4x2, Matrix4x3, Point,
@ -7,6 +6,16 @@ use nalgebra::{
};
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
#[rustfmt::skip]
#[test]
@ -160,7 +169,7 @@ fn matrix_trybuild_tests() {
let t = trybuild::TestCases::new();
// 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]
@ -168,7 +177,7 @@ fn dmatrix_trybuild_tests() {
let t = trybuild::TestCases::new();
// 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]
@ -279,7 +288,7 @@ fn dmatrix_arbitrary_expressions() {
let a = dmatrix![1 + 2 , 2 * 3;
4 * f(5 + 6), 7 - 8 * 9];
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);
}

View File

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

View File

@ -1,5 +1,5 @@
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];
| ^

View File

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

View File

@ -1,5 +1,5 @@
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];
| ^

View File

@ -1,44 +1,44 @@
[package]
name = "nalgebra-sparse"
version = "0.10.0"
authors = ["Andreas Longva", "Sébastien Crozet <developer@crozet.re>"]
version = "0.9.0"
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
edition = "2018"
description = "Sparse matrix computation based on nalgebra."
documentation = "https://www.nalgebra.org/docs"
homepage = "https://nalgebra.org"
repository = "https://github.com/dimforge/nalgebra"
readme = "../README.md"
categories = ["science", "mathematics", "wasm", "no-std"]
keywords = ["linear", "algebra", "matrix", "vector", "math"]
categories = [ "science", "mathematics", "wasm", "no-std" ]
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
license = "Apache-2.0"
[features]
proptest-support = ["proptest", "nalgebra/proptest-support"]
compare = ["matrixcompare-core"]
serde-serialize = ["serde/std"]
compare = [ "matrixcompare-core" ]
serde-serialize = [ "serde/std" ]
# 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
slow-tests = []
[dependencies]
nalgebra = { version = "0.33", path = "../" }
nalgebra = { version="0.32", path = "../" }
num-traits = { version = "0.2", default-features = false }
proptest = { version = "1.0", optional = true }
matrixcompare-core = { version = "0.1.0", optional = true }
pest = { version = "2", optional = true }
pest_derive = { version = "2", optional = true }
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
pest = { version = "2", optional = true }
pest_derive = { version = "2", optional = true }
serde = { version = "1.0", default-features = false, features = [ "derive" ], optional = true }
[dev-dependencies]
itertools = "0.13"
matrixcompare = { version = "0.3.0", features = ["proptest-support"] }
nalgebra = { version = "0.33", path = "../", features = ["compare"] }
itertools = "0.10"
matrixcompare = { version = "0.3.0", features = [ "proptest-support" ] }
nalgebra = { version="0.32", path = "../", features = ["compare"] }
tempfile = "3.3"
serde_json = "1.0"
[package.metadata.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::csr::CsrMatrix;
use nalgebra::storage::RawStorage;
use nalgebra::{ClosedAddAssign, DMatrix, Dim, Matrix, Scalar};
use nalgebra::{ClosedAdd, DMatrix, Dim, Matrix, Scalar};
use num_traits::Zero;
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>
where
T: Scalar + Zero + ClosedAddAssign,
T: Scalar + Zero + ClosedAdd,
{
fn from(coo: &'a CooMatrix<T>) -> Self {
convert_coo_dense(coo)
@ -29,7 +29,7 @@ where
impl<'a, T> From<&'a CooMatrix<T>> for CsrMatrix<T>
where
T: Scalar + Zero + ClosedAddAssign,
T: Scalar + Zero + ClosedAdd,
{
fn from(matrix: &'a CooMatrix<T>) -> Self {
convert_coo_csr(matrix)
@ -38,7 +38,7 @@ where
impl<'a, T> From<&'a CsrMatrix<T>> for CooMatrix<T>
where
T: Scalar + Zero + ClosedAddAssign,
T: Scalar + Zero + ClosedAdd,
{
fn from(matrix: &'a CsrMatrix<T>) -> Self {
convert_csr_coo(matrix)
@ -59,7 +59,7 @@ where
impl<'a, T> From<&'a CsrMatrix<T>> for DMatrix<T>
where
T: Scalar + Zero + ClosedAddAssign,
T: Scalar + Zero + ClosedAdd,
{
fn from(matrix: &'a CsrMatrix<T>) -> Self {
convert_csr_dense(matrix)
@ -68,7 +68,7 @@ where
impl<'a, T> From<&'a CooMatrix<T>> for CscMatrix<T>
where
T: Scalar + Zero + ClosedAddAssign,
T: Scalar + Zero + ClosedAdd,
{
fn from(matrix: &'a CooMatrix<T>) -> Self {
convert_coo_csc(matrix)
@ -98,7 +98,7 @@ where
impl<'a, T> From<&'a CscMatrix<T>> for DMatrix<T>
where
T: Scalar + Zero + ClosedAddAssign,
T: Scalar + Zero + ClosedAdd,
{
fn from(matrix: &'a CscMatrix<T>) -> Self {
convert_csc_dense(matrix)

View File

@ -8,7 +8,7 @@ use std::ops::Add;
use num_traits::Zero;
use nalgebra::storage::RawStorage;
use nalgebra::{ClosedAddAssign, DMatrix, Dim, Matrix, Scalar};
use nalgebra::{ClosedAdd, DMatrix, Dim, Matrix, Scalar};
use crate::coo::CooMatrix;
use crate::cs;
@ -41,7 +41,7 @@ where
/// Converts a [`CooMatrix`] to a dense matrix.
pub fn convert_coo_dense<T>(coo: &CooMatrix<T>) -> DMatrix<T>
where
T: Scalar + Zero + ClosedAddAssign,
T: Scalar + Zero + ClosedAdd,
{
let mut output = DMatrix::repeat(coo.nrows(), coo.ncols(), T::zero());
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.
pub fn convert_csr_dense<T>(csr: &CsrMatrix<T>) -> DMatrix<T>
where
T: Scalar + ClosedAddAssign + Zero,
T: Scalar + ClosedAdd + Zero,
{
let mut output = DMatrix::zeros(csr.nrows(), csr.ncols());
@ -157,7 +157,7 @@ where
/// Converts a [`CscMatrix`] to a dense matrix.
pub fn convert_csc_dense<T>(csc: &CscMatrix<T>) -> DMatrix<T>
where
T: Scalar + ClosedAddAssign + Zero,
T: Scalar + ClosedAdd + Zero,
{
let mut output = DMatrix::zeros(csc.nrows(), csc.ncols());
@ -306,7 +306,7 @@ where
|val| sorted_vals.push(val),
&idx_workspace[..count],
&values_workspace[..count],
Add::add,
&Add::add,
);
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).
// TODO: Consider giving the iterator a concrete type instead of impl trait...?
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 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> {
#[inline]
pub fn identity(n: usize) -> Self {
@ -368,7 +360,7 @@ where
if let Some(minor_indices) = lane {
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);
self.remaining_values = remaining;
self.current_lane_idx += 1;
@ -577,7 +569,7 @@ where
} else if sort {
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(
SparseFormatErrorKind::InvalidStructure,
"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(
SparseFormatErrorKind::IndexOutOfBounds,
"A major offset is out of bounds.",
)
})?;
),
)?;
// We test for in-bounds, uniqueness and monotonicity at the same time
// to ensure that we only visit each minor index once
@ -661,9 +653,9 @@ where
if !monotonic && sort {
let range_size = range_end - range_start;
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.extend_from_slice(minor_idx_in_lane);
minor_idx_buffer.extend_from_slice(&minor_idx_in_lane);
apply_permutation(
&mut minor_indices[range_start..range_end],
&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 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(
num_rows: 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
/// 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(
num_rows: 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.
///
/// 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>,
}
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> {
/// 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> {
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> {
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 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(
num_rows: 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
/// 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(
num_rows: 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.
///
/// 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>,
}
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> {
/// 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> {
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> {
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]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SparseFormatErrorKind {

View File

@ -10,8 +10,8 @@ use nalgebra::allocator::Allocator;
use nalgebra::base::storage::RawStorage;
use nalgebra::constraint::{DimEq, ShapeConstraint};
use nalgebra::{
ClosedAddAssign, ClosedDivAssign, ClosedMulAssign, ClosedSubAssign, DefaultAllocator, Dim, Dyn,
Matrix, OMatrix, Scalar, U1,
ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dyn, Matrix, OMatrix,
Scalar, U1,
};
use num_traits::{One, Zero};
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.
// Sub to SpAdd with negative coefficients. This is not well-defined for
// 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;
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)
.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
});
@ -164,7 +164,7 @@ macro_rules! impl_scalar_mul {
impl<T> MulAssign<T> for $matrix_type<T>
where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One
T: Scalar + ClosedAdd + ClosedMul + Zero + One
{
fn mul_assign(&mut self, scalar: T) {
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>
where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One
T: Scalar + ClosedAdd + ClosedMul + Zero + One
{
fn mul_assign(&mut self, scalar: &'a T) {
for val in self.values_mut() {
@ -227,15 +227,15 @@ impl_neg!(CscMatrix);
macro_rules! impl_div {
($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;
matrix /= scalar;
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()
});
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()
.iter()
.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)
.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()
});
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) {
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>
where T : Scalar + ClosedAddAssign + ClosedMulAssign + ClosedDivAssign + Zero + One
where T : Scalar + ClosedAdd + ClosedMul + ClosedDiv + Zero + One
{
fn div_assign(&mut self, scalar: &'a T) {
*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
where
T: Scalar + ClosedMulAssign + ClosedAddAssign + ClosedSubAssign + ClosedDivAssign + Neg + Zero + One,
T: Scalar + ClosedMul + ClosedAdd + ClosedSub + ClosedDiv + Neg + Zero + One,
R: Dim,
C: Dim,
S: RawStorage<T, R, C>,
DefaultAllocator: Allocator<Dyn, C>,
DefaultAllocator: Allocator<T, Dyn, C>,
// TODO: Is it possible to simplify these bounds?
ShapeConstraint:
// 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<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
+ DimEq<U1, S::RStride>
+ DimEq<R, Dyn>

View File

@ -149,8 +149,8 @@ impl<T> Op<T> {
#[must_use]
pub fn as_ref(&self) -> Op<&T> {
match self {
Op::NoOp(obj) => Op::NoOp(obj),
Op::Transpose(obj) => Op::Transpose(obj),
Op::NoOp(obj) => Op::NoOp(&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::Op;
use crate::SparseEntryMut;
use nalgebra::{ClosedAddAssign, ClosedMulAssign, DMatrixView, DMatrixViewMut, Scalar};
use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, Scalar};
use num_traits::{One, Zero};
fn spmm_cs_unexpected_entry() -> OperationError {
@ -28,7 +28,7 @@ pub fn spmm_cs_prealloc_unchecked<T>(
b: &CsMatrix<T>,
) -> Result<(), OperationError>
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().minor_dim(), b.pattern().minor_dim());
@ -73,7 +73,7 @@ pub fn spmm_cs_prealloc<T>(
b: &CsMatrix<T>,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One,
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
for i in 0..c.pattern().major_dim() {
let a_lane_i = a.get_lane(i).unwrap();
@ -119,7 +119,7 @@ pub fn spadd_cs_prealloc<T>(
a: Op<&CsMatrix<T>>,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One,
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
match a {
Op::NoOp(a) => {
@ -181,7 +181,7 @@ pub fn spmm_cs_dense<T>(
a: Op<&CsMatrix<T>>,
b: Op<DMatrixView<'_, T>>,
) where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One,
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
match a {
Op::NoOp(a) => {

View File

@ -4,7 +4,7 @@ use crate::ops::serial::cs::{
};
use crate::ops::serial::{OperationError, OperationErrorKind};
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 std::borrow::Cow;
@ -21,7 +21,7 @@ pub fn spmm_csc_dense<'a, T>(
a: Op<&CscMatrix<T>>,
b: Op<impl Into<DMatrixView<'a, T>>>,
) where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One,
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
let b = b.convert();
spmm_csc_dense_(beta, c.into(), alpha, a, b)
@ -34,7 +34,7 @@ fn spmm_csc_dense_<T>(
a: Op<&CscMatrix<T>>,
b: Op<DMatrixView<'_, T>>,
) where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One,
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
assert_compatible_spmm_dims!(c, a, b);
// 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>>,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One,
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
assert_compatible_spadd_dims!(c, a);
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>>,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One,
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
assert_compatible_spmm_dims!(c, a, b);
use Op::NoOp;
match (&a, &b) {
(NoOp(a), NoOp(b)) => {
(NoOp(ref a), NoOp(ref b)) => {
// Note: We have to reverse the order for CSC matrices
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>>,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One,
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
assert_compatible_spmm_dims!(c, a, b);
use Op::NoOp;
match (&a, &b) {
(NoOp(a), NoOp(b)) => {
(NoOp(ref a), NoOp(ref b)) => {
// Note: We have to reverse the order for CSC matrices
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,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAddAssign + ClosedMulAssign + Zero + One,
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
F: Fn(
T,
&mut CscMatrix<T>,
@ -152,9 +152,9 @@ where
use Cow::*;
match (&a, &b) {
(NoOp(_), NoOp(_)) => unreachable!(),
(Transpose(a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
(NoOp(_), Transpose(b)) => (Borrowed(a_ref), Owned(b.transpose())),
(Transpose(a), Transpose(b)) => (Owned(a.transpose()), Owned(b.transpose())),
(Transpose(ref a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
(NoOp(_), Transpose(ref b)) => (Borrowed(a_ref), 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()))

View File

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

View File

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

View File

@ -80,7 +80,7 @@ impl SparsityPattern {
#[inline]
#[must_use]
pub fn major_dim(&self) -> usize {
assert!(!self.major_offsets.is_empty());
assert!(self.major_offsets.len() > 0);
self.major_offsets.len() - 1
}
@ -162,7 +162,7 @@ impl SparsityPattern {
// We test for in-bounds, uniqueness and monotonicity at the same time
// to ensure that we only visit each minor index once
let mut iter = minor_indices.iter();
let mut prev: Option<usize> = None;
let mut prev = None;
while let Some(next) = iter.next().copied() {
if next >= minor_dim {
@ -170,10 +170,10 @@ impl SparsityPattern {
}
if let Some(prev) = prev {
match prev.cmp(&next) {
std::cmp::Ordering::Greater => return Err(NonmonotonicMinorIndices),
std::cmp::Ordering::Equal => return Err(DuplicateEntry),
std::cmp::Ordering::Less => {}
if prev > next {
return Err(NonmonotonicMinorIndices);
} else if prev == next {
return Err(DuplicateEntry);
}
}
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
/// 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(
major_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.
#[non_exhaustive]
#[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]
fn coo_try_from_triplets_panics_on_mismatched_vectors() {
// 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;
#[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]
fn csc_matrix_valid_data() {
// 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;
#[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]
fn csr_matrix_valid_data() {
// Construct matrix from valid data and check that selected methods return results

View File

@ -1,19 +1,5 @@
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]
fn sparsity_pattern_valid_data() {
// 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.
/// An immutable column-major matrix view with dimensions known at compile-time.
///
/// See [`SMatrixViewMut`] for a mutable version of this type.
/// A column-major matrix view with dimensions known at compile-time.
///
/// **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> =
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.
///
/// See [`DMatrixViewMut`] for a mutable version of this type.
/// A column-major matrix view dynamic numbers of rows and columns.
///
/// **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> =
Matrix<T, Dyn, Dyn, ViewStorage<'a, T, Dyn, Dyn, RStride, CStride>>;
/// An immutable column-major 1x1 matrix view.
///
/// See [`MatrixViewMut1`] for a mutable version of this type.
/// A column-major 1x1 matrix view.
///
/// **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> =
Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>;
/// An immutable column-major 2x2 matrix view.
///
/// See [`MatrixViewMut2`] for a mutable version of this type.
/// A column-major 2x2 matrix view.
///
/// **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> =
Matrix<T, U2, U2, ViewStorage<'a, T, U2, U2, RStride, CStride>>;
/// An immutable column-major 3x3 matrix view.
///
/// See [`MatrixViewMut3`] for a mutable version of this type.
/// A column-major 3x3 matrix view.
///
/// **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> =
Matrix<T, U3, U3, ViewStorage<'a, T, U3, U3, RStride, CStride>>;
/// An immutable column-major 4x4 matrix view.
///
/// See [`MatrixViewMut4`] for a mutable version of this type.
/// A column-major 4x4 matrix view.
///
/// **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> =
Matrix<T, U4, U4, ViewStorage<'a, T, U4, U4, RStride, CStride>>;
/// An immutable column-major 5x5 matrix view.
///
/// See [`MatrixViewMut5`] for a mutable version of this type.
/// A column-major 5x5 matrix view.
///
/// **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> =
Matrix<T, U5, U5, ViewStorage<'a, T, U5, U5, RStride, CStride>>;
/// An immutable column-major 6x6 matrix view.
///
/// See [`MatrixViewMut6`] for a mutable version of this type.
/// A column-major 6x6 matrix view.
///
/// **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> =
Matrix<T, U6, U6, ViewStorage<'a, T, U6, U6, RStride, CStride>>;
/// An immutable column-major 1x2 matrix view.
///
/// See [`MatrixViewMut1x2`] for a mutable version of this type.
/// A column-major 1x2 matrix view.
///
/// **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> =
Matrix<T, U1, U2, ViewStorage<'a, T, U1, U2, RStride, CStride>>;
/// An immutable column-major 1x3 matrix view.
///
/// See [`MatrixViewMut1x3`] for a mutable version of this type.
/// A column-major 1x3 matrix view.
///
/// **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> =
Matrix<T, U1, U3, ViewStorage<'a, T, U1, U3, RStride, CStride>>;
/// An immutable column-major 1x4 matrix view.
///
/// See [`MatrixViewMut1x4`] for a mutable version of this type.
/// A column-major 1x4 matrix view.
///
/// **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> =
Matrix<T, U1, U4, ViewStorage<'a, T, U1, U4, RStride, CStride>>;
/// An immutable column-major 1x5 matrix view.
///
/// See [`MatrixViewMut1x5`] for a mutable version of this type.
/// A column-major 1x5 matrix view.
///
/// **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> =
Matrix<T, U1, U5, ViewStorage<'a, T, U1, U5, RStride, CStride>>;
/// An immutable column-major 1x6 matrix view.
///
/// See [`MatrixViewMut1x6`] for a mutable version of this type.
/// A column-major 1x6 matrix view.
///
/// **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> =
Matrix<T, U1, U6, ViewStorage<'a, T, U1, U6, RStride, CStride>>;
/// An immutable column-major 2x1 matrix view.
///
/// See [`MatrixViewMut2x1`] for a mutable version of this type.
/// A column-major 2x1 matrix view.
///
/// **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> =
Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>;
/// An immutable column-major 2x3 matrix view.
///
/// See [`MatrixViewMut2x3`] for a mutable version of this type.
/// A column-major 2x3 matrix view.
///
/// **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> =
Matrix<T, U2, U3, ViewStorage<'a, T, U2, U3, RStride, CStride>>;
/// An immutable column-major 2x4 matrix view.
///
/// See [`MatrixViewMut2x4`] for a mutable version of this type.
/// A column-major 2x4 matrix view.
///
/// **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> =
Matrix<T, U2, U4, ViewStorage<'a, T, U2, U4, RStride, CStride>>;
/// An immutable column-major 2x5 matrix view.
///
/// See [`MatrixViewMut2x5`] for a mutable version of this type.
/// A column-major 2x5 matrix view.
///
/// **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> =
Matrix<T, U2, U5, ViewStorage<'a, T, U2, U5, RStride, CStride>>;
/// An immutable column-major 2x6 matrix view.
///
/// See [`MatrixViewMut2x6`] for a mutable version of this type.
/// A column-major 2x6 matrix view.
///
/// **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> =
Matrix<T, U2, U6, ViewStorage<'a, T, U2, U6, RStride, CStride>>;
/// An immutable column-major 3x1 matrix view.
///
/// See [`MatrixViewMut3x1`] for a mutable version of this type.
/// A column-major 3x1 matrix view.
///
/// **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> =
Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>;
/// An immutable column-major 3x2 matrix view.
///
/// See [`MatrixViewMut3x2`] for a mutable version of this type.
/// A column-major 3x2 matrix view.
///
/// **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> =
Matrix<T, U3, U2, ViewStorage<'a, T, U3, U2, RStride, CStride>>;
/// An immutable column-major 3x4 matrix view.
///
/// See [`MatrixViewMut3x4`] for a mutable version of this type.
/// A column-major 3x4 matrix view.
///
/// **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> =
Matrix<T, U3, U4, ViewStorage<'a, T, U3, U4, RStride, CStride>>;
/// An immutable column-major 3x5 matrix view.
///
/// See [`MatrixViewMut3x5`] for a mutable version of this type.
/// A column-major 3x5 matrix view.
///
/// **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> =
Matrix<T, U3, U5, ViewStorage<'a, T, U3, U5, RStride, CStride>>;
/// An immutable column-major 3x6 matrix view.
///
/// See [`MatrixViewMut3x6`] for a mutable version of this type.
/// A column-major 3x6 matrix view.
///
/// **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> =
Matrix<T, U3, U6, ViewStorage<'a, T, U3, U6, RStride, CStride>>;
/// An immutable column-major 4x1 matrix view.
///
/// See [`MatrixViewMut4x1`] for a mutable version of this type.
/// A column-major 4x1 matrix view.
///
/// **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> =
Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>;
/// An immutable column-major 4x2 matrix view.
///
/// See [`MatrixViewMut4x2`] for a mutable version of this type.
/// A column-major 4x2 matrix view.
///
/// **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> =
Matrix<T, U4, U2, ViewStorage<'a, T, U4, U2, RStride, CStride>>;
/// An immutable column-major 4x3 matrix view.
///
/// See [`MatrixViewMut4x3`] for a mutable version of this type.
/// A column-major 4x3 matrix view.
///
/// **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> =
Matrix<T, U4, U3, ViewStorage<'a, T, U4, U3, RStride, CStride>>;
/// An immutable column-major 4x5 matrix view.
///
/// See [`MatrixViewMut4x5`] for a mutable version of this type.
/// A column-major 4x5 matrix view.
///
/// **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> =
Matrix<T, U4, U5, ViewStorage<'a, T, U4, U5, RStride, CStride>>;
/// An immutable column-major 4x6 matrix view.
///
/// See [`MatrixViewMut4x6`] for a mutable version of this type.
/// A column-major 4x6 matrix view.
///
/// **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> =
Matrix<T, U4, U6, ViewStorage<'a, T, U4, U6, RStride, CStride>>;
/// An immutable column-major 5x1 matrix view.
///
/// See [`MatrixViewMut5x1`] for a mutable version of this type.
/// A column-major 5x1 matrix view.
///
/// **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> =
Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>;
/// An immutable column-major 5x2 matrix view.
///
/// See [`MatrixViewMut5x2`] for a mutable version of this type.
/// A column-major 5x2 matrix view.
///
/// **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> =
Matrix<T, U5, U2, ViewStorage<'a, T, U5, U2, RStride, CStride>>;
/// An immutable column-major 5x3 matrix view.
///
/// See [`MatrixViewMut5x3`] for a mutable version of this type.
/// A column-major 5x3 matrix view.
///
/// **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> =
Matrix<T, U5, U3, ViewStorage<'a, T, U5, U3, RStride, CStride>>;
/// An immutable column-major 5x4 matrix view.
///
/// See [`MatrixViewMut5x4`] for a mutable version of this type.
/// A column-major 5x4 matrix view.
///
/// **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> =
Matrix<T, U5, U4, ViewStorage<'a, T, U5, U4, RStride, CStride>>;
/// An immutable column-major 5x6 matrix view.
///
/// See [`MatrixViewMut5x6`] for a mutable version of this type.
/// A column-major 5x6 matrix view.
///
/// **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> =
Matrix<T, U5, U6, ViewStorage<'a, T, U5, U6, RStride, CStride>>;
/// An immutable column-major 6x1 matrix view.
///
/// See [`MatrixViewMut6x1`] for a mutable version of this type.
/// A column-major 6x1 matrix view.
///
/// **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> =
Matrix<T, U6, U1, ViewStorage<'a, T, U6, U1, RStride, CStride>>;
/// An immutable column-major 6x2 matrix view.
///
/// See [`MatrixViewMut6x2`] for a mutable version of this type.
/// A column-major 6x2 matrix view.
///
/// **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> =
Matrix<T, U6, U2, ViewStorage<'a, T, U6, U2, RStride, CStride>>;
/// An immutable column-major 6x3 matrix view.
///
/// See [`MatrixViewMut6x3`] for a mutable version of this type.
/// A column-major 6x3 matrix view.
///
/// **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> =
Matrix<T, U6, U3, ViewStorage<'a, T, U6, U3, RStride, CStride>>;
/// An immutable column-major 6x4 matrix view.
///
/// See [`MatrixViewMut6x4`] for a mutable version of this type.
/// A column-major 6x4 matrix view.
///
/// **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> =
Matrix<T, U6, U4, ViewStorage<'a, T, U6, U4, RStride, CStride>>;
/// An immutable column-major 6x5 matrix view.
///
/// See [`MatrixViewMut6x5`] for a mutable version of this type.
/// A column-major 6x5 matrix view.
///
/// **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> =
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.
///
/// 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.**
/// A column-major matrix view with 1 row and a number of columns chosen at runtime.
pub type MatrixView1xX<'a, T, RStride = U1, CStride = U1> =
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.
///
/// 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.**
/// A column-major matrix view with 2 rows and a number of columns chosen at runtime.
pub type MatrixView2xX<'a, T, RStride = U1, CStride = U2> =
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.
///
/// 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.**
/// A column-major matrix view with 3 rows and a number of columns chosen at runtime.
pub type MatrixView3xX<'a, T, RStride = U1, CStride = U3> =
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.
///
/// 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.**
/// A column-major matrix view with 4 rows and a number of columns chosen at runtime.
pub type MatrixView4xX<'a, T, RStride = U1, CStride = U4> =
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.
///
/// 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.**
/// A column-major matrix view with 5 rows and a number of columns chosen at runtime.
pub type MatrixView5xX<'a, T, RStride = U1, CStride = U5> =
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.
///
/// 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.**
/// A column-major matrix view with 6 rows and a number of columns chosen at runtime.
pub type MatrixView6xX<'a, T, RStride = U1, CStride = U6> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 1 column.
pub type MatrixViewXx1<'a, T, RStride = U1, CStride = Dyn> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 2 columns.
pub type MatrixViewXx2<'a, T, RStride = U1, CStride = Dyn> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 3 columns.
pub type MatrixViewXx3<'a, T, RStride = U1, CStride = Dyn> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 4 columns.
pub type MatrixViewXx4<'a, T, RStride = U1, CStride = Dyn> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 5 columns.
pub type MatrixViewXx5<'a, T, RStride = U1, CStride = Dyn> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 6 columns.
pub type MatrixViewXx6<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U6, ViewStorage<'a, T, Dyn, U6, RStride, CStride>>;
/// An immutable column vector view with dimensions known at compile-time.
///
/// See [`VectorViewMut`] for a mutable version of this type.
/// A column vector view with dimensions known at compile-time.
///
/// **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> =
Matrix<T, D, U1, ViewStorage<'a, T, D, U1, RStride, CStride>>;
/// An immutable column vector view with dimensions known at compile-time.
///
/// See [`SVectorViewMut`] for a mutable version of this type.
/// A column vector view with dimensions known at compile-time.
///
/// **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> =
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.
///
/// 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.**
/// A column vector view dynamic numbers of rows and columns.
pub type DVectorView<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorage<'a, T, Dyn, U1, RStride, CStride>>;
/// An immutable 1D column vector view.
///
/// See [`VectorViewMut1`] for a mutable version of this type.
/// A 1D column vector view.
///
/// **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> =
Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>;
/// An immutable 2D column vector view.
///
/// See [`VectorViewMut2`] for a mutable version of this type.
/// A 2D column vector view.
///
/// **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> =
Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>;
/// An immutable 3D column vector view.
///
/// See [`VectorViewMut3`] for a mutable version of this type.
/// A 3D column vector view.
///
/// **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> =
Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>;
/// An immutable 4D column vector view.
///
/// See [`VectorViewMut4`] for a mutable version of this type.
/// A 4D column vector view.
///
/// **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> =
Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>;
/// An immutable 5D column vector view.
///
/// See [`VectorViewMut5`] for a mutable version of this type.
/// A 5D column vector view.
///
/// **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> =
Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>;
/// An immutable 6D column vector view.
///
/// See [`VectorViewMut6`] for a mutable version of this type.
/// A 6D column vector view.
///
/// **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> =
@ -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.
///
/// See [`SMatrixView`] for an immutable version of this type.
/// A column-major matrix view with dimensions known at compile-time.
///
/// **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> =
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.
///
/// See [`DMatrixView`] for an immutable version of this type.
/// A column-major matrix view dynamic numbers of rows and columns.
///
/// **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> =
Matrix<T, Dyn, Dyn, ViewStorageMut<'a, T, Dyn, Dyn, RStride, CStride>>;
/// A mutable column-major 1x1 matrix view.
///
/// See [`MatrixView1`] for an immutable version of this type.
/// A column-major 1x1 matrix view.
///
/// **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> =
Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>;
/// A mutable column-major 2x2 matrix view.
///
/// See [`MatrixView2`] for an immutable version of this type.
/// A column-major 2x2 matrix view.
///
/// **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> =
Matrix<T, U2, U2, ViewStorageMut<'a, T, U2, U2, RStride, CStride>>;
/// A mutable column-major 3x3 matrix view.
///
/// See [`MatrixView3`] for an immutable version of this type.
/// A column-major 3x3 matrix view.
///
/// **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> =
Matrix<T, U3, U3, ViewStorageMut<'a, T, U3, U3, RStride, CStride>>;
/// A mutable column-major 4x4 matrix view.
///
/// See [`MatrixView4`] for an immutable version of this type.
/// A column-major 4x4 matrix view.
///
/// **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> =
Matrix<T, U4, U4, ViewStorageMut<'a, T, U4, U4, RStride, CStride>>;
/// A mutable column-major 5x5 matrix view.
///
/// See [`MatrixView5`] for an immutable version of this type.
/// A column-major 5x5 matrix view.
///
/// **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> =
Matrix<T, U5, U5, ViewStorageMut<'a, T, U5, U5, RStride, CStride>>;
/// A mutable column-major 6x6 matrix view.
///
/// See [`MatrixView6`] for an immutable version of this type.
/// A column-major 6x6 matrix view.
///
/// **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> =
Matrix<T, U6, U6, ViewStorageMut<'a, T, U6, U6, RStride, CStride>>;
/// A mutable column-major 1x2 matrix view.
///
/// See [`MatrixView1x2`] for an immutable version of this type.
/// A column-major 1x2 matrix view.
///
/// **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> =
Matrix<T, U1, U2, ViewStorageMut<'a, T, U1, U2, RStride, CStride>>;
/// A mutable column-major 1x3 matrix view.
///
/// See [`MatrixView1x3`] for an immutable version of this type.
/// A column-major 1x3 matrix view.
///
/// **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> =
Matrix<T, U1, U3, ViewStorageMut<'a, T, U1, U3, RStride, CStride>>;
/// A mutable column-major 1x4 matrix view.
///
/// See [`MatrixView1x4`] for an immutable version of this type.
/// A column-major 1x4 matrix view.
///
/// **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> =
Matrix<T, U1, U4, ViewStorageMut<'a, T, U1, U4, RStride, CStride>>;
/// A mutable column-major 1x5 matrix view.
///
/// See [`MatrixView1x5`] for an immutable version of this type.
/// A column-major 1x5 matrix view.
///
/// **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> =
Matrix<T, U1, U5, ViewStorageMut<'a, T, U1, U5, RStride, CStride>>;
/// A mutable column-major 1x6 matrix view.
///
/// See [`MatrixView1x6`] for an immutable version of this type.
/// A column-major 1x6 matrix view.
///
/// **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> =
Matrix<T, U1, U6, ViewStorageMut<'a, T, U1, U6, RStride, CStride>>;
/// A mutable column-major 2x1 matrix view.
///
/// See [`MatrixView2x1`] for an immutable version of this type.
/// A column-major 2x1 matrix view.
///
/// **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> =
Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>;
/// A mutable column-major 2x3 matrix view.
///
/// See [`MatrixView2x3`] for an immutable version of this type.
/// A column-major 2x3 matrix view.
///
/// **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> =
Matrix<T, U2, U3, ViewStorageMut<'a, T, U2, U3, RStride, CStride>>;
/// A mutable column-major 2x4 matrix view.
///
/// See [`MatrixView2x4`] for an immutable version of this type.
/// A column-major 2x4 matrix view.
///
/// **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> =
Matrix<T, U2, U4, ViewStorageMut<'a, T, U2, U4, RStride, CStride>>;
/// A mutable column-major 2x5 matrix view.
///
/// See [`MatrixView2x5`] for an immutable version of this type.
/// A column-major 2x5 matrix view.
///
/// **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> =
Matrix<T, U2, U5, ViewStorageMut<'a, T, U2, U5, RStride, CStride>>;
/// A mutable column-major 2x6 matrix view.
///
/// See [`MatrixView2x6`] for an immutable version of this type.
/// A column-major 2x6 matrix view.
///
/// **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> =
Matrix<T, U2, U6, ViewStorageMut<'a, T, U2, U6, RStride, CStride>>;
/// A mutable column-major 3x1 matrix view.
///
/// See [`MatrixView3x1`] for an immutable version of this type.
/// A column-major 3x1 matrix view.
///
/// **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> =
Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>;
/// A mutable column-major 3x2 matrix view.
///
/// See [`MatrixView3x2`] for an immutable version of this type.
/// A column-major 3x2 matrix view.
///
/// **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> =
Matrix<T, U3, U2, ViewStorageMut<'a, T, U3, U2, RStride, CStride>>;
/// A mutable column-major 3x4 matrix view.
///
/// See [`MatrixView3x4`] for an immutable version of this type.
/// A column-major 3x4 matrix view.
///
/// **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> =
Matrix<T, U3, U4, ViewStorageMut<'a, T, U3, U4, RStride, CStride>>;
/// A mutable column-major 3x5 matrix view.
///
/// See [`MatrixView3x5`] for an immutable version of this type.
/// A column-major 3x5 matrix view.
///
/// **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> =
Matrix<T, U3, U5, ViewStorageMut<'a, T, U3, U5, RStride, CStride>>;
/// A mutable column-major 3x6 matrix view.
///
/// See [`MatrixView3x6`] for an immutable version of this type.
/// A column-major 3x6 matrix view.
///
/// **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> =
Matrix<T, U3, U6, ViewStorageMut<'a, T, U3, U6, RStride, CStride>>;
/// A mutable column-major 4x1 matrix view.
///
/// See [`MatrixView4x1`] for an immutable version of this type.
/// A column-major 4x1 matrix view.
///
/// **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> =
Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>;
/// A mutable column-major 4x2 matrix view.
///
/// See [`MatrixView4x2`] for an immutable version of this type.
/// A column-major 4x2 matrix view.
///
/// **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> =
Matrix<T, U4, U2, ViewStorageMut<'a, T, U4, U2, RStride, CStride>>;
/// A mutable column-major 4x3 matrix view.
///
/// See [`MatrixView4x3`] for an immutable version of this type.
/// A column-major 4x3 matrix view.
///
/// **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> =
Matrix<T, U4, U3, ViewStorageMut<'a, T, U4, U3, RStride, CStride>>;
/// A mutable column-major 4x5 matrix view.
///
/// See [`MatrixView4x5`] for an immutable version of this type.
/// A column-major 4x5 matrix view.
///
/// **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> =
Matrix<T, U4, U5, ViewStorageMut<'a, T, U4, U5, RStride, CStride>>;
/// A mutable column-major 4x6 matrix view.
///
/// See [`MatrixView4x6`] for an immutable version of this type.
/// A column-major 4x6 matrix view.
///
/// **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> =
Matrix<T, U4, U6, ViewStorageMut<'a, T, U4, U6, RStride, CStride>>;
/// A mutable column-major 5x1 matrix view.
///
/// See [`MatrixView5x1`] for an immutable version of this type.
/// A column-major 5x1 matrix view.
///
/// **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> =
Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>;
/// A mutable column-major 5x2 matrix view.
///
/// See [`MatrixView5x2`] for an immutable version of this type.
/// A column-major 5x2 matrix view.
///
/// **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> =
Matrix<T, U5, U2, ViewStorageMut<'a, T, U5, U2, RStride, CStride>>;
/// A mutable column-major 5x3 matrix view.
///
/// See [`MatrixView5x3`] for an immutable version of this type.
/// A column-major 5x3 matrix view.
///
/// **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> =
Matrix<T, U5, U3, ViewStorageMut<'a, T, U5, U3, RStride, CStride>>;
/// A mutable column-major 5x4 matrix view.
///
/// See [`MatrixView5x4`] for an immutable version of this type.
/// A column-major 5x4 matrix view.
///
/// **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> =
Matrix<T, U5, U4, ViewStorageMut<'a, T, U5, U4, RStride, CStride>>;
/// A mutable column-major 5x6 matrix view.
///
/// See [`MatrixView5x6`] for an immutable version of this type.
/// A column-major 5x6 matrix view.
///
/// **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> =
Matrix<T, U5, U6, ViewStorageMut<'a, T, U5, U6, RStride, CStride>>;
/// A mutable column-major 6x1 matrix view.
///
/// See [`MatrixView6x1`] for an immutable version of this type.
/// A column-major 6x1 matrix view.
///
/// **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> =
Matrix<T, U6, U1, ViewStorageMut<'a, T, U6, U1, RStride, CStride>>;
/// A mutable column-major 6x2 matrix view.
///
/// See [`MatrixView6x2`] for an immutable version of this type.
/// A column-major 6x2 matrix view.
///
/// **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> =
Matrix<T, U6, U2, ViewStorageMut<'a, T, U6, U2, RStride, CStride>>;
/// A mutable column-major 6x3 matrix view.
///
/// See [`MatrixView6x3`] for an immutable version of this type.
/// A column-major 6x3 matrix view.
///
/// **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> =
Matrix<T, U6, U3, ViewStorageMut<'a, T, U6, U3, RStride, CStride>>;
/// A mutable column-major 6x4 matrix view.
///
/// See [`MatrixView6x4`] for an immutable version of this type.
/// A column-major 6x4 matrix view.
///
/// **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> =
Matrix<T, U6, U4, ViewStorageMut<'a, T, U6, U4, RStride, CStride>>;
/// A mutable column-major 6x5 matrix view.
///
/// See [`MatrixView6x5`] for an immutable version of this type.
/// A column-major 6x5 matrix view.
///
/// **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> =
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.
///
/// 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.**
/// A column-major matrix view with 1 row and a number of columns chosen at runtime.
pub type MatrixViewMut1xX<'a, T, RStride = U1, CStride = U1> =
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.
///
/// 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.**
/// A column-major matrix view with 2 rows and a number of columns chosen at runtime.
pub type MatrixViewMut2xX<'a, T, RStride = U1, CStride = U2> =
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.
///
/// 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.**
/// A column-major matrix view with 3 rows and a number of columns chosen at runtime.
pub type MatrixViewMut3xX<'a, T, RStride = U1, CStride = U3> =
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.
///
/// 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.**
/// A column-major matrix view with 4 rows and a number of columns chosen at runtime.
pub type MatrixViewMut4xX<'a, T, RStride = U1, CStride = U4> =
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.
///
/// 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.**
/// A column-major matrix view with 5 rows and a number of columns chosen at runtime.
pub type MatrixViewMut5xX<'a, T, RStride = U1, CStride = U5> =
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.
///
/// 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.**
/// A column-major matrix view with 6 rows and a number of columns chosen at runtime.
pub type MatrixViewMut6xX<'a, T, RStride = U1, CStride = U6> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 1 column.
pub type MatrixViewMutXx1<'a, T, RStride = U1, CStride = Dyn> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 2 columns.
pub type MatrixViewMutXx2<'a, T, RStride = U1, CStride = Dyn> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 3 columns.
pub type MatrixViewMutXx3<'a, T, RStride = U1, CStride = Dyn> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 4 columns.
pub type MatrixViewMutXx4<'a, T, RStride = U1, CStride = Dyn> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 5 columns.
pub type MatrixViewMutXx5<'a, T, RStride = U1, CStride = Dyn> =
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.
///
/// 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.**
/// A column-major matrix view with a number of rows chosen at runtime and 6 columns.
pub type MatrixViewMutXx6<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U6, ViewStorageMut<'a, T, Dyn, U6, RStride, CStride>>;
/// A mutable column vector view with dimensions known at compile-time.
///
/// See [`VectorView`] for an immutable version of this type.
/// A column vector view with dimensions known at compile-time.
///
/// **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> =
Matrix<T, D, U1, ViewStorageMut<'a, T, D, U1, RStride, CStride>>;
/// A mutable column vector view with dimensions known at compile-time.
///
/// See [`SVectorView`] for an immutable version of this type.
/// A column vector view with dimensions known at compile-time.
///
/// **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> =
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.
///
/// See [`DVectorView`] for an immutable version of this type.
/// A column vector view dynamic numbers of rows and columns.
///
/// **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> =
Matrix<T, Dyn, U1, ViewStorageMut<'a, T, Dyn, U1, RStride, CStride>>;
/// A mutable 1D column vector view.
///
/// See [`VectorView1`] for an immutable version of this type.
/// A 1D column vector view.
///
/// **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> =
Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>;
/// A mutable 2D column vector view.
///
/// See [`VectorView2`] for an immutable version of this type.
/// A 2D column vector view.
///
/// **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> =
Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>;
/// A mutable 3D column vector view.
///
/// See [`VectorView3`] for an immutable version of this type.
/// A 3D column vector view.
///
/// **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> =
Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>;
/// A mutable 4D column vector view.
///
/// See [`VectorView4`] for an immutable version of this type.
/// A 4D column vector view.
///
/// **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> =
Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>;
/// A mutable 5D column vector view.
///
/// See [`VectorView5`] for an immutable version of this type.
/// A 5D column vector view.
///
/// **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> =
Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>;
/// A mutable 6D column vector view.
///
/// See [`VectorView6`] for an immutable version of this type.
/// A 6D column vector view.
///
/// **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> =

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
/// 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.
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.
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.
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.
///
/// # Safety
/// The user must make sure that every single entry of the buffer has been initialized,
/// 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.
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: R,
ncols: C,
iter: I,
) -> Self::Buffer<T>;
) -> Self::Buffer;
#[inline]
/// 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,
ncols: C,
iter: I,
) -> Self::Buffer<T> {
) -> Self::Buffer {
let mut res = Self::allocate_uninit(nrows, ncols);
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."
);
<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` ×
/// `CFrom`) elements to a smaller or larger size (`RTo`, `CTo`).
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
/// `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(
nrows: RTo,
ncols: CTo,
buf: <Self as Allocator<RFrom, CFrom>>::Buffer<T>,
) -> <Self as Allocator<RTo, CTo>>::BufferUninit<T>;
buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer,
) -> <Self as Allocator<T, RTo, CTo>>::BufferUninit;
}
/// 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.
/// Restricts the given number of rows and columns to be respectively the same.
pub trait SameShapeAllocator<R1, C1, R2, C2>:
Allocator<R1, C1> + Allocator<SameShapeR<R1, R2>, SameShapeC<C1, C2>>
pub trait SameShapeAllocator<T, R1, C1, R2, C2>:
Allocator<T, R1, C1> + Allocator<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>
where
R1: 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
R1: Dim,
R2: Dim,
C1: 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>,
{
}
// XXX: Bad name.
/// Restricts the given number of rows to be equal.
pub trait SameShapeVectorAllocator<R1, R2>:
Allocator<R1> + Allocator<SameShapeR<R1, R2>> + SameShapeAllocator<R1, U1, R2, U1>
pub trait SameShapeVectorAllocator<T, R1, R2>:
Allocator<T, R1> + Allocator<T, SameShapeR<R1, R2>> + SameShapeAllocator<T, R1, U1, R2, U1>
where
R1: 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
R1: 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>,
{
}

View File

@ -27,7 +27,7 @@ use std::mem;
* Static RawStorage.
*
*/
/// An array-based statically sized matrix data storage.
/// A array-based statically sized matrix data storage.
#[repr(transparent)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(
@ -42,6 +42,7 @@ use std::mem;
)
)]
#[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]);
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>>
for ArrayStorage<T, R, C>
where
DefaultAllocator: Allocator<Const<R>, Const<C>, Buffer<T> = Self>,
DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
{
#[inline]
fn into_owned(self) -> Owned<T, Const<R>, Const<C>>
where
DefaultAllocator: Allocator<Const<R>, Const<C>>,
DefaultAllocator: Allocator<T, Const<R>, Const<C>>,
{
self
}
@ -126,16 +127,10 @@ where
#[inline]
fn clone_owned(&self) -> Owned<T, Const<R>, Const<C>>
where
DefaultAllocator: Allocator<Const<R>, Const<C>>,
DefaultAllocator: Allocator<T, Const<R>, Const<C>>,
{
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>>
@ -256,7 +251,7 @@ where
V: SeqAccess<'a>,
{
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;
while let Some(value) = visitor.next_element()? {
@ -269,7 +264,7 @@ where
if curr == R * C {
// 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 {
for i in 0..curr {
// Safety:

View File

@ -1,6 +1,6 @@
use crate::{RawStorage, SimdComplexField};
use num::{One, Zero};
use simba::scalar::{ClosedAddAssign, ClosedMulAssign};
use simba::scalar::{ClosedAdd, ClosedMul};
use crate::base::allocator::Allocator;
use crate::base::blas_uninit::{axcpy_uninit, gemm_uninit, gemv_uninit};
@ -17,7 +17,7 @@ use crate::base::{
/// # Dot/scalar product
impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S>
where
T: Scalar + Zero + ClosedAddAssign + ClosedMulAssign,
T: Scalar + Zero + ClosedAdd + ClosedMul,
{
#[inline(always)]
fn dotx<R2: Dim, C2: Dim, SB>(
@ -275,7 +275,7 @@ where
/// # BLAS functions
impl<T, D: Dim, S> Vector<T, D, S>
where
T: Scalar + Zero + ClosedAddAssign + ClosedMulAssign,
T: Scalar + Zero + ClosedAdd + ClosedMul,
S: StorageMut<T, D>,
{
/// 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>
where
T: Scalar + Zero + ClosedAddAssign + ClosedMulAssign,
T: Scalar + Zero + ClosedAdd + ClosedMul,
{
#[inline(always)]
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>
where
T: Scalar + Zero + ClosedAddAssign + ClosedMulAssign,
T: Scalar + Zero + ClosedAdd + ClosedMul,
{
#[inline(always)]
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>
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`.
///
@ -1098,7 +1098,7 @@ where
S3: Storage<T, R3, C3>,
S4: Storage<T, D4, 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?
let mut work = Matrix::zeros_generic(self.shape_generic().0, Const::<1>);
@ -1196,7 +1196,7 @@ where
S2: Storage<T, D2, D2>,
S3: Storage<T, R3, C3>,
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?
let mut work = Vector::zeros_generic(mid.shape_generic().0, Const::<1>);

View File

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

View File

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

View File

@ -3,7 +3,7 @@
use num::{Signed, Zero};
use std::ops::{Add, Mul};
use simba::scalar::{ClosedDivAssign, ClosedMulAssign};
use simba::scalar::{ClosedDiv, ClosedMul};
use simba::simd::SimdPartialOrd;
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::storage::{Storage, StorageMut};
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.
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>
where
T: Signed,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C>,
{
let mut res = self.clone_owned();
@ -55,7 +55,7 @@ macro_rules! component_binop_impl(
where T: $Trait,
R2: Dim, C2: Dim,
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> {
assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
@ -148,7 +148,7 @@ macro_rules! component_binop_impl(
/// # Componentwise operations
impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA> {
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"
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);
```
";
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"
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>
where
T: SimdPartialOrd,
DefaultAllocator: Allocator<R1, C1>,
DefaultAllocator: Allocator<T, R1, C1>,
{
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>
where
T: SimdPartialOrd,
DefaultAllocator: Allocator<R1, C1>,
DefaultAllocator: Allocator<T, R1, C1>,
{
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>)
where
T: SimdPartialOrd,
DefaultAllocator: Allocator<R1, C1>,
DefaultAllocator: Allocator<T, R1, C1>,
{
// TODO: can this be optimized?
(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()?"]
pub fn add_scalar(&self, rhs: T) -> OMatrix<T, R1, C1>
where
T: ClosedAddAssign,
DefaultAllocator: Allocator<R1, C1>,
T: ClosedAdd,
DefaultAllocator: Allocator<T, R1, C1>,
{
let mut res = self.clone_owned();
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]
pub fn add_scalar_mut(&mut self, rhs: T)
where
T: ClosedAddAssign,
T: ClosedAdd,
SA: StorageMut<T, R1, C1>,
{
for e in self.iter_mut() {

View File

@ -6,7 +6,7 @@ use crate::base::dimension::{Dim, DimName, Dyn};
#[derive(Copy, Clone, Debug)]
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> {}
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> {
/// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level
/// constant.
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 {
@ -45,19 +35,12 @@ impl<D: DimName> DimEq<Dyn, D> for ShapeConstraint {
macro_rules! equality_trait_decl(
($($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]
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
/// constant.
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 {
@ -75,17 +58,17 @@ macro_rules! 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 \
rows of a matrix.",
SameNumberOfRows,
"Constrains `D1` and `D2` to be equivalent. \
"Constraints `D1` and `D2` to be equivalent. \
They are both assumed to be the number of \
columns of a matrix.",
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).
pub trait SameDimension<D1: Dim, D2: Dim>:
SameNumberOfRows<D1, D2> + SameNumberOfColumns<D1, D2>

View File

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

View File

@ -97,8 +97,6 @@ macro_rules! impl_constructors(
}
/// Creates, without bound checking, a new matrix view from the given data array.
/// # Safety
/// `data[start..start+rstride * cstride]` must be within bounds.
#[inline]
pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self {
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.
///
/// # Safety
///
/// `start`, `rstride`, and `cstride`, with the given matrix size will not index
/// outside of `data`.
#[inline]
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))
@ -264,10 +257,6 @@ macro_rules! impl_constructors_mut(
}
/// 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]
pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self {
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.
/// # Safety
/// `data[start..start+rstride * cstride]` must be within bounds.
#[inline]
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(

View File

@ -8,11 +8,11 @@ use simba::simd::{PrimitiveSimdValue, SimdValue};
use crate::base::allocator::{Allocator, SameShapeAllocator};
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"))]
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::storage::{IsContiguous, RawStorage, RawStorageMut};
use crate::base::{
@ -35,7 +35,8 @@ where
C2: Dim,
T1: Scalar,
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>,
{
#[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
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> {
#[inline]
fn from(arr: [T; D]) -> Self {
@ -496,7 +473,7 @@ where
}
#[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]
fn from(vec: Vec<T>) -> Self {
Self::from_vec(vec)
@ -504,7 +481,7 @@ impl<T: Scalar> From<Vec<T>> for DVector<T> {
}
#[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]
fn from(vec: Vec<T>) -> Self {
Self::from_vec(vec)
@ -560,7 +537,7 @@ impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R
where
T: From<[<T as SimdValue>::Element; 2]>,
T::Element: Scalar + SimdValue,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{
#[inline]
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
T: From<[<T as SimdValue>::Element; 4]>,
T::Element: Scalar + SimdValue,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{
#[inline]
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
T: From<[<T as SimdValue>::Element; 8]>,
T::Element: Scalar + SimdValue,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{
#[inline]
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
T: From<[<T as SimdValue>::Element; 16]>,
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 {
let (nrows, ncols) = arr[0].shape_generic();

View File

@ -12,16 +12,14 @@ use alloc::vec::Vec;
use super::Const;
use crate::base::allocator::{Allocator, Reallocator};
use crate::base::array_storage::ArrayStorage;
use crate::base::dimension::Dim;
#[cfg(any(feature = "alloc", feature = "std"))]
use crate::base::dimension::{DimName, Dyn};
use crate::base::storage::{RawStorage, RawStorageMut, Storage};
use crate::base::dimension::Dyn;
use crate::base::dimension::{Dim, DimName};
use crate::base::storage::{RawStorage, RawStorageMut};
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::vec_storage::VecStorage;
use crate::base::Scalar;
#[cfg(any(feature = "std", feature = "alloc"))]
use std::mem::ManuallyDrop;
use std::mem::MaybeUninit;
use std::mem::{ManuallyDrop, MaybeUninit};
/*
*
@ -34,21 +32,21 @@ use std::mem::MaybeUninit;
pub struct DefaultAllocator;
// Static - Static
impl<const R: usize, const C: usize> Allocator<Const<R>, Const<C>> for DefaultAllocator {
type Buffer<T: Scalar> = ArrayStorage<T, R, C>;
type BufferUninit<T: Scalar> = ArrayStorage<MaybeUninit<T>, R, C>;
impl<T: Scalar, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>>
for DefaultAllocator
{
type Buffer = ArrayStorage<T, R, C>;
type BufferUninit = ArrayStorage<MaybeUninit<T>, R, C>;
#[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.
let array: [[MaybeUninit<T>; R]; C] = unsafe { MaybeUninit::uninit().assume_init() };
ArrayStorage(array)
}
#[inline(always)]
unsafe fn assume_init<T: Scalar>(
uninit: ArrayStorage<MaybeUninit<T>, R, C>,
) -> ArrayStorage<T, R, C> {
unsafe fn assume_init(uninit: ArrayStorage<MaybeUninit<T>, R, C>) -> ArrayStorage<T, R, C> {
// Safety:
// * The caller guarantees that all elements of the array are initialized
// * `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]
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: Const<R>,
ncols: Const<C>,
iter: I,
) -> Self::Buffer<T> {
) -> Self::Buffer {
let mut res = Self::allocate_uninit(nrows, ncols);
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
// 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 - Dyn
#[cfg(any(feature = "std", feature = "alloc"))]
impl<C: Dim> Allocator<Dyn, C> for DefaultAllocator {
type Buffer<T: Scalar> = VecStorage<T, Dyn, C>;
type BufferUninit<T: Scalar> = VecStorage<MaybeUninit<T>, Dyn, C>;
impl<T: Scalar, C: Dim> Allocator<T, Dyn, C> for DefaultAllocator {
type Buffer = VecStorage<T, Dyn, C>;
type BufferUninit = VecStorage<MaybeUninit<T>, Dyn, C>;
#[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 length = nrows.value() * ncols.value();
data.reserve_exact(length);
@ -101,9 +99,7 @@ impl<C: Dim> Allocator<Dyn, C> for DefaultAllocator {
}
#[inline]
unsafe fn assume_init<T: Scalar>(
uninit: VecStorage<MaybeUninit<T>, Dyn, C>,
) -> VecStorage<T, Dyn, C> {
unsafe fn assume_init(uninit: VecStorage<MaybeUninit<T>, Dyn, C>) -> VecStorage<T, Dyn, C> {
// Avoids a double-drop.
let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into();
@ -118,11 +114,11 @@ impl<C: Dim> Allocator<Dyn, C> for DefaultAllocator {
}
#[inline]
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: Dyn,
ncols: C,
iter: I,
) -> Self::Buffer<T> {
) -> Self::Buffer {
let it = iter.into_iter();
let res: Vec<T> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(),
@ -134,12 +130,12 @@ impl<C: Dim> Allocator<Dyn, C> for DefaultAllocator {
// Static - Dyn
#[cfg(any(feature = "std", feature = "alloc"))]
impl<R: DimName> Allocator<R, Dyn> for DefaultAllocator {
type Buffer<T: Scalar> = VecStorage<T, R, Dyn>;
type BufferUninit<T: Scalar> = VecStorage<MaybeUninit<T>, R, Dyn>;
impl<T: Scalar, R: DimName> Allocator<T, R, Dyn> for DefaultAllocator {
type Buffer = VecStorage<T, R, Dyn>;
type BufferUninit = VecStorage<MaybeUninit<T>, R, Dyn>;
#[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 length = nrows.value() * ncols.value();
data.reserve_exact(length);
@ -149,9 +145,7 @@ impl<R: DimName> Allocator<R, Dyn> for DefaultAllocator {
}
#[inline]
unsafe fn assume_init<T: Scalar>(
uninit: VecStorage<MaybeUninit<T>, R, Dyn>,
) -> VecStorage<T, R, Dyn> {
unsafe fn assume_init(uninit: VecStorage<MaybeUninit<T>, R, Dyn>) -> VecStorage<T, R, Dyn> {
// Avoids a double-drop.
let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into();
@ -166,11 +160,11 @@ impl<R: DimName> Allocator<R, Dyn> for DefaultAllocator {
}
#[inline]
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: R,
ncols: Dyn,
iter: I,
) -> Self::Buffer<T> {
) -> Self::Buffer {
let it = iter.into_iter();
let res: Vec<T> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(),
@ -191,15 +185,15 @@ impl<T: Scalar, RFrom, CFrom, const RTO: usize, const CTO: usize>
where
RFrom: Dim,
CFrom: Dim,
Self: Allocator<RFrom, CFrom>,
Self: Allocator<T, RFrom, CFrom>,
{
#[inline]
unsafe fn reallocate_copy(
rto: Const<RTO>,
cto: Const<CTO>,
buf: <Self as Allocator<RFrom, CFrom>>::Buffer<T>,
buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer,
) -> 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();
@ -210,8 +204,8 @@ where
// Safety:
// - 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.
buf.forget_elements();
// - We forget `buf` so that we dont drop the other elements.
std::mem::forget(buf);
res
}
@ -230,7 +224,7 @@ where
cto: CTo,
buf: ArrayStorage<T, RFROM, CFROM>,
) -> 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();
@ -241,8 +235,8 @@ where
// Safety:
// - 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.
buf.forget_elements();
// - We forget `buf` so that we dont drop the other elements.
std::mem::forget(buf);
res
}
@ -261,7 +255,7 @@ where
cto: Dyn,
buf: ArrayStorage<T, RFROM, CFROM>,
) -> 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();
@ -272,8 +266,8 @@ where
// Safety:
// - 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.
buf.forget_elements();
// - We forget `buf` so that we dont drop the other elements.
std::mem::forget(buf);
res
}

View File

@ -23,6 +23,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
feature = "rkyv-serialize",
archive_attr(derive(bytecheck::CheckBytes))
)]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
pub struct Dyn(pub usize);
#[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
/// 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 {
#[inline(always)]
fn is<D: Dim>() -> bool {
@ -219,6 +216,7 @@ dim_ops!(
archive(as = "Self")
)]
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
pub struct Const<const R: usize>;
/// 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]
pub fn upper_triangle(&self) -> OMatrix<T, R, C>
where
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C>,
{
let mut res = self.clone_owned();
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]
pub fn lower_triangle(&self) -> OMatrix<T, R, C>
where
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C>,
{
let mut res = self.clone_owned();
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
I: IntoIterator<Item = &'a usize>,
I::IntoIter: ExactSizeIterator + Clone,
DefaultAllocator: Allocator<Dyn, C>,
DefaultAllocator: Allocator<T, Dyn, C>,
{
let irows = irows.into_iter();
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
I: IntoIterator<Item = &'a usize>,
I::IntoIter: ExactSizeIterator,
DefaultAllocator: Allocator<R, Dyn>,
DefaultAllocator: Allocator<T, R, Dyn>,
{
let icols = icols.into_iter();
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 {
unsafe {
compress_rows(
m.as_mut_slice(),
&mut m.as_mut_slice(),
nrows.value(),
ncols.value(),
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 {
extend_rows(
res.as_mut_slice(),
&mut res.as_mut_slice(),
nrows.value(),
ncols.value(),
i,
@ -909,7 +909,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
unsafe {
if new_nrows.value() < nrows {
compress_rows(
data.as_mut_slice(),
&mut data.as_mut_slice(),
nrows,
ncols,
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,
));
extend_rows(
res.as_mut_slice(),
&mut res.as_mut_slice(),
nrows,
new_ncols.value(),
nrows,
@ -1037,7 +1037,7 @@ impl<T: Scalar> OMatrix<T, Dyn, Dyn> {
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, C: Dim> OMatrix<T, Dyn, C>
where
DefaultAllocator: Allocator<Dyn, C>,
DefaultAllocator: Allocator<T, Dyn, C>,
{
/// Changes the number of rows of this matrix in-place.
///
@ -1058,7 +1058,7 @@ where
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, R: Dim> OMatrix<T, R, Dyn>
where
DefaultAllocator: Allocator<R, Dyn>,
DefaultAllocator: Allocator<T, R, Dyn>,
{
/// 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
/// any bounds checking.
///
/// # Safety
///
/// `index` must within bounds of the array.
#[inline]
#[must_use]
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
/// any bounds checking.
/// # Safety
///
/// `index` must within bounds of the array.
#[inline]
#[must_use]
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::{
Allocator, DefaultAllocator, Dim, OVector, One, RealField, Scalar, Unit, Vector, Zero,
};
use simba::scalar::{ClosedAddAssign, ClosedMulAssign, ClosedSubAssign};
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub};
/// # Interpolation
impl<
T: Scalar + Zero + One + ClosedAddAssign + ClosedSubAssign + ClosedMulAssign,
D: Dim,
S: Storage<T, D>,
> Vector<T, D, S>
impl<T: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, 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.
///
@ -26,7 +23,7 @@ impl<
#[must_use]
pub fn lerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D>
where
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<T, D>,
{
let mut res = self.clone_owned();
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>
where
T: RealField,
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<T, D>,
{
let me = Unit::new_normalize(self.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,
) -> Unit<OVector<T, D>>
where
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<T, D>,
{
// TODO: the result is wrong when self and rhs are collinear with opposite direction.
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,
) -> Option<Unit<OVector<T, D>>>
where
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<T, D>,
{
let c_hang = self.dot(rhs);

View File

@ -12,29 +12,26 @@ use std::mem;
use crate::base::dimension::{Dim, U1};
use crate::base::storage::{RawStorage, RawStorageMut};
use crate::base::{Matrix, MatrixView, MatrixViewMut, Scalar, ViewStorage, ViewStorageMut};
#[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)>,
}
use crate::base::{Matrix, MatrixView, MatrixViewMut, Scalar};
macro_rules! iterator {
(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
// case the iterator is trivial because it does not have any stride).
impl<T, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
RawIter<$Ptr, T, R, C, RStride, CStride>
{
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.
fn new<'a, S: $Storage<T, R, C, RStride = RStride, CStride = CStride>>(
storage: $SRef,
) -> Self {
pub fn new(storage: $SRef) -> $Name<'a, T, R, C, S> {
let shape = storage.shape();
let strides = storage.strides();
let inner_offset = shape.0.value() * strides.0.value();
@ -58,7 +55,7 @@ macro_rules! iterator {
unsafe { ptr.add(inner_offset) }
};
RawIter {
$Name {
ptr,
inner_ptr: ptr,
inner_end,
@ -69,13 +66,11 @@ macro_rules! iterator {
}
}
impl<T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Iterator
for RawIter<$Ptr, T, R, C, RStride, CStride>
{
type Item = $Ptr;
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]
fn next(&mut self) -> Option<Self::Item> {
fn next(&mut self) -> Option<$Ref> {
unsafe {
if self.size == 0 {
None
@ -107,7 +102,10 @@ macro_rules! iterator {
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
for RawIter<$Ptr, T, R, C, RStride, CStride>
impl<'a, T, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> DoubleEndedIterator
for $Name<'a, T, R, C, S>
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
fn next_back(&mut self) -> Option<$Ref> {
unsafe {
if self.size == 0 {
None
@ -154,85 +152,21 @@ macro_rules! iterator {
.ptr
.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
for $Name<'a, T, R, C, S>
{
#[inline(always)]
#[inline]
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 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.
@ -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) {
// 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 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) {
// 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 left_iter = ColumnIterMut {

View File

@ -18,7 +18,7 @@ use rkyv::bytecheck;
#[cfg(feature = "rkyv-serialize-no-std")]
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 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 = "cuda", derive(cust_core::DeviceCopy))]
pub struct Matrix<T, R, C, S> {
/// 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> {
/// Creates a new matrix with the given data without statically checking that the matrix
/// dimension matches the storage dimension.
///
/// # Safety
///
/// The storage dimension must match the given dimensions.
#[inline(always)]
pub const unsafe fn from_data_statically_unchecked(data: S) -> Matrix<T, R, C, S> {
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
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C>,
{
/// 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.
#[inline(always)]
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,
))
}
@ -533,7 +530,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
max_relative: T::Epsilon,
) -> bool
where
T: RelativeEq + Scalar,
T: RelativeEq,
R2: Dim,
C2: Dim,
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
T: Scalar,
S: Storage<T, R, C>,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C>,
{
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>,
R2: Dim,
C2: Dim,
DefaultAllocator: SameShapeAllocator<R, C, R2, C2>,
DefaultAllocator: SameShapeAllocator<T, R, C, R2, C2>,
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
{
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
T: Scalar,
S: Storage<T, R, C>,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C>,
{
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>,
R2: Dim,
C2: Dim,
DefaultAllocator: SameShapeAllocator<R, C, R2, C2>,
DefaultAllocator: SameShapeAllocator<T, R, C, R2, C2>,
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
{
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>
where
T: Scalar,
DefaultAllocator: Allocator<C, R>,
DefaultAllocator: Allocator<T, C, R>,
{
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>
where
T: Scalar,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T2, R, C>,
{
let (nrows, ncols) = self.shape_generic();
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
T: Scalar,
OMatrix<T2, R, C>: SupersetOf<Self>,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T2, R, C>,
{
crate::convert(self)
}
@ -769,7 +766,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
where
T: Scalar,
Self: SupersetOf<OMatrix<T2, R, C>>,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T2, R, C>,
{
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>
where
T: Scalar,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T2, R, C>,
{
let (nrows, ncols) = self.shape_generic();
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,
S2: RawStorage<T2, R, C>,
F: FnMut(T, T2) -> N3,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<N3, R, C>,
{
let (nrows, ncols) = self.shape_generic();
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>,
S3: RawStorage<N3, R, C>,
F: FnMut(T, T2, N3) -> N4,
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<N4, R, C>,
{
let (nrows, ncols) = self.shape_generic();
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.
///
/// # Safety
///
/// Both `(r, c)` must have `r < nrows(), c < ncols()`.
#[inline]
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());
@ -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> {
/// Gets a reference to the i-th element of this column vector without bound checking.
/// # Safety
/// `i` must be less than `D`.
#[inline]
#[must_use]
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> {
/// Gets a mutable reference to the i-th element of this column vector without bound checking.
/// # Safety
/// `i` must be less than `D`.
#[inline]
#[must_use]
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()?"]
pub fn adjoint(&self) -> OMatrix<T, C, R>
where
DefaultAllocator: Allocator<C, R>,
DefaultAllocator: Allocator<T, C, R>,
{
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]
pub fn conjugate_transpose(&self) -> OMatrix<T, C, R>
where
DefaultAllocator: Allocator<C, R>,
DefaultAllocator: Allocator<T, C, R>,
{
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()?"]
pub fn conjugate(&self) -> OMatrix<T, R, C>
where
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C>,
{
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()?"]
pub fn unscale(&self, real: T::SimdRealField) -> OMatrix<T, R, C>
where
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C>,
{
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()?"]
pub fn scale(&self, real: T::SimdRealField) -> OMatrix<T, R, C>
where
DefaultAllocator: Allocator<R, C>,
DefaultAllocator: Allocator<T, R, C>,
{
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]
pub fn diagonal(&self) -> OVector<T, D>
where
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<T, D>,
{
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]
pub fn map_diagonal<T2: Scalar>(&self, mut f: impl FnMut(T) -> T2) -> OVector<T2, D>
where
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<T2, D>,
{
assert!(
self.is_square(),
@ -1586,7 +1575,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D, D>> SquareMatrix<T, D, S> {
#[must_use]
pub fn trace(&self) -> T
where
T: Scalar + Zero + ClosedAddAssign,
T: Scalar + Zero + ClosedAdd,
{
assert!(
self.is_square(),
@ -1610,7 +1599,7 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
#[must_use]
pub fn symmetric_part(&self) -> OMatrix<T, D, D>
where
DefaultAllocator: Allocator<D, D>,
DefaultAllocator: Allocator<T, D, D>,
{
assert!(
self.is_square(),
@ -1627,7 +1616,7 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
#[must_use]
pub fn hermitian_part(&self) -> OMatrix<T, D, D>
where
DefaultAllocator: Allocator<D, D>,
DefaultAllocator: Allocator<T, D, D>,
{
assert!(
self.is_square(),
@ -1650,7 +1639,7 @@ impl<T: Scalar + Zero + One, D: DimAdd<U1> + IsNotStaticOne, S: RawStorage<T, D,
#[must_use]
pub fn to_homogeneous(&self) -> OMatrix<T, DimSum<D, U1>, DimSum<D, U1>>
where
DefaultAllocator: Allocator<DimSum<D, U1>, DimSum<D, U1>>,
DefaultAllocator: Allocator<T, DimSum<D, U1>, DimSum<D, U1>>,
{
assert!(
self.is_square(),
@ -1671,7 +1660,7 @@ impl<T: Scalar + Zero, D: DimAdd<U1>, S: RawStorage<T, D>> Vector<T, D, S> {
#[must_use]
pub fn to_homogeneous(&self) -> OVector<T, DimSum<D, U1>>
where
DefaultAllocator: Allocator<DimSum<D, U1>>,
DefaultAllocator: Allocator<T, DimSum<D, U1>>,
{
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>>
where
SB: RawStorage<T, DimSum<D, U1>>,
DefaultAllocator: Allocator<D>,
DefaultAllocator: Allocator<T, D>,
{
if v[v.len() - 1].is_zero() {
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]
pub fn push(&self, element: T) -> OVector<T, DimSum<D, U1>>
where
DefaultAllocator: Allocator<DimSum<D, U1>>,
DefaultAllocator: Allocator<T, DimSum<D, U1>>,
{
let len = self.len();
let hnrows = DimSum::<D, U1>::from_usize(len + 1);
@ -2002,12 +1991,8 @@ mod tests {
}
/// # Cross product
impl<
T: Scalar + ClosedAddAssign + ClosedSubAssign + ClosedMulAssign,
R: Dim,
C: Dim,
S: RawStorage<T, R, C>,
> Matrix<T, R, C, S>
impl<T: Scalar + ClosedAdd + ClosedSub + ClosedMul, 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`.
#[inline]
@ -2056,7 +2041,7 @@ impl<
R2: Dim,
C2: Dim,
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>,
{
let shape = self.shape();
@ -2256,7 +2241,7 @@ where
where
T: Scalar,
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()))
}

View File

@ -15,12 +15,16 @@ where
R: Dim,
C: Dim,
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 SimdBool = T::SimdBool;
#[inline]
fn lanes() -> usize {
T::lanes()
}
#[inline]
fn splat(val: Self::Element) -> Self {
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> {
/// 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]
pub unsafe fn from_raw_parts(ptr: $Ptr,
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::`
impl<'a, T, R: Dim, C: Dim> $T<'a, T, R, C, Dyn, Dyn> {
/// 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]
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>
@ -84,10 +75,6 @@ macro_rules! view_storage_impl (
}
/// Create a new matrix view without bounds checking.
///
/// # Safety
///
/// `strides` must be a valid stride indexing.
#[inline]
pub unsafe fn new_with_strides_unchecked<S, RStor, CStor, RStride, CStride>(storage: $SRef,
start: (usize, usize),
@ -141,7 +128,12 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Clone
{
#[inline]
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> {
#[inline]
fn into_owned(self) -> Owned<T, R, C>
where DefaultAllocator: Allocator<R, C> {
where DefaultAllocator: Allocator<T, R, C> {
self.clone_owned()
}
#[inline]
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 it = MatrixIter::new(self).cloned();
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)
}
/// Slices this matrix starting at its component `(irow, icol)` and with `(RVIEW, CVIEW)`
/// consecutive components.
/// Slices this matrix starting at its component `(irow, icol)` and with `(R::dim(),
/// CView::dim())` consecutive components.
#[inline]
#[deprecated = slice_deprecation_note!($fixed_view)]
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)
}
/// Return a view of this matrix starting at its component `(irow, icol)` and with
/// `(RVIEW, CVIEW)` consecutive components.
/// Return a view of this matrix starting at its component `(irow, icol)` and with `(R::dim(),
/// CView::dim())` consecutive components.
#[inline]
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> {

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