Skip to content

Commit a47f478

Browse files
committed
replace LANGE_* with MAT_*, add max(svdvals(a)) option
1 parent 753e31b commit a47f478

File tree

1 file changed

+41
-32
lines changed

1 file changed

+41
-32
lines changed

src/stdlib_linalg_norms.fypp

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)