#![deny(non_camel_case_types)]
#![deny(unused_parens)]
#![deny(non_upper_case_globals)]
#![deny(unused_qualifications)]
#![deny(unused_results)]
#![deny(missing_docs)]
#![doc(
html_favicon_url = "https://nalgebra.org/img/favicon.ico",
html_root_url = "https://nalgebra.org/rustdoc"
)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))]
#[cfg(feature = "arbitrary")]
extern crate quickcheck;
#[cfg(feature = "serde")]
extern crate serde;
#[cfg(feature = "serde")]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "abomonation-serialize")]
extern crate abomonation;
#[cfg(feature = "mint")]
extern crate mint;
#[macro_use]
extern crate approx;
#[cfg(feature = "std")]
extern crate matrixmultiply;
extern crate num_traits as num;
#[cfg(feature = "std")]
extern crate rand_distr;
#[cfg(all(feature = "alloc", not(feature = "std")))]
extern crate alloc;
#[cfg(not(feature = "std"))]
extern crate core as std;
#[cfg(feature = "io")]
extern crate pest;
#[macro_use]
#[cfg(feature = "io")]
extern crate pest_derive;
pub mod base;
#[cfg(feature = "debug")]
pub mod debug;
pub mod geometry;
#[cfg(feature = "io")]
pub mod io;
pub mod linalg;
#[cfg(feature = "sparse")]
pub mod sparse;
pub use crate::base::*;
pub use crate::geometry::*;
pub use crate::linalg::*;
#[cfg(feature = "sparse")]
pub use crate::sparse::*;
#[cfg(feature = "std")]
#[deprecated(
note = "The 'core' module is being renamed to 'base' to avoid conflicts with the 'core' crate."
)]
pub use base as core;
use simba::scalar::SupersetOf;
use std::cmp::{self, Ordering, PartialOrd};
use num::{One, Signed, Zero};
use base::allocator::Allocator;
pub use num_complex::Complex;
pub use simba::scalar::{
ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, ComplexField, Field, RealField,
};
pub use simba::simd::{SimdBool, SimdComplexField, SimdPartialOrd, SimdRealField};
#[inline]
pub fn one<T: One>() -> T {
T::one()
}
#[inline]
pub fn zero<T: Zero>() -> T {
T::zero()
}
#[inline]
pub fn wrap<T>(mut val: T, min: T, max: T) -> T
where
T: Copy + PartialOrd + ClosedAdd + ClosedSub,
{
assert!(min < max, "Invalid wrapping bounds.");
let width = max - min;
if val < min {
val += width;
while val < min {
val += width
}
val
} else if val > max {
val -= width;
while val > max {
val -= width
}
val
} else {
val
}
}
#[inline]
pub fn clamp<T: PartialOrd>(val: T, min: T, max: T) -> T {
if val > min {
if val < max {
val
} else {
max
}
} else {
min
}
}
#[inline]
pub fn max<T: Ord>(a: T, b: T) -> T {
cmp::max(a, b)
}
#[inline]
pub fn min<T: Ord>(a: T, b: T) -> T {
cmp::min(a, b)
}
#[deprecated(note = "use the inherent method `Matrix::abs` or `RealField::abs` instead")]
#[inline]
pub fn abs<T: Signed>(a: &T) -> T {
a.abs()
}
#[deprecated(note = "use the inherent method `Matrix::inf` instead")]
#[inline]
pub fn inf<N, R: Dim, C: Dim>(a: &MatrixMN<N, R, C>, b: &MatrixMN<N, R, C>) -> MatrixMN<N, R, C>
where
N: Scalar + SimdPartialOrd,
DefaultAllocator: Allocator<N, R, C>,
{
a.inf(b)
}
#[deprecated(note = "use the inherent method `Matrix::sup` instead")]
#[inline]
pub fn sup<N, R: Dim, C: Dim>(a: &MatrixMN<N, R, C>, b: &MatrixMN<N, R, C>) -> MatrixMN<N, R, C>
where
N: Scalar + SimdPartialOrd,
DefaultAllocator: Allocator<N, R, C>,
{
a.sup(b)
}
#[deprecated(note = "use the inherent method `Matrix::inf_sup` instead")]
#[inline]
pub fn inf_sup<N, R: Dim, C: Dim>(
a: &MatrixMN<N, R, C>,
b: &MatrixMN<N, R, C>,
) -> (MatrixMN<N, R, C>, MatrixMN<N, R, C>)
where
N: Scalar + SimdPartialOrd,
DefaultAllocator: Allocator<N, R, C>,
{
a.inf_sup(b)
}
#[inline]
pub fn partial_cmp<T: PartialOrd>(a: &T, b: &T) -> Option<Ordering> {
a.partial_cmp(b)
}
#[inline]
pub fn partial_lt<T: PartialOrd>(a: &T, b: &T) -> bool {
a.lt(b)
}
#[inline]
pub fn partial_le<T: PartialOrd>(a: &T, b: &T) -> bool {
a.le(b)
}
#[inline]
pub fn partial_gt<T: PartialOrd>(a: &T, b: &T) -> bool {
a.gt(b)
}
#[inline]
pub fn partial_ge<T: PartialOrd>(a: &T, b: &T) -> bool {
a.ge(b)
}
#[inline]
pub fn partial_min<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> Option<&'a T> {
if let Some(ord) = a.partial_cmp(b) {
match ord {
Ordering::Greater => Some(b),
_ => Some(a),
}
} else {
None
}
}
#[inline]
pub fn partial_max<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> Option<&'a T> {
if let Some(ord) = a.partial_cmp(b) {
match ord {
Ordering::Less => Some(b),
_ => Some(a),
}
} else {
None
}
}
#[inline]
pub fn partial_clamp<'a, T: PartialOrd>(value: &'a T, min: &'a T, max: &'a T) -> Option<&'a T> {
if let (Some(cmp_min), Some(cmp_max)) = (value.partial_cmp(min), value.partial_cmp(max)) {
if cmp_min == Ordering::Less {
Some(min)
} else if cmp_max == Ordering::Greater {
Some(max)
} else {
Some(value)
}
} else {
None
}
}
#[inline]
pub fn partial_sort2<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> Option<(&'a T, &'a T)> {
if let Some(ord) = a.partial_cmp(b) {
match ord {
Ordering::Less => Some((a, b)),
_ => Some((b, a)),
}
} else {
None
}
}
#[inline]
pub fn center<N: SimdComplexField, D: DimName>(p1: &Point<N, D>, p2: &Point<N, D>) -> Point<N, D>
where
DefaultAllocator: Allocator<N, D>,
{
((&p1.coords + &p2.coords) * convert::<_, N>(0.5)).into()
}
#[inline]
pub fn distance<N: SimdComplexField, D: DimName>(
p1: &Point<N, D>,
p2: &Point<N, D>,
) -> N::SimdRealField
where
DefaultAllocator: Allocator<N, D>,
{
(&p2.coords - &p1.coords).norm()
}
#[inline]
pub fn distance_squared<N: SimdComplexField, D: DimName>(
p1: &Point<N, D>,
p2: &Point<N, D>,
) -> N::SimdRealField
where
DefaultAllocator: Allocator<N, D>,
{
(&p2.coords - &p1.coords).norm_squared()
}
#[inline]
pub fn convert<From, To: SupersetOf<From>>(t: From) -> To {
To::from_subset(&t)
}
#[inline]
pub fn try_convert<From: SupersetOf<To>, To>(t: From) -> Option<To> {
t.to_subset()
}
#[inline]
pub fn is_convertible<From: SupersetOf<To>, To>(t: &From) -> bool {
t.is_in_subset()
}
#[inline]
pub fn convert_unchecked<From: SupersetOf<To>, To>(t: From) -> To {
t.to_subset_unchecked()
}
#[inline]
pub fn convert_ref<From, To: SupersetOf<From>>(t: &From) -> To {
To::from_subset(t)
}
#[inline]
pub fn try_convert_ref<From: SupersetOf<To>, To>(t: &From) -> Option<To> {
t.to_subset()
}
#[inline]
pub fn convert_ref_unchecked<From: SupersetOf<To>, To>(t: &From) -> To {
t.to_subset_unchecked()
}