lax/
opnorm.rs

1//! Operator norm
2
3use 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_);