Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 37 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ path = "src/lib.rs"

[features]
default = ["std", "macros"]
std = ["matrixmultiply", "num-traits/std", "num-complex/std", "num-rational/std", "approx/std", "simba/std"]
std = [
"matrixmultiply",
"num-traits/std",
"num-complex/std",
"num-rational/std",
"approx/std",
"simba/std",
]
sparse = []
debug = ["approx/num-complex", "rand"]
alloc = []
Expand Down Expand Up @@ -60,20 +67,31 @@ convert-glam030 = ["glam030"]
## `serde-serialize`.
serde-serialize-no-std = ["serde", "num-complex/serde"]
serde-serialize = ["serde-serialize-no-std", "serde/std"]
rkyv-serialize-no-std = ["rkyv/size_32"]
rkyv-serialize = ["rkyv-serialize-no-std", "rkyv/std", "rkyv/validation"]
rkyv-serialize-no-std = ["rkyv/pointer_width_32"]
rkyv-serialize = [
"rkyv-serialize-no-std",
"rkyv/std",
"rkyv/bytecheck",
"dep:bytecheck",
]

# Randomness
## To use rand in a #[no-std] environment, enable the
## `rand-no-std` feature instead of `rand`.
rand-no-std = ["rand-package"]
rand = ["rand-no-std", "rand-package/std", "rand-package/std_rng", "rand-package/thread_rng", "rand_distr"]
rand = [
"rand-no-std",
"rand-package/std",
"rand-package/std_rng",
"rand-package/thread_rng",
"rand_distr",
]

# Tests
arbitrary = ["quickcheck"]
proptest-support = ["proptest"]
slow-tests = []
rkyv-safe-deser = ["rkyv-serialize", "rkyv/validation"]
rkyv-safe-deser = ["rkyv-serialize"]

[dependencies]
nalgebra-macros = { version = "0.2.2", path = "nalgebra-macros", optional = true }
Expand All @@ -87,15 +105,20 @@ simba = { version = "0.9", default-features = false }
alga = { version = "0.9", default-features = false, optional = true }
rand_distr = { version = "0.5", default-features = false, optional = true }
matrixmultiply = { version = "0.3", optional = true }
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
rkyv = { version = "0.7.41", default-features = false, optional = true }
serde = { version = "1.0", default-features = false, features = [
"derive",
], optional = true }
rkyv = { version = "0.8", default-features = false, optional = true }
mint = { version = "0.5", optional = true }
quickcheck = { version = "1", optional = true }
pest = { version = "2", optional = true }
pest_derive = { version = "2", optional = true }
bytemuck = { version = "1.5", optional = true }
bytecheck = { version = "0.8", optional = true }
matrixcompare-core = { version = "0.1", optional = true }
proptest = { version = "1", optional = true, default-features = false, features = ["std"] }
proptest = { version = "1", optional = true, default-features = false, features = [
"std",
] }
glam014 = { package = "glam", version = "0.14", optional = true }
glam015 = { package = "glam", version = "0.15", optional = true }
glam016 = { package = "glam", version = "0.16", optional = true }
Expand Down Expand Up @@ -131,7 +154,12 @@ trybuild = "1.0.90"
cool_asserts = "2.0.3"

[workspace]
members = ["nalgebra-lapack", "nalgebra-glm", "nalgebra-sparse", "nalgebra-macros"]
members = [
"nalgebra-lapack",
"nalgebra-glm",
"nalgebra-sparse",
"nalgebra-macros",
]
resolver = "2"

[[example]]
Expand Down
38 changes: 27 additions & 11 deletions src/base/array_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde-serialize-no-std")]
use std::marker::PhantomData;

#[cfg(feature = "rkyv-serialize")]
use rkyv::bytecheck;

use crate::base::allocator::Allocator;
use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{Const, ToTypenum};
Expand All @@ -32,16 +29,15 @@ use std::mem;
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(
feature = "rkyv-serialize-no-std",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize),
archive(
as = "ArrayStorage<T::Archived, R, C>",
bound(archive = "
T: rkyv::Archive,
[[T; R]; C]: rkyv::Archive<Archived = [[T::Archived; R]; C]>
")
derive(rkyv::Archive, rkyv::Portable, rkyv::Serialize, rkyv::Deserialize, bytecheck::CheckBytes),
rkyv(
as = ArrayStorage<T::Archived, R, C>,
archive_bounds(
T: rkyv::Archive,
[[T; R]; C]: rkyv::Archive<Archived = [[T::Archived; R]; C]>
)
)
)]
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]);

impl<T, const R: usize, const C: usize> ArrayStorage<T, R, C> {
Expand Down Expand Up @@ -182,6 +178,26 @@ where
}
}

// TODO: implement PartialEq with generics.

#[cfg(feature = "rkyv-serialize")]
impl<const R: usize, const C: usize> PartialEq<ArrayStorage<f32, R, C>>
for ArrayStorage<rkyv::rend::f32_le, R, C>
{
fn eq(&self, other: &ArrayStorage<f32, R, C>) -> bool {
self.as_slice() == other.as_slice()
}
}

#[cfg(feature = "rkyv-serialize")]
impl<const R: usize, const C: usize> PartialEq<ArrayStorage<rkyv::rend::f32_le, R, C>>
for ArrayStorage<f32, R, C>
{
fn eq(&self, other: &ArrayStorage<rkyv::rend::f32_le, R, C>) -> bool {
self.as_slice() == other.as_slice()
}
}

/*
*
* Serialization.
Expand Down
9 changes: 1 addition & 8 deletions src/base/dimension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use std::fmt::Debug;
use std::ops::{Add, Div, Mul, Sub};
use typenum::{self, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, Unsigned};

#[cfg(feature = "rkyv-serialize")]
use rkyv::bytecheck;
#[cfg(feature = "serde-serialize-no-std")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};

Expand All @@ -19,10 +17,6 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
feature = "rkyv-serialize-no-std",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
#[cfg_attr(
feature = "rkyv-serialize",
archive_attr(derive(bytecheck::CheckBytes))
)]
pub struct Dyn(pub usize);

#[deprecated(note = "use Dyn instead.")]
Expand Down Expand Up @@ -216,9 +210,8 @@ dim_ops!(
#[cfg_attr(
feature = "rkyv-serialize-no-std",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize),
archive(as = "Self")
rkyv(derive(Debug), compare(PartialEq))
)]
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
pub struct Const<const R: usize>;

/// Trait implemented exclusively by type-level integers.
Expand Down
91 changes: 79 additions & 12 deletions src/base/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};

#[cfg(feature = "rkyv-serialize-no-std")]
use super::rkyv_wrappers::CustomPhantom;
#[cfg(feature = "rkyv-serialize")]
use rkyv::bytecheck;

#[cfg(feature = "rkyv-serialize-no-std")]
use rkyv::{with::With, Archive, Archived};
use rkyv::Archive;

use simba::scalar::{ClosedAddAssign, ClosedMulAssign, ClosedSubAssign, Field, SupersetOf};
use simba::simd::SimdPartialOrd;
Expand Down Expand Up @@ -161,16 +160,29 @@ pub type MatrixCross<T, R1, C1, R2, C2> =
#[cfg_attr(
feature = "rkyv-serialize-no-std",
derive(Archive, rkyv::Serialize, rkyv::Deserialize),
archive(
as = "Matrix<T::Archived, R, C, S::Archived>",
bound(archive = "
T: Archive,
S: Archive,
With<PhantomData<(T, R, C)>, CustomPhantom<(Archived<T>, R, C)>>: Archive<Archived = PhantomData<(Archived<T>, R, C)>>
")
rkyv(
compare(PartialEq, PartialOrd),
derive(Debug),
archive_bounds(
<S as Archive>::Archived: core::fmt::Debug,
<CustomPhantom<(<T as Archive>::Archived, R, C)> as rkyv::with::ArchiveWith<PhantomData<(T, R, C)>>>::Archived: Archive,
<CustomPhantom<(<T as Archive>::Archived, R, C)> as rkyv::with::ArchiveWith<PhantomData<(T, R, C)>>>::Archived: core::fmt::Debug,
//T: PartialEq,
T: Archive,
//S: Archive,
S: core::fmt::Debug,
),
deserialize_bounds(
<S as Archive>::Archived: core::fmt::Debug,
<CustomPhantom<(<T as Archive>::Archived, R, C)> as rkyv::with::ArchiveWith<PhantomData<(T, R, C)>>>::Archived: Archive,
<CustomPhantom<(<T as Archive>::Archived, R, C)> as rkyv::with::ArchiveWith<PhantomData<(T, R, C)>>>::Archived: core::fmt::Debug,
//T: PartialEq,
T: Archive,
//S: Archive,
S: core::fmt::Debug,
)
)
)]
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
pub struct Matrix<T, R, C, S> {
/// The data storage that contains all the matrix components. Disappointed?
///
Expand Down Expand Up @@ -207,7 +219,7 @@ pub struct Matrix<T, R, C, S> {
// of the `RawStorage` trait. However, because we don't have
// specialization, this is not possible because these `T, R, C`
// allows us to desambiguate a lot of configurations.
#[cfg_attr(feature = "rkyv-serialize-no-std", with(CustomPhantom<(T::Archived, R, C)>))]
#[cfg_attr(feature = "rkyv-serialize-no-std", rkyv(with =CustomPhantom<(T::Archived, R, C)>))]
_phantoms: PhantomData<(T, R, C)>,
}

Expand Down Expand Up @@ -1900,6 +1912,61 @@ where
self.shape() == right.shape() && self.iter().zip(right.iter()).all(|(l, r)| l == r)
}
}
/*
#[cfg(feature = "rkyv-serialize-no-std")]
impl<T, R, R2, C, C2, S, S2: rkyv::Archive> PartialEq<ArchivedMatrix<T, R2, C2, S2>>
for Matrix<T, R, C, S>
where
T: PartialEq,
C: Dim,
C2: Dim,
R: Dim,
R2: Dim + rkyv::Archive,
S: RawStorage<T, R, C>,
S2: core::fmt::Debug,
T: Archive,
<S2 as Archive>::Archived: core::fmt::Debug + RawStorage<T, R2, C2>,
//<R2 as Archive>::Archived: Dim,
{
#[inline]
fn eq(&self, right: &ArchivedMatrix<T, R2, C2, S2>) -> bool {
let shape = self.data.shape();
let shape = (shape.0.value(), shape.1.value());
let shape_right = right.data.shape();
let shape_right = (shape_right.0.value(), shape_right.1.value());
shape == shape_right
&& self
.iter()
.zip(MatrixIter::new(&right.data))
.all(|(l, r)| l == r)
}
}

#[cfg(feature = "rkyv-serialize-no-std")]
impl<T, R, C, S, S2> PartialEq<Matrix<T, R, C, S>> for ArchivedMatrix<T, R, C, S2>
where
T: PartialEq,
C: Dim,
R: Dim + rkyv::Archive,
S: RawStorage<T, R, C>,
S2: core::fmt::Debug + rkyv::Archive,
T: Archive,
<S2 as Archive>::Archived: core::fmt::Debug + RawStorage<T::Archived, R, C>,
//<R as Archive>::Archived: Dim,
{
#[inline]
fn eq(&self, right: &Matrix<T, R, C, S>) -> bool {
let shape = right.data.shape();
let shape = (shape.0.value(), shape.1.value());
let shape_right = self.data.shape();
let shape_right = (shape_right.0.value(), shape_right.1.value());
shape == shape_right
&& right
.iter()
.zip(MatrixIter::new(&self.data))
.all(|(l, r)| l == r)
}
}*/

macro_rules! impl_fmt {
($trait: path, $fmt_str_without_precision: expr, $fmt_str_with_precision: expr) => {
Expand Down
21 changes: 13 additions & 8 deletions src/base/rkyv_wrappers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
//! Copied from <https://github.com/rkyv/rkyv_contrib> (MIT-Apache2 licences) which isn’t published yet.

use rkyv::{
rancor::Fallible,
with::{ArchiveWith, DeserializeWith, SerializeWith},
Fallible,
Place,
};
use std::marker::PhantomData;

#[derive(Debug)]
/// A wrapper that allows for changing the generic type of a `PhantomData<T>`.
pub struct CustomPhantom<NT: ?Sized> {
_data: PhantomData<*const NT>,
Expand All @@ -18,13 +20,7 @@ impl<OT: ?Sized, NT: ?Sized> ArchiveWith<PhantomData<OT>> for CustomPhantom<NT>
type Resolver = ();

#[inline]
unsafe fn resolve_with(
_: &PhantomData<OT>,
_: usize,
_: Self::Resolver,
_: *mut Self::Archived,
) {
}
fn resolve_with(_: &PhantomData<OT>, _: Self::Resolver, _: Place<Self::Archived>) {}
}

impl<OT: ?Sized, NT: ?Sized, S: Fallible + ?Sized> SerializeWith<PhantomData<OT>, S>
Expand All @@ -44,3 +40,12 @@ impl<OT: ?Sized, NT: ?Sized, D: Fallible + ?Sized>
Ok(PhantomData)
}
}

// TODO: implement PartialEq with generics.

#[cfg(feature = "rkyv-serialize")]
impl<NT: ?Sized> PartialEq<CustomPhantom<NT>> for CustomPhantom<NT> {
fn eq(&self, _other: &CustomPhantom<NT>) -> bool {
true
}
}
14 changes: 5 additions & 9 deletions src/base/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ use crate::base::DefaultAllocator;
use crate::storage::RawStorage;
use crate::{Dim, Matrix, OMatrix, RealField, Scalar, SimdComplexField, SimdRealField};

#[cfg(feature = "rkyv-serialize")]
use rkyv::bytecheck;

/// A wrapper that ensures the underlying algebraic entity has a unit norm.
///
/// **It is likely that the only piece of documentation that you need in this page are:**
Expand All @@ -27,14 +24,13 @@ use rkyv::bytecheck;
#[cfg_attr(
feature = "rkyv-serialize-no-std",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize),
archive(
as = "Unit<T::Archived>",
bound(archive = "
rkyv(derive(Debug)),
rkyv(compare(PartialEq)),
rkyv(archive_bounds(
T: rkyv::Archive,
")
)
<T as rkyv::Archive>::Archived: fmt::Debug,
)),
)]
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
pub struct Unit<T> {
pub(crate) value: T,
}
Expand Down
Loading