1use super::{AsPtr, NormType};
4use crate::{layout::MatrixLayout, *};
5use cauchy::*;
6
7pub struct OperatorNormWork<T: Scalar> {
8 pub ty: NormType,
9 pub layout: MatrixLayout,
10 pub work: Vec<MaybeUninit<T::Real>>,
11}
12
13pub trait OperatorNormWorkImpl {
14 type Elem: Scalar;
15 fn new(t: NormType, l: MatrixLayout) -> Self;
16 fn calc(&mut self, a: &[Self::Elem]) -> <Self::Elem as Scalar>::Real;
17}
18
19macro_rules! impl_operator_norm {
20 ($s:ty, $lange:path) => {
21 impl OperatorNormWorkImpl for OperatorNormWork<$s> {
22 type Elem = $s;
23
24 fn new(ty: NormType, layout: MatrixLayout) -> Self {
25 let m = layout.lda();
26 let work = match (ty, layout) {
27 (NormType::Infinity, MatrixLayout::F { .. })
28 | (NormType::One, MatrixLayout::C { .. }) => vec_uninit(m as usize),
29 _ => Vec::new(),
30 };
31 OperatorNormWork { ty, layout, work }
32 }
33
34 fn calc(&mut self, a: &[Self::Elem]) -> <Self::Elem as Scalar>::Real {
35 let m = self.layout.lda();
36 let n = self.layout.len();
37 let t = match self.layout {
38 MatrixLayout::F { .. } => self.ty,
39 MatrixLayout::C { .. } => self.ty.transpose(),
40 };
41 unsafe {
42 $lange(
43 t.as_ptr(),
44 &m,
45 &n,
46 AsPtr::as_ptr(a),
47 &m,
48 AsPtr::as_mut_ptr(&mut self.work),
49 )
50 }
51 }
52 }
53 };
54}
55impl_operator_norm!(c64, lapack_sys::zlange_);
56impl_operator_norm!(c32, lapack_sys::clange_);
57impl_operator_norm!(f64, lapack_sys::dlange_);
58impl_operator_norm!(f32, lapack_sys::slange_);