@@ -26,20 +26,22 @@ submodule(stdlib_linalg) stdlib_linalg_norms
26
26
integer(ilp), parameter :: NORM_MINUSINF = -huge(0_ilp)
27
27
28
28
!> 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
33
35
34
36
interface parse_norm_type
35
37
module procedure parse_norm_type_integer
36
38
module procedure parse_norm_type_character
37
39
end interface parse_norm_type
38
40
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
43
45
44
46
45
47
interface stride_1d
@@ -112,61 +114,68 @@ submodule(stdlib_linalg) stdlib_linalg_norms
112
114
end subroutine parse_norm_type_character
113
115
114
116
!> 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)
116
118
!> Parsed matrix norm type
117
119
integer(ilp), optional, intent(in) :: order
118
120
!> LANGE task
119
- character, intent(out) :: lange_task
121
+ character, intent(out) :: mat_task
120
122
!> Error flag
121
123
type(linalg_state_type), intent(inout) :: err
122
124
123
125
if (present(order)) then
124
126
125
127
select case (order)
126
128
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
128
132
case (NORM_ONE)
129
- lange_task = LANGE_NORM_ONE
133
+ mat_task = MAT_NORM_ONE
130
134
case default
131
135
err = linalg_state_type(this,LINALG_VALUE_ERROR,'Integer order ',order,' is not a valid matrix norm input.')
132
136
end select
133
137
134
138
else
135
139
136
140
! No user input: Frobenius norm
137
- lange_task = LANGE_NORM_FRO
141
+ mat_task = MAT_NORM_FRO
138
142
139
143
endif
140
- end subroutine lange_task_request_integer
144
+ end subroutine mat_task_request_integer
141
145
142
- pure subroutine lange_task_request_character (order,lange_task ,err)
146
+ pure subroutine mat_task_request_character (order,mat_task ,err)
143
147
!> User input value
144
148
character(len=*), intent(in) :: order
145
149
!> Return value: norm type
146
- character, intent(out) :: lange_task
150
+ character, intent(out) :: mat_task
147
151
!> State return flag
148
152
type(linalg_state_type), intent(out) :: err
149
153
150
154
integer(ilp) :: int_order,read_err
151
155
152
156
select case (order)
153
157
case ('inf','Inf','INF')
154
- lange_task = LANGE_NORM_INF
158
+ mat_task = MAT_NORM_INF
155
159
case ('Euclidean','euclidean','EUCLIDEAN','Frobenius','frobenius','FROBENIUS','Fro','fro','frob')
156
- lange_task = LANGE_NORM_FRO
160
+ mat_task = MAT_NORM_FRO
157
161
case default
158
162
159
163
! Check if this input can be read as an integer
160
164
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
162
166
! Cannot read as an integer
163
167
err = linalg_state_type(this,LINALG_ERROR,'Matrix norm input',order,' is not recognized.')
164
168
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
+
167
176
end select
168
177
169
- end subroutine lange_task_request_character
178
+ end subroutine mat_task_request_character
170
179
171
180
#:for rk,rt,ri in ALL_KINDS_TYPES
172
181
@@ -446,7 +455,7 @@ ${loop_variables_end(rank-1," "*12)}$
446
455
447
456
type(linalg_state_type) :: err_
448
457
integer(ilp) :: m,n
449
- character :: lange_task
458
+ character :: mat_task
450
459
real(${rk}$), target :: work1(1)
451
460
real(${rk}$), pointer :: work(:)
452
461
@@ -463,22 +472,22 @@ ${loop_variables_end(rank-1," "*12)}$
463
472
end if
464
473
465
474
! Check norm request: user + *LANGE support
466
- call lange_task_request (order,lange_task ,err_)
475
+ call mat_task_request (order,mat_task ,err_)
467
476
if (err_%error()) then
468
477
call linalg_error_handling(err_,err)
469
478
return
470
479
endif
471
480
472
- if (lange_task==LANGE_NORM_INF ) then
481
+ if (mat_task==MAT_NORM_INF ) then
473
482
allocate(work(m))
474
483
else
475
484
work => work1
476
485
endif
477
486
478
487
! LAPACK interface
479
- nrm = lange(lange_task ,m,n,a,m,work)
488
+ nrm = lange(mat_task ,m,n,a,m,work)
480
489
481
- if (lange_task==LANGE_NORM_INF ) deallocate(work)
490
+ if (mat_task==MAT_NORM_INF ) deallocate(work)
482
491
483
492
end function matrix_norm_${ii}$_${ri}$
484
493
@@ -503,7 +512,7 @@ ${loop_variables_end(rank-1," "*12)}$
503
512
integer(ilp), dimension(${rank}$), parameter :: dim_range = [(m,m=1_ilp,${rank}$_ilp)]
504
513
integer(ilp) :: ${loop_variables('j',rank-2,2)}$
505
514
logical :: contiguous_data
506
- character :: lange_task
515
+ character :: mat_task
507
516
real(${rk}$), target :: work1(1)
508
517
real(${rk}$), pointer :: work(:)
509
518
${rt}$, pointer :: apack${ranksuffix(rank)}$
@@ -525,7 +534,7 @@ ${loop_variables_end(rank-1," "*12)}$
525
534
endif
526
535
527
536
! Check norm request: user + *LANGE support
528
- call lange_task_request (order,lange_task ,err_)
537
+ call mat_task_request (order,mat_task ,err_)
529
538
if (err_%error()) then
530
539
allocate(nrm${emptyranksuffix(rank-2)}$)
531
540
call linalg_error_handling(err_,err)
@@ -559,7 +568,7 @@ ${loop_variables_end(rank-1," "*12)}$
559
568
560
569
endif
561
570
562
- if (lange_task==LANGE_NORM_INF ) then
571
+ if (mat_task==MAT_NORM_INF ) then
563
572
allocate(work(m))
564
573
else
565
574
work => work1
@@ -573,10 +582,10 @@ ${loop_variables_end(rank-1," "*12)}$
573
582
! LAPACK interface
574
583
${loop_variables_start('j', 'apack', rank-2, 2)}$
575
584
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)
577
586
${loop_variables_end(rank-2)}$
578
587
579
- if (lange_task==LANGE_NORM_INF ) deallocate(work)
588
+ if (mat_task==MAT_NORM_INF ) deallocate(work)
580
589
if (.not.contiguous_data) deallocate(apack)
581
590
582
591
end function matrix_norm_${rank}$D_to_${rank-2}$D_${ii}$_${ri}$
0 commit comments