88! Vector norms
99submodule(stdlib_linalg) stdlib_linalg_norms
1010 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
1313 use stdlib_linalg_state, only: linalg_state_type, linalg_error_handling, LINALG_ERROR, &
1414 LINALG_INTERNAL_ERROR, LINALG_VALUE_ERROR
1515 use iso_c_binding, only: c_intptr_t,c_char,c_loc
@@ -119,6 +119,47 @@ submodule(stdlib_linalg) stdlib_linalg_norms
119119
120120 end function stride_1d_${ri}$
121121
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}$
122163
123164 #:for it,ii in INPUT_OPTIONS
124165
@@ -155,8 +196,8 @@ submodule(stdlib_linalg) stdlib_linalg_norms
155196 call norm_${rank}$D_${ii}$_${ri}$(a, nrm=nrm, order=order, err=err)
156197
157198 end function stdlib_linalg_norm_${rank}$D_order_err_${ii}$_${ri}$
158-
159- ! Internal implementation
199+
200+ ! Internal implementation: ${rank}$-d
160201 pure module subroutine norm_${rank}$D_${ii}$_${ri}$(a, nrm, order, err)
161202 !> Input ${rank}$-d matrix a${ranksuffix(rank)}$
162203 ${rt}$, intent(in), target :: a${ranksuffix(rank)}$
@@ -168,7 +209,6 @@ submodule(stdlib_linalg) stdlib_linalg_norms
168209 type(linalg_state_type), intent(out), optional :: err
169210
170211 type(linalg_state_type) :: err_
171-
172212 integer(ilp) :: sze,norm_request
173213 real(${rk}$) :: rorder
174214 intrinsic :: abs, sum, sqrt, maxval, minval, conjg
@@ -190,34 +230,11 @@ submodule(stdlib_linalg) stdlib_linalg_norms
190230 if (err_%error()) then
191231 call linalg_error_handling(err_,err)
192232 return
193- endif
233+ endif
194234
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)
221238
222239 end subroutine norm_${rank}$D_${ii}$_${ri}$
223240
0 commit comments