Merge remote-tracking branch 'upstream/dev' into rot-interp
This commit is contained in:
commit
5a1f9a5236
|
@ -49,8 +49,6 @@ jobs:
|
||||||
build-nalgebra-all-features:
|
build-nalgebra-all-features:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
# Needed because the --all-features build which enables cuda support.
|
|
||||||
- uses: Jimver/cuda-toolkit@v0.2.4
|
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: cargo build --all-features;
|
- run: cargo build --all-features;
|
||||||
- run: cargo build -p nalgebra-glm --all-features;
|
- run: cargo build -p nalgebra-glm --all-features;
|
||||||
|
@ -61,7 +59,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: test
|
- name: test
|
||||||
run: cargo test --features arbitrary,rand,serde-serialize,sparse,debug,io,compare,libm,proptest-support,slow-tests;
|
run: cargo test --features arbitrary,rand,serde-serialize,sparse,debug,io,compare,libm,proptest-support,slow-tests,rkyv-safe-deser,rayon;
|
||||||
test-nalgebra-glm:
|
test-nalgebra-glm:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
@ -120,20 +118,9 @@ jobs:
|
||||||
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=x86_64-unknown-linux-gnu;
|
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=x86_64-unknown-linux-gnu;
|
||||||
- name: build thumbv7em-none-eabihf nalgebra-glm
|
- name: build thumbv7em-none-eabihf nalgebra-glm
|
||||||
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=thumbv7em-none-eabihf;
|
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=thumbv7em-none-eabihf;
|
||||||
build-cuda:
|
docs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: Jimver/cuda-toolkit@v0.2.4
|
|
||||||
with:
|
|
||||||
cuda: '11.2.2'
|
|
||||||
- name: Install nightly-2021-12-04
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
toolchain: nightly-2021-12-04
|
|
||||||
override: true
|
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: rustup target add nvptx64-nvidia-cuda
|
- name: Generate documentation
|
||||||
- run: cargo build --no-default-features --features cuda
|
run: cargo doc
|
||||||
- run: cargo build --no-default-features --features cuda --target=nvptx64-nvidia-cuda
|
|
||||||
env:
|
|
||||||
CUDA_ARCH: "350"
|
|
||||||
|
|
352
CHANGELOG.md
352
CHANGELOG.md
|
@ -1,16 +1,170 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
All notable changes to `nalgebra`, starting with the version 0.6.0 will be
|
All notable changes to `nalgebra`, starting with the version 0.6.0 will be
|
||||||
documented here.
|
documented here.
|
||||||
|
|
||||||
This project adheres to [Semantic Versioning](https://semver.org/).
|
This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
|
|
||||||
## [0.30.1] (09 Jan. 2022)
|
## Unreleased
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- The `cuda` feature has been removed, as the toolchain it depends on
|
||||||
|
is long abandoned.
|
||||||
|
|
||||||
|
## [0.32.5] (28 March 2024)
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Fix numerical issue on SVD with near-identity matrix.
|
||||||
|
|
||||||
|
## [0.32.4] (19 Feb 2023)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- Add the `glam-0.25` feature to enable conversion from/to types from `glam` v0.25.
|
||||||
|
|
||||||
|
## [0.32.3] (09 July 2023)
|
||||||
|
|
||||||
|
### Modified
|
||||||
|
|
||||||
|
- Statically sized matrices are now serialized as tuples to match how serde
|
||||||
|
serialized plain arrays.
|
||||||
|
- Don’t require `Scalar` for matrix `PartialEq` and `Eq`.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Allow trailing punctuation in macros `vector!`, `matrix!`, `point!`, etc.
|
||||||
|
- 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`.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed severe catastrophic cancellation issue in variance calculation.
|
||||||
|
|
||||||
|
## [0.32.2] (07 March 2023)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add the `glam-0.23` to enable conversion from/to type from `glam` v0.23.
|
||||||
|
|
||||||
|
## [0.32.1] (14 Jan. 2023)
|
||||||
|
|
||||||
|
### Modified
|
||||||
|
|
||||||
|
- Updated `nalgebra-macros` to use the new `Dyn`, avoiding macro-generated deprecation warnings.
|
||||||
|
|
||||||
|
## [0.32.0] (14 Jan. 2023)
|
||||||
|
|
||||||
|
### Modified
|
||||||
|
|
||||||
|
- Renamed all `MatrixSlice` types to `MatrixView`. In general all occurrences of the world `Slice` or `slice` have been
|
||||||
|
replaced by `View` or `view`.
|
||||||
|
- Deprecated all the types involving `Slice` in its name, in favor of the word `View`.
|
||||||
|
- Make it so that most `nalgebra` objects archive as themselves (when using `rkyv` for serialization).
|
||||||
|
- Renamed `Dynamic` to `Dyn` and make `Dyn` a tuple struct.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add `Cholesky::ln_determinant` to compute the natural logarithm of the determinant of a matrix decomposed
|
||||||
|
with Cholesky. This can be more numerically stable than computing the determinant itself when very small and/or
|
||||||
|
large values are involved.
|
||||||
|
- Added new methods `Matrix::as_view` and `Matrix::as_view_mut`, which are very useful when working with view-based
|
||||||
|
APIs.
|
||||||
|
- Added parallel column iterator using `rayon`: `Matrix::par_column_iter` and `Matrix::par_column_iter_mut`. The `rayon`
|
||||||
|
feature must be enabled to access these methods.
|
||||||
|
- Implement `ReshapableStorage` for matrix slices (only for unit strides at the moment).
|
||||||
|
- Add `U0, U1, …` constants alongside the `U0, U1, …` types. This lets us write `U4` instead of `U4::name()` or
|
||||||
|
`Const::<4>` when we need const dimensions.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed the implementation of `Rotation3::euler_angles` to return the angles in the documented order (roll, pitch, yaw).
|
||||||
|
|
||||||
|
## [0.31.4] (13 Nov. 2022)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add a `convert-glam022` feature to enable conversion between `nalgebra` and `glam v0.22`.
|
||||||
|
|
||||||
|
## [0.31.3] (30 Oct. 2022)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add `Matrix::try_cast` to attempt casting the inner scalar types when that cast may fail.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed the usage of `CheckBytes` with `rkyv`.
|
||||||
|
|
||||||
|
## [0.31.2] (09 Oct. 2022)
|
||||||
|
|
||||||
|
### Modified
|
||||||
|
|
||||||
|
- Use `#[inline]` on the `Dim` implementation for `Const` to improve opt-level 1 performance.
|
||||||
|
- Make the `Point::new` constructions const-fn.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add `UnitVector::cast` to change the underlying scalar type.
|
||||||
|
|
||||||
|
## [0.31.1] (31 July 2022)
|
||||||
|
|
||||||
|
### Modified
|
||||||
|
|
||||||
|
- Improve performances of multiplication of two sparse matrices.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add `Matrix::from_row_iterator` to build a matrix from an iterator yielding components in row-major order.
|
||||||
|
- Add support for conversion from/to types of `glam` 0.21.
|
||||||
|
- `nalgebra-sparse`: add support for the matrix-market export of sparse matrices.
|
||||||
|
- `nalgebra-lapack`: add a `GE` for solving the generalized eigenvalues problem.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix `Rotation3::from_matrix` and `UnitQuaternion::from_matrix` when the input matrix is already a valid
|
||||||
|
rotation matrix.
|
||||||
|
|
||||||
|
## [0.31.0] (30 Apr. 2022)
|
||||||
|
|
||||||
|
### Breaking changes
|
||||||
|
|
||||||
|
- Switch to `cust` 0.3 (for CUDA support).
|
||||||
|
- Switch to `rkyv` 0.7
|
||||||
|
- Remove support for serialization based on `abomonation`.
|
||||||
|
- Remove support for conversions between `nalgebra` types and `glam` 0.13.
|
||||||
|
|
||||||
|
### Modified
|
||||||
|
|
||||||
|
- The aliases for `Const` types have been simplified to help `rust-analyzer`.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add `TryFrom` conversion between `UnitVector2/3/4` and `glam`’s `Vec2/3/4`.
|
||||||
|
- `nalgebra-sparse`: added support for serialization of sparse matrices with `serde`.
|
||||||
|
- `nalgebra-sparse`: add a CSC matrix constructor from unsorted (but valid) data.
|
||||||
|
- `nalgebra-lapack`: add generalized eigenvalues/eigenvectors calculation + QZ decomposition.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Improve stability of SVD.
|
||||||
|
- Fix slerp for `UnitComplex`.
|
||||||
|
|
||||||
|
## [0.30.1] (09 Jan. 2022)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
- Add conversion from/to types of `glam` 0.19 and 0.20.
|
- Add conversion from/to types of `glam` 0.19 and 0.20.
|
||||||
|
|
||||||
## [0.30.0] (02 Jan. 2022)
|
## [0.30.0] (02 Jan. 2022)
|
||||||
|
|
||||||
### Breaking changes
|
### Breaking changes
|
||||||
|
|
||||||
- The `Dim` trait is now marked as unsafe.
|
- The `Dim` trait is now marked as unsafe.
|
||||||
- The `Matrix::pow` and `Matrix::pow_mut` methods only allow positive integer exponents now. To compute negative
|
- The `Matrix::pow` and `Matrix::pow_mut` methods only allow positive integer exponents now. To compute negative
|
||||||
exponents, the user is free to invert the matrix before calling `pow` with the exponent’s absolute value.
|
exponents, the user is free to invert the matrix before calling `pow` with the exponent’s absolute value.
|
||||||
|
@ -20,6 +174,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
return `Option<Self>`, meaning that it could be implemented by any type.
|
return `Option<Self>`, meaning that it could be implemented by any type.
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
- Use more concise debug impls for matrices and geometric transformation types.
|
- Use more concise debug impls for matrices and geometric transformation types.
|
||||||
- The singular values computed by the SVD are now sorted in increasing order by default. Use `SVD::new_unordered`
|
- The singular values computed by the SVD are now sorted in increasing order by default. Use `SVD::new_unordered`
|
||||||
instead to reproduce the older behavior without the sorting overhead.
|
instead to reproduce the older behavior without the sorting overhead.
|
||||||
|
@ -29,6 +184,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
- The `Matrix::pow` and `Matrix::pow_mut` methods will now also work with integer matrices.
|
- The `Matrix::pow` and `Matrix::pow_mut` methods will now also work with integer matrices.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added the conversion trait `From<Vec<T>>` and method `from_vec_storage` for `RowDVector`.
|
- Added the conversion trait `From<Vec<T>>` and method `from_vec_storage` for `RowDVector`.
|
||||||
- Added implementation of `From` and `Into` for converting between `nalgebra` types and types from
|
- Added implementation of `From` and `Into` for converting between `nalgebra` types and types from
|
||||||
`glam 0.18`. These can be enabled by enabling the `convert-glam018` cargo features.
|
`glam 0.18`. These can be enabled by enabling the `convert-glam018` cargo features.
|
||||||
|
@ -49,6 +205,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
- `nalgebra-sparse`: added reading MatrixMarked data files to a sparse `CooMatrix`.
|
- `nalgebra-sparse`: added reading MatrixMarked data files to a sparse `CooMatrix`.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed a potential unsoundness with `matrix.get(i)` and `matrix.get_mut(i)` where `i` is an `usize`, and `matrix`
|
- Fixed a potential unsoundness with `matrix.get(i)` and `matrix.get_mut(i)` where `i` is an `usize`, and `matrix`
|
||||||
is a matrix slice with non-default strides.
|
is a matrix slice with non-default strides.
|
||||||
- Fixed potential unsoundness with `vector.perp` where `vector` isn’t actually a 2D vector as expected.
|
- Fixed potential unsoundness with `vector.perp` where `vector` isn’t actually a 2D vector as expected.
|
||||||
|
@ -57,9 +214,10 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
- Fixed the `no-std` build of `nalgebra-glm`.
|
- Fixed the `no-std` build of `nalgebra-glm`.
|
||||||
- Fix the `pow` and `pow_mut` functions (the result was incorrect for some exponent values).
|
- Fix the `pow` and `pow_mut` functions (the result was incorrect for some exponent values).
|
||||||
|
|
||||||
|
|
||||||
## [0.29.0]
|
## [0.29.0]
|
||||||
|
|
||||||
### Breaking changes
|
### Breaking changes
|
||||||
|
|
||||||
- We updated to the version 0.6 of `simba`. This means that the trait bounds `T: na::RealField`, `na::ComplexField`,
|
- We updated to the version 0.6 of `simba`. This means that the trait bounds `T: na::RealField`, `na::ComplexField`,
|
||||||
`na::SimdRealField`, `na:SimdComplexField` no imply that `T: Copy` (they only imply that `T: Clone`). This may affect
|
`na::SimdRealField`, `na:SimdComplexField` no imply that `T: Copy` (they only imply that `T: Clone`). This may affect
|
||||||
generic code.
|
generic code.
|
||||||
|
@ -71,6 +229,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
way.
|
way.
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
- `Orthographic3::from_matrix_unchecked` is now `const fn`.
|
- `Orthographic3::from_matrix_unchecked` is now `const fn`.
|
||||||
- `Perspective3::from_matrix_unchecked` is now `const fn`.
|
- `Perspective3::from_matrix_unchecked` is now `const fn`.
|
||||||
- `Rotation::from_matrix_unchecked` is now `const fn`.
|
- `Rotation::from_matrix_unchecked` is now `const fn`.
|
||||||
|
@ -78,6 +237,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
`Copy` are now much safer to work with thanks to the refactoring of the `Allocator` system.
|
`Copy` are now much safer to work with thanks to the refactoring of the `Allocator` system.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- The conversion traits form the `bytemuck` crates are now implemented for the geometric types too.
|
- The conversion traits form the `bytemuck` crates are now implemented for the geometric types too.
|
||||||
- Added operator overloading for `Transform * UnitComplex`, `UnitComplex * Transform`, `Transform ×= UnitComplex`,
|
- Added operator overloading for `Transform * UnitComplex`, `UnitComplex * Transform`, `Transform ×= UnitComplex`,
|
||||||
`Transform ÷= UnitComplex`.
|
`Transform ÷= UnitComplex`.
|
||||||
|
@ -88,16 +248,21 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
cargo features.
|
cargo features.
|
||||||
|
|
||||||
## [0.28.0]
|
## [0.28.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Implement `Hash` for `Transform`.
|
- Implement `Hash` for `Transform`.
|
||||||
- Implement `Borrow` and `BorrowMut` for contiguous slices.
|
- Implement `Borrow` and `BorrowMut` for contiguous slices.
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
- The `OPoint<T, D>` type has been added. It takes the dimension number as a type-level integer (e.g. `Const<3>`) instead
|
|
||||||
|
- The `OPoint<T, D>` type has been added. It takes the dimension number as a type-level integer (e.g. `Const<3>`)
|
||||||
|
instead
|
||||||
of a const-generic. The type `Point<T, const D: usize>` is now an alias for `OPoint`. This changes doesn't affect any
|
of a const-generic. The type `Point<T, const D: usize>` is now an alias for `OPoint`. This changes doesn't affect any
|
||||||
of the existing code using `Point`. However, it will allow the use `OPoint` in a generic context where the dimension
|
of the existing code using `Point`. However, it will allow the use `OPoint` in a generic context where the dimension
|
||||||
cannot be easily expressed as a const-generic (because of the current limitation of const-generics in Rust).
|
cannot be easily expressed as a const-generic (because of the current limitation of const-generics in Rust).
|
||||||
- Several clippy warnings were fixed. This results in some method signature changes (e.g. taking `self` instead of `&self`)
|
- Several clippy warnings were fixed. This results in some method signature changes (e.g. taking `self` instead
|
||||||
|
of `&self`)
|
||||||
but this should not have any practical infulances on existing codebase.
|
but this should not have any practical infulances on existing codebase.
|
||||||
- The `Point::new` constructors are no longer const-fn. This is due to some limitations in const-fn
|
- The `Point::new` constructors are no longer const-fn. This is due to some limitations in const-fn
|
||||||
not allowing custom trait-bounds. Use the `point!` macro instead to build points in const environments.
|
not allowing custom trait-bounds. Use the `point!` macro instead to build points in const environments.
|
||||||
|
@ -105,30 +270,38 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
- Methods returning `Result<(), ()>` now return `bool` instead.
|
- Methods returning `Result<(), ()>` now return `bool` instead.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed a potential unsoundess issue when converting a mutable slice to a `&mut[T]`.
|
- Fixed a potential unsoundess issue when converting a mutable slice to a `&mut[T]`.
|
||||||
|
|
||||||
## [0.27.1]
|
## [0.27.1]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed a bug in the conversion from `glam::Vec2` or `glam::DVec2` to `Isometry2`.
|
- Fixed a bug in the conversion from `glam::Vec2` or `glam::DVec2` to `Isometry2`.
|
||||||
|
|
||||||
## [0.27.0]
|
## [0.27.0]
|
||||||
|
|
||||||
This removes the `convert-glam` and `convert-glam-unchecked` optional features.
|
This removes the `convert-glam` and `convert-glam-unchecked` optional features.
|
||||||
Instead, this adds the `convert-glam013`, `convert-glam014`, and `convert-glam015` optional features for
|
Instead, this adds the `convert-glam013`, `convert-glam014`, and `convert-glam015` optional features for
|
||||||
conversions targeting the versions 0.13, 0.14, and 0.15 of `glam`.
|
conversions targeting the versions 0.13, 0.14, and 0.15 of `glam`.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add macros `matrix!`, `dmatrix!`, `vector!`, `dvector!`, `point!` for constructing matrices/vectors/points in a
|
- Add macros `matrix!`, `dmatrix!`, `vector!`, `dvector!`, `point!` for constructing matrices/vectors/points in a
|
||||||
more convenient way. See [#886](https://github.com/dimforge/nalgebra/pull/886) and [#899](https://github.com/dimforge/nalgebra/pull/899).
|
more convenient way. See [#886](https://github.com/dimforge/nalgebra/pull/886)
|
||||||
|
and [#899](https://github.com/dimforge/nalgebra/pull/899).
|
||||||
- Add `CooMatrix::reserve` to `nalgebra-sparse`.
|
- Add `CooMatrix::reserve` to `nalgebra-sparse`.
|
||||||
- Add basic support for serialization using `rkyv`. Can be enabled with the features `rkyv-serialize` or
|
- Add basic support for serialization using `rkyv`. Can be enabled with the features `rkyv-serialize` or
|
||||||
`rkyv-serialize-no-std`.
|
`rkyv-serialize-no-std`.
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed a potential unsoundness issue after deserializing an invalid `DVector` using `serde`.
|
- Fixed a potential unsoundness issue after deserializing an invalid `DVector` using `serde`.
|
||||||
|
|
||||||
## [0.26.2]
|
## [0.26.2]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Conversion from an array `[T; D]` to an isometry `Isometry<T, _, D>` (as a translation).
|
- Conversion from an array `[T; D]` to an isometry `Isometry<T, _, D>` (as a translation).
|
||||||
- Conversion from a static vector `SVector<T; D>` to an isometry `Isometry<T, _, D>` (as a translation).
|
- Conversion from a static vector `SVector<T; D>` to an isometry `Isometry<T, _, D>` (as a translation).
|
||||||
- Conversion from a point `Point<T; D>` to an isometry `Isometry<T, _, D>` (as a translation).
|
- Conversion from a point `Point<T; D>` to an isometry `Isometry<T, _, D>` (as a translation).
|
||||||
|
@ -138,14 +311,17 @@ conversions targeting the versions 0.13, 0.14, and 0.15 of `glam`.
|
||||||
- Conversion of a glam type `Vec2/3/4` from/to a `Translation2/3/4`.
|
- Conversion of a glam type `Vec2/3/4` from/to a `Translation2/3/4`.
|
||||||
|
|
||||||
## [0.26.1]
|
## [0.26.1]
|
||||||
|
|
||||||
Fix a regression introduced in 0.26.0 preventing `DVector` from being serialized with `serde`.
|
Fix a regression introduced in 0.26.0 preventing `DVector` from being serialized with `serde`.
|
||||||
|
|
||||||
## [0.26.0]
|
## [0.26.0]
|
||||||
|
|
||||||
This release integrates `min-const-generics` to nalgebra. See
|
This release integrates `min-const-generics` to nalgebra. See
|
||||||
[our blog post](https://www.dimforge.com/blog/2021/04/12/integrating-const-generics-to-nalgebra)
|
[our blog post](https://www.dimforge.com/blog/2021/04/12/integrating-const-generics-to-nalgebra)
|
||||||
for details about this release.
|
for details about this release.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add type aliases for unit vector, e.g., `UnitVector3`.
|
- Add type aliases for unit vector, e.g., `UnitVector3`.
|
||||||
- Add a `pow` and `pow_mut` function to square matrices.
|
- Add a `pow` and `pow_mut` function to square matrices.
|
||||||
- Add `Cholesky::determinant` to compute the determinant of a matrix decomposed
|
- Add `Cholesky::determinant` to compute the determinant of a matrix decomposed
|
||||||
|
@ -153,8 +329,8 @@ for details about this release.
|
||||||
- Add the `serde-serialize-no-std` feature to enable serialization of static matrices/vectors
|
- Add the `serde-serialize-no-std` feature to enable serialization of static matrices/vectors
|
||||||
with serde, but without requiring `std`.
|
with serde, but without requiring `std`.
|
||||||
|
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
- The `serde` crate isn't enabled by default now. Enable the `serde-serialize` or the
|
- The `serde` crate isn't enabled by default now. Enable the `serde-serialize` or the
|
||||||
`serde-serialize-no-std` features instead.
|
`serde-serialize-no-std` features instead.
|
||||||
- The `Const<const D: usize>` type has been introduced to represent dimensions known
|
- The `Const<const D: usize>` type has been introduced to represent dimensions known
|
||||||
|
@ -176,16 +352,22 @@ for details about this release.
|
||||||
constructor is also a `const fn` now.
|
constructor is also a `const fn` now.
|
||||||
|
|
||||||
## [0.25.4]
|
## [0.25.4]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix a compilation error when only the `serde-serialize` feature is enabled.
|
- Fix a compilation error when only the `serde-serialize` feature is enabled.
|
||||||
|
|
||||||
## [0.25.3]
|
## [0.25.3]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- The `Vector::simd_cap_magnitude` method to cap the magnitude of the vector with
|
- The `Vector::simd_cap_magnitude` method to cap the magnitude of the vector with
|
||||||
SIMD components.
|
SIMD components.
|
||||||
|
|
||||||
## [0.25.2]
|
## [0.25.2]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- A `convert-glam` cargo feature to enable implementations of `From` traits to convert
|
- A `convert-glam` cargo feature to enable implementations of `From` traits to convert
|
||||||
between `glam` types and `nalgebra` types.
|
between `glam` types and `nalgebra` types.
|
||||||
- A `convert-glam-unchecked` cargo feature to enable some extra `glam`/`nalgebra` conversions that may
|
- A `convert-glam-unchecked` cargo feature to enable some extra `glam`/`nalgebra` conversions that may
|
||||||
|
@ -196,56 +378,70 @@ for details about this release.
|
||||||
type of the components of a given entity. Example: `vector.cast::<f32>()`.
|
type of the components of a given entity. Example: `vector.cast::<f32>()`.
|
||||||
|
|
||||||
## [0.25.1]
|
## [0.25.1]
|
||||||
|
|
||||||
This release replaces the version 0.25.0 which has been yanked. The 0.25.0 version
|
This release replaces the version 0.25.0 which has been yanked. The 0.25.0 version
|
||||||
added significant complication to build `nalgebra` targeting a `#[no-std]` platform
|
added significant complication to build `nalgebra` targeting a `#[no-std]` platform
|
||||||
not supported by `rand`.
|
not supported by `rand`.
|
||||||
|
|
||||||
The `rand` dependency is now optional (and disabled by default). You may enable it with:
|
The `rand` dependency is now optional (and disabled by default). You may enable it with:
|
||||||
|
|
||||||
- The `rand-no-std` cargo feature when targeting a `#[no-std]` environment.
|
- The `rand-no-std` cargo feature when targeting a `#[no-std]` environment.
|
||||||
- The `rand` cargo feature when targeting a `std` environment.
|
- The `rand` cargo feature when targeting a `std` environment.
|
||||||
|
|
||||||
## [0.25.0] - Yanked
|
## [0.25.0] - Yanked
|
||||||
|
|
||||||
This updates all the dependencies of nalgebra to their latest version, including:
|
This updates all the dependencies of nalgebra to their latest version, including:
|
||||||
|
|
||||||
- rand 0.8
|
- rand 0.8
|
||||||
- proptest 1.0
|
- proptest 1.0
|
||||||
- simba 0.4
|
- simba 0.4
|
||||||
|
|
||||||
### New crate: nalgebra-sparse
|
### New crate: nalgebra-sparse
|
||||||
|
|
||||||
Alongside this release of `nalgebra`, we are releasing `nalgebra-sparse`: a crate dedicated to sparse matrix
|
Alongside this release of `nalgebra`, we are releasing `nalgebra-sparse`: a crate dedicated to sparse matrix
|
||||||
computation with `nalgebra`. The `sparse` module of `nalgebra`itself still exists for backward compatibility,
|
computation with `nalgebra`. The `sparse` module of `nalgebra`itself still exists for backward compatibility,
|
||||||
but it will be deprecated soon in favor of the `nalgebra-sparse` crate.
|
but it will be deprecated soon in favor of the `nalgebra-sparse` crate.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* Add `UnitDualQuaternion`, a dual-quaternion with unit magnitude which can be used as an isometry transformation.
|
* Add `UnitDualQuaternion`, a dual-quaternion with unit magnitude which can be used as an isometry transformation.
|
||||||
* Add `UDU::new()` and `matrix.udu()` to compute the UDU factorization of a matrix.
|
* Add `UDU::new()` and `matrix.udu()` to compute the UDU factorization of a matrix.
|
||||||
* Add `ColPivQR::new()` and `matrix.col_piv_qr()` to compute the QR decomposition with column pivoting of a matrix.
|
* Add `ColPivQR::new()` and `matrix.col_piv_qr()` to compute the QR decomposition with column pivoting of a matrix.
|
||||||
* Add `from_basis_unchecked` to all the rotation types. This builds a rotation from a set of basis vectors (representing the columns of the corresponding rotation matrix).
|
* Add `from_basis_unchecked` to all the rotation types. This builds a rotation from a set of basis vectors (representing
|
||||||
|
the columns of the corresponding rotation matrix).
|
||||||
* Add `Matrix::cap_magnitude` to cap the magnitude of a vector.
|
* Add `Matrix::cap_magnitude` to cap the magnitude of a vector.
|
||||||
* Add `UnitQuaternion::append_axisangle_linearized` to approximately append a rotation represented as an axis-angle to a rotation represented as an unit quaternion.
|
* Add `UnitQuaternion::append_axisangle_linearized` to approximately append a rotation represented as an axis-angle to a
|
||||||
|
rotation represented as an unit quaternion.
|
||||||
* Mark the iterators on matrix components as `DoubleEndedIter`.
|
* Mark the iterators on matrix components as `DoubleEndedIter`.
|
||||||
* Re-export `simba::simd::SimdValue` at the root of the `nalgebra` crate.
|
* Re-export `simba::simd::SimdValue` at the root of the `nalgebra` crate.
|
||||||
|
|
||||||
## [0.24.0]
|
## [0.24.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* The `DualQuaternion` type. It is still work-in-progress, but the basics are here:
|
* The `DualQuaternion` type. It is still work-in-progress, but the basics are here:
|
||||||
creation from its real and dual part, multiplication of two dual quaternions,
|
creation from its real and dual part, multiplication of two dual quaternions,
|
||||||
and normalization.
|
and normalization.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
* There is no blanket `impl<T> PartialEq for Unit<T>` anymore. Instead, it is
|
* There is no blanket `impl<T> PartialEq for Unit<T>` anymore. Instead, it is
|
||||||
implemented specifically for `UnitComplex`, `UnitQuaternion` and `Unit<Vector>`.
|
implemented specifically for `UnitComplex`, `UnitQuaternion` and `Unit<Vector>`.
|
||||||
|
|
||||||
## [0.23.2]
|
## [0.23.2]
|
||||||
|
|
||||||
In this release, we improved the documentation of some of the geometric types
|
In this release, we improved the documentation of some of the geometric types
|
||||||
by applying changes similar to what we did in the version 0.23.1 for matrices.
|
by applying changes similar to what we did in the version 0.23.1 for matrices.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* The `Isometry::inv_mul` method which is a more efficient way of doing
|
* The `Isometry::inv_mul` method which is a more efficient way of doing
|
||||||
`isometry1.inverse() * isometry2`.
|
`isometry1.inverse() * isometry2`.
|
||||||
|
|
||||||
## [0.23.1]
|
## [0.23.1]
|
||||||
|
|
||||||
In this release we improved the documentation of the matrix and vector types by:
|
In this release we improved the documentation of the matrix and vector types by:
|
||||||
|
|
||||||
- Grouping `impl` bocks logically, adding a title comment to these impl blocks.
|
- Grouping `impl` bocks logically, adding a title comment to these impl blocks.
|
||||||
- Reference these impl blocks docs at the top of the documentation page for `Matrix`.
|
- Reference these impl blocks docs at the top of the documentation page for `Matrix`.
|
||||||
- Reduce the depth of type aliasing. Now all vector and matrix types are aliases of `Matrix`
|
- Reduce the depth of type aliasing. Now all vector and matrix types are aliases of `Matrix`
|
||||||
|
@ -254,13 +450,17 @@ In this release we improved the documentation of the matrix and vector types by:
|
||||||
## [0.23.0]
|
## [0.23.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
* The `.inverse_transform_unit_vector(v)` was added to `Rotation2/3`, `Isometry2/3`, `UnitQuaternion`, and `UnitComplex`.
|
|
||||||
|
* The `.inverse_transform_unit_vector(v)` was added to `Rotation2/3`, `Isometry2/3`, `UnitQuaternion`,
|
||||||
|
and `UnitComplex`.
|
||||||
It applies the corresponding rotation to a unit vector `Unit<Vector2/3>`.
|
It applies the corresponding rotation to a unit vector `Unit<Vector2/3>`.
|
||||||
* The `Point.map(f)` and `Point.apply(f)` to apply a function to each component of the point, similarly to `Vector.map(f)`
|
* The `Point.map(f)` and `Point.apply(f)` to apply a function to each component of the point, similarly
|
||||||
|
to `Vector.map(f)`
|
||||||
and `Vector.apply(f)`.
|
and `Vector.apply(f)`.
|
||||||
* The `Quaternion::from([N; 4])` conversion to build a quaternion from an array of four elements.
|
* The `Quaternion::from([N; 4])` conversion to build a quaternion from an array of four elements.
|
||||||
* The `Isometry::from(Translation)` conversion to build an isometry from a translation.
|
* The `Isometry::from(Translation)` conversion to build an isometry from a translation.
|
||||||
* The `Vector::ith_axis(i)` which build a unit vector, e.g., `Unit<Vector3<f32>>` with its i-th component set to 1.0, and the
|
* The `Vector::ith_axis(i)` which build a unit vector, e.g., `Unit<Vector3<f32>>` with its i-th component set to 1.0,
|
||||||
|
and the
|
||||||
others set to zero.
|
others set to zero.
|
||||||
* The `Isometry.lerp_slerp` and `Isometry.try_lerp_slerp` methods to interpolate between two isometries using linear
|
* The `Isometry.lerp_slerp` and `Isometry.try_lerp_slerp` methods to interpolate between two isometries using linear
|
||||||
interpolation for the translational part, and spherical interpolation for the rotational part.
|
interpolation for the translational part, and spherical interpolation for the rotational part.
|
||||||
|
@ -268,12 +468,14 @@ In this release we improved the documentation of the matrix and vector types by:
|
||||||
spherical interpolation.
|
spherical interpolation.
|
||||||
|
|
||||||
## [0.22.0]
|
## [0.22.0]
|
||||||
|
|
||||||
In this release, we are using the new version 0.2 of simba. One major change of that version is that the
|
In this release, we are using the new version 0.2 of simba. One major change of that version is that the
|
||||||
use of `libm` is now opt-in when building targeting `no-std` environment. If you are using floating-point
|
use of `libm` is now opt-in when building targeting `no-std` environment. If you are using floating-point
|
||||||
operations with nalgebra in a `no-std` environment, you will need to enable the new `libm` feature
|
operations with nalgebra in a `no-std` environment, you will need to enable the new `libm` feature
|
||||||
of nalgebra for your code to compile again.
|
of nalgebra for your code to compile again.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* The `libm` feature that enables `libm` when building for `no-std` environment.
|
* The `libm` feature that enables `libm` when building for `no-std` environment.
|
||||||
* The `libm-force` feature that enables `libm` even when building for a not `no-std` environment.
|
* The `libm-force` feature that enables `libm` even when building for a not `no-std` environment.
|
||||||
* `Cholesky::new_unchecked` which build a Cholesky decomposition without checking that its input is
|
* `Cholesky::new_unchecked` which build a Cholesky decomposition without checking that its input is
|
||||||
|
@ -284,6 +486,7 @@ of nalgebra for your code to compile again.
|
||||||
* The `Vector::ith(i, x)` that builds a vector filled with zeros except for the `i`-th component set to `x`.
|
* The `Vector::ith(i, x)` that builds a vector filled with zeros except for the `i`-th component set to `x`.
|
||||||
|
|
||||||
## [0.21.0]
|
## [0.21.0]
|
||||||
|
|
||||||
In this release, we are no longer relying on traits from the __alga__ crate for our generic code.
|
In this release, we are no longer relying on traits from the __alga__ crate for our generic code.
|
||||||
Instead, we use traits from the new [simba](https://crates.io/crates/simba) crate which are both
|
Instead, we use traits from the new [simba](https://crates.io/crates/simba) crate which are both
|
||||||
simpler, and allow for significant optimizations like AoSoA SIMD.
|
simpler, and allow for significant optimizations like AoSoA SIMD.
|
||||||
|
@ -292,75 +495,98 @@ Refer to the [monthly dimforge blogpost](https://www.dimforge.org/blog/2020/04/0
|
||||||
for details about this switch and its benefits.
|
for details about this switch and its benefits.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* It is now possible to use SIMD types like `simba::f32x4` as scalar types for nalgebra's matrices and
|
* It is now possible to use SIMD types like `simba::f32x4` as scalar types for nalgebra's matrices and
|
||||||
geometric types.
|
geometric types.
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* Use of traits like `alga::general::{RealField, ComplexField}` have now been replaced by
|
* Use of traits like `alga::general::{RealField, ComplexField}` have now been replaced by
|
||||||
`simba::scalar::{RealField, ComplexField}`.
|
`simba::scalar::{RealField, ComplexField}`.
|
||||||
* The implementation of traits from the __alga__ crate (and well as the dependency to _alga__) are now
|
* The implementation of traits from the __alga__ crate (and well as the dependency to _alga__) are now
|
||||||
omitted unless the `alga` cargo feature is activated.
|
omitted unless the `alga` cargo feature is activated.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
* The `Neg` unary operator is no longer implemented for `UnitComplex` and `UnitQuaternion`. This caused
|
* The `Neg` unary operator is no longer implemented for `UnitComplex` and `UnitQuaternion`. This caused
|
||||||
hard-to-track errors when we mistakenly write, e.g., `-q * v` instead of `-(q * v)`.
|
hard-to-track errors when we mistakenly write, e.g., `-q * v` instead of `-(q * v)`.
|
||||||
* The `na::convert_unchecked` is no longer marked as unsafe.
|
* The `na::convert_unchecked` is no longer marked as unsafe.
|
||||||
|
|
||||||
## [0.20.0]
|
## [0.20.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* `cholesky.rank_one_update(...)` which performs a rank-one update on the cholesky decomposition of a matrix.
|
* `cholesky.rank_one_update(...)` which performs a rank-one update on the cholesky decomposition of a matrix.
|
||||||
* `From<&Matrix>` is now implemented for matrix slices.
|
* `From<&Matrix>` is now implemented for matrix slices.
|
||||||
* `.try_set_magnitude(...)` which sets the magnitude of a vector, while keeping its direction.
|
* `.try_set_magnitude(...)` which sets the magnitude of a vector, while keeping its direction.
|
||||||
* Implementations of `From` and `Into` for the conversion between matrix slices and standard (`&[N]` `&mut [N]`) slices.
|
* Implementations of `From` and `Into` for the conversion between matrix slices and standard (`&[N]` `&mut [N]`) slices.
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* We started some major changes in order to allow non-Copy types to be used as scalar types inside of matrices/vectors.
|
* We started some major changes in order to allow non-Copy types to be used as scalar types inside of matrices/vectors.
|
||||||
|
|
||||||
## [0.19.0]
|
## [0.19.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* `.remove_rows_at` and `remove_columns_at` which removes a set of rows or columns (specified by indices) from a matrix.
|
* `.remove_rows_at` and `remove_columns_at` which removes a set of rows or columns (specified by indices) from a matrix.
|
||||||
* Several formatting traits have been implemented for all matrices/vectors: `LowerExp`, `UpperExp`, `Octal`, `LowerHex`,
|
* Several formatting traits have been implemented for all matrices/vectors: `LowerExp`, `UpperExp`, `Octal`, `LowerHex`,
|
||||||
`UpperHex`, `Binary`, `Pointer`.
|
`UpperHex`, `Binary`, `Pointer`.
|
||||||
* `UnitQuaternion::quaternions_mean(...)` which computes the mean rotation of a set of unit quaternions. This implements
|
* `UnitQuaternion::quaternions_mean(...)` which computes the mean rotation of a set of unit quaternions. This implements
|
||||||
the algorithm from _Oshman, Yaakov, and Avishy Carmi, "Attitude estimation from vector observations using a genetic-algorithm-embedded quaternion particle filter."
|
the algorithm from _Oshman, Yaakov, and Avishy Carmi, "Attitude estimation from vector observations using a
|
||||||
|
genetic-algorithm-embedded quaternion particle filter."
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* It is now possible to get the `min/max` element of unsigned integer matrices.
|
* It is now possible to get the `min/max` element of unsigned integer matrices.
|
||||||
|
|
||||||
### Added to nalgebra-glm
|
### Added to nalgebra-glm
|
||||||
|
|
||||||
* Some infinite and reversed perspectives: `::infinite_perspective_rh_no`, `::infinite_perspective_rh_zo`,
|
* Some infinite and reversed perspectives: `::infinite_perspective_rh_no`, `::infinite_perspective_rh_zo`,
|
||||||
`::reversed_perspective_rh_zo`, and `::reversed_infinite_perspective_rh_zo`.
|
`::reversed_perspective_rh_zo`, and `::reversed_infinite_perspective_rh_zo`.
|
||||||
|
|
||||||
## [0.18.0]
|
## [0.18.0]
|
||||||
|
|
||||||
This release adds full complex number support to nalgebra. This includes all common vector/matrix operations as well
|
This release adds full complex number support to nalgebra. This includes all common vector/matrix operations as well
|
||||||
as matrix decomposition. This excludes geometric type (like `Isometry`, `Rotation`, `Translation`, etc.) from the
|
as matrix decomposition. This excludes geometric type (like `Isometry`, `Rotation`, `Translation`, etc.) from the
|
||||||
`geometry` module.
|
`geometry` module.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
#### Quaternion and geometric operations
|
#### Quaternion and geometric operations
|
||||||
* Add trigonometric functions for quaternions: `.cos, .sin, .tan, .acos, .asin, .atan, .cosh, .sinh, .tanh, .acosh, .asinh, .atanh`.
|
|
||||||
|
* Add trigonometric functions for
|
||||||
|
quaternions: `.cos, .sin, .tan, .acos, .asin, .atan, .cosh, .sinh, .tanh, .acosh, .asinh, .atanh`.
|
||||||
* Add geometric algebra operations for quaternions: `.inner, .outer, .project, .rejection`
|
* Add geometric algebra operations for quaternions: `.inner, .outer, .project, .rejection`
|
||||||
* Add `.left_div, .right_div` for quaternions.
|
* Add `.left_div, .right_div` for quaternions.
|
||||||
* Add `.renormalize` to `Unit<...>` and `Rotation3` to correct potential drift due to repeated operations.
|
* Add `.renormalize` to `Unit<...>` and `Rotation3` to correct potential drift due to repeated operations.
|
||||||
Those drifts could cause them not to be pure rotations anymore.
|
Those drifts could cause them not to be pure rotations anymore.
|
||||||
|
|
||||||
#### Convolution
|
#### Convolution
|
||||||
|
|
||||||
* `.convolve_full(kernel)` returns the convolution of `self` by `kernel`.
|
* `.convolve_full(kernel)` returns the convolution of `self` by `kernel`.
|
||||||
* `.convolve_valid(kernel)` returns the convolution of `self` by `kernel` after removal of all the elements relying on zero-padding.
|
* `.convolve_valid(kernel)` returns the convolution of `self` by `kernel` after removal of all the elements relying on
|
||||||
|
zero-padding.
|
||||||
* `.convolve_same(kernel)` returns the convolution of `self` by `kernel` with a result of the same size as `self`.
|
* `.convolve_same(kernel)` returns the convolution of `self` by `kernel` with a result of the same size as `self`.
|
||||||
|
|
||||||
#### Complex number support
|
#### Complex number support
|
||||||
|
|
||||||
* Add the `::from_matrix` constructor too all rotation types to extract a rotation from a raw matrix.
|
* Add the `::from_matrix` constructor too all rotation types to extract a rotation from a raw matrix.
|
||||||
* Add the `::from_matrix_eps` constructor too all rotation types to extract a rotation from a raw matrix. This takes
|
* Add the `::from_matrix_eps` constructor too all rotation types to extract a rotation from a raw matrix. This takes
|
||||||
more argument than `::from_matrix` to control the convergence of the underlying optimization algorithm.
|
more argument than `::from_matrix` to control the convergence of the underlying optimization algorithm.
|
||||||
* Add `.camax()` which returns the matrix component with the greatest L1-norm.
|
* Add `.camax()` which returns the matrix component with the greatest L1-norm.
|
||||||
* Add `.camin()` which returns the matrix component with the smallest L1-norm.
|
* Add `.camin()` which returns the matrix component with the smallest L1-norm.
|
||||||
* Add `.ad_mul(b)` for matrix-multiplication of `self.adjoint() * b`.
|
* Add `.ad_mul(b)` for matrix-multiplication of `self.adjoint() * b`.
|
||||||
* Add `.ad_mul_to(b)` which is the same as `.ad_mul` but with a provided matrix to be filled with the result of the multiplication.
|
* Add `.ad_mul_to(b)` which is the same as `.ad_mul` but with a provided matrix to be filled with the result of the
|
||||||
|
multiplication.
|
||||||
* Add BLAS operations involving complex conjugation (following similar names as the original BLAS spec):
|
* Add BLAS operations involving complex conjugation (following similar names as the original BLAS spec):
|
||||||
* `.dotc(rhs)` equal to `self.adjoint() * rhs`.
|
* `.dotc(rhs)` equal to `self.adjoint() * rhs`.
|
||||||
* `.gerc(alpha, x, y, beta)` equivalent to `self = alpha * x * y.adjoint() + beta * self`
|
* `.gerc(alpha, x, y, beta)` equivalent to `self = alpha * x * y.adjoint() + beta * self`
|
||||||
* `.hegerc` which is like `gerc` but for Hermitian matrices.
|
* `.hegerc` which is like `gerc` but for Hermitian matrices.
|
||||||
* `.syger` which is the new name of `.ger_symm` which is equivalent to `self = alpha * x * y.transpose() + beta * self`.
|
* `.syger` which is the new name of `.ger_symm` which is equivalent
|
||||||
* `.sygemv` which is the new name of `.gemv_symm` which is equivalent to `self = alpha * a * x + beta * self` with `a` symmetric.
|
to `self = alpha * x * y.transpose() + beta * self`.
|
||||||
|
* `.sygemv` which is the new name of `.gemv_symm` which is equivalent to `self = alpha * a * x + beta * self`
|
||||||
|
with `a` symmetric.
|
||||||
* `.hegemv(alpha, a, x, beta)` which is like `.sygemv` but with `a` Hermitian.
|
* `.hegemv(alpha, a, x, beta)` which is like `.sygemv` but with `a` Hermitian.
|
||||||
* `.gemv_ad(alpha, a, x, beta)` which is equivalent to `self = alpha * a.adjoint() * x + beta * self`.
|
* `.gemv_ad(alpha, a, x, beta)` which is equivalent to `self = alpha * a.adjoint() * x + beta * self`.
|
||||||
* `.gemm_ad(alpha, a, b, beta)` which is equivalent to `self = alpha * a.adjoint() * b + beta * self`.
|
* `.gemm_ad(alpha, a, b, beta)` which is equivalent to `self = alpha * a.adjoint() * b + beta * self`.
|
||||||
|
@ -369,14 +595,17 @@ as matrix decomposition. This excludes geometric type (like `Isometry`, `Rotatio
|
||||||
Note that all the other BLAS operation will continue to work for all fields, including floats and complex numbers.
|
Note that all the other BLAS operation will continue to work for all fields, including floats and complex numbers.
|
||||||
|
|
||||||
### Renamed
|
### Renamed
|
||||||
* `RealSchur` has been renamed `Schur` because it can now work with complex matrices.
|
|
||||||
|
|
||||||
|
* `RealSchur` has been renamed `Schur` because it can now work with complex matrices.
|
||||||
|
|
||||||
## [0.17.0]
|
## [0.17.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
* Add swizzling up to dimension 3 for vectors. For example, you can do `v.zxy()` as an equivalent to `Vector3::new(v.z, v.x, v.y)`.
|
|
||||||
* Add swizzling up to dimension 3 for points. For example, you can do `p.zxy()` as an equivalent to `Point3::new(p.z, p.x, p.y)`.
|
* Add swizzling up to dimension 3 for vectors. For example, you can do `v.zxy()` as an equivalent
|
||||||
|
to `Vector3::new(v.z, v.x, v.y)`.
|
||||||
|
* Add swizzling up to dimension 3 for points. For example, you can do `p.zxy()` as an equivalent
|
||||||
|
to `Point3::new(p.z, p.x, p.y)`.
|
||||||
* Add `.copy_from_slice` to copy matrix components from a slice in column-major order.
|
* Add `.copy_from_slice` to copy matrix components from a slice in column-major order.
|
||||||
* Add `.dot` to quaternions.
|
* Add `.dot` to quaternions.
|
||||||
* Add `.zip_zip_map` for iterating on three matrices simultaneously, and applying a closure to them.
|
* Add `.zip_zip_map` for iterating on three matrices simultaneously, and applying a closure to them.
|
||||||
|
@ -387,7 +616,8 @@ Note that all the other BLAS operation will continue to work for all fields, inc
|
||||||
* Add `From/Into` impls to allow the conversion of any transformation type to a matrix.
|
* Add `From/Into` impls to allow the conversion of any transformation type to a matrix.
|
||||||
* Add `Into` impls to convert a matrix slice into an owned matrix.
|
* Add `Into` impls to convert a matrix slice into an owned matrix.
|
||||||
* Add `Point*::from_slice` to create a point from a slice.
|
* Add `Point*::from_slice` to create a point from a slice.
|
||||||
* Add `.map_with_location` to matrices to apply a map which passes the component indices to the user-defined closure alongside
|
* Add `.map_with_location` to matrices to apply a map which passes the component indices to the user-defined closure
|
||||||
|
alongside
|
||||||
the component itself.
|
the component itself.
|
||||||
* Add impl `From<Vector>` for `Point`.
|
* Add impl `From<Vector>` for `Point`.
|
||||||
* Add impl `From<Vector4>` for `Quaternion`.
|
* Add impl `From<Vector4>` for `Quaternion`.
|
||||||
|
@ -397,7 +627,8 @@ Note that all the other BLAS operation will continue to work for all fields, inc
|
||||||
* Add `.to_homogeneous` to square matrices (and with dimensions higher than 1x1). This will increase their number of row
|
* Add `.to_homogeneous` to square matrices (and with dimensions higher than 1x1). This will increase their number of row
|
||||||
and columns by 1. The new column and row are filled with 0, except for the diagonal element which is set to 1.
|
and columns by 1. The new column and row are filled with 0, except for the diagonal element which is set to 1.
|
||||||
* Implement `Extend<Vec>` for matrices with a dynamic storage. The provided `Vec` is assumed to represent a column-major
|
* Implement `Extend<Vec>` for matrices with a dynamic storage. The provided `Vec` is assumed to represent a column-major
|
||||||
matrix with the same number of rows as the one being extended. This will effectively append new columns on the right of
|
matrix with the same number of rows as the one being extended. This will effectively append new columns on the right
|
||||||
|
of
|
||||||
the matrix being extended.
|
the matrix being extended.
|
||||||
* Implement `Extend<Vec>` for vectors with a dynamic storage. This will concatenate the vector with the given `Vec`.
|
* Implement `Extend<Vec>` for vectors with a dynamic storage. This will concatenate the vector with the given `Vec`.
|
||||||
* Implement `Extend<Matrix<...>>` for matrices with dynamic storage. This will concatenate the columns of both matrices.
|
* Implement `Extend<Matrix<...>>` for matrices with dynamic storage. This will concatenate the columns of both matrices.
|
||||||
|
@ -406,10 +637,12 @@ Note that all the other BLAS operation will continue to work for all fields, inc
|
||||||
* Add a `.len()` method to retrieve the size of a `MatrixVec`.
|
* Add a `.len()` method to retrieve the size of a `MatrixVec`.
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* The orthographic projection no longer require that `bottom < top`, that `left < right`, and that `znear < zfar`. The
|
* The orthographic projection no longer require that `bottom < top`, that `left < right`, and that `znear < zfar`. The
|
||||||
only restriction now ith that they must not be equal (in which case the projection would be singular).
|
only restriction now ith that they must not be equal (in which case the projection would be singular).
|
||||||
* The `Point::from_coordinates` methods is deprecated. Use `Point::from` instead.
|
* The `Point::from_coordinates` methods is deprecated. Use `Point::from` instead.
|
||||||
* The `.transform_point` and `.transform_vector` methods are now inherent methods for matrices so that the user does not have to
|
* The `.transform_point` and `.transform_vector` methods are now inherent methods for matrices so that the user does not
|
||||||
|
have to
|
||||||
explicitly import the `Transform` trait from the alga crate.
|
explicitly import the `Transform` trait from the alga crate.
|
||||||
* Renamed the matrix storage types: `MatrixArray` -> `ArrayStorage` and `MatrixVec` -> `VecStorage`.
|
* Renamed the matrix storage types: `MatrixArray` -> `ArrayStorage` and `MatrixVec` -> `VecStorage`.
|
||||||
* Renamed `.unwrap()` to `.into_inner()` for geometric types that wrap another type.
|
* Renamed `.unwrap()` to `.into_inner()` for geometric types that wrap another type.
|
||||||
|
@ -417,32 +650,46 @@ Note that all the other BLAS operation will continue to work for all fields, inc
|
||||||
* Deprecate several functions at the root of the crate (replaced by methods).
|
* Deprecate several functions at the root of the crate (replaced by methods).
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
* Remove the `Deref` impl for `MatrixVec` as it could cause hard-to-understand compilation errors.
|
* Remove the `Deref` impl for `MatrixVec` as it could cause hard-to-understand compilation errors.
|
||||||
|
|
||||||
### nalgebra-glm
|
### nalgebra-glm
|
||||||
|
|
||||||
* Add several alternative projection computations, e.g., `ortho_lh`, `ortho_lh_no`, `perspective_lh`, etc.
|
* Add several alternative projection computations, e.g., `ortho_lh`, `ortho_lh_no`, `perspective_lh`, etc.
|
||||||
* Add features matching those of nalgebra, in particular: `serde-serialize`, `abmonation-serialize`, std` (enabled by default).
|
* Add features matching those of nalgebra, in particular:`serde-serialize`, `abmonation-serialize`, std` (enabled by
|
||||||
|
default).
|
||||||
|
|
||||||
## [0.16.0]
|
## [0.16.0]
|
||||||
|
|
||||||
All dependencies have been updated to their latest versions.
|
All dependencies have been updated to their latest versions.
|
||||||
|
|
||||||
## Modified
|
## Modified
|
||||||
* Adjust `UnitQuaternion`s, `Rotation3`s, and `Rotation2`s generated from the `Standard` distribution to be uniformly distributed.
|
|
||||||
|
* Adjust `UnitQuaternion`s, `Rotation3`s, and `Rotation2`s generated from the `Standard` distribution to be uniformly
|
||||||
|
distributed.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* Add a feature `stdweb` to activate the dependency feature `rand/stdweb`.
|
* Add a feature `stdweb` to activate the dependency feature `rand/stdweb`.
|
||||||
* Add blas-like methods `.imin()` and `.imax()` that return the index of the minimum and maximum entry of a vector.
|
* Add blas-like methods `.imin()` and `.imax()` that return the index of the minimum and maximum entry of a vector.
|
||||||
* Add construction of a `Point` from an array by implementing the `From` trait.
|
* Add construction of a `Point` from an array by implementing the `From` trait.
|
||||||
* Add support for generating uniformly distributed random unit column vectors using the `Standard` distribution.
|
* Add support for generating uniformly distributed random unit column vectors using the `Standard` distribution.
|
||||||
|
|
||||||
## [0.15.0]
|
## [0.15.0]
|
||||||
|
|
||||||
The most notable change of this release is the support for using part of the library without the rust standard
|
The most notable change of this release is the support for using part of the library without the rust standard
|
||||||
library (i.e. it supports `#![no_std]`). See the corresponding [documentation](https://nalgebra.org/wasm_and_embedded_programming/).
|
library (i.e. it supports `#![no_std]`). See the
|
||||||
|
corresponding [documentation](https://nalgebra.org/wasm_and_embedded_programming/).
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* Rename the `core` module to `base` to avoid conflicts with the `core` crate implicitly imported when
|
* Rename the `core` module to `base` to avoid conflicts with the `core` crate implicitly imported when
|
||||||
`#![no_std]` is enabled.
|
`#![no_std]` is enabled.
|
||||||
* Constructors of the `MatrixSlice*` types have been renamed from `new_*` to `from_slice_*`. This was
|
* Constructors of the `MatrixSlice*` types have been renamed from `new_*` to `from_slice_*`. This was
|
||||||
necessary to avoid the `incoherent_fundamental_impls` lint that is going to become a hard error.
|
necessary to avoid the `incoherent_fundamental_impls` lint that is going to become a hard error.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* Add `UnitQuaternion` constructor `::new_eps(...)` and `::from_scaled_axis_eps(...)` that return the
|
* Add `UnitQuaternion` constructor `::new_eps(...)` and `::from_scaled_axis_eps(...)` that return the
|
||||||
identity if the magnitude of the input axisangle is smaller than the epsilon provided.
|
identity if the magnitude of the input axisangle is smaller than the epsilon provided.
|
||||||
* Add methods `.rotation_between_axis(...)` and `.scaled_rotation_between_axis(...)` to `UnitComplex`
|
* Add methods `.rotation_between_axis(...)` and `.scaled_rotation_between_axis(...)` to `UnitComplex`
|
||||||
|
@ -452,9 +699,13 @@ library (i.e. it supports `#![no_std]`). See the corresponding [documentation](h
|
||||||
* Add functions to construct a random matrix with a user-defined distribution: `::from_distribution(...)`.
|
* Add functions to construct a random matrix with a user-defined distribution: `::from_distribution(...)`.
|
||||||
|
|
||||||
## [0.14.0]
|
## [0.14.0]
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* Allow the `Isometry * Unit<Vector>` multiplication.
|
* Allow the `Isometry * Unit<Vector>` multiplication.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* Add blas-like operations: `.quadform(...)` and `.quadform_tr(...)` to compute respectively
|
* Add blas-like operations: `.quadform(...)` and `.quadform_tr(...)` to compute respectively
|
||||||
the quadratic forms `self = alpha * A.transpose() * B * A + beta * self` and
|
the quadratic forms `self = alpha * A.transpose() * B * A + beta * self` and
|
||||||
`alpha * A * B * A.transpose() + beta * self`. Here, `A, B` are matrices with
|
`alpha * A * B * A.transpose() + beta * self`. Here, `A, B` are matrices with
|
||||||
|
@ -484,8 +735,6 @@ library (i.e. it supports `#![no_std]`). See the corresponding [documentation](h
|
||||||
`UnitQuaternion::rotation_between_axis(...)` that take Unit vectors instead of
|
`UnitQuaternion::rotation_between_axis(...)` that take Unit vectors instead of
|
||||||
Vector as arguments.
|
Vector as arguments.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.13.0]
|
## [0.13.0]
|
||||||
|
|
||||||
The **nalgebra-lapack** crate has been updated. This now includes a broad range
|
The **nalgebra-lapack** crate has been updated. This now includes a broad range
|
||||||
|
@ -495,6 +744,7 @@ This adds support for serialization using the
|
||||||
[abomonation](https://crates.io/crates/abomonation) crate.
|
[abomonation](https://crates.io/crates/abomonation) crate.
|
||||||
|
|
||||||
### Breaking semantic change
|
### Breaking semantic change
|
||||||
|
|
||||||
* The implementation of slicing with steps now matches the documentation.
|
* The implementation of slicing with steps now matches the documentation.
|
||||||
Before, step identified the number to add to pass from one column/row index
|
Before, step identified the number to add to pass from one column/row index
|
||||||
to the next one. This made 0 step invalid. Now (and on the documentation so
|
to the next one. This made 0 step invalid. Now (and on the documentation so
|
||||||
|
@ -503,6 +753,7 @@ This adds support for serialization using the
|
||||||
example, a step of, say, 3 on previous versions should now bet set to 2.
|
example, a step of, say, 3 on previous versions should now bet set to 2.
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* The trait `Axpy` has been replaced by a method `.axpy`.
|
* The trait `Axpy` has been replaced by a method `.axpy`.
|
||||||
* The alias `MatrixNM` is now deprecated. Use `MatrixMN` instead (we
|
* The alias `MatrixNM` is now deprecated. Use `MatrixMN` instead (we
|
||||||
reordered M and N to be in alphabetical order).
|
reordered M and N to be in alphabetical order).
|
||||||
|
@ -512,6 +763,7 @@ This adds support for serialization using the
|
||||||
`.component_div_assign(...)` instead.
|
`.component_div_assign(...)` instead.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* `alga::general::Real` is now re-exported by nalgebra.
|
* `alga::general::Real` is now re-exported by nalgebra.
|
||||||
elements.)
|
elements.)
|
||||||
* `::zeros(...)` that creates a matrix filled with zeroes.
|
* `::zeros(...)` that creates a matrix filled with zeroes.
|
||||||
|
@ -547,17 +799,20 @@ Pure Rust implementation of some Blas operations:
|
||||||
* `.ger_symm(...)` is the same as `.ger` except that `self` is assumed symmetric.
|
* `.ger_symm(...)` is the same as `.ger` except that `self` is assumed symmetric.
|
||||||
|
|
||||||
New slicing methods:
|
New slicing methods:
|
||||||
|
|
||||||
* `.rows_range(...)` that retrieves a reference to a range of rows.
|
* `.rows_range(...)` that retrieves a reference to a range of rows.
|
||||||
* `.rows_range_mut(...)` that retrieves a mutable reference to a range of rows.
|
* `.rows_range_mut(...)` that retrieves a mutable reference to a range of rows.
|
||||||
* `.columns_range(...)` that retrieves a reference to a range of columns.
|
* `.columns_range(...)` that retrieves a reference to a range of columns.
|
||||||
* `.columns_range_mut(...)` that retrieves a mutable reference to a range of columns.
|
* `.columns_range_mut(...)` that retrieves a mutable reference to a range of columns.
|
||||||
|
|
||||||
Matrix decompositions implemented in pure Rust:
|
Matrix decompositions implemented in pure Rust:
|
||||||
|
|
||||||
* Cholesky, SVD, LU, QR, Hessenberg, Schur, Symmetric eigendecompositions,
|
* Cholesky, SVD, LU, QR, Hessenberg, Schur, Symmetric eigendecompositions,
|
||||||
Bidiagonal, Symmetric tridiagonal
|
Bidiagonal, Symmetric tridiagonal
|
||||||
* Computation of householder reflectors and givens rotations.
|
* Computation of householder reflectors and givens rotations.
|
||||||
|
|
||||||
Matrix edition:
|
Matrix edition:
|
||||||
|
|
||||||
* `.upper_triangle()` extracts the upper triangle of a matrix, including the diagonal.
|
* `.upper_triangle()` extracts the upper triangle of a matrix, including the diagonal.
|
||||||
* `.lower_triangle()` extracts the lower triangle of a matrix, including the diagonal.
|
* `.lower_triangle()` extracts the lower triangle of a matrix, including the diagonal.
|
||||||
* `.fill(...)` fills the matrix with a single value.
|
* `.fill(...)` fills the matrix with a single value.
|
||||||
|
@ -574,37 +829,45 @@ Matrix edition:
|
||||||
* `.swap_columns(...)` swaps two columns.
|
* `.swap_columns(...)` swaps two columns.
|
||||||
|
|
||||||
Column removal:
|
Column removal:
|
||||||
|
|
||||||
* `.remove_column(...)` removes one column.
|
* `.remove_column(...)` removes one column.
|
||||||
* `.remove_fixed_columns<D>(...)` removes `D` columns.
|
* `.remove_fixed_columns<D>(...)` removes `D` columns.
|
||||||
* `.remove_columns(...)` removes a number of columns known at run-time.
|
* `.remove_columns(...)` removes a number of columns known at run-time.
|
||||||
|
|
||||||
Row removal:
|
Row removal:
|
||||||
|
|
||||||
* `.remove_row(...)` removes one row.
|
* `.remove_row(...)` removes one row.
|
||||||
* `.remove_fixed_rows<D>(...)` removes `D` rows.
|
* `.remove_fixed_rows<D>(...)` removes `D` rows.
|
||||||
* `.remove_rows(...)` removes a number of rows known at run-time.
|
* `.remove_rows(...)` removes a number of rows known at run-time.
|
||||||
|
|
||||||
Column insertion:
|
Column insertion:
|
||||||
|
|
||||||
* `.insert_column(...)` adds one column at the given position.
|
* `.insert_column(...)` adds one column at the given position.
|
||||||
* `.insert_fixed_columns<D>(...)` adds `D` columns at the given position.
|
* `.insert_fixed_columns<D>(...)` adds `D` columns at the given position.
|
||||||
* `.insert_columns(...)` adds at the given position a number of columns known at run-time.
|
* `.insert_columns(...)` adds at the given position a number of columns known at run-time.
|
||||||
|
|
||||||
Row insertion:
|
Row insertion:
|
||||||
|
|
||||||
* `.insert_row(...)` adds one row at the given position.
|
* `.insert_row(...)` adds one row at the given position.
|
||||||
* `.insert_fixed_rows<D>(...)` adds `D` rows at the given position.
|
* `.insert_fixed_rows<D>(...)` adds `D` rows at the given position.
|
||||||
* `.insert_rows(...)` adds at the given position a number of rows known at run-time.
|
* `.insert_rows(...)` adds at the given position a number of rows known at run-time.
|
||||||
|
|
||||||
## [0.12.0]
|
## [0.12.0]
|
||||||
|
|
||||||
The main change of this release is the update of the dependency serde to 1.0.
|
The main change of this release is the update of the dependency serde to 1.0.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* `.trace()` that computes the trace of a matrix (the sum of its diagonal
|
* `.trace()` that computes the trace of a matrix (the sum of its diagonal
|
||||||
elements.)
|
elements.)
|
||||||
|
|
||||||
## [0.11.0]
|
## [0.11.0]
|
||||||
|
|
||||||
The [website](https://nalgebra.org) has been fully rewritten and gives a good
|
The [website](https://nalgebra.org) has been fully rewritten and gives a good
|
||||||
overview of all the added/modified features.
|
overview of all the added/modified features.
|
||||||
|
|
||||||
This version is a major rewrite of the library. Major changes are:
|
This version is a major rewrite of the library. Major changes are:
|
||||||
|
|
||||||
* Algebraic traits are now defined by the [alga](https://crates.io/crates/alga) crate.
|
* Algebraic traits are now defined by the [alga](https://crates.io/crates/alga) crate.
|
||||||
All other mathematical traits, except `Axpy` have been removed from
|
All other mathematical traits, except `Axpy` have been removed from
|
||||||
**nalgebra**.
|
**nalgebra**.
|
||||||
|
@ -622,9 +885,11 @@ This version is a major rewrite of the library. Major changes are:
|
||||||
* Matrix **slices** are now implemented.
|
* Matrix **slices** are now implemented.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
Lots of features including rectangular matrices, slices, and Serde
|
Lots of features including rectangular matrices, slices, and Serde
|
||||||
serialization. Refer to the brand new [website](https://nalgebra.org) for more
|
serialization. Refer to the brand new [website](https://nalgebra.org) for more
|
||||||
details. The following free-functions have been added as well:
|
details. The following free-functions have been added as well:
|
||||||
|
|
||||||
* `::id()` that returns the universal [identity element](https://nalgebra.org/performance_tricks/#the-id-type)
|
* `::id()` that returns the universal [identity element](https://nalgebra.org/performance_tricks/#the-id-type)
|
||||||
of type `Id`.
|
of type `Id`.
|
||||||
* `::inf_sup()` that returns both the infimum and supremum of a value at the
|
* `::inf_sup()` that returns both the infimum and supremum of a value at the
|
||||||
|
@ -634,6 +899,7 @@ details. The following free-functions have been added as well:
|
||||||
the interval width to it.
|
the interval width to it.
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* `::cast` -> `::convert`
|
* `::cast` -> `::convert`
|
||||||
* `point.as_vector()` -> `point.coords`
|
* `point.as_vector()` -> `point.coords`
|
||||||
* `na::origin` -> `P::origin()`
|
* `na::origin` -> `P::origin()`
|
||||||
|
@ -644,6 +910,7 @@ details. The following free-functions have been added as well:
|
||||||
* `::angle_between` -> `::angle`
|
* `::angle_between` -> `::angle`
|
||||||
|
|
||||||
Componentwise multiplication and division has been replaced by methods:
|
Componentwise multiplication and division has been replaced by methods:
|
||||||
|
|
||||||
* multiplication -> `.componentwise_mul`, `.componentwise_mul_mut`.
|
* multiplication -> `.componentwise_mul`, `.componentwise_mul_mut`.
|
||||||
* division -> `.componentwise_div`, `.componentwise_div_mut`.
|
* division -> `.componentwise_div`, `.componentwise_div_mut`.
|
||||||
|
|
||||||
|
@ -653,8 +920,8 @@ only:
|
||||||
`.eig`), `::hessenberg`, `::qr`, `::to_homogeneous`, `::to_rotation_matrix`,
|
`.eig`), `::hessenberg`, `::qr`, `::to_homogeneous`, `::to_rotation_matrix`,
|
||||||
`::transpose`, `::shape`.
|
`::transpose`, `::shape`.
|
||||||
|
|
||||||
|
|
||||||
The following free-functions are now replaced by static methods only:
|
The following free-functions are now replaced by static methods only:
|
||||||
|
|
||||||
* `::householder_matrix` under the name `::new_householder_generic`
|
* `::householder_matrix` under the name `::new_householder_generic`
|
||||||
* `::identity`
|
* `::identity`
|
||||||
* `::new_identity` under the name `::identity`
|
* `::new_identity` under the name `::identity`
|
||||||
|
@ -663,6 +930,7 @@ The following free-functions are now replaced by static methods only:
|
||||||
|
|
||||||
The following free-function are now replaced methods accessible through traits
|
The following free-function are now replaced methods accessible through traits
|
||||||
only:
|
only:
|
||||||
|
|
||||||
* `::transform` -> methods `.transform_point` and `.transform_vector` of the `alga::linear::Transformation` trait.
|
* `::transform` -> methods `.transform_point` and `.transform_vector` of the `alga::linear::Transformation` trait.
|
||||||
* `::inverse_transform` -> methods `.inverse_transform_point` and
|
* `::inverse_transform` -> methods `.inverse_transform_point` and
|
||||||
`.inverse_transform_vector` of the `alga::linear::ProjectiveTransformation`
|
`.inverse_transform_vector` of the `alga::linear::ProjectiveTransformation`
|
||||||
|
@ -679,9 +947,8 @@ only:
|
||||||
`alga::linear::Rotation` trait.
|
`alga::linear::Rotation` trait.
|
||||||
* `::is_zero` -> method with the same name from `num::Zero`.
|
* `::is_zero` -> method with the same name from `num::Zero`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
* The free functions `::prepend_rotation`, `::append_rotation`,
|
* The free functions `::prepend_rotation`, `::append_rotation`,
|
||||||
`::append_rotation_wrt_center`, `::append_rotation_wrt_point`,
|
`::append_rotation_wrt_center`, `::append_rotation_wrt_point`,
|
||||||
`::append_transformation`, and `::append_translation ` have been removed.
|
`::append_transformation`, and `::append_translation ` have been removed.
|
||||||
|
@ -705,11 +972,14 @@ only:
|
||||||
`rotation.angle()` and `rotation.axis()`.
|
`rotation.angle()` and `rotation.axis()`.
|
||||||
|
|
||||||
## [0.10.0]
|
## [0.10.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
Binary operations are now allowed between references as well. For example
|
Binary operations are now allowed between references as well. For example
|
||||||
`Vector3<f32> + &Vector3<f32>` is now possible.
|
`Vector3<f32> + &Vector3<f32>` is now possible.
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
Removed unused parameters to methods from the `ApproxEq` trait. Those were
|
Removed unused parameters to methods from the `ApproxEq` trait. Those were
|
||||||
required before rust 1.0 to help type inference. They are not needed any more
|
required before rust 1.0 to help type inference. They are not needed any more
|
||||||
since it now allowed to write for a type `T` that implements `ApproxEq`:
|
since it now allowed to write for a type `T` that implements `ApproxEq`:
|
||||||
|
@ -717,7 +987,9 @@ since it now allowed to write for a type `T` that implements `ApproxEq`:
|
||||||
`ApproxEq::approx_epsilon(None::<T>)`.
|
`ApproxEq::approx_epsilon(None::<T>)`.
|
||||||
|
|
||||||
## [0.9.0]
|
## [0.9.0]
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* Renamed:
|
* Renamed:
|
||||||
- `::from_col_vector` -> `::from_column_vector`
|
- `::from_col_vector` -> `::from_column_vector`
|
||||||
- `::from_col_iter` -> `::from_column_iter`
|
- `::from_col_iter` -> `::from_column_iter`
|
||||||
|
@ -739,11 +1011,13 @@ Other similar trait changes are to be expected in the future, e.g., for the
|
||||||
|
|
||||||
Methods marked `unsafe` for reasons unrelated to memory safety are no
|
Methods marked `unsafe` for reasons unrelated to memory safety are no
|
||||||
longer unsafe. Instead, their name end with `_unchecked`. In particular:
|
longer unsafe. Instead, their name end with `_unchecked`. In particular:
|
||||||
|
|
||||||
* `Rotation3::new_with_matrix` -> `Rotation3::from_matrix_unchecked`
|
* `Rotation3::new_with_matrix` -> `Rotation3::from_matrix_unchecked`
|
||||||
* `PerspectiveMatrix3::new_with_matrix` -> `PerspectiveMatrix3::from_matrix_unchecked`
|
* `PerspectiveMatrix3::new_with_matrix` -> `PerspectiveMatrix3::from_matrix_unchecked`
|
||||||
* `OrthographicMatrix3::new_with_matrix` -> `OrthographicMatrix3::from_matrix_unchecked`
|
* `OrthographicMatrix3::new_with_matrix` -> `OrthographicMatrix3::from_matrix_unchecked`
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- A `Unit<T>` type that wraps normalized values. In particular,
|
- A `Unit<T>` type that wraps normalized values. In particular,
|
||||||
`UnitQuaternion<N>` is now an alias for `Unit<Quaternion<N>>`.
|
`UnitQuaternion<N>` is now an alias for `Unit<Quaternion<N>>`.
|
||||||
- `.ln()`, `.exp()` and `.powf(..)` for quaternions and unit quaternions.
|
- `.ln()`, `.exp()` and `.powf(..)` for quaternions and unit quaternions.
|
||||||
|
@ -760,7 +1034,9 @@ crate for vectors, rotations and points. To enable them, activate the
|
||||||
`abstract_algebra` feature.
|
`abstract_algebra` feature.
|
||||||
|
|
||||||
## [0.8.0]
|
## [0.8.0]
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* Almost everything (types, methods, and traits) now use fulls names instead
|
* Almost everything (types, methods, and traits) now use fulls names instead
|
||||||
of abbreviations (e.g. `Vec3` becomes `Vector3`). Most changes are obvious.
|
of abbreviations (e.g. `Vec3` becomes `Vector3`). Most changes are obvious.
|
||||||
Note however that:
|
Note however that:
|
||||||
|
@ -774,19 +1050,24 @@ crate for vectors, rotations and points. To enable them, activate the
|
||||||
e.g., `vec.rs` becomes `vector.rs`.
|
e.g., `vec.rs` becomes `vector.rs`.
|
||||||
|
|
||||||
## [0.7.0]
|
## [0.7.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* Added implementation of assignment operators (+=, -=, etc.) for
|
* Added implementation of assignment operators (+=, -=, etc.) for
|
||||||
everything.
|
everything.
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* Points and vectors are now linked to each other with associated types
|
* Points and vectors are now linked to each other with associated types
|
||||||
(on the PointAsVector trait).
|
(on the PointAsVector trait).
|
||||||
|
|
||||||
|
|
||||||
## [0.6.0]
|
## [0.6.0]
|
||||||
|
|
||||||
**Announcement:** a users forum has been created for `nalgebra`, `ncollide`, and `nphysics`. See
|
**Announcement:** a users forum has been created for `nalgebra`, `ncollide`, and `nphysics`. See
|
||||||
you [there](https://users.nphysics.org)!
|
you [there](https://users.nphysics.org)!
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* Added a dependency to [generic-array](https://crates.io/crates/generic-array). Feature-gated:
|
* Added a dependency to [generic-array](https://crates.io/crates/generic-array). Feature-gated:
|
||||||
requires `features="generic_sizes"`.
|
requires `features="generic_sizes"`.
|
||||||
* Added statically sized vectors with user-defined sizes: `VectorN`. Feature-gated: requires
|
* Added statically sized vectors with user-defined sizes: `VectorN`. Feature-gated: requires
|
||||||
|
@ -795,10 +1076,13 @@ you [there](https://users.nphysics.org)!
|
||||||
translation): `Similarity2`, `Similarity3`.
|
translation): `Similarity2`, `Similarity3`.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
* Removed zero-sized elements `Vector0`, `Point0`.
|
* Removed zero-sized elements `Vector0`, `Point0`.
|
||||||
* Removed 4-dimensional transformations `Rotation4` and `Isometry4` (which had an implementation too incomplete to be useful).
|
* Removed 4-dimensional transformations `Rotation4` and `Isometry4` (which had an implementation too incomplete to be
|
||||||
|
useful).
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
* Vectors are now multipliable with isometries. This will result into a pure rotation (this is how
|
* Vectors are now multipliable with isometries. This will result into a pure rotation (this is how
|
||||||
vectors differ from point semantically: they design directions, so they are not translatable).
|
vectors differ from point semantically: they design directions, so they are not translatable).
|
||||||
* `{Isometry3, Rotation3}::look_at` reimplemented and renamed to `::look_at_rh` and `::look_at_lh` to agree
|
* `{Isometry3, Rotation3}::look_at` reimplemented and renamed to `::look_at_rh` and `::look_at_lh` to agree
|
||||||
|
|
44
Cargo.toml
44
Cargo.toml
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra"
|
name = "nalgebra"
|
||||||
version = "0.30.1"
|
version = "0.32.3"
|
||||||
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
|
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
|
||||||
|
|
||||||
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."
|
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."
|
||||||
|
@ -10,7 +10,7 @@ repository = "https://github.com/dimforge/nalgebra"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
categories = [ "science", "mathematics", "wasm", "no-std" ]
|
categories = [ "science", "mathematics", "wasm", "no-std" ]
|
||||||
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
|
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
|
||||||
license = "BSD-3-Clause"
|
license = "Apache-2.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
exclude = ["/ci/*", "/.travis.yml", "/Makefile"]
|
exclude = ["/ci/*", "/.travis.yml", "/Makefile"]
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ path = "src/lib.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "std", "macros" ]
|
default = [ "std", "macros" ]
|
||||||
std = [ "matrixmultiply", "simba/std" ]
|
std = [ "matrixmultiply", "num-traits/std", "num-complex/std", "num-rational/std", "approx/std", "simba/std" ]
|
||||||
sparse = [ ]
|
sparse = [ ]
|
||||||
debug = [ "approx/num-complex", "rand" ]
|
debug = [ "approx/num-complex", "rand" ]
|
||||||
alloc = [ ]
|
alloc = [ ]
|
||||||
|
@ -32,12 +32,11 @@ compare = [ "matrixcompare-core" ]
|
||||||
libm = [ "simba/libm" ]
|
libm = [ "simba/libm" ]
|
||||||
libm-force = [ "simba/libm_force" ]
|
libm-force = [ "simba/libm_force" ]
|
||||||
macros = [ "nalgebra-macros" ]
|
macros = [ "nalgebra-macros" ]
|
||||||
cuda = [ "cust_core", "simba/cuda" ]
|
|
||||||
|
|
||||||
# Conversion
|
# Conversion
|
||||||
convert-mint = [ "mint" ]
|
convert-mint = [ "mint" ]
|
||||||
convert-bytemuck = [ "bytemuck" ]
|
convert-bytemuck = [ "bytemuck" ]
|
||||||
convert-glam013 = [ "glam013" ]
|
|
||||||
convert-glam014 = [ "glam014" ]
|
convert-glam014 = [ "glam014" ]
|
||||||
convert-glam015 = [ "glam015" ]
|
convert-glam015 = [ "glam015" ]
|
||||||
convert-glam016 = [ "glam016" ]
|
convert-glam016 = [ "glam016" ]
|
||||||
|
@ -45,6 +44,11 @@ convert-glam017 = [ "glam017" ]
|
||||||
convert-glam018 = [ "glam018" ]
|
convert-glam018 = [ "glam018" ]
|
||||||
convert-glam019 = [ "glam019" ]
|
convert-glam019 = [ "glam019" ]
|
||||||
convert-glam020 = [ "glam020" ]
|
convert-glam020 = [ "glam020" ]
|
||||||
|
convert-glam021 = [ "glam021" ]
|
||||||
|
convert-glam022 = [ "glam022" ]
|
||||||
|
convert-glam023 = [ "glam023" ]
|
||||||
|
convert-glam024 = [ "glam024" ]
|
||||||
|
convert-glam025 = [ "glam025" ]
|
||||||
|
|
||||||
# Serialization
|
# Serialization
|
||||||
## To use serde in a #[no-std] environment, enable the
|
## To use serde in a #[no-std] environment, enable the
|
||||||
|
@ -53,8 +57,8 @@ convert-glam020 = [ "glam020" ]
|
||||||
## `serde-serialize`.
|
## `serde-serialize`.
|
||||||
serde-serialize-no-std = [ "serde", "num-complex/serde" ]
|
serde-serialize-no-std = [ "serde", "num-complex/serde" ]
|
||||||
serde-serialize = [ "serde-serialize-no-std", "serde/std" ]
|
serde-serialize = [ "serde-serialize-no-std", "serde/std" ]
|
||||||
rkyv-serialize-no-std = [ "rkyv" ]
|
rkyv-serialize-no-std = [ "rkyv/size_32" ]
|
||||||
rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std" ]
|
rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std", "rkyv/validation" ]
|
||||||
|
|
||||||
# Randomness
|
# Randomness
|
||||||
## To use rand in a #[no-std] environment, enable the
|
## To use rand in a #[no-std] environment, enable the
|
||||||
|
@ -66,21 +70,22 @@ rand = [ "rand-no-std", "rand-package/std", "rand-package/std_rng", "rand
|
||||||
arbitrary = [ "quickcheck" ]
|
arbitrary = [ "quickcheck" ]
|
||||||
proptest-support = [ "proptest" ]
|
proptest-support = [ "proptest" ]
|
||||||
slow-tests = []
|
slow-tests = []
|
||||||
|
rkyv-safe-deser = [ "rkyv-serialize", "rkyv/validation" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra-macros = { version = "0.1", path = "nalgebra-macros", optional = true }
|
nalgebra-macros = { version = "0.2.1", path = "nalgebra-macros", optional = true }
|
||||||
typenum = "1.12"
|
typenum = "1.12"
|
||||||
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
|
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = { version = "0.2", default-features = false }
|
||||||
num-complex = { version = "0.4", default-features = false }
|
num-complex = { version = "0.4", default-features = false }
|
||||||
num-rational = { version = "0.4", default-features = false }
|
num-rational = { version = "0.4", default-features = false }
|
||||||
approx = { version = "0.5", default-features = false }
|
approx = { version = "0.5", default-features = false }
|
||||||
simba = { version = "0.7", default-features = false }
|
simba = { version = "0.8", default-features = false }
|
||||||
alga = { version = "0.9", default-features = false, optional = true }
|
alga = { version = "0.9", default-features = false, optional = true }
|
||||||
rand_distr = { version = "0.4", default-features = false, optional = true }
|
rand_distr = { version = "0.4", default-features = false, optional = true }
|
||||||
matrixmultiply = { version = "0.3", optional = true }
|
matrixmultiply = { version = "0.3", optional = true }
|
||||||
serde = { version = "1.0", default-features = false, features = [ "derive" ], optional = true }
|
serde = { version = "1.0", default-features = false, features = [ "derive" ], optional = true }
|
||||||
rkyv = { version = "~0.6.4", default-features = false, features = ["const_generics"], optional = true }
|
rkyv = { version = "0.7.41", default-features = false, optional = true }
|
||||||
mint = { version = "0.5", optional = true }
|
mint = { version = "0.5", optional = true }
|
||||||
quickcheck = { version = "1", optional = true }
|
quickcheck = { version = "1", optional = true }
|
||||||
pest = { version = "2", optional = true }
|
pest = { version = "2", optional = true }
|
||||||
|
@ -88,7 +93,6 @@ pest_derive = { version = "2", optional = true }
|
||||||
bytemuck = { version = "1.5", optional = true }
|
bytemuck = { version = "1.5", optional = true }
|
||||||
matrixcompare-core = { version = "0.1", optional = true }
|
matrixcompare-core = { version = "0.1", optional = true }
|
||||||
proptest = { version = "1", optional = true, default-features = false, features = ["std"] }
|
proptest = { version = "1", optional = true, default-features = false, features = ["std"] }
|
||||||
glam013 = { package = "glam", version = "0.13", optional = true }
|
|
||||||
glam014 = { package = "glam", version = "0.14", optional = true }
|
glam014 = { package = "glam", version = "0.14", optional = true }
|
||||||
glam015 = { package = "glam", version = "0.15", optional = true }
|
glam015 = { package = "glam", version = "0.15", optional = true }
|
||||||
glam016 = { package = "glam", version = "0.16", optional = true }
|
glam016 = { package = "glam", version = "0.16", optional = true }
|
||||||
|
@ -96,14 +100,19 @@ glam017 = { package = "glam", version = "0.17", optional = true }
|
||||||
glam018 = { package = "glam", version = "0.18", optional = true }
|
glam018 = { package = "glam", version = "0.18", optional = true }
|
||||||
glam019 = { package = "glam", version = "0.19", optional = true }
|
glam019 = { package = "glam", version = "0.19", optional = true }
|
||||||
glam020 = { package = "glam", version = "0.20", optional = true }
|
glam020 = { package = "glam", version = "0.20", optional = true }
|
||||||
cust_core = { version = "0.1", optional = true }
|
glam021 = { package = "glam", version = "0.21", optional = true }
|
||||||
|
glam022 = { package = "glam", version = "0.22", optional = true }
|
||||||
|
glam023 = { package = "glam", version = "0.23", optional = true }
|
||||||
|
glam024 = { package = "glam", version = "0.24", optional = true }
|
||||||
|
glam025 = { package = "glam", version = "0.25", optional = true }
|
||||||
|
rayon = { version = "1.6", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
rand_xorshift = "0.3"
|
rand_xorshift = "0.3"
|
||||||
rand_isaac = "0.3"
|
rand_isaac = "0.3"
|
||||||
criterion = { version = "0.3", features = ["html_reports"] }
|
criterion = { version = "0.4", features = ["html_reports"] }
|
||||||
|
nalgebra = { path = ".", features = ["debug", "compare", "rand", "macros"]}
|
||||||
|
|
||||||
# For matrix comparison macro
|
# For matrix comparison macro
|
||||||
matrixcompare = "0.3.0"
|
matrixcompare = "0.3.0"
|
||||||
|
@ -131,6 +140,7 @@ required-features = ["rand"]
|
||||||
lto = true
|
lto = true
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
# Enable certain features when building docs for docs.rs
|
# Enable all the features when building the docs on docs.rs
|
||||||
features = [ "proptest-support", "compare", "macros", "rand" ]
|
all-features = true
|
||||||
|
# define the configuration attribute `docsrs`
|
||||||
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
16
README.md
16
README.md
|
@ -29,19 +29,3 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
## Acknowledgements
|
|
||||||
nalgebra is supported by our **platinum** sponsors:
|
|
||||||
<p>
|
|
||||||
<a href="https://embark-studios.com">
|
|
||||||
<img src="https://www.embark.dev/img/logo_black.png" width="301px">
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
And our gold sponsors:
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="https://fragcolor.com">
|
|
||||||
<img src="https://dimforge.com/img/fragcolor_logo1_color_black.svg" width="151px">
|
|
||||||
</a>
|
|
||||||
</p>
|
|
|
@ -53,7 +53,7 @@ fn mat_div_scalar(b: &mut criterion::Criterion) {
|
||||||
b.bench_function("mat_div_scalar", move |bh| {
|
b.bench_function("mat_div_scalar", move |bh| {
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
let mut aa = a.clone();
|
let mut aa = a.clone();
|
||||||
let mut b = aa.slice_mut((0, 0), (1000, 1000));
|
let mut b = aa.view_mut((0, 0), (1000, 1000));
|
||||||
b /= n
|
b /= n
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -142,7 +142,7 @@ fn iter(bench: &mut criterion::Criterion) {
|
||||||
bench.bench_function("iter", move |bh| {
|
bench.bench_function("iter", move |bh| {
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
for value in a.iter() {
|
for value in a.iter() {
|
||||||
criterion::black_box(value);
|
std::hint::black_box(value);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -154,7 +154,7 @@ fn iter_rev(bench: &mut criterion::Criterion) {
|
||||||
bench.bench_function("iter_rev", move |bh| {
|
bench.bench_function("iter_rev", move |bh| {
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
for value in a.iter().rev() {
|
for value in a.iter().rev() {
|
||||||
criterion::black_box(value);
|
std::hint::black_box(value);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#![feature(bench_black_box)]
|
|
||||||
#![allow(unused_macros)]
|
#![allow(unused_macros)]
|
||||||
|
|
||||||
extern crate nalgebra as na;
|
extern crate nalgebra as na;
|
||||||
|
|
|
@ -4,7 +4,7 @@ version = "0.0.0"
|
||||||
authors = [ "You" ]
|
authors = [ "You" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra = "0.30.0"
|
nalgebra = "0.32.0"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "example"
|
name = "example"
|
||||||
|
|
|
@ -28,7 +28,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`.
|
/// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`.
|
||||||
/// /!\ This is an exact replicate of `reflect_wrt_hyperplane2, but for 3D.
|
/// /!\ This is an exact replicate of `reflect_wrt_hyperplane2`, but for 3D.
|
||||||
fn reflect_wrt_hyperplane3<T>(plane_normal: &Unit<Vector3<T>>, vector: &Vector3<T>) -> Vector3<T>
|
fn reflect_wrt_hyperplane3<T>(plane_normal: &Unit<Vector3<T>>, vector: &Vector3<T>) -> Vector3<T>
|
||||||
where
|
where
|
||||||
T: RealField,
|
T: RealField,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
extern crate nalgebra as na;
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
use na::{DMatrix, Dynamic, Matrix2x3, Matrix3x2, Const};
|
use na::{DMatrix, Dyn, Matrix2x3, Matrix3x2, Const};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Matrices can be reshaped in-place without moving or copying values.
|
// Matrices can be reshaped in-place without moving or copying values.
|
||||||
|
@ -46,9 +46,9 @@ fn main() {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
let dm3 = dm1.reshape_generic(Dynamic::new(6), Dynamic::new(2));
|
let dm3 = dm1.reshape_generic(Dyn(6), Dyn(2));
|
||||||
assert_eq!(dm3, dm2);
|
assert_eq!(dm3, dm2);
|
||||||
|
|
||||||
// Invalid reshapings of dynamic matrices will panic at run-time.
|
// Invalid reshapings of dynamic matrices will panic at run-time.
|
||||||
//let dm4 = dm3.reshape_generic(Dynamic::new(6), Dynamic::new(6));
|
//let dm4 = dm3.reshape_generic(Dyn(6), Dyn(6));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra-glm"
|
name = "nalgebra-glm"
|
||||||
version = "0.16.0"
|
version = "0.18.0"
|
||||||
authors = ["sebcrozet <developer@crozet.re>"]
|
authors = ["sebcrozet <developer@crozet.re>"]
|
||||||
|
|
||||||
description = "A computer-graphics oriented API for nalgebra, inspired by the C++ GLM library."
|
description = "A computer-graphics oriented API for nalgebra, inspired by the C++ GLM library."
|
||||||
|
@ -10,7 +10,7 @@ repository = "https://github.com/dimforge/nalgebra"
|
||||||
readme = "../README.md"
|
readme = "../README.md"
|
||||||
categories = [ "science", "mathematics", "wasm", "no standard library" ]
|
categories = [ "science", "mathematics", "wasm", "no standard library" ]
|
||||||
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
|
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
|
||||||
license = "BSD-3-Clause"
|
license = "Apache-2.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
|
@ -21,12 +21,10 @@ default = [ "std" ]
|
||||||
std = [ "nalgebra/std", "simba/std" ]
|
std = [ "nalgebra/std", "simba/std" ]
|
||||||
arbitrary = [ "nalgebra/arbitrary" ]
|
arbitrary = [ "nalgebra/arbitrary" ]
|
||||||
serde-serialize = [ "nalgebra/serde-serialize-no-std" ]
|
serde-serialize = [ "nalgebra/serde-serialize-no-std" ]
|
||||||
cuda = [ "nalgebra/cuda" ]
|
|
||||||
|
|
||||||
# Conversion
|
# Conversion
|
||||||
convert-mint = [ "nalgebra/mint" ]
|
convert-mint = [ "nalgebra/mint" ]
|
||||||
convert-bytemuck = [ "nalgebra/bytemuck" ]
|
convert-bytemuck = [ "nalgebra/bytemuck" ]
|
||||||
convert-glam013 = [ "nalgebra/glam013" ]
|
|
||||||
convert-glam014 = [ "nalgebra/glam014" ]
|
convert-glam014 = [ "nalgebra/glam014" ]
|
||||||
convert-glam015 = [ "nalgebra/glam015" ]
|
convert-glam015 = [ "nalgebra/glam015" ]
|
||||||
convert-glam016 = [ "nalgebra/glam016" ]
|
convert-glam016 = [ "nalgebra/glam016" ]
|
||||||
|
@ -36,5 +34,5 @@ convert-glam018 = [ "nalgebra/glam018" ]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = { version = "0.2", default-features = false }
|
||||||
approx = { version = "0.5", default-features = false }
|
approx = { version = "0.5", default-features = false }
|
||||||
simba = { version = "0.7", default-features = false }
|
simba = { version = "0.8", default-features = false }
|
||||||
nalgebra = { path = "..", version = "0.30", default-features = false }
|
nalgebra = { path = "..", version = "0.32", default-features = false }
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
../LICENSE
|
|
@ -5,38 +5,38 @@ use na::{
|
||||||
|
|
||||||
/// A matrix with components of type `T`. It has `R` rows, and `C` columns.
|
/// A matrix with components of type `T`. It has `R` rows, and `C` columns.
|
||||||
///
|
///
|
||||||
/// In this library, vectors, represented as [`TVec`](type.TVec.html) and
|
/// In this library, vectors, represented as [`TVec`] and
|
||||||
/// friends, are also matrices. Operations that operate on a matrix will
|
/// friends, are also matrices. Operations that operate on a matrix will
|
||||||
/// also work on a vector.
|
/// also work on a vector.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`TMat2`](type.TMat2.html)
|
/// * [`TMat2`]
|
||||||
/// * [`TMat2x2`](type.TMat2x2.html)
|
/// * [`TMat2x2`]
|
||||||
/// * [`TMat2x3`](type.TMat2x3.html)
|
/// * [`TMat2x3`]
|
||||||
/// * [`TMat2x4`](type.TMat2x4.html)
|
/// * [`TMat2x4`]
|
||||||
/// * [`TMat3`](type.TMat3.html)
|
/// * [`TMat3`]
|
||||||
/// * [`TMat3x2`](type.TMat3x2.html)
|
/// * [`TMat3x2`]
|
||||||
/// * [`TMat3x3`](type.TMat3x3.html)
|
/// * [`TMat3x3`]
|
||||||
/// * [`TMat3x4`](type.TMat3x4.html)
|
/// * [`TMat3x4`]
|
||||||
/// * [`TMat4`](type.TMat4.html)
|
/// * [`TMat4`]
|
||||||
/// * [`TMat4x2`](type.TMat4x2.html)
|
/// * [`TMat4x2`]
|
||||||
/// * [`TMat4x3`](type.TMat4x3.html)
|
/// * [`TMat4x3`]
|
||||||
/// * [`TMat4x4`](type.TMat4x4.html)
|
/// * [`TMat4x4`]
|
||||||
/// * [`TVec`](type.TVec.html)
|
/// * [`TVec`]
|
||||||
pub type TMat<T, const R: usize, const C: usize> = SMatrix<T, R, C>;
|
pub type TMat<T, const R: usize, const C: usize> = SMatrix<T, R, C>;
|
||||||
/// A column vector with components of type `T`. It has `D` rows (and one column).
|
/// A column vector with components of type `T`. It has `D` rows (and one column).
|
||||||
///
|
///
|
||||||
/// In this library, vectors are represented as a single column matrix, so
|
/// In this library, vectors are represented as a single column matrix, so
|
||||||
/// operations on [`TMat`](type.TMat.html) are also valid on vectors.
|
/// operations on [`TMat`] are also valid on vectors.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`TMat`](type.TMat.html)
|
/// * [`TMat`]
|
||||||
/// * [`TVec1`](type.TVec1.html)
|
/// * [`TVec1`]
|
||||||
/// * [`TVec2`](type.TVec2.html)
|
/// * [`TVec2`]
|
||||||
/// * [`TVec3`](type.TVec3.html)
|
/// * [`TVec3`]
|
||||||
/// * [`TVec4`](type.TVec4.html)
|
/// * [`TVec4`]
|
||||||
pub type TVec<T, const R: usize> = SVector<T, R>;
|
pub type TVec<T, const R: usize> = SVector<T, R>;
|
||||||
/// A quaternion with components of type `T`.
|
/// A quaternion with components of type `T`.
|
||||||
pub type Qua<T> = Quaternion<T>;
|
pub type Qua<T> = Quaternion<T>;
|
||||||
|
@ -47,28 +47,28 @@ pub type Qua<T> = Quaternion<T>;
|
||||||
///
|
///
|
||||||
/// ## Constructors:
|
/// ## Constructors:
|
||||||
///
|
///
|
||||||
/// * [`make_vec1`](fn.make_vec1.html)
|
/// * [`make_vec1()`](crate::make_vec1)
|
||||||
/// * [`vec1`](fn.vec1.html)
|
/// * [`vec1()`](crate::vec1)
|
||||||
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
|
/// * [`vec2_to_vec1()`](crate::vec2_to_vec1)
|
||||||
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
/// * [`vec3_to_vec1()`](crate::vec3_to_vec1)
|
||||||
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
|
/// * [`vec4_to_vec1()`](crate::vec4_to_vec1)
|
||||||
///
|
///
|
||||||
/// ## Related types:
|
/// ## Related types:
|
||||||
///
|
///
|
||||||
/// * [`BVec1`](type.BVec1.html)
|
/// * [`BVec1`]
|
||||||
/// * [`DVec1`](type.DVec1.html)
|
/// * [`DVec1`]
|
||||||
/// * [`IVec1`](type.IVec1.html)
|
/// * [`IVec1`]
|
||||||
/// * [`I16Vec1`](type.I16Vec1.html)
|
/// * [`I16Vec1`]
|
||||||
/// * [`I32Vec1`](type.I32Vec1.html)
|
/// * [`I32Vec1`]
|
||||||
/// * [`I64Vec1`](type.I64Vec1.html)
|
/// * [`I64Vec1`]
|
||||||
/// * [`I8Vec1`](type.I8Vec1.html)
|
/// * [`I8Vec1`]
|
||||||
/// * [`TVec`](type.TVec.html)
|
/// * [`TVec`]
|
||||||
/// * [`UVec1`](type.UVec1.html)
|
/// * [`UVec1`]
|
||||||
/// * [`U16Vec1`](type.U16Vec1.html)
|
/// * [`U16Vec1`]
|
||||||
/// * [`U32Vec1`](type.U32Vec1.html)
|
/// * [`U32Vec1`]
|
||||||
/// * [`U64Vec1`](type.U64Vec1.html)
|
/// * [`U64Vec1`]
|
||||||
/// * [`U8Vec1`](type.U8Vec1.html)
|
/// * [`U8Vec1`]
|
||||||
/// * [`Vec1`](type.Vec1.html)
|
/// * [`Vec1`]
|
||||||
pub type TVec1<T> = TVec<T, 1>;
|
pub type TVec1<T> = TVec<T, 1>;
|
||||||
/// A 2D vector with components of type `T`.
|
/// A 2D vector with components of type `T`.
|
||||||
///
|
///
|
||||||
|
@ -76,29 +76,28 @@ pub type TVec1<T> = TVec<T, 1>;
|
||||||
///
|
///
|
||||||
/// ## Constructors:
|
/// ## Constructors:
|
||||||
///
|
///
|
||||||
/// * [`make_vec2`](fn.make_vec2.html)
|
/// * [`make_vec2()`](crate::make_vec2)
|
||||||
/// * [`vec2`](fn.vec2.html)
|
/// * [`vec2()`](crate::vec2)
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2()`](crate::vec1_to_vec2)
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2()`](crate::vec3_to_vec2)
|
||||||
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
|
/// * [`vec4_to_vec2()`](crate::vec4_to_vec2)
|
||||||
///
|
///
|
||||||
/// ## Related types:
|
/// ## Related types:
|
||||||
///
|
///
|
||||||
/// * [`vec2`](fn.vec2.html)
|
/// * [`BVec2`]
|
||||||
/// * [`BVec2`](type.BVec2.html)
|
/// * [`DVec2`]
|
||||||
/// * [`DVec2`](type.DVec2.html)
|
/// * [`IVec2`]
|
||||||
/// * [`IVec2`](type.IVec2.html)
|
/// * [`I16Vec2`]
|
||||||
/// * [`I16Vec2`](type.I16Vec2.html)
|
/// * [`I32Vec2`]
|
||||||
/// * [`I32Vec2`](type.I32Vec2.html)
|
/// * [`I64Vec2`]
|
||||||
/// * [`I64Vec2`](type.I64Vec2.html)
|
/// * [`I8Vec2`]
|
||||||
/// * [`I8Vec2`](type.I8Vec2.html)
|
/// * [`TVec`]
|
||||||
/// * [`TVec`](type.TVec.html)
|
/// * [`UVec2`]
|
||||||
/// * [`UVec2`](type.UVec2.html)
|
/// * [`U16Vec2`]
|
||||||
/// * [`U16Vec2`](type.U16Vec2.html)
|
/// * [`U32Vec2`]
|
||||||
/// * [`U32Vec2`](type.U32Vec2.html)
|
/// * [`U64Vec2`]
|
||||||
/// * [`U64Vec2`](type.U64Vec2.html)
|
/// * [`U8Vec2`]
|
||||||
/// * [`U8Vec2`](type.U8Vec2.html)
|
/// * [`Vec2`]
|
||||||
/// * [`Vec2`](type.Vec2.html)
|
|
||||||
pub type TVec2<T> = TVec<T, 2>;
|
pub type TVec2<T> = TVec<T, 2>;
|
||||||
/// A 3D vector with components of type `T`.
|
/// A 3D vector with components of type `T`.
|
||||||
///
|
///
|
||||||
|
@ -106,29 +105,28 @@ pub type TVec2<T> = TVec<T, 2>;
|
||||||
///
|
///
|
||||||
/// ## Constructors:
|
/// ## Constructors:
|
||||||
///
|
///
|
||||||
/// * [`make_vec3`](fn.make_vec3.html)
|
/// * [`make_vec3()`](crate::make_vec3)
|
||||||
/// * [`vec3`](fn.vec3.html)
|
/// * [`vec3()`](crate::vec3)
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3()`](crate::vec1_to_vec3)
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3()`](crate::vec2_to_vec3)
|
||||||
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
|
/// * [`vec4_to_vec3()`](crate::vec4_to_vec3)
|
||||||
///
|
///
|
||||||
/// ## Related types:
|
/// ## Related types:
|
||||||
///
|
///
|
||||||
/// * [`vec3`](fn.vec3.html)
|
/// * [`BVec3`]
|
||||||
/// * [`BVec3`](type.BVec3.html)
|
/// * [`DVec3`]
|
||||||
/// * [`DVec3`](type.DVec3.html)
|
/// * [`IVec3`]
|
||||||
/// * [`IVec3`](type.IVec3.html)
|
/// * [`I16Vec3`]
|
||||||
/// * [`I16Vec3`](type.I16Vec3.html)
|
/// * [`I32Vec3`]
|
||||||
/// * [`I32Vec3`](type.I32Vec3.html)
|
/// * [`I64Vec3`]
|
||||||
/// * [`I64Vec3`](type.I64Vec3.html)
|
/// * [`I8Vec3`]
|
||||||
/// * [`I8Vec3`](type.I8Vec3.html)
|
/// * [`TVec`]
|
||||||
/// * [`TVec`](type.TVec.html)
|
/// * [`UVec3`]
|
||||||
/// * [`UVec3`](type.UVec3.html)
|
/// * [`U16Vec3`]
|
||||||
/// * [`U16Vec3`](type.U16Vec3.html)
|
/// * [`U32Vec3`]
|
||||||
/// * [`U32Vec3`](type.U32Vec3.html)
|
/// * [`U64Vec3`]
|
||||||
/// * [`U64Vec3`](type.U64Vec3.html)
|
/// * [`U8Vec3`]
|
||||||
/// * [`U8Vec3`](type.U8Vec3.html)
|
/// * [`Vec3`]
|
||||||
/// * [`Vec3`](type.Vec3.html)
|
|
||||||
pub type TVec3<T> = TVec<T, 3>;
|
pub type TVec3<T> = TVec<T, 3>;
|
||||||
/// A 4D vector with components of type `T`.
|
/// A 4D vector with components of type `T`.
|
||||||
///
|
///
|
||||||
|
@ -136,28 +134,27 @@ pub type TVec3<T> = TVec<T, 3>;
|
||||||
///
|
///
|
||||||
/// ## Constructors:
|
/// ## Constructors:
|
||||||
///
|
///
|
||||||
/// * [`make_vec4`](fn.make_vec4.html)
|
/// * [`make_vec4()`](crate::make_vec4)
|
||||||
/// * [`vec4`](fn.vec4.html)
|
/// * [`vec4()`](crate::vec4)
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4()`](crate::vec1_to_vec4)
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4()`](crate::vec2_to_vec4)
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4()`](crate::vec3_to_vec4)
|
||||||
///
|
///
|
||||||
/// ## Related types:
|
/// ## Related types:
|
||||||
///
|
///
|
||||||
/// * [`vec4`](fn.vec4.html)
|
/// * [`BVec4`]
|
||||||
/// * [`BVec4`](type.BVec4.html)
|
/// * [`DVec4`]
|
||||||
/// * [`DVec4`](type.DVec4.html)
|
/// * [`IVec4`]
|
||||||
/// * [`IVec4`](type.IVec4.html)
|
/// * [`I16Vec4`]
|
||||||
/// * [`I16Vec4`](type.I16Vec4.html)
|
/// * [`I32Vec4`]
|
||||||
/// * [`I32Vec4`](type.I32Vec4.html)
|
/// * [`I64Vec4`]
|
||||||
/// * [`I64Vec4`](type.I64Vec4.html)
|
/// * [`I8Vec4`]
|
||||||
/// * [`I8Vec4`](type.I8Vec4.html)
|
/// * [`UVec4`]
|
||||||
/// * [`UVec4`](type.UVec4.html)
|
/// * [`U16Vec4`]
|
||||||
/// * [`U16Vec4`](type.U16Vec4.html)
|
/// * [`U32Vec4`]
|
||||||
/// * [`U32Vec4`](type.U32Vec4.html)
|
/// * [`U64Vec4`]
|
||||||
/// * [`U64Vec4`](type.U64Vec4.html)
|
/// * [`U8Vec4`]
|
||||||
/// * [`U8Vec4`](type.U8Vec4.html)
|
/// * [`Vec4`]
|
||||||
/// * [`Vec4`](type.Vec4.html)
|
|
||||||
pub type TVec4<T> = TVec<T, 4>;
|
pub type TVec4<T> = TVec<T, 4>;
|
||||||
/// A 1D vector with boolean components.
|
/// A 1D vector with boolean components.
|
||||||
pub type BVec1 = TVec1<bool>;
|
pub type BVec1 = TVec1<bool>;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use na;
|
|
||||||
|
|
||||||
use crate::aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
use crate::traits::Number;
|
use crate::traits::Number;
|
||||||
|
@ -20,7 +19,7 @@ use crate::RealNumber;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`sign`](fn.sign.html)
|
/// * [`sign()`]
|
||||||
pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat<T, R, C> {
|
pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat<T, R, C> {
|
||||||
x.abs()
|
x.abs()
|
||||||
}
|
}
|
||||||
|
@ -37,11 +36,11 @@ pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`ceil`](fn.ceil.html)
|
/// * [`ceil()`]
|
||||||
/// * [`floor`](fn.floor.html)
|
/// * [`floor()`]
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract()`]
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round()`]
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc()`]
|
||||||
pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|x| x.ceil())
|
x.map(|x| x.ceil())
|
||||||
}
|
}
|
||||||
|
@ -65,8 +64,8 @@ pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`clamp`](fn.clamp.html)
|
/// * [`clamp()`]
|
||||||
/// * [`clamp_vec`](fn.clamp_vec.html)
|
/// * [`clamp_vec()`]
|
||||||
pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
|
pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
|
||||||
na::clamp(x, min_val, max_val)
|
na::clamp(x, min_val, max_val)
|
||||||
}
|
}
|
||||||
|
@ -89,8 +88,8 @@ pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`clamp_scalar`](fn.clamp_scalar.html)
|
/// * [`clamp_scalar()`]
|
||||||
/// * [`clamp_vec`](fn.clamp_vec.html)
|
/// * [`clamp_vec()`]
|
||||||
pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T) -> TVec<T, D> {
|
pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T) -> TVec<T, D> {
|
||||||
x.map(|x| na::clamp(x, min_val, max_val))
|
x.map(|x| na::clamp(x, min_val, max_val))
|
||||||
}
|
}
|
||||||
|
@ -120,8 +119,8 @@ pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T)
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`clamp_scalar`](fn.clamp_scalar.html)
|
/// * [`clamp_scalar()`]
|
||||||
/// * [`clamp`](fn.clamp.html)
|
/// * [`clamp()`]
|
||||||
pub fn clamp_vec<T: Number, const D: usize>(
|
pub fn clamp_vec<T: Number, const D: usize>(
|
||||||
x: &TVec<T, D>,
|
x: &TVec<T, D>,
|
||||||
min_val: &TVec<T, D>,
|
min_val: &TVec<T, D>,
|
||||||
|
@ -136,13 +135,13 @@ pub fn clamp_vec<T: Number, const D: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
|
/// * [`float_bits_to_int_vec()`]
|
||||||
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
|
/// * [`float_bits_to_uint()`]
|
||||||
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
|
/// * [`float_bits_to_uint_vec()`]
|
||||||
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
|
/// * [`int_bits_to_float()`]
|
||||||
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
|
/// * [`int_bits_to_float_vec()`]
|
||||||
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
|
/// * [`uint_bits_to_float()`]
|
||||||
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
/// * [`uint_bits_to_float_scalar()`]
|
||||||
pub fn float_bits_to_int(v: f32) -> i32 {
|
pub fn float_bits_to_int(v: f32) -> i32 {
|
||||||
unsafe { mem::transmute(v) }
|
unsafe { mem::transmute(v) }
|
||||||
}
|
}
|
||||||
|
@ -153,13 +152,13 @@ pub fn float_bits_to_int(v: f32) -> i32 {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
|
/// * [`float_bits_to_int()`]
|
||||||
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
|
/// * [`float_bits_to_uint()`]
|
||||||
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
|
/// * [`float_bits_to_uint_vec()`]
|
||||||
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
|
/// * [`int_bits_to_float()`]
|
||||||
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
|
/// * [`int_bits_to_float_vec()`]
|
||||||
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
|
/// * [`uint_bits_to_float()`]
|
||||||
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
/// * [`uint_bits_to_float_scalar()`]
|
||||||
pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
|
pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
|
||||||
v.map(float_bits_to_int)
|
v.map(float_bits_to_int)
|
||||||
}
|
}
|
||||||
|
@ -170,13 +169,13 @@ pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
|
/// * [`float_bits_to_int()`]
|
||||||
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
|
/// * [`float_bits_to_int_vec()`]
|
||||||
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
|
/// * [`float_bits_to_uint_vec()`]
|
||||||
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
|
/// * [`int_bits_to_float()`]
|
||||||
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
|
/// * [`int_bits_to_float_vec()`]
|
||||||
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
|
/// * [`uint_bits_to_float()`]
|
||||||
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
/// * [`uint_bits_to_float_scalar()`]
|
||||||
pub fn float_bits_to_uint(v: f32) -> u32 {
|
pub fn float_bits_to_uint(v: f32) -> u32 {
|
||||||
unsafe { mem::transmute(v) }
|
unsafe { mem::transmute(v) }
|
||||||
}
|
}
|
||||||
|
@ -187,13 +186,13 @@ pub fn float_bits_to_uint(v: f32) -> u32 {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
|
/// * [`float_bits_to_int()`]
|
||||||
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
|
/// * [`float_bits_to_int_vec()`]
|
||||||
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
|
/// * [`float_bits_to_uint()`]
|
||||||
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
|
/// * [`int_bits_to_float()`]
|
||||||
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
|
/// * [`int_bits_to_float_vec()`]
|
||||||
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
|
/// * [`uint_bits_to_float()`]
|
||||||
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
/// * [`uint_bits_to_float_scalar()`]
|
||||||
pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D> {
|
pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D> {
|
||||||
v.map(float_bits_to_uint)
|
v.map(float_bits_to_uint)
|
||||||
}
|
}
|
||||||
|
@ -210,10 +209,10 @@ pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D>
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`ceil`](fn.ceil.html)
|
/// * [`ceil()`]
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract()`]
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round()`]
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc()`]
|
||||||
pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|x| x.floor())
|
x.map(|x| x.floor())
|
||||||
}
|
}
|
||||||
|
@ -236,10 +235,10 @@ pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`ceil`](fn.ceil.html)
|
/// * [`ceil()`]
|
||||||
/// * [`floor`](fn.floor.html)
|
/// * [`floor()`]
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round()`]
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc()`]
|
||||||
pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|x| x.fract())
|
x.map(|x| x.fract())
|
||||||
}
|
}
|
||||||
|
@ -258,13 +257,13 @@ pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
|
/// * [`float_bits_to_int()`]
|
||||||
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
|
/// * [`float_bits_to_int_vec()`]
|
||||||
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
|
/// * [`float_bits_to_uint()`]
|
||||||
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
|
/// * [`float_bits_to_uint_vec()`]
|
||||||
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
|
/// * [`int_bits_to_float_vec()`]
|
||||||
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
|
/// * [`uint_bits_to_float()`]
|
||||||
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
/// * [`uint_bits_to_float_scalar()`]
|
||||||
pub fn int_bits_to_float(v: i32) -> f32 {
|
pub fn int_bits_to_float(v: i32) -> f32 {
|
||||||
f32::from_bits(v as u32)
|
f32::from_bits(v as u32)
|
||||||
}
|
}
|
||||||
|
@ -275,13 +274,13 @@ pub fn int_bits_to_float(v: i32) -> f32 {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
|
/// * [`float_bits_to_int()`]
|
||||||
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
|
/// * [`float_bits_to_int_vec()`]
|
||||||
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
|
/// * [`float_bits_to_uint()`]
|
||||||
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
|
/// * [`float_bits_to_uint_vec()`]
|
||||||
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
|
/// * [`int_bits_to_float()`]
|
||||||
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
|
/// * [`uint_bits_to_float()`]
|
||||||
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
/// * [`uint_bits_to_float_scalar()`]
|
||||||
pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
|
pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
|
||||||
v.map(int_bits_to_float)
|
v.map(int_bits_to_float)
|
||||||
}
|
}
|
||||||
|
@ -315,8 +314,8 @@ pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`mix`](fn.mix.html)
|
/// * [`mix()`]
|
||||||
/// * [`mix_vec`](fn.mix_vec.html)
|
/// * [`mix_vec()`]
|
||||||
pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
|
pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
|
||||||
x * (T::one() - a) + y * a
|
x * (T::one() - a) + y * a
|
||||||
}
|
}
|
||||||
|
@ -336,8 +335,8 @@ pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`mix_scalar`](fn.mix_scalar.html)
|
/// * [`mix_scalar()`]
|
||||||
/// * [`mix_vec`](fn.mix_vec.html)
|
/// * [`mix_vec()`]
|
||||||
pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
|
pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
|
||||||
x * (T::one() - a) + y * a
|
x * (T::one() - a) + y * a
|
||||||
}
|
}
|
||||||
|
@ -359,14 +358,14 @@ pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> T
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`mix_scalar`](fn.mix_scalar.html)
|
/// * [`mix_scalar()`]
|
||||||
/// * [`mix`](fn.mix.html)
|
/// * [`mix()`]
|
||||||
pub fn mix_vec<T: Number, const D: usize>(
|
pub fn mix_vec<T: Number, const D: usize>(
|
||||||
x: &TVec<T, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<T, D>,
|
y: &TVec<T, D>,
|
||||||
a: &TVec<T, D>,
|
a: &TVec<T, D>,
|
||||||
) -> TVec<T, D> {
|
) -> TVec<T, D> {
|
||||||
x.component_mul(&(TVec::<T, D>::repeat(T::one()) - a)) + y.component_mul(&a)
|
x.component_mul(&(TVec::<T, D>::repeat(T::one()) - a)) + y.component_mul(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a.
|
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a.
|
||||||
|
@ -383,8 +382,8 @@ pub fn mix_vec<T: Number, const D: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`lerp`](fn.lerp.html)
|
/// * [`lerp()`]
|
||||||
/// * [`lerp_vec`](fn.lerp_vec.html)
|
/// * [`lerp_vec()`]
|
||||||
pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
|
pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
|
||||||
mix_scalar(x, y, a)
|
mix_scalar(x, y, a)
|
||||||
}
|
}
|
||||||
|
@ -405,8 +404,8 @@ pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`lerp_scalar`](fn.lerp_scalar.html)
|
/// * [`lerp_scalar()`]
|
||||||
/// * [`lerp_vec`](fn.lerp_vec.html)
|
/// * [`lerp_vec()`]
|
||||||
pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
|
pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
|
||||||
mix(x, y, a)
|
mix(x, y, a)
|
||||||
}
|
}
|
||||||
|
@ -429,8 +428,8 @@ pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) ->
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`lerp_scalar`](fn.lerp_scalar.html)
|
/// * [`lerp_scalar()`]
|
||||||
/// * [`lerp`](fn.lerp.html)
|
/// * [`lerp()`]
|
||||||
pub fn lerp_vec<T: Number, const D: usize>(
|
pub fn lerp_vec<T: Number, const D: usize>(
|
||||||
x: &TVec<T, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<T, D>,
|
y: &TVec<T, D>,
|
||||||
|
@ -445,7 +444,7 @@ pub fn lerp_vec<T: Number, const D: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`modf`](fn.modf.html)
|
/// * [`modf()`]
|
||||||
pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
|
pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.zip_map(y, |x, y| x % y)
|
x.zip_map(y, |x, y| x % y)
|
||||||
}
|
}
|
||||||
|
@ -454,7 +453,7 @@ pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TV
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`modf_vec`](fn.modf_vec.html)
|
/// * [`modf_vec()`]
|
||||||
pub fn modf<T: Number>(x: T, i: T) -> T {
|
pub fn modf<T: Number>(x: T, i: T) -> T {
|
||||||
x % i
|
x % i
|
||||||
}
|
}
|
||||||
|
@ -473,10 +472,10 @@ pub fn modf<T: Number>(x: T, i: T) -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`ceil`](fn.ceil.html)
|
/// * [`ceil()`]
|
||||||
/// * [`floor`](fn.floor.html)
|
/// * [`floor()`]
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract()`]
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc()`]
|
||||||
pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|x| x.round())
|
x.map(|x| x.round())
|
||||||
}
|
}
|
||||||
|
@ -497,7 +496,7 @@ pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`abs`](fn.abs.html)
|
/// * [`abs()`]
|
||||||
///
|
///
|
||||||
pub fn sign<T: Number, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn sign<T: Number, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|x| if x.is_zero() { T::zero() } else { x.signum() })
|
x.map(|x| if x.is_zero() { T::zero() } else { x.signum() })
|
||||||
|
@ -545,10 +544,10 @@ pub fn step_vec<T: Number, const D: usize>(edge: &TVec<T, D>, x: &TVec<T, D>) ->
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`ceil`](fn.ceil.html)
|
/// * [`ceil()`]
|
||||||
/// * [`floor`](fn.floor.html)
|
/// * [`floor()`]
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract()`]
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round()`]
|
||||||
pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.map(|x| x.trunc())
|
x.map(|x| x.trunc())
|
||||||
}
|
}
|
||||||
|
@ -559,13 +558,13 @@ pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
|
/// * [`float_bits_to_int()`]
|
||||||
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
|
/// * [`float_bits_to_int_vec()`]
|
||||||
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
|
/// * [`float_bits_to_uint()`]
|
||||||
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
|
/// * [`float_bits_to_uint_vec()`]
|
||||||
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
|
/// * [`int_bits_to_float()`]
|
||||||
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
|
/// * [`int_bits_to_float_vec()`]
|
||||||
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
|
/// * [`uint_bits_to_float()`]
|
||||||
pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
|
pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
|
||||||
f32::from_bits(v)
|
f32::from_bits(v)
|
||||||
}
|
}
|
||||||
|
@ -576,13 +575,13 @@ pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
|
/// * [`float_bits_to_int()`]
|
||||||
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
|
/// * [`float_bits_to_int_vec()`]
|
||||||
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
|
/// * [`float_bits_to_uint()`]
|
||||||
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
|
/// * [`float_bits_to_uint_vec()`]
|
||||||
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
|
/// * [`int_bits_to_float()`]
|
||||||
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
|
/// * [`int_bits_to_float_vec()`]
|
||||||
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
/// * [`uint_bits_to_float_scalar()`]
|
||||||
pub fn uint_bits_to_float<const D: usize>(v: &TVec<u32, D>) -> TVec<f32, D> {
|
pub fn uint_bits_to_float<const D: usize>(v: &TVec<u32, D>) -> TVec<f32, D> {
|
||||||
v.map(uint_bits_to_float_scalar)
|
v.map(uint_bits_to_float_scalar)
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,7 @@ pub fn mat2x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn mat3<T: Scalar>(m11: T, m12: T, m13: T,
|
pub fn mat3<T: Scalar>(m11: T, m12: T, m13: T,
|
||||||
m21: T, m22: T, m23: T,
|
m21: T, m22: T, m23: T,
|
||||||
m31: T, m32: T, m33: T) -> TMat3<T> {
|
m31: T, m32: T, m33: T) -> TMat3<T> {
|
||||||
|
@ -115,6 +116,7 @@ pub fn mat3x2<T: Scalar>(m11: T, m12: T,
|
||||||
|
|
||||||
/// Create a new 3x3 matrix.
|
/// Create a new 3x3 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T,
|
pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T,
|
||||||
m21: T, m22: T, m23: T,
|
m21: T, m22: T, m23: T,
|
||||||
m31: T, m32: T, m33: T) -> TMat3<T> {
|
m31: T, m32: T, m33: T) -> TMat3<T> {
|
||||||
|
@ -127,6 +129,7 @@ pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T,
|
||||||
|
|
||||||
/// Create a new 3x4 matrix.
|
/// Create a new 3x4 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn mat3x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
pub fn mat3x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
||||||
m21: T, m22: T, m23: T, m24: T,
|
m21: T, m22: T, m23: T, m24: T,
|
||||||
m31: T, m32: T, m33: T, m34: T) -> TMat3x4<T> {
|
m31: T, m32: T, m33: T, m34: T) -> TMat3x4<T> {
|
||||||
|
@ -153,6 +156,7 @@ pub fn mat4x2<T: Scalar>(m11: T, m12: T,
|
||||||
|
|
||||||
/// Create a new 4x3 matrix.
|
/// Create a new 4x3 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T,
|
pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T,
|
||||||
m21: T, m22: T, m23: T,
|
m21: T, m22: T, m23: T,
|
||||||
m31: T, m32: T, m33: T,
|
m31: T, m32: T, m33: T,
|
||||||
|
@ -167,6 +171,7 @@ pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T,
|
||||||
|
|
||||||
/// Create a new 4x4 matrix.
|
/// Create a new 4x4 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
||||||
m21: T, m22: T, m23: T, m24: T,
|
m21: T, m22: T, m23: T, m24: T,
|
||||||
m31: T, m32: T, m33: T, m34: T,
|
m31: T, m32: T, m33: T, m34: T,
|
||||||
|
@ -181,6 +186,7 @@ pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
||||||
|
|
||||||
/// Create a new 4x4 matrix.
|
/// Create a new 4x4 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn mat4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
pub fn mat4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
||||||
m21: T, m22: T, m23: T, m24: T,
|
m21: T, m22: T, m23: T, m24: T,
|
||||||
m31: T, m32: T, m33: T, m34: T,
|
m31: T, m32: T, m33: T, m34: T,
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::RealNumber;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`exp2`](fn.exp2.html)
|
/// * [`exp2()`]
|
||||||
pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| x.exp())
|
v.map(|x| x.exp())
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`exp`](fn.exp.html)
|
/// * [`exp()`]
|
||||||
pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| x.exp2())
|
v.map(|x| x.exp2())
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`sqrt`](fn.sqrt.html)
|
/// * [`sqrt()`]
|
||||||
pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| T::one() / x.sqrt())
|
v.map(|x| T::one() / x.sqrt())
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D>
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`log2`](fn.log2.html)
|
/// * [`log2()`]
|
||||||
pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| x.ln())
|
v.map(|x| x.ln())
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`log`](fn.log.html)
|
/// * [`log()`]
|
||||||
pub fn log2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn log2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| x.log2())
|
v.map(|x| x.log2())
|
||||||
}
|
}
|
||||||
|
@ -55,10 +55,10 @@ pub fn pow<T: RealNumber, const D: usize>(base: &TVec<T, D>, exponent: &TVec<T,
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`exp`](fn.exp.html)
|
/// * [`exp()`]
|
||||||
/// * [`exp2`](fn.exp2.html)
|
/// * [`exp2()`]
|
||||||
/// * [`inversesqrt`](fn.inversesqrt.html)
|
/// * [`inversesqrt()`]
|
||||||
/// * [`pow`](fn.pow.html)
|
/// * [`pow`]
|
||||||
pub fn sqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
pub fn sqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
v.map(|x| x.sqrt())
|
v.map(|x| x.sqrt())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use na;
|
|
||||||
|
|
||||||
use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
||||||
use crate::RealNumber;
|
use crate::RealNumber;
|
||||||
|
|
||||||
|
@ -41,11 +39,11 @@ pub fn pick_matrix<T: RealNumber>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`project_no`](fn.project_no.html)
|
/// * [`project_no()`]
|
||||||
/// * [`project_zo`](fn.project_zo.html)
|
/// * [`project_zo()`]
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject()`]
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no()`]
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo()`]
|
||||||
pub fn project<T: RealNumber>(
|
pub fn project<T: RealNumber>(
|
||||||
obj: &TVec3<T>,
|
obj: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
|
@ -68,11 +66,11 @@ pub fn project<T: RealNumber>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`project`](fn.project.html)
|
/// * [`project()`]
|
||||||
/// * [`project_zo`](fn.project_zo.html)
|
/// * [`project_zo()`]
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject()`]
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no()`]
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo()`]
|
||||||
pub fn project_no<T: RealNumber>(
|
pub fn project_no<T: RealNumber>(
|
||||||
obj: &TVec3<T>,
|
obj: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
|
@ -96,11 +94,11 @@ pub fn project_no<T: RealNumber>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`project`](fn.project.html)
|
/// * [`project()`]
|
||||||
/// * [`project_no`](fn.project_no.html)
|
/// * [`project_no()`]
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject()`]
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no()`]
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo()`]
|
||||||
pub fn project_zo<T: RealNumber>(
|
pub fn project_zo<T: RealNumber>(
|
||||||
obj: &TVec3<T>,
|
obj: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
|
@ -129,11 +127,11 @@ pub fn project_zo<T: RealNumber>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`project`](fn.project.html)
|
/// * [`project()`]
|
||||||
/// * [`project_no`](fn.project_no.html)
|
/// * [`project_no()`]
|
||||||
/// * [`project_zo`](fn.project_zo.html)
|
/// * [`project_zo()`]
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no()`]
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo()`]
|
||||||
pub fn unproject<T: RealNumber>(
|
pub fn unproject<T: RealNumber>(
|
||||||
win: &TVec3<T>,
|
win: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
|
@ -156,11 +154,11 @@ pub fn unproject<T: RealNumber>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`project`](fn.project.html)
|
/// * [`project()`]
|
||||||
/// * [`project_no`](fn.project_no.html)
|
/// * [`project_no()`]
|
||||||
/// * [`project_zo`](fn.project_zo.html)
|
/// * [`project_zo()`]
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject()`]
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo()`]
|
||||||
pub fn unproject_no<T: RealNumber>(
|
pub fn unproject_no<T: RealNumber>(
|
||||||
win: &TVec3<T>,
|
win: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
|
@ -193,11 +191,11 @@ pub fn unproject_no<T: RealNumber>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`project`](fn.project.html)
|
/// * [`project()`]
|
||||||
/// * [`project_no`](fn.project_no.html)
|
/// * [`project_no()`]
|
||||||
/// * [`project_zo`](fn.project_zo.html)
|
/// * [`project_zo()`]
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject()`]
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no()`]
|
||||||
pub fn unproject_zo<T: RealNumber>(
|
pub fn unproject_zo<T: RealNumber>(
|
||||||
win: &TVec3<T>,
|
win: &TVec3<T>,
|
||||||
model: &TMat4<T>,
|
model: &TMat4<T>,
|
||||||
|
|
|
@ -18,8 +18,8 @@ pub fn identity<T: Number, const D: usize>() -> TMat<T, D, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`look_at_lh`](fn.look_at_lh.html)
|
/// * [`look_at_lh()`]
|
||||||
/// * [`look_at_rh`](fn.look_at_rh.html)
|
/// * [`look_at_rh()`]
|
||||||
pub fn look_at<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
pub fn look_at<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
look_at_rh(eye, center, up)
|
look_at_rh(eye, center, up)
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,8 @@ pub fn look_at<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>)
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`look_at`](fn.look_at.html)
|
/// * [`look_at()`]
|
||||||
/// * [`look_at_rh`](fn.look_at_rh.html)
|
/// * [`look_at_rh()`]
|
||||||
pub fn look_at_lh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
pub fn look_at_lh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up)
|
TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up)
|
||||||
}
|
}
|
||||||
|
@ -50,8 +50,8 @@ pub fn look_at_lh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`look_at`](fn.look_at.html)
|
/// * [`look_at()`]
|
||||||
/// * [`look_at_lh`](fn.look_at_lh.html)
|
/// * [`look_at_lh()`]
|
||||||
pub fn look_at_rh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
pub fn look_at_rh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up)
|
TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up)
|
||||||
}
|
}
|
||||||
|
@ -66,11 +66,11 @@ pub fn look_at_rh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotate_x`](fn.rotate_x.html)
|
/// * [`rotate_x()`]
|
||||||
/// * [`rotate_y`](fn.rotate_y.html)
|
/// * [`rotate_y()`]
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z()`]
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale()`]
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate()`]
|
||||||
pub fn rotate<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
|
pub fn rotate<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
|
||||||
m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous()
|
m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,11 @@ pub fn rotate<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotate`](fn.rotate.html)
|
/// * [`rotate()`]
|
||||||
/// * [`rotate_y`](fn.rotate_y.html)
|
/// * [`rotate_y()`]
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z()`]
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale()`]
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate()`]
|
||||||
pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
rotate(m, angle, &TVec::x())
|
rotate(m, angle, &TVec::x())
|
||||||
}
|
}
|
||||||
|
@ -102,11 +102,11 @@ pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotate`](fn.rotate.html)
|
/// * [`rotate()`]
|
||||||
/// * [`rotate_x`](fn.rotate_x.html)
|
/// * [`rotate_x()`]
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z()`]
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale()`]
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate()`]
|
||||||
pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
rotate(m, angle, &TVec::y())
|
rotate(m, angle, &TVec::y())
|
||||||
}
|
}
|
||||||
|
@ -120,11 +120,11 @@ pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotate`](fn.rotate.html)
|
/// * [`rotate()`]
|
||||||
/// * [`rotate_x`](fn.rotate_x.html)
|
/// * [`rotate_x()`]
|
||||||
/// * [`rotate_y`](fn.rotate_y.html)
|
/// * [`rotate_y()`]
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale()`]
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate()`]
|
||||||
pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
rotate(m, angle, &TVec::z())
|
rotate(m, angle, &TVec::z())
|
||||||
}
|
}
|
||||||
|
@ -138,11 +138,11 @@ pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotate`](fn.rotate.html)
|
/// * [`rotate()`]
|
||||||
/// * [`rotate_x`](fn.rotate_x.html)
|
/// * [`rotate_x()`]
|
||||||
/// * [`rotate_y`](fn.rotate_y.html)
|
/// * [`rotate_y()`]
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z()`]
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate()`]
|
||||||
pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
|
pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
|
||||||
m.prepend_nonuniform_scaling(v)
|
m.prepend_nonuniform_scaling(v)
|
||||||
}
|
}
|
||||||
|
@ -156,11 +156,11 @@ pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotate`](fn.rotate.html)
|
/// * [`rotate()`]
|
||||||
/// * [`rotate_x`](fn.rotate_x.html)
|
/// * [`rotate_x()`]
|
||||||
/// * [`rotate_y`](fn.rotate_y.html)
|
/// * [`rotate_y()`]
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z()`]
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale()`]
|
||||||
pub fn translate<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
|
pub fn translate<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
|
||||||
m.prepend_translation(v)
|
m.prepend_translation(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use na::{self, Unit};
|
use na::Unit;
|
||||||
|
|
||||||
use crate::aliases::Qua;
|
use crate::aliases::Qua;
|
||||||
use crate::RealNumber;
|
use crate::RealNumber;
|
||||||
|
|
|
@ -12,9 +12,9 @@ use crate::traits::Number;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`max4_scalar`](fn.max4_scalar.html)
|
/// * [`max4_scalar()`]
|
||||||
/// * [`min3_scalar`](fn.min3_scalar.html)
|
/// * [`min3_scalar()`]
|
||||||
/// * [`min4_scalar`](fn.min4_scalar.html)
|
/// * [`min4_scalar()`]
|
||||||
pub fn max2_scalar<T: Number>(a: T, b: T) -> T {
|
pub fn max2_scalar<T: Number>(a: T, b: T) -> T {
|
||||||
if a >= b {
|
if a >= b {
|
||||||
a
|
a
|
||||||
|
@ -35,9 +35,9 @@ pub fn max2_scalar<T: Number>(a: T, b: T) -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`max4_scalar`](fn.max4_scalar.html)
|
/// * [`max4_scalar()`]
|
||||||
/// * [`min3_scalar`](fn.min3_scalar.html)
|
/// * [`min3_scalar()`]
|
||||||
/// * [`min4_scalar`](fn.min4_scalar.html)
|
/// * [`min4_scalar()`]
|
||||||
pub fn min2_scalar<T: Number>(a: T, b: T) -> T {
|
pub fn min2_scalar<T: Number>(a: T, b: T) -> T {
|
||||||
if a <= b {
|
if a <= b {
|
||||||
a
|
a
|
||||||
|
@ -58,9 +58,9 @@ pub fn min2_scalar<T: Number>(a: T, b: T) -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`max4_scalar`](fn.max4_scalar.html)
|
/// * [`max4_scalar()`]
|
||||||
/// * [`min3_scalar`](fn.min3_scalar.html)
|
/// * [`min3_scalar()`]
|
||||||
/// * [`min4_scalar`](fn.min4_scalar.html)
|
/// * [`min4_scalar()`]
|
||||||
pub fn max3_scalar<T: Number>(a: T, b: T, c: T) -> T {
|
pub fn max3_scalar<T: Number>(a: T, b: T, c: T) -> T {
|
||||||
max2_scalar(max2_scalar(a, b), c)
|
max2_scalar(max2_scalar(a, b), c)
|
||||||
}
|
}
|
||||||
|
@ -77,9 +77,9 @@ pub fn max3_scalar<T: Number>(a: T, b: T, c: T) -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`max3_scalar`](fn.max3_scalar.html)
|
/// * [`max3_scalar()`]
|
||||||
/// * [`min3_scalar`](fn.min3_scalar.html)
|
/// * [`min3_scalar()`]
|
||||||
/// * [`min4_scalar`](fn.min4_scalar.html)
|
/// * [`min4_scalar()`]
|
||||||
pub fn max4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
|
pub fn max4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
|
||||||
max2_scalar(max2_scalar(a, b), max2_scalar(c, d))
|
max2_scalar(max2_scalar(a, b), max2_scalar(c, d))
|
||||||
}
|
}
|
||||||
|
@ -96,9 +96,9 @@ pub fn max4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`max3_scalar`](fn.max3_scalar.html)
|
/// * [`max3_scalar()`]
|
||||||
/// * [`max4_scalar`](fn.max4_scalar.html)
|
/// * [`max4_scalar()`]
|
||||||
/// * [`min4_scalar`](fn.min4_scalar.html)
|
/// * [`min4_scalar()`]
|
||||||
pub fn min3_scalar<T: Number>(a: T, b: T, c: T) -> T {
|
pub fn min3_scalar<T: Number>(a: T, b: T, c: T) -> T {
|
||||||
min2_scalar(min2_scalar(a, b), c)
|
min2_scalar(min2_scalar(a, b), c)
|
||||||
}
|
}
|
||||||
|
@ -115,9 +115,9 @@ pub fn min3_scalar<T: Number>(a: T, b: T, c: T) -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`max3_scalar`](fn.max3_scalar.html)
|
/// * [`max3_scalar()`]
|
||||||
/// * [`max4_scalar`](fn.max4_scalar.html)
|
/// * [`max4_scalar()`]
|
||||||
/// * [`min3_scalar`](fn.min3_scalar.html)
|
/// * [`min3_scalar()`]
|
||||||
pub fn min4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
|
pub fn min4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
|
||||||
min2_scalar(min2_scalar(a, b), min2_scalar(c, d))
|
min2_scalar(min2_scalar(a, b), min2_scalar(c, d))
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,18 +10,18 @@ pub fn epsilon<T: AbsDiffEq<Epsilon = T>>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`](crate::four_over_pi)
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`](crate::half_pi)
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`](crate::one_over_pi)
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`](crate::one_over_two_pi)
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`quarter_pi()`](crate::quarter_pi)
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`root_half_pi()`](crate::root_half_pi)
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_pi()`](crate::root_pi)
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_two_pi()`](crate::root_two_pi)
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi()`](crate::three_over_two_pi)
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`](crate::two_over_pi)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi()`](crate::two_over_root_pi)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi()`](crate::two_pi)
|
||||||
pub fn pi<T: RealNumber>() -> T {
|
pub fn pi<T: RealNumber>() -> T {
|
||||||
T::pi()
|
T::pi()
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,15 @@ use crate::traits::Number;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`](crate::comp_max)
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min()`](crate::comp_min)
|
||||||
/// * [`max2`](fn.max2.html)
|
/// * [`max2()`]
|
||||||
/// * [`max3`](fn.max3.html)
|
/// * [`max3()`]
|
||||||
/// * [`max4`](fn.max4.html)
|
/// * [`max4()`]
|
||||||
/// * [`min`](fn.min.html)
|
/// * [`min()`]
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2()`]
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3()`]
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4()`]
|
||||||
pub fn max<T: Number, const D: usize>(a: &TVec<T, D>, b: T) -> TVec<T, D> {
|
pub fn max<T: Number, const D: usize>(a: &TVec<T, D>, b: T) -> TVec<T, D> {
|
||||||
a.map(|a| crate::max2_scalar(a, b))
|
a.map(|a| crate::max2_scalar(a, b))
|
||||||
}
|
}
|
||||||
|
@ -22,15 +22,15 @@ pub fn max<T: Number, const D: usize>(a: &TVec<T, D>, b: T) -> TVec<T, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`](crate::comp_max)
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min()`](crate::comp_min)
|
||||||
/// * [`max`](fn.max.html)
|
/// * [`max()`]
|
||||||
/// * [`max3`](fn.max3.html)
|
/// * [`max3()`]
|
||||||
/// * [`max4`](fn.max4.html)
|
/// * [`max4()`]
|
||||||
/// * [`min`](fn.min.html)
|
/// * [`min()`]
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2()`]
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3()`]
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4()`]
|
||||||
pub fn max2<T: Number, const D: usize>(a: &TVec<T, D>, b: &TVec<T, D>) -> TVec<T, D> {
|
pub fn max2<T: Number, const D: usize>(a: &TVec<T, D>, b: &TVec<T, D>) -> TVec<T, D> {
|
||||||
a.zip_map(b, |a, b| crate::max2_scalar(a, b))
|
a.zip_map(b, |a, b| crate::max2_scalar(a, b))
|
||||||
}
|
}
|
||||||
|
@ -39,15 +39,15 @@ pub fn max2<T: Number, const D: usize>(a: &TVec<T, D>, b: &TVec<T, D>) -> TVec<T
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`](crate::comp_max)
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min()`](crate::comp_min)
|
||||||
/// * [`max`](fn.max.html)
|
/// * [`max()`]
|
||||||
/// * [`max2`](fn.max2.html)
|
/// * [`max2()`]
|
||||||
/// * [`max4`](fn.max4.html)
|
/// * [`max4()`]
|
||||||
/// * [`min`](fn.min.html)
|
/// * [`min()`]
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2()`]
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3()`]
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4()`]
|
||||||
pub fn max3<T: Number, const D: usize>(
|
pub fn max3<T: Number, const D: usize>(
|
||||||
a: &TVec<T, D>,
|
a: &TVec<T, D>,
|
||||||
b: &TVec<T, D>,
|
b: &TVec<T, D>,
|
||||||
|
@ -60,15 +60,15 @@ pub fn max3<T: Number, const D: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`](crate::comp_max)
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min()`](crate::comp_min)
|
||||||
/// * [`max`](fn.max.html)
|
/// * [`max()`]
|
||||||
/// * [`max2`](fn.max2.html)
|
/// * [`max2()`]
|
||||||
/// * [`max3`](fn.max3.html)
|
/// * [`max3()`]
|
||||||
/// * [`min`](fn.min.html)
|
/// * [`min()`]
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2()`]
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3()`]
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4()`]
|
||||||
pub fn max4<T: Number, const D: usize>(
|
pub fn max4<T: Number, const D: usize>(
|
||||||
a: &TVec<T, D>,
|
a: &TVec<T, D>,
|
||||||
b: &TVec<T, D>,
|
b: &TVec<T, D>,
|
||||||
|
@ -82,15 +82,15 @@ pub fn max4<T: Number, const D: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`](crate::comp_max)
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min()`](crate::comp_min)
|
||||||
/// * [`max`](fn.max.html)
|
/// * [`max()`]
|
||||||
/// * [`max2`](fn.max2.html)
|
/// * [`max2()`]
|
||||||
/// * [`max3`](fn.max3.html)
|
/// * [`max3()`]
|
||||||
/// * [`max4`](fn.max4.html)
|
/// * [`max4()`]
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2()`]
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3()`]
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4()`]
|
||||||
pub fn min<T: Number, const D: usize>(x: &TVec<T, D>, y: T) -> TVec<T, D> {
|
pub fn min<T: Number, const D: usize>(x: &TVec<T, D>, y: T) -> TVec<T, D> {
|
||||||
x.map(|x| crate::min2_scalar(x, y))
|
x.map(|x| crate::min2_scalar(x, y))
|
||||||
}
|
}
|
||||||
|
@ -99,15 +99,15 @@ pub fn min<T: Number, const D: usize>(x: &TVec<T, D>, y: T) -> TVec<T, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`](crate::comp_max)
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min()`](crate::comp_min)
|
||||||
/// * [`max`](fn.max.html)
|
/// * [`max()`]
|
||||||
/// * [`max2`](fn.max2.html)
|
/// * [`max2()`]
|
||||||
/// * [`max3`](fn.max3.html)
|
/// * [`max3()`]
|
||||||
/// * [`max4`](fn.max4.html)
|
/// * [`max4()`]
|
||||||
/// * [`min`](fn.min.html)
|
/// * [`min()`]
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3()`]
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4()`]
|
||||||
pub fn min2<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
|
pub fn min2<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
|
||||||
x.zip_map(y, |a, b| crate::min2_scalar(a, b))
|
x.zip_map(y, |a, b| crate::min2_scalar(a, b))
|
||||||
}
|
}
|
||||||
|
@ -116,15 +116,15 @@ pub fn min2<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`](crate::comp_max)
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min()`](crate::comp_min)
|
||||||
/// * [`max`](fn.max.html)
|
/// * [`max()`]
|
||||||
/// * [`max2`](fn.max2.html)
|
/// * [`max2()`]
|
||||||
/// * [`max3`](fn.max3.html)
|
/// * [`max3()`]
|
||||||
/// * [`max4`](fn.max4.html)
|
/// * [`max4()`]
|
||||||
/// * [`min`](fn.min.html)
|
/// * [`min()`]
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2()`]
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4()`]
|
||||||
pub fn min3<T: Number, const D: usize>(
|
pub fn min3<T: Number, const D: usize>(
|
||||||
a: &TVec<T, D>,
|
a: &TVec<T, D>,
|
||||||
b: &TVec<T, D>,
|
b: &TVec<T, D>,
|
||||||
|
@ -137,15 +137,15 @@ pub fn min3<T: Number, const D: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`](crate::comp_max)
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min()`](crate::comp_min)
|
||||||
/// * [`max`](fn.max.html)
|
/// * [`max()`]
|
||||||
/// * [`max2`](fn.max2.html)
|
/// * [`max2()`]
|
||||||
/// * [`max3`](fn.max3.html)
|
/// * [`max3()`]
|
||||||
/// * [`max4`](fn.max4.html)
|
/// * [`max4()`]
|
||||||
/// * [`min`](fn.min.html)
|
/// * [`min()`]
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2()`]
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3()`]
|
||||||
pub fn min4<T: Number, const D: usize>(
|
pub fn min4<T: Number, const D: usize>(
|
||||||
a: &TVec<T, D>,
|
a: &TVec<T, D>,
|
||||||
b: &TVec<T, D>,
|
b: &TVec<T, D>,
|
||||||
|
|
|
@ -5,9 +5,9 @@ use crate::traits::Number;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
|
/// * [`equal_eps_vec()`]
|
||||||
/// * [`not_equal_eps`](fn.not_equal_eps.html)
|
/// * [`not_equal_eps()`]
|
||||||
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
|
/// * [`not_equal_eps_vec()`]
|
||||||
pub fn equal_eps<T: Number, const D: usize>(
|
pub fn equal_eps<T: Number, const D: usize>(
|
||||||
x: &TVec<T, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<T, D>,
|
y: &TVec<T, D>,
|
||||||
|
@ -20,9 +20,9 @@ pub fn equal_eps<T: Number, const D: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`equal_eps`](fn.equal_eps.html)
|
/// * [`equal_eps()`]
|
||||||
/// * [`not_equal_eps`](fn.not_equal_eps.html)
|
/// * [`not_equal_eps()`]
|
||||||
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
|
/// * [`not_equal_eps_vec()`]
|
||||||
pub fn equal_eps_vec<T: Number, const D: usize>(
|
pub fn equal_eps_vec<T: Number, const D: usize>(
|
||||||
x: &TVec<T, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<T, D>,
|
y: &TVec<T, D>,
|
||||||
|
@ -35,9 +35,9 @@ pub fn equal_eps_vec<T: Number, const D: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`equal_eps`](fn.equal_eps.html)
|
/// * [`equal_eps()`]
|
||||||
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
|
/// * [`equal_eps_vec()`]
|
||||||
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
|
/// * [`not_equal_eps_vec()`]
|
||||||
pub fn not_equal_eps<T: Number, const D: usize>(
|
pub fn not_equal_eps<T: Number, const D: usize>(
|
||||||
x: &TVec<T, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<T, D>,
|
y: &TVec<T, D>,
|
||||||
|
@ -50,9 +50,9 @@ pub fn not_equal_eps<T: Number, const D: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`equal_eps`](fn.equal_eps.html)
|
/// * [`equal_eps()`]
|
||||||
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
|
/// * [`equal_eps_vec()`]
|
||||||
/// * [`not_equal_eps`](fn.not_equal_eps.html)
|
/// * [`not_equal_eps()`]
|
||||||
pub fn not_equal_eps_vec<T: Number, const D: usize>(
|
pub fn not_equal_eps_vec<T: Number, const D: usize>(
|
||||||
x: &TVec<T, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<T, D>,
|
y: &TVec<T, D>,
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub fn cross<T: Number>(x: &TVec3<T>, y: &TVec3<T>) -> TVec3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`distance2`](fn.distance2.html)
|
/// * [`distance2()`](crate::distance2)
|
||||||
pub fn distance<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
|
pub fn distance<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
|
||||||
(p1 - p0).norm()
|
(p1 - p0).norm()
|
||||||
}
|
}
|
||||||
|
@ -37,13 +37,13 @@ pub fn faceforward<T: Number, const D: usize>(
|
||||||
|
|
||||||
/// The magnitude of a vector.
|
/// The magnitude of a vector.
|
||||||
///
|
///
|
||||||
/// A synonym for [`magnitude`](fn.magnitude.html).
|
/// A synonym for [`magnitude()`].
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2()`](crate::length2)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude()`]
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2()`](crate::magnitude2)
|
||||||
pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
x.norm()
|
x.norm()
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,8 @@ pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`length`](fn.length.html)
|
/// * [`length()`]
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2()`](crate::magnitude2)
|
||||||
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
|
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
|
||||||
pub fn magnitude<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
pub fn magnitude<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
x.norm()
|
x.norm()
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use crate::RealNumber;
|
use crate::RealNumber;
|
||||||
use na;
|
|
||||||
|
|
||||||
/// The Euler constant.
|
/// The Euler constant.
|
||||||
///
|
///
|
||||||
/// This is a shorthand alias for [`euler`](fn.euler.html).
|
/// This is a shorthand alias for [`euler()`].
|
||||||
pub fn e<T: RealNumber>() -> T {
|
pub fn e<T: RealNumber>() -> T {
|
||||||
T::e()
|
T::e()
|
||||||
}
|
}
|
||||||
|
@ -17,18 +16,18 @@ pub fn euler<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`]
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`]
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`]
|
||||||
/// * [`pi`](fn.pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`quarter_pi()`]
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`root_half_pi()`]
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_pi()`]
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_two_pi()`]
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi()`]
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`]
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi()`]
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi()`]
|
||||||
pub fn four_over_pi<T: RealNumber>() -> T {
|
pub fn four_over_pi<T: RealNumber>() -> T {
|
||||||
na::convert::<_, T>(4.0) / T::pi()
|
na::convert::<_, T>(4.0) / T::pi()
|
||||||
}
|
}
|
||||||
|
@ -42,18 +41,18 @@ pub fn golden_ratio<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`]
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`]
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`]
|
||||||
/// * [`pi`](fn.pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`quarter_pi()`]
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`root_half_pi()`]
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_pi()`]
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_two_pi()`]
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi()`]
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`]
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi()`]
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi()`]
|
||||||
pub fn half_pi<T: RealNumber>() -> T {
|
pub fn half_pi<T: RealNumber>() -> T {
|
||||||
T::frac_pi_2()
|
T::frac_pi_2()
|
||||||
}
|
}
|
||||||
|
@ -62,8 +61,8 @@ pub fn half_pi<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`ln_ten`](fn.ln_ten.html)
|
/// * [`ln_ten()`]
|
||||||
/// * [`ln_two`](fn.ln_two.html)
|
/// * [`ln_two()`]
|
||||||
pub fn ln_ln_two<T: RealNumber>() -> T {
|
pub fn ln_ln_two<T: RealNumber>() -> T {
|
||||||
T::ln_2().ln()
|
T::ln_2().ln()
|
||||||
}
|
}
|
||||||
|
@ -72,8 +71,8 @@ pub fn ln_ln_two<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`ln_ln_two`](fn.ln_ln_two.html)
|
/// * [`ln_ln_two()`]
|
||||||
/// * [`ln_two`](fn.ln_two.html)
|
/// * [`ln_two()`]
|
||||||
pub fn ln_ten<T: RealNumber>() -> T {
|
pub fn ln_ten<T: RealNumber>() -> T {
|
||||||
T::ln_10()
|
T::ln_10()
|
||||||
}
|
}
|
||||||
|
@ -82,8 +81,8 @@ pub fn ln_ten<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`ln_ln_two`](fn.ln_ln_two.html)
|
/// * [`ln_ln_two()`]
|
||||||
/// * [`ln_ten`](fn.ln_ten.html)
|
/// * [`ln_ten()`]
|
||||||
pub fn ln_two<T: RealNumber>() -> T {
|
pub fn ln_two<T: RealNumber>() -> T {
|
||||||
T::ln_2()
|
T::ln_2()
|
||||||
}
|
}
|
||||||
|
@ -95,18 +94,18 @@ pub use na::one;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`]
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`]
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`]
|
||||||
/// * [`pi`](fn.pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`quarter_pi()`]
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`root_half_pi()`]
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_pi()`]
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_two_pi()`]
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi()`]
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`]
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi()`]
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi()`]
|
||||||
pub fn one_over_pi<T: RealNumber>() -> T {
|
pub fn one_over_pi<T: RealNumber>() -> T {
|
||||||
T::frac_1_pi()
|
T::frac_1_pi()
|
||||||
}
|
}
|
||||||
|
@ -120,18 +119,18 @@ pub fn one_over_root_two<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`]
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`]
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`]
|
||||||
/// * [`pi`](fn.pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`quarter_pi()`]
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`root_half_pi()`]
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_pi()`]
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_two_pi()`]
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi()`]
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`]
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi()`]
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi()`]
|
||||||
pub fn one_over_two_pi<T: RealNumber>() -> T {
|
pub fn one_over_two_pi<T: RealNumber>() -> T {
|
||||||
T::frac_1_pi() * na::convert(0.5)
|
T::frac_1_pi() * na::convert(0.5)
|
||||||
}
|
}
|
||||||
|
@ -140,18 +139,18 @@ pub fn one_over_two_pi<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`]
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`]
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`]
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`]
|
||||||
/// * [`pi`](fn.pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`root_half_pi()`]
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_pi()`]
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_two_pi()`]
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi()`]
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`]
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi()`]
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi()`]
|
||||||
pub fn quarter_pi<T: RealNumber>() -> T {
|
pub fn quarter_pi<T: RealNumber>() -> T {
|
||||||
T::frac_pi_4()
|
T::frac_pi_4()
|
||||||
}
|
}
|
||||||
|
@ -160,8 +159,8 @@ pub fn quarter_pi<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`root_three`](fn.root_three.html)
|
/// * [`root_three()`]
|
||||||
/// * [`root_two`](fn.root_two.html)
|
/// * [`root_two()`]
|
||||||
pub fn root_five<T: RealNumber>() -> T {
|
pub fn root_five<T: RealNumber>() -> T {
|
||||||
na::convert::<_, T>(5.0).sqrt()
|
na::convert::<_, T>(5.0).sqrt()
|
||||||
}
|
}
|
||||||
|
@ -170,18 +169,18 @@ pub fn root_five<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`]
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`]
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`]
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`]
|
||||||
/// * [`pi`](fn.pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`quarter_pi()`]
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_pi()`]
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_two_pi()`]
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi()`]
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`]
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi()`]
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi()`]
|
||||||
pub fn root_half_pi<T: RealNumber>() -> T {
|
pub fn root_half_pi<T: RealNumber>() -> T {
|
||||||
(T::pi() / na::convert(2.0)).sqrt()
|
(T::pi() / na::convert(2.0)).sqrt()
|
||||||
}
|
}
|
||||||
|
@ -195,18 +194,18 @@ pub fn root_ln_four<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`]
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`]
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`]
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`]
|
||||||
/// * [`pi`](fn.pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`quarter_pi()`]
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`root_half_pi()`]
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_two_pi()`]
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi()`]
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`]
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi()`]
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi()`]
|
||||||
pub fn root_pi<T: RealNumber>() -> T {
|
pub fn root_pi<T: RealNumber>() -> T {
|
||||||
T::pi().sqrt()
|
T::pi().sqrt()
|
||||||
}
|
}
|
||||||
|
@ -215,8 +214,8 @@ pub fn root_pi<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`root_five`](fn.root_five.html)
|
/// * [`root_five()`]
|
||||||
/// * [`root_two`](fn.root_two.html)
|
/// * [`root_two()`]
|
||||||
pub fn root_three<T: RealNumber>() -> T {
|
pub fn root_three<T: RealNumber>() -> T {
|
||||||
na::convert::<_, T>(3.0).sqrt()
|
na::convert::<_, T>(3.0).sqrt()
|
||||||
}
|
}
|
||||||
|
@ -225,8 +224,8 @@ pub fn root_three<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`root_five`](fn.root_five.html)
|
/// * [`root_five()`]
|
||||||
/// * [`root_three`](fn.root_three.html)
|
/// * [`root_three()`]
|
||||||
pub fn root_two<T: RealNumber>() -> T {
|
pub fn root_two<T: RealNumber>() -> T {
|
||||||
// TODO: there should be a crate::sqrt_2() on the RealNumber trait.
|
// TODO: there should be a crate::sqrt_2() on the RealNumber trait.
|
||||||
na::convert::<_, T>(2.0).sqrt()
|
na::convert::<_, T>(2.0).sqrt()
|
||||||
|
@ -236,18 +235,18 @@ pub fn root_two<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`]
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`]
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`]
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`]
|
||||||
/// * [`pi`](fn.pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`quarter_pi()`]
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`root_half_pi()`]
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_pi()`]
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi()`]
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`]
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi()`]
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi()`]
|
||||||
pub fn root_two_pi<T: RealNumber>() -> T {
|
pub fn root_two_pi<T: RealNumber>() -> T {
|
||||||
T::two_pi().sqrt()
|
T::two_pi().sqrt()
|
||||||
}
|
}
|
||||||
|
@ -256,7 +255,7 @@ pub fn root_two_pi<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`two_thirds`](fn.two_thirds.html)
|
/// * [`two_thirds()`]
|
||||||
pub fn third<T: RealNumber>() -> T {
|
pub fn third<T: RealNumber>() -> T {
|
||||||
na::convert(1.0 / 3.0)
|
na::convert(1.0 / 3.0)
|
||||||
}
|
}
|
||||||
|
@ -265,18 +264,18 @@ pub fn third<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`]
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`]
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`]
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`]
|
||||||
/// * [`pi`](fn.pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`quarter_pi()`]
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`root_half_pi()`]
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_pi()`]
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_two_pi()`]
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`]
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi()`]
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi()`]
|
||||||
pub fn three_over_two_pi<T: RealNumber>() -> T {
|
pub fn three_over_two_pi<T: RealNumber>() -> T {
|
||||||
na::convert::<_, T>(3.0) / T::two_pi()
|
na::convert::<_, T>(3.0) / T::two_pi()
|
||||||
}
|
}
|
||||||
|
@ -285,17 +284,18 @@ pub fn three_over_two_pi<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`]
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`]
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`]
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`]
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`quarter_pi()`]
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_half_pi()`]
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_pi()`]
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`root_two_pi()`]
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`three_over_two_pi()`]
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_over_root_pi()`]
|
||||||
|
/// * [`two_pi()`]
|
||||||
pub fn two_over_pi<T: RealNumber>() -> T {
|
pub fn two_over_pi<T: RealNumber>() -> T {
|
||||||
T::frac_2_pi()
|
T::frac_2_pi()
|
||||||
}
|
}
|
||||||
|
@ -304,18 +304,18 @@ pub fn two_over_pi<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`]
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`]
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`]
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`]
|
||||||
/// * [`pi`](fn.pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`quarter_pi()`]
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`root_half_pi()`]
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_pi()`]
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_two_pi()`]
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi()`]
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`]
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi()`]
|
||||||
pub fn two_over_root_pi<T: RealNumber>() -> T {
|
pub fn two_over_root_pi<T: RealNumber>() -> T {
|
||||||
T::frac_2_sqrt_pi()
|
T::frac_2_sqrt_pi()
|
||||||
}
|
}
|
||||||
|
@ -324,18 +324,18 @@ pub fn two_over_root_pi<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`four_over_pi`](fn.four_over_pi.html)
|
/// * [`four_over_pi()`]
|
||||||
/// * [`half_pi`](fn.half_pi.html)
|
/// * [`half_pi()`]
|
||||||
/// * [`one_over_pi`](fn.one_over_pi.html)
|
/// * [`one_over_pi()`]
|
||||||
/// * [`one_over_two_pi`](fn.one_over_two_pi.html)
|
/// * [`one_over_two_pi()`]
|
||||||
/// * [`pi`](fn.pi.html)
|
/// * [`pi()`](crate::pi)
|
||||||
/// * [`quarter_pi`](fn.quarter_pi.html)
|
/// * [`quarter_pi()`]
|
||||||
/// * [`root_half_pi`](fn.root_half_pi.html)
|
/// * [`root_half_pi()`]
|
||||||
/// * [`root_pi`](fn.root_pi.html)
|
/// * [`root_pi()`]
|
||||||
/// * [`root_two_pi`](fn.root_two_pi.html)
|
/// * [`root_two_pi()`]
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi()`]
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi()`]
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi()`]
|
||||||
pub fn two_pi<T: RealNumber>() -> T {
|
pub fn two_pi<T: RealNumber>() -> T {
|
||||||
T::two_pi()
|
T::two_pi()
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ pub fn two_pi<T: RealNumber>() -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`third`](fn.third.html)
|
/// * [`third()`]
|
||||||
pub fn two_thirds<T: RealNumber>() -> T {
|
pub fn two_thirds<T: RealNumber>() -> T {
|
||||||
na::convert(2.0 / 3.0)
|
na::convert(2.0 / 3.0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,24 @@ use na::DefaultAllocator;
|
||||||
use crate::traits::{Alloc, Number, Dimension};
|
use crate::traits::{Alloc, Number, Dimension};
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
|
||||||
/// Component-wise approximate equality beween two vectors.
|
/// Component-wise approximate equality between two vectors.
|
||||||
pub fn epsilon_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
|
pub fn epsilon_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
|
||||||
where DefaultAllocator: Alloc<T, D> {
|
where DefaultAllocator: Alloc<T, D> {
|
||||||
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
|
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate equality beween two scalars.
|
/// Component-wise approximate equality between two scalars.
|
||||||
pub fn epsilon_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
|
pub fn epsilon_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
|
||||||
abs_diff_eq!(x, y, epsilon = epsilon)
|
abs_diff_eq!(x, y, epsilon = epsilon)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate non-equality beween two vectors.
|
/// Component-wise approximate non-equality between two vectors.
|
||||||
pub fn epsilon_not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
|
pub fn epsilon_not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
|
||||||
where DefaultAllocator: Alloc<T, D> {
|
where DefaultAllocator: Alloc<T, D> {
|
||||||
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
|
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate non-equality beween two scalars.
|
/// Component-wise approximate non-equality between two scalars.
|
||||||
pub fn epsilon_not_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
|
pub fn epsilon_not_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
|
||||||
abs_diff_ne!(x, y, epsilon = epsilon)
|
abs_diff_ne!(x, y, epsilon = epsilon)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ use crate::aliases::{TMat, TVec};
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`row`](fn.row.html)
|
/// * [`row()`]
|
||||||
/// * [`set_column`](fn.set_column.html)
|
/// * [`set_column()`]
|
||||||
/// * [`set_row`](fn.set_row.html)
|
/// * [`set_row()`]
|
||||||
pub fn column<T: Scalar, const R: usize, const C: usize>(
|
pub fn column<T: Scalar, const R: usize, const C: usize>(
|
||||||
m: &TMat<T, R, C>,
|
m: &TMat<T, R, C>,
|
||||||
index: usize,
|
index: usize,
|
||||||
|
@ -20,9 +20,9 @@ pub fn column<T: Scalar, const R: usize, const C: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`column`](fn.column.html)
|
/// * [`column()`]
|
||||||
/// * [`row`](fn.row.html)
|
/// * [`row()`]
|
||||||
/// * [`set_row`](fn.set_row.html)
|
/// * [`set_row()`]
|
||||||
pub fn set_column<T: Scalar, const R: usize, const C: usize>(
|
pub fn set_column<T: Scalar, const R: usize, const C: usize>(
|
||||||
m: &TMat<T, R, C>,
|
m: &TMat<T, R, C>,
|
||||||
index: usize,
|
index: usize,
|
||||||
|
@ -37,9 +37,9 @@ pub fn set_column<T: Scalar, const R: usize, const C: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`column`](fn.column.html)
|
/// * [`column()`]
|
||||||
/// * [`set_column`](fn.set_column.html)
|
/// * [`set_column()`]
|
||||||
/// * [`set_row`](fn.set_row.html)
|
/// * [`set_row()`]
|
||||||
pub fn row<T: Scalar, const R: usize, const C: usize>(
|
pub fn row<T: Scalar, const R: usize, const C: usize>(
|
||||||
m: &TMat<T, R, C>,
|
m: &TMat<T, R, C>,
|
||||||
index: usize,
|
index: usize,
|
||||||
|
@ -51,9 +51,9 @@ pub fn row<T: Scalar, const R: usize, const C: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`column`](fn.column.html)
|
/// * [`column()`]
|
||||||
/// * [`row`](fn.row.html)
|
/// * [`row()`]
|
||||||
/// * [`set_column`](fn.set_column.html)
|
/// * [`set_column()`]
|
||||||
pub fn set_row<T: Scalar, const R: usize, const C: usize>(
|
pub fn set_row<T: Scalar, const R: usize, const C: usize>(
|
||||||
m: &TMat<T, R, C>,
|
m: &TMat<T, R, C>,
|
||||||
index: usize,
|
index: usize,
|
||||||
|
|
|
@ -128,9 +128,9 @@ pub fn make_quat<T: RealNumber>(ptr: &[T]) -> Qua<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`make_vec2`](fn.make_vec2.html)
|
/// * [`make_vec2()`]
|
||||||
/// * [`make_vec3`](fn.make_vec3.html)
|
/// * [`make_vec3()`]
|
||||||
/// * [`make_vec4`](fn.make_vec4.html)
|
/// * [`make_vec4()`]
|
||||||
pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
|
pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
|
||||||
v.clone()
|
v.clone()
|
||||||
}
|
}
|
||||||
|
@ -139,12 +139,11 @@ pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
|
/// * [`vec3_to_vec1()`]
|
||||||
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
/// * [`vec4_to_vec1()`]
|
||||||
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
|
/// * [`vec1_to_vec2()`]
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec3()`]
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec4()`]
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
|
||||||
pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
|
pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
|
||||||
TVec1::new(v.x.clone())
|
TVec1::new(v.x.clone())
|
||||||
}
|
}
|
||||||
|
@ -153,12 +152,11 @@ pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
|
/// * [`vec2_to_vec1()`]
|
||||||
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
|
/// * [`vec4_to_vec1()`]
|
||||||
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
|
/// * [`vec1_to_vec2()`]
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec3()`]
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec4()`]
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
|
||||||
pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
|
pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
|
||||||
TVec1::new(v.x.clone())
|
TVec1::new(v.x.clone())
|
||||||
}
|
}
|
||||||
|
@ -167,12 +165,11 @@ pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
|
/// * [`vec2_to_vec1()`]
|
||||||
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
|
/// * [`vec3_to_vec1()`]
|
||||||
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
/// * [`vec1_to_vec2()`]
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec3()`]
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec4()`]
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
|
||||||
pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
|
pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
|
||||||
TVec1::new(v.x.clone())
|
TVec1::new(v.x.clone())
|
||||||
}
|
}
|
||||||
|
@ -183,12 +180,12 @@ pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2()`]
|
||||||
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
|
/// * [`vec4_to_vec2()`]
|
||||||
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
|
/// * [`vec2_to_vec1()`]
|
||||||
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
/// * [`vec2_to_vec2()`]
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3()`]
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4()`]
|
||||||
pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
|
pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
|
||||||
TVec2::new(v.x.clone(), T::zero())
|
TVec2::new(v.x.clone(), T::zero())
|
||||||
}
|
}
|
||||||
|
@ -197,13 +194,13 @@ pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2()`]
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2()`]
|
||||||
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
|
/// * [`vec4_to_vec2()`]
|
||||||
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
|
/// * [`vec2_to_vec1()`]
|
||||||
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
/// * [`vec2_to_vec2()`]
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3()`]
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4()`]
|
||||||
pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
|
pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
|
||||||
v.clone()
|
v.clone()
|
||||||
}
|
}
|
||||||
|
@ -212,12 +209,12 @@ pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2()`]
|
||||||
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
|
/// * [`vec4_to_vec2()`]
|
||||||
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
|
/// * [`vec2_to_vec1()`]
|
||||||
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
/// * [`vec2_to_vec2()`]
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3()`]
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4()`]
|
||||||
pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
|
pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
|
||||||
TVec2::new(v.x.clone(), v.y.clone())
|
TVec2::new(v.x.clone(), v.y.clone())
|
||||||
}
|
}
|
||||||
|
@ -226,12 +223,12 @@ pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2()`]
|
||||||
/// * [`vec3_to_vec2`](fn.vec4_to_vec2.html)
|
/// * [`vec3_to_vec2()`]
|
||||||
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
|
/// * [`vec2_to_vec1()`]
|
||||||
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
/// * [`vec2_to_vec2()`]
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3()`]
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4()`]
|
||||||
pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
|
pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
|
||||||
TVec2::new(v.x.clone(), v.y.clone())
|
TVec2::new(v.x.clone(), v.y.clone())
|
||||||
}
|
}
|
||||||
|
@ -240,9 +237,9 @@ pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`make_vec1`](fn.make_vec1.html)
|
/// * [`make_vec1()`]
|
||||||
/// * [`make_vec3`](fn.make_vec3.html)
|
/// * [`make_vec3()`]
|
||||||
/// * [`make_vec4`](fn.make_vec4.html)
|
/// * [`make_vec4()`]
|
||||||
pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
|
pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
|
||||||
TVec2::from_column_slice(ptr)
|
TVec2::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
@ -253,11 +250,11 @@ pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3()`]
|
||||||
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
|
/// * [`vec3_to_vec3()`]
|
||||||
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
|
/// * [`vec4_to_vec3()`]
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2()`]
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4()`]
|
||||||
pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
|
pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
|
||||||
TVec3::new(v.x.clone(), T::zero(), T::zero())
|
TVec3::new(v.x.clone(), T::zero(), T::zero())
|
||||||
}
|
}
|
||||||
|
@ -268,12 +265,12 @@ pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3()`]
|
||||||
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
|
/// * [`vec3_to_vec3()`]
|
||||||
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
|
/// * [`vec4_to_vec3()`]
|
||||||
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
/// * [`vec3_to_vec1()`]
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2()`]
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4()`]
|
||||||
pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
|
pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
|
||||||
TVec3::new(v.x.clone(), v.y.clone(), T::zero())
|
TVec3::new(v.x.clone(), v.y.clone(), T::zero())
|
||||||
}
|
}
|
||||||
|
@ -282,12 +279,12 @@ pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3()`]
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3()`]
|
||||||
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
|
/// * [`vec4_to_vec3()`]
|
||||||
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
/// * [`vec3_to_vec1()`]
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2()`]
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4()`]
|
||||||
pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
|
pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
|
||||||
v.clone()
|
v.clone()
|
||||||
}
|
}
|
||||||
|
@ -296,12 +293,12 @@ pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3()`]
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3()`]
|
||||||
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
|
/// * [`vec3_to_vec3()`]
|
||||||
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
/// * [`vec3_to_vec1()`]
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2()`]
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4()`]
|
||||||
pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
|
pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
|
||||||
TVec3::new(v.x.clone(), v.y.clone(), v.z.clone())
|
TVec3::new(v.x.clone(), v.y.clone(), v.z.clone())
|
||||||
}
|
}
|
||||||
|
@ -310,9 +307,9 @@ pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`make_vec1`](fn.make_vec1.html)
|
/// * [`make_vec1()`]
|
||||||
/// * [`make_vec2`](fn.make_vec2.html)
|
/// * [`make_vec2()`]
|
||||||
/// * [`make_vec4`](fn.make_vec4.html)
|
/// * [`make_vec4()`]
|
||||||
pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
|
pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
|
||||||
TVec3::from_column_slice(ptr)
|
TVec3::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
@ -323,12 +320,12 @@ pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4()`]
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4()`]
|
||||||
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
|
/// * [`vec4_to_vec4()`]
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2()`]
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3()`]
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4()`]
|
||||||
pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> {
|
pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> {
|
||||||
TVec4::new(v.x, T::zero(), T::zero(), T::zero())
|
TVec4::new(v.x, T::zero(), T::zero(), T::zero())
|
||||||
}
|
}
|
||||||
|
@ -339,12 +336,12 @@ pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4()`]
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4()`]
|
||||||
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
|
/// * [`vec4_to_vec4()`]
|
||||||
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
|
/// * [`vec2_to_vec1()`]
|
||||||
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
/// * [`vec2_to_vec2()`]
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3()`]
|
||||||
pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> {
|
pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> {
|
||||||
TVec4::new(v.x, v.y, T::zero(), T::zero())
|
TVec4::new(v.x, v.y, T::zero(), T::zero())
|
||||||
}
|
}
|
||||||
|
@ -355,12 +352,12 @@ pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4()`]
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4()`]
|
||||||
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
|
/// * [`vec4_to_vec4()`]
|
||||||
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
/// * [`vec3_to_vec1()`]
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2()`]
|
||||||
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
|
/// * [`vec3_to_vec3()`]
|
||||||
pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> {
|
pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> {
|
||||||
TVec4::new(v.x, v.y, v.z, T::zero())
|
TVec4::new(v.x, v.y, v.z, T::zero())
|
||||||
}
|
}
|
||||||
|
@ -369,12 +366,12 @@ pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4()`]
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4()`]
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4()`]
|
||||||
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
|
/// * [`vec4_to_vec1()`]
|
||||||
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
|
/// * [`vec4_to_vec2()`]
|
||||||
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
|
/// * [`vec4_to_vec3()`]
|
||||||
pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
|
pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
|
||||||
v.clone()
|
v.clone()
|
||||||
}
|
}
|
||||||
|
@ -383,9 +380,9 @@ pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`make_vec1`](fn.make_vec1.html)
|
/// * [`make_vec1()`]
|
||||||
/// * [`make_vec2`](fn.make_vec2.html)
|
/// * [`make_vec2()`]
|
||||||
/// * [`make_vec3`](fn.make_vec3.html)
|
/// * [`make_vec3()`]
|
||||||
pub fn make_vec4<T: Scalar>(ptr: &[T]) -> TVec4<T> {
|
pub fn make_vec4<T: Scalar>(ptr: &[T]) -> TVec4<T> {
|
||||||
TVec4::from_column_slice(ptr)
|
TVec4::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,9 @@ use crate::traits::Number;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`]
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min()`]
|
||||||
/// * [`comp_mul`](fn.comp_mul.html)
|
/// * [`comp_mul()`]
|
||||||
pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
||||||
m.iter().fold(T::zero(), |x, y| x + *y)
|
m.iter().fold(T::zero(), |x, y| x + *y)
|
||||||
}
|
}
|
||||||
|
@ -38,13 +38,13 @@ pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) ->
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_add`](fn.comp_add.html)
|
/// * [`comp_add()`]
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`]
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min()`]
|
||||||
/// * [`max`](fn.max.html)
|
/// * [`max()`](crate::max)
|
||||||
/// * [`max2`](fn.max2.html)
|
/// * [`max2()`](crate::max2)
|
||||||
/// * [`max3`](fn.max3.html)
|
/// * [`max3()`](crate::max3)
|
||||||
/// * [`max4`](fn.max4.html)
|
/// * [`max4()`](crate::max4)
|
||||||
pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
||||||
m.iter()
|
m.iter()
|
||||||
.fold(T::min_value(), |x, y| crate::max2_scalar(x, *y))
|
.fold(T::min_value(), |x, y| crate::max2_scalar(x, *y))
|
||||||
|
@ -65,13 +65,13 @@ pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) ->
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_add`](fn.comp_add.html)
|
/// * [`comp_add()`]
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`]
|
||||||
/// * [`comp_mul`](fn.comp_mul.html)
|
/// * [`comp_mul()`]
|
||||||
/// * [`min`](fn.min.html)
|
/// * [`min()`](crate::min)
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2()`](crate::min2)
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3()`](crate::min3)
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4()`](crate::min4)
|
||||||
pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
||||||
m.iter()
|
m.iter()
|
||||||
.fold(T::max_value(), |x, y| crate::min2_scalar(x, *y))
|
.fold(T::max_value(), |x, y| crate::min2_scalar(x, *y))
|
||||||
|
@ -92,9 +92,9 @@ pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) ->
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`comp_add`](fn.comp_add.html)
|
/// * [`comp_add()`]
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max()`]
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min()`]
|
||||||
pub fn comp_mul<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
pub fn comp_mul<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
||||||
m.iter().fold(T::one(), |x, y| x * *y)
|
m.iter().fold(T::one(), |x, y| x * *y)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::traits::Number;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`right_handed`](fn.right_handed.html)
|
/// * [`right_handed()`]
|
||||||
pub fn left_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
|
pub fn left_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
|
||||||
a.cross(b).dot(c) < T::zero()
|
a.cross(b).dot(c) < T::zero()
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ pub fn left_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`left_handed`](fn.left_handed.html)
|
/// * [`left_handed()`]
|
||||||
pub fn right_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
|
pub fn right_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
|
||||||
a.cross(b).dot(c) > T::zero()
|
a.cross(b).dot(c) > T::zero()
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::RealNumber;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`matrix_cross`](fn.matrix_cross.html)
|
/// * [`matrix_cross()`]
|
||||||
pub fn matrix_cross3<T: RealNumber>(x: &TVec3<T>) -> TMat3<T> {
|
pub fn matrix_cross3<T: RealNumber>(x: &TVec3<T>) -> TMat3<T> {
|
||||||
x.cross_matrix()
|
x.cross_matrix()
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ pub fn matrix_cross3<T: RealNumber>(x: &TVec3<T>) -> TMat3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`matrix_cross3`](fn.matrix_cross3.html)
|
/// * [`matrix_cross3()`]
|
||||||
pub fn matrix_cross<T: RealNumber>(x: &TVec3<T>) -> TMat4<T> {
|
pub fn matrix_cross<T: RealNumber>(x: &TVec3<T>) -> TMat4<T> {
|
||||||
crate::mat3_to_mat4(&x.cross_matrix())
|
crate::mat3_to_mat4(&x.cross_matrix())
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,14 @@ use crate::traits::Number;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`diagonal2x3`](fn.diagonal2x3.html)
|
/// * [`diagonal2x3()`]
|
||||||
/// * [`diagonal2x4`](fn.diagonal2x4.html)
|
/// * [`diagonal2x4()`]
|
||||||
/// * [`diagonal3x2`](fn.diagonal3x2.html)
|
/// * [`diagonal3x2()`]
|
||||||
/// * [`diagonal3x3`](fn.diagonal3x3.html)
|
/// * [`diagonal3x3()`]
|
||||||
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
/// * [`diagonal3x4()`]
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2()`]
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3()`]
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4()`]
|
||||||
pub fn diagonal2x2<T: Number>(v: &TVec2<T>) -> TMat2<T> {
|
pub fn diagonal2x2<T: Number>(v: &TVec2<T>) -> TMat2<T> {
|
||||||
TMat2::from_diagonal(v)
|
TMat2::from_diagonal(v)
|
||||||
}
|
}
|
||||||
|
@ -23,14 +23,14 @@ pub fn diagonal2x2<T: Number>(v: &TVec2<T>) -> TMat2<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`diagonal2x2`](fn.diagonal2x2.html)
|
/// * [`diagonal2x2()`]
|
||||||
/// * [`diagonal2x4`](fn.diagonal2x4.html)
|
/// * [`diagonal2x4()`]
|
||||||
/// * [`diagonal3x2`](fn.diagonal3x2.html)
|
/// * [`diagonal3x2()`]
|
||||||
/// * [`diagonal3x3`](fn.diagonal3x3.html)
|
/// * [`diagonal3x3()`]
|
||||||
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
/// * [`diagonal3x4()`]
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2()`]
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3()`]
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4()`]
|
||||||
pub fn diagonal2x3<T: Number>(v: &TVec2<T>) -> TMat2x3<T> {
|
pub fn diagonal2x3<T: Number>(v: &TVec2<T>) -> TMat2x3<T> {
|
||||||
TMat2x3::from_partial_diagonal(v.as_slice())
|
TMat2x3::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
@ -39,14 +39,14 @@ pub fn diagonal2x3<T: Number>(v: &TVec2<T>) -> TMat2x3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`diagonal2x2`](fn.diagonal2x2.html)
|
/// * [`diagonal2x2()`]
|
||||||
/// * [`diagonal2x3`](fn.diagonal2x3.html)
|
/// * [`diagonal2x3()`]
|
||||||
/// * [`diagonal3x2`](fn.diagonal3x2.html)
|
/// * [`diagonal3x2()`]
|
||||||
/// * [`diagonal3x3`](fn.diagonal3x3.html)
|
/// * [`diagonal3x3()`]
|
||||||
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
/// * [`diagonal3x4()`]
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2()`]
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3()`]
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4()`]
|
||||||
pub fn diagonal2x4<T: Number>(v: &TVec2<T>) -> TMat2x4<T> {
|
pub fn diagonal2x4<T: Number>(v: &TVec2<T>) -> TMat2x4<T> {
|
||||||
TMat2x4::from_partial_diagonal(v.as_slice())
|
TMat2x4::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
@ -55,14 +55,14 @@ pub fn diagonal2x4<T: Number>(v: &TVec2<T>) -> TMat2x4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`diagonal2x2`](fn.diagonal2x2.html)
|
/// * [`diagonal2x2()`]
|
||||||
/// * [`diagonal2x3`](fn.diagonal2x3.html)
|
/// * [`diagonal2x3()`]
|
||||||
/// * [`diagonal2x4`](fn.diagonal2x4.html)
|
/// * [`diagonal2x4()`]
|
||||||
/// * [`diagonal3x3`](fn.diagonal3x3.html)
|
/// * [`diagonal3x3()`]
|
||||||
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
/// * [`diagonal3x4()`]
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2()`]
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3()`]
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4()`]
|
||||||
pub fn diagonal3x2<T: Number>(v: &TVec2<T>) -> TMat3x2<T> {
|
pub fn diagonal3x2<T: Number>(v: &TVec2<T>) -> TMat3x2<T> {
|
||||||
TMat3x2::from_partial_diagonal(v.as_slice())
|
TMat3x2::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
@ -71,14 +71,14 @@ pub fn diagonal3x2<T: Number>(v: &TVec2<T>) -> TMat3x2<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`diagonal2x2`](fn.diagonal2x2.html)
|
/// * [`diagonal2x2()`]
|
||||||
/// * [`diagonal2x3`](fn.diagonal2x3.html)
|
/// * [`diagonal2x3()`]
|
||||||
/// * [`diagonal2x4`](fn.diagonal2x4.html)
|
/// * [`diagonal2x4()`]
|
||||||
/// * [`diagonal3x2`](fn.diagonal3x2.html)
|
/// * [`diagonal3x2()`]
|
||||||
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
/// * [`diagonal3x4()`]
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2()`]
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3()`]
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4()`]
|
||||||
pub fn diagonal3x3<T: Number>(v: &TVec3<T>) -> TMat3<T> {
|
pub fn diagonal3x3<T: Number>(v: &TVec3<T>) -> TMat3<T> {
|
||||||
TMat3::from_diagonal(v)
|
TMat3::from_diagonal(v)
|
||||||
}
|
}
|
||||||
|
@ -87,14 +87,14 @@ pub fn diagonal3x3<T: Number>(v: &TVec3<T>) -> TMat3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`diagonal2x2`](fn.diagonal2x2.html)
|
/// * [`diagonal2x2()`]
|
||||||
/// * [`diagonal2x3`](fn.diagonal2x3.html)
|
/// * [`diagonal2x3()`]
|
||||||
/// * [`diagonal2x4`](fn.diagonal2x4.html)
|
/// * [`diagonal2x4()`]
|
||||||
/// * [`diagonal3x2`](fn.diagonal3x2.html)
|
/// * [`diagonal3x2()`]
|
||||||
/// * [`diagonal3x3`](fn.diagonal3x3.html)
|
/// * [`diagonal3x3()`]
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2()`]
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3()`]
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4()`]
|
||||||
pub fn diagonal3x4<T: Number>(v: &TVec3<T>) -> TMat3x4<T> {
|
pub fn diagonal3x4<T: Number>(v: &TVec3<T>) -> TMat3x4<T> {
|
||||||
TMat3x4::from_partial_diagonal(v.as_slice())
|
TMat3x4::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
@ -103,14 +103,14 @@ pub fn diagonal3x4<T: Number>(v: &TVec3<T>) -> TMat3x4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`diagonal2x2`](fn.diagonal2x2.html)
|
/// * [`diagonal2x2()`]
|
||||||
/// * [`diagonal2x3`](fn.diagonal2x3.html)
|
/// * [`diagonal2x3()`]
|
||||||
/// * [`diagonal2x4`](fn.diagonal2x4.html)
|
/// * [`diagonal2x4()`]
|
||||||
/// * [`diagonal3x2`](fn.diagonal3x2.html)
|
/// * [`diagonal3x2()`]
|
||||||
/// * [`diagonal3x3`](fn.diagonal3x3.html)
|
/// * [`diagonal3x3()`]
|
||||||
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
/// * [`diagonal3x4()`]
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3()`]
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4()`]
|
||||||
pub fn diagonal4x2<T: Number>(v: &TVec2<T>) -> TMat4x2<T> {
|
pub fn diagonal4x2<T: Number>(v: &TVec2<T>) -> TMat4x2<T> {
|
||||||
TMat4x2::from_partial_diagonal(v.as_slice())
|
TMat4x2::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
@ -119,14 +119,14 @@ pub fn diagonal4x2<T: Number>(v: &TVec2<T>) -> TMat4x2<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`diagonal2x2`](fn.diagonal2x2.html)
|
/// * [`diagonal2x2()`]
|
||||||
/// * [`diagonal2x3`](fn.diagonal2x3.html)
|
/// * [`diagonal2x3()`]
|
||||||
/// * [`diagonal2x4`](fn.diagonal2x4.html)
|
/// * [`diagonal2x4()`]
|
||||||
/// * [`diagonal3x2`](fn.diagonal3x2.html)
|
/// * [`diagonal3x2()`]
|
||||||
/// * [`diagonal3x3`](fn.diagonal3x3.html)
|
/// * [`diagonal3x3()`]
|
||||||
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
/// * [`diagonal3x4()`]
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2()`]
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4()`]
|
||||||
pub fn diagonal4x3<T: Number>(v: &TVec3<T>) -> TMat4x3<T> {
|
pub fn diagonal4x3<T: Number>(v: &TVec3<T>) -> TMat4x3<T> {
|
||||||
TMat4x3::from_partial_diagonal(v.as_slice())
|
TMat4x3::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
@ -135,14 +135,14 @@ pub fn diagonal4x3<T: Number>(v: &TVec3<T>) -> TMat4x3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`diagonal2x2`](fn.diagonal2x2.html)
|
/// * [`diagonal2x2()`]
|
||||||
/// * [`diagonal2x3`](fn.diagonal2x3.html)
|
/// * [`diagonal2x3()`]
|
||||||
/// * [`diagonal2x4`](fn.diagonal2x4.html)
|
/// * [`diagonal2x4()`]
|
||||||
/// * [`diagonal3x2`](fn.diagonal3x2.html)
|
/// * [`diagonal3x2()`]
|
||||||
/// * [`diagonal3x3`](fn.diagonal3x3.html)
|
/// * [`diagonal3x3()`]
|
||||||
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
/// * [`diagonal3x4()`]
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2()`]
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3()`]
|
||||||
pub fn diagonal4x4<T: Number>(v: &TVec4<T>) -> TMat4<T> {
|
pub fn diagonal4x4<T: Number>(v: &TVec4<T>) -> TMat4<T> {
|
||||||
TMat4::from_diagonal(v)
|
TMat4::from_diagonal(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::RealNumber;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`distance`](fn.distance.html)
|
/// * [`distance()`](crate::distance)
|
||||||
pub fn distance2<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
|
pub fn distance2<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
|
||||||
(p1 - p0).norm_squared()
|
(p1 - p0).norm_squared()
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,9 @@ pub fn distance2<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`l1_norm`](fn.l1_norm.html)
|
/// * [`l1_norm()`]
|
||||||
/// * [`l2_distance`](fn.l2_distance.html)
|
/// * [`l2_distance()`]
|
||||||
/// * [`l2_norm`](fn.l2_norm.html)
|
/// * [`l2_norm()`]
|
||||||
pub fn l1_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
pub fn l1_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
l1_norm(&(y - x))
|
l1_norm(&(y - x))
|
||||||
}
|
}
|
||||||
|
@ -28,27 +28,27 @@ pub fn l1_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`l1_distance`](fn.l1_distance.html)
|
/// * [`l1_distance()`]
|
||||||
/// * [`l2_distance`](fn.l2_distance.html)
|
/// * [`l2_distance()`]
|
||||||
/// * [`l2_norm`](fn.l2_norm.html)
|
/// * [`l2_norm()`]
|
||||||
pub fn l1_norm<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> T {
|
pub fn l1_norm<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> T {
|
||||||
crate::comp_add(&v.abs())
|
crate::comp_add(&v.abs())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The l2-norm of `x - y`.
|
/// The l2-norm of `x - y`.
|
||||||
///
|
///
|
||||||
/// This is the same value as returned by [`length2`](fn.length2.html) and
|
/// This is the same value as returned by [`length2()`] and
|
||||||
/// [`magnitude2`](fn.magnitude2.html).
|
/// [`magnitude2()`].
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`l1_distance`](fn.l1_distance.html)
|
/// * [`l1_distance()`]
|
||||||
/// * [`l1_norm`](fn.l1_norm.html)
|
/// * [`l1_norm()`]
|
||||||
/// * [`l2_norm`](fn.l2_norm.html)
|
/// * [`l2_norm()`]
|
||||||
/// * [`length`](fn.length.html)
|
/// * [`length()`](crate::length)
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2()`]
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude()`](crate::magnitude)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2()`]
|
||||||
pub fn l2_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
pub fn l2_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
l2_norm(&(y - x))
|
l2_norm(&(y - x))
|
||||||
}
|
}
|
||||||
|
@ -57,33 +57,33 @@ pub fn l2_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>
|
||||||
///
|
///
|
||||||
/// This is also known as the Euclidean norm.
|
/// This is also known as the Euclidean norm.
|
||||||
///
|
///
|
||||||
/// This is the same value as returned by [`length`](fn.length.html) and
|
/// This is the same value as returned by [`length()`](crate::length) and
|
||||||
/// [`magnitude`](fn.magnitude.html).
|
/// [`magnitude()`](crate::magnitude).
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`l1_distance`](fn.l1_distance.html)
|
/// * [`l1_distance()`]
|
||||||
/// * [`l1_norm`](fn.l1_norm.html)
|
/// * [`l1_norm()`]
|
||||||
/// * [`l2_distance`](fn.l2_distance.html)
|
/// * [`l2_distance()`]
|
||||||
/// * [`length`](fn.length.html)
|
/// * [`length()`](crate::length)
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2()`]
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude()`](crate::magnitude)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2()`]
|
||||||
pub fn l2_norm<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
pub fn l2_norm<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
x.norm()
|
x.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The squared magnitude of `x`.
|
/// The squared magnitude of `x`.
|
||||||
///
|
///
|
||||||
/// A synonym for [`magnitude2`](fn.magnitude2.html).
|
/// A synonym for [`magnitude2()`].
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`distance`](fn.distance.html)
|
/// * [`distance()`](crate::distance)
|
||||||
/// * [`distance2`](fn.distance2.html)
|
/// * [`distance2()`]
|
||||||
/// * [`length`](fn.length.html)
|
/// * [`length()`](crate::length)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude()`](crate::magnitude)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2()`]
|
||||||
pub fn length2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
pub fn length2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
x.norm_squared()
|
x.norm_squared()
|
||||||
}
|
}
|
||||||
|
@ -94,10 +94,10 @@ pub fn length2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`distance`](fn.distance.html)
|
/// * [`distance()`](crate::distance)
|
||||||
/// * [`distance2`](fn.distance2.html)
|
/// * [`distance2()`]
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2()`]
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude()`](crate::magnitude)
|
||||||
/// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html)
|
/// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html)
|
||||||
pub fn magnitude2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
pub fn magnitude2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
x.norm_squared()
|
x.norm_squared()
|
||||||
|
|
|
@ -4,11 +4,11 @@ use crate::aliases::TVec;
|
||||||
|
|
||||||
/// The dot product of the normalized version of `x` and `y`.
|
/// The dot product of the normalized version of `x` and `y`.
|
||||||
///
|
///
|
||||||
/// This is currently the same as [`normalize_dot`](fn.normalize_dot.html).
|
/// This is currently the same as [`normalize_dot()`]
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`normalize_dot`](fn.normalize_dot.html`)
|
/// * [`normalize_dot()`]
|
||||||
pub fn fast_normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
pub fn fast_normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
// XXX: improve those.
|
// XXX: improve those.
|
||||||
x.normalize().dot(&y.normalize())
|
x.normalize().dot(&y.normalize())
|
||||||
|
@ -18,7 +18,7 @@ pub fn fast_normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVe
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`)
|
/// * [`fast_normalize_dot()`]
|
||||||
pub fn normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
pub fn normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
// XXX: improve those.
|
// XXX: improve those.
|
||||||
x.normalize().dot(&y.normalize())
|
x.normalize().dot(&y.normalize())
|
||||||
|
|
|
@ -80,7 +80,7 @@ pub fn quat_to_mat3<T: RealNumber>(x: &Qua<T>) -> TMat3<T> {
|
||||||
.into_inner()
|
.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a quaternion to a rotation matrix in homogenous coordinates.
|
/// Converts a quaternion to a rotation matrix in homogeneous coordinates.
|
||||||
pub fn quat_to_mat4<T: RealNumber>(x: &Qua<T>) -> TMat4<T> {
|
pub fn quat_to_mat4<T: RealNumber>(x: &Qua<T>) -> TMat4<T> {
|
||||||
UnitQuaternion::new_unchecked(*x).to_homogeneous()
|
UnitQuaternion::new_unchecked(*x).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,6 @@ pub fn mat3_to_quat<T: RealNumber>(x: &TMat3<T>) -> Qua<T> {
|
||||||
|
|
||||||
/// Converts a rotation matrix in homogeneous coordinates to a quaternion.
|
/// Converts a rotation matrix in homogeneous coordinates to a quaternion.
|
||||||
pub fn to_quat<T: RealNumber>(x: &TMat4<T>) -> Qua<T> {
|
pub fn to_quat<T: RealNumber>(x: &TMat4<T>) -> Qua<T> {
|
||||||
let rot = x.fixed_slice::<3, 3>(0, 0).into_owned();
|
let rot = x.fixed_view::<3, 3>(0, 0).into_owned();
|
||||||
mat3_to_quat(&rot)
|
mat3_to_quat(&rot)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,11 @@ use crate::traits::{Number, RealNumber};
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`scaling`](fn.scaling.html)
|
/// * [`scaling()`]
|
||||||
/// * [`translation`](fn.translation.html)
|
/// * [`translation()`]
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d()`]
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d()`]
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d()`]
|
||||||
pub fn rotation<T: RealNumber>(angle: T, v: &TVec3<T>) -> TMat4<T> {
|
pub fn rotation<T: RealNumber>(angle: T, v: &TVec3<T>) -> TMat4<T> {
|
||||||
Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous()
|
Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,11 @@ pub fn rotation<T: RealNumber>(angle: T, v: &TVec3<T>) -> TMat4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotation`](fn.rotation.html)
|
/// * [`rotation()`]
|
||||||
/// * [`translation`](fn.translation.html)
|
/// * [`translation()`]
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d()`]
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d()`]
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d()`]
|
||||||
pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> {
|
pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> {
|
||||||
TMat4::new_nonuniform_scaling(v)
|
TMat4::new_nonuniform_scaling(v)
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,11 @@ pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotation`](fn.rotation.html)
|
/// * [`rotation()`]
|
||||||
/// * [`scaling`](fn.scaling.html)
|
/// * [`scaling()`]
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d()`]
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d()`]
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d()`]
|
||||||
pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
|
pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
|
||||||
TMat4::new_translation(v)
|
TMat4::new_translation(v)
|
||||||
}
|
}
|
||||||
|
@ -46,11 +46,11 @@ pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotation`](fn.rotation.html)
|
/// * [`rotation()`]
|
||||||
/// * [`scaling`](fn.scaling.html)
|
/// * [`scaling()`]
|
||||||
/// * [`translation`](fn.translation.html)
|
/// * [`translation()`]
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d()`]
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d()`]
|
||||||
pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> {
|
pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> {
|
||||||
Rotation2::new(angle).to_homogeneous()
|
Rotation2::new(angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
@ -59,11 +59,11 @@ pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotation`](fn.rotation.html)
|
/// * [`rotation()`]
|
||||||
/// * [`scaling`](fn.scaling.html)
|
/// * [`scaling()`]
|
||||||
/// * [`translation`](fn.translation.html)
|
/// * [`translation()`]
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d()`]
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d()`]
|
||||||
pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
|
pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
|
||||||
TMat3::new_nonuniform_scaling(v)
|
TMat3::new_nonuniform_scaling(v)
|
||||||
}
|
}
|
||||||
|
@ -72,11 +72,11 @@ pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotation`](fn.rotation.html)
|
/// * [`rotation()`]
|
||||||
/// * [`scaling`](fn.scaling.html)
|
/// * [`scaling()`]
|
||||||
/// * [`translation`](fn.translation.html)
|
/// * [`translation()`]
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d()`]
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d()`]
|
||||||
pub fn translation2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
|
pub fn translation2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
|
||||||
TMat3::new_translation(v)
|
TMat3::new_translation(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub fn proj2d<T: Number>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
|
||||||
let mut res = TMat3::identity();
|
let mut res = TMat3::identity();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut part = res.fixed_slice_mut::<2, 2>(0, 0);
|
let mut part = res.fixed_view_mut::<2, 2>(0, 0);
|
||||||
part -= normal * normal.transpose();
|
part -= normal * normal.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ pub fn proj<T: Number>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
|
||||||
let mut res = TMat4::identity();
|
let mut res = TMat4::identity();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut part = res.fixed_slice_mut::<3, 3>(0, 0);
|
let mut part = res.fixed_view_mut::<3, 3>(0, 0);
|
||||||
part -= normal * normal.transpose();
|
part -= normal * normal.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ pub fn reflect2d<T: RealNumber>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
|
||||||
let mut res = TMat3::identity();
|
let mut res = TMat3::identity();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut part = res.fixed_slice_mut::<2, 2>(0, 0);
|
let mut part = res.fixed_view_mut::<2, 2>(0, 0);
|
||||||
part -= (normal * T::from_subset(&2.0)) * normal.transpose();
|
part -= (normal * T::from_subset(&2.0)) * normal.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ pub fn reflect<T: RealNumber>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
|
||||||
let mut res = TMat4::identity();
|
let mut res = TMat4::identity();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut part = res.fixed_slice_mut::<3, 3>(0, 0);
|
let mut part = res.fixed_view_mut::<3, 3>(0, 0);
|
||||||
part -= (normal * T::from_subset(&2.0)) * normal.transpose();
|
part -= (normal * T::from_subset(&2.0)) * normal.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,11 @@ use crate::traits::{Number, RealNumber};
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d()`](crate::rotation2d)
|
||||||
/// * [`scale2d`](fn.scale2d.html)
|
/// * [`scale2d()`]
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d()`](crate::scaling2d)
|
||||||
/// * [`translate2d`](fn.translate2d.html)
|
/// * [`translate2d()`]
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d()`](crate::translation2d)
|
||||||
pub fn rotate2d<T: RealNumber>(m: &TMat3<T>, angle: T) -> TMat3<T> {
|
pub fn rotate2d<T: RealNumber>(m: &TMat3<T>, angle: T) -> TMat3<T> {
|
||||||
m * UnitComplex::new(angle).to_homogeneous()
|
m * UnitComplex::new(angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,11 @@ pub fn rotate2d<T: RealNumber>(m: &TMat3<T>, angle: T) -> TMat3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotate2d`](fn.rotate2d.html)
|
/// * [`rotate2d()`]
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d()`](crate::rotation2d)
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d()`](crate::scaling2d)
|
||||||
/// * [`translate2d`](fn.translate2d.html)
|
/// * [`translate2d()`]
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d()`](crate::translation2d)
|
||||||
pub fn scale2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
|
pub fn scale2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
|
||||||
m.prepend_nonuniform_scaling(v)
|
m.prepend_nonuniform_scaling(v)
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,11 @@ pub fn scale2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`rotate2d`](fn.rotate2d.html)
|
/// * [`rotate2d()`]
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d()`](crate::rotation2d)
|
||||||
/// * [`scale2d`](fn.scale2d.html)
|
/// * [`scale2d()`]
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d()`](crate::scaling2d)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d()`](crate::translation2d)
|
||||||
pub fn translate2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
|
pub fn translate2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
|
||||||
m.prepend_translation(v)
|
m.prepend_translation(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::traits::Number;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`are_collinear2d`](fn.are_collinear2d.html)
|
/// * [`are_collinear2d()`]
|
||||||
pub fn are_collinear<T: Number>(v0: &TVec3<T>, v1: &TVec3<T>, epsilon: T) -> bool {
|
pub fn are_collinear<T: Number>(v0: &TVec3<T>, v1: &TVec3<T>, epsilon: T) -> bool {
|
||||||
is_null(&v0.cross(v1), epsilon)
|
is_null(&v0.cross(v1), epsilon)
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ pub fn are_collinear<T: Number>(v0: &TVec3<T>, v1: &TVec3<T>, epsilon: T) -> boo
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`are_collinear`](fn.are_collinear.html)
|
/// * [`are_collinear()`]
|
||||||
pub fn are_collinear2d<T: Number>(v0: &TVec2<T>, v1: &TVec2<T>, epsilon: T) -> bool {
|
pub fn are_collinear2d<T: Number>(v0: &TVec2<T>, v1: &TVec2<T>, epsilon: T) -> bool {
|
||||||
abs_diff_eq!(v0.perp(v1), T::zero(), epsilon = epsilon)
|
abs_diff_eq!(v0.perp(v1), T::zero(), epsilon = epsilon)
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,10 @@ pub fn is_comp_null<T: Number, const D: usize>(v: &TVec<T, D>, epsilon: T) -> TV
|
||||||
|
|
||||||
/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon).
|
/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon).
|
||||||
pub fn is_normalized<T: RealNumber, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
|
pub fn is_normalized<T: RealNumber, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
|
||||||
abs_diff_eq!(v.norm_squared(), T::one(), epsilon = epsilon * epsilon)
|
// 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `v` is zero (up to an epsilon).
|
/// Returns `true` if `v` is zero (up to an epsilon).
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
* All function names use `snake_case`, which is the Rust convention.
|
* All function names use `snake_case`, which is the Rust convention.
|
||||||
* All type names use `CamelCase`, which is the Rust convention.
|
* All type names use `CamelCase`, which is the Rust convention.
|
||||||
* All function arguments, except for scalars, are all passed by-reference.
|
* All function arguments, except for scalars, are all passed by-reference.
|
||||||
* The most generic vector and matrix types are [`TMat`](type.TMat.html) and [`TVec`](type.TVec.html) instead of `mat` and `vec`.
|
* The most generic vector and matrix types are [`TMat`] and [`TVec`] instead of `mat` and `vec`.
|
||||||
* Some feature are not yet implemented and should be added in the future. In particular, no packing
|
* Some feature are not yet implemented and should be added in the future. In particular, no packing
|
||||||
functions are available.
|
functions are available.
|
||||||
* A few features are not implemented and will never be. This includes functions related to color
|
* A few features are not implemented and will never be. This includes functions related to color
|
||||||
|
@ -47,17 +47,17 @@
|
||||||
|
|
||||||
In addition, because Rust does not allows function overloading, all functions must be given a unique name.
|
In addition, because Rust does not allows function overloading, all functions must be given a unique name.
|
||||||
Here are a few rules chosen arbitrarily for **nalgebra-glm**:
|
Here are a few rules chosen arbitrarily for **nalgebra-glm**:
|
||||||
* Functions operating in 2d will usually end with the `2d` suffix, e.g., [`glm::rotate2d`](fn.rotate2d.html) is for 2D while [`glm::rotate`](fn.rotate.html) is for 3D.
|
* 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`](fn.rotate_vec2.html).
|
* 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)`](fn.quat_dot.html).
|
* Every function related to quaternions start with the `quat_` prefix, e.g., [`glm::quat_dot(q1, q2)`](crate::quat_dot).
|
||||||
* All the conversion functions have unique names as described [below](#conversions).
|
* All the conversion functions have unique names as described [below](#conversions).
|
||||||
### Vector and matrix construction
|
### Vector and matrix construction
|
||||||
Vectors, matrices, and quaternions can be constructed using several approaches:
|
Vectors, matrices, and quaternions can be constructed using several approaches:
|
||||||
* Using functions with the same name as their type in lower-case. For example [`glm::vec3(x, y, z)`](fn.vec3.html) will create a 3D vector.
|
* 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 the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.OMatrix.html#method.new-27) will create a 3D vector.
|
* Using the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.OMatrix.html#method.new-27) will create a 3D vector.
|
||||||
* Using the functions prefixed by `make_` to build a vector a matrix from a slice. For example [`glm::make_vec3(&[x, y, z])`](fn.make_vec3.html) 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.
|
||||||
Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice.
|
Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice.
|
||||||
* Using a geometric construction function. For example [`glm::rotation(angle, axis)`](fn.rotation.html) 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)`](crate::rotation) will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis.
|
||||||
* Using swizzling and conversions as described in the next sections.
|
* Using swizzling and conversions as described in the next sections.
|
||||||
### Swizzling
|
### Swizzling
|
||||||
Vector swizzling is a native feature of **nalgebra** itself. Therefore, you can use it with all
|
Vector swizzling is a native feature of **nalgebra** itself. Therefore, you can use it with all
|
||||||
|
@ -75,9 +75,9 @@
|
||||||
It is often useful to convert one algebraic type to another. There are two main approaches for converting
|
It is often useful to convert one algebraic type to another. There are two main approaches for converting
|
||||||
between types in `nalgebra-glm`:
|
between types in `nalgebra-glm`:
|
||||||
* Using function with the form `type1_to_type2` in order to convert an instance of `type1` into an instance of `type2`.
|
* Using function with the form `type1_to_type2` in order to convert an instance of `type1` into an instance of `type2`.
|
||||||
For example [`glm::mat3_to_mat4(m)`](fn.mat3_to_mat4.html) will convert the 3x3 matrix `m` to a 4x4 matrix by appending one column on the right
|
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
|
||||||
and one row on the left. Those now row and columns are filled with 0 except for the diagonal element which is set to 1.
|
and one row on the left. Those now row and columns are filled with 0 except for the diagonal element which is set to 1.
|
||||||
* Using one of the [`convert`](fn.convert.html), [`try_convert`](fn.try_convert.html), or [`convert_unchecked`](fn.convert_unchecked.html) functions.
|
* Using one of the [`convert`](crate::convert), [`try_convert`](crate::try_convert), or [`convert_unchecked`](crate::convert_unchecked) functions.
|
||||||
These functions are directly re-exported from nalgebra and are extremely versatile:
|
These functions are directly re-exported from nalgebra and are extremely versatile:
|
||||||
1. The `convert` function can convert any type (especially geometric types from nalgebra like `Isometry3`) into another algebraic type which is equivalent but more general. For example,
|
1. The `convert` function can convert any type (especially geometric types from nalgebra like `Isometry3`) into another algebraic type which is equivalent but more general. For example,
|
||||||
`let sim: Similarity3<_> = na::convert(isometry)` will convert an `Isometry3` into a `Similarity3`.
|
`let sim: Similarity3<_> = na::convert(isometry)` will convert an `Isometry3` into a `Similarity3`.
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use approx::AbsDiffEq;
|
use approx::AbsDiffEq;
|
||||||
use num::{Bounded, Signed};
|
use num::{Bounded, Signed};
|
||||||
|
|
||||||
use core::cmp::PartialOrd;
|
|
||||||
use na::Scalar;
|
use na::Scalar;
|
||||||
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, RealField};
|
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, RealField};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use na;
|
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use crate::RealNumber;
|
use crate::RealNumber;
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,8 @@ use crate::traits::Number;
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`any`](fn.any.html)
|
/// * [`any()`]
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not()`]
|
||||||
pub fn all<const D: usize>(v: &TVec<bool, D>) -> bool {
|
pub fn all<const D: usize>(v: &TVec<bool, D>) -> bool {
|
||||||
v.iter().all(|x| *x)
|
v.iter().all(|x| *x)
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,8 @@ pub fn all<const D: usize>(v: &TVec<bool, D>) -> bool {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`all`](fn.all.html)
|
/// * [`all()`]
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not()`]
|
||||||
pub fn any<const D: usize>(v: &TVec<bool, D>) -> bool {
|
pub fn any<const D: usize>(v: &TVec<bool, D>) -> bool {
|
||||||
v.iter().any(|x| *x)
|
v.iter().any(|x| *x)
|
||||||
}
|
}
|
||||||
|
@ -59,12 +59,12 @@ pub fn any<const D: usize>(v: &TVec<bool, D>) -> bool {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`greater_than`](fn.greater_than.html)
|
/// * [`greater_than()`]
|
||||||
/// * [`greater_than_equal`](fn.greater_than_equal.html)
|
/// * [`greater_than_equal()`]
|
||||||
/// * [`less_than`](fn.less_than.html)
|
/// * [`less_than()`]
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal()`]
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not()`]
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal()`]
|
||||||
pub fn equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
pub fn equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
x.zip_map(y, |x, y| x == y)
|
x.zip_map(y, |x, y| x == y)
|
||||||
}
|
}
|
||||||
|
@ -82,12 +82,12 @@ pub fn equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`equal`](fn.equal.html)
|
/// * [`equal()`]
|
||||||
/// * [`greater_than_equal`](fn.greater_than_equal.html)
|
/// * [`greater_than_equal()`]
|
||||||
/// * [`less_than`](fn.less_than.html)
|
/// * [`less_than()`]
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal()`]
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not()`]
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal()`]
|
||||||
pub fn greater_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
pub fn greater_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
x.zip_map(y, |x, y| x > y)
|
x.zip_map(y, |x, y| x > y)
|
||||||
}
|
}
|
||||||
|
@ -105,12 +105,12 @@ pub fn greater_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`equal`](fn.equal.html)
|
/// * [`equal()`]
|
||||||
/// * [`greater_than`](fn.greater_than.html)
|
/// * [`greater_than()`]
|
||||||
/// * [`less_than`](fn.less_than.html)
|
/// * [`less_than()`]
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal()`]
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not()`]
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal()`]
|
||||||
pub fn greater_than_equal<T: Number, const D: usize>(
|
pub fn greater_than_equal<T: Number, const D: usize>(
|
||||||
x: &TVec<T, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<T, D>,
|
y: &TVec<T, D>,
|
||||||
|
@ -131,17 +131,17 @@ pub fn greater_than_equal<T: Number, const D: usize>(
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`equal`](fn.equal.html)
|
/// * [`equal()`]
|
||||||
/// * [`greater_than`](fn.greater_than.html)
|
/// * [`greater_than()`]
|
||||||
/// * [`greater_than_equal`](fn.greater_than_equal.html)
|
/// * [`greater_than_equal()`]
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal()`]
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not()`]
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal()`]
|
||||||
pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
x.zip_map(y, |x, y| x < y)
|
x.zip_map(y, |x, y| x < y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise `>=` comparison.
|
/// Component-wise `<=` comparison.
|
||||||
///
|
///
|
||||||
/// # Examples:
|
/// # Examples:
|
||||||
///
|
///
|
||||||
|
@ -154,12 +154,12 @@ pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`equal`](fn.equal.html)
|
/// * [`equal()`]
|
||||||
/// * [`greater_than`](fn.greater_than.html)
|
/// * [`greater_than()`]
|
||||||
/// * [`greater_than_equal`](fn.greater_than_equal.html)
|
/// * [`greater_than_equal()`]
|
||||||
/// * [`less_than`](fn.less_than.html)
|
/// * [`less_than()`]
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not()`]
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal()`]
|
||||||
pub fn less_than_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
pub fn less_than_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
x.zip_map(y, |x, y| x <= y)
|
x.zip_map(y, |x, y| x <= y)
|
||||||
}
|
}
|
||||||
|
@ -176,14 +176,14 @@ pub fn less_than_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`all`](fn.all.html)
|
/// * [`all()`]
|
||||||
/// * [`any`](fn.any.html)
|
/// * [`any()`]
|
||||||
/// * [`equal`](fn.equal.html)
|
/// * [`equal()`]
|
||||||
/// * [`greater_than`](fn.greater_than.html)
|
/// * [`greater_than()`]
|
||||||
/// * [`greater_than_equal`](fn.greater_than_equal.html)
|
/// * [`greater_than_equal()`]
|
||||||
/// * [`less_than`](fn.less_than.html)
|
/// * [`less_than()`]
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal()`]
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal()`]
|
||||||
pub fn not<const D: usize>(v: &TVec<bool, D>) -> TVec<bool, D> {
|
pub fn not<const D: usize>(v: &TVec<bool, D>) -> TVec<bool, D> {
|
||||||
v.map(|x| !x)
|
v.map(|x| !x)
|
||||||
}
|
}
|
||||||
|
@ -201,12 +201,12 @@ pub fn not<const D: usize>(v: &TVec<bool, D>) -> TVec<bool, D> {
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`equal`](fn.equal.html)
|
/// * [`equal()`]
|
||||||
/// * [`greater_than`](fn.greater_than.html)
|
/// * [`greater_than()`]
|
||||||
/// * [`greater_than_equal`](fn.greater_than_equal.html)
|
/// * [`greater_than_equal()`]
|
||||||
/// * [`less_than`](fn.less_than.html)
|
/// * [`less_than()`]
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal()`]
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not()`]
|
||||||
pub fn not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
pub fn not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
x.zip_map(y, |x, y| x != y)
|
x.zip_map(y, |x, y| x != y)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra-lapack"
|
name = "nalgebra-lapack"
|
||||||
version = "0.21.0"
|
version = "0.24.0"
|
||||||
authors = [ "Sébastien Crozet <developer@crozet.re>", "Andrew Straw <strawman@astraw.com>" ]
|
authors = [ "Sébastien Crozet <developer@crozet.re>", "Andrew Straw <strawman@astraw.com>" ]
|
||||||
|
|
||||||
description = "Matrix decompositions using nalgebra matrices and Lapack bindings."
|
description = "Matrix decompositions using nalgebra matrices and Lapack bindings."
|
||||||
|
@ -10,7 +10,7 @@ repository = "https://github.com/dimforge/nalgebra"
|
||||||
readme = "../README.md"
|
readme = "../README.md"
|
||||||
categories = [ "science", "mathematics" ]
|
categories = [ "science", "mathematics" ]
|
||||||
keywords = [ "linear", "algebra", "matrix", "vector", "lapack" ]
|
keywords = [ "linear", "algebra", "matrix", "vector", "lapack" ]
|
||||||
license = "BSD-3-Clause"
|
license = "MIT"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
|
@ -29,18 +29,19 @@ accelerate = ["lapack-src/accelerate"]
|
||||||
intel-mkl = ["lapack-src/intel-mkl"]
|
intel-mkl = ["lapack-src/intel-mkl"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra = { version = "0.30", path = ".." }
|
nalgebra = { version = "0.32", path = ".." }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
num-complex = { version = "0.4", default-features = false }
|
num-complex = { version = "0.4", default-features = false }
|
||||||
simba = "0.7"
|
simba = "0.8"
|
||||||
serde = { version = "1.0", features = [ "derive" ], optional = true }
|
serde = { version = "1.0", features = [ "derive" ], optional = true }
|
||||||
lapack = { version = "0.19", default-features = false }
|
lapack = { version = "0.19", default-features = false }
|
||||||
lapack-src = { version = "0.8", default-features = false }
|
lapack-src = { version = "0.8", default-features = false }
|
||||||
# clippy = "*"
|
# clippy = "*"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nalgebra = { version = "0.30", features = [ "arbitrary", "rand" ], path = ".." }
|
nalgebra = { version = "0.32", features = [ "arbitrary", "rand" ], path = ".." }
|
||||||
proptest = { version = "1", default-features = false, features = ["std"] }
|
proptest = { version = "1", default-features = false, features = ["std"] }
|
||||||
quickcheck = "1"
|
quickcheck = "1"
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,12 @@ use num_complex::Complex;
|
||||||
use simba::scalar::RealField;
|
use simba::scalar::RealField;
|
||||||
|
|
||||||
use crate::ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
use na::allocator::Allocator;
|
|
||||||
use na::dimension::{Const, Dim};
|
use na::dimension::{Const, Dim};
|
||||||
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
|
use na::{allocator::Allocator, DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
/// Eigendecomposition of a real square matrix with real eigenvalues.
|
/// Eigendecomposition of a real square matrix with real or complex eigenvalues.
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
|
@ -36,8 +35,10 @@ pub struct Eigen<T: Scalar, D: Dim>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
|
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
/// The eigenvalues of the decomposed matrix.
|
/// The real parts of eigenvalues of the decomposed matrix.
|
||||||
pub eigenvalues: OVector<T, D>,
|
pub eigenvalues_re: OVector<T, D>,
|
||||||
|
/// The imaginary parts of the eigenvalues of the decomposed matrix.
|
||||||
|
pub eigenvalues_im: OVector<T, D>,
|
||||||
/// The (right) eigenvectors of the decomposed matrix.
|
/// The (right) eigenvectors of the decomposed matrix.
|
||||||
pub eigenvectors: Option<OMatrix<T, D, D>>,
|
pub eigenvectors: Option<OMatrix<T, D, D>>,
|
||||||
/// The left eigenvectors of the decomposed matrix.
|
/// The left eigenvectors of the decomposed matrix.
|
||||||
|
@ -69,8 +70,8 @@ where
|
||||||
"Unable to compute the eigenvalue decomposition of a non-square matrix."
|
"Unable to compute the eigenvalue decomposition of a non-square matrix."
|
||||||
);
|
);
|
||||||
|
|
||||||
let ljob = if left_eigenvectors { b'V' } else { b'T' };
|
let ljob = if left_eigenvectors { b'V' } else { b'N' };
|
||||||
let rjob = if eigenvectors { b'V' } else { b'T' };
|
let rjob = if eigenvectors { b'V' } else { b'N' };
|
||||||
|
|
||||||
let (nrows, ncols) = m.shape_generic();
|
let (nrows, ncols) = m.shape_generic();
|
||||||
let n = nrows.value();
|
let n = nrows.value();
|
||||||
|
@ -104,213 +105,231 @@ where
|
||||||
lapack_check!(info);
|
lapack_check!(info);
|
||||||
|
|
||||||
let mut work = vec![T::zero(); lwork as usize];
|
let mut work = vec![T::zero(); lwork as usize];
|
||||||
|
let mut vl = if left_eigenvectors {
|
||||||
match (left_eigenvectors, eigenvectors) {
|
Some(Matrix::zeros_generic(nrows, ncols))
|
||||||
(true, true) => {
|
} else {
|
||||||
// TODO: avoid the initializations?
|
|
||||||
let mut vl = Matrix::zeros_generic(nrows, ncols);
|
|
||||||
let mut vr = Matrix::zeros_generic(nrows, ncols);
|
|
||||||
|
|
||||||
T::xgeev(
|
|
||||||
ljob,
|
|
||||||
rjob,
|
|
||||||
n as i32,
|
|
||||||
m.as_mut_slice(),
|
|
||||||
lda,
|
|
||||||
wr.as_mut_slice(),
|
|
||||||
wi.as_mut_slice(),
|
|
||||||
&mut vl.as_mut_slice(),
|
|
||||||
n as i32,
|
|
||||||
&mut vr.as_mut_slice(),
|
|
||||||
n as i32,
|
|
||||||
&mut work,
|
|
||||||
lwork,
|
|
||||||
&mut info,
|
|
||||||
);
|
|
||||||
lapack_check!(info);
|
|
||||||
|
|
||||||
if wi.iter().all(|e| e.is_zero()) {
|
|
||||||
return Some(Self {
|
|
||||||
eigenvalues: wr,
|
|
||||||
left_eigenvectors: Some(vl),
|
|
||||||
eigenvectors: Some(vr),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(true, false) => {
|
|
||||||
// TODO: avoid the initialization?
|
|
||||||
let mut vl = Matrix::zeros_generic(nrows, ncols);
|
|
||||||
|
|
||||||
T::xgeev(
|
|
||||||
ljob,
|
|
||||||
rjob,
|
|
||||||
n as i32,
|
|
||||||
m.as_mut_slice(),
|
|
||||||
lda,
|
|
||||||
wr.as_mut_slice(),
|
|
||||||
wi.as_mut_slice(),
|
|
||||||
&mut vl.as_mut_slice(),
|
|
||||||
n as i32,
|
|
||||||
&mut placeholder2,
|
|
||||||
1 as i32,
|
|
||||||
&mut work,
|
|
||||||
lwork,
|
|
||||||
&mut info,
|
|
||||||
);
|
|
||||||
lapack_check!(info);
|
|
||||||
|
|
||||||
if wi.iter().all(|e| e.is_zero()) {
|
|
||||||
return Some(Self {
|
|
||||||
eigenvalues: wr,
|
|
||||||
left_eigenvectors: Some(vl),
|
|
||||||
eigenvectors: None,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(false, true) => {
|
|
||||||
// TODO: avoid the initialization?
|
|
||||||
let mut vr = Matrix::zeros_generic(nrows, ncols);
|
|
||||||
|
|
||||||
T::xgeev(
|
|
||||||
ljob,
|
|
||||||
rjob,
|
|
||||||
n as i32,
|
|
||||||
m.as_mut_slice(),
|
|
||||||
lda,
|
|
||||||
wr.as_mut_slice(),
|
|
||||||
wi.as_mut_slice(),
|
|
||||||
&mut placeholder1,
|
|
||||||
1 as i32,
|
|
||||||
&mut vr.as_mut_slice(),
|
|
||||||
n as i32,
|
|
||||||
&mut work,
|
|
||||||
lwork,
|
|
||||||
&mut info,
|
|
||||||
);
|
|
||||||
lapack_check!(info);
|
|
||||||
|
|
||||||
if wi.iter().all(|e| e.is_zero()) {
|
|
||||||
return Some(Self {
|
|
||||||
eigenvalues: wr,
|
|
||||||
left_eigenvectors: None,
|
|
||||||
eigenvectors: Some(vr),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(false, false) => {
|
|
||||||
T::xgeev(
|
|
||||||
ljob,
|
|
||||||
rjob,
|
|
||||||
n as i32,
|
|
||||||
m.as_mut_slice(),
|
|
||||||
lda,
|
|
||||||
wr.as_mut_slice(),
|
|
||||||
wi.as_mut_slice(),
|
|
||||||
&mut placeholder1,
|
|
||||||
1 as i32,
|
|
||||||
&mut placeholder2,
|
|
||||||
1 as i32,
|
|
||||||
&mut work,
|
|
||||||
lwork,
|
|
||||||
&mut info,
|
|
||||||
);
|
|
||||||
lapack_check!(info);
|
|
||||||
|
|
||||||
if wi.iter().all(|e| e.is_zero()) {
|
|
||||||
return Some(Self {
|
|
||||||
eigenvalues: wr,
|
|
||||||
left_eigenvectors: None,
|
|
||||||
eigenvectors: None,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
};
|
||||||
|
let mut vr = if eigenvectors {
|
||||||
|
Some(Matrix::zeros_generic(nrows, ncols))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
/// The complex eigenvalues of the given matrix.
|
let vl_ref = vl
|
||||||
///
|
.as_mut()
|
||||||
/// Panics if the eigenvalue computation does not converge.
|
.map(|m| m.as_mut_slice())
|
||||||
pub fn complex_eigenvalues(mut m: OMatrix<T, D, D>) -> OVector<Complex<T>, D>
|
.unwrap_or(&mut placeholder1);
|
||||||
where
|
let vr_ref = vr
|
||||||
DefaultAllocator: Allocator<Complex<T>, D>,
|
.as_mut()
|
||||||
{
|
.map(|m| m.as_mut_slice())
|
||||||
assert!(
|
.unwrap_or(&mut placeholder2);
|
||||||
m.is_square(),
|
|
||||||
"Unable to compute the eigenvalue decomposition of a non-square matrix."
|
|
||||||
);
|
|
||||||
|
|
||||||
let nrows = m.shape_generic().0;
|
|
||||||
let n = nrows.value();
|
|
||||||
|
|
||||||
let lda = n as i32;
|
|
||||||
|
|
||||||
// TODO: avoid the initialization?
|
|
||||||
let mut wr = Matrix::zeros_generic(nrows, Const::<1>);
|
|
||||||
let mut wi = Matrix::zeros_generic(nrows, Const::<1>);
|
|
||||||
|
|
||||||
let mut info = 0;
|
|
||||||
let mut placeholder1 = [T::zero()];
|
|
||||||
let mut placeholder2 = [T::zero()];
|
|
||||||
|
|
||||||
let lwork = T::xgeev_work_size(
|
|
||||||
b'T',
|
|
||||||
b'T',
|
|
||||||
n as i32,
|
|
||||||
m.as_mut_slice(),
|
|
||||||
lda,
|
|
||||||
wr.as_mut_slice(),
|
|
||||||
wi.as_mut_slice(),
|
|
||||||
&mut placeholder1,
|
|
||||||
n as i32,
|
|
||||||
&mut placeholder2,
|
|
||||||
n as i32,
|
|
||||||
&mut info,
|
|
||||||
);
|
|
||||||
|
|
||||||
lapack_panic!(info);
|
|
||||||
|
|
||||||
let mut work = vec![T::zero(); lwork as usize];
|
|
||||||
|
|
||||||
T::xgeev(
|
T::xgeev(
|
||||||
b'T',
|
ljob,
|
||||||
b'T',
|
rjob,
|
||||||
n as i32,
|
n as i32,
|
||||||
m.as_mut_slice(),
|
m.as_mut_slice(),
|
||||||
lda,
|
lda,
|
||||||
wr.as_mut_slice(),
|
wr.as_mut_slice(),
|
||||||
wi.as_mut_slice(),
|
wi.as_mut_slice(),
|
||||||
&mut placeholder1,
|
vl_ref,
|
||||||
1 as i32,
|
if left_eigenvectors { n as i32 } else { 1 },
|
||||||
&mut placeholder2,
|
vr_ref,
|
||||||
1 as i32,
|
if eigenvectors { n as i32 } else { 1 },
|
||||||
&mut work,
|
&mut work,
|
||||||
lwork,
|
lwork,
|
||||||
&mut info,
|
&mut info,
|
||||||
);
|
);
|
||||||
lapack_panic!(info);
|
lapack_check!(info);
|
||||||
|
|
||||||
let mut res = Matrix::zeros_generic(nrows, Const::<1>);
|
Some(Self {
|
||||||
|
eigenvalues_re: wr,
|
||||||
for i in 0..res.len() {
|
eigenvalues_im: wi,
|
||||||
res[i] = Complex::new(wr[i].clone(), wi[i].clone());
|
left_eigenvectors: vl,
|
||||||
|
eigenvectors: vr,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
/// Returns `true` if all the eigenvalues are real.
|
||||||
|
pub fn eigenvalues_are_real(&self) -> bool {
|
||||||
|
self.eigenvalues_im.iter().all(|e| e.is_zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The determinant of the decomposed matrix.
|
/// The determinant of the decomposed matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn determinant(&self) -> T {
|
pub fn determinant(&self) -> Complex<T> {
|
||||||
let mut det = T::one();
|
let mut det: Complex<T> = na::one();
|
||||||
for e in self.eigenvalues.iter() {
|
for (re, im) in self.eigenvalues_re.iter().zip(self.eigenvalues_im.iter()) {
|
||||||
det *= e.clone();
|
det *= Complex::new(re.clone(), im.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
det
|
det
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a tuple of vectors. The elements of the tuple are the real parts of the eigenvalues, left eigenvectors and right eigenvectors respectively.
|
||||||
|
pub fn get_real_elements(
|
||||||
|
&self,
|
||||||
|
) -> (
|
||||||
|
Vec<T>,
|
||||||
|
Option<Vec<OVector<T, D>>>,
|
||||||
|
Option<Vec<OVector<T, D>>>,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
DefaultAllocator: Allocator<T, D>,
|
||||||
|
{
|
||||||
|
let (number_of_elements, _) = self.eigenvalues_re.shape_generic();
|
||||||
|
let number_of_elements_value = number_of_elements.value();
|
||||||
|
let mut eigenvalues = Vec::<T>::with_capacity(number_of_elements_value);
|
||||||
|
let mut eigenvectors = match self.eigenvectors.is_some() {
|
||||||
|
true => Some(Vec::<OVector<T, D>>::with_capacity(
|
||||||
|
number_of_elements_value,
|
||||||
|
)),
|
||||||
|
false => None,
|
||||||
|
};
|
||||||
|
let mut left_eigenvectors = match self.left_eigenvectors.is_some() {
|
||||||
|
true => Some(Vec::<OVector<T, D>>::with_capacity(
|
||||||
|
number_of_elements_value,
|
||||||
|
)),
|
||||||
|
false => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut c = 0;
|
||||||
|
while c < number_of_elements_value {
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
if left_eigenvectors.is_some() {
|
||||||
|
left_eigenvectors.as_mut().unwrap().push(
|
||||||
|
self.left_eigenvectors
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.column(c)
|
||||||
|
.into_owned(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if self.eigenvalues_im[c] != T::zero() {
|
||||||
|
//skip next entry
|
||||||
|
c += 1;
|
||||||
|
}
|
||||||
|
c += 1;
|
||||||
|
}
|
||||||
|
(eigenvalues, left_eigenvectors, eigenvectors)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a tuple of vectors. The elements of the tuple are the complex eigenvalues, complex left eigenvectors and complex right eigenvectors respectively.
|
||||||
|
/// The elements appear as conjugate pairs within each vector, with the positive of the pair always being first.
|
||||||
|
pub fn get_complex_elements(
|
||||||
|
&self,
|
||||||
|
) -> (
|
||||||
|
Option<Vec<Complex<T>>>,
|
||||||
|
Option<Vec<OVector<Complex<T>, D>>>,
|
||||||
|
Option<Vec<OVector<Complex<T>, D>>>,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
DefaultAllocator: Allocator<Complex<T>, D>,
|
||||||
|
{
|
||||||
|
match self.eigenvalues_are_real() {
|
||||||
|
true => (None, None, None),
|
||||||
|
false => {
|
||||||
|
let (number_of_elements, _) = self.eigenvalues_re.shape_generic();
|
||||||
|
let number_of_elements_value = number_of_elements.value();
|
||||||
|
let number_of_complex_entries =
|
||||||
|
self.eigenvalues_im
|
||||||
|
.iter()
|
||||||
|
.fold(0, |acc, e| if !e.is_zero() { acc + 1 } else { acc });
|
||||||
|
let mut eigenvalues = Vec::<Complex<T>>::with_capacity(number_of_complex_entries);
|
||||||
|
let mut eigenvectors = match self.eigenvectors.is_some() {
|
||||||
|
true => Some(Vec::<OVector<Complex<T>, D>>::with_capacity(
|
||||||
|
number_of_complex_entries,
|
||||||
|
)),
|
||||||
|
false => None,
|
||||||
|
};
|
||||||
|
let mut left_eigenvectors = match self.left_eigenvectors.is_some() {
|
||||||
|
true => Some(Vec::<OVector<Complex<T>, D>>::with_capacity(
|
||||||
|
number_of_complex_entries,
|
||||||
|
)),
|
||||||
|
false => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut c = 0;
|
||||||
|
while c < number_of_elements_value {
|
||||||
|
if self.eigenvalues_im[c] != T::zero() {
|
||||||
|
//Complex conjugate pairs of eigenvalues appear consecutively with the eigenvalue having the positive imaginary part first.
|
||||||
|
eigenvalues.push(Complex::<T>::new(
|
||||||
|
self.eigenvalues_re[c].clone(),
|
||||||
|
self.eigenvalues_im[c].clone(),
|
||||||
|
));
|
||||||
|
eigenvalues.push(Complex::<T>::new(
|
||||||
|
self.eigenvalues_re[c + 1].clone(),
|
||||||
|
self.eigenvalues_im[c + 1].clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
if eigenvectors.is_some() {
|
||||||
|
let mut vec = OVector::<Complex<T>, D>::zeros_generic(
|
||||||
|
number_of_elements,
|
||||||
|
Const::<1>,
|
||||||
|
);
|
||||||
|
let mut vec_conj = OVector::<Complex<T>, D>::zeros_generic(
|
||||||
|
number_of_elements,
|
||||||
|
Const::<1>,
|
||||||
|
);
|
||||||
|
|
||||||
|
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(),
|
||||||
|
);
|
||||||
|
vec_conj[r] = Complex::<T>::new(
|
||||||
|
self.eigenvectors.as_ref().unwrap()[(r, c)].clone(),
|
||||||
|
self.eigenvectors.as_ref().unwrap()[(r, c + 1)].clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
eigenvectors.as_mut().unwrap().push(vec);
|
||||||
|
eigenvectors.as_mut().unwrap().push(vec_conj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if left_eigenvectors.is_some() {
|
||||||
|
let mut vec = OVector::<Complex<T>, D>::zeros_generic(
|
||||||
|
number_of_elements,
|
||||||
|
Const::<1>,
|
||||||
|
);
|
||||||
|
let mut vec_conj = OVector::<Complex<T>, D>::zeros_generic(
|
||||||
|
number_of_elements,
|
||||||
|
Const::<1>,
|
||||||
|
);
|
||||||
|
|
||||||
|
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(),
|
||||||
|
);
|
||||||
|
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(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
left_eigenvectors.as_mut().unwrap().push(vec);
|
||||||
|
left_eigenvectors.as_mut().unwrap().push(vec_conj);
|
||||||
|
}
|
||||||
|
//skip next entry
|
||||||
|
c += 1;
|
||||||
|
}
|
||||||
|
c += 1;
|
||||||
|
}
|
||||||
|
(Some(eigenvalues), left_eigenvectors, eigenvectors)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -0,0 +1,350 @@
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use num::Zero;
|
||||||
|
use num_complex::Complex;
|
||||||
|
|
||||||
|
use simba::scalar::RealField;
|
||||||
|
|
||||||
|
use crate::ComplexHelper;
|
||||||
|
use na::allocator::Allocator;
|
||||||
|
use na::dimension::{Const, Dim};
|
||||||
|
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
|
||||||
|
|
||||||
|
use lapack;
|
||||||
|
|
||||||
|
/// Generalized eigenvalues and generalized eigenvectors (left and right) of a pair of N*N real square matrices.
|
||||||
|
///
|
||||||
|
/// Each generalized eigenvalue (lambda) satisfies determinant(A - lambda*B) = 0
|
||||||
|
///
|
||||||
|
/// The right eigenvector v(j) corresponding to the eigenvalue lambda(j)
|
||||||
|
/// of (A,B) satisfies
|
||||||
|
///
|
||||||
|
/// A * v(j) = lambda(j) * B * v(j).
|
||||||
|
///
|
||||||
|
/// The left eigenvector u(j) corresponding to the eigenvalue lambda(j)
|
||||||
|
/// of (A,B) satisfies
|
||||||
|
///
|
||||||
|
/// u(j)**H * A = lambda(j) * u(j)**H * B .
|
||||||
|
/// where u(j)**H is the conjugate-transpose of u(j).
|
||||||
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "serde-serialize",
|
||||||
|
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<T, D, D> + Allocator<T, D>,
|
||||||
|
OVector<T, D>: Deserialize<'de>,
|
||||||
|
OMatrix<T, D, D>: Deserialize<'de>")
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct GeneralizedEigen<T: Scalar, D: Dim>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
|
||||||
|
{
|
||||||
|
alphar: OVector<T, D>,
|
||||||
|
alphai: OVector<T, D>,
|
||||||
|
beta: OVector<T, D>,
|
||||||
|
vsl: OMatrix<T, D, D>,
|
||||||
|
vsr: OMatrix<T, D, D>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Scalar + Copy, D: Dim> Copy for GeneralizedEigen<T, D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
|
OMatrix<T, D, D>: Copy,
|
||||||
|
OVector<T, D>: Copy,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: GeneralizedEigenScalar + RealField + Copy, D: Dim> GeneralizedEigen<T, D>
|
||||||
|
where
|
||||||
|
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
|
||||||
|
///
|
||||||
|
/// Panics if the method did not converge.
|
||||||
|
pub fn new(a: OMatrix<T, D, D>, b: OMatrix<T, D, D>) -> Self {
|
||||||
|
Self::try_new(a, b).expect("Calculation of generalized eigenvalues failed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempts to compute the generalized eigenvalues (and eigenvectors) via the raw returns from LAPACK's
|
||||||
|
/// dggev and sggev routines
|
||||||
|
///
|
||||||
|
/// Returns `None` if the method did not converge.
|
||||||
|
pub fn try_new(mut a: OMatrix<T, D, D>, mut b: OMatrix<T, D, D>) -> Option<Self> {
|
||||||
|
assert!(
|
||||||
|
a.is_square() && b.is_square(),
|
||||||
|
"Unable to compute the generalized eigenvalues of non-square matrices."
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
a.shape_generic() == b.shape_generic(),
|
||||||
|
"Unable to compute the generalized eigenvalues of two square matrices of different dimensions."
|
||||||
|
);
|
||||||
|
|
||||||
|
let (nrows, ncols) = a.shape_generic();
|
||||||
|
let n = nrows.value();
|
||||||
|
|
||||||
|
let mut info = 0;
|
||||||
|
|
||||||
|
let mut alphar = Matrix::zeros_generic(nrows, Const::<1>);
|
||||||
|
let mut alphai = Matrix::zeros_generic(nrows, Const::<1>);
|
||||||
|
let mut beta = Matrix::zeros_generic(nrows, Const::<1>);
|
||||||
|
let mut vsl = Matrix::zeros_generic(nrows, ncols);
|
||||||
|
let mut vsr = Matrix::zeros_generic(nrows, ncols);
|
||||||
|
|
||||||
|
let lwork = T::xggev_work_size(
|
||||||
|
b'V',
|
||||||
|
b'V',
|
||||||
|
n as i32,
|
||||||
|
a.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
b.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
alphar.as_mut_slice(),
|
||||||
|
alphai.as_mut_slice(),
|
||||||
|
beta.as_mut_slice(),
|
||||||
|
vsl.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
vsr.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
&mut info,
|
||||||
|
);
|
||||||
|
lapack_check!(info);
|
||||||
|
|
||||||
|
let mut work = vec![T::zero(); lwork as usize];
|
||||||
|
|
||||||
|
T::xggev(
|
||||||
|
b'V',
|
||||||
|
b'V',
|
||||||
|
n as i32,
|
||||||
|
a.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
b.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
alphar.as_mut_slice(),
|
||||||
|
alphai.as_mut_slice(),
|
||||||
|
beta.as_mut_slice(),
|
||||||
|
vsl.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
vsr.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
&mut work,
|
||||||
|
lwork,
|
||||||
|
&mut info,
|
||||||
|
);
|
||||||
|
lapack_check!(info);
|
||||||
|
|
||||||
|
Some(GeneralizedEigen {
|
||||||
|
alphar,
|
||||||
|
alphai,
|
||||||
|
beta,
|
||||||
|
vsl,
|
||||||
|
vsr,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculates the generalized eigenvectors (left and right) associated with the generalized eigenvalues
|
||||||
|
///
|
||||||
|
/// Outputs two matrices.
|
||||||
|
/// The first output matrix contains the left eigenvectors of the generalized eigenvalues
|
||||||
|
/// as columns.
|
||||||
|
/// The second matrix contains the right eigenvectors of the generalized eigenvalues
|
||||||
|
/// as columns.
|
||||||
|
pub fn eigenvectors(&self) -> (OMatrix<Complex<T>, D, D>, OMatrix<Complex<T>, D, D>)
|
||||||
|
where
|
||||||
|
DefaultAllocator:
|
||||||
|
Allocator<Complex<T>, D, D> + Allocator<Complex<T>, D> + Allocator<(Complex<T>, T), D>,
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
How the eigenvectors are built up:
|
||||||
|
|
||||||
|
Since the input entries are all real, the generalized eigenvalues if complex come in pairs
|
||||||
|
as a consequence of the [complex conjugate root thorem](https://en.wikipedia.org/wiki/Complex_conjugate_root_theorem)
|
||||||
|
The Lapack routine output reflects this by expecting the user to unpack the real and complex eigenvalues associated
|
||||||
|
eigenvectors from the real matrix output via the following procedure
|
||||||
|
|
||||||
|
(Note: VL stands for the lapack real matrix output containing the left eigenvectors as columns,
|
||||||
|
VR stands for the lapack real matrix output containing the right eigenvectors as columns)
|
||||||
|
|
||||||
|
If the j-th and (j+1)-th eigenvalues form a complex conjugate pair,
|
||||||
|
then
|
||||||
|
|
||||||
|
u(j) = VL(:,j)+i*VL(:,j+1)
|
||||||
|
u(j+1) = VL(:,j)-i*VL(:,j+1)
|
||||||
|
|
||||||
|
and
|
||||||
|
|
||||||
|
u(j) = VR(:,j)+i*VR(:,j+1)
|
||||||
|
v(j+1) = VR(:,j)-i*VR(:,j+1).
|
||||||
|
*/
|
||||||
|
|
||||||
|
let n = self.vsl.shape().0;
|
||||||
|
|
||||||
|
let mut l = self.vsl.map(|x| Complex::new(x, T::RealField::zero()));
|
||||||
|
|
||||||
|
let mut r = self.vsr.map(|x| Complex::new(x, T::RealField::zero()));
|
||||||
|
|
||||||
|
let eigenvalues = self.raw_eigenvalues();
|
||||||
|
|
||||||
|
let mut c = 0;
|
||||||
|
|
||||||
|
while c < n {
|
||||||
|
if eigenvalues[c].0.im.abs() != T::RealField::zero() && c + 1 < n {
|
||||||
|
// taking care of the left eigenvector matrix
|
||||||
|
l.column_mut(c).zip_apply(&self.vsl.column(c + 1), |r, i| {
|
||||||
|
*r = Complex::new(r.re.clone(), i.clone());
|
||||||
|
});
|
||||||
|
l.column_mut(c + 1).zip_apply(&self.vsl.column(c), |i, r| {
|
||||||
|
*i = Complex::new(r.clone(), -i.re.clone());
|
||||||
|
});
|
||||||
|
|
||||||
|
// taking care of the right eigenvector matrix
|
||||||
|
r.column_mut(c).zip_apply(&self.vsr.column(c + 1), |r, i| {
|
||||||
|
*r = Complex::new(r.re.clone(), i.clone());
|
||||||
|
});
|
||||||
|
r.column_mut(c + 1).zip_apply(&self.vsr.column(c), |i, r| {
|
||||||
|
*i = Complex::new(r.clone(), -i.re.clone());
|
||||||
|
});
|
||||||
|
|
||||||
|
c += 2;
|
||||||
|
} else {
|
||||||
|
c += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(l, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Outputs the unprocessed (almost) version of generalized eigenvalues ((alphar, alphai), beta)
|
||||||
|
/// straight from LAPACK
|
||||||
|
#[must_use]
|
||||||
|
pub fn raw_eigenvalues(&self) -> OVector<(Complex<T>, T), D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Allocator<(Complex<T>, T), D>,
|
||||||
|
{
|
||||||
|
let mut out = Matrix::from_element_generic(
|
||||||
|
self.vsl.shape_generic().0,
|
||||||
|
Const::<1>,
|
||||||
|
(Complex::zero(), T::RealField::zero()),
|
||||||
|
);
|
||||||
|
|
||||||
|
for i in 0..out.len() {
|
||||||
|
out[i] = (Complex::new(self.alphar[i], self.alphai[i]), self.beta[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Lapack functions dispatch.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/// Trait implemented by scalars for which Lapack implements the RealField GeneralizedEigen decomposition.
|
||||||
|
pub trait GeneralizedEigenScalar: Scalar {
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
fn xggev(
|
||||||
|
jobvsl: u8,
|
||||||
|
jobvsr: u8,
|
||||||
|
n: i32,
|
||||||
|
a: &mut [Self],
|
||||||
|
lda: i32,
|
||||||
|
b: &mut [Self],
|
||||||
|
ldb: i32,
|
||||||
|
alphar: &mut [Self],
|
||||||
|
alphai: &mut [Self],
|
||||||
|
beta: &mut [Self],
|
||||||
|
vsl: &mut [Self],
|
||||||
|
ldvsl: i32,
|
||||||
|
vsr: &mut [Self],
|
||||||
|
ldvsr: i32,
|
||||||
|
work: &mut [Self],
|
||||||
|
lwork: i32,
|
||||||
|
info: &mut i32,
|
||||||
|
);
|
||||||
|
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
fn xggev_work_size(
|
||||||
|
jobvsl: u8,
|
||||||
|
jobvsr: u8,
|
||||||
|
n: i32,
|
||||||
|
a: &mut [Self],
|
||||||
|
lda: i32,
|
||||||
|
b: &mut [Self],
|
||||||
|
ldb: i32,
|
||||||
|
alphar: &mut [Self],
|
||||||
|
alphai: &mut [Self],
|
||||||
|
beta: &mut [Self],
|
||||||
|
vsl: &mut [Self],
|
||||||
|
ldvsl: i32,
|
||||||
|
vsr: &mut [Self],
|
||||||
|
ldvsr: i32,
|
||||||
|
info: &mut i32,
|
||||||
|
) -> i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! generalized_eigen_scalar_impl (
|
||||||
|
($N: ty, $xggev: path) => (
|
||||||
|
impl GeneralizedEigenScalar for $N {
|
||||||
|
#[inline]
|
||||||
|
fn xggev(jobvsl: u8,
|
||||||
|
jobvsr: u8,
|
||||||
|
n: i32,
|
||||||
|
a: &mut [$N],
|
||||||
|
lda: i32,
|
||||||
|
b: &mut [$N],
|
||||||
|
ldb: i32,
|
||||||
|
alphar: &mut [$N],
|
||||||
|
alphai: &mut [$N],
|
||||||
|
beta : &mut [$N],
|
||||||
|
vsl: &mut [$N],
|
||||||
|
ldvsl: i32,
|
||||||
|
vsr: &mut [$N],
|
||||||
|
ldvsr: i32,
|
||||||
|
work: &mut [$N],
|
||||||
|
lwork: i32,
|
||||||
|
info: &mut i32) {
|
||||||
|
unsafe { $xggev(jobvsl, jobvsr, n, a, lda, b, ldb, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, work, lwork, info); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn xggev_work_size(jobvsl: u8,
|
||||||
|
jobvsr: u8,
|
||||||
|
n: i32,
|
||||||
|
a: &mut [$N],
|
||||||
|
lda: i32,
|
||||||
|
b: &mut [$N],
|
||||||
|
ldb: i32,
|
||||||
|
alphar: &mut [$N],
|
||||||
|
alphai: &mut [$N],
|
||||||
|
beta : &mut [$N],
|
||||||
|
vsl: &mut [$N],
|
||||||
|
ldvsl: i32,
|
||||||
|
vsr: &mut [$N],
|
||||||
|
ldvsr: i32,
|
||||||
|
info: &mut i32)
|
||||||
|
-> i32 {
|
||||||
|
let mut work = [ Zero::zero() ];
|
||||||
|
let lwork = -1 as i32;
|
||||||
|
|
||||||
|
unsafe { $xggev(jobvsl, jobvsr, n, a, lda, b, ldb, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, &mut work, lwork, info); }
|
||||||
|
ComplexHelper::real_part(work[0]) as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
generalized_eigen_scalar_impl!(f32, lapack::sggev);
|
||||||
|
generalized_eigen_scalar_impl!(f64, lapack::dggev);
|
|
@ -83,9 +83,11 @@ mod lapack_check;
|
||||||
|
|
||||||
mod cholesky;
|
mod cholesky;
|
||||||
mod eigen;
|
mod eigen;
|
||||||
|
mod generalized_eigenvalues;
|
||||||
mod hessenberg;
|
mod hessenberg;
|
||||||
mod lu;
|
mod lu;
|
||||||
mod qr;
|
mod qr;
|
||||||
|
mod qz;
|
||||||
mod schur;
|
mod schur;
|
||||||
mod svd;
|
mod svd;
|
||||||
mod symmetric_eigen;
|
mod symmetric_eigen;
|
||||||
|
@ -94,9 +96,11 @@ use num_complex::Complex;
|
||||||
|
|
||||||
pub use self::cholesky::{Cholesky, CholeskyScalar};
|
pub use self::cholesky::{Cholesky, CholeskyScalar};
|
||||||
pub use self::eigen::Eigen;
|
pub use self::eigen::Eigen;
|
||||||
|
pub use self::generalized_eigenvalues::GeneralizedEigen;
|
||||||
pub use self::hessenberg::Hessenberg;
|
pub use self::hessenberg::Hessenberg;
|
||||||
pub use self::lu::{LUScalar, LU};
|
pub use self::lu::{LUScalar, LU};
|
||||||
pub use self::qr::QR;
|
pub use self::qr::QR;
|
||||||
|
pub use self::qz::QZ;
|
||||||
pub use self::schur::Schur;
|
pub use self::schur::Schur;
|
||||||
pub use self::svd::SVD;
|
pub use self::svd::SVD;
|
||||||
pub use self::symmetric_eigen::SymmetricEigen;
|
pub use self::symmetric_eigen::SymmetricEigen;
|
||||||
|
|
|
@ -126,7 +126,7 @@ where
|
||||||
|
|
||||||
let mut q = self
|
let mut q = self
|
||||||
.qr
|
.qr
|
||||||
.generic_slice((0, 0), (nrows, min_nrows_ncols))
|
.generic_view((0, 0), (nrows, min_nrows_ncols))
|
||||||
.into_owned();
|
.into_owned();
|
||||||
|
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
|
|
|
@ -0,0 +1,321 @@
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use num::Zero;
|
||||||
|
use num_complex::Complex;
|
||||||
|
|
||||||
|
use simba::scalar::RealField;
|
||||||
|
|
||||||
|
use crate::ComplexHelper;
|
||||||
|
use na::allocator::Allocator;
|
||||||
|
use na::dimension::{Const, Dim};
|
||||||
|
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
|
||||||
|
|
||||||
|
use lapack;
|
||||||
|
|
||||||
|
/// QZ decomposition of a pair of N*N square matrices.
|
||||||
|
///
|
||||||
|
/// Retrieves the left and right matrices of Schur Vectors (VSL and VSR)
|
||||||
|
/// the upper-quasitriangular matrix `S` and upper triangular matrix `T` such that the
|
||||||
|
/// decomposed input matrix `a` equals `VSL * S * VSL.transpose()` and
|
||||||
|
/// decomposed input matrix `b` equals `VSL * T * VSL.transpose()`.
|
||||||
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "serde-serialize",
|
||||||
|
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<T, D, D> + Allocator<T, D>,
|
||||||
|
OVector<T, D>: Deserialize<'de>,
|
||||||
|
OMatrix<T, D, D>: Deserialize<'de>")
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct QZ<T: Scalar, D: Dim>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
|
||||||
|
{
|
||||||
|
alphar: OVector<T, D>,
|
||||||
|
alphai: OVector<T, D>,
|
||||||
|
beta: OVector<T, D>,
|
||||||
|
vsl: OMatrix<T, D, D>,
|
||||||
|
s: OMatrix<T, D, D>,
|
||||||
|
vsr: OMatrix<T, D, D>,
|
||||||
|
t: OMatrix<T, D, D>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Scalar + Copy, D: Dim> Copy for QZ<T, D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
|
OMatrix<T, D, D>: Copy,
|
||||||
|
OVector<T, D>: Copy,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: QZScalar + RealField, D: Dim> QZ<T, D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
|
{
|
||||||
|
/// Attempts to compute the QZ decomposition of input real square matrices `a` and `b`.
|
||||||
|
///
|
||||||
|
/// i.e retrieves the left and right matrices of Schur Vectors (VSL and VSR)
|
||||||
|
/// the upper-quasitriangular matrix `S` and upper triangular matrix `T` such that the
|
||||||
|
/// decomposed matrix `a` equals `VSL * S * VSL.transpose()` and
|
||||||
|
/// decomposed matrix `b` equals `VSL * T * VSL.transpose()`.
|
||||||
|
///
|
||||||
|
/// Panics if the method did not converge.
|
||||||
|
pub fn new(a: OMatrix<T, D, D>, b: OMatrix<T, D, D>) -> Self {
|
||||||
|
Self::try_new(a, b).expect("QZ decomposition: convergence failed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes the decomposition of input matrices `a` and `b` into a pair of matrices of Schur vectors
|
||||||
|
/// , a quasi-upper triangular matrix and an upper-triangular matrix .
|
||||||
|
///
|
||||||
|
/// Returns `None` if the method did not converge.
|
||||||
|
pub fn try_new(mut a: OMatrix<T, D, D>, mut b: OMatrix<T, D, D>) -> Option<Self> {
|
||||||
|
assert!(
|
||||||
|
a.is_square() && b.is_square(),
|
||||||
|
"Unable to compute the qz decomposition of non-square matrices."
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
a.shape_generic() == b.shape_generic(),
|
||||||
|
"Unable to compute the qz decomposition of two square matrices of different dimensions."
|
||||||
|
);
|
||||||
|
|
||||||
|
let (nrows, ncols) = a.shape_generic();
|
||||||
|
let n = nrows.value();
|
||||||
|
|
||||||
|
let mut info = 0;
|
||||||
|
|
||||||
|
let mut alphar = Matrix::zeros_generic(nrows, Const::<1>);
|
||||||
|
let mut alphai = Matrix::zeros_generic(nrows, Const::<1>);
|
||||||
|
let mut beta = Matrix::zeros_generic(nrows, Const::<1>);
|
||||||
|
let mut vsl = Matrix::zeros_generic(nrows, ncols);
|
||||||
|
let mut vsr = Matrix::zeros_generic(nrows, ncols);
|
||||||
|
// Placeholders:
|
||||||
|
let mut bwork = [0i32];
|
||||||
|
let mut unused = 0;
|
||||||
|
|
||||||
|
let lwork = T::xgges_work_size(
|
||||||
|
b'V',
|
||||||
|
b'V',
|
||||||
|
b'N',
|
||||||
|
n as i32,
|
||||||
|
a.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
b.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
&mut unused,
|
||||||
|
alphar.as_mut_slice(),
|
||||||
|
alphai.as_mut_slice(),
|
||||||
|
beta.as_mut_slice(),
|
||||||
|
vsl.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
vsr.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
&mut bwork,
|
||||||
|
&mut info,
|
||||||
|
);
|
||||||
|
lapack_check!(info);
|
||||||
|
|
||||||
|
let mut work = vec![T::zero(); lwork as usize];
|
||||||
|
|
||||||
|
T::xgges(
|
||||||
|
b'V',
|
||||||
|
b'V',
|
||||||
|
b'N',
|
||||||
|
n as i32,
|
||||||
|
a.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
b.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
&mut unused,
|
||||||
|
alphar.as_mut_slice(),
|
||||||
|
alphai.as_mut_slice(),
|
||||||
|
beta.as_mut_slice(),
|
||||||
|
vsl.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
vsr.as_mut_slice(),
|
||||||
|
n as i32,
|
||||||
|
&mut work,
|
||||||
|
lwork,
|
||||||
|
&mut bwork,
|
||||||
|
&mut info,
|
||||||
|
);
|
||||||
|
lapack_check!(info);
|
||||||
|
|
||||||
|
Some(QZ {
|
||||||
|
alphar,
|
||||||
|
alphai,
|
||||||
|
beta,
|
||||||
|
vsl,
|
||||||
|
s: a,
|
||||||
|
vsr,
|
||||||
|
t: b,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves the left and right matrices of Schur Vectors (VSL and VSR)
|
||||||
|
/// the upper-quasitriangular matrix `S` and upper triangular matrix `T` such that the
|
||||||
|
/// decomposed input matrix `a` equals `VSL * S * VSL.transpose()` and
|
||||||
|
/// decomposed input matrix `b` equals `VSL * T * VSL.transpose()`.
|
||||||
|
pub fn unpack(
|
||||||
|
self,
|
||||||
|
) -> (
|
||||||
|
OMatrix<T, D, D>,
|
||||||
|
OMatrix<T, D, D>,
|
||||||
|
OMatrix<T, D, D>,
|
||||||
|
OMatrix<T, D, D>,
|
||||||
|
) {
|
||||||
|
(self.vsl, self.s, self.t, self.vsr)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// outputs the unprocessed (almost) version of generalized eigenvalues ((alphar, alpai), beta)
|
||||||
|
/// straight from LAPACK
|
||||||
|
#[must_use]
|
||||||
|
pub fn raw_eigenvalues(&self) -> OVector<(Complex<T>, T), D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Allocator<(Complex<T>, T), D>,
|
||||||
|
{
|
||||||
|
let mut out = Matrix::from_element_generic(
|
||||||
|
self.vsl.shape_generic().0,
|
||||||
|
Const::<1>,
|
||||||
|
(Complex::zero(), T::RealField::zero()),
|
||||||
|
);
|
||||||
|
|
||||||
|
for i in 0..out.len() {
|
||||||
|
out[i] = (
|
||||||
|
Complex::new(self.alphar[i].clone(), self.alphai[i].clone()),
|
||||||
|
self.beta[i].clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Lapack functions dispatch.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/// Trait implemented by scalars for which Lapack implements the RealField QZ decomposition.
|
||||||
|
pub trait QZScalar: Scalar {
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
fn xgges(
|
||||||
|
jobvsl: u8,
|
||||||
|
jobvsr: u8,
|
||||||
|
sort: u8,
|
||||||
|
// select: ???
|
||||||
|
n: i32,
|
||||||
|
a: &mut [Self],
|
||||||
|
lda: i32,
|
||||||
|
b: &mut [Self],
|
||||||
|
ldb: i32,
|
||||||
|
sdim: &mut i32,
|
||||||
|
alphar: &mut [Self],
|
||||||
|
alphai: &mut [Self],
|
||||||
|
beta: &mut [Self],
|
||||||
|
vsl: &mut [Self],
|
||||||
|
ldvsl: i32,
|
||||||
|
vsr: &mut [Self],
|
||||||
|
ldvsr: i32,
|
||||||
|
work: &mut [Self],
|
||||||
|
lwork: i32,
|
||||||
|
bwork: &mut [i32],
|
||||||
|
info: &mut i32,
|
||||||
|
);
|
||||||
|
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
fn xgges_work_size(
|
||||||
|
jobvsl: u8,
|
||||||
|
jobvsr: u8,
|
||||||
|
sort: u8,
|
||||||
|
// select: ???
|
||||||
|
n: i32,
|
||||||
|
a: &mut [Self],
|
||||||
|
lda: i32,
|
||||||
|
b: &mut [Self],
|
||||||
|
ldb: i32,
|
||||||
|
sdim: &mut i32,
|
||||||
|
alphar: &mut [Self],
|
||||||
|
alphai: &mut [Self],
|
||||||
|
beta: &mut [Self],
|
||||||
|
vsl: &mut [Self],
|
||||||
|
ldvsl: i32,
|
||||||
|
vsr: &mut [Self],
|
||||||
|
ldvsr: i32,
|
||||||
|
bwork: &mut [i32],
|
||||||
|
info: &mut i32,
|
||||||
|
) -> i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! qz_scalar_impl (
|
||||||
|
($N: ty, $xgges: path) => (
|
||||||
|
impl QZScalar for $N {
|
||||||
|
#[inline]
|
||||||
|
fn xgges(jobvsl: u8,
|
||||||
|
jobvsr: u8,
|
||||||
|
sort: u8,
|
||||||
|
// select: ???
|
||||||
|
n: i32,
|
||||||
|
a: &mut [$N],
|
||||||
|
lda: i32,
|
||||||
|
b: &mut [$N],
|
||||||
|
ldb: i32,
|
||||||
|
sdim: &mut i32,
|
||||||
|
alphar: &mut [$N],
|
||||||
|
alphai: &mut [$N],
|
||||||
|
beta : &mut [$N],
|
||||||
|
vsl: &mut [$N],
|
||||||
|
ldvsl: i32,
|
||||||
|
vsr: &mut [$N],
|
||||||
|
ldvsr: i32,
|
||||||
|
work: &mut [$N],
|
||||||
|
lwork: i32,
|
||||||
|
bwork: &mut [i32],
|
||||||
|
info: &mut i32) {
|
||||||
|
unsafe { $xgges(jobvsl, jobvsr, sort, None, n, a, lda, b, ldb, sdim, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, work, lwork, bwork, info); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn xgges_work_size(jobvsl: u8,
|
||||||
|
jobvsr: u8,
|
||||||
|
sort: u8,
|
||||||
|
// select: ???
|
||||||
|
n: i32,
|
||||||
|
a: &mut [$N],
|
||||||
|
lda: i32,
|
||||||
|
b: &mut [$N],
|
||||||
|
ldb: i32,
|
||||||
|
sdim: &mut i32,
|
||||||
|
alphar: &mut [$N],
|
||||||
|
alphai: &mut [$N],
|
||||||
|
beta : &mut [$N],
|
||||||
|
vsl: &mut [$N],
|
||||||
|
ldvsl: i32,
|
||||||
|
vsr: &mut [$N],
|
||||||
|
ldvsr: i32,
|
||||||
|
bwork: &mut [i32],
|
||||||
|
info: &mut i32)
|
||||||
|
-> i32 {
|
||||||
|
let mut work = [ Zero::zero() ];
|
||||||
|
let lwork = -1 as i32;
|
||||||
|
|
||||||
|
unsafe { $xgges(jobvsl, jobvsr, sort, None, n, a, lda, b, ldb, sdim, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, &mut work, lwork, bwork, info); }
|
||||||
|
ComplexHelper::real_part(work[0]) as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
qz_scalar_impl!(f32, lapack::sgges);
|
||||||
|
qz_scalar_impl!(f64, lapack::dgges);
|
|
@ -157,7 +157,7 @@ macro_rules! svd_impl(
|
||||||
let mut res: OMatrix<_, R, C> = Matrix::zeros_generic(nrows, ncols);
|
let mut res: OMatrix<_, R, C> = Matrix::zeros_generic(nrows, ncols);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, ncols));
|
let mut sres = res.generic_view_mut((0, 0), (min_nrows_ncols, ncols));
|
||||||
sres.copy_from(&self.vt.rows_generic(0, min_nrows_ncols));
|
sres.copy_from(&self.vt.rows_generic(0, min_nrows_ncols));
|
||||||
|
|
||||||
for i in 0 .. min_nrows_ncols.value() {
|
for i in 0 .. min_nrows_ncols.value() {
|
||||||
|
@ -183,7 +183,7 @@ macro_rules! svd_impl(
|
||||||
let mut res: OMatrix<_, C, R> = Matrix::zeros_generic(ncols, nrows);
|
let mut res: OMatrix<_, C, R> = Matrix::zeros_generic(ncols, nrows);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, nrows));
|
let mut sres = res.generic_view_mut((0, 0), (min_nrows_ncols, nrows));
|
||||||
self.u.columns_generic(0, min_nrows_ncols).transpose_to(&mut sres);
|
self.u.columns_generic(0, min_nrows_ncols).transpose_to(&mut sres);
|
||||||
|
|
||||||
for i in 0 .. min_nrows_ncols.value() {
|
for i in 0 .. min_nrows_ncols.value() {
|
||||||
|
|
|
@ -58,8 +58,8 @@ proptest! {
|
||||||
let sol1 = chol.solve(&b1).unwrap();
|
let sol1 = chol.solve(&b1).unwrap();
|
||||||
let sol2 = chol.solve(&b2).unwrap();
|
let sol2 = chol.solve(&b2).unwrap();
|
||||||
|
|
||||||
prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-4));
|
||||||
prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ proptest! {
|
||||||
let id1 = &m * &m1;
|
let id1 = &m * &m1;
|
||||||
let id2 = &m1 * &m;
|
let id2 = &m1 * &m;
|
||||||
|
|
||||||
prop_assert!(id1.is_identity(1.0e-5) && id2.is_identity(1.0e-5))
|
prop_assert!(id1.is_identity(1.0e-4) && id2.is_identity(1.0e-4))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
use na::Matrix3;
|
||||||
|
use nalgebra_lapack::Eigen;
|
||||||
|
use num_complex::Complex;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn complex_eigen() {
|
||||||
|
let m = Matrix3::<f64>::new(
|
||||||
|
4.0 / 5.0,
|
||||||
|
-3.0 / 5.0,
|
||||||
|
0.0,
|
||||||
|
3.0 / 5.0,
|
||||||
|
4.0 / 5.0,
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
2.0,
|
||||||
|
2.0,
|
||||||
|
);
|
||||||
|
let eigen = Eigen::new(m, true, true).expect("Eigen Creation Failed!");
|
||||||
|
let (some_eigenvalues, some_left_vec, some_right_vec) = eigen.get_complex_elements();
|
||||||
|
let eigenvalues = some_eigenvalues.expect("Eigenvalues Failed");
|
||||||
|
let _left_eigenvectors = some_left_vec.expect("Left Eigenvectors Failed");
|
||||||
|
let eigenvectors = some_right_vec.expect("Right Eigenvectors Failed");
|
||||||
|
|
||||||
|
assert_relative_eq!(
|
||||||
|
eigenvalues[0].re,
|
||||||
|
Complex::<f64>::new(4.0 / 5.0, 3.0 / 5.0).re
|
||||||
|
);
|
||||||
|
assert_relative_eq!(
|
||||||
|
eigenvalues[0].im,
|
||||||
|
Complex::<f64>::new(4.0 / 5.0, 3.0 / 5.0).im
|
||||||
|
);
|
||||||
|
assert_relative_eq!(
|
||||||
|
eigenvalues[1].re,
|
||||||
|
Complex::<f64>::new(4.0 / 5.0, -3.0 / 5.0).re
|
||||||
|
);
|
||||||
|
assert_relative_eq!(
|
||||||
|
eigenvalues[1].im,
|
||||||
|
Complex::<f64>::new(4.0 / 5.0, -3.0 / 5.0).im
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_relative_eq!(eigenvectors[0][0].re, -12.0 / 32.7871926215100059134410999);
|
||||||
|
assert_relative_eq!(eigenvectors[0][0].im, -9.0 / 32.7871926215100059134410999);
|
||||||
|
assert_relative_eq!(eigenvectors[0][1].re, -9.0 / 32.7871926215100059134410999);
|
||||||
|
assert_relative_eq!(eigenvectors[0][1].im, 12.0 / 32.7871926215100059134410999);
|
||||||
|
assert_relative_eq!(eigenvectors[0][2].re, 25.0 / 32.7871926215100059134410999);
|
||||||
|
assert_relative_eq!(eigenvectors[0][2].im, 0.0);
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
use na::dimension::Const;
|
||||||
|
use na::{DMatrix, OMatrix};
|
||||||
|
use nl::GeneralizedEigen;
|
||||||
|
use num_complex::Complex;
|
||||||
|
use simba::scalar::ComplexField;
|
||||||
|
|
||||||
|
use crate::proptest::*;
|
||||||
|
use proptest::{prop_assert, prop_compose, proptest};
|
||||||
|
|
||||||
|
prop_compose! {
|
||||||
|
fn f64_dynamic_dim_squares()
|
||||||
|
(n in PROPTEST_MATRIX_DIM)
|
||||||
|
(a in matrix(PROPTEST_F64,n,n), b in matrix(PROPTEST_F64,n,n)) -> (DMatrix<f64>, DMatrix<f64>){
|
||||||
|
(a,b)
|
||||||
|
}}
|
||||||
|
|
||||||
|
proptest! {
|
||||||
|
#[test]
|
||||||
|
fn ge((a,b) in f64_dynamic_dim_squares()){
|
||||||
|
|
||||||
|
let a_c = a.clone().map(|x| Complex::new(x, 0.0));
|
||||||
|
let b_c = b.clone().map(|x| Complex::new(x, 0.0));
|
||||||
|
let n = a.shape_generic().0;
|
||||||
|
|
||||||
|
let ge = GeneralizedEigen::new(a.clone(), b.clone());
|
||||||
|
let (vsl,vsr) = ge.clone().eigenvectors();
|
||||||
|
|
||||||
|
|
||||||
|
for (i,(alpha,beta)) in ge.raw_eigenvalues().iter().enumerate() {
|
||||||
|
let l_a = a_c.clone() * Complex::new(*beta, 0.0);
|
||||||
|
let l_b = b_c.clone() * *alpha;
|
||||||
|
|
||||||
|
prop_assert!(
|
||||||
|
relative_eq!(
|
||||||
|
((&l_a - &l_b)*vsr.column(i)).map(|x| x.modulus()),
|
||||||
|
OMatrix::zeros_generic(n, Const::<1>),
|
||||||
|
epsilon = 1.0e-5));
|
||||||
|
|
||||||
|
prop_assert!(
|
||||||
|
relative_eq!(
|
||||||
|
(vsl.column(i).adjoint()*(&l_a - &l_b)).map(|x| x.modulus()),
|
||||||
|
OMatrix::zeros_generic(Const::<1>, n),
|
||||||
|
epsilon = 1.0e-5))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ge_static(a in matrix4(), b in matrix4()) {
|
||||||
|
|
||||||
|
let ge = GeneralizedEigen::new(a.clone(), b.clone());
|
||||||
|
let a_c =a.clone().map(|x| Complex::new(x, 0.0));
|
||||||
|
let b_c = b.clone().map(|x| Complex::new(x, 0.0));
|
||||||
|
let (vsl,vsr) = ge.eigenvectors();
|
||||||
|
let eigenvalues = ge.raw_eigenvalues();
|
||||||
|
|
||||||
|
for (i,(alpha,beta)) in eigenvalues.iter().enumerate() {
|
||||||
|
let l_a = a_c.clone() * Complex::new(*beta, 0.0);
|
||||||
|
let l_b = b_c.clone() * *alpha;
|
||||||
|
|
||||||
|
prop_assert!(
|
||||||
|
relative_eq!(
|
||||||
|
((&l_a - &l_b)*vsr.column(i)).map(|x| x.modulus()),
|
||||||
|
OMatrix::zeros_generic(Const::<4>, Const::<1>),
|
||||||
|
epsilon = 1.0e-5));
|
||||||
|
prop_assert!(
|
||||||
|
relative_eq!((vsl.column(i).adjoint()*(&l_a - &l_b)).map(|x| x.modulus()),
|
||||||
|
OMatrix::zeros_generic(Const::<1>, Const::<4>),
|
||||||
|
epsilon = 1.0e-5))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -51,10 +51,10 @@ proptest! {
|
||||||
let tr_sol1 = lup.solve_transpose(&b1).unwrap();
|
let tr_sol1 = lup.solve_transpose(&b1).unwrap();
|
||||||
let tr_sol2 = lup.solve_transpose(&b2).unwrap();
|
let tr_sol2 = lup.solve_transpose(&b2).unwrap();
|
||||||
|
|
||||||
prop_assert!(relative_eq!(&m * sol1, b1, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(&m * sol1, b1, epsilon = 1.0e-5));
|
||||||
prop_assert!(relative_eq!(&m * sol2, b2, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(&m * sol2, b2, epsilon = 1.0e-5));
|
||||||
prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-5));
|
||||||
prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -68,10 +68,10 @@ proptest! {
|
||||||
let tr_sol1 = lup.solve_transpose(&b1).unwrap();
|
let tr_sol1 = lup.solve_transpose(&b1).unwrap();
|
||||||
let tr_sol2 = lup.solve_transpose(&b2).unwrap();
|
let tr_sol2 = lup.solve_transpose(&b2).unwrap();
|
||||||
|
|
||||||
prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-5));
|
||||||
prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-5));
|
||||||
prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-5));
|
||||||
prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-5));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
mod cholesky;
|
mod cholesky;
|
||||||
|
mod complex_eigen;
|
||||||
|
mod generalized_eigenvalues;
|
||||||
mod lu;
|
mod lu;
|
||||||
mod qr;
|
mod qr;
|
||||||
|
mod qz;
|
||||||
mod real_eigensystem;
|
mod real_eigensystem;
|
||||||
mod schur;
|
mod schur;
|
||||||
mod svd;
|
mod svd;
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
use na::DMatrix;
|
||||||
|
use nl::QZ;
|
||||||
|
|
||||||
|
use crate::proptest::*;
|
||||||
|
use proptest::{prop_assert, prop_compose, proptest};
|
||||||
|
|
||||||
|
prop_compose! {
|
||||||
|
fn f64_dynamic_dim_squares()
|
||||||
|
(n in PROPTEST_MATRIX_DIM)
|
||||||
|
(a in matrix(PROPTEST_F64,n,n), b in matrix(PROPTEST_F64,n,n)) -> (DMatrix<f64>, DMatrix<f64>){
|
||||||
|
(a,b)
|
||||||
|
}}
|
||||||
|
|
||||||
|
proptest! {
|
||||||
|
#[test]
|
||||||
|
fn qz((a,b) in f64_dynamic_dim_squares()) {
|
||||||
|
|
||||||
|
let qz = QZ::new(a.clone(), b.clone());
|
||||||
|
let (vsl,s,t,vsr) = qz.clone().unpack();
|
||||||
|
|
||||||
|
prop_assert!(relative_eq!(&vsl * s * vsr.transpose(), a, epsilon = 1.0e-7));
|
||||||
|
prop_assert!(relative_eq!(vsl * t * vsr.transpose(), b, epsilon = 1.0e-7));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn qz_static(a in matrix4(), b in matrix4()) {
|
||||||
|
let qz = QZ::new(a.clone(), b.clone());
|
||||||
|
let (vsl,s,t,vsr) = qz.unpack();
|
||||||
|
|
||||||
|
prop_assert!(relative_eq!(&vsl * s * vsr.transpose(), a, epsilon = 1.0e-7));
|
||||||
|
prop_assert!(relative_eq!(vsl * t * vsr.transpose(), b, epsilon = 1.0e-7));
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,30 +13,36 @@ proptest! {
|
||||||
let m = DMatrix::<f64>::new_random(n, n);
|
let m = DMatrix::<f64>::new_random(n, n);
|
||||||
|
|
||||||
if let Some(eig) = Eigen::new(m.clone(), true, true) {
|
if let Some(eig) = Eigen::new(m.clone(), true, true) {
|
||||||
let eigvals = DMatrix::from_diagonal(&eig.eigenvalues);
|
// TODO: test the complex case too.
|
||||||
|
if eig.eigenvalues_are_real() {
|
||||||
|
let eigvals = DMatrix::from_diagonal(&eig.eigenvalues_re);
|
||||||
let transformed_eigvectors = &m * eig.eigenvectors.as_ref().unwrap();
|
let transformed_eigvectors = &m * eig.eigenvectors.as_ref().unwrap();
|
||||||
let scaled_eigvectors = eig.eigenvectors.as_ref().unwrap() * &eigvals;
|
let scaled_eigvectors = eig.eigenvectors.as_ref().unwrap() * &eigvals;
|
||||||
|
|
||||||
let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.as_ref().unwrap();
|
let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.as_ref().unwrap();
|
||||||
let scaled_left_eigvectors = eig.left_eigenvectors.as_ref().unwrap() * &eigvals;
|
let scaled_left_eigvectors = eig.left_eigenvectors.as_ref().unwrap() * &eigvals;
|
||||||
|
|
||||||
prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-5));
|
||||||
prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-5));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn eigensystem_static(m in matrix4()) {
|
fn eigensystem_static(m in matrix4()) {
|
||||||
if let Some(eig) = Eigen::new(m, true, true) {
|
if let Some(eig) = Eigen::new(m, true, true) {
|
||||||
let eigvals = Matrix4::from_diagonal(&eig.eigenvalues);
|
// TODO: test the complex case too.
|
||||||
|
if eig.eigenvalues_are_real() {
|
||||||
|
let eigvals = Matrix4::from_diagonal(&eig.eigenvalues_re);
|
||||||
let transformed_eigvectors = m * eig.eigenvectors.unwrap();
|
let transformed_eigvectors = m * eig.eigenvectors.unwrap();
|
||||||
let scaled_eigvectors = eig.eigenvectors.unwrap() * eigvals;
|
let scaled_eigvectors = eig.eigenvectors.unwrap() * eigvals;
|
||||||
|
|
||||||
let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.unwrap();
|
let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.unwrap();
|
||||||
let scaled_left_eigvectors = eig.left_eigenvectors.unwrap() * eigvals;
|
let scaled_left_eigvectors = eig.left_eigenvectors.unwrap() * eigvals;
|
||||||
|
|
||||||
prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-5));
|
||||||
prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-7));
|
prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-5));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,17 @@ proptest! {
|
||||||
let n = cmp::max(1, cmp::min(n, 10));
|
let n = cmp::max(1, cmp::min(n, 10));
|
||||||
let m = DMatrix::<f64>::new_random(n, n);
|
let m = DMatrix::<f64>::new_random(n, n);
|
||||||
|
|
||||||
let (vecs, vals) = Schur::new(m.clone()).unpack();
|
if let Some(schur) = Schur::try_new(m.clone()) {
|
||||||
|
let (vecs, vals) = schur.unpack();
|
||||||
prop_assert!(relative_eq!(&vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7))
|
prop_assert!(relative_eq!(&vecs * vals * vecs.transpose(), m, epsilon = 1.0e-5))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn schur_static(m in matrix4()) {
|
fn schur_static(m in matrix4()) {
|
||||||
let (vecs, vals) = Schur::new(m.clone()).unpack();
|
if let Some(schur) = Schur::try_new(m.clone()) {
|
||||||
prop_assert!(relative_eq!(vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7))
|
let (vecs, vals) = schur.unpack();
|
||||||
|
prop_assert!(relative_eq!(vecs * vals * vecs.transpose(), m, epsilon = 1.0e-5))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra-macros"
|
name = "nalgebra-macros"
|
||||||
version = "0.1.0"
|
version = "0.2.1"
|
||||||
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
|
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Procedural macros for nalgebra"
|
description = "Procedural macros for nalgebra"
|
||||||
|
@ -21,5 +21,5 @@ quote = "1.0"
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nalgebra = { version = "0.30.0", path = ".." }
|
nalgebra = { version = "0.32.0", path = ".." }
|
||||||
trybuild = "1.0.42"
|
trybuild = "1.0.42"
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
../LICENSE
|
|
@ -191,8 +191,8 @@ pub fn dmatrix(stream: TokenStream) -> TokenStream {
|
||||||
let output = quote! {
|
let output = quote! {
|
||||||
nalgebra::DMatrix::<_>
|
nalgebra::DMatrix::<_>
|
||||||
::from_vec_storage(nalgebra::VecStorage::new(
|
::from_vec_storage(nalgebra::VecStorage::new(
|
||||||
nalgebra::Dynamic::new(#row_dim),
|
nalgebra::Dyn(#row_dim),
|
||||||
nalgebra::Dynamic::new(#col_dim),
|
nalgebra::Dyn(#col_dim),
|
||||||
vec!#array_tokens))
|
vec!#array_tokens))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ impl Parse for Vector {
|
||||||
elements: Vec::new(),
|
elements: Vec::new(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let elements = MatrixRowSyntax::parse_separated_nonempty(input)?
|
let elements = MatrixRowSyntax::parse_terminated(input)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect();
|
.collect();
|
||||||
Ok(Self { elements })
|
Ok(Self { elements })
|
||||||
|
@ -285,7 +285,7 @@ pub fn dvector(stream: TokenStream) -> TokenStream {
|
||||||
let output = quote! {
|
let output = quote! {
|
||||||
nalgebra::DVector::<_>
|
nalgebra::DVector::<_>
|
||||||
::from_vec_storage(nalgebra::VecStorage::new(
|
::from_vec_storage(nalgebra::VecStorage::new(
|
||||||
nalgebra::Dynamic::new(#len),
|
nalgebra::Dyn(#len),
|
||||||
nalgebra::Const::<1>,
|
nalgebra::Const::<1>,
|
||||||
vec!#array_tokens))
|
vec!#array_tokens))
|
||||||
};
|
};
|
||||||
|
|
|
@ -94,6 +94,12 @@ fn dmatrix_small_dims_exhaustive() {
|
||||||
DMatrix::from_row_slice(4, 4, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]));
|
DMatrix::from_row_slice(4, 4, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matrix_trailing_semi() {
|
||||||
|
matrix![1, 2;];
|
||||||
|
dmatrix![1, 2;];
|
||||||
|
}
|
||||||
|
|
||||||
// Skip rustfmt because it just makes the test bloated without making it more readable
|
// Skip rustfmt because it just makes the test bloated without making it more readable
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -151,6 +157,13 @@ fn dvector_small_dims_exhaustive() {
|
||||||
assert_eq_and_type!(dvector![1, 2, 3, 4, 5, 6], DVector::from_column_slice(&[1, 2, 3, 4, 5, 6]));
|
assert_eq_and_type!(dvector![1, 2, 3, 4, 5, 6], DVector::from_column_slice(&[1, 2, 3, 4, 5, 6]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn vector_trailing_comma() {
|
||||||
|
vector![1, 2,];
|
||||||
|
point![1, 2,];
|
||||||
|
dvector![1, 2,];
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn matrix_trybuild_tests() {
|
fn matrix_trybuild_tests() {
|
||||||
let t = trybuild::TestCases::new();
|
let t = trybuild::TestCases::new();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra-sparse"
|
name = "nalgebra-sparse"
|
||||||
version = "0.6.0"
|
version = "0.9.0"
|
||||||
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
|
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Sparse matrix computation based on nalgebra."
|
description = "Sparse matrix computation based on nalgebra."
|
||||||
|
@ -24,7 +24,7 @@ io = [ "pest", "pest_derive" ]
|
||||||
slow-tests = []
|
slow-tests = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra = { version="0.30", path = "../" }
|
nalgebra = { version="0.32", path = "../" }
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = { version = "0.2", default-features = false }
|
||||||
proptest = { version = "1.0", optional = true }
|
proptest = { version = "1.0", optional = true }
|
||||||
matrixcompare-core = { version = "0.1.0", optional = true }
|
matrixcompare-core = { version = "0.1.0", optional = true }
|
||||||
|
@ -35,9 +35,10 @@ serde = { version = "1.0", default-features = false, features = [ "derive" ], op
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
matrixcompare = { version = "0.3.0", features = [ "proptest-support" ] }
|
matrixcompare = { version = "0.3.0", features = [ "proptest-support" ] }
|
||||||
nalgebra = { version="0.30", path = "../", features = ["compare"] }
|
nalgebra = { version="0.32", path = "../", features = ["compare"] }
|
||||||
|
tempfile = "3.3"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
# Enable certain features when building docs for docs.rs
|
# Enable certain features when building docs for docs.rs
|
||||||
features = [ "proptest-support", "compare" ]
|
features = [ "proptest-support", "compare", "io"]
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
../LICENSE
|
|
@ -306,7 +306,7 @@ where
|
||||||
|val| sorted_vals.push(val),
|
|val| sorted_vals.push(val),
|
||||||
&idx_workspace[..count],
|
&idx_workspace[..count],
|
||||||
&values_workspace[..count],
|
&values_workspace[..count],
|
||||||
&Add::add,
|
Add::add,
|
||||||
);
|
);
|
||||||
|
|
||||||
let new_col_count = sorted_minor_idx.len() - sorted_ja_current_len;
|
let new_col_count = sorted_minor_idx.len() - sorted_ja_current_len;
|
||||||
|
|
|
@ -160,6 +160,25 @@ impl<T> CooMatrix<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Try to construct a COO matrix from the given dimensions and a finite iterator of
|
||||||
|
/// (i, j, v) triplets.
|
||||||
|
///
|
||||||
|
/// Returns an error if either row or column indices contain indices out of bounds.
|
||||||
|
/// Note that the COO format inherently supports duplicate entries, but they are not
|
||||||
|
/// eagerly summed.
|
||||||
|
///
|
||||||
|
/// Implementation note:
|
||||||
|
/// Calls try_from_triplets so each value is scanned twice.
|
||||||
|
pub fn try_from_triplets_iter(
|
||||||
|
nrows: usize,
|
||||||
|
ncols: usize,
|
||||||
|
triplets: impl IntoIterator<Item = (usize, usize, T)>,
|
||||||
|
) -> Result<Self, SparseFormatError> {
|
||||||
|
let (row_indices, (col_indices, values)) =
|
||||||
|
triplets.into_iter().map(|(r, c, v)| (r, (c, v))).unzip();
|
||||||
|
Self::try_from_triplets(nrows, ncols, row_indices, col_indices, values)
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator over triplets (i, j, v).
|
/// An iterator over triplets (i, j, v).
|
||||||
// TODO: Consider giving the iterator a concrete type instead of impl trait...?
|
// TODO: Consider giving the iterator a concrete type instead of impl trait...?
|
||||||
pub fn triplet_iter(&self) -> impl Iterator<Item = (usize, usize, &T)> {
|
pub fn triplet_iter(&self) -> impl Iterator<Item = (usize, usize, &T)> {
|
||||||
|
@ -170,6 +189,16 @@ impl<T> CooMatrix<T> {
|
||||||
.map(|((i, j), v)| (*i, *j, v))
|
.map(|((i, j), v)| (*i, *j, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A mutable iterator over triplets (i, j, v).
|
||||||
|
// TODO: Consider giving the iterator a concrete type instead of impl trait...?
|
||||||
|
pub fn triplet_iter_mut(&mut self) -> impl Iterator<Item = (usize, usize, &mut T)> {
|
||||||
|
self.row_indices
|
||||||
|
.iter()
|
||||||
|
.zip(&self.col_indices)
|
||||||
|
.zip(self.values.iter_mut())
|
||||||
|
.map(|((i, j), v)| (*i, *j, v))
|
||||||
|
}
|
||||||
|
|
||||||
/// Reserves capacity for COO matrix by at least `additional` elements.
|
/// Reserves capacity for COO matrix by at least `additional` elements.
|
||||||
///
|
///
|
||||||
/// This increase the capacities of triplet holding arrays by reserving more space to avoid
|
/// This increase the capacities of triplet holding arrays by reserving more space to avoid
|
||||||
|
@ -211,6 +240,13 @@ impl<T> CooMatrix<T> {
|
||||||
self.values.push(v);
|
self.values.push(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clear all triplets from the matrix.
|
||||||
|
pub fn clear_triplets(&mut self) {
|
||||||
|
self.col_indices.clear();
|
||||||
|
self.row_indices.clear();
|
||||||
|
self.values.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/// The number of rows in the matrix.
|
/// The number of rows in the matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::mem::replace;
|
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use num_traits::One;
|
use num_traits::One;
|
||||||
|
@ -226,6 +225,15 @@ impl<T> CsMatrix<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Default for CsMatrix<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
sparsity_pattern: Default::default(),
|
||||||
|
values: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Scalar + One> CsMatrix<T> {
|
impl<T: Scalar + One> CsMatrix<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn identity(n: usize) -> Self {
|
pub fn identity(n: usize) -> Self {
|
||||||
|
@ -360,7 +368,7 @@ where
|
||||||
if let Some(minor_indices) = lane {
|
if let Some(minor_indices) = lane {
|
||||||
let count = minor_indices.len();
|
let count = minor_indices.len();
|
||||||
|
|
||||||
let remaining = replace(&mut self.remaining_values, &mut []);
|
let remaining = std::mem::take(&mut self.remaining_values);
|
||||||
let (values_in_lane, remaining) = remaining.split_at_mut(count);
|
let (values_in_lane, remaining) = remaining.split_at_mut(count);
|
||||||
self.remaining_values = remaining;
|
self.remaining_values = remaining;
|
||||||
self.current_lane_idx += 1;
|
self.current_lane_idx += 1;
|
||||||
|
@ -494,7 +502,7 @@ where
|
||||||
assert_eq!(source_minor_indices.len(), values.len());
|
assert_eq!(source_minor_indices.len(), values.len());
|
||||||
let nnz = values.len();
|
let nnz = values.len();
|
||||||
|
|
||||||
// Count the number of occurences of each minor index
|
// Count the number of occurrences of each minor index
|
||||||
let mut minor_counts = vec![0; minor_dim];
|
let mut minor_counts = vec![0; minor_dim];
|
||||||
for minor_idx in source_minor_indices {
|
for minor_idx in source_minor_indices {
|
||||||
minor_counts[*minor_idx] += 1;
|
minor_counts[*minor_idx] += 1;
|
||||||
|
@ -569,7 +577,7 @@ where
|
||||||
} else if sort {
|
} else if sort {
|
||||||
unreachable!("Internal error: Sorting currently not supported if no values are present.");
|
unreachable!("Internal error: Sorting currently not supported if no values are present.");
|
||||||
}
|
}
|
||||||
if major_offsets.len() == 0 {
|
if major_offsets.is_empty() {
|
||||||
return Err(SparseFormatError::from_kind_and_msg(
|
return Err(SparseFormatError::from_kind_and_msg(
|
||||||
SparseFormatErrorKind::InvalidStructure,
|
SparseFormatErrorKind::InvalidStructure,
|
||||||
"Number of offsets should be greater than 0.",
|
"Number of offsets should be greater than 0.",
|
||||||
|
@ -615,12 +623,12 @@ where
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let minor_idx_in_lane = minor_indices.get(range_start..range_end).ok_or(
|
let minor_idx_in_lane = minor_indices.get(range_start..range_end).ok_or_else(|| {
|
||||||
SparseFormatError::from_kind_and_msg(
|
SparseFormatError::from_kind_and_msg(
|
||||||
SparseFormatErrorKind::IndexOutOfBounds,
|
SparseFormatErrorKind::IndexOutOfBounds,
|
||||||
"A major offset is out of bounds.",
|
"A major offset is out of bounds.",
|
||||||
),
|
)
|
||||||
)?;
|
})?;
|
||||||
|
|
||||||
// We test for in-bounds, uniqueness and monotonicity at the same time
|
// We test for in-bounds, uniqueness and monotonicity at the same time
|
||||||
// to ensure that we only visit each minor index once
|
// to ensure that we only visit each minor index once
|
||||||
|
@ -653,9 +661,9 @@ where
|
||||||
if !monotonic && sort {
|
if !monotonic && sort {
|
||||||
let range_size = range_end - range_start;
|
let range_size = range_end - range_start;
|
||||||
minor_index_permutation.resize(range_size, 0);
|
minor_index_permutation.resize(range_size, 0);
|
||||||
compute_sort_permutation(&mut minor_index_permutation, &minor_idx_in_lane);
|
compute_sort_permutation(&mut minor_index_permutation, minor_idx_in_lane);
|
||||||
minor_idx_buffer.clear();
|
minor_idx_buffer.clear();
|
||||||
minor_idx_buffer.extend_from_slice(&minor_idx_in_lane);
|
minor_idx_buffer.extend_from_slice(minor_idx_in_lane);
|
||||||
apply_permutation(
|
apply_permutation(
|
||||||
&mut minor_indices[range_start..range_end],
|
&mut minor_indices[range_start..range_end],
|
||||||
&minor_idx_buffer,
|
&minor_idx_buffer,
|
||||||
|
|
|
@ -24,6 +24,7 @@ use std::slice::{Iter, IterMut};
|
||||||
/// # Usage
|
/// # Usage
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
/// use nalgebra_sparse::coo::CooMatrix;
|
||||||
/// use nalgebra_sparse::csc::CscMatrix;
|
/// use nalgebra_sparse::csc::CscMatrix;
|
||||||
/// use nalgebra::{DMatrix, Matrix3x4};
|
/// use nalgebra::{DMatrix, Matrix3x4};
|
||||||
/// use matrixcompare::assert_matrix_eq;
|
/// use matrixcompare::assert_matrix_eq;
|
||||||
|
@ -32,8 +33,9 @@ use std::slice::{Iter, IterMut};
|
||||||
/// // change the sparsity pattern of the matrix after it has been constructed. The easiest
|
/// // change the sparsity pattern of the matrix after it has been constructed. The easiest
|
||||||
/// // way to construct a CSC matrix is to first incrementally construct a COO matrix,
|
/// // way to construct a CSC matrix is to first incrementally construct a COO matrix,
|
||||||
/// // and then convert it to CSC.
|
/// // and then convert it to CSC.
|
||||||
/// # use nalgebra_sparse::coo::CooMatrix;
|
///
|
||||||
/// # let coo = CooMatrix::<f64>::new(3, 3);
|
/// let mut coo = CooMatrix::<f64>::new(3, 3);
|
||||||
|
/// coo.push(2, 0, 1.0);
|
||||||
/// let csc = CscMatrix::from(&coo);
|
/// let csc = CscMatrix::from(&coo);
|
||||||
///
|
///
|
||||||
/// // Alternatively, a CSC matrix can be constructed directly from raw CSC data.
|
/// // Alternatively, a CSC matrix can be constructed directly from raw CSC data.
|
||||||
|
@ -156,7 +158,7 @@ impl<T> CscMatrix<T> {
|
||||||
/// an error is returned to indicate the failure.
|
/// an error is returned to indicate the failure.
|
||||||
///
|
///
|
||||||
/// An error is returned if the data given does not conform to the CSC storage format.
|
/// An error is returned if the data given does not conform to the CSC storage format.
|
||||||
/// See the documentation for [CscMatrix](struct.CscMatrix.html) for more information.
|
/// See the documentation for [`CscMatrix`] for more information.
|
||||||
pub fn try_from_csc_data(
|
pub fn try_from_csc_data(
|
||||||
num_rows: usize,
|
num_rows: usize,
|
||||||
num_cols: usize,
|
num_cols: usize,
|
||||||
|
@ -182,7 +184,7 @@ impl<T> CscMatrix<T> {
|
||||||
///
|
///
|
||||||
/// An error is returned if the data given does not conform to the CSC storage format
|
/// An error is returned if the data given does not conform to the CSC storage format
|
||||||
/// with the exception of having unsorted row indices and values.
|
/// with the exception of having unsorted row indices and values.
|
||||||
/// See the documentation for [CscMatrix](struct.CscMatrix.html) for more information.
|
/// See the documentation for [`CscMatrix`] for more information.
|
||||||
pub fn try_from_unsorted_csc_data(
|
pub fn try_from_unsorted_csc_data(
|
||||||
num_rows: usize,
|
num_rows: usize,
|
||||||
num_cols: usize,
|
num_cols: usize,
|
||||||
|
@ -572,6 +574,14 @@ impl<T> CscMatrix<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Default for CscMatrix<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
cs: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert pattern format errors into more meaningful CSC-specific errors.
|
/// Convert pattern format errors into more meaningful CSC-specific errors.
|
||||||
///
|
///
|
||||||
/// This ensures that the terminology is consistent: we are talking about rows and columns,
|
/// This ensures that the terminology is consistent: we are talking about rows and columns,
|
||||||
|
@ -615,6 +625,15 @@ pub struct CscTripletIter<'a, T> {
|
||||||
values_iter: Iter<'a, T>,
|
values_iter: Iter<'a, T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Clone for CscTripletIter<'a, T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
CscTripletIter {
|
||||||
|
pattern_iter: self.pattern_iter.clone(),
|
||||||
|
values_iter: self.values_iter.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T: Clone> CscTripletIter<'a, T> {
|
impl<'a, T: Clone> CscTripletIter<'a, T> {
|
||||||
/// Adapts the triplet iterator to return owned values.
|
/// Adapts the triplet iterator to return owned values.
|
||||||
///
|
///
|
||||||
|
@ -746,7 +765,7 @@ impl<'a, T> CscColMut<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Column iterator for [CscMatrix](struct.CscMatrix.html).
|
/// Column iterator for [`CscMatrix`].
|
||||||
pub struct CscColIter<'a, T> {
|
pub struct CscColIter<'a, T> {
|
||||||
lane_iter: CsLaneIter<'a, T>,
|
lane_iter: CsLaneIter<'a, T>,
|
||||||
}
|
}
|
||||||
|
@ -759,7 +778,7 @@ impl<'a, T> Iterator for CscColIter<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mutable column iterator for [CscMatrix](struct.CscMatrix.html).
|
/// Mutable column iterator for [`CscMatrix`].
|
||||||
pub struct CscColIterMut<'a, T> {
|
pub struct CscColIterMut<'a, T> {
|
||||||
lane_iter: CsLaneIterMut<'a, T>,
|
lane_iter: CsLaneIterMut<'a, T>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ use std::slice::{Iter, IterMut};
|
||||||
/// # Usage
|
/// # Usage
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
/// use nalgebra_sparse::coo::CooMatrix;
|
||||||
/// use nalgebra_sparse::csr::CsrMatrix;
|
/// use nalgebra_sparse::csr::CsrMatrix;
|
||||||
/// use nalgebra::{DMatrix, Matrix3x4};
|
/// use nalgebra::{DMatrix, Matrix3x4};
|
||||||
/// use matrixcompare::assert_matrix_eq;
|
/// use matrixcompare::assert_matrix_eq;
|
||||||
|
@ -33,8 +34,9 @@ use std::slice::{Iter, IterMut};
|
||||||
/// // change the sparsity pattern of the matrix after it has been constructed. The easiest
|
/// // change the sparsity pattern of the matrix after it has been constructed. The easiest
|
||||||
/// // way to construct a CSR matrix is to first incrementally construct a COO matrix,
|
/// // way to construct a CSR matrix is to first incrementally construct a COO matrix,
|
||||||
/// // and then convert it to CSR.
|
/// // and then convert it to CSR.
|
||||||
/// # use nalgebra_sparse::coo::CooMatrix;
|
///
|
||||||
/// # let coo = CooMatrix::<f64>::new(3, 3);
|
/// let mut coo = CooMatrix::<f64>::new(3, 3);
|
||||||
|
/// coo.push(2, 0, 1.0);
|
||||||
/// let csr = CsrMatrix::from(&coo);
|
/// let csr = CsrMatrix::from(&coo);
|
||||||
///
|
///
|
||||||
/// // Alternatively, a CSR matrix can be constructed directly from raw CSR data.
|
/// // Alternatively, a CSR matrix can be constructed directly from raw CSR data.
|
||||||
|
@ -157,7 +159,7 @@ impl<T> CsrMatrix<T> {
|
||||||
/// an error is returned to indicate the failure.
|
/// an error is returned to indicate the failure.
|
||||||
///
|
///
|
||||||
/// An error is returned if the data given does not conform to the CSR storage format.
|
/// An error is returned if the data given does not conform to the CSR storage format.
|
||||||
/// See the documentation for [CsrMatrix](struct.CsrMatrix.html) for more information.
|
/// See the documentation for [`CsrMatrix`] for more information.
|
||||||
pub fn try_from_csr_data(
|
pub fn try_from_csr_data(
|
||||||
num_rows: usize,
|
num_rows: usize,
|
||||||
num_cols: usize,
|
num_cols: usize,
|
||||||
|
@ -183,7 +185,7 @@ impl<T> CsrMatrix<T> {
|
||||||
///
|
///
|
||||||
/// An error is returned if the data given does not conform to the CSR storage format
|
/// An error is returned if the data given does not conform to the CSR storage format
|
||||||
/// with the exception of having unsorted column indices and values.
|
/// with the exception of having unsorted column indices and values.
|
||||||
/// See the documentation for [CsrMatrix](struct.CsrMatrix.html) for more information.
|
/// See the documentation for [`CsrMatrix`] for more information.
|
||||||
pub fn try_from_unsorted_csr_data(
|
pub fn try_from_unsorted_csr_data(
|
||||||
num_rows: usize,
|
num_rows: usize,
|
||||||
num_cols: usize,
|
num_cols: usize,
|
||||||
|
@ -573,6 +575,14 @@ impl<T> CsrMatrix<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Default for CsrMatrix<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
cs: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert pattern format errors into more meaningful CSR-specific errors.
|
/// Convert pattern format errors into more meaningful CSR-specific errors.
|
||||||
///
|
///
|
||||||
/// This ensures that the terminology is consistent: we are talking about rows and columns,
|
/// This ensures that the terminology is consistent: we are talking about rows and columns,
|
||||||
|
@ -616,6 +626,15 @@ pub struct CsrTripletIter<'a, T> {
|
||||||
values_iter: Iter<'a, T>,
|
values_iter: Iter<'a, T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Clone for CsrTripletIter<'a, T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
CsrTripletIter {
|
||||||
|
pattern_iter: self.pattern_iter.clone(),
|
||||||
|
values_iter: self.values_iter.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T: Clone> CsrTripletIter<'a, T> {
|
impl<'a, T: Clone> CsrTripletIter<'a, T> {
|
||||||
/// Adapts the triplet iterator to return owned values.
|
/// Adapts the triplet iterator to return owned values.
|
||||||
///
|
///
|
||||||
|
@ -751,7 +770,7 @@ impl<'a, T> CsrRowMut<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Row iterator for [CsrMatrix](struct.CsrMatrix.html).
|
/// Row iterator for [`CsrMatrix`].
|
||||||
pub struct CsrRowIter<'a, T> {
|
pub struct CsrRowIter<'a, T> {
|
||||||
lane_iter: CsLaneIter<'a, T>,
|
lane_iter: CsLaneIter<'a, T>,
|
||||||
}
|
}
|
||||||
|
@ -764,7 +783,7 @@ impl<'a, T> Iterator for CsrRowIter<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mutable row iterator for [CsrMatrix](struct.CsrMatrix.html).
|
/// Mutable row iterator for [`CsrMatrix`].
|
||||||
pub struct CsrRowIterMut<'a, T> {
|
pub struct CsrRowIterMut<'a, T> {
|
||||||
lane_iter: CsLaneIterMut<'a, T>,
|
lane_iter: CsLaneIterMut<'a, T>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::ops::serial::spsolve_csc_lower_triangular;
|
||||||
use crate::ops::Op;
|
use crate::ops::Op;
|
||||||
use crate::pattern::SparsityPattern;
|
use crate::pattern::SparsityPattern;
|
||||||
use core::{iter, mem};
|
use core::{iter, mem};
|
||||||
use nalgebra::{DMatrix, DMatrixSlice, DMatrixSliceMut, RealField};
|
use nalgebra::{DMatrix, DMatrixView, DMatrixViewMut, RealField};
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
/// A symbolic sparse Cholesky factorization of a CSC matrix.
|
/// A symbolic sparse Cholesky factorization of a CSC matrix.
|
||||||
|
@ -264,7 +264,7 @@ impl<T: RealField> CscCholesky<T> {
|
||||||
///
|
///
|
||||||
/// Panics if `B` is not square.
|
/// Panics if `B` is not square.
|
||||||
#[must_use = "Did you mean to use solve_mut()?"]
|
#[must_use = "Did you mean to use solve_mut()?"]
|
||||||
pub fn solve<'a>(&'a self, b: impl Into<DMatrixSlice<'a, T>>) -> DMatrix<T> {
|
pub fn solve<'a>(&'a self, b: impl Into<DMatrixView<'a, T>>) -> DMatrix<T> {
|
||||||
let b = b.into();
|
let b = b.into();
|
||||||
let mut output = b.clone_owned();
|
let mut output = b.clone_owned();
|
||||||
self.solve_mut(&mut output);
|
self.solve_mut(&mut output);
|
||||||
|
@ -278,7 +278,7 @@ impl<T: RealField> CscCholesky<T> {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if `b` is not square.
|
/// Panics if `b` is not square.
|
||||||
pub fn solve_mut<'a>(&'a self, b: impl Into<DMatrixSliceMut<'a, T>>) {
|
pub fn solve_mut<'a>(&'a self, b: impl Into<DMatrixViewMut<'a, T>>) {
|
||||||
let expect_msg = "If the Cholesky factorization succeeded,\
|
let expect_msg = "If the Cholesky factorization succeeded,\
|
||||||
then the triangular solve should never fail";
|
then the triangular solve should never fail";
|
||||||
// Solve LY = B
|
// Solve LY = B
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
//! Implementation of matrix market io code.
|
//! Implementation of matrix market io code.
|
||||||
//!
|
//!
|
||||||
//! See the [website](https://math.nist.gov/MatrixMarket/formats.html) or the [paper](https://www.researchgate.net/publication/2630533_The_Matrix_Market_Exchange_Formats_Initial_Design) for more details about matrix market.
|
//! See the [website](https://math.nist.gov/MatrixMarket/formats.html) or the [paper](https://www.researchgate.net/publication/2630533_The_Matrix_Market_Exchange_Formats_Initial_Design) for more details about matrix market.
|
||||||
use crate::coo::CooMatrix;
|
|
||||||
use crate::SparseFormatError;
|
use crate::SparseFormatError;
|
||||||
use crate::SparseFormatErrorKind;
|
use crate::SparseFormatErrorKind;
|
||||||
|
use crate::{CooMatrix, CscMatrix, CsrMatrix};
|
||||||
use nalgebra::Complex;
|
use nalgebra::Complex;
|
||||||
use pest::iterators::Pairs;
|
use pest::iterators::Pairs;
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
|
@ -12,7 +12,8 @@ use std::convert::Infallible;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Formatter;
|
use std::fmt::Formatter;
|
||||||
use std::fs;
|
use std::fs::{self, File};
|
||||||
|
use std::io::{BufWriter, Write};
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
use std::num::TryFromIntError;
|
use std::num::TryFromIntError;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
@ -267,7 +268,7 @@ impl fmt::Display for MatrixMarketError {
|
||||||
write!(f, "InvalidHeader,")?;
|
write!(f, "InvalidHeader,")?;
|
||||||
}
|
}
|
||||||
MatrixMarketErrorKind::EntryMismatch => {
|
MatrixMarketErrorKind::EntryMismatch => {
|
||||||
write!(f, "EntryNumUnmatched,")?;
|
write!(f, "EntryMismatch,")?;
|
||||||
}
|
}
|
||||||
MatrixMarketErrorKind::TypeMismatch => {
|
MatrixMarketErrorKind::TypeMismatch => {
|
||||||
write!(f, "TypeMismatch,")?;
|
write!(f, "TypeMismatch,")?;
|
||||||
|
@ -288,7 +289,7 @@ impl fmt::Display for MatrixMarketError {
|
||||||
write!(f, "NotLowerTriangle,")?;
|
write!(f, "NotLowerTriangle,")?;
|
||||||
}
|
}
|
||||||
MatrixMarketErrorKind::NonSquare => {
|
MatrixMarketErrorKind::NonSquare => {
|
||||||
write!(f, "NotSquareMatrix,")?;
|
write!(f, "NonSquare,")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write!(f, " message: {}", self.message)
|
write!(f, " message: {}", self.message)
|
||||||
|
@ -506,6 +507,21 @@ mod internal {
|
||||||
fn negative(self) -> Result<Self, MatrixMarketError>;
|
fn negative(self) -> Result<Self, MatrixMarketError>;
|
||||||
/// When matrix is a Hermitian matrix, it will convert itself to its conjugate.
|
/// When matrix is a Hermitian matrix, it will convert itself to its conjugate.
|
||||||
fn conjugate(self) -> Result<Self, MatrixMarketError>;
|
fn conjugate(self) -> Result<Self, MatrixMarketError>;
|
||||||
|
/// Returns the name of SupportedMatrixMarketScalar, used when write the matrix
|
||||||
|
fn typename() -> &'static str;
|
||||||
|
/// Write the data self to w
|
||||||
|
fn write_matrix_market<W: std::fmt::Write>(&self, w: W) -> Result<(), std::fmt::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SupportedMatrixMarketExport<T: SupportedMatrixMarketScalar> {
|
||||||
|
/// iterate over triplets
|
||||||
|
fn triplet_iter(&self) -> Box<dyn Iterator<Item = (usize, usize, &T)> + '_>;
|
||||||
|
/// number of rows
|
||||||
|
fn nrows(&self) -> usize;
|
||||||
|
/// number of columns
|
||||||
|
fn ncols(&self) -> usize;
|
||||||
|
/// number of non-zeros
|
||||||
|
fn nnz(&self) -> usize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,6 +573,17 @@ macro_rules! mm_int_impl {
|
||||||
fn negative(self) -> Result<Self, MatrixMarketError> {
|
fn negative(self) -> Result<Self, MatrixMarketError> {
|
||||||
Ok(-self)
|
Ok(-self)
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
fn typename() -> &'static str {
|
||||||
|
"integer"
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn write_matrix_market<W: std::fmt::Write>(
|
||||||
|
&self,
|
||||||
|
mut w: W,
|
||||||
|
) -> Result<(), std::fmt::Error> {
|
||||||
|
write!(w, "{}", self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -602,6 +629,17 @@ macro_rules! mm_real_impl {
|
||||||
fn negative(self) -> Result<Self, MatrixMarketError> {
|
fn negative(self) -> Result<Self, MatrixMarketError> {
|
||||||
Ok(-self)
|
Ok(-self)
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
fn typename() -> &'static str {
|
||||||
|
"real"
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn write_matrix_market<W: std::fmt::Write>(
|
||||||
|
&self,
|
||||||
|
mut w: W,
|
||||||
|
) -> Result<(), std::fmt::Error> {
|
||||||
|
write!(w, "{}", self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -648,6 +686,17 @@ macro_rules! mm_complex_impl {
|
||||||
fn negative(self) -> Result<Self, MatrixMarketError> {
|
fn negative(self) -> Result<Self, MatrixMarketError> {
|
||||||
Ok(-self)
|
Ok(-self)
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
fn typename() -> &'static str {
|
||||||
|
"complex"
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn write_matrix_market<W: std::fmt::Write>(
|
||||||
|
&self,
|
||||||
|
mut w: W,
|
||||||
|
) -> Result<(), std::fmt::Error> {
|
||||||
|
write!(w, "{} {}", self.re, self.im)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -697,6 +746,17 @@ macro_rules! mm_pattern_impl {
|
||||||
format!("Pattern type has no negative"),
|
format!("Pattern type has no negative"),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
fn typename() -> &'static str {
|
||||||
|
"pattern"
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn write_matrix_market<W: std::fmt::Write>(
|
||||||
|
&self,
|
||||||
|
mut _w: W,
|
||||||
|
) -> Result<(), std::fmt::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -715,6 +775,46 @@ mm_complex_impl!(f64);
|
||||||
|
|
||||||
mm_pattern_impl!(());
|
mm_pattern_impl!(());
|
||||||
|
|
||||||
|
/// A marker trait for sparse matrix types that can be exported to the matrix market format.
|
||||||
|
///
|
||||||
|
/// This is a sealed trait; it cannot be implemented by external crates. This is done in order to prevent leaking
|
||||||
|
/// some of the implementation details we currently rely on. We may relax this restriction in the future.
|
||||||
|
pub trait MatrixMarketExport<T: MatrixMarketScalar>:
|
||||||
|
internal::SupportedMatrixMarketExport<T>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! mm_matrix_impl {
|
||||||
|
($T_MATRIX:ty) => {
|
||||||
|
impl<T: MatrixMarketScalar> MatrixMarketExport<T> for $T_MATRIX {}
|
||||||
|
|
||||||
|
impl<T: internal::SupportedMatrixMarketScalar> internal::SupportedMatrixMarketExport<T>
|
||||||
|
for $T_MATRIX
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn triplet_iter(&self) -> Box<dyn Iterator<Item = (usize, usize, &T)> + '_> {
|
||||||
|
Box::new(self.triplet_iter())
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn nrows(&self) -> usize {
|
||||||
|
self.nrows()
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn ncols(&self) -> usize {
|
||||||
|
self.ncols()
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn nnz(&self) -> usize {
|
||||||
|
self.nnz()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_matrix_impl!(CooMatrix<T>);
|
||||||
|
mm_matrix_impl!(CsrMatrix<T>);
|
||||||
|
mm_matrix_impl!(CscMatrix<T>);
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[grammar = "io/matrix_market.pest"]
|
#[grammar = "io/matrix_market.pest"]
|
||||||
struct MatrixMarketParser;
|
struct MatrixMarketParser;
|
||||||
|
@ -1329,3 +1429,123 @@ fn next_dense_coordinate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Save a sparse matrix as a Matrix Market format string.
|
||||||
|
///
|
||||||
|
/// The exporter only writes the matrix into `coordinate` and `general` format.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// Examples
|
||||||
|
/// --------
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra_sparse::CooMatrix;
|
||||||
|
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
/// use nalgebra_sparse::io::{save_to_matrix_market_str};
|
||||||
|
/// let expected_str = r#"%%matrixmarket matrix coordinate integer general
|
||||||
|
/// % matrixmarket file generated by nalgebra-sparse.
|
||||||
|
/// 5 4 2
|
||||||
|
/// 1 1 10
|
||||||
|
/// 2 3 5
|
||||||
|
/// "#;
|
||||||
|
/// let row_indices = vec![0,1];
|
||||||
|
/// let col_indices = vec![0,2];
|
||||||
|
/// let values = vec![10,5];
|
||||||
|
/// let matrix = CooMatrix::try_from_triplets(5,4,row_indices,col_indices,values)?;
|
||||||
|
/// let generated_matrixmarket_str = save_to_matrix_market_str(&matrix);
|
||||||
|
/// assert_eq!(expected_str,generated_matrixmarket_str);
|
||||||
|
/// # Ok(()) }
|
||||||
|
/// ```
|
||||||
|
pub fn save_to_matrix_market_str<T, S>(sparse_matrix: &S) -> String
|
||||||
|
where
|
||||||
|
T: MatrixMarketScalar,
|
||||||
|
S: MatrixMarketExport<T>,
|
||||||
|
{
|
||||||
|
let mut bytes = Vec::<u8>::new();
|
||||||
|
// This will call impl<A: Allocator> Write for Vec<u8, A>
|
||||||
|
// The vector will grow as needed.
|
||||||
|
// So, unwrap here won't cause any issue.
|
||||||
|
save_to_matrix_market(&mut bytes, sparse_matrix).unwrap();
|
||||||
|
|
||||||
|
String::from_utf8(bytes)
|
||||||
|
.expect("Unexpected non UTF-8 data was generated when export to matrix market string")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Save a sparse matrix to a Matrix Market format file.
|
||||||
|
///
|
||||||
|
/// The exporter only saves the matrix with the `coordinate` and `general` matrix market formats.
|
||||||
|
///
|
||||||
|
/// Errors
|
||||||
|
/// --------
|
||||||
|
///
|
||||||
|
/// See [MatrixMarketErrorKind] for a list of possible error conditions.
|
||||||
|
///
|
||||||
|
/// Examples
|
||||||
|
/// --------
|
||||||
|
/// ```no_run
|
||||||
|
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
/// use nalgebra_sparse::io::{save_to_matrix_market_file,load_coo_from_matrix_market_str};
|
||||||
|
/// let str = r#"
|
||||||
|
/// %%matrixmarket matrix coordinate integer general
|
||||||
|
/// 5 4 2
|
||||||
|
/// 1 1 10
|
||||||
|
/// 2 3 5
|
||||||
|
/// "#;
|
||||||
|
/// let matrix = load_coo_from_matrix_market_str::<i32>(&str)?;
|
||||||
|
/// save_to_matrix_market_file(&matrix,"path/to/matrix.mtx")?;
|
||||||
|
/// # Ok(()) }
|
||||||
|
/// ```
|
||||||
|
pub fn save_to_matrix_market_file<T, S, P>(sparse_matrix: &S, path: P) -> Result<(), std::io::Error>
|
||||||
|
where
|
||||||
|
T: MatrixMarketScalar,
|
||||||
|
S: MatrixMarketExport<T>,
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let file = File::create(path)?;
|
||||||
|
let mut file = BufWriter::new(file);
|
||||||
|
save_to_matrix_market(&mut file, sparse_matrix)?;
|
||||||
|
// Quote from BufWriter doc.
|
||||||
|
// > It is critical to call flush before BufWriter<W> is dropped. Though dropping will attempt to flush the contents of the buffer, any errors that happen in the process of dropping will be ignored. Calling flush ensures that the buffer is empty and thus dropping will not even attempt file operations.
|
||||||
|
file.flush()
|
||||||
|
.expect("Unexpected error when flushing the buffer data to File");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Save a sparse matrix to an [std::io::Write] instance.
|
||||||
|
///
|
||||||
|
/// This is the most general save functionality. See [save_to_matrix_market_file] and
|
||||||
|
/// [save_to_matrix_market_str] for higher-level functionality.
|
||||||
|
pub fn save_to_matrix_market<T, S, W>(mut w: W, sparse_matrix: &S) -> Result<(), std::io::Error>
|
||||||
|
where
|
||||||
|
T: MatrixMarketScalar,
|
||||||
|
S: MatrixMarketExport<T>,
|
||||||
|
W: Write,
|
||||||
|
{
|
||||||
|
// write header
|
||||||
|
writeln!(
|
||||||
|
w,
|
||||||
|
"%%matrixmarket matrix coordinate {} general",
|
||||||
|
T::typename()
|
||||||
|
)?;
|
||||||
|
|
||||||
|
//write comment
|
||||||
|
writeln!(w, "% matrixmarket file generated by nalgebra-sparse.")?;
|
||||||
|
|
||||||
|
// write shape information
|
||||||
|
writeln!(
|
||||||
|
w,
|
||||||
|
"{} {} {}",
|
||||||
|
sparse_matrix.nrows(),
|
||||||
|
sparse_matrix.ncols(),
|
||||||
|
sparse_matrix.nnz()
|
||||||
|
)?;
|
||||||
|
|
||||||
|
//write triplets
|
||||||
|
let mut buffer = String::new();
|
||||||
|
for (r, c, d) in sparse_matrix.triplet_iter() {
|
||||||
|
buffer.clear();
|
||||||
|
d.write_matrix_market(&mut buffer)
|
||||||
|
.expect("Unexpected format error was generated when write to String");
|
||||||
|
writeln!(w, "{} {} {}", r + 1, c + 1, buffer)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
//!
|
//!
|
||||||
//! | Format | Import | Export |
|
//! | Format | Import | Export |
|
||||||
//! | ------------------------------------------------|------------|------------|
|
//! | ------------------------------------------------|------------|------------|
|
||||||
//! | [Matrix market](#matrix-market-format) | Yes | No |
|
//! | [Matrix market](#matrix-market-format) | Yes | Yes |
|
||||||
//!
|
//!
|
||||||
//! [Matrix market]: https://math.nist.gov/MatrixMarket/formats.html
|
//! [Matrix market]: https://math.nist.gov/MatrixMarket/formats.html
|
||||||
//!
|
//!
|
||||||
|
@ -19,10 +19,12 @@
|
||||||
//! which also uses the Matrix Market file format.
|
//! which also uses the Matrix Market file format.
|
||||||
//!
|
//!
|
||||||
//! We currently offer functionality for importing a Matrix market file to an instance of a
|
//! We currently offer functionality for importing a Matrix market file to an instance of a
|
||||||
//! [CooMatrix](crate::CooMatrix) through the function [load_coo_from_matrix_market_file]. It is also possible to load
|
//! [CooMatrix](crate::CooMatrix) through the function [load_coo_from_matrix_market_file],
|
||||||
//! a matrix stored in the matrix market format with the function [load_coo_from_matrix_market_str].
|
//! as well as functionality for writing various sparse matrices to the matrix market format
|
||||||
//!
|
//! through [save_to_matrix_market_file]. It is also possible to load
|
||||||
//! Export is currently not implemented, but [planned](https://github.com/dimforge/nalgebra/issues/1037).
|
//! a matrix stored as a string in the matrix market format with the function
|
||||||
|
//! [load_coo_from_matrix_market_str], or similarly write to a string with
|
||||||
|
//! [save_to_matrix_market_str].
|
||||||
//!
|
//!
|
||||||
//! Our implementation is based on the [format description](https://math.nist.gov/MatrixMarket/formats.html)
|
//! Our implementation is based on the [format description](https://math.nist.gov/MatrixMarket/formats.html)
|
||||||
//! on the Matrix Market website and the
|
//! on the Matrix Market website and the
|
||||||
|
@ -32,7 +34,8 @@
|
||||||
//! > "*The Matrix Market Exchange Formats: Initial Design.*" (1996).
|
//! > "*The Matrix Market Exchange Formats: Initial Design.*" (1996).
|
||||||
|
|
||||||
pub use self::matrix_market::{
|
pub use self::matrix_market::{
|
||||||
load_coo_from_matrix_market_file, load_coo_from_matrix_market_str, MatrixMarketError,
|
load_coo_from_matrix_market_file, load_coo_from_matrix_market_str, save_to_matrix_market,
|
||||||
MatrixMarketErrorKind, MatrixMarketScalar,
|
save_to_matrix_market_file, save_to_matrix_market_str, MatrixMarketError,
|
||||||
|
MatrixMarketErrorKind, MatrixMarketExport, MatrixMarketScalar,
|
||||||
};
|
};
|
||||||
mod matrix_market;
|
mod matrix_market;
|
||||||
|
|
|
@ -143,8 +143,6 @@
|
||||||
)]
|
)]
|
||||||
|
|
||||||
pub extern crate nalgebra as na;
|
pub extern crate nalgebra as na;
|
||||||
#[cfg(feature = "io")]
|
|
||||||
extern crate pest;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
#[cfg(feature = "io")]
|
#[cfg(feature = "io")]
|
||||||
extern crate pest_derive;
|
extern crate pest_derive;
|
||||||
|
@ -201,7 +199,7 @@ impl SparseFormatError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The type of format error described by a [SparseFormatError](struct.SparseFormatError.html).
|
/// The type of format error described by a [`SparseFormatError`].
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum SparseFormatErrorKind {
|
pub enum SparseFormatErrorKind {
|
||||||
|
|
|
@ -3,14 +3,14 @@ use crate::csr::CsrMatrix;
|
||||||
|
|
||||||
use crate::ops::serial::{
|
use crate::ops::serial::{
|
||||||
spadd_csc_prealloc, spadd_csr_prealloc, spadd_pattern, spmm_csc_dense, spmm_csc_pattern,
|
spadd_csc_prealloc, spadd_csr_prealloc, spadd_pattern, spmm_csc_dense, spmm_csc_pattern,
|
||||||
spmm_csc_prealloc, spmm_csr_dense, spmm_csr_pattern, spmm_csr_prealloc,
|
spmm_csc_prealloc_unchecked, spmm_csr_dense, spmm_csr_pattern, spmm_csr_prealloc_unchecked,
|
||||||
};
|
};
|
||||||
use crate::ops::Op;
|
use crate::ops::Op;
|
||||||
use nalgebra::allocator::Allocator;
|
use nalgebra::allocator::Allocator;
|
||||||
use nalgebra::base::storage::RawStorage;
|
use nalgebra::base::storage::RawStorage;
|
||||||
use nalgebra::constraint::{DimEq, ShapeConstraint};
|
use nalgebra::constraint::{DimEq, ShapeConstraint};
|
||||||
use nalgebra::{
|
use nalgebra::{
|
||||||
ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dynamic, Matrix, OMatrix,
|
ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dyn, Matrix, OMatrix,
|
||||||
Scalar, U1,
|
Scalar, U1,
|
||||||
};
|
};
|
||||||
use num_traits::{One, Zero};
|
use num_traits::{One, Zero};
|
||||||
|
@ -59,7 +59,7 @@ macro_rules! impl_sp_plus_minus {
|
||||||
let mut result = $matrix_type::try_from_pattern_and_values(pattern, values)
|
let mut result = $matrix_type::try_from_pattern_and_values(pattern, values)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
$spadd_fn(T::zero(), &mut result, T::one(), Op::NoOp(&a)).unwrap();
|
$spadd_fn(T::zero(), &mut result, T::one(), Op::NoOp(&a)).unwrap();
|
||||||
$spadd_fn(T::one(), &mut result, $factor * T::one(), Op::NoOp(&b)).unwrap();
|
$spadd_fn(T::one(), &mut result, $factor, Op::NoOp(&b)).unwrap();
|
||||||
result
|
result
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -112,9 +112,9 @@ macro_rules! impl_spmm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_spmm!(CsrMatrix, spmm_csr_pattern, spmm_csr_prealloc);
|
impl_spmm!(CsrMatrix, spmm_csr_pattern, spmm_csr_prealloc_unchecked);
|
||||||
// Need to switch order of operations for CSC pattern
|
// Need to switch order of operations for CSC pattern
|
||||||
impl_spmm!(CscMatrix, spmm_csc_pattern, spmm_csc_prealloc);
|
impl_spmm!(CscMatrix, spmm_csc_pattern, spmm_csc_prealloc_unchecked);
|
||||||
|
|
||||||
/// Implements Scalar * Matrix operations for *concrete* scalar types. The reason this is necessary
|
/// Implements Scalar * Matrix operations for *concrete* scalar types. The reason this is necessary
|
||||||
/// is that we are not able to implement Mul<Matrix<T>> for all T generically due to orphan rules.
|
/// is that we are not able to implement Mul<Matrix<T>> for all T generically due to orphan rules.
|
||||||
|
@ -273,8 +273,8 @@ macro_rules! impl_spmm_cs_dense {
|
||||||
// Implement ref-ref
|
// Implement ref-ref
|
||||||
impl_spmm_cs_dense!(&'a $matrix_type_name<T>, &'a Matrix<T, R, C, S>, $spmm_fn, |lhs, rhs| {
|
impl_spmm_cs_dense!(&'a $matrix_type_name<T>, &'a Matrix<T, R, C, S>, $spmm_fn, |lhs, rhs| {
|
||||||
let (_, ncols) = rhs.shape_generic();
|
let (_, ncols) = rhs.shape_generic();
|
||||||
let nrows = Dynamic::new(lhs.nrows());
|
let nrows = Dyn(lhs.nrows());
|
||||||
let mut result = OMatrix::<T, Dynamic, C>::zeros_generic(nrows, ncols);
|
let mut result = OMatrix::<T, Dyn, C>::zeros_generic(nrows, ncols);
|
||||||
$spmm_fn(T::zero(), &mut result, T::one(), Op::NoOp(lhs), Op::NoOp(rhs));
|
$spmm_fn(T::zero(), &mut result, T::one(), Op::NoOp(lhs), Op::NoOp(rhs));
|
||||||
result
|
result
|
||||||
});
|
});
|
||||||
|
@ -302,21 +302,21 @@ macro_rules! impl_spmm_cs_dense {
|
||||||
R: Dim,
|
R: Dim,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
S: RawStorage<T, R, C>,
|
S: RawStorage<T, R, C>,
|
||||||
DefaultAllocator: Allocator<T, Dynamic, C>,
|
DefaultAllocator: Allocator<T, Dyn, C>,
|
||||||
// TODO: Is it possible to simplify these bounds?
|
// TODO: Is it possible to simplify these bounds?
|
||||||
ShapeConstraint:
|
ShapeConstraint:
|
||||||
// Bounds so that we can turn OMatrix<T, Dynamic, C> into a DMatrixSliceMut
|
// Bounds so that we can turn OMatrix<T, Dyn, C> into a DMatrixSliceMut
|
||||||
DimEq<U1, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as RawStorage<T, Dynamic, C>>::RStride>
|
DimEq<U1, <<DefaultAllocator as Allocator<T, Dyn, C>>::Buffer as RawStorage<T, Dyn, C>>::RStride>
|
||||||
+ DimEq<C, Dynamic>
|
+ DimEq<C, Dyn>
|
||||||
+ DimEq<Dynamic, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as RawStorage<T, Dynamic, C>>::CStride>
|
+ DimEq<Dyn, <<DefaultAllocator as Allocator<T, Dyn, C>>::Buffer as RawStorage<T, Dyn, C>>::CStride>
|
||||||
// Bounds so that we can turn &Matrix<T, R, C, S> into a DMatrixSlice
|
// Bounds so that we can turn &Matrix<T, R, C, S> into a DMatrixSlice
|
||||||
+ DimEq<U1, S::RStride>
|
+ DimEq<U1, S::RStride>
|
||||||
+ DimEq<R, Dynamic>
|
+ DimEq<R, Dyn>
|
||||||
+ DimEq<Dynamic, S::CStride>
|
+ DimEq<Dyn, S::CStride>
|
||||||
{
|
{
|
||||||
// We need the column dimension to be generic, so that if RHS is a vector, then
|
// We need the column dimension to be generic, so that if RHS is a vector, then
|
||||||
// we also get a vector (and not a matrix)
|
// we also get a vector (and not a matrix)
|
||||||
type Output = OMatrix<T, Dynamic, C>;
|
type Output = OMatrix<T, Dyn, C>;
|
||||||
|
|
||||||
fn mul(self, rhs: $dense_matrix_type) -> Self::Output {
|
fn mul(self, rhs: $dense_matrix_type) -> Self::Output {
|
||||||
let $lhs = self;
|
let $lhs = self;
|
||||||
|
|
|
@ -149,8 +149,8 @@ impl<T> Op<T> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn as_ref(&self) -> Op<&T> {
|
pub fn as_ref(&self) -> Op<&T> {
|
||||||
match self {
|
match self {
|
||||||
Op::NoOp(obj) => Op::NoOp(&obj),
|
Op::NoOp(obj) => Op::NoOp(obj),
|
||||||
Op::Transpose(obj) => Op::Transpose(&obj),
|
Op::Transpose(obj) => Op::Transpose(obj),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::cs::CsMatrix;
|
||||||
use crate::ops::serial::{OperationError, OperationErrorKind};
|
use crate::ops::serial::{OperationError, OperationErrorKind};
|
||||||
use crate::ops::Op;
|
use crate::ops::Op;
|
||||||
use crate::SparseEntryMut;
|
use crate::SparseEntryMut;
|
||||||
use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, Scalar};
|
use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, Scalar};
|
||||||
use num_traits::{One, Zero};
|
use num_traits::{One, Zero};
|
||||||
|
|
||||||
fn spmm_cs_unexpected_entry() -> OperationError {
|
fn spmm_cs_unexpected_entry() -> OperationError {
|
||||||
|
@ -20,6 +20,51 @@ fn spmm_cs_unexpected_entry() -> OperationError {
|
||||||
/// reversed (since transpose(AB) = transpose(B) * transpose(A) and CSC(A) = transpose(CSR(A)).
|
/// reversed (since transpose(AB) = transpose(B) * transpose(A) and CSC(A) = transpose(CSR(A)).
|
||||||
///
|
///
|
||||||
/// We assume here that the matrices have already been verified to be dimensionally compatible.
|
/// We assume here that the matrices have already been verified to be dimensionally compatible.
|
||||||
|
pub fn spmm_cs_prealloc_unchecked<T>(
|
||||||
|
beta: T,
|
||||||
|
c: &mut CsMatrix<T>,
|
||||||
|
alpha: T,
|
||||||
|
a: &CsMatrix<T>,
|
||||||
|
b: &CsMatrix<T>,
|
||||||
|
) -> Result<(), OperationError>
|
||||||
|
where
|
||||||
|
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());
|
||||||
|
let some_val = Zero::zero();
|
||||||
|
let mut scratchpad_values: Vec<T> = vec![some_val; b.pattern().minor_dim()];
|
||||||
|
for i in 0..c.pattern().major_dim() {
|
||||||
|
let a_lane_i = a.get_lane(i).unwrap();
|
||||||
|
|
||||||
|
let mut c_lane_i = c.get_lane_mut(i).unwrap();
|
||||||
|
|
||||||
|
for (&k, a_ik) in a_lane_i.minor_indices().iter().zip(a_lane_i.values()) {
|
||||||
|
let b_lane_k = b.get_lane(k).unwrap();
|
||||||
|
let alpha_aik = alpha.clone() * a_ik.clone();
|
||||||
|
for (j, b_kj) in b_lane_k.minor_indices().iter().zip(b_lane_k.values()) {
|
||||||
|
// use a dense scatter vector to accumulate non-zeros quickly
|
||||||
|
unsafe {
|
||||||
|
*scratchpad_values.get_unchecked_mut(*j) += alpha_aik.clone() * b_kj.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get indices from C pattern and gather from the dense scratchpad_values
|
||||||
|
let (indices, values) = c_lane_i.indices_and_values_mut();
|
||||||
|
values
|
||||||
|
.iter_mut()
|
||||||
|
.zip(indices)
|
||||||
|
.for_each(|(output_ref, index)| unsafe {
|
||||||
|
*output_ref = beta.clone() * output_ref.clone()
|
||||||
|
+ scratchpad_values.get_unchecked(*index).clone();
|
||||||
|
*scratchpad_values.get_unchecked_mut(*index) = Zero::zero();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn spmm_cs_prealloc<T>(
|
pub fn spmm_cs_prealloc<T>(
|
||||||
beta: T,
|
beta: T,
|
||||||
c: &mut CsMatrix<T>,
|
c: &mut CsMatrix<T>,
|
||||||
|
@ -131,10 +176,10 @@ where
|
||||||
/// the transposed operation must be specified for the CSC matrix.
|
/// the transposed operation must be specified for the CSC matrix.
|
||||||
pub fn spmm_cs_dense<T>(
|
pub fn spmm_cs_dense<T>(
|
||||||
beta: T,
|
beta: T,
|
||||||
mut c: DMatrixSliceMut<'_, T>,
|
mut c: DMatrixViewMut<'_, T>,
|
||||||
alpha: T,
|
alpha: T,
|
||||||
a: Op<&CsMatrix<T>>,
|
a: Op<&CsMatrix<T>>,
|
||||||
b: Op<DMatrixSlice<'_, T>>,
|
b: Op<DMatrixView<'_, T>>,
|
||||||
) where
|
) where
|
||||||
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use crate::csc::CscMatrix;
|
use crate::csc::CscMatrix;
|
||||||
use crate::ops::serial::cs::{spadd_cs_prealloc, spmm_cs_dense, spmm_cs_prealloc};
|
use crate::ops::serial::cs::{
|
||||||
|
spadd_cs_prealloc, spmm_cs_dense, spmm_cs_prealloc, spmm_cs_prealloc_unchecked,
|
||||||
|
};
|
||||||
use crate::ops::serial::{OperationError, OperationErrorKind};
|
use crate::ops::serial::{OperationError, OperationErrorKind};
|
||||||
use crate::ops::Op;
|
use crate::ops::Op;
|
||||||
use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, RealField, Scalar};
|
use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, RealField, Scalar};
|
||||||
use num_traits::{One, Zero};
|
use num_traits::{One, Zero};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -14,10 +16,10 @@ use std::borrow::Cow;
|
||||||
/// Panics if the dimensions of the matrices involved are not compatible with the expression.
|
/// Panics if the dimensions of the matrices involved are not compatible with the expression.
|
||||||
pub fn spmm_csc_dense<'a, T>(
|
pub fn spmm_csc_dense<'a, T>(
|
||||||
beta: T,
|
beta: T,
|
||||||
c: impl Into<DMatrixSliceMut<'a, T>>,
|
c: impl Into<DMatrixViewMut<'a, T>>,
|
||||||
alpha: T,
|
alpha: T,
|
||||||
a: Op<&CscMatrix<T>>,
|
a: Op<&CscMatrix<T>>,
|
||||||
b: Op<impl Into<DMatrixSlice<'a, T>>>,
|
b: Op<impl Into<DMatrixView<'a, T>>>,
|
||||||
) where
|
) where
|
||||||
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
||||||
{
|
{
|
||||||
|
@ -27,10 +29,10 @@ pub fn spmm_csc_dense<'a, T>(
|
||||||
|
|
||||||
fn spmm_csc_dense_<T>(
|
fn spmm_csc_dense_<T>(
|
||||||
beta: T,
|
beta: T,
|
||||||
c: DMatrixSliceMut<'_, T>,
|
c: DMatrixViewMut<'_, T>,
|
||||||
alpha: T,
|
alpha: T,
|
||||||
a: Op<&CscMatrix<T>>,
|
a: Op<&CscMatrix<T>>,
|
||||||
b: Op<DMatrixSlice<'_, T>>,
|
b: Op<DMatrixView<'_, T>>,
|
||||||
) where
|
) where
|
||||||
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
||||||
{
|
{
|
||||||
|
@ -83,14 +85,65 @@ where
|
||||||
{
|
{
|
||||||
assert_compatible_spmm_dims!(c, a, b);
|
assert_compatible_spmm_dims!(c, a, b);
|
||||||
|
|
||||||
use Op::{NoOp, Transpose};
|
use Op::NoOp;
|
||||||
|
|
||||||
match (&a, &b) {
|
match (&a, &b) {
|
||||||
(NoOp(ref a), NoOp(ref b)) => {
|
(NoOp(a), NoOp(b)) => {
|
||||||
// Note: We have to reverse the order for CSC matrices
|
// Note: We have to reverse the order for CSC matrices
|
||||||
spmm_cs_prealloc(beta, &mut c.cs, alpha, &b.cs, &a.cs)
|
spmm_cs_prealloc(beta, &mut c.cs, alpha, &b.cs, &a.cs)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => spmm_csc_transposed(beta, c, alpha, a, b, spmm_csc_prealloc),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`.
|
||||||
|
/// This will not return an error even if the patterns don't match.
|
||||||
|
/// Should be used for situations where pattern creation immediately precedes multiplication.
|
||||||
|
///
|
||||||
|
/// Panics if the dimensions of the matrices involved are not compatible with the expression.
|
||||||
|
pub fn spmm_csc_prealloc_unchecked<T>(
|
||||||
|
beta: T,
|
||||||
|
c: &mut CscMatrix<T>,
|
||||||
|
alpha: T,
|
||||||
|
a: Op<&CscMatrix<T>>,
|
||||||
|
b: Op<&CscMatrix<T>>,
|
||||||
|
) -> Result<(), OperationError>
|
||||||
|
where
|
||||||
|
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
||||||
|
{
|
||||||
|
assert_compatible_spmm_dims!(c, a, b);
|
||||||
|
|
||||||
|
use Op::NoOp;
|
||||||
|
|
||||||
|
match (&a, &b) {
|
||||||
|
(NoOp(a), NoOp(b)) => {
|
||||||
|
// Note: We have to reverse the order for CSC matrices
|
||||||
|
spmm_cs_prealloc_unchecked(beta, &mut c.cs, alpha, &b.cs, &a.cs)
|
||||||
|
}
|
||||||
|
_ => spmm_csc_transposed(beta, c, alpha, a, b, spmm_csc_prealloc_unchecked),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spmm_csc_transposed<T, F>(
|
||||||
|
beta: T,
|
||||||
|
c: &mut CscMatrix<T>,
|
||||||
|
alpha: T,
|
||||||
|
a: Op<&CscMatrix<T>>,
|
||||||
|
b: Op<&CscMatrix<T>>,
|
||||||
|
spmm_kernel: F,
|
||||||
|
) -> Result<(), OperationError>
|
||||||
|
where
|
||||||
|
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
||||||
|
F: Fn(
|
||||||
|
T,
|
||||||
|
&mut CscMatrix<T>,
|
||||||
|
T,
|
||||||
|
Op<&CscMatrix<T>>,
|
||||||
|
Op<&CscMatrix<T>>,
|
||||||
|
) -> Result<(), OperationError>,
|
||||||
|
{
|
||||||
|
use Op::{NoOp, Transpose};
|
||||||
|
|
||||||
// Currently we handle transposition by explicitly precomputing transposed matrices
|
// Currently we handle transposition by explicitly precomputing transposed matrices
|
||||||
// and calling the operation again without transposition
|
// and calling the operation again without transposition
|
||||||
let a_ref: &CscMatrix<T> = a.inner_ref();
|
let a_ref: &CscMatrix<T> = a.inner_ref();
|
||||||
|
@ -99,17 +152,12 @@ where
|
||||||
use Cow::*;
|
use Cow::*;
|
||||||
match (&a, &b) {
|
match (&a, &b) {
|
||||||
(NoOp(_), NoOp(_)) => unreachable!(),
|
(NoOp(_), NoOp(_)) => unreachable!(),
|
||||||
(Transpose(ref a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
|
(Transpose(a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
|
||||||
(NoOp(_), Transpose(ref b)) => (Borrowed(a_ref), Owned(b.transpose())),
|
(NoOp(_), Transpose(b)) => (Borrowed(a_ref), Owned(b.transpose())),
|
||||||
(Transpose(ref a), Transpose(ref b)) => {
|
(Transpose(a), Transpose(b)) => (Owned(a.transpose()), Owned(b.transpose())),
|
||||||
(Owned(a.transpose()), Owned(b.transpose()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
spmm_kernel(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))
|
||||||
spmm_csc_prealloc(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Solve the lower triangular system `op(L) X = B`.
|
/// Solve the lower triangular system `op(L) X = B`.
|
||||||
|
@ -125,7 +173,7 @@ where
|
||||||
/// Panics if `L` is not square, or if `L` and `B` are not dimensionally compatible.
|
/// Panics if `L` is not square, or if `L` and `B` are not dimensionally compatible.
|
||||||
pub fn spsolve_csc_lower_triangular<'a, T: RealField>(
|
pub fn spsolve_csc_lower_triangular<'a, T: RealField>(
|
||||||
l: Op<&CscMatrix<T>>,
|
l: Op<&CscMatrix<T>>,
|
||||||
b: impl Into<DMatrixSliceMut<'a, T>>,
|
b: impl Into<DMatrixViewMut<'a, T>>,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
let b = b.into();
|
let b = b.into();
|
||||||
let l_matrix = l.into_inner();
|
let l_matrix = l.into_inner();
|
||||||
|
@ -147,7 +195,7 @@ pub fn spsolve_csc_lower_triangular<'a, T: RealField>(
|
||||||
|
|
||||||
fn spsolve_csc_lower_triangular_no_transpose<T: RealField>(
|
fn spsolve_csc_lower_triangular_no_transpose<T: RealField>(
|
||||||
l: &CscMatrix<T>,
|
l: &CscMatrix<T>,
|
||||||
b: DMatrixSliceMut<'_, T>,
|
b: DMatrixViewMut<'_, T>,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
let mut x = b;
|
let mut x = b;
|
||||||
|
|
||||||
|
@ -205,7 +253,7 @@ fn spsolve_encountered_zero_diagonal() -> Result<(), OperationError> {
|
||||||
|
|
||||||
fn spsolve_csc_lower_triangular_transpose<T: RealField>(
|
fn spsolve_csc_lower_triangular_transpose<T: RealField>(
|
||||||
l: &CscMatrix<T>,
|
l: &CscMatrix<T>,
|
||||||
b: DMatrixSliceMut<'_, T>,
|
b: DMatrixViewMut<'_, T>,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
let mut x = b;
|
let mut x = b;
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
use crate::csr::CsrMatrix;
|
use crate::csr::CsrMatrix;
|
||||||
use crate::ops::serial::cs::{spadd_cs_prealloc, spmm_cs_dense, spmm_cs_prealloc};
|
use crate::ops::serial::cs::{
|
||||||
|
spadd_cs_prealloc, spmm_cs_dense, spmm_cs_prealloc, spmm_cs_prealloc_unchecked,
|
||||||
|
};
|
||||||
use crate::ops::serial::OperationError;
|
use crate::ops::serial::OperationError;
|
||||||
use crate::ops::Op;
|
use crate::ops::Op;
|
||||||
use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, Scalar};
|
use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, Scalar};
|
||||||
use num_traits::{One, Zero};
|
use num_traits::{One, Zero};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
/// Sparse-dense matrix-matrix multiplication `C <- beta * C + alpha * op(A) * op(B)`.
|
/// Sparse-dense matrix-matrix multiplication `C <- beta * C + alpha * op(A) * op(B)`.
|
||||||
pub fn spmm_csr_dense<'a, T>(
|
pub fn spmm_csr_dense<'a, T>(
|
||||||
beta: T,
|
beta: T,
|
||||||
c: impl Into<DMatrixSliceMut<'a, T>>,
|
c: impl Into<DMatrixViewMut<'a, T>>,
|
||||||
alpha: T,
|
alpha: T,
|
||||||
a: Op<&CsrMatrix<T>>,
|
a: Op<&CsrMatrix<T>>,
|
||||||
b: Op<impl Into<DMatrixSlice<'a, T>>>,
|
b: Op<impl Into<DMatrixView<'a, T>>>,
|
||||||
) where
|
) where
|
||||||
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
||||||
{
|
{
|
||||||
|
@ -22,10 +24,10 @@ pub fn spmm_csr_dense<'a, T>(
|
||||||
|
|
||||||
fn spmm_csr_dense_<T>(
|
fn spmm_csr_dense_<T>(
|
||||||
beta: T,
|
beta: T,
|
||||||
c: DMatrixSliceMut<'_, T>,
|
c: DMatrixViewMut<'_, T>,
|
||||||
alpha: T,
|
alpha: T,
|
||||||
a: Op<&CsrMatrix<T>>,
|
a: Op<&CsrMatrix<T>>,
|
||||||
b: Op<DMatrixSlice<'_, T>>,
|
b: Op<DMatrixView<'_, T>>,
|
||||||
) where
|
) where
|
||||||
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
||||||
{
|
{
|
||||||
|
@ -77,30 +79,71 @@ where
|
||||||
{
|
{
|
||||||
assert_compatible_spmm_dims!(c, a, b);
|
assert_compatible_spmm_dims!(c, a, b);
|
||||||
|
|
||||||
use Op::{NoOp, Transpose};
|
use Op::NoOp;
|
||||||
|
|
||||||
match (&a, &b) {
|
match (&a, &b) {
|
||||||
(NoOp(ref a), NoOp(ref b)) => spmm_cs_prealloc(beta, &mut c.cs, alpha, &a.cs, &b.cs),
|
(NoOp(a), NoOp(b)) => spmm_cs_prealloc(beta, &mut c.cs, alpha, &a.cs, &b.cs),
|
||||||
_ => {
|
_ => spmm_csr_transposed(beta, c, alpha, a, b, spmm_csr_prealloc),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`.
|
||||||
|
/// This will not return an error even if the patterns don't match.
|
||||||
|
/// Should be used for situations where pattern creation immediately precedes multiplication.
|
||||||
|
///
|
||||||
|
/// Panics if the dimensions of the matrices involved are not compatible with the expression.
|
||||||
|
pub fn spmm_csr_prealloc_unchecked<T>(
|
||||||
|
beta: T,
|
||||||
|
c: &mut CsrMatrix<T>,
|
||||||
|
alpha: T,
|
||||||
|
a: Op<&CsrMatrix<T>>,
|
||||||
|
b: Op<&CsrMatrix<T>>,
|
||||||
|
) -> Result<(), OperationError>
|
||||||
|
where
|
||||||
|
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),
|
||||||
|
_ => spmm_csr_transposed(beta, c, alpha, a, b, spmm_csr_prealloc_unchecked),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spmm_csr_transposed<T, F>(
|
||||||
|
beta: T,
|
||||||
|
c: &mut CsrMatrix<T>,
|
||||||
|
alpha: T,
|
||||||
|
a: Op<&CsrMatrix<T>>,
|
||||||
|
b: Op<&CsrMatrix<T>>,
|
||||||
|
spmm_kernel: F,
|
||||||
|
) -> Result<(), OperationError>
|
||||||
|
where
|
||||||
|
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
||||||
|
F: Fn(
|
||||||
|
T,
|
||||||
|
&mut CsrMatrix<T>,
|
||||||
|
T,
|
||||||
|
Op<&CsrMatrix<T>>,
|
||||||
|
Op<&CsrMatrix<T>>,
|
||||||
|
) -> Result<(), OperationError>,
|
||||||
|
{
|
||||||
|
use Op::{NoOp, Transpose};
|
||||||
|
|
||||||
// Currently we handle transposition by explicitly precomputing transposed matrices
|
// Currently we handle transposition by explicitly precomputing transposed matrices
|
||||||
// and calling the operation again without transposition
|
// and calling the operation again without transposition
|
||||||
// TODO: At least use workspaces to allow control of allocations. Maybe
|
|
||||||
// consider implementing certain patterns (like A^T * B) explicitly
|
|
||||||
let a_ref: &CsrMatrix<T> = a.inner_ref();
|
let a_ref: &CsrMatrix<T> = a.inner_ref();
|
||||||
let b_ref: &CsrMatrix<T> = b.inner_ref();
|
let b_ref: &CsrMatrix<T> = b.inner_ref();
|
||||||
let (a, b) = {
|
let (a, b) = {
|
||||||
use Cow::*;
|
use Cow::*;
|
||||||
match (&a, &b) {
|
match (&a, &b) {
|
||||||
(NoOp(_), NoOp(_)) => unreachable!(),
|
(NoOp(_), NoOp(_)) => unreachable!(),
|
||||||
(Transpose(ref a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
|
(Transpose(a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
|
||||||
(NoOp(_), Transpose(ref b)) => (Borrowed(a_ref), Owned(b.transpose())),
|
(NoOp(_), Transpose(b)) => (Borrowed(a_ref), Owned(b.transpose())),
|
||||||
(Transpose(ref a), Transpose(ref b)) => {
|
(Transpose(a), Transpose(b)) => (Owned(a.transpose()), Owned(b.transpose())),
|
||||||
(Owned(a.transpose()), Owned(b.transpose()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
spmm_kernel(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))
|
||||||
spmm_csr_prealloc(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,18 +125,22 @@ fn iterate_union<'a>(
|
||||||
) -> impl Iterator<Item = usize> + 'a {
|
) -> impl Iterator<Item = usize> + 'a {
|
||||||
iter::from_fn(move || {
|
iter::from_fn(move || {
|
||||||
if let (Some(a_item), Some(b_item)) = (sorted_a.first(), sorted_b.first()) {
|
if let (Some(a_item), Some(b_item)) = (sorted_a.first(), sorted_b.first()) {
|
||||||
let item = if a_item < b_item {
|
let item = match a_item.cmp(b_item) {
|
||||||
|
std::cmp::Ordering::Less => {
|
||||||
sorted_a = &sorted_a[1..];
|
sorted_a = &sorted_a[1..];
|
||||||
a_item
|
a_item
|
||||||
} else if b_item < a_item {
|
}
|
||||||
|
std::cmp::Ordering::Greater => {
|
||||||
sorted_b = &sorted_b[1..];
|
sorted_b = &sorted_b[1..];
|
||||||
b_item
|
b_item
|
||||||
} else {
|
}
|
||||||
|
std::cmp::Ordering::Equal => {
|
||||||
// Both lists contain the same element, advance both slices to avoid
|
// Both lists contain the same element, advance both slices to avoid
|
||||||
// duplicate entries in the result
|
// duplicate entries in the result
|
||||||
sorted_a = &sorted_a[1..];
|
sorted_a = &sorted_a[1..];
|
||||||
sorted_b = &sorted_b[1..];
|
sorted_b = &sorted_b[1..];
|
||||||
a_item
|
a_item
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Some(*item)
|
Some(*item)
|
||||||
} else if let Some(a_item) = sorted_a.first() {
|
} else if let Some(a_item) = sorted_a.first() {
|
||||||
|
|
|
@ -80,7 +80,7 @@ impl SparsityPattern {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn major_dim(&self) -> usize {
|
pub fn major_dim(&self) -> usize {
|
||||||
assert!(self.major_offsets.len() > 0);
|
assert!(!self.major_offsets.is_empty());
|
||||||
self.major_offsets.len() - 1
|
self.major_offsets.len() - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ impl SparsityPattern {
|
||||||
// We test for in-bounds, uniqueness and monotonicity at the same time
|
// We test for in-bounds, uniqueness and monotonicity at the same time
|
||||||
// to ensure that we only visit each minor index once
|
// to ensure that we only visit each minor index once
|
||||||
let mut iter = minor_indices.iter();
|
let mut iter = minor_indices.iter();
|
||||||
let mut prev = None;
|
let mut prev: Option<usize> = None;
|
||||||
|
|
||||||
while let Some(next) = iter.next().copied() {
|
while let Some(next) = iter.next().copied() {
|
||||||
if next >= minor_dim {
|
if next >= minor_dim {
|
||||||
|
@ -170,10 +170,10 @@ impl SparsityPattern {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(prev) = prev {
|
if let Some(prev) = prev {
|
||||||
if prev > next {
|
match prev.cmp(&next) {
|
||||||
return Err(NonmonotonicMinorIndices);
|
std::cmp::Ordering::Greater => return Err(NonmonotonicMinorIndices),
|
||||||
} else if prev == next {
|
std::cmp::Ordering::Equal => return Err(DuplicateEntry),
|
||||||
return Err(DuplicateEntry);
|
std::cmp::Ordering::Less => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prev = Some(next);
|
prev = Some(next);
|
||||||
|
@ -195,6 +195,14 @@ impl SparsityPattern {
|
||||||
///
|
///
|
||||||
/// Panics if the number of major offsets is not exactly one greater than the major dimension
|
/// Panics if the number of major offsets is not exactly one greater than the major dimension
|
||||||
/// or if major offsets do not start with 0 and end with the number of minor indices.
|
/// or if major offsets do not start with 0 and end with the number of minor indices.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Assumes that the major offsets and indices adhere to the requirements of being a valid
|
||||||
|
/// sparsity pattern.
|
||||||
|
/// Specifically, that major offsets is monotonically increasing, and
|
||||||
|
/// `major_offsets[i]..major_offsets[i+1]` refers to a major lane in the sparsity pattern,
|
||||||
|
/// and `minor_indices[major_offsets[i]..major_offsets[i+1]]` is monotonically increasing.
|
||||||
pub unsafe fn from_offset_and_indices_unchecked(
|
pub unsafe fn from_offset_and_indices_unchecked(
|
||||||
major_dim: usize,
|
major_dim: usize,
|
||||||
minor_dim: usize,
|
minor_dim: usize,
|
||||||
|
@ -291,6 +299,16 @@ impl SparsityPattern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for SparsityPattern {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
major_offsets: vec![0],
|
||||||
|
minor_indices: vec![],
|
||||||
|
minor_dim: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Error type for `SparsityPattern` format errors.
|
/// Error type for `SparsityPattern` format errors.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
|
|
@ -87,6 +87,40 @@ fn coo_construction_for_valid_data() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn coo_triplets_iter_mut() {
|
||||||
|
// Arbitrary matrix, with duplicates
|
||||||
|
let i = vec![0, 1, 0, 0, 0, 0, 2, 1];
|
||||||
|
let j = vec![0, 2, 0, 1, 0, 3, 3, 2];
|
||||||
|
let v = vec![2, 3, 4, 7, 1, 3, 1, 5];
|
||||||
|
let mut coo =
|
||||||
|
CooMatrix::<i32>::try_from_triplets(3, 5, i.clone(), j.clone(), v.clone()).unwrap();
|
||||||
|
|
||||||
|
let actual_triplets: Vec<_> = coo.triplet_iter_mut().map(|(i, j, v)| (i, j, *v)).collect();
|
||||||
|
|
||||||
|
let expected_triplets: Vec<_> = i
|
||||||
|
.iter()
|
||||||
|
.zip(&j)
|
||||||
|
.zip(&v)
|
||||||
|
.map(|((i, j), v)| (*i, *j, *v))
|
||||||
|
.collect();
|
||||||
|
assert_eq!(expected_triplets, actual_triplets);
|
||||||
|
|
||||||
|
for (_i, _j, v) in coo.triplet_iter_mut() {
|
||||||
|
*v += *v;
|
||||||
|
}
|
||||||
|
|
||||||
|
let actual_triplets: Vec<_> = coo.triplet_iter_mut().map(|(i, j, v)| (i, j, *v)).collect();
|
||||||
|
let v = vec![4, 6, 8, 14, 2, 6, 2, 10];
|
||||||
|
let expected_triplets: Vec<_> = i
|
||||||
|
.iter()
|
||||||
|
.zip(&j)
|
||||||
|
.zip(&v)
|
||||||
|
.map(|((i, j), v)| (*i, *j, *v))
|
||||||
|
.collect();
|
||||||
|
assert_eq!(expected_triplets, actual_triplets);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn coo_try_from_triplets_reports_out_of_bounds_indices() {
|
fn coo_try_from_triplets_reports_out_of_bounds_indices() {
|
||||||
{
|
{
|
||||||
|
@ -150,6 +184,31 @@ fn coo_try_from_triplets_reports_out_of_bounds_indices() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn coo_try_from_triplets_iter() {
|
||||||
|
// Check that try_from_triplets_iter panics when the triplet vectors have different lengths
|
||||||
|
macro_rules! assert_errs {
|
||||||
|
($result:expr) => {
|
||||||
|
assert!(matches!(
|
||||||
|
$result.unwrap_err().kind(),
|
||||||
|
SparseFormatErrorKind::IndexOutOfBounds
|
||||||
|
))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_errs!(CooMatrix::<f32>::try_from_triplets_iter(
|
||||||
|
3,
|
||||||
|
5,
|
||||||
|
vec![(0, 6, 3.0)].into_iter(),
|
||||||
|
));
|
||||||
|
assert!(CooMatrix::<f32>::try_from_triplets_iter(
|
||||||
|
3,
|
||||||
|
5,
|
||||||
|
vec![(0, 3, 3.0), (1, 2, 2.0), (0, 3, 1.0),].into_iter(),
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn coo_try_from_triplets_panics_on_mismatched_vectors() {
|
fn coo_try_from_triplets_panics_on_mismatched_vectors() {
|
||||||
// Check that try_from_triplets panics when the triplet vectors have different lengths
|
// Check that try_from_triplets panics when the triplet vectors have different lengths
|
||||||
|
@ -226,6 +285,29 @@ fn coo_push_valid_entries() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn coo_clear_triplets_valid_entries() {
|
||||||
|
let mut coo = CooMatrix::new(3, 3);
|
||||||
|
|
||||||
|
coo.push(0, 0, 1);
|
||||||
|
coo.push(0, 0, 2);
|
||||||
|
coo.push(2, 2, 3);
|
||||||
|
assert_eq!(
|
||||||
|
coo.triplet_iter().collect::<Vec<_>>(),
|
||||||
|
vec![(0, 0, &1), (0, 0, &2), (2, 2, &3)]
|
||||||
|
);
|
||||||
|
coo.clear_triplets();
|
||||||
|
assert_eq!(coo.triplet_iter().collect::<Vec<_>>(), vec![]);
|
||||||
|
// making sure everyhting works after clearing
|
||||||
|
coo.push(0, 0, 1);
|
||||||
|
coo.push(0, 0, 2);
|
||||||
|
coo.push(2, 2, 3);
|
||||||
|
assert_eq!(
|
||||||
|
coo.triplet_iter().collect::<Vec<_>>(),
|
||||||
|
vec![(0, 0, &1), (0, 0, &2), (2, 2, &3)]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn coo_push_out_of_bounds_entries() {
|
fn coo_push_out_of_bounds_entries() {
|
||||||
{
|
{
|
||||||
|
@ -291,8 +373,8 @@ fn coo_push_matrix_valid_entries() {
|
||||||
// Works with sliced
|
// Works with sliced
|
||||||
{
|
{
|
||||||
let source = nalgebra::SMatrix::<i32, 2, 2>::new(6, 7, 8, 9);
|
let source = nalgebra::SMatrix::<i32, 2, 2>::new(6, 7, 8, 9);
|
||||||
let sliced = source.fixed_slice::<2, 1>(0, 0);
|
let view = source.fixed_view::<2, 1>(0, 0);
|
||||||
coo.push_matrix(1, 0, &sliced);
|
coo.push_matrix(1, 0, &view);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
coo.triplet_iter().collect::<Vec<_>>(),
|
coo.triplet_iter().collect::<Vec<_>>(),
|
||||||
|
|
|
@ -12,6 +12,18 @@ use crate::common::csc_strategy;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn csc_matrix_default() {
|
||||||
|
let matrix: CscMatrix<f32> = CscMatrix::default();
|
||||||
|
|
||||||
|
assert_eq!(matrix.nrows(), 0);
|
||||||
|
assert_eq!(matrix.ncols(), 0);
|
||||||
|
assert_eq!(matrix.nnz(), 0);
|
||||||
|
|
||||||
|
assert_eq!(matrix.values(), &[]);
|
||||||
|
assert!(matrix.get_entry(0, 0).is_none());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn csc_matrix_valid_data() {
|
fn csc_matrix_valid_data() {
|
||||||
// Construct matrix from valid data and check that selected methods return results
|
// Construct matrix from valid data and check that selected methods return results
|
||||||
|
|
|
@ -12,6 +12,18 @@ use crate::common::csr_strategy;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn csr_matrix_default() {
|
||||||
|
let matrix: CsrMatrix<f32> = CsrMatrix::default();
|
||||||
|
|
||||||
|
assert_eq!(matrix.nrows(), 0);
|
||||||
|
assert_eq!(matrix.ncols(), 0);
|
||||||
|
assert_eq!(matrix.nnz(), 0);
|
||||||
|
|
||||||
|
assert_eq!(matrix.values(), &[]);
|
||||||
|
assert!(matrix.get_entry(0, 0).is_none());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn csr_matrix_valid_data() {
|
fn csr_matrix_valid_data() {
|
||||||
// Construct matrix from valid data and check that selected methods return results
|
// Construct matrix from valid data and check that selected methods return results
|
||||||
|
|
|
@ -1,12 +1,21 @@
|
||||||
use matrixcompare::assert_matrix_eq;
|
use matrixcompare::assert_matrix_eq;
|
||||||
use nalgebra::dmatrix;
|
use nalgebra::matrix;
|
||||||
use nalgebra::Complex;
|
use nalgebra::Complex;
|
||||||
use nalgebra_sparse::io::load_coo_from_matrix_market_str;
|
use nalgebra_sparse::io::{
|
||||||
|
load_coo_from_matrix_market_file, load_coo_from_matrix_market_str, save_to_matrix_market_file,
|
||||||
|
save_to_matrix_market_str,
|
||||||
|
};
|
||||||
|
use nalgebra_sparse::proptest::coo_no_duplicates;
|
||||||
use nalgebra_sparse::CooMatrix;
|
use nalgebra_sparse::CooMatrix;
|
||||||
|
use proptest::prelude::*;
|
||||||
|
use tempfile::tempdir;
|
||||||
|
|
||||||
|
type C64 = Complex<f64>;
|
||||||
|
type C32 = Complex<f32>;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_sparse_real_general_empty() {
|
fn test_matrixmarket_load_sparse_real_general_empty() {
|
||||||
// Test several valid zero-shapes of a sparse matrix
|
// Test several valid zero-shapes of a sparse matrix
|
||||||
let shapes = vec![ (0, 0), (1, 0), (0, 1) ];
|
let shapes = vec![ (0, 0), (1, 0), (0, 1) ];
|
||||||
let strings: Vec<String> = shapes
|
let strings: Vec<String> = shapes
|
||||||
|
@ -24,7 +33,7 @@ fn test_matrixmarket_sparse_real_general_empty() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_dense_real_general_empty() {
|
fn test_matrixmarket_load_dense_real_general_empty() {
|
||||||
// Test several valid zero-shapes of a dense matrix
|
// Test several valid zero-shapes of a dense matrix
|
||||||
let shapes = vec![ (0, 0), (1, 0), (0, 1) ];
|
let shapes = vec![ (0, 0), (1, 0), (0, 1) ];
|
||||||
let strings: Vec<String> = shapes
|
let strings: Vec<String> = shapes
|
||||||
|
@ -42,7 +51,7 @@ fn test_matrixmarket_dense_real_general_empty() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_sparse_real_general() {
|
fn test_matrixmarket_load_sparse_real_general() {
|
||||||
let file_str = r#"
|
let file_str = r#"
|
||||||
%%MatrixMarket matrix CoOrdinate real general
|
%%MatrixMarket matrix CoOrdinate real general
|
||||||
% This is also an example of free-format features.
|
% This is also an example of free-format features.
|
||||||
|
@ -89,7 +98,7 @@ fn test_matrixmarket_sparse_real_general() {
|
||||||
5 5 1.200e+01
|
5 5 1.200e+01
|
||||||
"#;
|
"#;
|
||||||
let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap();
|
let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap();
|
||||||
let expected = dmatrix![
|
let expected = matrix![
|
||||||
1.0, 0.0, 0.0, 6.0, 0.0;
|
1.0, 0.0, 0.0, 6.0, 0.0;
|
||||||
0.0, 10.5, 0.0, 0.0, 0.0;
|
0.0, 10.5, 0.0, 0.0, 0.0;
|
||||||
0.0, 0.0, 0.015, 0.0, 0.0;
|
0.0, 0.0, 0.015, 0.0, 0.0;
|
||||||
|
@ -101,7 +110,7 @@ fn test_matrixmarket_sparse_real_general() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_sparse_int_symmetric() {
|
fn test_matrixmarket_load_sparse_int_symmetric() {
|
||||||
let file_str = r#"
|
let file_str = r#"
|
||||||
%%MatrixMarket matrix coordinate integer symmetric
|
%%MatrixMarket matrix coordinate integer symmetric
|
||||||
%
|
%
|
||||||
|
@ -117,7 +126,7 @@ fn test_matrixmarket_sparse_int_symmetric() {
|
||||||
5 5 55
|
5 5 55
|
||||||
"#;
|
"#;
|
||||||
let sparse_mat = load_coo_from_matrix_market_str::<i128>(file_str).unwrap();
|
let sparse_mat = load_coo_from_matrix_market_str::<i128>(file_str).unwrap();
|
||||||
let expected = dmatrix![
|
let expected = matrix![
|
||||||
11, 0, 0, 0, -15;
|
11, 0, 0, 0, -15;
|
||||||
0, 22, 23, 24, 0;
|
0, 22, 23, 24, 0;
|
||||||
0, 23, 33, 0, 35;
|
0, 23, 33, 0, 35;
|
||||||
|
@ -129,7 +138,7 @@ fn test_matrixmarket_sparse_int_symmetric() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_sparse_complex_hermitian() {
|
fn test_matrixmarket_load_sparse_complex_hermitian() {
|
||||||
let file_str = r#"
|
let file_str = r#"
|
||||||
%%MatrixMarket matrix coordinate complex hermitian
|
%%MatrixMarket matrix coordinate complex hermitian
|
||||||
%
|
%
|
||||||
|
@ -144,19 +153,19 @@ fn test_matrixmarket_sparse_complex_hermitian() {
|
||||||
|
|
||||||
"#;
|
"#;
|
||||||
let sparse_mat = load_coo_from_matrix_market_str::<Complex<f64>>(file_str).unwrap();
|
let sparse_mat = load_coo_from_matrix_market_str::<Complex<f64>>(file_str).unwrap();
|
||||||
let expected = dmatrix![
|
let expected = matrix![
|
||||||
Complex::<f64>{re:1.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0},Complex::<f64>{re:0.0,im:0.0};
|
C64{re:1.0,im:0.0}, C64{re:0.0,im:0.0}, C64{re:0.0,im:0.0}, C64{re:0.0,im:0.0},C64{re:0.0,im:0.0};
|
||||||
Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:10.5,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:250.5,im:-22.22},Complex::<f64>{re:0.0,im:0.0};
|
C64{re:0.0,im:0.0}, C64{re:10.5,im:0.0}, C64{re:0.0,im:0.0}, C64{re:250.5,im:-22.22},C64{re:0.0,im:0.0};
|
||||||
Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.015,im:0.0}, Complex::<f64>{re:0.0,im:0.0},Complex::<f64>{re:0.0,im:0.0};
|
C64{re:0.0,im:0.0}, C64{re:0.0,im:0.0}, C64{re:0.015,im:0.0}, C64{re:0.0,im:0.0},C64{re:0.0,im:0.0};
|
||||||
Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:250.5,im:22.22}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:-280.0,im:0.0},Complex::<f64>{re:0.0,im:-33.32};
|
C64{re:0.0,im:0.0}, C64{re:250.5,im:22.22}, C64{re:0.0,im:0.0}, C64{re:-280.0,im:0.0},C64{re:0.0,im:-33.32};
|
||||||
Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:33.32},Complex::<f64>{re:12.0,im:0.0};
|
C64{re:0.0,im:0.0}, C64{re:0.0,im:0.0}, C64{re:0.0,im:0.0}, C64{re:0.0,im:33.32},C64{re:12.0,im:0.0};
|
||||||
];
|
];
|
||||||
assert_matrix_eq!(sparse_mat, expected);
|
assert_matrix_eq!(sparse_mat, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_sparse_real_skew() {
|
fn test_matrixmarket_load_sparse_real_skew() {
|
||||||
let file_str = r#"
|
let file_str = r#"
|
||||||
%%MatrixMarket matrix coordinate real skew-symmetric
|
%%MatrixMarket matrix coordinate real skew-symmetric
|
||||||
%
|
%
|
||||||
|
@ -167,7 +176,7 @@ fn test_matrixmarket_sparse_real_skew() {
|
||||||
5 3 -35.0
|
5 3 -35.0
|
||||||
"#;
|
"#;
|
||||||
let sparse_mat = load_coo_from_matrix_market_str::<f64>(file_str).unwrap();
|
let sparse_mat = load_coo_from_matrix_market_str::<f64>(file_str).unwrap();
|
||||||
let expected = dmatrix![
|
let expected = matrix![
|
||||||
0.0, 0.0, 0.0, 0.0, 15.0;
|
0.0, 0.0, 0.0, 0.0, 15.0;
|
||||||
0.0, 0.0, 23.0, 24.0, 0.0;
|
0.0, 0.0, 23.0, 24.0, 0.0;
|
||||||
0.0, -23.0, 0.0, 0.0, 35.0;
|
0.0, -23.0, 0.0, 0.0, 35.0;
|
||||||
|
@ -179,7 +188,7 @@ fn test_matrixmarket_sparse_real_skew() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_sparse_pattern_general() {
|
fn test_matrixmarket_load_sparse_pattern_general() {
|
||||||
let file_str = r#"
|
let file_str = r#"
|
||||||
%%MatrixMarket matrix coordinate pattern general
|
%%MatrixMarket matrix coordinate pattern general
|
||||||
%
|
%
|
||||||
|
@ -198,10 +207,10 @@ fn test_matrixmarket_sparse_pattern_general() {
|
||||||
let pattern_matrix = load_coo_from_matrix_market_str::<()>(file_str).unwrap();
|
let pattern_matrix = load_coo_from_matrix_market_str::<()>(file_str).unwrap();
|
||||||
let nrows = pattern_matrix.nrows();
|
let nrows = pattern_matrix.nrows();
|
||||||
let ncols = pattern_matrix.ncols();
|
let ncols = pattern_matrix.ncols();
|
||||||
let (row_idx, col_idx, val) = pattern_matrix.disassemble();
|
let (row_idx, col_idx, val) = pattern_matrix.clone().disassemble();
|
||||||
let values = vec![1; val.len()];
|
let values = vec![1; val.len()];
|
||||||
let sparse_mat = CooMatrix::try_from_triplets(nrows, ncols, row_idx, col_idx, values).unwrap();
|
let sparse_mat = CooMatrix::try_from_triplets(nrows, ncols, row_idx, col_idx, values).unwrap();
|
||||||
let expected = dmatrix![
|
let expected = matrix![
|
||||||
1, 0, 0, 0, 1;
|
1, 0, 0, 0, 1;
|
||||||
0, 0, 1, 1, 0;
|
0, 0, 1, 1, 0;
|
||||||
0, 1, 0, 0, 1;
|
0, 1, 0, 0, 1;
|
||||||
|
@ -213,7 +222,7 @@ fn test_matrixmarket_sparse_pattern_general() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_dense_real_general() {
|
fn test_matrixmarket_load_dense_real_general() {
|
||||||
let file_str = r#"
|
let file_str = r#"
|
||||||
%%MatrixMarket matrix array real general
|
%%MatrixMarket matrix array real general
|
||||||
%
|
%
|
||||||
|
@ -233,7 +242,7 @@ fn test_matrixmarket_dense_real_general() {
|
||||||
|
|
||||||
"#;
|
"#;
|
||||||
let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap();
|
let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap();
|
||||||
let expected = dmatrix![
|
let expected = matrix![
|
||||||
1.0, 5.0, 9.0;
|
1.0, 5.0, 9.0;
|
||||||
2.0, 6.0, 10.0;
|
2.0, 6.0, 10.0;
|
||||||
3.0, 7.0, 11.0;
|
3.0, 7.0, 11.0;
|
||||||
|
@ -244,7 +253,7 @@ fn test_matrixmarket_dense_real_general() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_dense_real_symmetric() {
|
fn test_matrixmarket_load_dense_real_symmetric() {
|
||||||
let file_str = r#"
|
let file_str = r#"
|
||||||
%%MatrixMarket matrix array real symmetric
|
%%MatrixMarket matrix array real symmetric
|
||||||
%
|
%
|
||||||
|
@ -262,7 +271,7 @@ fn test_matrixmarket_dense_real_symmetric() {
|
||||||
|
|
||||||
"#;
|
"#;
|
||||||
let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap();
|
let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap();
|
||||||
let expected = dmatrix![
|
let expected = matrix![
|
||||||
1.0, 2.0, 3.0, 4.0;
|
1.0, 2.0, 3.0, 4.0;
|
||||||
2.0, 5.0, 6.0, 7.0;
|
2.0, 5.0, 6.0, 7.0;
|
||||||
3.0, 6.0, 8.0, 9.0;
|
3.0, 6.0, 8.0, 9.0;
|
||||||
|
@ -273,7 +282,7 @@ fn test_matrixmarket_dense_real_symmetric() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_dense_complex_hermitian() {
|
fn test_matrixmarket_load_dense_complex_hermitian() {
|
||||||
let file_str = r#"
|
let file_str = r#"
|
||||||
%%MatrixMarket matrix array complex hermitian
|
%%MatrixMarket matrix array complex hermitian
|
||||||
%
|
%
|
||||||
|
@ -290,19 +299,19 @@ fn test_matrixmarket_dense_complex_hermitian() {
|
||||||
10.0 0.0
|
10.0 0.0
|
||||||
|
|
||||||
"#;
|
"#;
|
||||||
let sparse_mat = load_coo_from_matrix_market_str::<Complex<f64>>(file_str).unwrap();
|
let sparse_mat = load_coo_from_matrix_market_str::<C64>(file_str).unwrap();
|
||||||
let expected = dmatrix![
|
let expected = matrix![
|
||||||
Complex::<f64>{re:1.0,im:0.0}, Complex::<f64>{re:2.0,im:-2.0} ,Complex::<f64>{re:3.0,im:-3.0} ,Complex::<f64>{re:4.0,im:-4.0};
|
C64{re:1.0,im:0.0}, C64{re:2.0,im:-2.0} ,C64{re:3.0,im:-3.0} ,C64{re:4.0,im:-4.0};
|
||||||
Complex::<f64>{re:2.0,im:2.0}, Complex::<f64>{re:5.0,im:0.0} ,Complex::<f64>{re:6.0,im:-6.0} ,Complex::<f64>{re:7.0,im:-7.0};
|
C64{re:2.0,im:2.0}, C64{re:5.0,im:0.0} ,C64{re:6.0,im:-6.0} ,C64{re:7.0,im:-7.0};
|
||||||
Complex::<f64>{re:3.0,im:3.0}, Complex::<f64>{re:6.0,im:6.0} ,Complex::<f64>{re:8.0,im:0.0} ,Complex::<f64>{re:9.0,im:-9.0};
|
C64{re:3.0,im:3.0}, C64{re:6.0,im:6.0} ,C64{re:8.0,im:0.0} ,C64{re:9.0,im:-9.0};
|
||||||
Complex::<f64>{re:4.0,im:4.0}, Complex::<f64>{re:7.0,im:7.0} ,Complex::<f64>{re:9.0,im:9.0} ,Complex::<f64>{re:10.0,im:0.0};
|
C64{re:4.0,im:4.0}, C64{re:7.0,im:7.0} ,C64{re:9.0,im:9.0} ,C64{re:10.0,im:0.0};
|
||||||
];
|
];
|
||||||
assert_matrix_eq!(sparse_mat, expected);
|
assert_matrix_eq!(sparse_mat, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_dense_int_skew() {
|
fn test_matrixmarket_load_dense_int_skew() {
|
||||||
let file_str = r#"
|
let file_str = r#"
|
||||||
%%MatrixMarket matrix array integer skew-symmetric
|
%%MatrixMarket matrix array integer skew-symmetric
|
||||||
%
|
%
|
||||||
|
@ -315,7 +324,7 @@ fn test_matrixmarket_dense_int_skew() {
|
||||||
6
|
6
|
||||||
"#;
|
"#;
|
||||||
let sparse_mat = load_coo_from_matrix_market_str::<i32>(file_str).unwrap();
|
let sparse_mat = load_coo_from_matrix_market_str::<i32>(file_str).unwrap();
|
||||||
let expected = dmatrix![
|
let expected = matrix![
|
||||||
0,-1,-2,-3;
|
0,-1,-2,-3;
|
||||||
1, 0,-4,-5;
|
1, 0,-4,-5;
|
||||||
2, 4, 0,-6;
|
2, 4, 0,-6;
|
||||||
|
@ -326,7 +335,7 @@ fn test_matrixmarket_dense_int_skew() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn test_matrixmarket_dense_complex_general() {
|
fn test_matrixmarket_load_dense_complex_general() {
|
||||||
let file_str = r#"
|
let file_str = r#"
|
||||||
%%MatrixMarket matrix array complex general
|
%%MatrixMarket matrix array complex general
|
||||||
%
|
%
|
||||||
|
@ -336,10 +345,124 @@ fn test_matrixmarket_dense_complex_general() {
|
||||||
1 0
|
1 0
|
||||||
1 0
|
1 0
|
||||||
"#;
|
"#;
|
||||||
let sparse_mat = load_coo_from_matrix_market_str::<Complex<f32>>(file_str).unwrap();
|
let sparse_mat = load_coo_from_matrix_market_str::<C32>(file_str).unwrap();
|
||||||
let expected = dmatrix![
|
let expected = matrix![
|
||||||
Complex::<f32>{re:1.0,im:0.0},Complex::<f32>{re:1.0,im:0.0};
|
C32{re:1.0,im:0.0},C32{re:1.0,im:0.0};
|
||||||
Complex::<f32>{re:1.0,im:0.0},Complex::<f32>{re:1.0,im:0.0};
|
C32{re:1.0,im:0.0},C32{re:1.0,im:0.0};
|
||||||
];
|
];
|
||||||
assert_matrix_eq!(sparse_mat, expected);
|
assert_matrix_eq!(sparse_mat, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[rustfmt::skip]
|
||||||
|
fn test_matrixmarket_write_real(){
|
||||||
|
let dense_matrix = matrix![
|
||||||
|
1.0, 2.0, 3.0;
|
||||||
|
2.0, 0.0, 3.0;
|
||||||
|
];
|
||||||
|
let row_indices = vec![0,1,0,0,1];
|
||||||
|
let col_indices = vec![0,0,1,2,2];
|
||||||
|
let values = vec![1.0,2.0,2.0,3.0,3.0];
|
||||||
|
let coo_matrix = CooMatrix::try_from_triplets(2, 3, row_indices, col_indices, values).unwrap();
|
||||||
|
assert_matrix_eq!(dense_matrix,coo_matrix);
|
||||||
|
let expected = r#"%%matrixmarket matrix coordinate real general
|
||||||
|
% matrixmarket file generated by nalgebra-sparse.
|
||||||
|
2 3 5
|
||||||
|
1 1 1
|
||||||
|
2 1 2
|
||||||
|
1 2 2
|
||||||
|
1 3 3
|
||||||
|
2 3 3
|
||||||
|
"#;
|
||||||
|
let matrixmarket_str = save_to_matrix_market_str(&coo_matrix);
|
||||||
|
assert_eq!(matrixmarket_str,expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_matrixmarket_write_int() {
|
||||||
|
let dense_matrix = matrix![
|
||||||
|
1,2,3;
|
||||||
|
2,0,3;
|
||||||
|
];
|
||||||
|
let row_indices = vec![0, 1, 0, 0, 1];
|
||||||
|
let col_indices = vec![0, 0, 1, 2, 2];
|
||||||
|
let values = vec![1, 2, 2, 3, 3];
|
||||||
|
let coo_matrix = CooMatrix::try_from_triplets(2, 3, row_indices, col_indices, values).unwrap();
|
||||||
|
assert_matrix_eq!(dense_matrix, coo_matrix);
|
||||||
|
let expected = r#"%%matrixmarket matrix coordinate integer general
|
||||||
|
% matrixmarket file generated by nalgebra-sparse.
|
||||||
|
2 3 5
|
||||||
|
1 1 1
|
||||||
|
2 1 2
|
||||||
|
1 2 2
|
||||||
|
1 3 3
|
||||||
|
2 3 3
|
||||||
|
"#;
|
||||||
|
let matrixmarket_str = save_to_matrix_market_str(&coo_matrix);
|
||||||
|
assert_eq!(matrixmarket_str, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_matrixmarket_write_pattern() {
|
||||||
|
let row_indices = vec![0, 1, 0, 0, 1];
|
||||||
|
let col_indices = vec![0, 0, 1, 2, 2];
|
||||||
|
let values = vec![(), (), (), (), ()];
|
||||||
|
let coo_matrix = CooMatrix::try_from_triplets(2, 3, row_indices, col_indices, values).unwrap();
|
||||||
|
let expected = r#"%%matrixmarket matrix coordinate pattern general
|
||||||
|
% matrixmarket file generated by nalgebra-sparse.
|
||||||
|
2 3 5
|
||||||
|
1 1
|
||||||
|
2 1
|
||||||
|
1 2
|
||||||
|
1 3
|
||||||
|
2 3
|
||||||
|
"#;
|
||||||
|
let matrixmarket_str = save_to_matrix_market_str(&coo_matrix);
|
||||||
|
assert_eq!(matrixmarket_str, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_matrixmarket_write_complex() {
|
||||||
|
let row_indices = vec![0, 1, 0, 0, 1];
|
||||||
|
let col_indices = vec![0, 0, 1, 2, 2];
|
||||||
|
let values = vec![
|
||||||
|
C64 { re: 1.0, im: 2.0 },
|
||||||
|
C64 { re: 2.0, im: 3.0 },
|
||||||
|
C64 { re: 3.0, im: 4.0 },
|
||||||
|
C64 { re: 4.0, im: 5.0 },
|
||||||
|
C64 { re: 5.0, im: 6.0 },
|
||||||
|
];
|
||||||
|
let coo_matrix = CooMatrix::try_from_triplets(2, 3, row_indices, col_indices, values).unwrap();
|
||||||
|
let expected = r#"%%matrixmarket matrix coordinate complex general
|
||||||
|
% matrixmarket file generated by nalgebra-sparse.
|
||||||
|
2 3 5
|
||||||
|
1 1 1 2
|
||||||
|
2 1 2 3
|
||||||
|
1 2 3 4
|
||||||
|
1 3 4 5
|
||||||
|
2 3 5 6
|
||||||
|
"#;
|
||||||
|
let matrixmarket_str = save_to_matrix_market_str(&coo_matrix);
|
||||||
|
assert_eq!(matrixmarket_str, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
proptest! {
|
||||||
|
#[test]
|
||||||
|
fn coo_matrix_market_roundtrip_str(coo in coo_no_duplicates(-10 ..= 10, 0 ..= 10, 0..= 10, 100)) {
|
||||||
|
let generated_matrixmarket_string = save_to_matrix_market_str(&coo);
|
||||||
|
let generated_matrix = load_coo_from_matrix_market_str(&generated_matrixmarket_string).unwrap();
|
||||||
|
assert_matrix_eq!(generated_matrix, coo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proptest! {
|
||||||
|
#[test]
|
||||||
|
fn coo_matrix_market_roundtrip_file(coo in coo_no_duplicates(-10 ..= 10, 0 ..= 10, 0..= 10, 100)) {
|
||||||
|
let temp_dir = tempdir().expect("Unable to create temporary directory");
|
||||||
|
let file_path = temp_dir.path().join("temp.mtx");
|
||||||
|
save_to_matrix_market_file(&coo,&file_path).unwrap();
|
||||||
|
let generated_matrix = load_coo_from_matrix_market_file(file_path).unwrap();
|
||||||
|
assert_matrix_eq!(generated_matrix, coo);
|
||||||
|
temp_dir.close().expect("Unable to delete temporary directory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,14 +6,15 @@ use nalgebra_sparse::csc::CscMatrix;
|
||||||
use nalgebra_sparse::csr::CsrMatrix;
|
use nalgebra_sparse::csr::CsrMatrix;
|
||||||
use nalgebra_sparse::ops::serial::{
|
use nalgebra_sparse::ops::serial::{
|
||||||
spadd_csc_prealloc, spadd_csr_prealloc, spadd_pattern, spmm_csc_dense, spmm_csc_prealloc,
|
spadd_csc_prealloc, spadd_csr_prealloc, spadd_pattern, spmm_csc_dense, spmm_csc_prealloc,
|
||||||
spmm_csr_dense, spmm_csr_pattern, spmm_csr_prealloc, spsolve_csc_lower_triangular,
|
spmm_csc_prealloc_unchecked, spmm_csr_dense, spmm_csr_pattern, spmm_csr_prealloc,
|
||||||
|
spmm_csr_prealloc_unchecked, spsolve_csc_lower_triangular,
|
||||||
};
|
};
|
||||||
use nalgebra_sparse::ops::Op;
|
use nalgebra_sparse::ops::Op;
|
||||||
use nalgebra_sparse::pattern::SparsityPattern;
|
use nalgebra_sparse::pattern::SparsityPattern;
|
||||||
use nalgebra_sparse::proptest::{csc, csr, sparsity_pattern};
|
use nalgebra_sparse::proptest::{csc, csr, sparsity_pattern};
|
||||||
|
|
||||||
use nalgebra::proptest::{matrix, vector};
|
use nalgebra::proptest::{matrix, vector};
|
||||||
use nalgebra::{DMatrix, DMatrixSlice, DMatrixSliceMut, Scalar};
|
use nalgebra::{DMatrix, DMatrixView, DMatrixViewMut, Scalar};
|
||||||
|
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
|
|
||||||
|
@ -332,10 +333,10 @@ fn csc_square_with_non_zero_diagonals() -> impl Strategy<Value = CscMatrix<f64>>
|
||||||
/// Helper function to help us call dense GEMM with our `Op` type
|
/// Helper function to help us call dense GEMM with our `Op` type
|
||||||
fn dense_gemm<'a>(
|
fn dense_gemm<'a>(
|
||||||
beta: i32,
|
beta: i32,
|
||||||
c: impl Into<DMatrixSliceMut<'a, i32>>,
|
c: impl Into<DMatrixViewMut<'a, i32>>,
|
||||||
alpha: i32,
|
alpha: i32,
|
||||||
a: Op<impl Into<DMatrixSlice<'a, i32>>>,
|
a: Op<impl Into<DMatrixView<'a, i32>>>,
|
||||||
b: Op<impl Into<DMatrixSlice<'a, i32>>>,
|
b: Op<impl Into<DMatrixView<'a, i32>>>,
|
||||||
) {
|
) {
|
||||||
let mut c = c.into();
|
let mut c = c.into();
|
||||||
let a = a.convert();
|
let a = a.convert();
|
||||||
|
@ -543,6 +544,29 @@ proptest! {
|
||||||
prop_assert_eq!(&c_pattern, c_csr.pattern());
|
prop_assert_eq!(&c_pattern, c_csr.pattern());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn spmm_csr_prealloc_unchecked_test(SpmmCsrArgs { c, beta, alpha, a, b }
|
||||||
|
in spmm_csr_prealloc_args_strategy()
|
||||||
|
) {
|
||||||
|
// Test that we get the expected result by comparing to an equivalent dense operation
|
||||||
|
// (here we give in the C matrix, so the sparsity pattern is essentially fixed)
|
||||||
|
let mut c_sparse = c.clone();
|
||||||
|
spmm_csr_prealloc_unchecked(beta, &mut c_sparse, alpha, a.as_ref(), b.as_ref()).unwrap();
|
||||||
|
|
||||||
|
let mut c_dense = DMatrix::from(&c);
|
||||||
|
let op_a_dense = match a {
|
||||||
|
Op::NoOp(ref a) => DMatrix::from(a),
|
||||||
|
Op::Transpose(ref a) => DMatrix::from(a).transpose(),
|
||||||
|
};
|
||||||
|
let op_b_dense = match b {
|
||||||
|
Op::NoOp(ref b) => DMatrix::from(b),
|
||||||
|
Op::Transpose(ref b) => DMatrix::from(b).transpose(),
|
||||||
|
};
|
||||||
|
c_dense = beta * c_dense + alpha * &op_a_dense * op_b_dense;
|
||||||
|
|
||||||
|
prop_assert_eq!(&DMatrix::from(&c_sparse), &c_dense);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn spmm_csr_prealloc_test(SpmmCsrArgs { c, beta, alpha, a, b }
|
fn spmm_csr_prealloc_test(SpmmCsrArgs { c, beta, alpha, a, b }
|
||||||
in spmm_csr_prealloc_args_strategy()
|
in spmm_csr_prealloc_args_strategy()
|
||||||
|
@ -705,6 +729,29 @@ proptest! {
|
||||||
prop_assert_eq!(&DMatrix::from(&c_sparse), &c_dense);
|
prop_assert_eq!(&DMatrix::from(&c_sparse), &c_dense);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn spmm_csc_prealloc_unchecked_test(SpmmCscArgs { c, beta, alpha, a, b }
|
||||||
|
in spmm_csc_prealloc_args_strategy()
|
||||||
|
) {
|
||||||
|
// Test that we get the expected result by comparing to an equivalent dense operation
|
||||||
|
// (here we give in the C matrix, so the sparsity pattern is essentially fixed)
|
||||||
|
let mut c_sparse = c.clone();
|
||||||
|
spmm_csc_prealloc_unchecked(beta, &mut c_sparse, alpha, a.as_ref(), b.as_ref()).unwrap();
|
||||||
|
|
||||||
|
let mut c_dense = DMatrix::from(&c);
|
||||||
|
let op_a_dense = match a {
|
||||||
|
Op::NoOp(ref a) => DMatrix::from(a),
|
||||||
|
Op::Transpose(ref a) => DMatrix::from(a).transpose(),
|
||||||
|
};
|
||||||
|
let op_b_dense = match b {
|
||||||
|
Op::NoOp(ref b) => DMatrix::from(b),
|
||||||
|
Op::Transpose(ref b) => DMatrix::from(b).transpose(),
|
||||||
|
};
|
||||||
|
c_dense = beta * c_dense + alpha * &op_a_dense * op_b_dense;
|
||||||
|
|
||||||
|
prop_assert_eq!(&DMatrix::from(&c_sparse), &c_dense);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn spmm_csc_prealloc_panics_on_dim_mismatch(
|
fn spmm_csc_prealloc_panics_on_dim_mismatch(
|
||||||
(alpha, beta, c, a, b)
|
(alpha, beta, c, a, b)
|
||||||
|
|
|
@ -1,5 +1,19 @@
|
||||||
use nalgebra_sparse::pattern::{SparsityPattern, SparsityPatternFormatError};
|
use nalgebra_sparse::pattern::{SparsityPattern, SparsityPatternFormatError};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sparsity_pattern_default() {
|
||||||
|
// Check that the pattern created with `Default::default()` is equivalent to a zero-sized pattern.
|
||||||
|
let pattern = SparsityPattern::default();
|
||||||
|
let zero = SparsityPattern::zeros(0, 0);
|
||||||
|
|
||||||
|
assert_eq!(pattern.major_dim(), zero.major_dim());
|
||||||
|
assert_eq!(pattern.minor_dim(), zero.minor_dim());
|
||||||
|
assert_eq!(pattern.major_offsets(), zero.major_offsets());
|
||||||
|
assert_eq!(pattern.minor_indices(), zero.minor_indices());
|
||||||
|
|
||||||
|
assert_eq!(pattern.nnz(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sparsity_pattern_valid_data() {
|
fn sparsity_pattern_valid_data() {
|
||||||
// Construct pattern from valid data and check that selected methods return results
|
// Construct pattern from valid data and check that selected methods return results
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
use crate::base::dimension::Dynamic;
|
use crate::base::dimension::Dyn;
|
||||||
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
|
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
|
||||||
use crate::base::storage::Owned;
|
use crate::base::storage::Owned;
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
@ -48,69 +48,69 @@ pub type SMatrix<T, const R: usize, const C: usize> =
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type DMatrix<T> = Matrix<T, Dynamic, Dynamic, VecStorage<T, Dynamic, Dynamic>>;
|
pub type DMatrix<T> = Matrix<T, Dyn, Dyn, VecStorage<T, Dyn, Dyn>>;
|
||||||
|
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 1 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 1 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx1<T> = Matrix<T, Dynamic, U1, VecStorage<T, Dynamic, U1>>;
|
pub type MatrixXx1<T> = Matrix<T, Dyn, U1, VecStorage<T, Dyn, U1>>;
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 2 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 2 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx2<T> = Matrix<T, Dynamic, U2, VecStorage<T, Dynamic, U2>>;
|
pub type MatrixXx2<T> = Matrix<T, Dyn, U2, VecStorage<T, Dyn, U2>>;
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 3 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 3 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx3<T> = Matrix<T, Dynamic, U3, VecStorage<T, Dynamic, U3>>;
|
pub type MatrixXx3<T> = Matrix<T, Dyn, U3, VecStorage<T, Dyn, U3>>;
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 4 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 4 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx4<T> = Matrix<T, Dynamic, U4, VecStorage<T, Dynamic, U4>>;
|
pub type MatrixXx4<T> = Matrix<T, Dyn, U4, VecStorage<T, Dyn, U4>>;
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 5 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 5 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx5<T> = Matrix<T, Dynamic, U5, VecStorage<T, Dynamic, U5>>;
|
pub type MatrixXx5<T> = Matrix<T, Dyn, U5, VecStorage<T, Dyn, U5>>;
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 6 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 6 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx6<T> = Matrix<T, Dynamic, U6, VecStorage<T, Dynamic, U6>>;
|
pub type MatrixXx6<T> = Matrix<T, Dyn, U6, VecStorage<T, Dyn, U6>>;
|
||||||
|
|
||||||
/// A heap-allocated, row-major, matrix with 1 rows and a dynamic number of columns.
|
/// A heap-allocated, column-major, matrix with 1 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix1xX<T> = Matrix<T, U1, Dynamic, VecStorage<T, U1, Dynamic>>;
|
pub type Matrix1xX<T> = Matrix<T, U1, Dyn, VecStorage<T, U1, Dyn>>;
|
||||||
/// A heap-allocated, row-major, matrix with 2 rows and a dynamic number of columns.
|
/// A heap-allocated, column-major, matrix with 2 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix2xX<T> = Matrix<T, U2, Dynamic, VecStorage<T, U2, Dynamic>>;
|
pub type Matrix2xX<T> = Matrix<T, U2, Dyn, VecStorage<T, U2, Dyn>>;
|
||||||
/// A heap-allocated, row-major, matrix with 3 rows and a dynamic number of columns.
|
/// A heap-allocated, column-major, matrix with 3 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix3xX<T> = Matrix<T, U3, Dynamic, VecStorage<T, U3, Dynamic>>;
|
pub type Matrix3xX<T> = Matrix<T, U3, Dyn, VecStorage<T, U3, Dyn>>;
|
||||||
/// A heap-allocated, row-major, matrix with 4 rows and a dynamic number of columns.
|
/// A heap-allocated, column-major, matrix with 4 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix4xX<T> = Matrix<T, U4, Dynamic, VecStorage<T, U4, Dynamic>>;
|
pub type Matrix4xX<T> = Matrix<T, U4, Dyn, VecStorage<T, U4, Dyn>>;
|
||||||
/// A heap-allocated, row-major, matrix with 5 rows and a dynamic number of columns.
|
/// A heap-allocated, column-major, matrix with 5 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix5xX<T> = Matrix<T, U5, Dynamic, VecStorage<T, U5, Dynamic>>;
|
pub type Matrix5xX<T> = Matrix<T, U5, Dyn, VecStorage<T, U5, Dyn>>;
|
||||||
/// A heap-allocated, row-major, matrix with 6 rows and a dynamic number of columns.
|
/// A heap-allocated, column-major, matrix with 6 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix6xX<T> = Matrix<T, U6, Dynamic, VecStorage<T, U6, Dynamic>>;
|
pub type Matrix6xX<T> = Matrix<T, U6, Dyn, VecStorage<T, U6, Dyn>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 1x1 square matrix.
|
/// A stack-allocated, column-major, 1x1 square matrix.
|
||||||
///
|
///
|
||||||
|
@ -276,7 +276,7 @@ pub type Matrix6x5<T> = Matrix<T, U6, U5, ArrayStorage<T, 6, 5>>;
|
||||||
*/
|
*/
|
||||||
/// A dynamically sized column vector.
|
/// A dynamically sized column vector.
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type DVector<T> = Matrix<T, Dynamic, U1, VecStorage<T, Dynamic, U1>>;
|
pub type DVector<T> = Matrix<T, Dyn, U1, VecStorage<T, Dyn, U1>>;
|
||||||
|
|
||||||
/// An owned D-dimensional column vector.
|
/// An owned D-dimensional column vector.
|
||||||
pub type OVector<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>;
|
pub type OVector<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>;
|
||||||
|
@ -316,7 +316,7 @@ pub type Vector6<T> = Matrix<T, U6, U1, ArrayStorage<T, 6, 1>>;
|
||||||
*/
|
*/
|
||||||
/// A dynamically sized row vector.
|
/// A dynamically sized row vector.
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type RowDVector<T> = Matrix<T, U1, Dynamic, VecStorage<T, U1, Dynamic>>;
|
pub type RowDVector<T> = Matrix<T, U1, Dyn, VecStorage<T, U1, Dyn>>;
|
||||||
|
|
||||||
/// An owned D-dimensional row vector.
|
/// An owned D-dimensional row vector.
|
||||||
pub type RowOVector<T, D> = Matrix<T, U1, D, Owned<T, U1, D>>;
|
pub type RowOVector<T, D> = Matrix<T, U1, D, Owned<T, U1, D>>;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::base::dimension::{Dynamic, U1, U2, U3, U4, U5, U6};
|
use crate::base::dimension::{Dyn, U1, U2, U3, U4, U5, U6};
|
||||||
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
|
use crate::base::matrix_view::{ViewStorage, ViewStorageMut};
|
||||||
use crate::base::{Const, Matrix};
|
use crate::base::{Const, Matrix};
|
||||||
|
use crate::slice_deprecation_note;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -13,286 +14,345 @@ use crate::base::{Const, Matrix};
|
||||||
/// A column-major matrix slice with dimensions known at compile-time.
|
/// A column-major matrix slice 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.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(SMatrixView)]
|
||||||
pub type SMatrixSlice<'a, T, const R: usize, const C: usize> =
|
pub type SMatrixSlice<'a, T, const R: usize, const C: usize> =
|
||||||
Matrix<T, Const<R>, Const<C>, SliceStorage<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
|
Matrix<T, Const<R>, Const<C>, ViewStorage<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
|
||||||
|
|
||||||
/// A column-major matrix slice dynamic numbers of rows and columns.
|
/// A column-major matrix slice 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.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type DMatrixSlice<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(DMatrixView)]
|
||||||
Matrix<T, Dynamic, Dynamic, SliceStorage<'a, T, Dynamic, Dynamic, RStride, CStride>>;
|
pub type DMatrixSlice<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, Dyn, ViewStorage<'a, T, Dyn, Dyn, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 1x1 matrix slice.
|
/// A column-major 1x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView1)]
|
||||||
pub type MatrixSlice1<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U1, SliceStorage<'a, T, U1, U1, RStride, CStride>>;
|
Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>;
|
||||||
/// A column-major 2x2 matrix slice.
|
/// A column-major 2x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView2)]
|
||||||
pub type MatrixSlice2<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U2, SliceStorage<'a, T, U2, U2, RStride, CStride>>;
|
Matrix<T, U2, U2, ViewStorage<'a, T, U2, U2, RStride, CStride>>;
|
||||||
/// A column-major 3x3 matrix slice.
|
/// A column-major 3x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView3)]
|
||||||
pub type MatrixSlice3<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U3, SliceStorage<'a, T, U3, U3, RStride, CStride>>;
|
Matrix<T, U3, U3, ViewStorage<'a, T, U3, U3, RStride, CStride>>;
|
||||||
/// A column-major 4x4 matrix slice.
|
/// A column-major 4x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView4)]
|
||||||
pub type MatrixSlice4<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U4, SliceStorage<'a, T, U4, U4, RStride, CStride>>;
|
Matrix<T, U4, U4, ViewStorage<'a, T, U4, U4, RStride, CStride>>;
|
||||||
/// A column-major 5x5 matrix slice.
|
/// A column-major 5x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView5)]
|
||||||
pub type MatrixSlice5<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U5, SliceStorage<'a, T, U5, U5, RStride, CStride>>;
|
Matrix<T, U5, U5, ViewStorage<'a, T, U5, U5, RStride, CStride>>;
|
||||||
/// A column-major 6x6 matrix slice.
|
/// A column-major 6x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView6)]
|
||||||
pub type MatrixSlice6<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U6, SliceStorage<'a, T, U6, U6, RStride, CStride>>;
|
Matrix<T, U6, U6, ViewStorage<'a, T, U6, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 1x2 matrix slice.
|
/// A column-major 1x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView1x2)]
|
||||||
pub type MatrixSlice1x2<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1x2<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U2, SliceStorage<'a, T, U1, U2, RStride, CStride>>;
|
Matrix<T, U1, U2, ViewStorage<'a, T, U1, U2, RStride, CStride>>;
|
||||||
/// A column-major 1x3 matrix slice.
|
/// A column-major 1x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView1x3)]
|
||||||
pub type MatrixSlice1x3<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1x3<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U3, SliceStorage<'a, T, U1, U3, RStride, CStride>>;
|
Matrix<T, U1, U3, ViewStorage<'a, T, U1, U3, RStride, CStride>>;
|
||||||
/// A column-major 1x4 matrix slice.
|
/// A column-major 1x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView1x4)]
|
||||||
pub type MatrixSlice1x4<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1x4<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U4, SliceStorage<'a, T, U1, U4, RStride, CStride>>;
|
Matrix<T, U1, U4, ViewStorage<'a, T, U1, U4, RStride, CStride>>;
|
||||||
/// A column-major 1x5 matrix slice.
|
/// A column-major 1x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView1x5)]
|
||||||
pub type MatrixSlice1x5<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1x5<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U5, SliceStorage<'a, T, U1, U5, RStride, CStride>>;
|
Matrix<T, U1, U5, ViewStorage<'a, T, U1, U5, RStride, CStride>>;
|
||||||
/// A column-major 1x6 matrix slice.
|
/// A column-major 1x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView1x6)]
|
||||||
pub type MatrixSlice1x6<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1x6<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U6, SliceStorage<'a, T, U1, U6, RStride, CStride>>;
|
Matrix<T, U1, U6, ViewStorage<'a, T, U1, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 2x1 matrix slice.
|
/// A column-major 2x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView2x1)]
|
||||||
pub type MatrixSlice2x1<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2x1<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U1, SliceStorage<'a, T, U2, U1, RStride, CStride>>;
|
Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>;
|
||||||
/// A column-major 2x3 matrix slice.
|
/// A column-major 2x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView2x3)]
|
||||||
pub type MatrixSlice2x3<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2x3<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U3, SliceStorage<'a, T, U2, U3, RStride, CStride>>;
|
Matrix<T, U2, U3, ViewStorage<'a, T, U2, U3, RStride, CStride>>;
|
||||||
/// A column-major 2x4 matrix slice.
|
/// A column-major 2x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView2x4)]
|
||||||
pub type MatrixSlice2x4<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2x4<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U4, SliceStorage<'a, T, U2, U4, RStride, CStride>>;
|
Matrix<T, U2, U4, ViewStorage<'a, T, U2, U4, RStride, CStride>>;
|
||||||
/// A column-major 2x5 matrix slice.
|
/// A column-major 2x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView2x5)]
|
||||||
pub type MatrixSlice2x5<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2x5<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U5, SliceStorage<'a, T, U2, U5, RStride, CStride>>;
|
Matrix<T, U2, U5, ViewStorage<'a, T, U2, U5, RStride, CStride>>;
|
||||||
/// A column-major 2x6 matrix slice.
|
/// A column-major 2x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView2x6)]
|
||||||
pub type MatrixSlice2x6<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2x6<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U6, SliceStorage<'a, T, U2, U6, RStride, CStride>>;
|
Matrix<T, U2, U6, ViewStorage<'a, T, U2, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 3x1 matrix slice.
|
/// A column-major 3x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView3x1)]
|
||||||
pub type MatrixSlice3x1<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3x1<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U1, SliceStorage<'a, T, U3, U1, RStride, CStride>>;
|
Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>;
|
||||||
/// A column-major 3x2 matrix slice.
|
/// A column-major 3x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView3x2)]
|
||||||
pub type MatrixSlice3x2<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3x2<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U2, SliceStorage<'a, T, U3, U2, RStride, CStride>>;
|
Matrix<T, U3, U2, ViewStorage<'a, T, U3, U2, RStride, CStride>>;
|
||||||
/// A column-major 3x4 matrix slice.
|
/// A column-major 3x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView3x4)]
|
||||||
pub type MatrixSlice3x4<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3x4<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U4, SliceStorage<'a, T, U3, U4, RStride, CStride>>;
|
Matrix<T, U3, U4, ViewStorage<'a, T, U3, U4, RStride, CStride>>;
|
||||||
/// A column-major 3x5 matrix slice.
|
/// A column-major 3x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView3x5)]
|
||||||
pub type MatrixSlice3x5<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3x5<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U5, SliceStorage<'a, T, U3, U5, RStride, CStride>>;
|
Matrix<T, U3, U5, ViewStorage<'a, T, U3, U5, RStride, CStride>>;
|
||||||
/// A column-major 3x6 matrix slice.
|
/// A column-major 3x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView3x6)]
|
||||||
pub type MatrixSlice3x6<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3x6<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U6, SliceStorage<'a, T, U3, U6, RStride, CStride>>;
|
Matrix<T, U3, U6, ViewStorage<'a, T, U3, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 4x1 matrix slice.
|
/// A column-major 4x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView4x1)]
|
||||||
pub type MatrixSlice4x1<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4x1<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U1, SliceStorage<'a, T, U4, U1, RStride, CStride>>;
|
Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>;
|
||||||
/// A column-major 4x2 matrix slice.
|
/// A column-major 4x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView4x2)]
|
||||||
pub type MatrixSlice4x2<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4x2<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U2, SliceStorage<'a, T, U4, U2, RStride, CStride>>;
|
Matrix<T, U4, U2, ViewStorage<'a, T, U4, U2, RStride, CStride>>;
|
||||||
/// A column-major 4x3 matrix slice.
|
/// A column-major 4x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView4x3)]
|
||||||
pub type MatrixSlice4x3<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4x3<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U3, SliceStorage<'a, T, U4, U3, RStride, CStride>>;
|
Matrix<T, U4, U3, ViewStorage<'a, T, U4, U3, RStride, CStride>>;
|
||||||
/// A column-major 4x5 matrix slice.
|
/// A column-major 4x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView4x5)]
|
||||||
pub type MatrixSlice4x5<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4x5<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U5, SliceStorage<'a, T, U4, U5, RStride, CStride>>;
|
Matrix<T, U4, U5, ViewStorage<'a, T, U4, U5, RStride, CStride>>;
|
||||||
/// A column-major 4x6 matrix slice.
|
/// A column-major 4x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView4x6)]
|
||||||
pub type MatrixSlice4x6<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4x6<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U6, SliceStorage<'a, T, U4, U6, RStride, CStride>>;
|
Matrix<T, U4, U6, ViewStorage<'a, T, U4, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 5x1 matrix slice.
|
/// A column-major 5x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView5x1)]
|
||||||
pub type MatrixSlice5x1<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5x1<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U1, SliceStorage<'a, T, U5, U1, RStride, CStride>>;
|
Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>;
|
||||||
/// A column-major 5x2 matrix slice.
|
/// A column-major 5x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView5x2)]
|
||||||
pub type MatrixSlice5x2<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5x2<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U2, SliceStorage<'a, T, U5, U2, RStride, CStride>>;
|
Matrix<T, U5, U2, ViewStorage<'a, T, U5, U2, RStride, CStride>>;
|
||||||
/// A column-major 5x3 matrix slice.
|
/// A column-major 5x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView5x3)]
|
||||||
pub type MatrixSlice5x3<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5x3<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U3, SliceStorage<'a, T, U5, U3, RStride, CStride>>;
|
Matrix<T, U5, U3, ViewStorage<'a, T, U5, U3, RStride, CStride>>;
|
||||||
/// A column-major 5x4 matrix slice.
|
/// A column-major 5x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView5x4)]
|
||||||
pub type MatrixSlice5x4<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5x4<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U4, SliceStorage<'a, T, U5, U4, RStride, CStride>>;
|
Matrix<T, U5, U4, ViewStorage<'a, T, U5, U4, RStride, CStride>>;
|
||||||
/// A column-major 5x6 matrix slice.
|
/// A column-major 5x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView5x6)]
|
||||||
pub type MatrixSlice5x6<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5x6<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U6, SliceStorage<'a, T, U5, U6, RStride, CStride>>;
|
Matrix<T, U5, U6, ViewStorage<'a, T, U5, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 6x1 matrix slice.
|
/// A column-major 6x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView6x1)]
|
||||||
pub type MatrixSlice6x1<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6x1<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U1, SliceStorage<'a, T, U6, U1, RStride, CStride>>;
|
Matrix<T, U6, U1, ViewStorage<'a, T, U6, U1, RStride, CStride>>;
|
||||||
/// A column-major 6x2 matrix slice.
|
/// A column-major 6x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView6x2)]
|
||||||
pub type MatrixSlice6x2<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6x2<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U2, SliceStorage<'a, T, U6, U2, RStride, CStride>>;
|
Matrix<T, U6, U2, ViewStorage<'a, T, U6, U2, RStride, CStride>>;
|
||||||
/// A column-major 6x3 matrix slice.
|
/// A column-major 6x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView6x3)]
|
||||||
pub type MatrixSlice6x3<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6x3<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U3, SliceStorage<'a, T, U6, U3, RStride, CStride>>;
|
Matrix<T, U6, U3, ViewStorage<'a, T, U6, U3, RStride, CStride>>;
|
||||||
/// A column-major 6x4 matrix slice.
|
/// A column-major 6x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView6x4)]
|
||||||
pub type MatrixSlice6x4<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6x4<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U4, SliceStorage<'a, T, U6, U4, RStride, CStride>>;
|
Matrix<T, U6, U4, ViewStorage<'a, T, U6, U4, RStride, CStride>>;
|
||||||
/// A column-major 6x5 matrix slice.
|
/// A column-major 6x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView6x5)]
|
||||||
pub type MatrixSlice6x5<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6x5<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U5, SliceStorage<'a, T, U6, U5, RStride, CStride>>;
|
Matrix<T, U6, U5, ViewStorage<'a, T, U6, U5, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView1xX)]
|
||||||
pub type MatrixSlice1xX<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1xX<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, Dynamic, SliceStorage<'a, T, U1, Dynamic, RStride, CStride>>;
|
Matrix<T, U1, Dyn, ViewStorage<'a, T, U1, Dyn, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView2xX)]
|
||||||
pub type MatrixSlice2xX<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2xX<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, Dynamic, SliceStorage<'a, T, U2, Dynamic, RStride, CStride>>;
|
Matrix<T, U2, Dyn, ViewStorage<'a, T, U2, Dyn, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView3xX)]
|
||||||
pub type MatrixSlice3xX<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3xX<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, Dynamic, SliceStorage<'a, T, U3, Dynamic, RStride, CStride>>;
|
Matrix<T, U3, Dyn, ViewStorage<'a, T, U3, Dyn, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView4xX)]
|
||||||
pub type MatrixSlice4xX<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4xX<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, Dynamic, SliceStorage<'a, T, U4, Dynamic, RStride, CStride>>;
|
Matrix<T, U4, Dyn, ViewStorage<'a, T, U4, Dyn, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView5xX)]
|
||||||
pub type MatrixSlice5xX<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5xX<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, Dynamic, SliceStorage<'a, T, U5, Dynamic, RStride, CStride>>;
|
Matrix<T, U5, Dyn, ViewStorage<'a, T, U5, Dyn, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixView6xX)]
|
||||||
pub type MatrixSlice6xX<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6xX<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, Dynamic, SliceStorage<'a, T, U6, Dynamic, RStride, CStride>>;
|
Matrix<T, U6, Dyn, ViewStorage<'a, T, U6, Dyn, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
|
||||||
pub type MatrixSliceXx1<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewXx1)]
|
||||||
Matrix<T, Dynamic, U1, SliceStorage<'a, T, Dynamic, U1, RStride, CStride>>;
|
pub type MatrixSliceXx1<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U1, ViewStorage<'a, T, Dyn, U1, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
|
||||||
pub type MatrixSliceXx2<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewXx2)]
|
||||||
Matrix<T, Dynamic, U2, SliceStorage<'a, T, Dynamic, U2, RStride, CStride>>;
|
pub type MatrixSliceXx2<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U2, ViewStorage<'a, T, Dyn, U2, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
|
||||||
pub type MatrixSliceXx3<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewXx3)]
|
||||||
Matrix<T, Dynamic, U3, SliceStorage<'a, T, Dynamic, U3, RStride, CStride>>;
|
pub type MatrixSliceXx3<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U3, ViewStorage<'a, T, Dyn, U3, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
|
||||||
pub type MatrixSliceXx4<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewXx4)]
|
||||||
Matrix<T, Dynamic, U4, SliceStorage<'a, T, Dynamic, U4, RStride, CStride>>;
|
pub type MatrixSliceXx4<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U4, ViewStorage<'a, T, Dyn, U4, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
|
||||||
pub type MatrixSliceXx5<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewXx5)]
|
||||||
Matrix<T, Dynamic, U5, SliceStorage<'a, T, Dynamic, U5, RStride, CStride>>;
|
pub type MatrixSliceXx5<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U5, ViewStorage<'a, T, Dyn, U5, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
|
||||||
pub type MatrixSliceXx6<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewXx6)]
|
||||||
Matrix<T, Dynamic, U6, SliceStorage<'a, T, Dynamic, U6, RStride, CStride>>;
|
pub type MatrixSliceXx6<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U6, ViewStorage<'a, T, Dyn, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column vector slice with dimensions known at compile-time.
|
/// A column vector slice 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.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorView)]
|
||||||
pub type VectorSlice<'a, T, D, RStride = U1, CStride = D> =
|
pub type VectorSlice<'a, T, D, RStride = U1, CStride = D> =
|
||||||
Matrix<T, D, U1, SliceStorage<'a, T, D, U1, RStride, CStride>>;
|
Matrix<T, D, U1, ViewStorage<'a, T, D, U1, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column vector slice with dimensions known at compile-time.
|
/// A column vector slice 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.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(SVectorView)]
|
||||||
pub type SVectorSlice<'a, T, const D: usize> =
|
pub type SVectorSlice<'a, T, const D: usize> =
|
||||||
Matrix<T, Const<D>, Const<1>, SliceStorage<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
|
Matrix<T, Const<D>, Const<1>, ViewStorage<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
|
||||||
|
|
||||||
/// A column vector slice dynamic numbers of rows and columns.
|
/// A column vector slice dynamic numbers of rows and columns.
|
||||||
pub type DVectorSlice<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(DVectorView)]
|
||||||
Matrix<T, Dynamic, U1, SliceStorage<'a, T, Dynamic, U1, RStride, CStride>>;
|
pub type DVectorSlice<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U1, ViewStorage<'a, T, Dyn, U1, RStride, CStride>>;
|
||||||
|
|
||||||
/// A 1D column vector slice.
|
/// A 1D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorView1)]
|
||||||
pub type VectorSlice1<'a, T, RStride = U1, CStride = U1> =
|
pub type VectorSlice1<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U1, SliceStorage<'a, T, U1, U1, RStride, CStride>>;
|
Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>;
|
||||||
/// A 2D column vector slice.
|
/// A 2D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorView2)]
|
||||||
pub type VectorSlice2<'a, T, RStride = U1, CStride = U2> =
|
pub type VectorSlice2<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U1, SliceStorage<'a, T, U2, U1, RStride, CStride>>;
|
Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>;
|
||||||
/// A 3D column vector slice.
|
/// A 3D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorView3)]
|
||||||
pub type VectorSlice3<'a, T, RStride = U1, CStride = U3> =
|
pub type VectorSlice3<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U1, SliceStorage<'a, T, U3, U1, RStride, CStride>>;
|
Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>;
|
||||||
/// A 4D column vector slice.
|
/// A 4D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorView4)]
|
||||||
pub type VectorSlice4<'a, T, RStride = U1, CStride = U4> =
|
pub type VectorSlice4<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U1, SliceStorage<'a, T, U4, U1, RStride, CStride>>;
|
Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>;
|
||||||
/// A 5D column vector slice.
|
/// A 5D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorView5)]
|
||||||
pub type VectorSlice5<'a, T, RStride = U1, CStride = U5> =
|
pub type VectorSlice5<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U1, SliceStorage<'a, T, U5, U1, RStride, CStride>>;
|
Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>;
|
||||||
/// A 6D column vector slice.
|
/// A 6D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorView6)]
|
||||||
pub type VectorSlice6<'a, T, RStride = U1, CStride = U6> =
|
pub type VectorSlice6<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U1, SliceStorage<'a, T, U6, U1, RStride, CStride>>;
|
Matrix<T, U6, U1, ViewStorage<'a, T, U6, U1, RStride, CStride>>;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -304,297 +364,358 @@ pub type VectorSlice6<'a, T, RStride = U1, CStride = U6> =
|
||||||
/// A column-major matrix slice with `R` rows and `C` columns.
|
/// A column-major matrix slice with `R` rows and `C` columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = "Use MatrixViewMut instead, which has an identical definition."]
|
||||||
pub type MatrixSliceMutMN<'a, T, R, C, RStride = U1, CStride = R> =
|
pub type MatrixSliceMutMN<'a, T, R, C, RStride = U1, CStride = R> =
|
||||||
Matrix<T, R, C, SliceStorageMut<'a, T, R, C, RStride, CStride>>;
|
Matrix<T, R, C, ViewStorageMut<'a, T, R, C, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major matrix slice with `D` rows and columns.
|
/// A column-major matrix slice with `D` rows and columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = "Use MatrixViewMut instead."]
|
||||||
pub type MatrixSliceMutN<'a, T, D, RStride = U1, CStride = D> =
|
pub type MatrixSliceMutN<'a, T, D, RStride = U1, CStride = D> =
|
||||||
Matrix<T, D, D, SliceStorageMut<'a, T, D, D, RStride, CStride>>;
|
Matrix<T, D, D, ViewStorageMut<'a, T, D, D, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major matrix slice with dimensions known at compile-time.
|
/// A column-major matrix slice 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.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(SMatrixViewMut)]
|
||||||
pub type SMatrixSliceMut<'a, T, const R: usize, const C: usize> =
|
pub type SMatrixSliceMut<'a, T, const R: usize, const C: usize> =
|
||||||
Matrix<T, Const<R>, Const<C>, SliceStorageMut<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
|
Matrix<T, Const<R>, Const<C>, ViewStorageMut<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
|
||||||
|
|
||||||
/// A column-major matrix slice dynamic numbers of rows and columns.
|
/// A column-major matrix slice 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.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type DMatrixSliceMut<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(DMatrixViewMut)]
|
||||||
Matrix<T, Dynamic, Dynamic, SliceStorageMut<'a, T, Dynamic, Dynamic, RStride, CStride>>;
|
pub type DMatrixSliceMut<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, Dyn, ViewStorageMut<'a, T, Dyn, Dyn, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 1x1 matrix slice.
|
/// A column-major 1x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut1)]
|
||||||
pub type MatrixSliceMut1<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U1, SliceStorageMut<'a, T, U1, U1, RStride, CStride>>;
|
Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>;
|
||||||
/// A column-major 2x2 matrix slice.
|
/// A column-major 2x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut2)]
|
||||||
pub type MatrixSliceMut2<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U2, SliceStorageMut<'a, T, U2, U2, RStride, CStride>>;
|
Matrix<T, U2, U2, ViewStorageMut<'a, T, U2, U2, RStride, CStride>>;
|
||||||
/// A column-major 3x3 matrix slice.
|
/// A column-major 3x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut3)]
|
||||||
pub type MatrixSliceMut3<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U3, SliceStorageMut<'a, T, U3, U3, RStride, CStride>>;
|
Matrix<T, U3, U3, ViewStorageMut<'a, T, U3, U3, RStride, CStride>>;
|
||||||
/// A column-major 4x4 matrix slice.
|
/// A column-major 4x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut4)]
|
||||||
pub type MatrixSliceMut4<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U4, SliceStorageMut<'a, T, U4, U4, RStride, CStride>>;
|
Matrix<T, U4, U4, ViewStorageMut<'a, T, U4, U4, RStride, CStride>>;
|
||||||
/// A column-major 5x5 matrix slice.
|
/// A column-major 5x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut5)]
|
||||||
pub type MatrixSliceMut5<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U5, SliceStorageMut<'a, T, U5, U5, RStride, CStride>>;
|
Matrix<T, U5, U5, ViewStorageMut<'a, T, U5, U5, RStride, CStride>>;
|
||||||
/// A column-major 6x6 matrix slice.
|
/// A column-major 6x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut6)]
|
||||||
pub type MatrixSliceMut6<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U6, SliceStorageMut<'a, T, U6, U6, RStride, CStride>>;
|
Matrix<T, U6, U6, ViewStorageMut<'a, T, U6, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 1x2 matrix slice.
|
/// A column-major 1x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut1x2)]
|
||||||
pub type MatrixSliceMut1x2<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1x2<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U2, SliceStorageMut<'a, T, U1, U2, RStride, CStride>>;
|
Matrix<T, U1, U2, ViewStorageMut<'a, T, U1, U2, RStride, CStride>>;
|
||||||
/// A column-major 1x3 matrix slice.
|
/// A column-major 1x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut1x3)]
|
||||||
pub type MatrixSliceMut1x3<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1x3<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U3, SliceStorageMut<'a, T, U1, U3, RStride, CStride>>;
|
Matrix<T, U1, U3, ViewStorageMut<'a, T, U1, U3, RStride, CStride>>;
|
||||||
/// A column-major 1x4 matrix slice.
|
/// A column-major 1x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut1x4)]
|
||||||
pub type MatrixSliceMut1x4<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1x4<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U4, SliceStorageMut<'a, T, U1, U4, RStride, CStride>>;
|
Matrix<T, U1, U4, ViewStorageMut<'a, T, U1, U4, RStride, CStride>>;
|
||||||
/// A column-major 1x5 matrix slice.
|
/// A column-major 1x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut1x5)]
|
||||||
pub type MatrixSliceMut1x5<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1x5<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U5, SliceStorageMut<'a, T, U1, U5, RStride, CStride>>;
|
Matrix<T, U1, U5, ViewStorageMut<'a, T, U1, U5, RStride, CStride>>;
|
||||||
/// A column-major 1x6 matrix slice.
|
/// A column-major 1x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut1x6)]
|
||||||
pub type MatrixSliceMut1x6<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1x6<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U6, SliceStorageMut<'a, T, U1, U6, RStride, CStride>>;
|
Matrix<T, U1, U6, ViewStorageMut<'a, T, U1, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 2x1 matrix slice.
|
/// A column-major 2x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut2x1)]
|
||||||
pub type MatrixSliceMut2x1<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2x1<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U1, SliceStorageMut<'a, T, U2, U1, RStride, CStride>>;
|
Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>;
|
||||||
/// A column-major 2x3 matrix slice.
|
/// A column-major 2x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut2x3)]
|
||||||
pub type MatrixSliceMut2x3<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2x3<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U3, SliceStorageMut<'a, T, U2, U3, RStride, CStride>>;
|
Matrix<T, U2, U3, ViewStorageMut<'a, T, U2, U3, RStride, CStride>>;
|
||||||
/// A column-major 2x4 matrix slice.
|
/// A column-major 2x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut2x4)]
|
||||||
pub type MatrixSliceMut2x4<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2x4<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U4, SliceStorageMut<'a, T, U2, U4, RStride, CStride>>;
|
Matrix<T, U2, U4, ViewStorageMut<'a, T, U2, U4, RStride, CStride>>;
|
||||||
/// A column-major 2x5 matrix slice.
|
/// A column-major 2x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut2x5)]
|
||||||
pub type MatrixSliceMut2x5<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2x5<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U5, SliceStorageMut<'a, T, U2, U5, RStride, CStride>>;
|
Matrix<T, U2, U5, ViewStorageMut<'a, T, U2, U5, RStride, CStride>>;
|
||||||
/// A column-major 2x6 matrix slice.
|
/// A column-major 2x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut2x6)]
|
||||||
pub type MatrixSliceMut2x6<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2x6<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U6, SliceStorageMut<'a, T, U2, U6, RStride, CStride>>;
|
Matrix<T, U2, U6, ViewStorageMut<'a, T, U2, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 3x1 matrix slice.
|
/// A column-major 3x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut3x1)]
|
||||||
pub type MatrixSliceMut3x1<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3x1<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U1, SliceStorageMut<'a, T, U3, U1, RStride, CStride>>;
|
Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>;
|
||||||
/// A column-major 3x2 matrix slice.
|
/// A column-major 3x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut3x2)]
|
||||||
pub type MatrixSliceMut3x2<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3x2<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U2, SliceStorageMut<'a, T, U3, U2, RStride, CStride>>;
|
Matrix<T, U3, U2, ViewStorageMut<'a, T, U3, U2, RStride, CStride>>;
|
||||||
/// A column-major 3x4 matrix slice.
|
/// A column-major 3x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut3x4)]
|
||||||
pub type MatrixSliceMut3x4<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3x4<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U4, SliceStorageMut<'a, T, U3, U4, RStride, CStride>>;
|
Matrix<T, U3, U4, ViewStorageMut<'a, T, U3, U4, RStride, CStride>>;
|
||||||
/// A column-major 3x5 matrix slice.
|
/// A column-major 3x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut3x5)]
|
||||||
pub type MatrixSliceMut3x5<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3x5<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U5, SliceStorageMut<'a, T, U3, U5, RStride, CStride>>;
|
Matrix<T, U3, U5, ViewStorageMut<'a, T, U3, U5, RStride, CStride>>;
|
||||||
/// A column-major 3x6 matrix slice.
|
/// A column-major 3x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut3x6)]
|
||||||
pub type MatrixSliceMut3x6<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3x6<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U6, SliceStorageMut<'a, T, U3, U6, RStride, CStride>>;
|
Matrix<T, U3, U6, ViewStorageMut<'a, T, U3, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 4x1 matrix slice.
|
/// A column-major 4x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut4x1)]
|
||||||
pub type MatrixSliceMut4x1<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4x1<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U1, SliceStorageMut<'a, T, U4, U1, RStride, CStride>>;
|
Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>;
|
||||||
/// A column-major 4x2 matrix slice.
|
/// A column-major 4x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut4x2)]
|
||||||
pub type MatrixSliceMut4x2<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4x2<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U2, SliceStorageMut<'a, T, U4, U2, RStride, CStride>>;
|
Matrix<T, U4, U2, ViewStorageMut<'a, T, U4, U2, RStride, CStride>>;
|
||||||
/// A column-major 4x3 matrix slice.
|
/// A column-major 4x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut4x3)]
|
||||||
pub type MatrixSliceMut4x3<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4x3<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U3, SliceStorageMut<'a, T, U4, U3, RStride, CStride>>;
|
Matrix<T, U4, U3, ViewStorageMut<'a, T, U4, U3, RStride, CStride>>;
|
||||||
/// A column-major 4x5 matrix slice.
|
/// A column-major 4x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut4x5)]
|
||||||
pub type MatrixSliceMut4x5<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4x5<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U5, SliceStorageMut<'a, T, U4, U5, RStride, CStride>>;
|
Matrix<T, U4, U5, ViewStorageMut<'a, T, U4, U5, RStride, CStride>>;
|
||||||
/// A column-major 4x6 matrix slice.
|
/// A column-major 4x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut4x6)]
|
||||||
pub type MatrixSliceMut4x6<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4x6<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U6, SliceStorageMut<'a, T, U4, U6, RStride, CStride>>;
|
Matrix<T, U4, U6, ViewStorageMut<'a, T, U4, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 5x1 matrix slice.
|
/// A column-major 5x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut5x1)]
|
||||||
pub type MatrixSliceMut5x1<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5x1<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U1, SliceStorageMut<'a, T, U5, U1, RStride, CStride>>;
|
Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>;
|
||||||
/// A column-major 5x2 matrix slice.
|
/// A column-major 5x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut5x2)]
|
||||||
pub type MatrixSliceMut5x2<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5x2<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U2, SliceStorageMut<'a, T, U5, U2, RStride, CStride>>;
|
Matrix<T, U5, U2, ViewStorageMut<'a, T, U5, U2, RStride, CStride>>;
|
||||||
/// A column-major 5x3 matrix slice.
|
/// A column-major 5x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut5x3)]
|
||||||
pub type MatrixSliceMut5x3<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5x3<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U3, SliceStorageMut<'a, T, U5, U3, RStride, CStride>>;
|
Matrix<T, U5, U3, ViewStorageMut<'a, T, U5, U3, RStride, CStride>>;
|
||||||
/// A column-major 5x4 matrix slice.
|
/// A column-major 5x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut5x4)]
|
||||||
pub type MatrixSliceMut5x4<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5x4<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U4, SliceStorageMut<'a, T, U5, U4, RStride, CStride>>;
|
Matrix<T, U5, U4, ViewStorageMut<'a, T, U5, U4, RStride, CStride>>;
|
||||||
/// A column-major 5x6 matrix slice.
|
/// A column-major 5x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut5x6)]
|
||||||
pub type MatrixSliceMut5x6<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5x6<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U6, SliceStorageMut<'a, T, U5, U6, RStride, CStride>>;
|
Matrix<T, U5, U6, ViewStorageMut<'a, T, U5, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 6x1 matrix slice.
|
/// A column-major 6x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut6x1)]
|
||||||
pub type MatrixSliceMut6x1<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6x1<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U1, SliceStorageMut<'a, T, U6, U1, RStride, CStride>>;
|
Matrix<T, U6, U1, ViewStorageMut<'a, T, U6, U1, RStride, CStride>>;
|
||||||
/// A column-major 6x2 matrix slice.
|
/// A column-major 6x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut6x2)]
|
||||||
pub type MatrixSliceMut6x2<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6x2<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U2, SliceStorageMut<'a, T, U6, U2, RStride, CStride>>;
|
Matrix<T, U6, U2, ViewStorageMut<'a, T, U6, U2, RStride, CStride>>;
|
||||||
/// A column-major 6x3 matrix slice.
|
/// A column-major 6x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut6x3)]
|
||||||
pub type MatrixSliceMut6x3<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6x3<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U3, SliceStorageMut<'a, T, U6, U3, RStride, CStride>>;
|
Matrix<T, U6, U3, ViewStorageMut<'a, T, U6, U3, RStride, CStride>>;
|
||||||
/// A column-major 6x4 matrix slice.
|
/// A column-major 6x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut6x4)]
|
||||||
pub type MatrixSliceMut6x4<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6x4<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U4, SliceStorageMut<'a, T, U6, U4, RStride, CStride>>;
|
Matrix<T, U6, U4, ViewStorageMut<'a, T, U6, U4, RStride, CStride>>;
|
||||||
/// A column-major 6x5 matrix slice.
|
/// A column-major 6x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut6x5)]
|
||||||
pub type MatrixSliceMut6x5<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6x5<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U5, SliceStorageMut<'a, T, U6, U5, RStride, CStride>>;
|
Matrix<T, U6, U5, ViewStorageMut<'a, T, U6, U5, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut1xX)]
|
||||||
pub type MatrixSliceMut1xX<'a, T, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1xX<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, Dynamic, SliceStorageMut<'a, T, U1, Dynamic, RStride, CStride>>;
|
Matrix<T, U1, Dyn, ViewStorageMut<'a, T, U1, Dyn, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut2xX)]
|
||||||
pub type MatrixSliceMut2xX<'a, T, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2xX<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, Dynamic, SliceStorageMut<'a, T, U2, Dynamic, RStride, CStride>>;
|
Matrix<T, U2, Dyn, ViewStorageMut<'a, T, U2, Dyn, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut3xX)]
|
||||||
pub type MatrixSliceMut3xX<'a, T, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3xX<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, Dynamic, SliceStorageMut<'a, T, U3, Dynamic, RStride, CStride>>;
|
Matrix<T, U3, Dyn, ViewStorageMut<'a, T, U3, Dyn, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut4xX)]
|
||||||
pub type MatrixSliceMut4xX<'a, T, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4xX<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, Dynamic, SliceStorageMut<'a, T, U4, Dynamic, RStride, CStride>>;
|
Matrix<T, U4, Dyn, ViewStorageMut<'a, T, U4, Dyn, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut5xX)]
|
||||||
pub type MatrixSliceMut5xX<'a, T, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5xX<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, Dynamic, SliceStorageMut<'a, T, U5, Dynamic, RStride, CStride>>;
|
Matrix<T, U5, Dyn, ViewStorageMut<'a, T, U5, Dyn, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
|
||||||
|
#[deprecated = slice_deprecation_note!(MatrixViewMut6xX)]
|
||||||
pub type MatrixSliceMut6xX<'a, T, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6xX<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, Dynamic, SliceStorageMut<'a, T, U6, Dynamic, RStride, CStride>>;
|
Matrix<T, U6, Dyn, ViewStorageMut<'a, T, U6, Dyn, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
|
||||||
pub type MatrixSliceMutXx1<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewMutXx1)]
|
||||||
Matrix<T, Dynamic, U1, SliceStorageMut<'a, T, Dynamic, U1, RStride, CStride>>;
|
pub type MatrixSliceMutXx1<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U1, ViewStorageMut<'a, T, Dyn, U1, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
|
||||||
pub type MatrixSliceMutXx2<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewMutXx2)]
|
||||||
Matrix<T, Dynamic, U2, SliceStorageMut<'a, T, Dynamic, U2, RStride, CStride>>;
|
pub type MatrixSliceMutXx2<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U2, ViewStorageMut<'a, T, Dyn, U2, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
|
||||||
pub type MatrixSliceMutXx3<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewMutXx3)]
|
||||||
Matrix<T, Dynamic, U3, SliceStorageMut<'a, T, Dynamic, U3, RStride, CStride>>;
|
pub type MatrixSliceMutXx3<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U3, ViewStorageMut<'a, T, Dyn, U3, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
|
||||||
pub type MatrixSliceMutXx4<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewMutXx4)]
|
||||||
Matrix<T, Dynamic, U4, SliceStorageMut<'a, T, Dynamic, U4, RStride, CStride>>;
|
pub type MatrixSliceMutXx4<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U4, ViewStorageMut<'a, T, Dyn, U4, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
|
||||||
pub type MatrixSliceMutXx5<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewMutXx5)]
|
||||||
Matrix<T, Dynamic, U5, SliceStorageMut<'a, T, Dynamic, U5, RStride, CStride>>;
|
pub type MatrixSliceMutXx5<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U5, ViewStorageMut<'a, T, Dyn, U5, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
|
||||||
pub type MatrixSliceMutXx6<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(MatrixViewMutXx6)]
|
||||||
Matrix<T, Dynamic, U6, SliceStorageMut<'a, T, Dynamic, U6, RStride, CStride>>;
|
pub type MatrixSliceMutXx6<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U6, ViewStorageMut<'a, T, Dyn, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column vector slice with dimensions known at compile-time.
|
/// A column vector slice 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.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorViewMut)]
|
||||||
pub type VectorSliceMut<'a, T, D, RStride = U1, CStride = D> =
|
pub type VectorSliceMut<'a, T, D, RStride = U1, CStride = D> =
|
||||||
Matrix<T, D, U1, SliceStorageMut<'a, T, D, U1, RStride, CStride>>;
|
Matrix<T, D, U1, ViewStorageMut<'a, T, D, U1, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column vector slice with dimensions known at compile-time.
|
/// A column vector slice 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.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(SVectorViewMut)]
|
||||||
pub type SVectorSliceMut<'a, T, const D: usize> =
|
pub type SVectorSliceMut<'a, T, const D: usize> =
|
||||||
Matrix<T, Const<D>, Const<1>, SliceStorageMut<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
|
Matrix<T, Const<D>, Const<1>, ViewStorageMut<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
|
||||||
|
|
||||||
/// A column vector slice dynamic numbers of rows and columns.
|
/// A column vector slice 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.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type DVectorSliceMut<'a, T, RStride = U1, CStride = Dynamic> =
|
#[deprecated = slice_deprecation_note!(DVectorViewMut)]
|
||||||
Matrix<T, Dynamic, U1, SliceStorageMut<'a, T, Dynamic, U1, RStride, CStride>>;
|
pub type DVectorSliceMut<'a, T, RStride = U1, CStride = Dyn> =
|
||||||
|
Matrix<T, Dyn, U1, ViewStorageMut<'a, T, Dyn, U1, RStride, CStride>>;
|
||||||
|
|
||||||
/// A 1D column vector slice.
|
/// A 1D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorViewMut1)]
|
||||||
pub type VectorSliceMut1<'a, T, RStride = U1, CStride = U1> =
|
pub type VectorSliceMut1<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<T, U1, U1, SliceStorageMut<'a, T, U1, U1, RStride, CStride>>;
|
Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>;
|
||||||
/// A 2D column vector slice.
|
/// A 2D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorViewMut2)]
|
||||||
pub type VectorSliceMut2<'a, T, RStride = U1, CStride = U2> =
|
pub type VectorSliceMut2<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<T, U2, U1, SliceStorageMut<'a, T, U2, U1, RStride, CStride>>;
|
Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>;
|
||||||
/// A 3D column vector slice.
|
/// A 3D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorViewMut3)]
|
||||||
pub type VectorSliceMut3<'a, T, RStride = U1, CStride = U3> =
|
pub type VectorSliceMut3<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<T, U3, U1, SliceStorageMut<'a, T, U3, U1, RStride, CStride>>;
|
Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>;
|
||||||
/// A 4D column vector slice.
|
/// A 4D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorViewMut4)]
|
||||||
pub type VectorSliceMut4<'a, T, RStride = U1, CStride = U4> =
|
pub type VectorSliceMut4<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<T, U4, U1, SliceStorageMut<'a, T, U4, U1, RStride, CStride>>;
|
Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>;
|
||||||
/// A 5D column vector slice.
|
/// A 5D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorViewMut5)]
|
||||||
pub type VectorSliceMut5<'a, T, RStride = U1, CStride = U5> =
|
pub type VectorSliceMut5<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<T, U5, U1, SliceStorageMut<'a, T, U5, U1, RStride, CStride>>;
|
Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>;
|
||||||
/// A 6D column vector slice.
|
/// A 6D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated = slice_deprecation_note!(VectorViewMut6)]
|
||||||
pub type VectorSliceMut6<'a, T, RStride = U1, CStride = U6> =
|
pub type VectorSliceMut6<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<T, U6, U1, SliceStorageMut<'a, T, U6, U1, RStride, CStride>>;
|
Matrix<T, U6, U1, ViewStorageMut<'a, T, U6, U1, RStride, CStride>>;
|
||||||
|
|
|
@ -0,0 +1,875 @@
|
||||||
|
use crate::base::dimension::{Dyn, U1, U2, U3, U4, U5, U6};
|
||||||
|
use crate::base::matrix_view::{ViewStorage, ViewStorageMut};
|
||||||
|
use crate::base::{Const, Matrix};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Matrix view aliases.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// 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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.**
|
||||||
|
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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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> =
|
||||||
|
Matrix<T, U6, U1, ViewStorage<'a, T, U6, U1, RStride, CStride>>;
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Same thing, but for mutable views.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// A mutable column-major matrix view with dimensions known at compile-time.
|
||||||
|
///
|
||||||
|
/// See [`SMatrixView`] for an immutable version of this type.
|
||||||
|
///
|
||||||
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.**
|
||||||
|
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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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.
|
||||||
|
///
|
||||||
|
/// **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> =
|
||||||
|
Matrix<T, U6, U1, ViewStorageMut<'a, T, U6, U1, RStride, CStride>>;
|
|
@ -15,14 +15,14 @@ use std::mem::MaybeUninit;
|
||||||
///
|
///
|
||||||
/// An allocator is said to be:
|
/// An allocator is said to be:
|
||||||
/// − static: if `R` and `C` both implement `DimName`.
|
/// − static: if `R` and `C` both implement `DimName`.
|
||||||
/// − dynamic: if either one (or both) of `R` or `C` is equal to `Dynamic`.
|
/// − dynamic: if either one (or both) of `R` or `C` is equal to `Dyn`.
|
||||||
///
|
///
|
||||||
/// Every allocator must be both static and dynamic. Though not all implementations may share the
|
/// Every allocator must be both static and dynamic. Though not all implementations may share the
|
||||||
/// same `Buffer` type.
|
/// same `Buffer` type.
|
||||||
pub trait Allocator<T, 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 instanciate.
|
/// The type of buffer this allocator can instantiate.
|
||||||
type Buffer: 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 instanciate.
|
/// The type of buffer with uninitialized components this allocator can instantiate.
|
||||||
type BufferUninit: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous;
|
type BufferUninit: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous;
|
||||||
|
|
||||||
/// Allocates a buffer with the given number of rows and columns without initializing its content.
|
/// Allocates a buffer with the given number of rows and columns without initializing its content.
|
||||||
|
@ -41,6 +41,41 @@ pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized {
|
||||||
ncols: C,
|
ncols: C,
|
||||||
iter: I,
|
iter: I,
|
||||||
) -> Self::Buffer;
|
) -> Self::Buffer;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Allocates a buffer initialized with the content of the given row-major order iterator.
|
||||||
|
fn allocate_from_row_iterator<I: IntoIterator<Item = T>>(
|
||||||
|
nrows: R,
|
||||||
|
ncols: C,
|
||||||
|
iter: I,
|
||||||
|
) -> Self::Buffer {
|
||||||
|
let mut res = Self::allocate_uninit(nrows, ncols);
|
||||||
|
let mut count = 0;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// OK because the allocated buffer is guaranteed to be contiguous.
|
||||||
|
let res_ptr = res.as_mut_slice_unchecked();
|
||||||
|
|
||||||
|
for (k, e) in iter
|
||||||
|
.into_iter()
|
||||||
|
.take(ncols.value() * nrows.value())
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
let i = k / ncols.value();
|
||||||
|
let j = k % ncols.value();
|
||||||
|
// result[(i, j)] = e;
|
||||||
|
*res_ptr.get_unchecked_mut(i + j * nrows.value()) = MaybeUninit::new(e);
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
count == nrows.value() * ncols.value(),
|
||||||
|
"Matrix init. from row iterator: iterator not long enough."
|
||||||
|
);
|
||||||
|
|
||||||
|
<Self as Allocator<T, R, C>>::assume_init(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A matrix reallocator. Changes the size of the memory buffer that initially contains (`RFrom` ×
|
/// A matrix reallocator. Changes the size of the memory buffer that initially contains (`RFrom` ×
|
||||||
|
|
|
@ -5,12 +5,15 @@ use std::ops::Mul;
|
||||||
#[cfg(feature = "serde-serialize-no-std")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
use serde::de::{Error, SeqAccess, Visitor};
|
use serde::de::{Error, SeqAccess, Visitor};
|
||||||
#[cfg(feature = "serde-serialize-no-std")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
use serde::ser::SerializeSeq;
|
use serde::ser::SerializeTuple;
|
||||||
#[cfg(feature = "serde-serialize-no-std")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
#[cfg(feature = "serde-serialize-no-std")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
#[cfg(feature = "rkyv-serialize")]
|
||||||
|
use rkyv::bytecheck;
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::default_allocator::DefaultAllocator;
|
use crate::base::default_allocator::DefaultAllocator;
|
||||||
use crate::base::dimension::{Const, ToTypenum};
|
use crate::base::dimension::{Const, ToTypenum};
|
||||||
|
@ -27,7 +30,18 @@ use std::mem;
|
||||||
/// A array-based statically sized matrix data storage.
|
/// A array-based statically sized matrix data storage.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
#[cfg_attr(
|
||||||
|
feature = "rkyv-serialize-no-std",
|
||||||
|
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize),
|
||||||
|
archive(
|
||||||
|
as = "ArrayStorage<T::Archived, R, C>",
|
||||||
|
bound(archive = "
|
||||||
|
T: rkyv::Archive,
|
||||||
|
[[T; R]; C]: rkyv::Archive<Archived = [[T::Archived; R]; C]>
|
||||||
|
")
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]);
|
pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]);
|
||||||
|
|
||||||
impl<T, const R: usize, const C: usize> ArrayStorage<T, R, C> {
|
impl<T, const R: usize, const C: usize> ArrayStorage<T, R, C> {
|
||||||
|
@ -177,7 +191,7 @@ where
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
let mut serializer = serializer.serialize_seq(Some(R * C))?;
|
let mut serializer = serializer.serialize_tuple(R * C)?;
|
||||||
|
|
||||||
for e in self.as_slice().iter() {
|
for e in self.as_slice().iter() {
|
||||||
serializer.serialize_element(e)?;
|
serializer.serialize_element(e)?;
|
||||||
|
@ -196,7 +210,7 @@ where
|
||||||
where
|
where
|
||||||
D: Deserializer<'a>,
|
D: Deserializer<'a>,
|
||||||
{
|
{
|
||||||
deserializer.deserialize_seq(ArrayStorageVisitor::new())
|
deserializer.deserialize_tuple(R * C, ArrayStorageVisitor::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,45 +287,3 @@ unsafe impl<T: Scalar + Copy + bytemuck::Pod, const R: usize, const C: usize> by
|
||||||
for ArrayStorage<T, R, C>
|
for ArrayStorage<T, R, C>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rkyv-serialize-no-std")]
|
|
||||||
mod rkyv_impl {
|
|
||||||
use super::ArrayStorage;
|
|
||||||
use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize};
|
|
||||||
|
|
||||||
impl<T: Archive, const R: usize, const C: usize> Archive for ArrayStorage<T, R, C> {
|
|
||||||
type Archived = ArrayStorage<T::Archived, R, C>;
|
|
||||||
type Resolver = <[[T; R]; C] as Archive>::Resolver;
|
|
||||||
|
|
||||||
fn resolve(
|
|
||||||
&self,
|
|
||||||
pos: usize,
|
|
||||||
resolver: Self::Resolver,
|
|
||||||
out: &mut core::mem::MaybeUninit<Self::Archived>,
|
|
||||||
) {
|
|
||||||
self.0.resolve(
|
|
||||||
pos + offset_of!(Self::Archived, 0),
|
|
||||||
resolver,
|
|
||||||
project_struct!(out: Self::Archived => 0),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Serialize<S>, S: Fallible + ?Sized, const R: usize, const C: usize> Serialize<S>
|
|
||||||
for ArrayStorage<T, R, C>
|
|
||||||
{
|
|
||||||
fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
|
|
||||||
self.0.serialize(serializer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Archive, D: Fallible + ?Sized, const R: usize, const C: usize>
|
|
||||||
Deserialize<ArrayStorage<T, R, C>, D> for ArrayStorage<T::Archived, R, C>
|
|
||||||
where
|
|
||||||
T::Archived: Deserialize<T, D>,
|
|
||||||
{
|
|
||||||
fn deserialize(&self, deserializer: &mut D) -> Result<ArrayStorage<T, R, C>, D::Error> {
|
|
||||||
Ok(ArrayStorage(self.0.deserialize(deserializer)?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,11 +7,11 @@ use crate::base::blas_uninit::{axcpy_uninit, gemm_uninit, gemv_uninit};
|
||||||
use crate::base::constraint::{
|
use crate::base::constraint::{
|
||||||
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
|
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
|
||||||
};
|
};
|
||||||
use crate::base::dimension::{Const, Dim, Dynamic, U1, U2, U3, U4};
|
use crate::base::dimension::{Const, Dim, Dyn, U1, U2, U3, U4};
|
||||||
use crate::base::storage::{Storage, StorageMut};
|
use crate::base::storage::{Storage, StorageMut};
|
||||||
use crate::base::uninit::Init;
|
use crate::base::uninit::Init;
|
||||||
use crate::base::{
|
use crate::base::{
|
||||||
DVectorSlice, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorSlice,
|
DVectorView, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorView,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// # Dot/scalar product
|
/// # Dot/scalar product
|
||||||
|
@ -363,8 +363,8 @@ where
|
||||||
x: &Vector<T, D3, SC>,
|
x: &Vector<T, D3, SC>,
|
||||||
beta: T,
|
beta: T,
|
||||||
dot: impl Fn(
|
dot: impl Fn(
|
||||||
&DVectorSlice<'_, T, SB::RStride, SB::CStride>,
|
&DVectorView<'_, T, SB::RStride, SB::CStride>,
|
||||||
&DVectorSlice<'_, T, SC::RStride, SC::CStride>,
|
&DVectorView<'_, T, SC::RStride, SC::CStride>,
|
||||||
) -> T,
|
) -> T,
|
||||||
) where
|
) where
|
||||||
T: One,
|
T: One,
|
||||||
|
@ -393,7 +393,7 @@ where
|
||||||
let col2 = a.column(0);
|
let col2 = a.column(0);
|
||||||
let val = unsafe { x.vget_unchecked(0).clone() };
|
let val = unsafe { x.vget_unchecked(0).clone() };
|
||||||
self.axpy(alpha.clone() * val, &col2, beta);
|
self.axpy(alpha.clone() * val, &col2, beta);
|
||||||
self[0] += alpha.clone() * dot(&a.slice_range(1.., 0), &x.rows_range(1..));
|
self[0] += alpha.clone() * dot(&a.view_range(1.., 0), &x.rows_range(1..));
|
||||||
|
|
||||||
for j in 1..dim2 {
|
for j in 1..dim2 {
|
||||||
let col2 = a.column(j);
|
let col2 = a.column(j);
|
||||||
|
@ -506,7 +506,7 @@ where
|
||||||
a: &Matrix<T, R2, C2, SB>,
|
a: &Matrix<T, R2, C2, SB>,
|
||||||
x: &Vector<T, D3, SC>,
|
x: &Vector<T, D3, SC>,
|
||||||
beta: T,
|
beta: T,
|
||||||
dot: impl Fn(&VectorSlice<'_, T, R2, SB::RStride, SB::CStride>, &Vector<T, D3, SC>) -> T,
|
dot: impl Fn(&VectorView<'_, T, R2, SB::RStride, SB::CStride>, &Vector<T, D3, SC>) -> T,
|
||||||
) where
|
) where
|
||||||
T: One,
|
T: One,
|
||||||
SB: Storage<T, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
|
@ -890,9 +890,9 @@ where
|
||||||
|
|
||||||
for j in 0..dim1 {
|
for j in 0..dim1 {
|
||||||
let val = unsafe { conjugate(y.vget_unchecked(j).clone()) };
|
let val = unsafe { conjugate(y.vget_unchecked(j).clone()) };
|
||||||
let subdim = Dynamic::new(dim1 - j);
|
let subdim = Dyn(dim1 - j);
|
||||||
// TODO: avoid bound checks.
|
// TODO: avoid bound checks.
|
||||||
self.generic_slice_mut((j, j), (subdim, Const::<1>)).axpy(
|
self.generic_view_mut((j, j), (subdim, Const::<1>)).axpy(
|
||||||
alpha.clone() * val,
|
alpha.clone() * val,
|
||||||
&x.rows_range(j..),
|
&x.rows_range(j..),
|
||||||
beta.clone(),
|
beta.clone(),
|
||||||
|
|
|
@ -13,16 +13,17 @@ use matrixmultiply;
|
||||||
use num::{One, Zero};
|
use num::{One, Zero};
|
||||||
use simba::scalar::{ClosedAdd, ClosedMul};
|
use simba::scalar::{ClosedAdd, ClosedMul};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::mem;
|
use std::{any::TypeId, mem};
|
||||||
|
|
||||||
use crate::base::constraint::{
|
use crate::base::constraint::{
|
||||||
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
|
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
|
||||||
};
|
};
|
||||||
use crate::base::dimension::{Dim, Dynamic, U1};
|
#[cfg(feature = "std")]
|
||||||
|
use crate::base::dimension::Dyn;
|
||||||
|
use crate::base::dimension::{Dim, U1};
|
||||||
use crate::base::storage::{RawStorage, RawStorageMut};
|
use crate::base::storage::{RawStorage, RawStorageMut};
|
||||||
use crate::base::uninit::InitStatus;
|
use crate::base::uninit::InitStatus;
|
||||||
use crate::base::{Matrix, Scalar, Vector};
|
use crate::base::{Matrix, Scalar, Vector};
|
||||||
use std::any::TypeId;
|
|
||||||
|
|
||||||
// # Safety
|
// # Safety
|
||||||
// The content of `y` must only contain values for which
|
// The content of `y` must only contain values for which
|
||||||
|
@ -209,16 +210,16 @@ pub unsafe fn gemm_uninit<
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
{
|
{
|
||||||
// We assume large matrices will be Dynamic but small matrices static.
|
// We assume large matrices will be Dyn but small matrices static.
|
||||||
// We could use matrixmultiply for large statically-sized matrices but the performance
|
// We could use matrixmultiply for large statically-sized matrices but the performance
|
||||||
// threshold to activate it would be different from SMALL_DIM because our code optimizes
|
// threshold to activate it would be different from SMALL_DIM because our code optimizes
|
||||||
// better for statically-sized matrices.
|
// better for statically-sized matrices.
|
||||||
if R1::is::<Dynamic>()
|
if R1::is::<Dyn>()
|
||||||
|| C1::is::<Dynamic>()
|
|| C1::is::<Dyn>()
|
||||||
|| R2::is::<Dynamic>()
|
|| R2::is::<Dyn>()
|
||||||
|| C2::is::<Dynamic>()
|
|| C2::is::<Dyn>()
|
||||||
|| R3::is::<Dynamic>()
|
|| R3::is::<Dyn>()
|
||||||
|| C3::is::<Dynamic>()
|
|| C3::is::<Dyn>()
|
||||||
{
|
{
|
||||||
// matrixmultiply can be used only if the std feature is available.
|
// matrixmultiply can be used only if the std feature is available.
|
||||||
let nrows1 = y.nrows();
|
let nrows1 = y.nrows();
|
||||||
|
|
|
@ -59,7 +59,7 @@ where
|
||||||
SB: Storage<T, DimNameDiff<D, U1>>,
|
SB: Storage<T, DimNameDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
let mut res = Self::identity();
|
let mut res = Self::identity();
|
||||||
res.generic_slice_mut(
|
res.generic_view_mut(
|
||||||
(0, D::dim() - 1),
|
(0, D::dim() - 1),
|
||||||
(DimNameDiff::<D, U1>::name(), Const::<1>),
|
(DimNameDiff::<D, U1>::name(), Const::<1>),
|
||||||
)
|
)
|
||||||
|
@ -382,19 +382,19 @@ impl<T: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<T, D
|
||||||
DefaultAllocator: Allocator<T, DimNameDiff<D, U1>>,
|
DefaultAllocator: Allocator<T, DimNameDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
let scale = self
|
let scale = self
|
||||||
.generic_slice(
|
.generic_view(
|
||||||
(D::dim() - 1, 0),
|
(D::dim() - 1, 0),
|
||||||
(Const::<1>, DimNameDiff::<D, U1>::name()),
|
(Const::<1>, DimNameDiff::<D, U1>::name()),
|
||||||
)
|
)
|
||||||
.tr_dot(shift);
|
.tr_dot(shift);
|
||||||
let post_translation = self.generic_slice(
|
let post_translation = self.generic_view(
|
||||||
(0, 0),
|
(0, 0),
|
||||||
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
|
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
|
||||||
) * shift;
|
) * shift;
|
||||||
|
|
||||||
self[(D::dim() - 1, D::dim() - 1)] += scale;
|
self[(D::dim() - 1, D::dim() - 1)] += scale;
|
||||||
|
|
||||||
let mut translation = self.generic_slice_mut(
|
let mut translation = self.generic_view_mut(
|
||||||
(0, D::dim() - 1),
|
(0, D::dim() - 1),
|
||||||
(DimNameDiff::<D, U1>::name(), Const::<1>),
|
(DimNameDiff::<D, U1>::name(), Const::<1>),
|
||||||
);
|
);
|
||||||
|
@ -415,11 +415,11 @@ where
|
||||||
&self,
|
&self,
|
||||||
v: &OVector<T, DimNameDiff<D, U1>>,
|
v: &OVector<T, DimNameDiff<D, U1>>,
|
||||||
) -> OVector<T, DimNameDiff<D, U1>> {
|
) -> OVector<T, DimNameDiff<D, U1>> {
|
||||||
let transform = self.generic_slice(
|
let transform = self.generic_view(
|
||||||
(0, 0),
|
(0, 0),
|
||||||
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
|
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
|
||||||
);
|
);
|
||||||
let normalizer = self.generic_slice(
|
let normalizer = self.generic_view(
|
||||||
(D::dim() - 1, 0),
|
(D::dim() - 1, 0),
|
||||||
(Const::<1>, DimNameDiff::<D, U1>::name()),
|
(Const::<1>, DimNameDiff::<D, U1>::name()),
|
||||||
);
|
);
|
||||||
|
@ -437,9 +437,9 @@ impl<T: RealField, S: Storage<T, Const<3>, Const<3>>> SquareMatrix<T, Const<3>,
|
||||||
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
|
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn transform_point(&self, pt: &Point<T, 2>) -> Point<T, 2> {
|
pub fn transform_point(&self, pt: &Point<T, 2>) -> Point<T, 2> {
|
||||||
let transform = self.fixed_slice::<2, 2>(0, 0);
|
let transform = self.fixed_view::<2, 2>(0, 0);
|
||||||
let translation = self.fixed_slice::<2, 1>(0, 2);
|
let translation = self.fixed_view::<2, 1>(0, 2);
|
||||||
let normalizer = self.fixed_slice::<1, 2>(2, 0);
|
let normalizer = self.fixed_view::<1, 2>(2, 0);
|
||||||
let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((2, 2)).clone() };
|
let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((2, 2)).clone() };
|
||||||
|
|
||||||
if !n.is_zero() {
|
if !n.is_zero() {
|
||||||
|
@ -454,9 +454,9 @@ impl<T: RealField, S: Storage<T, Const<4>, Const<4>>> SquareMatrix<T, Const<4>,
|
||||||
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
|
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn transform_point(&self, pt: &Point<T, 3>) -> Point<T, 3> {
|
pub fn transform_point(&self, pt: &Point<T, 3>) -> Point<T, 3> {
|
||||||
let transform = self.fixed_slice::<3, 3>(0, 0);
|
let transform = self.fixed_view::<3, 3>(0, 0);
|
||||||
let translation = self.fixed_slice::<3, 1>(0, 3);
|
let translation = self.fixed_view::<3, 1>(0, 3);
|
||||||
let normalizer = self.fixed_slice::<1, 3>(3, 0);
|
let normalizer = self.fixed_view::<1, 3>(3, 0);
|
||||||
let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((3, 3)).clone() };
|
let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((3, 3)).clone() };
|
||||||
|
|
||||||
if !n.is_zero() {
|
if !n.is_zero() {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
//! Compatibility constraints between matrix shapes, e.g., for addition or multiplication.
|
//! Compatibility constraints between matrix shapes, e.g., for addition or multiplication.
|
||||||
|
|
||||||
use crate::base::dimension::{Dim, DimName, Dynamic};
|
use crate::base::dimension::{Dim, DimName, Dyn};
|
||||||
|
|
||||||
/// A type used in `where` clauses for enforcing constraints.
|
/// A type used in `where` clauses for enforcing constraints.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct ShapeConstraint;
|
pub struct ShapeConstraint;
|
||||||
|
|
||||||
/// Constraints `C1` and `R2` to be equivalent.
|
/// Constrains `C1` and `R2` to be equivalent.
|
||||||
pub trait AreMultipliable<R1: Dim, C1: Dim, R2: Dim, C2: Dim>: DimEq<C1, R2> {}
|
pub trait AreMultipliable<R1: Dim, C1: Dim, R2: Dim, C2: Dim>: DimEq<C1, R2> {}
|
||||||
|
|
||||||
impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for ShapeConstraint where
|
impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for ShapeConstraint where
|
||||||
|
@ -14,7 +14,7 @@ impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for Sha
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constraints `D1` and `D2` to be equivalent.
|
/// Constrains `D1` and `D2` to be equivalent.
|
||||||
pub trait DimEq<D1: Dim, D2: Dim> {
|
pub trait DimEq<D1: Dim, D2: Dim> {
|
||||||
/// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level
|
/// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level
|
||||||
/// constant.
|
/// constant.
|
||||||
|
@ -25,17 +25,17 @@ impl<D: Dim> DimEq<D, D> for ShapeConstraint {
|
||||||
type Representative = D;
|
type Representative = D;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DimName> DimEq<D, Dynamic> for ShapeConstraint {
|
impl<D: DimName> DimEq<D, Dyn> for ShapeConstraint {
|
||||||
type Representative = D;
|
type Representative = D;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DimName> DimEq<Dynamic, D> for ShapeConstraint {
|
impl<D: DimName> DimEq<Dyn, D> for ShapeConstraint {
|
||||||
type Representative = D;
|
type Representative = D;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! equality_trait_decl(
|
macro_rules! equality_trait_decl(
|
||||||
($($doc: expr, $Trait: ident),* $(,)*) => {$(
|
($($doc: expr, $Trait: ident),* $(,)*) => {$(
|
||||||
// XXX: we can't do something like `DimEq<D1> for D2` because we would require a blancket impl…
|
// XXX: we can't do something like `DimEq<D1> for D2` because we would require a blanket impl…
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
pub trait $Trait<D1: Dim, D2: Dim>: DimEq<D1, D2> + DimEq<D2, D1> {
|
pub trait $Trait<D1: Dim, D2: Dim>: DimEq<D1, D2> + DimEq<D2, D1> {
|
||||||
/// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level
|
/// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level
|
||||||
|
@ -47,28 +47,28 @@ macro_rules! equality_trait_decl(
|
||||||
type Representative = D;
|
type Representative = D;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DimName> $Trait<D, Dynamic> for ShapeConstraint {
|
impl<D: DimName> $Trait<D, Dyn> for ShapeConstraint {
|
||||||
type Representative = D;
|
type Representative = D;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DimName> $Trait<Dynamic, D> for ShapeConstraint {
|
impl<D: DimName> $Trait<Dyn, D> for ShapeConstraint {
|
||||||
type Representative = D;
|
type Representative = D;
|
||||||
}
|
}
|
||||||
)*}
|
)*}
|
||||||
);
|
);
|
||||||
|
|
||||||
equality_trait_decl!(
|
equality_trait_decl!(
|
||||||
"Constraints `D1` and `D2` to be equivalent. \
|
"Constrains `D1` and `D2` to be equivalent. \
|
||||||
They are both assumed to be the number of \
|
They are both assumed to be the number of \
|
||||||
rows of a matrix.",
|
rows of a matrix.",
|
||||||
SameNumberOfRows,
|
SameNumberOfRows,
|
||||||
"Constraints `D1` and `D2` to be equivalent. \
|
"Constrains `D1` and `D2` to be equivalent. \
|
||||||
They are both assumed to be the number of \
|
They are both assumed to be the number of \
|
||||||
columns of a matrix.",
|
columns of a matrix.",
|
||||||
SameNumberOfColumns
|
SameNumberOfColumns
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Constraints D1 and D2 to be equivalent, where they both designate dimensions of algebraic
|
/// Constrains D1 and D2 to be equivalent, where they both designate dimensions of algebraic
|
||||||
/// entities (e.g. square matrices).
|
/// entities (e.g. square matrices).
|
||||||
pub trait SameDimension<D1: Dim, D2: Dim>:
|
pub trait SameDimension<D1: Dim, D2: Dim>:
|
||||||
SameNumberOfRows<D1, D2> + SameNumberOfColumns<D1, D2>
|
SameNumberOfRows<D1, D2> + SameNumberOfColumns<D1, D2>
|
||||||
|
@ -82,10 +82,10 @@ impl<D: Dim> SameDimension<D, D> for ShapeConstraint {
|
||||||
type Representative = D;
|
type Representative = D;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DimName> SameDimension<D, Dynamic> for ShapeConstraint {
|
impl<D: DimName> SameDimension<D, Dyn> for ShapeConstraint {
|
||||||
type Representative = D;
|
type Representative = D;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DimName> SameDimension<Dynamic, D> for ShapeConstraint {
|
impl<D: DimName> SameDimension<Dyn, D> for ShapeConstraint {
|
||||||
type Representative = D;
|
type Representative = D;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ use typenum::{self, Cmp, Greater};
|
||||||
use simba::scalar::{ClosedAdd, ClosedMul};
|
use simba::scalar::{ClosedAdd, ClosedMul};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{Dim, DimName, Dynamic, ToTypenum};
|
use crate::base::dimension::{Dim, DimName, Dyn, ToTypenum};
|
||||||
use crate::base::storage::RawStorage;
|
use crate::base::storage::RawStorage;
|
||||||
use crate::base::{
|
use crate::base::{
|
||||||
ArrayStorage, Const, DefaultAllocator, Matrix, OMatrix, OVector, Scalar, Unit, Vector,
|
ArrayStorage, Const, DefaultAllocator, Matrix, OMatrix, OVector, Scalar, Unit, Vector,
|
||||||
|
@ -86,6 +86,17 @@ where
|
||||||
Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter))
|
Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a matrix with all its elements filled by an row-major order iterator.
|
||||||
|
#[inline]
|
||||||
|
pub fn from_row_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = T>,
|
||||||
|
{
|
||||||
|
Self::from_data(DefaultAllocator::allocate_from_row_iterator(
|
||||||
|
nrows, ncols, iter,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a matrix with its elements filled with the components provided by a slice in
|
/// Creates a matrix with its elements filled with the components provided by a slice in
|
||||||
/// row-major order.
|
/// row-major order.
|
||||||
///
|
///
|
||||||
|
@ -215,7 +226,7 @@ where
|
||||||
SB: RawStorage<T, Const<1>, C>,
|
SB: RawStorage<T, Const<1>, C>,
|
||||||
{
|
{
|
||||||
assert!(!rows.is_empty(), "At least one row must be given.");
|
assert!(!rows.is_empty(), "At least one row must be given.");
|
||||||
let nrows = R::try_to_usize().unwrap_or_else(|| rows.len());
|
let nrows = R::try_to_usize().unwrap_or(rows.len());
|
||||||
let ncols = rows[0].len();
|
let ncols = rows[0].len();
|
||||||
assert!(
|
assert!(
|
||||||
rows.len() == nrows,
|
rows.len() == nrows,
|
||||||
|
@ -257,7 +268,7 @@ where
|
||||||
SB: RawStorage<T, R>,
|
SB: RawStorage<T, R>,
|
||||||
{
|
{
|
||||||
assert!(!columns.is_empty(), "At least one column must be given.");
|
assert!(!columns.is_empty(), "At least one column must be given.");
|
||||||
let ncols = C::try_to_usize().unwrap_or_else(|| columns.len());
|
let ncols = C::try_to_usize().unwrap_or(columns.len());
|
||||||
let nrows = columns[0].len();
|
let nrows = columns[0].len();
|
||||||
assert!(
|
assert!(
|
||||||
columns.len() == ncols,
|
columns.len() == ncols,
|
||||||
|
@ -306,12 +317,12 @@ where
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
/// # use nalgebra::{Dynamic, DMatrix, Matrix, Const};
|
/// # use nalgebra::{Dyn, DMatrix, Matrix, Const};
|
||||||
///
|
///
|
||||||
/// let vec = vec![0, 1, 2, 3, 4, 5];
|
/// let vec = vec![0, 1, 2, 3, 4, 5];
|
||||||
/// let vec_ptr = vec.as_ptr();
|
/// let vec_ptr = vec.as_ptr();
|
||||||
///
|
///
|
||||||
/// let matrix = Matrix::from_vec_generic(Dynamic::new(vec.len()), Const::<1>, vec);
|
/// let matrix = Matrix::from_vec_generic(Dyn(vec.len()), Const::<1>, vec);
|
||||||
/// let matrix_storage_ptr = matrix.data.as_vec().as_ptr();
|
/// let matrix_storage_ptr = matrix.data.as_vec().as_ptr();
|
||||||
///
|
///
|
||||||
/// // `matrix` is backed by exactly the same `Vec` as it was constructed from.
|
/// // `matrix` is backed by exactly the same `Vec` as it was constructed from.
|
||||||
|
@ -479,6 +490,36 @@ macro_rules! impl_constructors(
|
||||||
Self::from_iterator_generic($($gargs, )* iter)
|
Self::from_iterator_generic($($gargs, )* iter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a matrix or vector with all its elements filled by a row-major iterator.
|
||||||
|
///
|
||||||
|
/// The output matrix is filled row-by-row.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
|
||||||
|
/// # use std::iter;
|
||||||
|
///
|
||||||
|
/// let v = Vector3::from_row_iterator((0..3).into_iter());
|
||||||
|
/// // The additional argument represents the vector dimension.
|
||||||
|
/// let dv = DVector::from_row_iterator(3, (0..3).into_iter());
|
||||||
|
/// let m = Matrix2x3::from_row_iterator((0..6).into_iter());
|
||||||
|
/// // The two additional arguments represent the matrix dimensions.
|
||||||
|
/// let dm = DMatrix::from_row_iterator(2, 3, (0..6).into_iter());
|
||||||
|
///
|
||||||
|
/// // For Vectors from_row_iterator is identical to from_iterator
|
||||||
|
/// assert!(v.x == 0 && v.y == 1 && v.z == 2);
|
||||||
|
/// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
|
||||||
|
/// assert!(m.m11 == 0 && m.m12 == 1 && m.m13 == 2 &&
|
||||||
|
/// m.m21 == 3 && m.m22 == 4 && m.m23 == 5);
|
||||||
|
/// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 1 && dm[(0, 2)] == 2 &&
|
||||||
|
/// dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn from_row_iterator<I>($($args: usize,)* iter: I) -> Self
|
||||||
|
where I: IntoIterator<Item = T> {
|
||||||
|
Self::from_row_iterator_generic($($gargs, )* iter)
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a matrix or vector filled with the results of a function applied to each of its
|
/// Creates a matrix or vector filled with the results of a function applied to each of its
|
||||||
/// component coordinates.
|
/// component coordinates.
|
||||||
///
|
///
|
||||||
|
@ -615,35 +656,35 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Constructors of matrices with a dynamic number of columns
|
/// # Constructors of matrices with a dynamic number of columns
|
||||||
impl<T: Scalar, R: DimName> OMatrix<T, R, Dynamic>
|
impl<T: Scalar, R: DimName> OMatrix<T, R, Dyn>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, R, Dynamic>,
|
DefaultAllocator: Allocator<T, R, Dyn>,
|
||||||
{
|
{
|
||||||
impl_constructors!(R, Dynamic;
|
impl_constructors!(R, Dyn;
|
||||||
=> R: DimName;
|
=> R: DimName;
|
||||||
R::name(), Dynamic::new(ncols);
|
R::name(), Dyn(ncols);
|
||||||
ncols);
|
ncols);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Constructors of dynamic vectors and matrices with a dynamic number of rows
|
/// # Constructors of dynamic vectors and matrices with a dynamic number of rows
|
||||||
impl<T: Scalar, C: DimName> OMatrix<T, Dynamic, C>
|
impl<T: Scalar, C: DimName> OMatrix<T, Dyn, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, Dynamic, C>,
|
DefaultAllocator: Allocator<T, Dyn, C>,
|
||||||
{
|
{
|
||||||
impl_constructors!(Dynamic, C;
|
impl_constructors!(Dyn, C;
|
||||||
=> C: DimName;
|
=> C: DimName;
|
||||||
Dynamic::new(nrows), C::name();
|
Dyn(nrows), C::name();
|
||||||
nrows);
|
nrows);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Constructors of fully dynamic matrices
|
/// # Constructors of fully dynamic matrices
|
||||||
impl<T: Scalar> OMatrix<T, Dynamic, Dynamic>
|
impl<T: Scalar> OMatrix<T, Dyn, Dyn>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<T, Dynamic, Dynamic>,
|
DefaultAllocator: Allocator<T, Dyn, Dyn>,
|
||||||
{
|
{
|
||||||
impl_constructors!(Dynamic, Dynamic;
|
impl_constructors!(Dyn, Dyn;
|
||||||
;
|
;
|
||||||
Dynamic::new(nrows), Dynamic::new(ncols);
|
Dyn(nrows), Dyn(ncols);
|
||||||
nrows, ncols);
|
nrows, ncols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,19 +790,19 @@ impl_constructors_from_data!(data; R, C; // Arguments for Matri
|
||||||
R::name(), C::name(); // Arguments for `_generic` constructors.
|
R::name(), C::name(); // Arguments for `_generic` constructors.
|
||||||
); // Arguments for non-generic constructors.
|
); // Arguments for non-generic constructors.
|
||||||
|
|
||||||
impl_constructors_from_data!(data; R, Dynamic;
|
impl_constructors_from_data!(data; R, Dyn;
|
||||||
=> R: DimName;
|
=> R: DimName;
|
||||||
R::name(), Dynamic::new(data.len() / R::dim());
|
R::name(), Dyn(data.len() / R::dim());
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_constructors_from_data!(data; Dynamic, C;
|
impl_constructors_from_data!(data; Dyn, C;
|
||||||
=> C: DimName;
|
=> C: DimName;
|
||||||
Dynamic::new(data.len() / C::dim()), C::name();
|
Dyn(data.len() / C::dim()), C::name();
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_constructors_from_data!(data; Dynamic, Dynamic;
|
impl_constructors_from_data!(data; Dyn, Dyn;
|
||||||
;
|
;
|
||||||
Dynamic::new(nrows), Dynamic::new(ncols);
|
Dyn(nrows), Dyn(ncols);
|
||||||
nrows, ncols);
|
nrows, ncols);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
use crate::base::dimension::{Const, Dim, DimName, Dynamic};
|
use crate::base::dimension::{Const, Dim, DimName, Dyn};
|
||||||
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
|
use crate::base::matrix_view::{ViewStorage, ViewStorageMut};
|
||||||
use crate::base::{MatrixSlice, MatrixSliceMutMN, Scalar};
|
use crate::base::{MatrixView, MatrixViewMut, Scalar};
|
||||||
|
|
||||||
use num_rational::Ratio;
|
use num_rational::Ratio;
|
||||||
|
|
||||||
/// # Creating matrix slices from `&[T]`
|
/// # Creating matrix views from `&[T]`
|
||||||
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
MatrixSlice<'a, T, R, C, RStride, CStride>
|
MatrixView<'a, T, R, C, RStride, CStride>
|
||||||
{
|
{
|
||||||
/// Creates, without bound-checking, a matrix slice from an array and with dimensions and strides specified by generic types instances.
|
/// Creates, without bounds checking, a matrix view from an array and with dimensions and strides specified by generic types instances.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
||||||
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_with_strides_generic_unchecked(
|
pub unsafe fn from_slice_with_strides_generic_unchecked(
|
||||||
data: &'a [T],
|
data: &'a [T],
|
||||||
|
@ -22,7 +22,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
rstride: RStride,
|
rstride: RStride,
|
||||||
cstride: CStride,
|
cstride: CStride,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let data = SliceStorage::from_raw_parts(
|
let data = ViewStorage::from_raw_parts(
|
||||||
data.as_ptr().add(start),
|
data.as_ptr().add(start),
|
||||||
(nrows, ncols),
|
(nrows, ncols),
|
||||||
(rstride, cstride),
|
(rstride, cstride),
|
||||||
|
@ -30,10 +30,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
Self::from_data(data)
|
Self::from_data(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances.
|
/// Creates a matrix view from an array and with dimensions and strides specified by generic types instances.
|
||||||
///
|
///
|
||||||
/// Panics if the input data array dose not contain enough elements.
|
/// Panics if the input data array dose not contain enough elements.
|
||||||
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_with_strides_generic(
|
pub fn from_slice_with_strides_generic(
|
||||||
data: &'a [T],
|
data: &'a [T],
|
||||||
|
@ -48,7 +48,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
assert!(
|
assert!(
|
||||||
data.len() + cstride.value() + rstride.value()
|
data.len() + cstride.value() + rstride.value()
|
||||||
>= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
|
>= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
|
||||||
"Matrix slice: input data buffer to small."
|
"Matrix view: input data buffer too small."
|
||||||
);
|
);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -57,12 +57,12 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSlice<'a, T, R, C> {
|
impl<'a, T: Scalar, R: Dim, C: Dim> MatrixView<'a, T, R, C> {
|
||||||
/// Creates, without bound-checking, a matrix slice from an array and with dimensions specified by generic types instances.
|
/// Creates, without bound-checking, a matrix view from an array and with dimensions specified by generic types instances.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
||||||
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_generic_unchecked(
|
pub unsafe fn from_slice_generic_unchecked(
|
||||||
data: &'a [T],
|
data: &'a [T],
|
||||||
|
@ -75,10 +75,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSlice<'a, T, R, C> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances.
|
/// Creates a matrix view from an array and with dimensions and strides specified by generic types instances.
|
||||||
///
|
///
|
||||||
/// Panics if the input data array dose not contain enough elements.
|
/// Panics if the input data array dose not contain enough elements.
|
||||||
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_generic(data: &'a [T], nrows: R, ncols: C) -> Self {
|
pub fn from_slice_generic(data: &'a [T], nrows: R, ncols: C) -> Self {
|
||||||
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
|
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
|
||||||
|
@ -87,8 +87,8 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSlice<'a, T, R, C> {
|
||||||
|
|
||||||
macro_rules! impl_constructors(
|
macro_rules! impl_constructors(
|
||||||
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
||||||
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSlice<'a, T, $($Dims),*> {
|
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixView<'a, T, $($Dims),*> {
|
||||||
/// Creates a new matrix slice from the given data array.
|
/// Creates a new matrix view from the given data array.
|
||||||
///
|
///
|
||||||
/// Panics if `data` does not contain enough elements.
|
/// Panics if `data` does not contain enough elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -96,26 +96,33 @@ macro_rules! impl_constructors(
|
||||||
Self::from_slice_generic(data, $($gargs),*)
|
Self::from_slice_generic(data, $($gargs),*)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates, without bound checking, a new matrix slice from the given data array.
|
/// Creates, without bound checking, a new matrix view from the given data array.
|
||||||
|
/// # Safety
|
||||||
|
/// `data[start..start+rstride * cstride]` must be within bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self {
|
pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self {
|
||||||
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixSlice<'a, T, $($Dims,)* Dynamic, Dynamic> {
|
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixView<'a, T, $($Dims,)* Dyn, Dyn> {
|
||||||
/// Creates a new matrix slice with the specified strides from the given data array.
|
/// Creates a new matrix view with the specified strides from the given data array.
|
||||||
///
|
///
|
||||||
/// Panics if `data` does not contain enough elements.
|
/// Panics if `data` does not contain enough elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_with_strides(data: &'a [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
pub fn from_slice_with_strides(data: &'a [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
||||||
Self::from_slice_with_strides_generic(data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
Self::from_slice_with_strides_generic(data, $($gargs,)* Dyn(rstride), Dyn(cstride))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates, without bound checking, a new matrix slice with the specified strides from the given data array.
|
/// Creates, without bound checking, a new matrix view with the specified strides from the given data array.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `start`, `rstride`, and `cstride`, with the given matrix size will not index
|
||||||
|
/// outside of `data`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
||||||
Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dyn(rstride), Dyn(cstride))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,30 +134,30 @@ impl_constructors!(R, C; // Arguments for Matrix<T, ...,
|
||||||
R::name(), C::name(); // Arguments for `_generic` constructors.
|
R::name(), C::name(); // Arguments for `_generic` constructors.
|
||||||
); // Arguments for non-generic constructors.
|
); // Arguments for non-generic constructors.
|
||||||
|
|
||||||
impl_constructors!(R, Dynamic;
|
impl_constructors!(R, Dyn;
|
||||||
=> R: DimName;
|
=> R: DimName;
|
||||||
R::name(), Dynamic::new(ncols);
|
R::name(), Dyn(ncols);
|
||||||
ncols);
|
ncols);
|
||||||
|
|
||||||
impl_constructors!(Dynamic, C;
|
impl_constructors!(Dyn, C;
|
||||||
=> C: DimName;
|
=> C: DimName;
|
||||||
Dynamic::new(nrows), C::name();
|
Dyn(nrows), C::name();
|
||||||
nrows);
|
nrows);
|
||||||
|
|
||||||
impl_constructors!(Dynamic, Dynamic;
|
impl_constructors!(Dyn, Dyn;
|
||||||
;
|
;
|
||||||
Dynamic::new(nrows), Dynamic::new(ncols);
|
Dyn(nrows), Dyn(ncols);
|
||||||
nrows, ncols);
|
nrows, ncols);
|
||||||
|
|
||||||
/// # Creating mutable matrix slices from `&mut [T]`
|
/// # Creating mutable matrix views from `&mut [T]`
|
||||||
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
MatrixSliceMutMN<'a, T, R, C, RStride, CStride>
|
MatrixViewMut<'a, T, R, C, RStride, CStride>
|
||||||
{
|
{
|
||||||
/// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
|
/// Creates, without bound-checking, a mutable matrix view from an array and with dimensions and strides specified by generic types instances.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
||||||
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_with_strides_generic_unchecked(
|
pub unsafe fn from_slice_with_strides_generic_unchecked(
|
||||||
data: &'a mut [T],
|
data: &'a mut [T],
|
||||||
|
@ -160,7 +167,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
rstride: RStride,
|
rstride: RStride,
|
||||||
cstride: CStride,
|
cstride: CStride,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let data = SliceStorageMut::from_raw_parts(
|
let data = ViewStorageMut::from_raw_parts(
|
||||||
data.as_mut_ptr().add(start),
|
data.as_mut_ptr().add(start),
|
||||||
(nrows, ncols),
|
(nrows, ncols),
|
||||||
(rstride, cstride),
|
(rstride, cstride),
|
||||||
|
@ -168,10 +175,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
Self::from_data(data)
|
Self::from_data(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
|
/// Creates a mutable matrix view from an array and with dimensions and strides specified by generic types instances.
|
||||||
///
|
///
|
||||||
/// Panics if the input data array dose not contain enough elements.
|
/// Panics if the input data array dose not contain enough elements.
|
||||||
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_with_strides_generic(
|
pub fn from_slice_with_strides_generic(
|
||||||
data: &'a mut [T],
|
data: &'a mut [T],
|
||||||
|
@ -186,7 +193,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
assert!(
|
assert!(
|
||||||
data.len() + cstride.value() + rstride.value()
|
data.len() + cstride.value() + rstride.value()
|
||||||
>= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
|
>= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
|
||||||
"Matrix slice: input data buffer to small."
|
"Matrix view: input data buffer too small."
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -208,7 +215,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Matrix slice: dimensions and strides result in aliased indices."
|
"Matrix view: dimensions and strides result in aliased indices."
|
||||||
);
|
);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -217,12 +224,12 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, T, R, C> {
|
impl<'a, T: Scalar, R: Dim, C: Dim> MatrixViewMut<'a, T, R, C> {
|
||||||
/// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions specified by generic types instances.
|
/// Creates, without bound-checking, a mutable matrix view from an array and with dimensions specified by generic types instances.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
||||||
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_generic_unchecked(
|
pub unsafe fn from_slice_generic_unchecked(
|
||||||
data: &'a mut [T],
|
data: &'a mut [T],
|
||||||
|
@ -235,10 +242,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, T, R, C> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
|
/// Creates a mutable matrix view from an array and with dimensions and strides specified by generic types instances.
|
||||||
///
|
///
|
||||||
/// Panics if the input data array dose not contain enough elements.
|
/// Panics if the input data array dose not contain enough elements.
|
||||||
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_generic(data: &'a mut [T], nrows: R, ncols: C) -> Self {
|
pub fn from_slice_generic(data: &'a mut [T], nrows: R, ncols: C) -> Self {
|
||||||
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
|
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
|
||||||
|
@ -247,8 +254,8 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, T, R, C> {
|
||||||
|
|
||||||
macro_rules! impl_constructors_mut(
|
macro_rules! impl_constructors_mut(
|
||||||
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
||||||
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMutMN<'a, T, $($Dims),*> {
|
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixViewMut<'a, T, $($Dims),*> {
|
||||||
/// Creates a new mutable matrix slice from the given data array.
|
/// Creates a new mutable matrix view from the given data array.
|
||||||
///
|
///
|
||||||
/// Panics if `data` does not contain enough elements.
|
/// Panics if `data` does not contain enough elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -256,28 +263,34 @@ macro_rules! impl_constructors_mut(
|
||||||
Self::from_slice_generic(data, $($gargs),*)
|
Self::from_slice_generic(data, $($gargs),*)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates, without bound checking, a new mutable matrix slice from the given data array.
|
/// Creates, without bound checking, a new mutable matrix view from the given data array.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `data[start..start+(R * C)]` must be within bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self {
|
pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self {
|
||||||
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMutMN<'a, T, $($Dims,)* Dynamic, Dynamic> {
|
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixViewMut<'a, T, $($Dims,)* Dyn, Dyn> {
|
||||||
/// Creates a new mutable matrix slice with the specified strides from the given data array.
|
/// Creates a new mutable matrix view with the specified strides from the given data array.
|
||||||
///
|
///
|
||||||
/// Panics if `data` does not contain enough elements.
|
/// Panics if `data` does not contain enough elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_with_strides_mut(data: &'a mut [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
pub fn from_slice_with_strides_mut(data: &'a mut [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
||||||
Self::from_slice_with_strides_generic(
|
Self::from_slice_with_strides_generic(
|
||||||
data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
data, $($gargs,)* Dyn(rstride), Dyn(cstride))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates, without bound checking, a new mutable matrix slice with the specified strides from the given data array.
|
/// Creates, without bound checking, a new mutable matrix view with the specified strides from the given data array.
|
||||||
|
/// # Safety
|
||||||
|
/// `data[start..start+rstride * cstride]` must be within bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
||||||
Self::from_slice_with_strides_generic_unchecked(
|
Self::from_slice_with_strides_generic_unchecked(
|
||||||
data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
data, start, $($gargs,)* Dyn(rstride), Dyn(cstride))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,17 +302,17 @@ impl_constructors_mut!(R, C; // Arguments for Matrix<T,
|
||||||
R::name(), C::name(); // Arguments for `_generic` constructors.
|
R::name(), C::name(); // Arguments for `_generic` constructors.
|
||||||
); // Arguments for non-generic constructors.
|
); // Arguments for non-generic constructors.
|
||||||
|
|
||||||
impl_constructors_mut!(R, Dynamic;
|
impl_constructors_mut!(R, Dyn;
|
||||||
=> R: DimName;
|
=> R: DimName;
|
||||||
R::name(), Dynamic::new(ncols);
|
R::name(), Dyn(ncols);
|
||||||
ncols);
|
ncols);
|
||||||
|
|
||||||
impl_constructors_mut!(Dynamic, C;
|
impl_constructors_mut!(Dyn, C;
|
||||||
=> C: DimName;
|
=> C: DimName;
|
||||||
Dynamic::new(nrows), C::name();
|
Dyn(nrows), C::name();
|
||||||
nrows);
|
nrows);
|
||||||
|
|
||||||
impl_constructors_mut!(Dynamic, Dynamic;
|
impl_constructors_mut!(Dyn, Dyn;
|
||||||
;
|
;
|
||||||
Dynamic::new(nrows), Dynamic::new(ncols);
|
Dyn(nrows), Dyn(ncols);
|
||||||
nrows, ncols);
|
nrows, ncols);
|
|
@ -8,22 +8,22 @@ use simba::simd::{PrimitiveSimdValue, SimdValue};
|
||||||
|
|
||||||
use crate::base::allocator::{Allocator, SameShapeAllocator};
|
use crate::base::allocator::{Allocator, SameShapeAllocator};
|
||||||
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
|
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
|
||||||
use crate::base::dimension::Dynamic;
|
|
||||||
use crate::base::dimension::{
|
use crate::base::dimension::{
|
||||||
Const, Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
|
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::iter::{MatrixIter, MatrixIterMut};
|
use crate::base::iter::{MatrixIter, MatrixIterMut};
|
||||||
use crate::base::storage::{IsContiguous, RawStorage, RawStorageMut};
|
use crate::base::storage::{IsContiguous, RawStorage, RawStorageMut};
|
||||||
use crate::base::{
|
use crate::base::{
|
||||||
ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixSlice,
|
ArrayStorage, DVectorView, DVectorViewMut, DefaultAllocator, Matrix, MatrixView, MatrixViewMut,
|
||||||
MatrixSliceMut, OMatrix, Scalar,
|
OMatrix, Scalar,
|
||||||
};
|
};
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use crate::base::{DVector, RowDVector, VecStorage};
|
use crate::base::{DVector, RowDVector, VecStorage};
|
||||||
use crate::base::{SliceStorage, SliceStorageMut};
|
use crate::base::{ViewStorage, ViewStorageMut};
|
||||||
use crate::constraint::DimEq;
|
use crate::constraint::DimEq;
|
||||||
use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorSlice, VectorSliceMut};
|
use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorView, VectorViewMut};
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
|
|
||||||
// TODO: too bad this won't work for slice conversions.
|
// TODO: too bad this won't work for slice conversions.
|
||||||
|
@ -98,6 +98,18 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> IntoIterator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> IntoIterator
|
||||||
|
for Matrix<T, R, C, ViewStorage<'a, T, R, C, RStride, CStride>>
|
||||||
|
{
|
||||||
|
type Item = &'a T;
|
||||||
|
type IntoIter = MatrixIter<'a, T, R, C, ViewStorage<'a, T, R, C, RStride, CStride>>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
MatrixIter::new_owned(self.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> IntoIterator
|
impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> IntoIterator
|
||||||
for &'a mut Matrix<T, R, C, S>
|
for &'a mut Matrix<T, R, C, S>
|
||||||
{
|
{
|
||||||
|
@ -110,6 +122,18 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> IntoIterator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> IntoIterator
|
||||||
|
for Matrix<T, R, C, ViewStorageMut<'a, T, R, C, RStride, CStride>>
|
||||||
|
{
|
||||||
|
type Item = &'a mut T;
|
||||||
|
type IntoIter = MatrixIterMut<'a, T, R, C, ViewStorageMut<'a, T, R, C, RStride, CStride>>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
MatrixIterMut::new_owned_mut(self.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Scalar, const D: usize> From<[T; D]> for SVector<T, D> {
|
impl<T: Scalar, const D: usize> From<[T; D]> for SVector<T, D> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [T; D]) -> Self {
|
fn from(arr: [T; D]) -> Self {
|
||||||
|
@ -126,19 +150,19 @@ impl<T: Scalar, const D: usize> From<SVector<T, D>> for [T; D] {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize>
|
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize>
|
||||||
From<VectorSlice<'a, T, Const<D>, RStride, CStride>> for [T; D]
|
From<VectorView<'a, T, Const<D>, RStride, CStride>> for [T; D]
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(vec: VectorSlice<'a, T, Const<D>, RStride, CStride>) -> Self {
|
fn from(vec: VectorView<'a, T, Const<D>, RStride, CStride>) -> Self {
|
||||||
vec.into_owned().into()
|
vec.into_owned().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize>
|
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize>
|
||||||
From<VectorSliceMut<'a, T, Const<D>, RStride, CStride>> for [T; D]
|
From<VectorViewMut<'a, T, Const<D>, RStride, CStride>> for [T; D]
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(vec: VectorSliceMut<'a, T, Const<D>, RStride, CStride>) -> Self {
|
fn from(vec: VectorViewMut<'a, T, Const<D>, RStride, CStride>) -> Self {
|
||||||
vec.into_owned().into()
|
vec.into_owned().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,19 +245,19 @@ impl<T: Scalar, const R: usize, const C: usize> From<SMatrix<T, R, C>> for [[T;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize>
|
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize>
|
||||||
From<MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>> for [[T; R]; C]
|
From<MatrixView<'a, T, Const<R>, Const<C>, RStride, CStride>> for [[T; R]; C]
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(mat: MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
|
fn from(mat: MatrixView<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
|
||||||
mat.into_owned().into()
|
mat.into_owned().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize>
|
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize>
|
||||||
From<MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>> for [[T; R]; C]
|
From<MatrixViewMut<'a, T, Const<R>, Const<C>, RStride, CStride>> for [[T; R]; C]
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(mat: MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
|
fn from(mat: MatrixViewMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
|
||||||
mat.into_owned().into()
|
mat.into_owned().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,192 +313,183 @@ impl_from_into_asref_borrow_2D!(
|
||||||
);
|
);
|
||||||
|
|
||||||
impl<'a, T, RStride, CStride, const R: usize, const C: usize>
|
impl<'a, T, RStride, CStride, const R: usize, const C: usize>
|
||||||
From<MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>>
|
From<MatrixView<'a, T, Const<R>, Const<C>, RStride, CStride>>
|
||||||
for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
|
for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
T: Scalar,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
|
fn from(matrix_view: MatrixView<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_view.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, T, C, RStride, CStride> From<MatrixSlice<'a, T, Dynamic, C, RStride, CStride>>
|
impl<'a, T, C, RStride, CStride> From<MatrixView<'a, T, Dyn, C, RStride, CStride>>
|
||||||
for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>>
|
for Matrix<T, Dyn, C, VecStorage<T, Dyn, C>>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
T: Scalar,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSlice<'a, T, Dynamic, C, RStride, CStride>) -> Self {
|
fn from(matrix_view: MatrixView<'a, T, Dyn, C, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_view.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, T, R, RStride, CStride> From<MatrixSlice<'a, T, R, Dynamic, RStride, CStride>>
|
impl<'a, T, R, RStride, CStride> From<MatrixView<'a, T, R, Dyn, RStride, CStride>>
|
||||||
for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>>
|
for Matrix<T, R, Dyn, VecStorage<T, R, Dyn>>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
T: Scalar,
|
||||||
R: DimName,
|
R: DimName,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSlice<'a, T, R, Dynamic, RStride, CStride>) -> Self {
|
fn from(matrix_view: MatrixView<'a, T, R, Dyn, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_view.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, RStride, CStride, const R: usize, const C: usize>
|
impl<'a, T, RStride, CStride, const R: usize, const C: usize>
|
||||||
From<MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>>
|
From<MatrixViewMut<'a, T, Const<R>, Const<C>, RStride, CStride>>
|
||||||
for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
|
for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
T: Scalar,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
|
fn from(matrix_view: MatrixViewMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_view.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, T, C, RStride, CStride> From<MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>>
|
impl<'a, T, C, RStride, CStride> From<MatrixViewMut<'a, T, Dyn, C, RStride, CStride>>
|
||||||
for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>>
|
for Matrix<T, Dyn, C, VecStorage<T, Dyn, C>>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
T: Scalar,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>) -> Self {
|
fn from(matrix_view: MatrixViewMut<'a, T, Dyn, C, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_view.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, T, R, RStride, CStride> From<MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>>
|
impl<'a, T, R, RStride, CStride> From<MatrixViewMut<'a, T, R, Dyn, RStride, CStride>>
|
||||||
for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>>
|
for Matrix<T, R, Dyn, VecStorage<T, R, Dyn>>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
T: Scalar,
|
||||||
R: DimName,
|
R: DimName,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>) -> Self {
|
fn from(matrix_view: MatrixViewMut<'a, T, R, Dyn, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_view.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a Matrix<T, R, C, S>>
|
impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a Matrix<T, R, C, S>>
|
||||||
for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride>
|
for MatrixView<'a, T, RView, CView, RStride, CStride>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
|
||||||
R: Dim,
|
R: Dim,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
RSlice: Dim,
|
RView: Dim,
|
||||||
CSlice: Dim,
|
CView: Dim,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
S: RawStorage<T, R, C>,
|
S: RawStorage<T, R, C>,
|
||||||
ShapeConstraint: DimEq<R, RSlice>
|
ShapeConstraint:
|
||||||
+ DimEq<C, CSlice>
|
DimEq<R, RView> + DimEq<C, CView> + DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>,
|
||||||
+ DimEq<RStride, S::RStride>
|
|
||||||
+ DimEq<CStride, S::CStride>,
|
|
||||||
{
|
{
|
||||||
fn from(m: &'a Matrix<T, R, C, S>) -> Self {
|
fn from(m: &'a Matrix<T, R, C, S>) -> Self {
|
||||||
let (row, col) = m.shape_generic();
|
let (row, col) = m.shape_generic();
|
||||||
let row_slice = RSlice::from_usize(row.value());
|
let rows_result = RView::from_usize(row.value());
|
||||||
let col_slice = CSlice::from_usize(col.value());
|
let cols_result = CView::from_usize(col.value());
|
||||||
|
|
||||||
let (rstride, cstride) = m.strides();
|
let (rstride, cstride) = m.strides();
|
||||||
|
|
||||||
let rstride_slice = RStride::from_usize(rstride);
|
let rstride_result = RStride::from_usize(rstride);
|
||||||
let cstride_slice = CStride::from_usize(cstride);
|
let cstride_result = CStride::from_usize(cstride);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = SliceStorage::from_raw_parts(
|
let data = ViewStorage::from_raw_parts(
|
||||||
m.data.ptr(),
|
m.data.ptr(),
|
||||||
(row_slice, col_slice),
|
(rows_result, cols_result),
|
||||||
(rstride_slice, cstride_slice),
|
(rstride_result, cstride_result),
|
||||||
);
|
);
|
||||||
Matrix::from_data_statically_unchecked(data)
|
Matrix::from_data_statically_unchecked(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
|
impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
|
||||||
for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride>
|
for MatrixView<'a, T, RView, CView, RStride, CStride>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
|
||||||
R: Dim,
|
R: Dim,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
RSlice: Dim,
|
RView: Dim,
|
||||||
CSlice: Dim,
|
CView: Dim,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
S: RawStorage<T, R, C>,
|
S: RawStorage<T, R, C>,
|
||||||
ShapeConstraint: DimEq<R, RSlice>
|
ShapeConstraint:
|
||||||
+ DimEq<C, CSlice>
|
DimEq<R, RView> + DimEq<C, CView> + DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>,
|
||||||
+ DimEq<RStride, S::RStride>
|
|
||||||
+ DimEq<CStride, S::CStride>,
|
|
||||||
{
|
{
|
||||||
fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
|
fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
|
||||||
let (row, col) = m.shape_generic();
|
let (row, col) = m.shape_generic();
|
||||||
let row_slice = RSlice::from_usize(row.value());
|
let rows_result = RView::from_usize(row.value());
|
||||||
let col_slice = CSlice::from_usize(col.value());
|
let cols_result = CView::from_usize(col.value());
|
||||||
|
|
||||||
let (rstride, cstride) = m.strides();
|
let (rstride, cstride) = m.strides();
|
||||||
|
|
||||||
let rstride_slice = RStride::from_usize(rstride);
|
let rstride_result = RStride::from_usize(rstride);
|
||||||
let cstride_slice = CStride::from_usize(cstride);
|
let cstride_result = CStride::from_usize(cstride);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = SliceStorage::from_raw_parts(
|
let data = ViewStorage::from_raw_parts(
|
||||||
m.data.ptr(),
|
m.data.ptr(),
|
||||||
(row_slice, col_slice),
|
(rows_result, cols_result),
|
||||||
(rstride_slice, cstride_slice),
|
(rstride_result, cstride_result),
|
||||||
);
|
);
|
||||||
Matrix::from_data_statically_unchecked(data)
|
Matrix::from_data_statically_unchecked(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
|
impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
|
||||||
for MatrixSliceMut<'a, T, RSlice, CSlice, RStride, CStride>
|
for MatrixViewMut<'a, T, RView, CView, RStride, CStride>
|
||||||
where
|
where
|
||||||
T: Scalar,
|
|
||||||
R: Dim,
|
R: Dim,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
RSlice: Dim,
|
RView: Dim,
|
||||||
CSlice: Dim,
|
CView: Dim,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
S: RawStorageMut<T, R, C>,
|
S: RawStorageMut<T, R, C>,
|
||||||
ShapeConstraint: DimEq<R, RSlice>
|
ShapeConstraint:
|
||||||
+ DimEq<C, CSlice>
|
DimEq<R, RView> + DimEq<C, CView> + DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>,
|
||||||
+ DimEq<RStride, S::RStride>
|
|
||||||
+ DimEq<CStride, S::CStride>,
|
|
||||||
{
|
{
|
||||||
fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
|
fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
|
||||||
let (row, col) = m.shape_generic();
|
let (row, col) = m.shape_generic();
|
||||||
let row_slice = RSlice::from_usize(row.value());
|
let rows_result = RView::from_usize(row.value());
|
||||||
let col_slice = CSlice::from_usize(col.value());
|
let cols_result = CView::from_usize(col.value());
|
||||||
|
|
||||||
let (rstride, cstride) = m.strides();
|
let (rstride, cstride) = m.strides();
|
||||||
|
|
||||||
let rstride_slice = RStride::from_usize(rstride);
|
let rstride_result = RStride::from_usize(rstride);
|
||||||
let cstride_slice = CStride::from_usize(cstride);
|
let cstride_result = CStride::from_usize(cstride);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = SliceStorageMut::from_raw_parts(
|
let data = ViewStorageMut::from_raw_parts(
|
||||||
m.data.ptr_mut(),
|
m.data.ptr_mut(),
|
||||||
(row_slice, col_slice),
|
(rows_result, cols_result),
|
||||||
(rstride_slice, cstride_slice),
|
(rstride_result, cstride_result),
|
||||||
);
|
);
|
||||||
Matrix::from_data_statically_unchecked(data)
|
Matrix::from_data_statically_unchecked(data)
|
||||||
}
|
}
|
||||||
|
@ -482,7 +497,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, T: Scalar> From<Vec<T>> for DVector<T> {
|
impl<T: Scalar> From<Vec<T>> for DVector<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(vec: Vec<T>) -> Self {
|
fn from(vec: Vec<T>) -> Self {
|
||||||
Self::from_vec(vec)
|
Self::from_vec(vec)
|
||||||
|
@ -490,7 +505,7 @@ impl<'a, T: Scalar> From<Vec<T>> for DVector<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, T: Scalar> From<Vec<T>> for RowDVector<T> {
|
impl<T: Scalar> From<Vec<T>> for RowDVector<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(vec: Vec<T>) -> Self {
|
fn from(vec: Vec<T>) -> Self {
|
||||||
Self::from_vec(vec)
|
Self::from_vec(vec)
|
||||||
|
@ -515,28 +530,28 @@ impl<'a, T: Scalar + Copy, R: Dim, C: Dim, S: RawStorageMut<T, R, C> + IsContigu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar + Copy> From<&'a [T]> for DVectorSlice<'a, T> {
|
impl<'a, T: Scalar + Copy> From<&'a [T]> for DVectorView<'a, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(slice: &'a [T]) -> Self {
|
fn from(slice: &'a [T]) -> Self {
|
||||||
Self::from_slice(slice, slice.len())
|
Self::from_slice(slice, slice.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar> From<DVectorSlice<'a, T>> for &'a [T] {
|
impl<'a, T: Scalar> From<DVectorView<'a, T>> for &'a [T] {
|
||||||
fn from(vec: DVectorSlice<'a, T>) -> &'a [T] {
|
fn from(vec: DVectorView<'a, T>) -> &'a [T] {
|
||||||
vec.data.into_slice()
|
vec.data.into_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar + Copy> From<&'a mut [T]> for DVectorSliceMut<'a, T> {
|
impl<'a, T: Scalar + Copy> From<&'a mut [T]> for DVectorViewMut<'a, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(slice: &'a mut [T]) -> Self {
|
fn from(slice: &'a mut [T]) -> Self {
|
||||||
Self::from_slice(slice, slice.len())
|
Self::from_slice(slice, slice.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Scalar> From<DVectorSliceMut<'a, T>> for &'a mut [T] {
|
impl<'a, T: Scalar> From<DVectorViewMut<'a, T>> for &'a mut [T] {
|
||||||
fn from(vec: DVectorSliceMut<'a, T>) -> &'a mut [T] {
|
fn from(vec: DVectorViewMut<'a, T>) -> &'a mut [T] {
|
||||||
vec.data.into_slice_mut()
|
vec.data.into_slice_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,21 +12,23 @@ use alloc::vec::Vec;
|
||||||
use super::Const;
|
use super::Const;
|
||||||
use crate::base::allocator::{Allocator, Reallocator};
|
use crate::base::allocator::{Allocator, Reallocator};
|
||||||
use crate::base::array_storage::ArrayStorage;
|
use crate::base::array_storage::ArrayStorage;
|
||||||
|
use crate::base::dimension::Dim;
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
use crate::base::dimension::Dynamic;
|
use crate::base::dimension::{DimName, Dyn};
|
||||||
use crate::base::dimension::{Dim, DimName};
|
|
||||||
use crate::base::storage::{RawStorage, RawStorageMut};
|
use crate::base::storage::{RawStorage, RawStorageMut};
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use crate::base::vec_storage::VecStorage;
|
use crate::base::vec_storage::VecStorage;
|
||||||
use crate::base::Scalar;
|
use crate::base::Scalar;
|
||||||
use std::mem::{ManuallyDrop, MaybeUninit};
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
use std::mem::ManuallyDrop;
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Allocator.
|
* Allocator.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/// An allocator based on `GenericArray` and `VecStorage` for statically-sized and dynamically-sized
|
/// An allocator based on [`ArrayStorage`] and [`VecStorage`] for statically-sized and dynamically-sized
|
||||||
/// matrices respectively.
|
/// matrices respectively.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct DefaultAllocator;
|
pub struct DefaultAllocator;
|
||||||
|
@ -82,15 +84,15 @@ impl<T: Scalar, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamic - Static
|
// Dyn - Static
|
||||||
// Dynamic - Dynamic
|
// Dyn - Dyn
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<T: Scalar, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
|
impl<T: Scalar, C: Dim> Allocator<T, Dyn, C> for DefaultAllocator {
|
||||||
type Buffer = VecStorage<T, Dynamic, C>;
|
type Buffer = VecStorage<T, Dyn, C>;
|
||||||
type BufferUninit = VecStorage<MaybeUninit<T>, Dynamic, C>;
|
type BufferUninit = VecStorage<MaybeUninit<T>, Dyn, C>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn allocate_uninit(nrows: Dynamic, ncols: C) -> VecStorage<MaybeUninit<T>, Dynamic, C> {
|
fn allocate_uninit(nrows: Dyn, ncols: C) -> VecStorage<MaybeUninit<T>, Dyn, C> {
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
let length = nrows.value() * ncols.value();
|
let length = nrows.value() * ncols.value();
|
||||||
data.reserve_exact(length);
|
data.reserve_exact(length);
|
||||||
|
@ -99,9 +101,7 @@ impl<T: Scalar, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn assume_init(
|
unsafe fn assume_init(uninit: VecStorage<MaybeUninit<T>, Dyn, C>) -> VecStorage<T, Dyn, C> {
|
||||||
uninit: VecStorage<MaybeUninit<T>, Dynamic, C>,
|
|
||||||
) -> VecStorage<T, Dynamic, C> {
|
|
||||||
// Avoids a double-drop.
|
// Avoids a double-drop.
|
||||||
let (nrows, ncols) = uninit.shape();
|
let (nrows, ncols) = uninit.shape();
|
||||||
let vec: Vec<_> = uninit.into();
|
let vec: Vec<_> = uninit.into();
|
||||||
|
@ -117,7 +117,7 @@ impl<T: Scalar, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
|
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
|
||||||
nrows: Dynamic,
|
nrows: Dyn,
|
||||||
ncols: C,
|
ncols: C,
|
||||||
iter: I,
|
iter: I,
|
||||||
) -> Self::Buffer {
|
) -> Self::Buffer {
|
||||||
|
@ -130,14 +130,14 @@ impl<T: Scalar, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static - Dynamic
|
// Static - Dyn
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<T: Scalar, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
|
impl<T: Scalar, R: DimName> Allocator<T, R, Dyn> for DefaultAllocator {
|
||||||
type Buffer = VecStorage<T, R, Dynamic>;
|
type Buffer = VecStorage<T, R, Dyn>;
|
||||||
type BufferUninit = VecStorage<MaybeUninit<T>, R, Dynamic>;
|
type BufferUninit = VecStorage<MaybeUninit<T>, R, Dyn>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn allocate_uninit(nrows: R, ncols: Dynamic) -> VecStorage<MaybeUninit<T>, R, Dynamic> {
|
fn allocate_uninit(nrows: R, ncols: Dyn) -> VecStorage<MaybeUninit<T>, R, Dyn> {
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
let length = nrows.value() * ncols.value();
|
let length = nrows.value() * ncols.value();
|
||||||
data.reserve_exact(length);
|
data.reserve_exact(length);
|
||||||
|
@ -147,9 +147,7 @@ impl<T: Scalar, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn assume_init(
|
unsafe fn assume_init(uninit: VecStorage<MaybeUninit<T>, R, Dyn>) -> VecStorage<T, R, Dyn> {
|
||||||
uninit: VecStorage<MaybeUninit<T>, R, Dynamic>,
|
|
||||||
) -> VecStorage<T, R, Dynamic> {
|
|
||||||
// Avoids a double-drop.
|
// Avoids a double-drop.
|
||||||
let (nrows, ncols) = uninit.shape();
|
let (nrows, ncols) = uninit.shape();
|
||||||
let vec: Vec<_> = uninit.into();
|
let vec: Vec<_> = uninit.into();
|
||||||
|
@ -166,7 +164,7 @@ impl<T: Scalar, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
|
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
|
||||||
nrows: R,
|
nrows: R,
|
||||||
ncols: Dynamic,
|
ncols: Dyn,
|
||||||
iter: I,
|
iter: I,
|
||||||
) -> Self::Buffer {
|
) -> Self::Buffer {
|
||||||
let it = iter.into_iter();
|
let it = iter.into_iter();
|
||||||
|
@ -215,20 +213,20 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static × Static -> Dynamic × Any
|
// Static × Static -> Dyn × Any
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<T: Scalar, CTo, const RFROM: usize, const CFROM: usize>
|
impl<T: Scalar, CTo, const RFROM: usize, const CFROM: usize>
|
||||||
Reallocator<T, Const<RFROM>, Const<CFROM>, Dynamic, CTo> for DefaultAllocator
|
Reallocator<T, Const<RFROM>, Const<CFROM>, Dyn, CTo> for DefaultAllocator
|
||||||
where
|
where
|
||||||
CTo: Dim,
|
CTo: Dim,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn reallocate_copy(
|
unsafe fn reallocate_copy(
|
||||||
rto: Dynamic,
|
rto: Dyn,
|
||||||
cto: CTo,
|
cto: CTo,
|
||||||
buf: ArrayStorage<T, RFROM, CFROM>,
|
buf: ArrayStorage<T, RFROM, CFROM>,
|
||||||
) -> VecStorage<MaybeUninit<T>, Dynamic, CTo> {
|
) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
|
||||||
let mut res = <Self as Allocator<T, Dynamic, CTo>>::allocate_uninit(rto, cto);
|
let mut res = <Self as Allocator<T, Dyn, CTo>>::allocate_uninit(rto, cto);
|
||||||
|
|
||||||
let (rfrom, cfrom) = buf.shape();
|
let (rfrom, cfrom) = buf.shape();
|
||||||
|
|
||||||
|
@ -246,20 +244,20 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static × Static -> Static × Dynamic
|
// Static × Static -> Static × Dyn
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<T: Scalar, RTo, const RFROM: usize, const CFROM: usize>
|
impl<T: Scalar, RTo, const RFROM: usize, const CFROM: usize>
|
||||||
Reallocator<T, Const<RFROM>, Const<CFROM>, RTo, Dynamic> for DefaultAllocator
|
Reallocator<T, Const<RFROM>, Const<CFROM>, RTo, Dyn> for DefaultAllocator
|
||||||
where
|
where
|
||||||
RTo: DimName,
|
RTo: DimName,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn reallocate_copy(
|
unsafe fn reallocate_copy(
|
||||||
rto: RTo,
|
rto: RTo,
|
||||||
cto: Dynamic,
|
cto: Dyn,
|
||||||
buf: ArrayStorage<T, RFROM, CFROM>,
|
buf: ArrayStorage<T, RFROM, CFROM>,
|
||||||
) -> VecStorage<MaybeUninit<T>, RTo, Dynamic> {
|
) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
|
||||||
let mut res = <Self as Allocator<T, RTo, Dynamic>>::allocate_uninit(rto, cto);
|
let mut res = <Self as Allocator<T, RTo, Dyn>>::allocate_uninit(rto, cto);
|
||||||
|
|
||||||
let (rfrom, cfrom) = buf.shape();
|
let (rfrom, cfrom) = buf.shape();
|
||||||
|
|
||||||
|
@ -279,60 +277,58 @@ where
|
||||||
|
|
||||||
// All conversion from a dynamic buffer to a dynamic buffer.
|
// All conversion from a dynamic buffer to a dynamic buffer.
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<T: Scalar, CFrom: Dim, CTo: Dim> Reallocator<T, Dynamic, CFrom, Dynamic, CTo>
|
impl<T: Scalar, CFrom: Dim, CTo: Dim> Reallocator<T, Dyn, CFrom, Dyn, CTo> for DefaultAllocator {
|
||||||
for DefaultAllocator
|
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn reallocate_copy(
|
unsafe fn reallocate_copy(
|
||||||
rto: Dynamic,
|
rto: Dyn,
|
||||||
cto: CTo,
|
cto: CTo,
|
||||||
buf: VecStorage<T, Dynamic, CFrom>,
|
buf: VecStorage<T, Dyn, CFrom>,
|
||||||
) -> VecStorage<MaybeUninit<T>, Dynamic, CTo> {
|
) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
|
||||||
let new_buf = buf.resize(rto.value() * cto.value());
|
let new_buf = buf.resize(rto.value() * cto.value());
|
||||||
VecStorage::new(rto, cto, new_buf)
|
VecStorage::new(rto, cto, new_buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<T: Scalar, CFrom: Dim, RTo: DimName> Reallocator<T, Dynamic, CFrom, RTo, Dynamic>
|
impl<T: Scalar, CFrom: Dim, RTo: DimName> Reallocator<T, Dyn, CFrom, RTo, Dyn>
|
||||||
for DefaultAllocator
|
for DefaultAllocator
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn reallocate_copy(
|
unsafe fn reallocate_copy(
|
||||||
rto: RTo,
|
rto: RTo,
|
||||||
cto: Dynamic,
|
cto: Dyn,
|
||||||
buf: VecStorage<T, Dynamic, CFrom>,
|
buf: VecStorage<T, Dyn, CFrom>,
|
||||||
) -> VecStorage<MaybeUninit<T>, RTo, Dynamic> {
|
) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
|
||||||
let new_buf = buf.resize(rto.value() * cto.value());
|
let new_buf = buf.resize(rto.value() * cto.value());
|
||||||
VecStorage::new(rto, cto, new_buf)
|
VecStorage::new(rto, cto, new_buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<T: Scalar, RFrom: DimName, CTo: Dim> Reallocator<T, RFrom, Dynamic, Dynamic, CTo>
|
impl<T: Scalar, RFrom: DimName, CTo: Dim> Reallocator<T, RFrom, Dyn, Dyn, CTo>
|
||||||
for DefaultAllocator
|
for DefaultAllocator
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn reallocate_copy(
|
unsafe fn reallocate_copy(
|
||||||
rto: Dynamic,
|
rto: Dyn,
|
||||||
cto: CTo,
|
cto: CTo,
|
||||||
buf: VecStorage<T, RFrom, Dynamic>,
|
buf: VecStorage<T, RFrom, Dyn>,
|
||||||
) -> VecStorage<MaybeUninit<T>, Dynamic, CTo> {
|
) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
|
||||||
let new_buf = buf.resize(rto.value() * cto.value());
|
let new_buf = buf.resize(rto.value() * cto.value());
|
||||||
VecStorage::new(rto, cto, new_buf)
|
VecStorage::new(rto, cto, new_buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<T: Scalar, RFrom: DimName, RTo: DimName> Reallocator<T, RFrom, Dynamic, RTo, Dynamic>
|
impl<T: Scalar, RFrom: DimName, RTo: DimName> Reallocator<T, RFrom, Dyn, RTo, Dyn>
|
||||||
for DefaultAllocator
|
for DefaultAllocator
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn reallocate_copy(
|
unsafe fn reallocate_copy(
|
||||||
rto: RTo,
|
rto: RTo,
|
||||||
cto: Dynamic,
|
cto: Dyn,
|
||||||
buf: VecStorage<T, RFrom, Dynamic>,
|
buf: VecStorage<T, RFrom, Dyn>,
|
||||||
) -> VecStorage<MaybeUninit<T>, RTo, Dynamic> {
|
) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
|
||||||
let new_buf = buf.resize(rto.value() * cto.value());
|
let new_buf = buf.resize(rto.value() * cto.value());
|
||||||
VecStorage::new(rto, cto, new_buf)
|
VecStorage::new(rto, cto, new_buf)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,54 +8,69 @@ use std::fmt::Debug;
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
use std::ops::{Add, Div, Mul, Sub};
|
||||||
use typenum::{self, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, Unsigned};
|
use typenum::{self, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, Unsigned};
|
||||||
|
|
||||||
|
#[cfg(feature = "rkyv-serialize")]
|
||||||
|
use rkyv::bytecheck;
|
||||||
#[cfg(feature = "serde-serialize-no-std")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
/// Dim of dynamically-sized algebraic entities.
|
/// Dim of dynamically-sized algebraic entities.
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
#[cfg_attr(
|
||||||
pub struct Dynamic {
|
feature = "rkyv-serialize-no-std",
|
||||||
value: usize,
|
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
|
||||||
}
|
)]
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "rkyv-serialize",
|
||||||
|
archive_attr(derive(bytecheck::CheckBytes))
|
||||||
|
)]
|
||||||
|
pub struct Dyn(pub usize);
|
||||||
|
|
||||||
impl Dynamic {
|
#[deprecated(note = "use Dyn instead.")]
|
||||||
|
pub type Dynamic = Dyn;
|
||||||
|
|
||||||
|
impl Dyn {
|
||||||
/// A dynamic size equal to `value`.
|
/// A dynamic size equal to `value`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[deprecated(note = "use Dyn(value) instead.")]
|
||||||
pub const fn new(value: usize) -> Self {
|
pub const fn new(value: usize) -> Self {
|
||||||
Self { value }
|
Self(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize-no-std")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
impl Serialize for Dynamic {
|
impl Serialize for Dyn {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
self.value.serialize(serializer)
|
self.0.serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize-no-std")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
impl<'de> Deserialize<'de> for Dynamic {
|
impl<'de> Deserialize<'de> for Dyn {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
usize::deserialize(deserializer).map(|x| Dynamic { value: x })
|
usize::deserialize(deserializer).map(|x| Dyn(x))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait implemented by `Dynamic`.
|
/// Trait implemented by `Dyn`.
|
||||||
pub trait IsDynamic {}
|
pub trait IsDynamic {}
|
||||||
/// Trait implemented by `Dynamic` and type-level integers different from `U1`.
|
/// Trait implemented by `Dyn` and type-level integers different from `U1`.
|
||||||
pub trait IsNotStaticOne {}
|
pub trait IsNotStaticOne {}
|
||||||
|
|
||||||
impl IsDynamic for Dynamic {}
|
impl IsDynamic for Dyn {}
|
||||||
impl IsNotStaticOne for Dynamic {}
|
impl IsNotStaticOne for Dyn {}
|
||||||
|
|
||||||
/// Trait implemented by any type that can be used as a dimension. This includes type-level
|
/// Trait implemented by any type that can be used as a dimension. This includes type-level
|
||||||
/// integers and `Dynamic` (for dimensions not known at compile-time).
|
/// integers and `Dyn` (for dimensions not known at compile-time).
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Hoists integers to the type level, including binary operations.
|
||||||
pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {
|
pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is<D: Dim>() -> bool {
|
fn is<D: Dim>() -> bool {
|
||||||
|
@ -63,7 +78,7 @@ pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the compile-time value of `Self`. Returns `None` if it is not known, i.e., if `Self =
|
/// Gets the compile-time value of `Self`. Returns `None` if it is not known, i.e., if `Self =
|
||||||
/// Dynamic`.
|
/// Dyn`.
|
||||||
fn try_to_usize() -> Option<usize>;
|
fn try_to_usize() -> Option<usize>;
|
||||||
|
|
||||||
/// Gets the run-time value of `self`. For type-level integers, this is the same as
|
/// Gets the run-time value of `self`. For type-level integers, this is the same as
|
||||||
|
@ -75,7 +90,7 @@ pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {
|
||||||
fn from_usize(dim: usize) -> Self;
|
fn from_usize(dim: usize) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Dim for Dynamic {
|
unsafe impl Dim for Dyn {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn try_to_usize() -> Option<usize> {
|
fn try_to_usize() -> Option<usize> {
|
||||||
None
|
None
|
||||||
|
@ -83,30 +98,30 @@ unsafe impl Dim for Dynamic {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_usize(dim: usize) -> Self {
|
fn from_usize(dim: usize) -> Self {
|
||||||
Self::new(dim)
|
Self(dim)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn value(&self) -> usize {
|
fn value(&self) -> usize {
|
||||||
self.value
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add<usize> for Dynamic {
|
impl Add<usize> for Dyn {
|
||||||
type Output = Dynamic;
|
type Output = Dyn;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(self, rhs: usize) -> Self {
|
fn add(self, rhs: usize) -> Self {
|
||||||
Self::new(self.value + rhs)
|
Self(self.0 + rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sub<usize> for Dynamic {
|
impl Sub<usize> for Dyn {
|
||||||
type Output = Dynamic;
|
type Output = Dyn;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub(self, rhs: usize) -> Self {
|
fn sub(self, rhs: usize) -> Self {
|
||||||
Self::new(self.value - rhs)
|
Self(self.0 - rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,22 +159,22 @@ macro_rules! dim_ops(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Dim> $DimOp<D> for Dynamic {
|
impl<D: Dim> $DimOp<D> for Dyn {
|
||||||
type Output = Dynamic;
|
type Output = Dyn;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, other: D) -> Dynamic {
|
fn $op(self, other: D) -> Dyn {
|
||||||
Dynamic::new($op_path(self.value, other.value()))
|
Dyn($op_path(self.value(), other.value()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use Const<T> instead of D: DimName?
|
// TODO: use Const<T> instead of D: DimName?
|
||||||
impl<D: DimName> $DimOp<Dynamic> for D {
|
impl<D: DimName> $DimOp<Dyn> for D {
|
||||||
type Output = Dynamic;
|
type Output = Dyn;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $op(self, other: Dynamic) -> Dynamic {
|
fn $op(self, other: Dyn) -> Dyn {
|
||||||
Dynamic::new($op_path(self.value(), other.value))
|
Dyn($op_path(self.value(), other.value()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +213,12 @@ dim_ops!(
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
#[cfg_attr(
|
||||||
|
feature = "rkyv-serialize-no-std",
|
||||||
|
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize),
|
||||||
|
archive(as = "Self")
|
||||||
|
)]
|
||||||
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
pub struct Const<const R: usize>;
|
pub struct Const<const R: usize>;
|
||||||
|
|
||||||
/// Trait implemented exclusively by type-level integers.
|
/// Trait implemented exclusively by type-level integers.
|
||||||
|
@ -233,37 +253,6 @@ impl<'de, const D: usize> Deserialize<'de> for Const<D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rkyv-serialize-no-std")]
|
|
||||||
mod rkyv_impl {
|
|
||||||
use super::Const;
|
|
||||||
use rkyv::{Archive, Deserialize, Fallible, Serialize};
|
|
||||||
|
|
||||||
impl<const R: usize> Archive for Const<R> {
|
|
||||||
type Archived = Self;
|
|
||||||
type Resolver = ();
|
|
||||||
|
|
||||||
fn resolve(
|
|
||||||
&self,
|
|
||||||
_: usize,
|
|
||||||
_: Self::Resolver,
|
|
||||||
_: &mut core::mem::MaybeUninit<Self::Archived>,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: Fallible + ?Sized, const R: usize> Serialize<S> for Const<R> {
|
|
||||||
fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: Fallible + ?Sized, const R: usize> Deserialize<Self, D> for Const<R> {
|
|
||||||
fn deserialize(&self, _: &mut D) -> Result<Self, D::Error> {
|
|
||||||
Ok(Const)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ToConst {
|
pub trait ToConst {
|
||||||
type Const: DimName;
|
type Const: DimName;
|
||||||
}
|
}
|
||||||
|
@ -273,14 +262,17 @@ pub trait ToTypenum {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<const T: usize> Dim for Const<T> {
|
unsafe impl<const T: usize> Dim for Const<T> {
|
||||||
|
#[inline]
|
||||||
fn try_to_usize() -> Option<usize> {
|
fn try_to_usize() -> Option<usize> {
|
||||||
Some(T)
|
Some(T)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn value(&self) -> usize {
|
fn value(&self) -> usize {
|
||||||
T
|
T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn from_usize(dim: usize) -> Self {
|
fn from_usize(dim: usize) -> Self {
|
||||||
assert_eq!(dim, T);
|
assert_eq!(dim, T);
|
||||||
Self
|
Self
|
||||||
|
@ -324,6 +316,11 @@ macro_rules! from_to_typenum (
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsNotStaticOne for $D { }
|
impl IsNotStaticOne for $D { }
|
||||||
|
|
||||||
|
/// The constant dimension
|
||||||
|
#[doc = stringify!($VAL)]
|
||||||
|
/// .
|
||||||
|
pub const $D: $D = Const::<$VAL>;
|
||||||
)*}
|
)*}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -337,3 +334,7 @@ from_to_typenum!(
|
||||||
U111, 111; U112, 112; U113, 113; U114, 114; U115, 115; U116, 116; U117, 117; U118, 118; U119, 119; U120, 120; U121, 121; U122, 122; U123, 123; U124, 124; U125, 125; U126, 126;
|
U111, 111; U112, 112; U113, 113; U114, 114; U115, 115; U116, 116; U117, 117; U118, 118; U119, 119; U120, 120; U121, 121; U122, 122; U123, 123; U124, 124; U125, 125; U126, 126;
|
||||||
U127, 127
|
U127, 127
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// The constant dimension 1.
|
||||||
|
// Note: We add U1 separately since it's not covered by the from_to_typenum! macro.
|
||||||
|
pub const U1: U1 = Const::<1>;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue