@@ -26,20 +26,22 @@ submodule(stdlib_linalg) stdlib_linalg_norms
2626 integer(ilp), parameter :: NORM_MINUSINF = -huge(0_ilp)
2727
2828 !> Wrappers to LAPACK *LANGE matrix norm flags
29- character, parameter :: LANGE_NORM_MAT = 'M' ! maxval(sum(abs(a))) ! over whole matrix: unused
30- character, parameter :: LANGE_NORM_ONE = '1' ! maxval(sum(abs(a),1)) ! over columns
31- character, parameter :: LANGE_NORM_INF = 'I' ! maxval(sum(abs(a),2)) ! over rows
32- character, parameter :: LANGE_NORM_FRO = 'E' ! sqrt(sum(a**2)) ! "Euclidean" or "Frobenius"
29+ character, parameter :: MAT_NORM_MAT = 'M' ! maxval(sum(abs(a))) ! over whole matrix: unused
30+ character, parameter :: MAT_NORM_ONE = '1' ! maxval(sum(abs(a),1)) ! over columns
31+ character, parameter :: MAT_NORM_INF = 'I' ! maxval(sum(abs(a),2)) ! over rows
32+ character, parameter :: MAT_NORM_FRO = 'E' ! sqrt(sum(a**2)) ! "Euclidean" or "Frobenius"
33+ !> Other wrappers to matrix norms
34+ character, parameter :: MAT_NORM_SVD = '2' ! maxval(svdvals(a)) ! Maximum singular value
3335
3436 interface parse_norm_type
3537 module procedure parse_norm_type_integer
3638 module procedure parse_norm_type_character
3739 end interface parse_norm_type
3840
39- interface lange_task_request
40- module procedure lange_task_request_integer
41- module procedure lange_task_request_character
42- end interface lange_task_request
41+ interface mat_task_request
42+ module procedure mat_task_request_integer
43+ module procedure mat_task_request_character
44+ end interface mat_task_request
4345
4446
4547 interface stride_1d
@@ -112,61 +114,68 @@ submodule(stdlib_linalg) stdlib_linalg_norms
112114 end subroutine parse_norm_type_character
113115
114116 !> From a user norm request, generate a *LANGE task command
115- pure subroutine lange_task_request_integer (order,lange_task ,err)
117+ pure subroutine mat_task_request_integer (order,mat_task ,err)
116118 !> Parsed matrix norm type
117119 integer(ilp), optional, intent(in) :: order
118120 !> LANGE task
119- character, intent(out) :: lange_task
121+ character, intent(out) :: mat_task
120122 !> Error flag
121123 type(linalg_state_type), intent(inout) :: err
122124
123125 if (present(order)) then
124126
125127 select case (order)
126128 case (NORM_INF)
127- lange_task = LANGE_NORM_INF
129+ mat_task = MAT_NORM_INF
130+ case (NORM_TWO)
131+ mat_task = MAT_NORM_SVD
128132 case (NORM_ONE)
129- lange_task = LANGE_NORM_ONE
133+ mat_task = MAT_NORM_ONE
130134 case default
131135 err = linalg_state_type(this,LINALG_VALUE_ERROR,'Integer order ',order,' is not a valid matrix norm input.')
132136 end select
133137
134138 else
135139
136140 ! No user input: Frobenius norm
137- lange_task = LANGE_NORM_FRO
141+ mat_task = MAT_NORM_FRO
138142
139143 endif
140- end subroutine lange_task_request_integer
144+ end subroutine mat_task_request_integer
141145
142- pure subroutine lange_task_request_character (order,lange_task ,err)
146+ pure subroutine mat_task_request_character (order,mat_task ,err)
143147 !> User input value
144148 character(len=*), intent(in) :: order
145149 !> Return value: norm type
146- character, intent(out) :: lange_task
150+ character, intent(out) :: mat_task
147151 !> State return flag
148152 type(linalg_state_type), intent(out) :: err
149153
150154 integer(ilp) :: int_order,read_err
151155
152156 select case (order)
153157 case ('inf','Inf','INF')
154- lange_task = LANGE_NORM_INF
158+ mat_task = MAT_NORM_INF
155159 case ('Euclidean','euclidean','EUCLIDEAN','Frobenius','frobenius','FROBENIUS','Fro','fro','frob')
156- lange_task = LANGE_NORM_FRO
160+ mat_task = MAT_NORM_FRO
157161 case default
158162
159163 ! Check if this input can be read as an integer
160164 read(order,*,iostat=read_err) int_order
161- if (read_err/=0 .or. int_order/=1 ) then
165+ if (read_err/=0 .or. all( int_order/=[1,2] ) then
162166 ! Cannot read as an integer
163167 err = linalg_state_type(this,LINALG_ERROR,'Matrix norm input',order,' is not recognized.')
164168 endif
165- lange_task = LANGE_NORM_ONE
166-
169+
170+ select case (int_order)
171+ case (1); mat_task = MAT_NORM_ONE
172+ case (2); mat_task = MAT_NORM_SVD
173+ case default; mat_task = MAT_NORM_ONE
174+ end select
175+
167176 end select
168177
169- end subroutine lange_task_request_character
178+ end subroutine mat_task_request_character
170179
171180 #:for rk,rt,ri in ALL_KINDS_TYPES
172181
@@ -446,7 +455,7 @@ ${loop_variables_end(rank-1," "*12)}$
446455
447456 type(linalg_state_type) :: err_
448457 integer(ilp) :: m,n
449- character :: lange_task
458+ character :: mat_task
450459 real(${rk}$), target :: work1(1)
451460 real(${rk}$), pointer :: work(:)
452461
@@ -463,22 +472,22 @@ ${loop_variables_end(rank-1," "*12)}$
463472 end if
464473
465474 ! Check norm request: user + *LANGE support
466- call lange_task_request (order,lange_task ,err_)
475+ call mat_task_request (order,mat_task ,err_)
467476 if (err_%error()) then
468477 call linalg_error_handling(err_,err)
469478 return
470479 endif
471480
472- if (lange_task==LANGE_NORM_INF ) then
481+ if (mat_task==MAT_NORM_INF ) then
473482 allocate(work(m))
474483 else
475484 work => work1
476485 endif
477486
478487 ! LAPACK interface
479- nrm = lange(lange_task ,m,n,a,m,work)
488+ nrm = lange(mat_task ,m,n,a,m,work)
480489
481- if (lange_task==LANGE_NORM_INF ) deallocate(work)
490+ if (mat_task==MAT_NORM_INF ) deallocate(work)
482491
483492 end function matrix_norm_${ii}$_${ri}$
484493
@@ -503,7 +512,7 @@ ${loop_variables_end(rank-1," "*12)}$
503512 integer(ilp), dimension(${rank}$), parameter :: dim_range = [(m,m=1_ilp,${rank}$_ilp)]
504513 integer(ilp) :: ${loop_variables('j',rank-2,2)}$
505514 logical :: contiguous_data
506- character :: lange_task
515+ character :: mat_task
507516 real(${rk}$), target :: work1(1)
508517 real(${rk}$), pointer :: work(:)
509518 ${rt}$, pointer :: apack${ranksuffix(rank)}$
@@ -525,7 +534,7 @@ ${loop_variables_end(rank-1," "*12)}$
525534 endif
526535
527536 ! Check norm request: user + *LANGE support
528- call lange_task_request (order,lange_task ,err_)
537+ call mat_task_request (order,mat_task ,err_)
529538 if (err_%error()) then
530539 allocate(nrm${emptyranksuffix(rank-2)}$)
531540 call linalg_error_handling(err_,err)
@@ -559,7 +568,7 @@ ${loop_variables_end(rank-1," "*12)}$
559568
560569 endif
561570
562- if (lange_task==LANGE_NORM_INF ) then
571+ if (mat_task==MAT_NORM_INF ) then
563572 allocate(work(m))
564573 else
565574 work => work1
@@ -573,10 +582,10 @@ ${loop_variables_end(rank-1," "*12)}$
573582 ! LAPACK interface
574583${loop_variables_start('j', 'apack', rank-2, 2)}$
575584 nrm(${loop_variables('j',rank-2,2)}$) = &
576- lange(lange_task ,m,n,apack(:,:,${loop_variables('j',rank-2,2)}$),lda,work)
585+ lange(mat_task ,m,n,apack(:,:,${loop_variables('j',rank-2,2)}$),lda,work)
577586${loop_variables_end(rank-2)}$
578587
579- if (lange_task==LANGE_NORM_INF ) deallocate(work)
588+ if (mat_task==MAT_NORM_INF ) deallocate(work)
580589 if (.not.contiguous_data) deallocate(apack)
581590
582591 end function matrix_norm_${rank}$D_to_${rank-2}$D_${ii}$_${ri}$
0 commit comments