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