Merge branch 'dimforge:dev' into dev
This commit is contained in:
commit
02d66f28d0
|
@ -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.8
|
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: cargo build --all-features;
|
- run: cargo build --all-features;
|
||||||
- run: cargo build -p nalgebra-glm --all-features;
|
- run: cargo build -p nalgebra-glm --all-features;
|
||||||
|
@ -120,23 +118,6 @@ jobs:
|
||||||
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=x86_64-unknown-linux-gnu;
|
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=x86_64-unknown-linux-gnu;
|
||||||
- name: build thumbv7em-none-eabihf nalgebra-glm
|
- name: build thumbv7em-none-eabihf nalgebra-glm
|
||||||
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=thumbv7em-none-eabihf;
|
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=thumbv7em-none-eabihf;
|
||||||
build-cuda:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: Jimver/cuda-toolkit@v0.2.8
|
|
||||||
with:
|
|
||||||
cuda: '11.5.0'
|
|
||||||
- name: Install nightly-2021-12-04
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
toolchain: nightly-2021-12-04
|
|
||||||
override: true
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- run: rustup target add nvptx64-nvidia-cuda
|
|
||||||
- run: cargo build --no-default-features --features cuda
|
|
||||||
- run: cargo build --no-default-features --features cuda --target=nvptx64-nvidia-cuda
|
|
||||||
env:
|
|
||||||
CUDA_ARCH: "350"
|
|
||||||
docs:
|
docs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
244
CHANGELOG.md
244
CHANGELOG.md
|
@ -1,40 +1,67 @@
|
||||||
# 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/).
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
- Add the `glam-0.25` feature to enable conversion from/to types from `glam` v0.25.
|
||||||
|
|
||||||
## [0.32.3] (09 July 2023)
|
## [0.32.3] (09 July 2023)
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
- Statically sized matrices are now serialized as tuples to match how serde
|
- Statically sized matrices are now serialized as tuples to match how serde
|
||||||
serialized plain arrays.
|
serialized plain arrays.
|
||||||
- Don’t require `Scalar` for matrix `PartialEq` and `Eq`.
|
- Don’t require `Scalar` for matrix `PartialEq` and `Eq`.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Allow trailing punctuation in macros `vector!`, `matrix!`, `point!`, etc.
|
- Allow trailing punctuation in macros `vector!`, `matrix!`, `point!`, etc.
|
||||||
- Add the methods `Matrix1::as_scalar`, `::as_scalar_mut`, `::to_scalar`, `::into_scalar`.
|
- Add the methods `Matrix1::as_scalar`, `::as_scalar_mut`, `::to_scalar`, `::into_scalar`.
|
||||||
- Add `Rotation3::euler_angles_ordered`, a generalized euler angles calculation.
|
- Add `Rotation3::euler_angles_ordered`, a generalized euler angles calculation.
|
||||||
- Add the `glam-0.24` feature to enable conversion from/to types from `glam` v0.24.
|
- Add the `glam-0.24` feature to enable conversion from/to types from `glam` v0.24.
|
||||||
|
- Add the `glam-0.25` feature to enable conversion from/to types from `glam` v0.25.
|
||||||
- Add the `lerp` method to points.
|
- Add the `lerp` method to points.
|
||||||
- Implement `Clone` for `MatrixIter`.
|
- Implement `Clone` for `MatrixIter`.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed severe catastrophic cancellation issue in variance calculation.
|
- Fixed severe catastrophic cancellation issue in variance calculation.
|
||||||
|
|
||||||
## [0.32.2] (07 March 2023)
|
## [0.32.2] (07 March 2023)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add the `glam-0.23` to enable conversion from/to type from `glam` v0.23.
|
- Add the `glam-0.23` to enable conversion from/to type from `glam` v0.23.
|
||||||
|
|
||||||
## [0.32.1] (14 Jan. 2023)
|
## [0.32.1] (14 Jan. 2023)
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
- Updated `nalgebra-macros` to use the new `Dyn`, avoiding macro-generated deprecation warnings.
|
- Updated `nalgebra-macros` to use the new `Dyn`, avoiding macro-generated deprecation warnings.
|
||||||
|
|
||||||
## [0.32.0] (14 Jan. 2023)
|
## [0.32.0] (14 Jan. 2023)
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
- Renamed all `MatrixSlice` types to `MatrixView`. In general all occurrences of the world `Slice` or `slice` have been
|
- Renamed all `MatrixSlice` types to `MatrixView`. In general all occurrences of the world `Slice` or `slice` have been
|
||||||
replaced by `View` or `view`.
|
replaced by `View` or `view`.
|
||||||
- Deprecated all the types involving `Slice` in its name, in favor of the word `View`.
|
- Deprecated all the types involving `Slice` in its name, in favor of the word `View`.
|
||||||
|
@ -42,10 +69,12 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
- Renamed `Dynamic` to `Dyn` and make `Dyn` a tuple struct.
|
- Renamed `Dynamic` to `Dyn` and make `Dyn` a tuple struct.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add `Cholesky::ln_determinant` to compute the natural logarithm of the determinant of a matrix decomposed
|
- 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
|
with Cholesky. This can be more numerically stable than computing the determinant itself when very small and/or
|
||||||
large values are involved.
|
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 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`
|
- 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.
|
feature must be enabled to access these methods.
|
||||||
- Implement `ReshapableStorage` for matrix slices (only for unit strides at the moment).
|
- Implement `ReshapableStorage` for matrix slices (only for unit strides at the moment).
|
||||||
|
@ -53,76 +82,89 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
`Const::<4>` when we need const dimensions.
|
`Const::<4>` when we need const dimensions.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed the implementation of `Rotation3::euler_angles` to return the angles in the documented order (roll, pitch, yaw).
|
- Fixed the implementation of `Rotation3::euler_angles` to return the angles in the documented order (roll, pitch, yaw).
|
||||||
|
|
||||||
## [0.31.4] (13 Nov. 2022)
|
## [0.31.4] (13 Nov. 2022)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Add a `convert-glam022` feature to enable conversion between `nalgebra` and `glam v0.22`.
|
|
||||||
|
|
||||||
|
- Add a `convert-glam022` feature to enable conversion between `nalgebra` and `glam v0.22`.
|
||||||
|
|
||||||
## [0.31.3] (30 Oct. 2022)
|
## [0.31.3] (30 Oct. 2022)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add `Matrix::try_cast` to attempt casting the inner scalar types when that cast may fail.
|
- Add `Matrix::try_cast` to attempt casting the inner scalar types when that cast may fail.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed the usage of `CheckBytes` with `rkyv`.
|
- Fixed the usage of `CheckBytes` with `rkyv`.
|
||||||
|
|
||||||
## [0.31.2] (09 Oct. 2022)
|
## [0.31.2] (09 Oct. 2022)
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
- Use `#[inline]` on the `Dim` implementation for `Const` to improve opt-level 1 performance.
|
- Use `#[inline]` on the `Dim` implementation for `Const` to improve opt-level 1 performance.
|
||||||
- Make the `Point::new` constructions const-fn.
|
- Make the `Point::new` constructions const-fn.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Add `UnitVector::cast` to change the underlying scalar type.
|
|
||||||
|
|
||||||
|
- Add `UnitVector::cast` to change the underlying scalar type.
|
||||||
|
|
||||||
## [0.31.1] (31 July 2022)
|
## [0.31.1] (31 July 2022)
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
- Improve performances of multiplication of two sparse matrices.
|
- Improve performances of multiplication of two sparse matrices.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add `Matrix::from_row_iterator` to build a matrix from an iterator yielding components in row-major order.
|
- 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.
|
- Add support for conversion from/to types of `glam` 0.21.
|
||||||
- `nalgebra-sparse`: add support for the matrix-market export of sparse matrices.
|
- `nalgebra-sparse`: add support for the matrix-market export of sparse matrices.
|
||||||
- `nalgebra-lapack`: add a `GE` for solving the generalized eigenvalues problem.
|
- `nalgebra-lapack`: add a `GE` for solving the generalized eigenvalues problem.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix `Rotation3::from_matrix` and `UnitQuaternion::from_matrix` when the input matrix is already a valid
|
- Fix `Rotation3::from_matrix` and `UnitQuaternion::from_matrix` when the input matrix is already a valid
|
||||||
rotation matrix.
|
rotation matrix.
|
||||||
|
|
||||||
## [0.31.0] (30 Apr. 2022)
|
## [0.31.0] (30 Apr. 2022)
|
||||||
|
|
||||||
### Breaking changes
|
### Breaking changes
|
||||||
|
|
||||||
- Switch to `cust` 0.3 (for CUDA support).
|
- Switch to `cust` 0.3 (for CUDA support).
|
||||||
- Switch to `rkyv` 0.7
|
- Switch to `rkyv` 0.7
|
||||||
- Remove support for serialization based on `abomonation`.
|
- Remove support for serialization based on `abomonation`.
|
||||||
- Remove support for conversions between `nalgebra` types and `glam` 0.13.
|
- Remove support for conversions between `nalgebra` types and `glam` 0.13.
|
||||||
|
|
||||||
### Modified
|
### Modified
|
||||||
|
|
||||||
- The aliases for `Const` types have been simplified to help `rust-analyzer`.
|
- The aliases for `Const` types have been simplified to help `rust-analyzer`.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add `TryFrom` conversion between `UnitVector2/3/4` and `glam`’s `Vec2/3/4`.
|
- 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`: added support for serialization of sparse matrices with `serde`.
|
||||||
- `nalgebra-sparse`: add a CSC matrix constructor from unsorted (but valid) data.
|
- `nalgebra-sparse`: add a CSC matrix constructor from unsorted (but valid) data.
|
||||||
- `nalgebra-lapack`: add generalized eigenvalues/eigenvectors calculation + QZ decomposition.
|
- `nalgebra-lapack`: add generalized eigenvalues/eigenvectors calculation + QZ decomposition.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Improve stability of SVD.
|
- Improve stability of SVD.
|
||||||
- Fix slerp for `UnitComplex`.
|
- Fix slerp for `UnitComplex`.
|
||||||
|
|
||||||
## [0.30.1] (09 Jan. 2022)
|
## [0.30.1] (09 Jan. 2022)
|
||||||
|
|
||||||
### Added
|
### 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.
|
||||||
|
@ -132,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.
|
||||||
|
@ -141,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.
|
||||||
|
@ -161,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.
|
||||||
|
@ -169,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.
|
||||||
|
@ -183,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`.
|
||||||
|
@ -190,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`.
|
||||||
|
@ -200,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.
|
||||||
|
@ -217,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).
|
||||||
|
@ -250,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
|
||||||
|
@ -265,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
|
||||||
|
@ -288,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
|
||||||
|
@ -308,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`
|
||||||
|
@ -366,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.
|
||||||
|
@ -380,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
|
||||||
|
@ -396,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.
|
||||||
|
@ -404,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`.
|
||||||
|
@ -481,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.
|
||||||
|
@ -499,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`.
|
||||||
|
@ -509,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.
|
||||||
|
@ -518,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.
|
||||||
|
@ -529,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`
|
||||||
|
@ -564,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
|
||||||
|
@ -596,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
|
||||||
|
@ -607,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
|
||||||
|
@ -615,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).
|
||||||
|
@ -624,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.
|
||||||
|
@ -659,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.
|
||||||
|
@ -686,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**.
|
||||||
|
@ -734,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
|
||||||
|
@ -746,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()`
|
||||||
|
@ -756,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`.
|
||||||
|
|
||||||
|
@ -765,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`
|
||||||
|
@ -775,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`
|
||||||
|
@ -791,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.
|
||||||
|
@ -817,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`:
|
||||||
|
@ -829,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`
|
||||||
|
@ -851,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.
|
||||||
|
@ -872,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:
|
||||||
|
@ -886,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
|
||||||
|
@ -907,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
|
||||||
|
|
|
@ -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,7 +32,6 @@ 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
|
||||||
|
@ -49,6 +48,7 @@ convert-glam021 = [ "glam021" ]
|
||||||
convert-glam022 = [ "glam022" ]
|
convert-glam022 = [ "glam022" ]
|
||||||
convert-glam023 = [ "glam023" ]
|
convert-glam023 = [ "glam023" ]
|
||||||
convert-glam024 = [ "glam024" ]
|
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
|
||||||
|
@ -104,7 +104,7 @@ glam021 = { package = "glam", version = "0.21", optional = true }
|
||||||
glam022 = { package = "glam", version = "0.22", optional = true }
|
glam022 = { package = "glam", version = "0.22", optional = true }
|
||||||
glam023 = { package = "glam", version = "0.23", optional = true }
|
glam023 = { package = "glam", version = "0.23", optional = true }
|
||||||
glam024 = { package = "glam", version = "0.24", optional = true }
|
glam024 = { package = "glam", version = "0.24", optional = true }
|
||||||
cust_core = { version = "0.1", optional = true }
|
glam025 = { package = "glam", version = "0.25", optional = true }
|
||||||
rayon = { version = "1.6", optional = true }
|
rayon = { version = "1.6", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -21,7 +21,6 @@ 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" ]
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T
|
||||||
x.zip_map(y, |x, y| x < y)
|
x.zip_map(y, |x, y| x < y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise `>=` comparison.
|
/// Component-wise `<=` comparison.
|
||||||
///
|
///
|
||||||
/// # Examples:
|
/// # Examples:
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::mem::replace;
|
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use num_traits::One;
|
use num_traits::One;
|
||||||
|
@ -369,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;
|
||||||
|
@ -578,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.",
|
||||||
|
@ -624,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
|
||||||
|
|
|
@ -625,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.
|
||||||
///
|
///
|
||||||
|
|
|
@ -626,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.
|
||||||
///
|
///
|
||||||
|
|
|
@ -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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -42,7 +42,6 @@ use std::mem;
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]);
|
pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]);
|
||||||
|
|
||||||
impl<T, const R: usize, const C: usize> ArrayStorage<T, R, C> {
|
impl<T, const R: usize, const C: usize> ArrayStorage<T, R, C> {
|
||||||
|
|
|
@ -97,6 +97,8 @@ macro_rules! impl_constructors(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates, without bound checking, a new matrix view from the given data array.
|
/// Creates, without bound checking, a new matrix view from the given data array.
|
||||||
|
/// # Safety
|
||||||
|
/// `data[start..start+rstride * cstride]` must be within bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self {
|
pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self {
|
||||||
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
||||||
|
@ -113,6 +115,11 @@ macro_rules! impl_constructors(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates, without bound checking, a new matrix view with the specified strides from the given data array.
|
/// Creates, without bound checking, a new matrix view with the specified strides from the given data array.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `start`, `rstride`, and `cstride`, with the given matrix size will not index
|
||||||
|
/// outside of `data`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
||||||
Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dyn(rstride), Dyn(cstride))
|
Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dyn(rstride), Dyn(cstride))
|
||||||
|
@ -257,6 +264,10 @@ macro_rules! impl_constructors_mut(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates, without bound checking, a new mutable matrix view from the given data array.
|
/// Creates, without bound checking, a new mutable matrix view from the given data array.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `data[start..start+(R * C)]` must be within bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self {
|
pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self {
|
||||||
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
||||||
|
@ -274,6 +285,8 @@ macro_rules! impl_constructors_mut(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates, without bound checking, a new mutable matrix view with the specified strides from the given data array.
|
/// Creates, without bound checking, a new mutable matrix view with the specified strides from the given data array.
|
||||||
|
/// # Safety
|
||||||
|
/// `data[start..start+rstride * cstride]` must be within bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
||||||
Self::from_slice_with_strides_generic_unchecked(
|
Self::from_slice_with_strides_generic_unchecked(
|
||||||
|
|
|
@ -23,7 +23,6 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
feature = "rkyv-serialize",
|
feature = "rkyv-serialize",
|
||||||
archive_attr(derive(bytecheck::CheckBytes))
|
archive_attr(derive(bytecheck::CheckBytes))
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
pub struct Dyn(pub usize);
|
pub struct Dyn(pub usize);
|
||||||
|
|
||||||
#[deprecated(note = "use Dyn instead.")]
|
#[deprecated(note = "use Dyn instead.")]
|
||||||
|
@ -68,6 +67,10 @@ impl IsNotStaticOne for Dyn {}
|
||||||
|
|
||||||
/// Trait implemented by any type that can be used as a dimension. This includes type-level
|
/// Trait implemented by any type that can be used as a dimension. This includes type-level
|
||||||
/// integers and `Dyn` (for dimensions not known at compile-time).
|
/// integers and `Dyn` (for dimensions not known at compile-time).
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Hoists integers to the type level, including binary operations.
|
||||||
pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {
|
pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is<D: Dim>() -> bool {
|
fn is<D: Dim>() -> bool {
|
||||||
|
@ -216,7 +219,6 @@ dim_ops!(
|
||||||
archive(as = "Self")
|
archive(as = "Self")
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
pub struct Const<const R: usize>;
|
pub struct Const<const R: usize>;
|
||||||
|
|
||||||
/// Trait implemented exclusively by type-level integers.
|
/// Trait implemented exclusively by type-level integers.
|
||||||
|
|
|
@ -519,6 +519,10 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
|
|
||||||
/// Produces a view of the data at the given index, without doing
|
/// Produces a view of the data at the given index, without doing
|
||||||
/// any bounds checking.
|
/// any bounds checking.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `index` must within bounds of the array.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output
|
pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output
|
||||||
|
@ -530,6 +534,9 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
|
|
||||||
/// Returns a mutable view of the data at the given index, without doing
|
/// Returns a mutable view of the data at the given index, without doing
|
||||||
/// any bounds checking.
|
/// any bounds checking.
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `index` must within bounds of the array.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut
|
pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut
|
||||||
|
|
|
@ -171,7 +171,6 @@ pub type MatrixCross<T, R1, C1, R2, C2> =
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
pub struct Matrix<T, R, C, S> {
|
pub struct Matrix<T, R, C, S> {
|
||||||
/// The data storage that contains all the matrix components. Disappointed?
|
/// The data storage that contains all the matrix components. Disappointed?
|
||||||
///
|
///
|
||||||
|
@ -313,6 +312,10 @@ where
|
||||||
impl<T, R, C, S> Matrix<T, R, C, S> {
|
impl<T, R, C, S> Matrix<T, R, C, S> {
|
||||||
/// Creates a new matrix with the given data without statically checking that the matrix
|
/// Creates a new matrix with the given data without statically checking that the matrix
|
||||||
/// dimension matches the storage dimension.
|
/// dimension matches the storage dimension.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The storage dimension must match the given dimensions.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const unsafe fn from_data_statically_unchecked(data: S) -> Matrix<T, R, C, S> {
|
pub const unsafe fn from_data_statically_unchecked(data: S) -> Matrix<T, R, C, S> {
|
||||||
Matrix {
|
Matrix {
|
||||||
|
@ -1194,6 +1197,10 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swaps two entries without bound-checking.
|
/// Swaps two entries without bound-checking.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Both `(r, c)` must have `r < nrows(), c < ncols()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn swap_unchecked(&mut self, row_cols1: (usize, usize), row_cols2: (usize, usize)) {
|
pub unsafe fn swap_unchecked(&mut self, row_cols1: (usize, usize), row_cols2: (usize, usize)) {
|
||||||
debug_assert!(row_cols1.0 < self.nrows() && row_cols1.1 < self.ncols());
|
debug_assert!(row_cols1.0 < self.nrows() && row_cols1.1 < self.ncols());
|
||||||
|
@ -1300,6 +1307,8 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
|
||||||
|
|
||||||
impl<T, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
|
impl<T, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
|
||||||
/// Gets a reference to the i-th element of this column vector without bound checking.
|
/// Gets a reference to the i-th element of this column vector without bound checking.
|
||||||
|
/// # Safety
|
||||||
|
/// `i` must be less than `D`.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn vget_unchecked(&self, i: usize) -> &T {
|
pub unsafe fn vget_unchecked(&self, i: usize) -> &T {
|
||||||
|
@ -1311,6 +1320,8 @@ impl<T, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
|
||||||
|
|
||||||
impl<T, D: Dim, S: RawStorageMut<T, D>> Vector<T, D, S> {
|
impl<T, D: Dim, S: RawStorageMut<T, D>> Vector<T, D, S> {
|
||||||
/// Gets a mutable reference to the i-th element of this column vector without bound checking.
|
/// Gets a mutable reference to the i-th element of this column vector without bound checking.
|
||||||
|
/// # Safety
|
||||||
|
/// `i` must be less than `D`.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn vget_unchecked_mut(&mut self, i: usize) -> &mut T {
|
pub unsafe fn vget_unchecked_mut(&mut self, i: usize) -> &mut T {
|
||||||
|
|
|
@ -43,6 +43,10 @@ macro_rules! view_storage_impl (
|
||||||
|
|
||||||
impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, T, R, C, RStride, CStride> {
|
impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, T, R, C, RStride, CStride> {
|
||||||
/// Create a new matrix view without bounds checking and from a raw pointer.
|
/// Create a new matrix view without bounds checking and from a raw pointer.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `*ptr` must point to memory that is valid `[T; R * C]`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_raw_parts(ptr: $Ptr,
|
pub unsafe fn from_raw_parts(ptr: $Ptr,
|
||||||
shape: (R, C),
|
shape: (R, C),
|
||||||
|
@ -63,6 +67,11 @@ macro_rules! view_storage_impl (
|
||||||
// Dyn is arbitrary. It's just to be able to call the constructors with `Slice::`
|
// Dyn is arbitrary. It's just to be able to call the constructors with `Slice::`
|
||||||
impl<'a, T, R: Dim, C: Dim> $T<'a, T, R, C, Dyn, Dyn> {
|
impl<'a, T, R: Dim, C: Dim> $T<'a, T, R, C, Dyn, Dyn> {
|
||||||
/// Create a new matrix view without bounds checking.
|
/// Create a new matrix view without bounds checking.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `storage` contains sufficient elements beyond `start + R * C` such that all
|
||||||
|
/// accesses are within bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn new_unchecked<RStor, CStor, S>(storage: $SRef, start: (usize, usize), shape: (R, C))
|
pub unsafe fn new_unchecked<RStor, CStor, S>(storage: $SRef, start: (usize, usize), shape: (R, C))
|
||||||
-> $T<'a, T, R, C, S::RStride, S::CStride>
|
-> $T<'a, T, R, C, S::RStride, S::CStride>
|
||||||
|
@ -75,6 +84,10 @@ macro_rules! view_storage_impl (
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new matrix view without bounds checking.
|
/// Create a new matrix view without bounds checking.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `strides` must be a valid stride indexing.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn new_with_strides_unchecked<S, RStor, CStor, RStride, CStride>(storage: $SRef,
|
pub unsafe fn new_with_strides_unchecked<S, RStor, CStor, RStride, CStride>(storage: $SRef,
|
||||||
start: (usize, usize),
|
start: (usize, usize),
|
||||||
|
@ -128,12 +141,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Clone
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
*self
|
||||||
ptr: self.ptr,
|
|
||||||
shape: self.shape,
|
|
||||||
strides: self.strides,
|
|
||||||
_phantoms: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,8 +546,8 @@ macro_rules! matrix_view_impl (
|
||||||
$me.$generic_view_with_steps(start, shape, steps)
|
$me.$generic_view_with_steps(start, shape, steps)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Slices this matrix starting at its component `(irow, icol)` and with `(R::dim(),
|
/// Slices this matrix starting at its component `(irow, icol)` and with `(RVIEW, CVIEW)`
|
||||||
/// CView::dim())` consecutive components.
|
/// consecutive components.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[deprecated = slice_deprecation_note!($fixed_view)]
|
#[deprecated = slice_deprecation_note!($fixed_view)]
|
||||||
pub fn $fixed_slice<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize)
|
pub fn $fixed_slice<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize)
|
||||||
|
@ -547,8 +555,8 @@ macro_rules! matrix_view_impl (
|
||||||
$me.$fixed_view(irow, icol)
|
$me.$fixed_view(irow, icol)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a view of this matrix starting at its component `(irow, icol)` and with `(R::dim(),
|
/// Return a view of this matrix starting at its component `(irow, icol)` and with
|
||||||
/// CView::dim())` consecutive components.
|
/// `(RVIEW, CVIEW)` consecutive components.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn $fixed_view<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize)
|
pub fn $fixed_view<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize)
|
||||||
-> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, S::RStride, S::CStride> {
|
-> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, S::RStride, S::CStride> {
|
||||||
|
|
|
@ -336,7 +336,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
/// Sets the magnitude of this vector unless it is smaller than `min_magnitude`.
|
/// Sets the magnitude of this vector unless it is smaller than `min_magnitude`.
|
||||||
///
|
///
|
||||||
/// If `self.magnitude()` is smaller than `min_magnitude`, it will be left unchanged.
|
/// If `self.magnitude()` is smaller than `min_magnitude`, it will be left unchanged.
|
||||||
/// Otherwise this is equivalent to: `*self = self.normalize() * magnitude.
|
/// Otherwise this is equivalent to: `*self = self.normalize() * magnitude`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_set_magnitude(&mut self, magnitude: T::RealField, min_magnitude: T::RealField)
|
pub fn try_set_magnitude(&mut self, magnitude: T::RealField, min_magnitude: T::RealField)
|
||||||
where
|
where
|
||||||
|
@ -525,7 +525,7 @@ where
|
||||||
let (elt, basis) = vs[..i + 1].split_last_mut().unwrap();
|
let (elt, basis) = vs[..i + 1].split_last_mut().unwrap();
|
||||||
|
|
||||||
for basis_element in &basis[..nbasis_elements] {
|
for basis_element in &basis[..nbasis_elements] {
|
||||||
*elt -= &*basis_element * elt.dot(basis_element)
|
*elt -= basis_element * elt.dot(basis_element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -339,7 +339,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
let mean = self.mean();
|
let mean = self.mean();
|
||||||
|
|
||||||
self.iter().cloned().fold(T::zero(), |acc, x| {
|
self.iter().cloned().fold(T::zero(), |acc, x| {
|
||||||
acc + (x.clone() - mean.clone()) * (x.clone() - mean.clone())
|
acc + (x.clone() - mean.clone()) * (x - mean.clone())
|
||||||
}) / n_elements
|
}) / n_elements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@ pub type CStride<T, R, C = U1> =
|
||||||
/// The trait shared by all matrix data storage.
|
/// The trait shared by all matrix data storage.
|
||||||
///
|
///
|
||||||
/// TODO: doc
|
/// TODO: doc
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
/// In generic code, it is recommended use the `Storage` trait bound instead. The `RawStorage`
|
/// In generic code, it is recommended use the `Storage` trait bound instead. The `RawStorage`
|
||||||
/// trait bound is generally used by code that needs to work with storages that contains
|
/// trait bound is generally used by code that needs to work with storages that contains
|
||||||
/// `MaybeUninit<T>` elements.
|
/// `MaybeUninit<T>` elements.
|
||||||
|
@ -57,7 +59,7 @@ pub unsafe trait RawStorage<T, R: Dim, C: Dim = U1>: Sized {
|
||||||
|
|
||||||
/// The spacing between consecutive row elements and consecutive column elements.
|
/// The spacing between consecutive row elements and consecutive column elements.
|
||||||
///
|
///
|
||||||
/// For example this returns `(1, 5)` for a row-major matrix with 5 columns.
|
/// For example this returns `(1, 5)` for a column-major matrix with 5 columns.
|
||||||
fn strides(&self) -> (Self::RStride, Self::CStride);
|
fn strides(&self) -> (Self::RStride, Self::CStride);
|
||||||
|
|
||||||
/// Compute the index corresponding to the irow-th row and icol-th column of this matrix. The
|
/// Compute the index corresponding to the irow-th row and icol-th column of this matrix. The
|
||||||
|
@ -129,6 +131,14 @@ pub unsafe trait RawStorage<T, R: Dim, C: Dim = U1>: Sized {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait shared by all matrix data storage that don’t contain any uninitialized elements.
|
/// Trait shared by all matrix data storage that don’t contain any uninitialized elements.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Note that `Self` must always have a number of elements compatible with the matrix length (given
|
||||||
|
/// by `R` and `C` if they are known at compile-time). For example, implementors of this trait
|
||||||
|
/// should **not** allow the user to modify the size of the underlying buffer with safe methods
|
||||||
|
/// (for example the `VecStorage::data_mut` method is unsafe because the user could change the
|
||||||
|
/// vector's size so that it no longer contains enough elements: this will lead to UB.
|
||||||
pub unsafe trait Storage<T, R: Dim, C: Dim = U1>: RawStorage<T, R, C> {
|
pub unsafe trait Storage<T, R: Dim, C: Dim = U1>: RawStorage<T, R, C> {
|
||||||
/// Builds a matrix data storage that does not contain any reference.
|
/// Builds a matrix data storage that does not contain any reference.
|
||||||
fn into_owned(self) -> Owned<T, R, C>
|
fn into_owned(self) -> Owned<T, R, C>
|
||||||
|
@ -143,6 +153,8 @@ pub unsafe trait Storage<T, R: Dim, C: Dim = U1>: RawStorage<T, R, C> {
|
||||||
|
|
||||||
/// Trait implemented by matrix data storage that can provide a mutable access to its elements.
|
/// Trait implemented by matrix data storage that can provide a mutable access to its elements.
|
||||||
///
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
/// In generic code, it is recommended use the `StorageMut` trait bound instead. The
|
/// In generic code, it is recommended use the `StorageMut` trait bound instead. The
|
||||||
/// `RawStorageMut` trait bound is generally used by code that needs to work with storages that
|
/// `RawStorageMut` trait bound is generally used by code that needs to work with storages that
|
||||||
/// contains `MaybeUninit<T>` elements.
|
/// contains `MaybeUninit<T>` elements.
|
||||||
|
@ -194,10 +206,28 @@ pub unsafe trait RawStorageMut<T, R: Dim, C: Dim = U1>: RawStorage<T, R, C> {
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// If the indices are out of bounds, the method will cause undefined behavior.
|
/// If the indices are out of bounds, the method will cause undefined behavior.
|
||||||
|
///
|
||||||
|
/// # Validity
|
||||||
|
/// The default implementation of this trait function is only guaranteed to be
|
||||||
|
/// sound if invocations of `self.ptr_mut()` and `self.get_address_unchecked_linear_mut()`
|
||||||
|
/// result in stable references. If any of the data pointed to by these trait methods
|
||||||
|
/// moves as a consequence of invoking either of these methods then this default
|
||||||
|
/// trait implementation may be invalid or unsound and should be overridden.
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn swap_unchecked_linear(&mut self, i1: usize, i2: usize) {
|
unsafe fn swap_unchecked_linear(&mut self, i1: usize, i2: usize) {
|
||||||
let a = self.get_address_unchecked_linear_mut(i1);
|
// we can't just use the pointers returned from `get_address_unchecked_linear_mut` because calling a
|
||||||
let b = self.get_address_unchecked_linear_mut(i2);
|
// method taking self mutably invalidates any existing (mutable) pointers. since `get_address_unchecked_linear_mut` can
|
||||||
|
// also be overriden by a custom implementation, we can't just use `wrapping_add` assuming that's what the method does.
|
||||||
|
// instead, we use `offset_from` to compute the re-calculate the pointers from the base pointer.
|
||||||
|
// this is sound as long as this trait matches the Validity preconditions
|
||||||
|
// (and it's the caller's responsibility to ensure the indices are in-bounds).
|
||||||
|
let base = self.ptr_mut();
|
||||||
|
let offset1 = self.get_address_unchecked_linear_mut(i1).offset_from(base);
|
||||||
|
let offset2 = self.get_address_unchecked_linear_mut(i2).offset_from(base);
|
||||||
|
|
||||||
|
let base = self.ptr_mut();
|
||||||
|
let a = base.offset(offset1);
|
||||||
|
let b = base.offset(offset2);
|
||||||
|
|
||||||
ptr::swap(a, b);
|
ptr::swap(a, b);
|
||||||
}
|
}
|
||||||
|
@ -226,6 +256,10 @@ pub unsafe trait RawStorageMut<T, R: Dim, C: Dim = U1>: RawStorage<T, R, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait shared by all mutable matrix data storage that don’t contain any uninitialized elements.
|
/// Trait shared by all mutable matrix data storage that don’t contain any uninitialized elements.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// See safety note for `Storage`, `RawStorageMut`.
|
||||||
pub unsafe trait StorageMut<T, R: Dim, C: Dim = U1>:
|
pub unsafe trait StorageMut<T, R: Dim, C: Dim = U1>:
|
||||||
Storage<T, R, C> + RawStorageMut<T, R, C>
|
Storage<T, R, C> + RawStorageMut<T, R, C>
|
||||||
{
|
{
|
||||||
|
@ -241,6 +275,8 @@ where
|
||||||
|
|
||||||
/// Marker trait indicating that a storage is stored contiguously in memory.
|
/// Marker trait indicating that a storage is stored contiguously in memory.
|
||||||
///
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
/// The storage requirement means that for any value of `i` in `[0, nrows * ncols - 1]`, the value
|
/// The storage requirement means that for any value of `i` in `[0, nrows * ncols - 1]`, the value
|
||||||
/// `.get_unchecked_linear` returns one of the matrix component. This trait is unsafe because
|
/// `.get_unchecked_linear` returns one of the matrix component. This trait is unsafe because
|
||||||
/// failing to comply to this may cause Undefined Behaviors.
|
/// failing to comply to this may cause Undefined Behaviors.
|
||||||
|
|
|
@ -35,7 +35,6 @@ use rkyv::bytecheck;
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
// #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
pub struct Unit<T> {
|
pub struct Unit<T> {
|
||||||
pub(crate) value: T,
|
pub(crate) value: T,
|
||||||
}
|
}
|
||||||
|
@ -72,16 +71,6 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for Unit<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "cuda")]
|
|
||||||
unsafe impl<T: cust_core::DeviceCopy, R, C, S> cust_core::DeviceCopy for Unit<Matrix<T, R, C, S>>
|
|
||||||
where
|
|
||||||
T: Scalar,
|
|
||||||
R: Dim,
|
|
||||||
C: Dim,
|
|
||||||
S: RawStorage<T, R, C> + Copy,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, R, C, S> PartialEq for Unit<Matrix<T, R, C, S>>
|
impl<T, R, C, S> PartialEq for Unit<Matrix<T, R, C, S>>
|
||||||
where
|
where
|
||||||
T: Scalar + PartialEq,
|
T: Scalar + PartialEq,
|
||||||
|
|
|
@ -55,7 +55,6 @@ use simba::scalar::{ClosedNeg, RealField};
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
pub struct DualQuaternion<T> {
|
pub struct DualQuaternion<T> {
|
||||||
/// The real component of the quaternion
|
/// The real component of the quaternion
|
||||||
pub real: Quaternion<T>,
|
pub real: Quaternion<T>,
|
||||||
|
@ -320,6 +319,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RealField> DualQuaternion<T> {
|
impl<T: RealField> DualQuaternion<T> {
|
||||||
|
#[allow(clippy::wrong_self_convention)]
|
||||||
fn to_vector(&self) -> OVector<T, U8> {
|
fn to_vector(&self) -> OVector<T, U8> {
|
||||||
self.as_ref().clone().into()
|
self.as_ref().clone().into()
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,6 @@ use rkyv::bytecheck;
|
||||||
///
|
///
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
#[cfg_attr(feature = "serde-serialize-no-std", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize-no-std", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize-no-std",
|
feature = "serde-serialize-no-std",
|
||||||
|
|
|
@ -34,7 +34,6 @@ use rkyv::bytecheck;
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Orthographic3<T> {
|
pub struct Orthographic3<T> {
|
||||||
matrix: Matrix4<T>,
|
matrix: Matrix4<T>,
|
||||||
|
|
|
@ -35,7 +35,6 @@ use rkyv::bytecheck;
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Perspective3<T> {
|
pub struct Perspective3<T> {
|
||||||
matrix: Matrix4<T>,
|
matrix: Matrix4<T>,
|
||||||
|
|
|
@ -86,14 +86,6 @@ where
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "cuda")]
|
|
||||||
unsafe impl<T: Scalar + cust_core::DeviceCopy, D: DimName> cust_core::DeviceCopy for OPoint<T, D>
|
|
||||||
where
|
|
||||||
DefaultAllocator: Allocator<T, D>,
|
|
||||||
OVector<T, D>: cust_core::DeviceCopy,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "bytemuck")]
|
#[cfg(feature = "bytemuck")]
|
||||||
unsafe impl<T: Scalar, D: DimName> bytemuck::Zeroable for OPoint<T, D>
|
unsafe impl<T: Scalar, D: DimName> bytemuck::Zeroable for OPoint<T, D>
|
||||||
where
|
where
|
||||||
|
@ -317,6 +309,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a reference to i-th element of this point without bound-checking.
|
/// Gets a reference to i-th element of this point without bound-checking.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `i` must be less than `self.len()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn get_unchecked(&self, i: usize) -> &T {
|
pub unsafe fn get_unchecked(&self, i: usize) -> &T {
|
||||||
|
@ -344,6 +340,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a mutable reference to i-th element of this point without bound-checking.
|
/// Gets a mutable reference to i-th element of this point without bound-checking.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `i` must be less than `self.len()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn get_unchecked_mut(&mut self, i: usize) -> &mut T {
|
pub unsafe fn get_unchecked_mut(&mut self, i: usize) -> &mut T {
|
||||||
|
@ -351,6 +351,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swaps two entries without bound-checking.
|
/// Swaps two entries without bound-checking.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `i1` and `i2` must be less than `self.len()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn swap_unchecked(&mut self, i1: usize, i2: usize) {
|
pub unsafe fn swap_unchecked(&mut self, i1: usize, i2: usize) {
|
||||||
self.coords.swap_unchecked((i1, 0), (i2, 0))
|
self.coords.swap_unchecked((i1, 0), (i2, 0))
|
||||||
|
@ -499,10 +503,11 @@ where
|
||||||
|
|
||||||
let mut it = self.coords.iter();
|
let mut it = self.coords.iter();
|
||||||
|
|
||||||
write!(f, "{}", *it.next().unwrap())?;
|
<T as fmt::Display>::fmt(it.next().unwrap(), f)?;
|
||||||
|
|
||||||
for comp in it {
|
for comp in it {
|
||||||
write!(f, ", {}", *comp)?;
|
write!(f, ", ")?;
|
||||||
|
<T as fmt::Display>::fmt(comp, f)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, "}}")
|
write!(f, "}}")
|
||||||
|
|
|
@ -202,29 +202,11 @@ impl<T: Scalar> Point1<T> {
|
||||||
/// assert_eq!(p.x, 1.0);
|
/// assert_eq!(p.x, 1.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(feature = "cuda"))]
|
|
||||||
pub const fn new(x: T) -> Self {
|
pub const fn new(x: T) -> Self {
|
||||||
Point {
|
Point {
|
||||||
coords: Vector1::new(x),
|
coords: Vector1::new(x),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes this point from its components.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// # use nalgebra::Point1;
|
|
||||||
/// let p = Point1::new(1.0);
|
|
||||||
/// assert_eq!(p.x, 1.0);
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
#[cfg(feature = "cuda")]
|
|
||||||
pub fn new(x: T) -> Self {
|
|
||||||
Point {
|
|
||||||
coords: Vector1::new(x),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
macro_rules! componentwise_constructors_impl(
|
macro_rules! componentwise_constructors_impl(
|
||||||
($($doc: expr; $Point: ident, $Vector: ident, $($args: ident:$irow: expr),*);* $(;)*) => {$(
|
($($doc: expr; $Point: ident, $Vector: ident, $($args: ident:$irow: expr),*);* $(;)*) => {$(
|
||||||
|
@ -234,22 +216,9 @@ macro_rules! componentwise_constructors_impl(
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
#[doc = "```"]
|
#[doc = "```"]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(not(feature = "cuda"))]
|
|
||||||
pub const fn new($($args: T),*) -> Self {
|
pub const fn new($($args: T),*) -> Self {
|
||||||
Point { coords: $Vector::new($($args),*) }
|
Point { coords: $Vector::new($($args),*) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: always let new be const once CUDA updates its supported
|
|
||||||
// nightly version to something more recent.
|
|
||||||
#[doc = "Initializes this point from its components."]
|
|
||||||
#[doc = "# Example\n```"]
|
|
||||||
#[doc = $doc]
|
|
||||||
#[doc = "```"]
|
|
||||||
#[inline]
|
|
||||||
#[cfg(feature = "cuda")]
|
|
||||||
pub fn new($($args: T),*) -> Self {
|
|
||||||
Point { coords: $Vector::new($($args),*) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)*}
|
)*}
|
||||||
);
|
);
|
||||||
|
|
|
@ -38,7 +38,6 @@ use rkyv::bytecheck;
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
pub struct Quaternion<T> {
|
pub struct Quaternion<T> {
|
||||||
/// This quaternion as a 4D vector of coordinates in the `[ x, y, z, w ]` storage order.
|
/// This quaternion as a 4D vector of coordinates in the `[ x, y, z, w ]` storage order.
|
||||||
pub coords: Vector4<T>,
|
pub coords: Vector4<T>,
|
||||||
|
@ -1016,9 +1015,6 @@ impl<T: RealField + fmt::Display> fmt::Display for Quaternion<T> {
|
||||||
/// A unit quaternions. May be used to represent a rotation.
|
/// A unit quaternions. May be used to represent a rotation.
|
||||||
pub type UnitQuaternion<T> = Unit<Quaternion<T>>;
|
pub type UnitQuaternion<T> = Unit<Quaternion<T>>;
|
||||||
|
|
||||||
#[cfg(feature = "cuda")]
|
|
||||||
unsafe impl<T: cust_core::DeviceCopy> cust_core::DeviceCopy for UnitQuaternion<T> {}
|
|
||||||
|
|
||||||
impl<T: Scalar + ClosedNeg + PartialEq> PartialEq for UnitQuaternion<T> {
|
impl<T: Scalar + ClosedNeg + PartialEq> PartialEq for UnitQuaternion<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, rhs: &Self) -> bool {
|
fn eq(&self, rhs: &Self) -> bool {
|
||||||
|
|
|
@ -64,7 +64,6 @@ use rkyv::bytecheck;
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Rotation<T, const D: usize> {
|
pub struct Rotation<T, const D: usize> {
|
||||||
matrix: SMatrix<T, D, D>,
|
matrix: SMatrix<T, D, D>,
|
||||||
|
@ -185,6 +184,10 @@ impl<T: Scalar, const D: usize> Rotation<T, D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A mutable reference to the underlying matrix representation of this rotation.
|
/// A mutable reference to the underlying matrix representation of this rotation.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Invariants of the rotation matrix should not be violated.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[deprecated(note = "Use `.matrix_mut_unchecked()` instead.")]
|
#[deprecated(note = "Use `.matrix_mut_unchecked()` instead.")]
|
||||||
pub unsafe fn matrix_mut(&mut self) -> &mut SMatrix<T, D, D> {
|
pub unsafe fn matrix_mut(&mut self) -> &mut SMatrix<T, D, D> {
|
||||||
|
|
|
@ -1058,7 +1058,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||||
{
|
{
|
||||||
let mut angles = [T::zero(); 3];
|
let mut angles = [T::zero(); 3];
|
||||||
let eps = T::from_subset(&1e-7);
|
let eps = T::from_subset(&1e-7);
|
||||||
let _2 = T::from_subset(&2.0);
|
let two = T::from_subset(&2.0);
|
||||||
|
|
||||||
if extrinsic {
|
if extrinsic {
|
||||||
seq.reverse();
|
seq.reverse();
|
||||||
|
@ -1090,7 +1090,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||||
-s1,
|
-s1,
|
||||||
c1,
|
c1,
|
||||||
);
|
);
|
||||||
let o_t = &c * self.matrix() * (c.transpose() * r1l);
|
let o_t = c * self.matrix() * (c.transpose() * r1l);
|
||||||
angles[1] = o_t.m33.acos();
|
angles[1] = o_t.m33.acos();
|
||||||
|
|
||||||
let safe1 = angles[1].abs() >= eps;
|
let safe1 = angles[1].abs() >= eps;
|
||||||
|
@ -1131,7 +1131,7 @@ impl<T: SimdRealField> Rotation3<T> {
|
||||||
// dont adjust gimbal locked rotation
|
// dont adjust gimbal locked rotation
|
||||||
if adjust && observable {
|
if adjust && observable {
|
||||||
angles[0] += T::pi();
|
angles[0] += T::pi();
|
||||||
angles[1] = _2 * lambda - angles[1];
|
angles[1] = two * lambda - angles[1];
|
||||||
angles[2] -= T::pi();
|
angles[2] -= T::pi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ use rkyv::bytecheck;
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Scale<T, const D: usize> {
|
pub struct Scale<T, const D: usize> {
|
||||||
/// The scale coordinates, i.e., how much is multiplied to a point's coordinates when it is
|
/// The scale coordinates, i.e., how much is multiplied to a point's coordinates when it is
|
||||||
|
@ -149,6 +148,10 @@ impl<T: Scalar, const D: usize> Scale<T, D> {
|
||||||
/// assert_eq!(t.inverse_unchecked() * t, Scale2::identity());
|
/// assert_eq!(t.inverse_unchecked() * t, Scale2::identity());
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Should only be used if all scaling is known to be non-zero.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn inverse_unchecked(&self) -> Scale<T, D>
|
pub unsafe fn inverse_unchecked(&self) -> Scale<T, D>
|
||||||
|
|
|
@ -83,28 +83,28 @@ add_sub_impl!(Mul, mul, ClosedMul;
|
||||||
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
|
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
|
||||||
const D; for; where;
|
const D; for; where;
|
||||||
self: &'a Scale<T, D>, right: &'b SVector<T, D>, Output = SVector<T, D>;
|
self: &'a Scale<T, D>, right: &'b SVector<T, D>, Output = SVector<T, D>;
|
||||||
SVector::from(self.vector.component_mul(right));
|
self.vector.component_mul(right);
|
||||||
'a, 'b);
|
'a, 'b);
|
||||||
|
|
||||||
add_sub_impl!(Mul, mul, ClosedMul;
|
add_sub_impl!(Mul, mul, ClosedMul;
|
||||||
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
|
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
|
||||||
const D; for; where;
|
const D; for; where;
|
||||||
self: &'a Scale<T, D>, right: SVector<T, D>, Output = SVector<T, D>;
|
self: &'a Scale<T, D>, right: SVector<T, D>, Output = SVector<T, D>;
|
||||||
SVector::from(self.vector.component_mul(&right));
|
self.vector.component_mul(&right);
|
||||||
'a);
|
'a);
|
||||||
|
|
||||||
add_sub_impl!(Mul, mul, ClosedMul;
|
add_sub_impl!(Mul, mul, ClosedMul;
|
||||||
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
|
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
|
||||||
const D; for; where;
|
const D; for; where;
|
||||||
self: Scale<T, D>, right: &'b SVector<T, D>, Output = SVector<T, D>;
|
self: Scale<T, D>, right: &'b SVector<T, D>, Output = SVector<T, D>;
|
||||||
SVector::from(self.vector.component_mul(right));
|
self.vector.component_mul(right);
|
||||||
'b);
|
'b);
|
||||||
|
|
||||||
add_sub_impl!(Mul, mul, ClosedMul;
|
add_sub_impl!(Mul, mul, ClosedMul;
|
||||||
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
|
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
|
||||||
const D; for; where;
|
const D; for; where;
|
||||||
self: Scale<T, D>, right: SVector<T, D>, Output = SVector<T, D>;
|
self: Scale<T, D>, right: SVector<T, D>, Output = SVector<T, D>;
|
||||||
SVector::from(self.vector.component_mul(&right)); );
|
self.vector.component_mul(&right); );
|
||||||
|
|
||||||
// Scale *= Scale
|
// Scale *= Scale
|
||||||
add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul;
|
add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul;
|
||||||
|
|
|
@ -21,7 +21,6 @@ use rkyv::bytecheck;
|
||||||
/// A similarity, i.e., an uniform scaling, followed by a rotation, followed by a translation.
|
/// A similarity, i.e., an uniform scaling, followed by a rotation, followed by a translation.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
#[cfg_attr(feature = "serde-serialize-no-std", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize-no-std", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize-no-std",
|
feature = "serde-serialize-no-std",
|
||||||
|
|
|
@ -60,17 +60,14 @@ where
|
||||||
|
|
||||||
/// Tag representing the most general (not necessarily inversible) `Transform` type.
|
/// Tag representing the most general (not necessarily inversible) `Transform` type.
|
||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
pub enum TGeneral {}
|
pub enum TGeneral {}
|
||||||
|
|
||||||
/// Tag representing the most general inversible `Transform` type.
|
/// Tag representing the most general inversible `Transform` type.
|
||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
pub enum TProjective {}
|
pub enum TProjective {}
|
||||||
|
|
||||||
/// Tag representing an affine `Transform`. Its bottom-row is equal to `(0, 0 ... 0, 1)`.
|
/// Tag representing an affine `Transform`. Its bottom-row is equal to `(0, 0 ... 0, 1)`.
|
||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
pub enum TAffine {}
|
pub enum TAffine {}
|
||||||
|
|
||||||
impl TCategory for TGeneral {
|
impl TCategory for TGeneral {
|
||||||
|
@ -198,16 +195,6 @@ where
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "cuda")]
|
|
||||||
unsafe impl<T: RealField + cust_core::DeviceCopy, C: TCategory, const D: usize>
|
|
||||||
cust_core::DeviceCopy for Transform<T, C, D>
|
|
||||||
where
|
|
||||||
Const<D>: DimNameAdd<U1>,
|
|
||||||
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
|
|
||||||
Owned<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>: cust_core::DeviceCopy,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: RealField, C: TCategory, const D: usize> Clone for Transform<T, C, D>
|
impl<T: RealField, C: TCategory, const D: usize> Clone for Transform<T, C, D>
|
||||||
where
|
where
|
||||||
Const<D>: DimNameAdd<U1>,
|
Const<D>: DimNameAdd<U1>,
|
||||||
|
@ -411,7 +398,7 @@ where
|
||||||
/// 3.0, 4.0, 0.0,
|
/// 3.0, 4.0, 0.0,
|
||||||
/// 0.0, 0.0, 1.0);
|
/// 0.0, 0.0, 1.0);
|
||||||
/// let t = Transform2::from_matrix_unchecked(m);
|
/// let t = Transform2::from_matrix_unchecked(m);
|
||||||
/// assert_eq!(t.into_inner(), m);
|
/// assert_eq!(t.to_homogeneous(), m);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
|
@ -32,7 +32,6 @@ use rkyv::bytecheck;
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
|
||||||
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Translation<T, const D: usize> {
|
pub struct Translation<T, const D: usize> {
|
||||||
/// The translation coordinates, i.e., how much is added to a point's coordinates when it is
|
/// The translation coordinates, i.e., how much is added to a point's coordinates when it is
|
||||||
|
|
|
@ -31,9 +31,6 @@ use std::cmp::{Eq, PartialEq};
|
||||||
/// * [Conversion to a matrix <span style="float:right;">`to_rotation_matrix`, `to_homogeneous`…</span>](#conversion-to-a-matrix)
|
/// * [Conversion to a matrix <span style="float:right;">`to_rotation_matrix`, `to_homogeneous`…</span>](#conversion-to-a-matrix)
|
||||||
pub type UnitComplex<T> = Unit<Complex<T>>;
|
pub type UnitComplex<T> = Unit<Complex<T>>;
|
||||||
|
|
||||||
#[cfg(feature = "cuda")]
|
|
||||||
unsafe impl<T: cust_core::DeviceCopy> cust_core::DeviceCopy for UnitComplex<T> {}
|
|
||||||
|
|
||||||
impl<T: Scalar + PartialEq> PartialEq for UnitComplex<T> {
|
impl<T: Scalar + PartialEq> PartialEq for UnitComplex<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, rhs: &Self) -> bool {
|
fn eq(&self, rhs: &Self) -> bool {
|
||||||
|
|
|
@ -34,6 +34,17 @@ pub fn reflection_axis_mut<T: ComplexField, D: Dim, S: StorageMut<T, D>>(
|
||||||
|
|
||||||
if !factor.is_zero() {
|
if !factor.is_zero() {
|
||||||
column.unscale_mut(factor.sqrt());
|
column.unscale_mut(factor.sqrt());
|
||||||
|
|
||||||
|
// Normalize again, making sure the vector is unit-sized.
|
||||||
|
// If `factor` had a very small value, the first normalization
|
||||||
|
// (dividing by `factor.sqrt()`) might end up with a slightly
|
||||||
|
// non-unit vector (especially when using 32-bits float).
|
||||||
|
// Decompositions strongly rely on that unit-vector property,
|
||||||
|
// so we run a second normalization (that is much more numerically
|
||||||
|
// stable since the norm is close to 1) to ensure it has a unit
|
||||||
|
// size.
|
||||||
|
let _ = column.normalize_mut();
|
||||||
|
|
||||||
(-signed_norm, true)
|
(-signed_norm, true)
|
||||||
} else {
|
} else {
|
||||||
// TODO: not sure why we don't have a - sign here.
|
// TODO: not sure why we don't have a - sign here.
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub fn svd_ordered2<T: RealField>(
|
||||||
// because q >= 0 and r >= 0.
|
// because q >= 0 and r >= 0.
|
||||||
let sx = q.clone() + r.clone();
|
let sx = q.clone() + r.clone();
|
||||||
let sy = q - r;
|
let sy = q - r;
|
||||||
let sy_sign = if sy < T::zero() { -one.clone() } else { one };
|
let sy_sign = if sy < T::zero() { -one } else { one };
|
||||||
let singular_values = Vector2::new(sx, sy * sy_sign.clone());
|
let singular_values = Vector2::new(sx, sy * sy_sign.clone());
|
||||||
|
|
||||||
if compute_u || compute_v {
|
if compute_u || compute_v {
|
||||||
|
|
|
@ -360,7 +360,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn wilkinson_shift_random() {
|
fn wilkinson_shift_random() {
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let m = Matrix2::new_random();
|
let m = Matrix2::<f64>::new_random();
|
||||||
let m = m * m.transpose();
|
let m = m * m.transpose();
|
||||||
|
|
||||||
let expected = expected_shift(m);
|
let expected = expected_shift(m);
|
||||||
|
|
|
@ -20,3 +20,5 @@ mod v022;
|
||||||
mod v023;
|
mod v023;
|
||||||
#[cfg(feature = "glam024")]
|
#[cfg(feature = "glam024")]
|
||||||
mod v024;
|
mod v024;
|
||||||
|
#[cfg(feature = "glam025")]
|
||||||
|
mod v025;
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#[path = "../common/glam_isometry.rs"]
|
||||||
|
mod glam_isometry;
|
||||||
|
#[path = "../common/glam_matrix.rs"]
|
||||||
|
mod glam_matrix;
|
||||||
|
#[path = "../common/glam_point.rs"]
|
||||||
|
mod glam_point;
|
||||||
|
#[path = "../common/glam_quaternion.rs"]
|
||||||
|
mod glam_quaternion;
|
||||||
|
#[path = "../common/glam_rotation.rs"]
|
||||||
|
mod glam_rotation;
|
||||||
|
#[path = "../common/glam_similarity.rs"]
|
||||||
|
mod glam_similarity;
|
||||||
|
#[path = "../common/glam_translation.rs"]
|
||||||
|
mod glam_translation;
|
||||||
|
#[path = "../common/glam_unit_complex.rs"]
|
||||||
|
mod glam_unit_complex;
|
||||||
|
|
||||||
|
pub(self) use glam025 as glam;
|
|
@ -92,3 +92,11 @@ fn to_homogeneous() {
|
||||||
|
|
||||||
assert_eq!(a.to_homogeneous(), expected);
|
assert_eq!(a.to_homogeneous(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn display_fmt_respects_modifiers() {
|
||||||
|
let p = Point3::new(1.23, 3.45, 5.67);
|
||||||
|
assert_eq!(&format!("{p}"), "{1.23, 3.45, 5.67}");
|
||||||
|
assert_eq!(&format!("{p:.1}"), "{1.2, 3.5, 5.7}");
|
||||||
|
assert_eq!(&format!("{p:.0}"), "{1, 3, 6}");
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use na::DMatrix;
|
use na::{DMatrix, Matrix3};
|
||||||
|
|
||||||
#[cfg(feature = "proptest-support")]
|
#[cfg(feature = "proptest-support")]
|
||||||
mod proptest_tests {
|
mod proptest_tests {
|
||||||
|
@ -116,6 +116,31 @@ fn symmetric_eigen_singular_24x24() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regression test for #1368
|
||||||
|
#[test]
|
||||||
|
fn very_small_deviation_from_identity_issue_1368() {
|
||||||
|
let m = Matrix3::<f32>::new(
|
||||||
|
1.0,
|
||||||
|
3.1575704e-23,
|
||||||
|
8.1146196e-23,
|
||||||
|
3.1575704e-23,
|
||||||
|
1.0,
|
||||||
|
1.7471054e-22,
|
||||||
|
8.1146196e-23,
|
||||||
|
1.7471054e-22,
|
||||||
|
1.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
for v in m
|
||||||
|
.try_symmetric_eigen(f32::EPSILON, 0)
|
||||||
|
.unwrap()
|
||||||
|
.eigenvalues
|
||||||
|
.into_iter()
|
||||||
|
{
|
||||||
|
assert_relative_eq!(*v, 1.);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// #[cfg(feature = "arbitrary")]
|
// #[cfg(feature = "arbitrary")]
|
||||||
// quickcheck! {
|
// quickcheck! {
|
||||||
// TODO: full eigendecomposition is not implemented yet because of its complexity when some
|
// TODO: full eigendecomposition is not implemented yet because of its complexity when some
|
||||||
|
|
Loading…
Reference in New Issue