@@ -29,13 +29,18 @@ submodule(stdlib_linalg) stdlib_linalg_norms
2929 character, parameter :: LANGE_NORM_MAT = 'M' ! maxval(sum(abs(a))) ! over whole matrix: unused
3030 character, parameter :: LANGE_NORM_ONE = '1' ! maxval(sum(abs(a),1)) ! over columns
3131 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"
3333
3434 interface parse_norm_type
3535 module procedure parse_norm_type_integer
3636 module procedure parse_norm_type_character
3737 end interface parse_norm_type
3838
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+
3944
4045 interface stride_1d
4146 #:for rk,rt,ri in ALL_KINDS_TYPES
@@ -107,25 +112,61 @@ submodule(stdlib_linalg) stdlib_linalg_norms
107112 end subroutine parse_norm_type_character
108113
109114 !> 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)
111116 !> Parsed matrix norm type
112- integer(ilp), intent(in) :: norm_type
117+ integer(ilp), optional, intent(in) :: order
113118 !> LANGE task
114119 character, intent(out) :: lange_task
115120 !> Error flag
116121 type(linalg_state_type), intent(inout) :: err
117122
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
122165 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
129170
130171 #:for rk,rt,ri in ALL_KINDS_TYPES
131172
@@ -399,12 +440,12 @@ ${loop_variables_end(rank-1," "*12)}$
399440 !> Norm of the matrix.
400441 real(${rk}$) :: nrm
401442 !> Order of the matrix norm being computed.
402- ${it}$, intent(in) :: order
443+ ${it}$, #{if 'integer' in it}#optional, #{endif}# intent(in) :: order
403444 !> [optional] state return flag. On error if not requested, the code will stop
404445 type(linalg_state_type), intent(out), optional :: err
405446
406447 type(linalg_state_type) :: err_
407- integer(ilp) :: m,n,norm_request
448+ integer(ilp) :: m,n
408449 character :: lange_task
409450 real(${rk}$), target :: work1(1)
410451 real(${rk}$), pointer :: work(:)
@@ -422,8 +463,7 @@ ${loop_variables_end(rank-1," "*12)}$
422463 end if
423464
424465 ! 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_)
427467 if (err_%error()) then
428468 call linalg_error_handling(err_,err)
429469 return
@@ -451,7 +491,7 @@ ${loop_variables_end(rank-1," "*12)}$
451491 !> Norm of the matrix.
452492 real(${rk}$), allocatable :: nrm${ranksuffix(rank-2)}$
453493 !> Order of the matrix norm being computed.
454- ${it}$, intent(in) :: order
494+ ${it}$, #{if 'integer' in it}#optional, #{endif}# intent(in) :: order
455495 !> [optional] dimensions of the sub-matrices the norms should be evaluated at (default = [1,2])
456496 integer(ilp), optional, intent(in) :: dim(2)
457497 !> [optional] state return flag. On error if not requested, the code will stop
@@ -485,8 +525,7 @@ ${loop_variables_end(rank-1," "*12)}$
485525 endif
486526
487527 ! 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_)
490529 if (err_%error()) then
491530 allocate(nrm${emptyranksuffix(rank-2)}$)
492531 call linalg_error_handling(err_,err)
0 commit comments