8
8
! Vector norms
9
9
submodule(stdlib_linalg) stdlib_linalg_norms
10
10
use stdlib_linalg_constants
11
- use stdlib_linalg_blas, only: nrm2,asum
12
- use stdlib_linalg_lapack, only: lange
11
+ use stdlib_linalg_blas
12
+ use stdlib_linalg_lapack
13
13
use stdlib_linalg_state, only: linalg_state_type, linalg_error_handling, LINALG_ERROR, &
14
14
LINALG_INTERNAL_ERROR, LINALG_VALUE_ERROR
15
15
use iso_c_binding, only: c_intptr_t,c_char,c_loc
@@ -119,6 +119,47 @@ submodule(stdlib_linalg) stdlib_linalg_norms
119
119
120
120
end function stride_1d_${ri}$
121
121
122
+ ! Private internal implementation: 1D
123
+ pure subroutine internal_norm_1D_${ri}$(sze, a, nrm, norm_request, err)
124
+ !> Input matrix length
125
+ integer(ilp), intent(in) :: sze
126
+ !> Input contiguous 1-d matrix a(*)
127
+ ${rt}$, intent(in) :: a(sze)
128
+ !> Norm of the matrix.
129
+ real(${rk}$), intent(out) :: nrm
130
+ !> Internal matrix request
131
+ integer(ilp), intent(in) :: norm_request
132
+ !> State return flag. On error if not requested, the code will stop
133
+ type(linalg_state_type), intent(inout) :: err
134
+
135
+ integer(ilp) :: i
136
+ real(${rk}$) :: rorder
137
+ intrinsic :: abs, sum, sqrt, maxval, minval, conjg
138
+
139
+ ! Initialize norm to zero
140
+ nrm = 0.0_${rk}$
141
+
142
+ select case(norm_request)
143
+ case(NORM_ONE)
144
+ nrm = asum(sze,a,incx=1_ilp)
145
+ case(NORM_TWO)
146
+ nrm = nrm2(sze,a,incx=1_ilp)
147
+ case(NORM_INF)
148
+ #:if rt.startswith('complex')
149
+ ! The default BLAS stdlib_i${ri}$amax uses |Re(.)|+|Im(.)|. Do not use it.
150
+ i = stdlib_i${ri}$max1(sze,a,incx=1_ilp)
151
+ #:else
152
+ i = stdlib_i${ri}$amax(sze,a,incx=1_ilp)
153
+ #:endif
154
+ nrm = abs(a(i))
155
+ case(NORM_MINUSINF)
156
+ nrm = minval( abs(a) )
157
+ case (NORM_POW_FIRST:NORM_POW_LAST)
158
+ rorder = 1.0_${rk}$ / norm_request
159
+ nrm = sum( abs(a) ** norm_request ) ** rorder
160
+ end select
161
+
162
+ end subroutine internal_norm_1D_${ri}$
122
163
123
164
#:for it,ii in INPUT_OPTIONS
124
165
@@ -155,8 +196,8 @@ submodule(stdlib_linalg) stdlib_linalg_norms
155
196
call norm_${rank}$D_${ii}$_${ri}$(a, nrm=nrm, order=order, err=err)
156
197
157
198
end function stdlib_linalg_norm_${rank}$D_order_err_${ii}$_${ri}$
158
-
159
- ! Internal implementation
199
+
200
+ ! Internal implementation: ${rank}$-d
160
201
pure module subroutine norm_${rank}$D_${ii}$_${ri}$(a, nrm, order, err)
161
202
!> Input ${rank}$-d matrix a${ranksuffix(rank)}$
162
203
${rt}$, intent(in), target :: a${ranksuffix(rank)}$
@@ -168,7 +209,6 @@ submodule(stdlib_linalg) stdlib_linalg_norms
168
209
type(linalg_state_type), intent(out), optional :: err
169
210
170
211
type(linalg_state_type) :: err_
171
-
172
212
integer(ilp) :: sze,norm_request
173
213
real(${rk}$) :: rorder
174
214
intrinsic :: abs, sum, sqrt, maxval, minval, conjg
@@ -190,34 +230,11 @@ submodule(stdlib_linalg) stdlib_linalg_norms
190
230
if (err_%error()) then
191
231
call linalg_error_handling(err_,err)
192
232
return
193
- endif
233
+ endif
194
234
195
- select case(norm_request)
196
- case(NORM_ONE)
197
- #:if rank==1
198
- nrm = asum(sze,a,incx=1_ilp)
199
- #:else
200
- nrm = sum( abs(a) )
201
- #:endif
202
- case(NORM_TWO)
203
- #:if rank==1
204
- nrm = nrm2(sze,a,incx=1_ilp)
205
- #:elif rt.startswith('complex')
206
- nrm = sqrt( real( sum( a * conjg(a) ), ${rk}$) )
207
- #:else
208
- nrm = norm2(a)
209
- #:endif
210
- case(NORM_INF)
211
- nrm = maxval( abs(a) )
212
- case(NORM_MINUSINF)
213
- nrm = minval( abs(a) )
214
- case (NORM_POW_FIRST:NORM_POW_LAST)
215
- rorder = 1.0_${rk}$ / norm_request
216
- nrm = sum( abs(a) ** norm_request ) ** rorder
217
- case default
218
- err_ = linalg_state_type(this,LINALG_INTERNAL_ERROR,'invalid norm type after checking')
219
- call linalg_error_handling(err_,err)
220
- end select
235
+ ! Get norm
236
+ call internal_norm_1D_${ri}$(sze, a, nrm, norm_request, err_)
237
+ call linalg_error_handling(err_,err)
221
238
222
239
end subroutine norm_${rank}$D_${ii}$_${ri}$
223
240
0 commit comments