1 // SPDX-License-Identifier: Apache-2.0
2 //
3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
4 // Copyright 2008-2016 National ICT Australia (NICTA)
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // ------------------------------------------------------------------------
17 
18 
19 //! \addtogroup op_norm
20 //! @{
21 
22 
23 
24 template<typename eT>
25 inline
26 typename get_pod_type<eT>::result
mat_norm_1(const SpMat<eT> & X)27 spop_norm::mat_norm_1(const SpMat<eT>& X)
28   {
29   arma_extra_debug_sigprint();
30 
31   // TODO: this can be sped up with a dedicated implementation
32   return as_scalar( max( sum(abs(X), 0), 1) );
33   }
34 
35 
36 
37 template<typename eT>
38 inline
39 typename get_pod_type<eT>::result
mat_norm_2(const SpMat<eT> & X,const typename arma_real_only<eT>::result * junk)40 spop_norm::mat_norm_2(const SpMat<eT>& X, const typename arma_real_only<eT>::result* junk)
41   {
42   arma_extra_debug_sigprint();
43   arma_ignore(junk);
44 
45   // norm = sqrt( largest eigenvalue of (A^H)*A ), where ^H is the conjugate transpose
46   // http://math.stackexchange.com/questions/4368/computing-the-largest-eigenvalue-of-a-very-large-sparse-matrix
47 
48   typedef typename get_pod_type<eT>::result T;
49 
50   const SpMat<eT>& A = X;
51   const SpMat<eT>  B = trans(A);
52 
53   const SpMat<eT>  C = (A.n_rows <= A.n_cols) ? (A*B) : (B*A);
54 
55   Col<T> eigval;
56   eigs_sym(eigval, C, 1);
57 
58   return (eigval.n_elem > 0) ? T(std::sqrt(eigval[0])) : T(0);
59   }
60 
61 
62 
63 template<typename eT>
64 inline
65 typename get_pod_type<eT>::result
mat_norm_2(const SpMat<eT> & X,const typename arma_cx_only<eT>::result * junk)66 spop_norm::mat_norm_2(const SpMat<eT>& X, const typename arma_cx_only<eT>::result* junk)
67   {
68   arma_extra_debug_sigprint();
69   arma_ignore(junk);
70 
71   typedef typename get_pod_type<eT>::result T;
72 
73   // we're calling eigs_gen(), which currently requires ARPACK
74   #if !defined(ARMA_USE_ARPACK)
75     {
76     arma_stop_logic_error("norm(): use of ARPACK must be enabled for norm of complex matrices");
77     return T(0);
78     }
79   #endif
80 
81   const SpMat<eT>& A = X;
82   const SpMat<eT>  B = trans(A);
83 
84   const SpMat<eT>  C = (A.n_rows <= A.n_cols) ? (A*B) : (B*A);
85 
86   Col<eT> eigval;
87   eigs_gen(eigval, C, 1);
88 
89   return (eigval.n_elem > 0) ? T(std::sqrt(std::real(eigval[0]))) : T(0);
90   }
91 
92 
93 
94 template<typename eT>
95 inline
96 typename get_pod_type<eT>::result
mat_norm_inf(const SpMat<eT> & X)97 spop_norm::mat_norm_inf(const SpMat<eT>& X)
98   {
99   arma_extra_debug_sigprint();
100 
101   // TODO: this can be sped up with a dedicated implementation
102   return as_scalar( max( sum(abs(X), 1), 0) );
103   }
104 
105 
106 
107 //! @}
108