lax 0.18.0

LAPACK wrapper without ndarray
Documentation
//! Operator norm

use super::{AsPtr, NormType};
use crate::{layout::MatrixLayout, *};
use cauchy::*;

pub struct OperatorNormWork<T: Scalar> {
    pub ty: NormType,
    pub layout: MatrixLayout,
    pub work: Vec<MaybeUninit<T::Real>>,
}

pub trait OperatorNormWorkImpl {
    type Elem: Scalar;
    fn new(t: NormType, l: MatrixLayout) -> Self;
    fn calc(&mut self, a: &[Self::Elem]) -> <Self::Elem as Scalar>::Real;
}

macro_rules! impl_operator_norm {
    ($s:ty, $lange:path) => {
        impl OperatorNormWorkImpl for OperatorNormWork<$s> {
            type Elem = $s;

            fn new(ty: NormType, layout: MatrixLayout) -> Self {
                let m = layout.lda();
                let work = match (ty, layout) {
                    (NormType::Infinity, MatrixLayout::F { .. })
                    | (NormType::One, MatrixLayout::C { .. }) => vec_uninit(m as usize),
                    _ => Vec::new(),
                };
                OperatorNormWork { ty, layout, work }
            }

            fn calc(&mut self, a: &[Self::Elem]) -> <Self::Elem as Scalar>::Real {
                let m = self.layout.lda();
                let n = self.layout.len();
                let t = match self.layout {
                    MatrixLayout::F { .. } => self.ty,
                    MatrixLayout::C { .. } => self.ty.transpose(),
                };
                unsafe {
                    $lange(
                        t.as_ptr(),
                        &m,
                        &n,
                        AsPtr::as_ptr(a),
                        &m,
                        AsPtr::as_mut_ptr(&mut self.work),
                    )
                }
            }
        }
    };
}
impl_operator_norm!(c64, lapack_sys::zlange_);
impl_operator_norm!(c32, lapack_sys::clange_);
impl_operator_norm!(f64, lapack_sys::dlange_);
impl_operator_norm!(f32, lapack_sys::slange_);