@@ -29,13 +29,18 @@ submodule(stdlib_linalg) stdlib_linalg_norms
29
29
character, parameter :: LANGE_NORM_MAT = 'M' ! maxval(sum(abs(a))) ! over whole matrix: unused
30
30
character, parameter :: LANGE_NORM_ONE = '1' ! maxval(sum(abs(a),1)) ! over columns
31
31
character, parameter :: LANGE_NORM_INF = 'I' ! maxval(sum(abs(a),2)) ! over rows
32
- character, parameter :: LANGE_NORM_TWO = 'E' ! "Euclidean" or "Frobenius"
32
+ character, parameter :: LANGE_NORM_FRO = 'E' ! sqrt(sum(a**2)) ! "Euclidean" or "Frobenius"
33
33
34
34
interface parse_norm_type
35
35
module procedure parse_norm_type_integer
36
36
module procedure parse_norm_type_character
37
37
end interface parse_norm_type
38
38
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
43
+
39
44
40
45
interface stride_1d
41
46
#:for rk,rt,ri in ALL_KINDS_TYPES
@@ -107,25 +112,61 @@ submodule(stdlib_linalg) stdlib_linalg_norms
107
112
end subroutine parse_norm_type_character
108
113
109
114
!> From a user norm request, generate a *LANGE task command
110
- pure subroutine lange_task_request(norm_type ,lange_task,err)
115
+ pure subroutine lange_task_request_integer(order ,lange_task,err)
111
116
!> Parsed matrix norm type
112
- integer(ilp), intent(in) :: norm_type
117
+ integer(ilp), optional, intent(in) :: order
113
118
!> LANGE task
114
119
character, intent(out) :: lange_task
115
120
!> Error flag
116
121
type(linalg_state_type), intent(inout) :: err
117
122
118
- select case (norm_type)
119
- case (NORM_INF)
120
- lange_task = LANGE_NORM_INF
121
- case (NORM_ONE)
123
+ if (present(order)) then
124
+
125
+ select case (order)
126
+ case (NORM_INF)
127
+ lange_task = LANGE_NORM_INF
128
+ case (NORM_ONE)
129
+ lange_task = LANGE_NORM_ONE
130
+ case default
131
+ err = linalg_state_type(this,LINALG_VALUE_ERROR,'Integer order ',order,' is not a valid matrix norm input.')
132
+ end select
133
+
134
+ else
135
+
136
+ ! No user input: Frobenius norm
137
+ lange_task = LANGE_NORM_FRO
138
+
139
+ endif
140
+ end subroutine lange_task_request_integer
141
+
142
+ pure subroutine lange_task_request_character(order,lange_task,err)
143
+ !> User input value
144
+ character(len=*), intent(in) :: order
145
+ !> Return value: norm type
146
+ character, intent(out) :: lange_task
147
+ !> State return flag
148
+ type(linalg_state_type), intent(out) :: err
149
+
150
+ integer(ilp) :: int_order,read_err
151
+
152
+ select case (order)
153
+ case ('inf','Inf','INF')
154
+ lange_task = LANGE_NORM_INF
155
+ case ('Euclidean','euclidean','EUCLIDEAN','Frobenius','frobenius','FROBENIUS','Fro','fro','frob')
156
+ lange_task = LANGE_NORM_FRO
157
+ case default
158
+
159
+ ! Check if this input can be read as an integer
160
+ read(order,*,iostat=read_err) int_order
161
+ if (read_err/=0 .or. int_order/=1) then
162
+ ! Cannot read as an integer
163
+ err = linalg_state_type(this,LINALG_ERROR,'Matrix norm input',order,' is not recognized.')
164
+ endif
122
165
lange_task = LANGE_NORM_ONE
123
- case (NORM_TWO)
124
- lange_task = LANGE_NORM_TWO
125
- case default
126
- err = linalg_state_type(this,LINALG_VALUE_ERROR,'Order ',norm_type,' is not a valid matrix norm input.')
127
- end select
128
- end subroutine lange_task_request
166
+
167
+ end select
168
+
169
+ end subroutine lange_task_request_character
129
170
130
171
#:for rk,rt,ri in ALL_KINDS_TYPES
131
172
@@ -399,12 +440,12 @@ ${loop_variables_end(rank-1," "*12)}$
399
440
!> Norm of the matrix.
400
441
real(${rk}$) :: nrm
401
442
!> Order of the matrix norm being computed.
402
- ${it}$, intent(in) :: order
443
+ ${it}$, #{if 'integer' in it}#optional, #{endif}# intent(in) :: order
403
444
!> [optional] state return flag. On error if not requested, the code will stop
404
445
type(linalg_state_type), intent(out), optional :: err
405
446
406
447
type(linalg_state_type) :: err_
407
- integer(ilp) :: m,n,norm_request
448
+ integer(ilp) :: m,n
408
449
character :: lange_task
409
450
real(${rk}$), target :: work1(1)
410
451
real(${rk}$), pointer :: work(:)
@@ -422,8 +463,7 @@ ${loop_variables_end(rank-1," "*12)}$
422
463
end if
423
464
424
465
! Check norm request: user + *LANGE support
425
- call parse_norm_type(order,norm_request,err_)
426
- call lange_task_request(norm_request,lange_task,err_)
466
+ call lange_task_request(order,lange_task,err_)
427
467
if (err_%error()) then
428
468
call linalg_error_handling(err_,err)
429
469
return
@@ -451,7 +491,7 @@ ${loop_variables_end(rank-1," "*12)}$
451
491
!> Norm of the matrix.
452
492
real(${rk}$), allocatable :: nrm${ranksuffix(rank-2)}$
453
493
!> Order of the matrix norm being computed.
454
- ${it}$, intent(in) :: order
494
+ ${it}$, #{if 'integer' in it}#optional, #{endif}# intent(in) :: order
455
495
!> [optional] dimensions of the sub-matrices the norms should be evaluated at (default = [1,2])
456
496
integer(ilp), optional, intent(in) :: dim(2)
457
497
!> [optional] state return flag. On error if not requested, the code will stop
@@ -485,8 +525,7 @@ ${loop_variables_end(rank-1," "*12)}$
485
525
endif
486
526
487
527
! Check norm request: user + *LANGE support
488
- call parse_norm_type(order,norm_request,err_)
489
- call lange_task_request(norm_request,lange_task,err_)
528
+ call lange_task_request(order,lange_task,err_)
490
529
if (err_%error()) then
491
530
allocate(nrm${emptyranksuffix(rank-2)}$)
492
531
call linalg_error_handling(err_,err)
0 commit comments