@@ -40,6 +40,7 @@ module test_linalg_norm
4040 #:if rt.startswith('real')
4141 tests = [tests,new_unittest("norm2_${ri}$_${rank}$d",test_norm2_${ri}$_${rank}$d)]
4242 #:endif
43+ tests = [tests,new_unittest("maxabs_${ri}$_${rank}$d",test_maxabs_${ri}$_${rank}$d)]
4344 tests = [tests,new_unittest("norm_dimmed_${ri}$_${rank}$d",test_norm_dimmed_${ri}$_${rank}$d)]
4445 #:endfor
4546 #:endfor
@@ -135,9 +136,9 @@ module test_linalg_norm
135136
136137 end subroutine test_norm_${ri}$_${rank}$d
137138 #:endfor
138-
139- !> Test Euclidean norm; compare with Fortran intrinsic norm2 for reals
139+
140140 #:for rank in range(2, MAXRANK)
141+ !> Test Euclidean norm; compare with Fortran intrinsic norm2 for reals
141142 #:if rt.startswith('real')
142143 subroutine test_norm2_${ri}$_${rank}$d(error)
143144 type(error_type), allocatable, intent(out) :: error
@@ -178,6 +179,45 @@ module test_linalg_norm
178179 end subroutine test_norm2_${ri}$_${rank}$d
179180 #:endif
180181
182+ !> Test Infinity norm; compare with Fortran intrinsic max(abs(a))
183+ subroutine test_maxabs_${ri}$_${rank}$d(error)
184+ type(error_type), allocatable, intent(out) :: error
185+
186+ integer(ilp) :: j,dim
187+ integer(ilp), parameter :: ndim = ${rank}$
188+ integer(ilp), parameter :: n = 2_ilp**ndim
189+ real(${rk}$), parameter :: tol = 10*sqrt(epsilon(0.0_${rk}$))
190+ ${rt}$, allocatable :: a(:), b${ranksuffix(rank)}$
191+ intrinsic :: maxval, abs
192+ character(128) :: msg
193+
194+ allocate(a(n), b${fixedranksuffix(rank,2)}$)
195+
196+ ! Init as a range,but with small elements such that all power norms will
197+ ! never overflow, even in single precision
198+ a = [(0.01_${rk}$*(j-n/2_ilp), j=1_ilp,n)]
199+ b = reshape(a, shape(b))
200+
201+ ! Test some norms
202+ call check(error,abs(norm(a,'inf') - maxval(abs(a)))<tol*norm(a,'inf'),&
203+ 'Infinity norm does not match ${rt}$ `maxval(abs(.))` intrinsics')
204+ if (allocated(error)) return
205+
206+ ! Infinity norms
207+ call check(error,abs(norm(b,'inf')-maxval(abs(b)))<tol*norm(b,'inf'),&
208+ 'Dimmed Infinity norm does not match ${rt}$ `maxval(abs(.))` intrinsics')
209+ if (allocated(error)) return
210+
211+ ! Test norm as collapsed around dimension
212+ do dim = 1, ndim
213+ write(msg,"('Not all dim=',i0,' Infinity norms match ${rt}$ `maxval(abs(.))` intrinsics')") dim
214+ call check(error,all(abs(norm(b,'inf',dim)-maxval(abs(b),dim))<tol*max(1.0_${rk}$,norm(b,'inf',dim))),&
215+ trim(msg))
216+ if (allocated(error)) return
217+ end do
218+
219+ end subroutine test_maxabs_${ri}$_${rank}$d
220+
181221 ! Test norm along a dimension and compare it against individually evaluated norms
182222 subroutine test_norm_dimmed_${ri}$_${rank}$d(error)
183223 type(error_type), allocatable, intent(out) :: error
0 commit comments