use crate::util::*;
use blas_sys::{c_double_complex, c_float_complex};
use libc::{c_double, c_float};
use ndarray::Dimension;
use num_complex::*;
use num_traits::*;
#[allow(non_camel_case_types)]
pub type c32 = Complex<f32>;
#[allow(non_camel_case_types)]
pub type c64 = Complex<f64>;
pub trait BLASFloat:
Num + NumAssignOps + Send + Sync + Copy + Clone + Default + std::fmt::Debug + std::fmt::Display
{
type RealFloat: BLASFloat;
type FFIFloat;
const EPSILON: Self::RealFloat;
fn is_complex() -> bool;
fn conj(x: Self) -> Self;
fn abs(x: Self) -> Self::RealFloat;
}
impl BLASFloat for f32 {
type RealFloat = f32;
type FFIFloat = c_float;
const EPSILON: Self::RealFloat = f32::EPSILON;
#[inline]
fn is_complex() -> bool {
false
}
#[inline]
fn conj(x: Self) -> Self {
x
}
#[inline]
fn abs(x: Self) -> Self::RealFloat {
x.abs()
}
}
impl BLASFloat for f64 {
type RealFloat = f64;
type FFIFloat = c_double;
const EPSILON: Self::RealFloat = f64::EPSILON;
#[inline]
fn is_complex() -> bool {
false
}
#[inline]
fn conj(x: Self) -> Self {
x
}
#[inline]
fn abs(x: Self) -> Self::RealFloat {
x.abs()
}
}
impl BLASFloat for c32 {
type RealFloat = f32;
type FFIFloat = c_float_complex;
const EPSILON: Self::RealFloat = f32::EPSILON;
#[inline]
fn is_complex() -> bool {
true
}
#[inline]
fn conj(x: Self) -> Self {
x.conj()
}
#[inline]
fn abs(x: Self) -> Self::RealFloat {
x.abs()
}
}
impl BLASFloat for c64 {
type RealFloat = f64;
type FFIFloat = c_double_complex;
const EPSILON: Self::RealFloat = f64::EPSILON;
#[inline]
fn is_complex() -> bool {
true
}
#[inline]
fn conj(x: Self) -> Self {
x.conj()
}
#[inline]
fn abs(x: Self) -> Self::RealFloat {
x.abs()
}
}
pub trait BLASSymmetric {
type Float: BLASFloat;
type HermitianFloat: BLASFloat;
fn is_hermitian() -> bool;
}
pub struct BLASSymm<F>
where
F: BLASFloat,
{
_phantom: std::marker::PhantomData<F>,
}
impl<F> BLASSymmetric for BLASSymm<F>
where
F: BLASFloat,
{
type Float = F;
type HermitianFloat = F;
#[inline]
fn is_hermitian() -> bool {
false
}
}
pub struct BLASHermi<F>
where
F: BLASFloat,
{
_phantom: std::marker::PhantomData<F>,
}
impl<F> BLASSymmetric for BLASHermi<F>
where
F: BLASFloat,
{
type Float = F;
type HermitianFloat = <F as BLASFloat>::RealFloat;
#[inline]
fn is_hermitian() -> bool {
true
}
}
pub struct BLASFunc {}
pub trait BLASDriver<'c, F, D>
where
D: Dimension,
{
fn run_blas(self) -> Result<ArrayOut<'c, F, D>, AnyError>;
}
pub trait BLASBuilder_<'c, F, D>
where
D: Dimension,
{
fn driver(self) -> Result<impl BLASDriver<'c, F, D>, AnyError>;
}
pub trait BLASBuilder<'c, F, D>
where
D: Dimension,
{
fn run(self) -> Result<ArrayOut<'c, F, D>, AnyError>;
}