@@ -264,7 +264,7 @@ submodule(stdlib_linalg) stdlib_linalg_norms
264264 ! Internal implementation
265265 pure module subroutine norm_${rank}$D_to_${rank-1}$D_${ii}$_${ri}$(a, nrm, order, dim, err)
266266 !> Input matrix a[..]
267- ${rt}$, intent(in), target :: a${ranksuffix(rank)}$
267+ ${rt}$, intent(in) :: a${ranksuffix(rank)}$
268268 !> Dimension to collapse by computing the norm w.r.t other dimensions
269269 ! (dim must be defined before it is used for `nrm`)
270270 integer(ilp), intent(in) :: dim
@@ -276,11 +276,17 @@ submodule(stdlib_linalg) stdlib_linalg_norms
276276 type(linalg_state_type), intent(out), optional :: err
277277
278278 type(linalg_state_type) :: err_
279- integer(ilp) :: sze,norm_request
279+ integer(ilp) :: sze,lda,norm_request,${loop_variables('j',rank-1,1)}$
280+ logical :: contiguous_data
280281 real(${rk}$) :: rorder
282+ integer(ilp), dimension(${rank}$) :: spe,spack,perm,iperm
283+ integer(ilp), dimension(${rank}$), parameter :: dim_range = [(lda,lda=1_ilp,${rank}$_ilp)]
284+ ${rt}$, allocatable :: apack${ranksuffix(rank)}$
281285 intrinsic :: abs, sum, sqrt, norm2, maxval, minval, conjg
282286
283- sze = size(a,kind=ilp)
287+ ! Input matrix properties
288+ sze = size (a,kind=ilp)
289+ spe = shape(a,kind=ilp)
284290
285291 ! Initialize norm to zero
286292 nrm = 0.0_${rk}$
@@ -304,28 +310,60 @@ submodule(stdlib_linalg) stdlib_linalg_norms
304310 if (err_%error()) then
305311 call linalg_error_handling(err_,err)
306312 return
307- endif
313+ endif
308314
309- select case(norm_request)
310- case(NORM_ONE)
311- nrm = sum( abs(a) , dim = dim )
312- case(NORM_TWO)
313- #:if rt.startswith('complex')
314- nrm = sqrt( real( sum( a * conjg(a) , dim = dim ), ${rk}$) )
315- #:else
316- nrm = norm2( a , dim = dim )
317- #:endif
318- case(NORM_INF)
319- nrm = maxval( abs(a) , dim = dim )
320- case(NORM_MINUSINF)
321- nrm = minval( abs(a) , dim = dim )
322- case (NORM_POW_FIRST:NORM_POW_LAST)
323- rorder = 1.0_${rk}$ / norm_request
324- nrm = sum( abs(a) ** norm_request , dim = dim ) ** rorder
325- case default
326- err_ = linalg_state_type(this,LINALG_INTERNAL_ERROR,'invalid norm type after checking')
327- call linalg_error_handling(err_,err)
328- end select
315+ ! The norm's leading dimension
316+ lda = spe(dim)
317+
318+ ! Check if input column data is contiguous
319+ contiguous_data = dim==1 .or. all(norm_request/=[NORM_ONE,NORM_TWO])
320+
321+ ! Get packed data with the norm dimension as the first dimension
322+ if (.not.contiguous_data) then
323+
324+ ! Permute array to map dim to 1
325+ perm = [dim,pack(dim_range,dim_range/=dim)]
326+ iperm(perm) = dim_range
327+ spack = spe(perm)
328+ apack = reshape(a, shape=spack, order=iperm)
329+
330+ ${loop_variables_start('j', 'apack', rank-1, 1," "*12)}$
331+ select case(norm_request)
332+ case(NORM_ONE)
333+ nrm(${loop_variables('j',rank-1,1)}$) = &
334+ asum(lda,apack(:, ${loop_variables('j',rank-1,1)}$),incx=1_ilp)
335+ case(NORM_TWO)
336+ nrm(${loop_variables('j',rank-1,1)}$) = &
337+ nrm2(lda,apack(:, ${loop_variables('j',rank-1,1)}$),incx=1_ilp)
338+ end select
339+ ${loop_variables_end(rank-1," "*12)}$
340+
341+ else
342+
343+ select case(norm_request)
344+ case(NORM_ONE)
345+ ${loop_variables_start('j', 'a', rank-1, 1," "*20)}$
346+ nrm(${loop_variables('j',rank-1,1)}$) = &
347+ asum(lda,a(:, ${loop_variables('j',rank-1,1)}$),incx=1_ilp)
348+ ${loop_variables_end(rank-1," "*20)}$
349+ case(NORM_TWO)
350+ ${loop_variables_start('j', 'a', rank-1, 1," "*20)}$
351+ nrm(${loop_variables('j',rank-1,1)}$) = &
352+ nrm2(lda,a(:, ${loop_variables('j',rank-1,1)}$),incx=1_ilp)
353+ ${loop_variables_end(rank-1," "*20)}$
354+ case(NORM_INF)
355+ nrm = maxval( abs(a) , dim = dim )
356+ case(NORM_MINUSINF)
357+ nrm = minval( abs(a) , dim = dim )
358+ case (NORM_POW_FIRST:NORM_POW_LAST)
359+ rorder = 1.0_${rk}$ / norm_request
360+ nrm = sum( abs(a) ** norm_request , dim = dim ) ** rorder
361+ case default
362+ err_ = linalg_state_type(this,LINALG_INTERNAL_ERROR,'invalid norm type after checking')
363+ call linalg_error_handling(err_,err)
364+ end select
365+
366+ endif
329367
330368 end subroutine norm_${rank}$D_to_${rank-1}$D_${ii}$_${ri}$
331369
0 commit comments