mod number_traits_impl;
mod rlst_num_impl;
use std::ops::Add;
pub use num::complex::Complex32 as c32;
pub use num::complex::Complex64 as c64;
use thiserror::Error;
use typenum::Cmp;
use typenum::Const;
use typenum::Less;
use typenum::NonZero;
use typenum::PInt;
use typenum::ToUInt;
use typenum::U;
use typenum::Unsigned;
use crate::Array;
use crate::ArrayFromContainerType;
use crate::ContainerTypeRepr;
use crate::ContainerTypeSelector;
use crate::DynArray;
use crate::IsSmallerThan;
use crate::RowMajorArrayFromContainerType;
use crate::StridedDynArray;
use crate::SubtractEqual;
use crate::dense::base_array::BaseArray;
use crate::dense::data_container::ArrayContainer;
use crate::dense::data_container::VectorContainer;
use crate::dense::layout::row_major_stride_from_shape;
use crate::dense::strided_base_array::StridedBaseArray;
use crate::traits::number_relations::{IsGreaterByOne, IsGreaterZero, IsSmallerByOne};
use typenum;
#[derive(Error, Debug)]
pub enum RlstError {
#[error("Method {0} is not implemented.")]
NotImplemented(String),
#[error("Operation {0} failed.")]
OperationFailed(String),
#[error("Matrix has empty dimension {0:#?}.")]
MatrixIsEmpty((usize, usize)),
#[error("Dimension mismatch. Expected {expected:}. Actual {actual:}")]
SingleDimensionError {
expected: usize,
actual: usize,
},
#[error("Index Layout error: {0}")]
IndexLayoutError(String),
#[error("MPI Rank does not exist. {0}")]
MpiRankError(i32),
#[error("Incompatible stride for Lapack.")]
IncompatibleStride,
#[error("Lapack error: {0}")]
LapackError(#[from] LapackError),
#[error("{0}")]
GeneralError(String),
#[error("I/O Error: {0}")]
IoError(String),
#[error("Matrix is not square. Dimension: {0}x{1}")]
MatrixNotSquare(usize, usize),
#[error("Matrix is not Hermitian (complex conjugate symmetric).")]
MatrixNotHermitian,
}
pub type RlstResult<T> = std::result::Result<T, RlstError>;
#[derive(Clone, Copy, PartialEq)]
pub enum TransMode {
NoTrans,
ConjNoTrans,
Trans,
ConjTrans,
}
pub trait Imply<T>: sealed::ImplyInner<T, Is = T> {}
impl<T, U> Imply<T> for U {}
mod sealed {
pub trait ImplyInner<T> {
type Is;
}
impl<T, U> ImplyInner<T> for U {
type Is = T;
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MemoryLayout {
ColumnMajor,
RowMajor,
Unknown,
}
#[derive(Error, Debug)]
pub enum LapackError {
#[error("LAPACK error code: {0}")]
LapackInfoCode(i32),
}
pub type LapackResult<T> = std::result::Result<T, LapackError>;
pub struct NumberType<const N: usize>;
pub struct NumberDifference<const M: usize, const N: usize>;
impl<const M: usize, const N: usize> IsGreaterByOne<N> for NumberType<M>
where
PInt<U<N>>: Add<typenum::P1, Output = PInt<U<M>>>,
Const<N>: ToUInt,
Const<M>: ToUInt,
<Const<N> as ToUInt>::Output: Unsigned + NonZero,
<Const<M> as ToUInt>::Output: Unsigned + NonZero,
{
}
impl<const D: usize, const M: usize, const N: usize> SubtractEqual<D> for NumberDifference<M, N>
where
Const<M>: ToUInt,
Const<N>: ToUInt,
Const<D>: ToUInt,
<Const<N> as ToUInt>::Output: Unsigned + NonZero,
<Const<M> as ToUInt>::Output: Unsigned + NonZero,
<Const<D> as ToUInt>::Output: Unsigned + NonZero,
NumberType<N>: IsSmallerThan<M>,
PInt<U<D>>: Add<PInt<U<N>>, Output = PInt<U<M>>>,
{
const OUTPUT: usize = D;
}
impl<const M: usize, const N: usize> IsSmallerByOne<N> for NumberType<M> where
NumberType<N>: IsGreaterByOne<M>
{
}
impl<const N: usize> IsGreaterZero for NumberType<N>
where
Const<N>: ToUInt,
<Const<N> as ToUInt>::Output: NonZero,
{
}
impl<const M: usize, const N: usize> IsSmallerThan<N> for NumberType<M>
where
Const<N>: ToUInt,
Const<M>: ToUInt,
<Const<N> as ToUInt>::Output: NonZero + Unsigned,
<Const<M> as ToUInt>::Output: NonZero + Unsigned,
PInt<U<M>>: Cmp<PInt<U<N>>, Output = Less>,
{
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UpLo {
Upper,
Lower,
}
pub struct Unknown;
pub struct Stack<const N: usize>;
impl ContainerTypeRepr for Unknown {
const STR: &str = "Unknown";
}
impl<const N: usize> ContainerTypeRepr for Stack<N> {
const STR: &str = "Stack";
}
impl ArrayFromContainerType for Unknown {
type OutputImpl<Item, const NDIM: usize>
= BaseArray<VectorContainer<Item>, NDIM>
where
Item: Copy + Default;
fn new_arr<Item, const NDIM: usize>(
shape: [usize; NDIM],
) -> Array<Self::OutputImpl<Item, NDIM>, NDIM>
where
Item: Copy + Default,
{
DynArray::from_shape(shape)
}
}
impl RowMajorArrayFromContainerType for Unknown {
type OutputImpl<Item, const NDIM: usize>
= StridedBaseArray<VectorContainer<Item>, NDIM>
where
Item: Copy + Default;
fn new_row_major_arr<Item, const NDIM: usize>(
shape: [usize; NDIM],
) -> Array<Self::OutputImpl<Item, NDIM>, NDIM>
where
Item: Copy + Default,
{
StridedDynArray::row_major(shape)
}
}
impl<const N: usize> ArrayFromContainerType for Stack<N> {
type OutputImpl<Item, const NDIM: usize>
= BaseArray<ArrayContainer<Item, N>, NDIM>
where
Item: Copy + Default;
fn new_arr<Item, const NDIM: usize>(
shape: [usize; NDIM],
) -> Array<Self::OutputImpl<Item, NDIM>, NDIM>
where
Item: Copy + Default,
{
Array::new(BaseArray::new(ArrayContainer::<Item, N>::new(), shape))
}
}
impl<const N: usize> RowMajorArrayFromContainerType for Stack<N> {
type OutputImpl<Item, const NDIM: usize>
= StridedBaseArray<ArrayContainer<Item, N>, NDIM>
where
Item: Copy + Default;
fn new_row_major_arr<Item, const NDIM: usize>(
shape: [usize; NDIM],
) -> Array<Self::OutputImpl<Item, NDIM>, NDIM>
where
Item: Copy + Default,
{
Array::new(StridedBaseArray::new(
ArrayContainer::<Item, N>::new(),
shape,
row_major_stride_from_shape(shape),
))
}
}
pub struct SelectContainerType;
impl ContainerTypeSelector<Unknown, Unknown> for SelectContainerType {
type Type = Unknown;
}
impl<const N: usize> ContainerTypeSelector<Stack<N>, Unknown> for SelectContainerType {
type Type = Stack<N>;
}
impl<const N: usize> ContainerTypeSelector<Unknown, Stack<N>> for SelectContainerType {
type Type = Stack<N>;
}
impl<const N: usize> ContainerTypeSelector<Stack<N>, Stack<N>> for SelectContainerType {
type Type = Stack<N>;
}