1#![cfg_attr(not(feature = "std"), no_std)]
245#![allow(non_snake_case)]
246#![warn(rustdoc::broken_intra_doc_links)]
247extern crate alloc;
248#[cfg(feature = "std")]
249extern crate std;
250#[macro_export]
252macro_rules! make_guard {
253 ($($name:ident),* $(,)?) => {
254 $(#[allow(unused_unsafe)] let $name = unsafe { $crate::generativity::Id::new() };
255 #[allow(unused, unused_unsafe)] let lifetime_brand = unsafe {
256 $crate::generativity::LifetimeBrand::new(&$name) }; #[allow(unused_unsafe)] let
257 $name = unsafe { $crate::generativity::Guard::new($name) };)*
258 };
259}
260macro_rules! repeat_n {
261 ($e:expr, $n:expr) => {
262 iter::repeat_n($e, $n)
263 };
264}
265use core::num::NonZeroUsize;
266use equator::{assert, debug_assert};
267use faer_traits::*;
268#[macro_export]
270macro_rules! auto {
271 ($ty:ty $(,)?) => {
272 $crate::Auto::<$ty>::auto()
273 };
274}
275macro_rules! dispatch {
276 ($imp:expr, $ty:ident, $T:ty $(,)?) => {
277 if const { <$T>::IS_NATIVE_C32 } {
278 unsafe {
279 transmute(
280 <ComplexImpl<f32> as ComplexField>::Arch::default()
281 .dispatch(transmute::<_, $ty<ComplexImpl<f32>>>($imp)),
282 )
283 }
284 } else if const { <$T>::IS_NATIVE_C64 } {
285 unsafe {
286 transmute(
287 <ComplexImpl<f64> as ComplexField>::Arch::default()
288 .dispatch(transmute::<_, $ty<ComplexImpl<f64>>>($imp)),
289 )
290 }
291 } else {
292 <$T>::Arch::default().dispatch($imp)
293 }
294 };
295}
296macro_rules! stack_mat {
297 ($name:ident, $m:expr, $n:expr, $A:expr, $N:expr, $T:ty $(,)?) => {
298 let mut __tmp = {
299 #[repr(align(64))]
300 struct __Col<T, const A: usize>([T; A]);
301 struct __Mat<T, const A: usize, const N: usize>([__Col<T, A>; N]);
302 core::mem::MaybeUninit::<__Mat<$T, $A, $N>>::uninit()
303 };
304 let __stack = MemStack::new_any(core::slice::from_mut(&mut __tmp));
305 let mut $name =
306 $crate::linalg::temp_mat_zeroed::<$T, _, _>($m, $n, __stack).0;
307 let mut $name = $crate::mat::AsMatMut::as_mat_mut(&mut $name);
308 };
309 ($name:ident, $m:expr, $n:expr, $T:ty $(,)?) => {
310 stack_mat!($name, $m, $n, $m, $n, $T)
311 };
312}
313#[macro_export]
314#[doc(hidden)]
315macro_rules! __dbg {
316 () => {
317 std::eprintln!("[{}:{}:{}]", std::file!(), std::line!(), std::column!())
318 };
319 ($val:expr $(,)?) => {
320 match $val { tmp => { std::eprintln!("[{}:{}:{}] {} = {:20?}", std::file!(),
321 std::line!(), std::column!(), std::stringify!($val), & tmp); tmp } }
322 };
323 ($($val:expr),+ $(,)?) => {
324 ($($crate::__dbg!($val)),+,)
325 };
326}
327#[cfg(feature = "perf-warn")]
328#[macro_export]
329#[doc(hidden)]
330macro_rules! __perf_warn {
331 ($name:ident) => {{
332 #[inline(always)]
333 #[allow(non_snake_case)]
334 fn $name() -> &'static ::core::sync::atomic::AtomicBool {
335 static $name: ::core::sync::atomic::AtomicBool =
336 ::core::sync::atomic::AtomicBool::new(false);
337 &$name
338 }
339 ::core::matches!(
340 $name().compare_exchange(
341 false,
342 true,
343 ::core::sync::atomic::Ordering::Relaxed,
344 ::core::sync::atomic::Ordering::Relaxed,
345 ),
346 Ok(_)
347 )
348 }};
349}
350#[doc(hidden)]
351#[macro_export]
352macro_rules! with_dim {
353 ($name:ident, $value:expr $(,)?) => {
354 let __val__ = $value; $crate::make_guard!($name); let $name =
355 $crate::utils::bound::Dim::new(__val__, $name);
356 };
357 ({ $(let $name:ident = $value:expr;)* }) => {
358 $(let __val__ = $value; $crate::make_guard!($name); let $name =
359 $crate::utils::bound::Dim::new(__val__, $name);)*
360 };
361}
362#[macro_export]
386macro_rules! zip {
387 ($head:expr $(,)?) => {
388 $crate::linalg::zip::LastEq($crate::linalg::zip::IntoView::into_view($head),
389 ::core::marker::PhantomData)
390 };
391 ($head:expr, $($tail:expr),* $(,)?) => {
392 $crate::linalg::zip::ZipEq::new($crate::linalg::zip::IntoView::into_view($head),
393 $crate::zip!($($tail,)*))
394 };
395}
396#[macro_export]
418macro_rules! Zip {
419 (..$(,)?) => {
420 _
421 };
422 ($head:ty $(,)?) => {
423 $crate::linalg::zip::Last::<$head >
424 };
425 ($head:ty, $($tail:tt)*) => {
426 $crate::linalg::zip::Zip::<$head, $crate::Zip!($($tail)*) >
427 };
428}
429#[macro_export]
449macro_rules! unzip {
450 (..$(,)?) => {
451 _
452 };
453 ($head:pat $(,)?) => {
454 $crate::linalg::zip::Last($head)
455 };
456 ($head:pat, $($tail:tt)*) => {
457 $crate::linalg::zip::Zip($head, $crate::unzip!($($tail)*))
458 };
459}
460#[macro_export]
461#[doc(hidden)]
462macro_rules! __transpose_impl {
463 ([$([$($col:expr),*])*] $($v:expr;)*) => {
464 [$([$($col,)*],)* [$($v,)*]]
465 };
466 ([$([$($col:expr),*])*] $($v0:expr, $($v:expr),*;)*) => {
467 $crate::__transpose_impl!([$([$($col),*])* [$($v0),*]] $($($v),*;)*)
468 };
469}
470#[macro_export]
494macro_rules! mat {
495 () => {
496 { compile_error!("number of columns in the matrix is ambiguous"); }
497 };
498 ($([$($v:expr),* $(,)?]),* $(,)?) => {
499 { let __data = ::core::mem::ManuallyDrop::new($crate::__transpose_impl!([]
500 $($($v),*;)*)); let __data = &* __data; let __ncols = __data.len(); let __nrows =
501 (* __data.get(0).unwrap()).len(); #[allow(unused_unsafe)] unsafe {
502 $crate::mat::Mat::from_fn(__nrows, __ncols, | i, j | ::core::ptr::from_ref(&
503 __data[j] [i]).read()) } }
504 };
505 (
506 @ alloc $($unsafe:ident)? ($stack:ident) ($var:pat) (uninit::<$ty:ty >, $($arg:expr),+
507 $(,)?)
508 ) => {
509 let (mut __mat__, $stack) = $($unsafe)? { $crate::linalg::temp_mat_uninit::<$ty, _, _
510 > ($($arg,)* $stack,) }; let $var = $crate::mat::AsMatMut::as_mat_mut(&mut __mat__);
511 };
512 (
513 @ alloc $($unsafe:ident)? ($stack:ident) ($var:pat) (zero::<$ty:ty >, $($arg:expr),+
514 $(,)?)
515 ) => {
516 let (mut __mat__, $stack) = $($unsafe)? { $crate::linalg::temp_mat_zeroed::<$ty, _, _
517 > ($($arg,)* $stack,) }; let $var = $crate::mat::AsMatMut::as_mat_mut(&mut __mat__);
518 };
519}
520#[macro_export]
531macro_rules! col {
532 ($($v:expr),* $(,)?) => {
533 { let __data = ::core::mem::ManuallyDrop::new([$($v,)*]); let __data = &* __data;
534 let __len = __data.len(); #[allow(unused_unsafe)] unsafe {
535 $crate::col::Col::from_fn(__len, | i | ::core::ptr::from_ref(& __data[i]).read())
536 } }
537 };
538 (
539 @ alloc $($unsafe:ident)? ($stack:ident) ($var:pat) (uninit::<$ty:ty >, $($arg:expr),+
540 $(,)?)
541 ) => {
542 let (mut __mat__, $stack) = $($unsafe)? { $crate::linalg::temp_mat_uninit::<$ty, _, _
543 > ($($arg,)* 1, $stack,) }; let $var = $crate::mat::AsMatMut::as_mat_mut(&mut __mat__).col_mut(0);
544 };
545
546 (
547 @ alloc $($unsafe:ident)? ($stack:ident) ($var:pat) (zero::<$ty:ty >, $($arg:expr),+
548 $(,)?)
549 ) => {
550 let (mut __mat__, $stack) = $($unsafe)? { $crate::linalg::temp_mat_zeroed::<$ty, _, _
551 > ($($arg,)* 1, $stack,) }; let $var = $crate::mat::AsMatMut::as_mat_mut(&mut __mat__).col_mut(0);
552 };
553}
554#[macro_export]
565macro_rules! row {
566 ($($v:expr),* $(,)?) => {
567 { let __data = ::core::mem::ManuallyDrop::new([$($v,)*]); let __data = &* __data;
568 let __len = __data.len(); #[allow(unused_unsafe)] unsafe {
569 $crate::row::Row::from_fn(__len, | i | ::core::ptr::from_ref(& __data[i]).read())
570 } }
571 };
572 (
573 @ alloc $($unsafe:ident)? ($stack:ident) ($var:pat) (uninit::<$ty:ty >, $($arg:expr),+
574 $(,)?)
575 ) => {
576 let (mut __mat__, $stack) = $($unsafe)? { $crate::linalg::temp_mat_uninit::<$ty, _, _
577 > ($($arg,)* 1, $stack,) }; let $var = $crate::mat::AsMatMut::as_mat_mut(&mut __mat__).col_mut(0).transpose_mut();
578 };
579
580 (
581 @ alloc $($unsafe:ident)? ($stack:ident) ($var:pat) (zero::<$ty:ty >, $($arg:expr),+
582 $(,)?)
583 ) => {
584 let (mut __mat__, $stack) = $($unsafe)? { $crate::linalg::temp_mat_zeroed::<$ty, _, _
585 > ($($arg,)* 1, $stack,) }; let $var = $crate::mat::AsMatMut::as_mat_mut(&mut __mat__).col_mut(0).transpose_mut();
586 };
587}
588#[doc(hidden)]
599#[track_caller]
600pub fn concat_impl<T: ComplexField>(
601 blocks: &[&[(mat::MatRef<'_, T>, Conj)]],
602) -> mat::Mat<T> {
603 #[inline(always)]
604 fn count_total_columns<T: ComplexField>(
605 block_row: &[(mat::MatRef<'_, T>, Conj)],
606 ) -> usize {
607 let mut out: usize = 0;
608 for (elem, _) in block_row.iter() {
609 out += elem.ncols();
610 }
611 out
612 }
613 #[inline(always)]
614 #[track_caller]
615 fn count_rows<T: ComplexField>(
616 block_row: &[(mat::MatRef<'_, T>, Conj)],
617 ) -> usize {
618 let mut out: usize = 0;
619 for (i, (e, _)) in block_row.iter().enumerate() {
620 if i == 0 {
621 out = e.nrows();
622 } else {
623 assert!(e.nrows() == out);
624 }
625 }
626 out
627 }
628 let mut n: usize = 0;
629 let mut m: usize = 0;
630 for row in blocks.iter() {
631 n += count_rows(row);
632 }
633 for (i, row) in blocks.iter().enumerate() {
634 let cols = count_total_columns(row);
635 if i == 0 {
636 m = cols;
637 } else {
638 assert!(cols == m);
639 }
640 }
641 let mut mat = mat::Mat::<T>::zeros(n, m);
642 let mut ni: usize = 0;
643 let mut mj: usize;
644 for row in blocks.iter() {
645 mj = 0;
646 for (elem, conj) in row.iter() {
647 let mut dst =
648 mat.as_mut()
649 .submatrix_mut(ni, mj, elem.nrows(), elem.ncols());
650 if *conj == Conj::No {
651 dst.copy_from(elem);
652 } else {
653 dst.copy_from(elem.conjugate());
654 }
655 mj += elem.ncols();
656 }
657 ni += row[0].0.nrows();
658 }
659 mat
660}
661#[macro_export]
669macro_rules! concat {
670 () => {
671 { compile_error!("number of columns in the matrix is ambiguous"); }
672 };
673 ($([$($v:expr),* $(,)?]),* $(,)?) => {
674 { $crate::concat_impl(& [$(& [$(($v).as_ref().__canonicalize(),)*],)*]) }
675 };
676}
677pub mod col;
679pub mod diag;
681#[cfg(feature = "std")]
683pub mod io;
684pub mod linalg;
685pub mod mat;
687#[path = "./operator/mod.rs"]
688pub mod matrix_free;
689pub mod perm;
691pub mod row;
693pub mod sparse;
694pub mod utils;
696#[cfg(feature = "threadteam")]
698pub use utils::team;
699pub trait Index: traits::IndexCore + traits::Index + seal::Seal {}
701impl<T: faer_traits::Index<Signed: seal::Seal> + seal::Seal> Index for T {}
702mod seal {
703 pub trait Seal {}
704 impl<T: faer_traits::Seal> Seal for T {}
705 impl Seal for crate::utils::bound::Dim<'_> {}
706 impl<I: crate::Index> Seal for crate::utils::bound::Idx<'_, I> {}
707 impl<I: crate::Index> Seal for crate::utils::bound::IdxInc<'_, I> {}
708 impl<I: crate::Index> Seal for crate::utils::bound::MaybeIdx<'_, I> {}
709 impl<I: crate::Index> Seal for crate::utils::bound::IdxIncOne<I> {}
710 impl<I: crate::Index> Seal for crate::utils::bound::MaybeIdxOne<I> {}
711 impl Seal for crate::utils::bound::One {}
712 impl Seal for crate::utils::bound::Zero {}
713 impl Seal for crate::ContiguousFwd {}
714 impl Seal for crate::ContiguousBwd {}
715}
716pub trait Unbind<I = usize>:
719 Send + Sync + Copy + core::fmt::Debug + seal::Seal
720{
721 unsafe fn new_unbound(idx: I) -> Self;
725 fn unbound(self) -> I;
727}
728pub type Idx<Dim, I = usize> = <Dim as ShapeIdx>::Idx<I>;
730pub type IdxInc<Dim, I = usize> = <Dim as ShapeIdx>::IdxInc<I>;
732pub type MaybeIdx<Dim, I = usize> = <Dim as ShapeIdx>::MaybeIdx<I>;
734pub trait ShapeIdx {
736 type Idx<I: Index>: Unbind<I> + Ord + Eq;
738 type IdxInc<I: Index>: Unbind<I> + Ord + Eq + From<Idx<Self, I>>;
740 type MaybeIdx<I: Index>: Unbind<I::Signed> + Ord + Eq;
742}
743pub trait Shape:
745 Unbind
746 + Ord
747 + ShapeIdx<
748 Idx<usize>: Ord + Eq + PartialOrd<Self>,
749 IdxInc<usize>: Ord + Eq + PartialOrd<Self>,
750 >
751{
752 const IS_BOUND: bool = true;
754 #[inline]
756 fn bind<'n>(self, guard: generativity::Guard<'n>) -> utils::bound::Dim<'n> {
757 utils::bound::Dim::new(self.unbound(), guard)
758 }
759 #[inline]
761 fn cast_idx_slice<I: Index>(slice: &[Idx<Self, I>]) -> &[I] {
762 unsafe { core::slice::from_raw_parts(slice.as_ptr() as _, slice.len()) }
763 }
764 #[inline]
766 fn cast_idx_inc_slice<I: Index>(slice: &[IdxInc<Self, I>]) -> &[I] {
767 unsafe { core::slice::from_raw_parts(slice.as_ptr() as _, slice.len()) }
768 }
769 #[inline(always)]
771 fn start() -> IdxInc<Self> {
772 unsafe { IdxInc::<Self>::new_unbound(0) }
773 }
774 #[inline(always)]
776 fn next(idx: Idx<Self>) -> IdxInc<Self> {
777 unsafe { IdxInc::<Self>::new_unbound(idx.unbound() + 1) }
778 }
779 #[inline(always)]
781 fn end(self) -> IdxInc<Self> {
782 unsafe { IdxInc::<Self>::new_unbound(self.unbound()) }
783 }
784 #[inline(always)]
786 fn idx(self, idx: usize) -> Option<Idx<Self>> {
787 if idx < self.unbound() {
788 Some(unsafe { Idx::<Self>::new_unbound(idx) })
789 } else {
790 None
791 }
792 }
793 #[inline(always)]
795 fn idx_inc(self, idx: usize) -> Option<IdxInc<Self>> {
796 if idx <= self.unbound() {
797 Some(unsafe { IdxInc::<Self>::new_unbound(idx) })
798 } else {
799 None
800 }
801 }
802 #[inline(always)]
804 fn checked_idx(self, idx: usize) -> Idx<Self> {
805 equator::assert!(idx < self.unbound());
806 unsafe { Idx::<Self>::new_unbound(idx) }
807 }
808 #[inline(always)]
810 fn checked_idx_inc(self, idx: usize) -> IdxInc<Self> {
811 equator::assert!(idx <= self.unbound());
812 unsafe { IdxInc::<Self>::new_unbound(idx) }
813 }
814 #[inline(always)]
818 unsafe fn unchecked_idx(self, idx: usize) -> Idx<Self> {
819 equator::debug_assert!(idx < self.unbound());
820 unsafe { Idx::<Self>::new_unbound(idx) }
821 }
822 #[inline(always)]
826 unsafe fn unchecked_idx_inc(self, idx: usize) -> IdxInc<Self> {
827 equator::debug_assert!(idx <= self.unbound());
828 unsafe { IdxInc::<Self>::new_unbound(idx) }
829 }
830 #[inline(always)]
832 fn indices(
833 from: IdxInc<Self>,
834 to: IdxInc<Self>,
835 ) -> impl Clone + ExactSizeIterator + DoubleEndedIterator<Item = Idx<Self>>
836 {
837 (from.unbound()..to.unbound()).map(
838 #[inline(always)]
839 |i| unsafe { Idx::<Self>::new_unbound(i) },
840 )
841 }
842}
843impl<T: Send + Sync + Copy + core::fmt::Debug + faer_traits::Seal> Unbind<T>
844 for T
845{
846 #[inline(always)]
847 unsafe fn new_unbound(idx: T) -> Self {
848 idx
849 }
850
851 #[inline(always)]
852 fn unbound(self) -> T {
853 self
854 }
855}
856impl ShapeIdx for usize {
857 type Idx<I: Index> = I;
858 type IdxInc<I: Index> = I;
859 type MaybeIdx<I: Index> = I::Signed;
860}
861impl Shape for usize {
862 const IS_BOUND: bool = false;
863}
864pub trait Stride:
866 seal::Seal + core::fmt::Debug + Copy + Send + Sync + 'static
867{
868 type Rev: Stride<Rev = Self>;
870 fn rev(self) -> Self::Rev;
872 fn element_stride(self) -> isize;
874}
875impl Stride for isize {
876 type Rev = Self;
877
878 #[inline(always)]
879 fn rev(self) -> Self::Rev {
880 -self
881 }
882
883 #[inline(always)]
884 fn element_stride(self) -> isize {
885 self
886 }
887}
888#[derive(Copy, Clone, Debug)]
890pub struct ContiguousFwd;
891#[derive(Copy, Clone, Debug)]
893pub struct ContiguousBwd;
894impl Stride for ContiguousFwd {
895 type Rev = ContiguousBwd;
896
897 #[inline(always)]
898 fn rev(self) -> Self::Rev {
899 ContiguousBwd
900 }
901
902 #[inline(always)]
903 fn element_stride(self) -> isize {
904 1
905 }
906}
907impl Stride for ContiguousBwd {
908 type Rev = ContiguousFwd;
909
910 #[inline(always)]
911 fn rev(self) -> Self::Rev {
912 ContiguousFwd
913 }
914
915 #[inline(always)]
916 fn element_stride(self) -> isize {
917 -1
918 }
919}
920#[derive(Copy, Clone, Debug, PartialEq, Eq)]
922pub enum TryReserveError {
923 CapacityOverflow,
925 AllocError {
927 layout: core::alloc::Layout,
929 },
930}
931#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
933pub enum Conj {
934 No,
936 Yes,
938}
939#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
940pub(crate) enum DiagStatus {
941 Unit,
942 Generic,
943}
944#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
946pub enum Accum {
947 Replace,
949 Add,
951}
952#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
954pub enum Side {
955 Lower,
957 Upper,
959}
960impl Conj {
961 #[inline]
963 pub const fn is_conj(self) -> bool {
964 matches!(self, Conj::Yes)
965 }
966
967 #[inline]
969 pub const fn compose(self, other: Self) -> Self {
970 match (self, other) {
971 (Conj::No, Conj::No) => Conj::No,
972 (Conj::Yes, Conj::Yes) => Conj::No,
973 (Conj::No, Conj::Yes) => Conj::Yes,
974 (Conj::Yes, Conj::No) => Conj::Yes,
975 }
976 }
977
978 #[inline]
981 pub const fn get<T: Conjugate>() -> Self {
982 if T::IS_CANONICAL { Self::No } else { Self::Yes }
983 }
984
985 #[inline]
986 pub(crate) fn apply<T: Conjugate>(value: &T) -> T::Canonical {
987 let value = unsafe { &*(value as *const T as *const T::Canonical) };
988 if const { matches!(Self::get::<T>(), Conj::Yes) } {
989 T::Canonical::conj_impl(value)
990 } else {
991 T::Canonical::copy_impl(value)
992 }
993 }
994
995 #[inline]
996 pub(crate) fn apply_rt<T: ComplexField>(self, value: &T) -> T {
997 if self.is_conj() {
998 T::conj_impl(value)
999 } else {
1000 T::copy_impl(value)
1001 }
1002 }
1003}
1004#[derive(Debug)]
1056pub enum Par<'team> {
1057 Seq,
1059 #[cfg(feature = "threadteam")]
1064 Team(threadteam::TeamExec<'team>),
1065 #[cfg(not(feature = "threadteam"))]
1068 #[doc(hidden)]
1069 __Lifetime(core::convert::Infallible, core::marker::PhantomData<&'team ()>),
1070}
1071#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1075pub enum ParShape {
1076 Seq,
1078 #[cfg(feature = "threadteam")]
1081 Team(NonZeroUsize, threadteam::DispatchCosts),
1082}
1083impl ParShape {
1084 #[inline]
1086 pub const fn seq() -> Self {
1087 Self::Seq
1088 }
1089
1090 #[cfg(feature = "threadteam")]
1092 #[inline]
1093 pub fn team(nthreads: usize) -> Self {
1094 #[cfg(feature = "threadteam")]
1095 Self::Team(
1096 NonZeroUsize::new(nthreads.max(1)).unwrap(),
1097 threadteam::DispatchCosts::host_default(),
1098 )
1099 }
1100
1101 #[inline]
1103 pub fn degree(self) -> usize {
1104 match self {
1105 Self::Seq => 1,
1106 #[cfg(feature = "threadteam")]
1107 Self::Team(n, _) => n.get(),
1108 }
1109 }
1110}
1111impl Par<'_> {
1112 #[inline]
1115 pub fn reborrow(&mut self) -> Par<'_> {
1116 match self {
1117 Par::Seq => Par::Seq,
1118 #[cfg(feature = "threadteam")]
1119 Par::Team(team) => Par::Team(team.reborrow()),
1120 #[cfg(not(feature = "threadteam"))]
1121 Par::__Lifetime(x, _) => match *x {},
1122 }
1123 }
1124
1125 #[inline]
1127 pub fn shape(&self) -> ParShape {
1128 match self {
1129 Par::Seq => ParShape::Seq,
1130 #[cfg(feature = "threadteam")]
1131 Par::Team(team) => ParShape::Team(team.size(), team.dispatch_costs()),
1132 #[cfg(not(feature = "threadteam"))]
1133 Par::__Lifetime(x, _) => match *x {},
1134 }
1135 }
1136
1137 #[inline]
1140 pub fn degree(&self) -> usize {
1141 match self {
1142 Par::Seq => 1,
1143 #[cfg(feature = "threadteam")]
1144 Par::Team(team) => team.size().get(),
1145 #[cfg(not(feature = "threadteam"))]
1146 Par::__Lifetime(x, _) => match *x {},
1147 }
1148 }
1149}
1150#[allow(non_camel_case_types)]
1151pub type c32 = traits::c32;
1153#[allow(non_camel_case_types)]
1154pub type c64 = traits::c64;
1156#[allow(non_camel_case_types)]
1157pub type cx128 = traits::cx128;
1159#[allow(non_camel_case_types)]
1160pub type fx128 = traits::fx128;
1162pub use col::{Col, ColMut, ColRef};
1163pub use mat::{Mat, MatMut, MatRef, MatUninitMut};
1164pub use row::{Row, RowMut, RowRef};
1165#[allow(unused_imports, dead_code)]
1166mod internal_prelude {
1167 pub use crate::simd_iter;
1168
1169 pub trait DivCeil: Sized {
1170 fn msrv_div_ceil(self, rhs: Self) -> Self;
1171 fn msrv_next_multiple_of(self, rhs: Self) -> Self;
1172 fn msrv_checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
1173 }
1174 impl DivCeil for usize {
1175 #[inline]
1176 fn msrv_div_ceil(self, rhs: Self) -> Self {
1177 let d = self / rhs;
1178 let r = self % rhs;
1179 if r > 0 { d + 1 } else { d }
1180 }
1181
1182 #[inline]
1183 fn msrv_next_multiple_of(self, rhs: Self) -> Self {
1184 match self % rhs {
1185 0 => self,
1186 r => self + (rhs - r),
1187 }
1188 }
1189
1190 #[inline]
1191 fn msrv_checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
1192 {
1193 match self.checked_rem(rhs)? {
1194 0 => Some(self),
1195 r => self.checked_add(rhs - r),
1196 }
1197 }
1198 }
1199 }
1200 pub(crate) use crate::col::{Col, ColMut, ColRef};
1201 pub(crate) use crate::diag::{Diag, DiagMut, DiagRef};
1202 pub(crate) use crate::hacks::transmute;
1203 pub(crate) use crate::linalg::{
1204 self, temp_mat_scratch, temp_mat_uninit, temp_mat_zeroed,
1205 };
1206 pub(crate) use crate::mat::{
1207 AsMat, AsMatMut, AsMatRef, Mat, MatMut, MatRef,
1208 };
1209 pub(crate) use crate::perm::{Perm, PermRef};
1210 pub(crate) use crate::prelude::*;
1211 pub(crate) use crate::row::{AsRowMut, AsRowRef, Row, RowMut, RowRef};
1212 pub(crate) use crate::utils::bound::{Array, Dim, Idx, IdxInc, MaybeIdx};
1213 pub(crate) use crate::utils::simd::SimdCtx;
1214 pub(crate) use crate::{Auto, NonExhaustive, Side, Spec};
1215 pub use faer_traits::ext::*;
1216 pub use faer_traits::math_utils::*;
1217 pub use faer_traits::{
1218 ComplexField, ComplexImpl, ComplexImplConj, Conjugate, Index,
1219 IndexCore, Real, RealField, SignedIndex, SimdArch, Symbolic,
1220 };
1221 pub use num_complex::Complex;
1222 #[cfg(test)]
1223 pub(crate) use std::dbg;
1224 #[cfg(test)]
1225 pub(crate) use {alloc::boxed::Box, alloc::vec, alloc::vec::Vec};
1226 #[inline]
1227 pub fn simd_align(i: usize) -> usize {
1228 i.wrapping_neg()
1229 }
1230 pub(crate) use self::{unzip as uz, zip as z};
1231 pub(crate) use crate::{
1232 Accum, Conj, ContiguousBwd, ContiguousFwd, DiagStatus, Par, ParShape,
1233 Shape, Stride, Unbind, make_guard, unzip, zip,
1234 };
1235 pub use dyn_stack::{MemStack, StackReq, alloc as alloca};
1236 pub use equator::{
1237 assert, assert as Assert, debug_assert, debug_assert as DebugAssert,
1238 };
1239 pub use reborrow::*;
1240}
1241#[allow(unused_imports)]
1242pub(crate) mod internal_prelude_sp {
1243 pub(crate) use crate::internal_prelude::*;
1244 pub(crate) use crate::sparse::{
1245 FaerError, NONE, Pair, SparseColMat, SparseColMatMut, SparseColMatRef,
1246 SparseRowMat, SparseRowMatMut, SparseRowMatRef, SymbolicSparseColMat,
1247 SymbolicSparseColMatRef, SymbolicSparseRowMat, SymbolicSparseRowMatRef,
1248 Triplet, csc_numeric, csc_symbolic, csr_numeric, csr_symbolic,
1249 linalg as linalg_sp, try_collect, try_zeroed, windows2,
1250 };
1251 pub(crate) use core::cell::Cell;
1252 pub(crate) use core::iter;
1253 pub(crate) use dyn_stack::MemBuffer;
1254}
1255pub mod prelude {
1257 #[cfg(feature = "linalg")]
1258 pub use super::linalg::solvers::{DenseSolve, Solve, SolveLstsq};
1259 #[cfg(feature = "sparse")]
1260 pub use super::prelude_sp::*;
1261 pub use super::{Par, ParShape, Scale, c32, c64, col, mat, row, unzip, zip};
1262 pub use col::{Col, ColMut, ColRef};
1263 pub use mat::{Mat, MatMut, MatRef, MatUninitMut};
1264 pub use reborrow::{IntoConst, Reborrow, ReborrowMut};
1265 pub use row::{Row, RowMut, RowRef};
1266 #[inline]
1268 pub fn default<T: Default>() -> T {
1269 Default::default()
1270 }
1271}
1272#[cfg(feature = "sparse")]
1273mod prelude_sp {
1274 use crate::sparse;
1275 pub use sparse::{
1276 SparseColMat, SparseColMatMut, SparseColMatRef, SparseRowMat,
1277 SparseRowMatMut, SparseRowMatRef,
1278 };
1279}
1280#[derive(Copy, Clone, Debug)]
1282#[repr(transparent)]
1283pub struct Scale<T>(pub T);
1284impl<T> Scale<T> {
1285 #[inline(always)]
1287 pub fn from_ref(value: &T) -> &Self {
1288 unsafe { &*(value as *const T as *const Self) }
1289 }
1290
1291 #[inline(always)]
1294 pub fn from_mut(value: &mut T) -> &mut Self {
1295 unsafe { &mut *(value as *mut T as *mut Self) }
1296 }
1297}
1298#[doc(hidden)]
1299pub mod hacks;
1300pub mod stats;
1302mod non_exhaustive {
1303 #[doc(hidden)]
1304 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
1305 #[repr(transparent)]
1306 pub struct NonExhaustive(pub(crate) ());
1307}
1308pub(crate) use non_exhaustive::NonExhaustive;
1309pub trait Auto<T> {
1312 fn auto() -> Self;
1314}
1315pub struct Spec<Config, T> {
1318 pub config: Config,
1320 __marker: core::marker::PhantomData<fn() -> T>,
1321}
1322impl<Config, T> core::ops::Deref for Spec<Config, T> {
1323 type Target = Config;
1324
1325 #[inline]
1326 fn deref(&self) -> &Self::Target {
1327 &self.config
1328 }
1329}
1330impl<Config, T> core::ops::DerefMut for Spec<Config, T> {
1331 #[inline]
1332 fn deref_mut(&mut self) -> &mut Self::Target {
1333 &mut self.config
1334 }
1335}
1336impl<Config: Copy, T> Copy for Spec<Config, T> {}
1337impl<Config: Clone, T> Clone for Spec<Config, T> {
1338 #[inline]
1339 fn clone(&self) -> Self {
1340 Self::new(self.config.clone())
1341 }
1342}
1343impl<Config: core::fmt::Debug, T> core::fmt::Debug for Spec<Config, T> {
1344 #[inline]
1345 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1346 self.config.fmt(f)
1347 }
1348}
1349impl<Config, T> Spec<Config, T> {
1350 #[inline]
1352 pub fn new(config: Config) -> Self {
1353 Spec {
1354 config,
1355 __marker: core::marker::PhantomData,
1356 }
1357 }
1358}
1359impl<T, Config> From<Config> for Spec<Config, T> {
1360 #[inline]
1361 fn from(config: Config) -> Self {
1362 Spec {
1363 config,
1364 __marker: core::marker::PhantomData,
1365 }
1366 }
1367}
1368impl<T, Config: Auto<T>> Default for Spec<Config, T> {
1369 #[inline]
1370 fn default() -> Self {
1371 Spec {
1372 config: Auto::<T>::auto(),
1373 __marker: core::marker::PhantomData,
1374 }
1375 }
1376}
1377mod into_range {
1378 use super::*;
1379 pub trait IntoRange<I> {
1380 type Len<N: Shape>: Shape;
1381 fn into_range(self, min: I, max: I) -> core::ops::Range<I>;
1382 }
1383 impl<I> IntoRange<I> for core::ops::Range<I> {
1384 type Len<N: Shape> = usize;
1385
1386 #[inline]
1387 fn into_range(self, _: I, _: I) -> core::ops::Range<I> {
1388 self
1389 }
1390 }
1391 impl<I> IntoRange<I> for core::ops::RangeFrom<I> {
1392 type Len<N: Shape> = usize;
1393
1394 #[inline]
1395 fn into_range(self, _: I, max: I) -> core::ops::Range<I> {
1396 self.start..max
1397 }
1398 }
1399 impl<I> IntoRange<I> for core::ops::RangeTo<I> {
1400 type Len<N: Shape> = usize;
1401
1402 #[inline]
1403 fn into_range(self, min: I, _: I) -> core::ops::Range<I> {
1404 min..self.end
1405 }
1406 }
1407 impl<I> IntoRange<I> for core::ops::RangeFull {
1408 type Len<N: Shape> = N;
1409
1410 #[inline]
1411 fn into_range(self, min: I, max: I) -> core::ops::Range<I> {
1412 min..max
1413 }
1414 }
1415}
1416mod sort;
1417pub extern crate dyn_stack;
1418pub extern crate faer_traits as traits;
1419#[doc(hidden)]
1420pub extern crate generativity;
1421pub extern crate num_complex as complex;
1422#[cfg(feature = "rand")]
1423#[cfg_attr(docs_rs, doc(cfg(feature = "rand")))]
1424pub extern crate rand;
1425pub extern crate reborrow;
1426
1427extern crate self as faer;
1428
1429#[macro_export]
1430#[doc(hidden)]
1431macro_rules! simd_iter {
1432 (for ($batch_id:tt, $i:pat $(,)?) in [$indices:expr; $batch_size:expr] $b:block $(,)?) => {#[allow(non_upper_case_globals, unconditional_panic)] 'out:{
1433 let (__head__, __body_batch__, __body_item__, __tail__) = &$indices;
1434 let __body_batch__ = __body_batch__.clone();
1435 let mut __body_item__ = __body_item__.clone();
1436 const {
1437 ::core::assert!($batch_size > 0);
1438 ::core::assert!($batch_size <= 8);
1439 }
1440 {
1441 if const { $batch_size == 1 } {if $batch_size == 1 { const $batch_id: usize = 0; if let &Some($i) = __head__ $b; }}
1442 if const { $batch_size == 2 } {if $batch_size == 2 { const $batch_id: usize = 1; if let &Some($i) = __head__ $b; }}
1443 if const { $batch_size == 3 } {if $batch_size == 3 { const $batch_id: usize = 2; if let &Some($i) = __head__ $b; }}
1444 if const { $batch_size == 4 } {if $batch_size == 4 { const $batch_id: usize = 3; if let &Some($i) = __head__ $b; }}
1445 if const { $batch_size == 5 } {if $batch_size == 5 { const $batch_id: usize = 4; if let &Some($i) = __head__ $b; }}
1446 if const { $batch_size == 6 } {if $batch_size == 6 { const $batch_id: usize = 5; if let &Some($i) = __head__ $b; }}
1447 if const { $batch_size == 7 } {if $batch_size == 7 { const $batch_id: usize = 6; if let &Some($i) = __head__ $b; }}
1448 if const { $batch_size == 8 } {if $batch_size == 8 { const $batch_id: usize = 7; if let &Some($i) = __head__ $b; }}
1449 }
1450 for __i__ in __body_batch__ {
1451 let __i__: [_; $batch_size] = __i__;
1452 let __i__ = __i__.as_slice();
1453 ::core::assert!(__i__.len() == $batch_size);
1454
1455 {
1456 if const { $batch_size > 0 } {if __i__.len() > 0 { const $batch_id: usize = 0; let $i = __i__[0]; $b }}
1457 if const { $batch_size > 1 } {if __i__.len() > 1 { const $batch_id: usize = 1; let $i = __i__[1]; $b }}
1458 if const { $batch_size > 2 } {if __i__.len() > 2 { const $batch_id: usize = 2; let $i = __i__[2]; $b }}
1459 if const { $batch_size > 3 } {if __i__.len() > 3 { const $batch_id: usize = 3; let $i = __i__[3]; $b }}
1460 if const { $batch_size > 4 } {if __i__.len() > 4 { const $batch_id: usize = 4; let $i = __i__[4]; $b }}
1461 if const { $batch_size > 5 } {if __i__.len() > 5 { const $batch_id: usize = 5; let $i = __i__[5]; $b }}
1462 if const { $batch_size > 6 } {if __i__.len() > 6 { const $batch_id: usize = 6; let $i = __i__[6]; $b }}
1463 if const { $batch_size > 7 } {if __i__.len() > 7 { const $batch_id: usize = 7; let $i = __i__[7]; $b }}
1464 }
1465 };
1466
1467 {
1468 if const { $batch_size > 0 } { if $batch_size > 0 { const $batch_id: usize = 0; if let Some($i) = __body_item__.next() $b else { if let &Some($i) = __tail__ $b; break 'out; } } }
1469 if const { $batch_size > 1 } { if $batch_size > 1 { const $batch_id: usize = 1; if let Some($i) = __body_item__.next() $b else { if let &Some($i) = __tail__ $b; break 'out; } } }
1470 if const { $batch_size > 2 } { if $batch_size > 2 { const $batch_id: usize = 2; if let Some($i) = __body_item__.next() $b else { if let &Some($i) = __tail__ $b; break 'out; } } }
1471 if const { $batch_size > 3 } { if $batch_size > 3 { const $batch_id: usize = 3; if let Some($i) = __body_item__.next() $b else { if let &Some($i) = __tail__ $b; break 'out; } } }
1472 if const { $batch_size > 4 } { if $batch_size > 4 { const $batch_id: usize = 4; if let Some($i) = __body_item__.next() $b else { if let &Some($i) = __tail__ $b; break 'out; } } }
1473 if const { $batch_size > 5 } { if $batch_size > 5 { const $batch_id: usize = 5; if let Some($i) = __body_item__.next() $b else { if let &Some($i) = __tail__ $b; break 'out; } } }
1474 if const { $batch_size > 6 } { if $batch_size > 6 { const $batch_id: usize = 6; if let Some($i) = __body_item__.next() $b else { if let &Some($i) = __tail__ $b; break 'out; } } }
1475 if const { $batch_size > 7 } { if $batch_size > 7 { const $batch_id: usize = 7; if let Some($i) = __body_item__.next() $b else { if let &Some($i) = __tail__ $b; break 'out; } } }
1476 }
1477 }};
1478 (for $i:pat in [$indices:expr] $b:block $(,)?) => {#[allow(non_upper_case_globals)]{
1479 let (__head__, __body__, __tail__) = &$indices;
1480 if let &Some($i) = __head__ $b;
1481 for $i in __body__.clone() $b;
1482 if let &Some($i) = __tail__ $b;
1483 }};
1484}