Skip to content

Commit ce36d85

Browse files
authored
Merge branch 'fortran-lang:master' into pseudo_inverse
2 parents 38bae4d + cc30d4c commit ce36d85

File tree

11 files changed

+652
-21
lines changed

11 files changed

+652
-21
lines changed

.github/workflows/CI.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
strategy:
2020
fail-fast: false
2121
matrix:
22-
os: [ubuntu-latest, macos-12]
22+
os: [ubuntu-latest, macos-13]
2323
toolchain:
2424
- {compiler: gcc, version: 10}
2525
- {compiler: gcc, version: 11}
@@ -34,9 +34,11 @@ jobs:
3434
toolchain:
3535
- {compiler: gcc, version: 10}
3636
exclude:
37-
- os: macos-12
37+
- os: macos-13
38+
toolchain: {compiler: intel-classic, version: '2021.9'}
39+
- os: macos-13
3840
toolchain: {compiler: intel, version: '2024.1'}
39-
- os: macos-12
41+
- os: macos-13
4042
toolchain: {compiler: gcc, version: 13}
4143
env:
4244
BUILD_DIR: ${{ matrix.build == 'cmake' && 'build' || '.' }}

doc/specs/stdlib_ascii.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Converts input character variable to all lowercase.
3838

3939
#### Class
4040

41-
Pure function.
41+
Elemental function.
4242

4343
#### Argument
4444

@@ -70,7 +70,7 @@ Converts input character variable to all uppercase.
7070

7171
#### Class
7272

73-
Pure function.
73+
Elemental function.
7474

7575
#### Argument
7676

@@ -107,7 +107,7 @@ or numeral present next to either of its 2 ends.
107107

108108
#### Class
109109

110-
Pure function.
110+
Elemental function.
111111

112112
#### Argument
113113

@@ -142,7 +142,7 @@ transformed to lowercase.
142142

143143
#### Class
144144

145-
Pure function.
145+
Elemental function.
146146

147147
#### Argument
148148

@@ -174,7 +174,7 @@ Reverses the order of all characters in the input character type.
174174

175175
#### Class
176176

177-
Pure function.
177+
Elemental function.
178178

179179
#### Argument
180180

doc/specs/stdlib_linalg.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,4 +1701,53 @@ If `err` is not present, exceptions trigger an `error stop`.
17011701
{!example/linalg/example_norm.f90!}
17021702
```
17031703

1704+
## `mnorm` - Computes the matrix norm of a generic-rank array.
1705+
1706+
### Status
1707+
1708+
Experimental
1709+
1710+
### Description
1711+
1712+
This function computes one of several matrix norms of `real` or `complex` array \( A \), depending on
1713+
the value of the `order` input argument. \( A \) must be an array of rank 2 or higher. For arrays of rank > 2,
1714+
matrix norms are computed over specified dimensions.
1715+
1716+
### Syntax
1717+
1718+
`x = ` [[stdlib_linalg(module):mnorm(interface)]] `(a [, order, dim, err])`
1719+
1720+
### Arguments
1721+
1722+
`a`: Shall be a rank-n `real` or `complex` array containing the data, where n >= 2. It is an `intent(in)` argument.
1723+
1724+
`order` (optional): Shall be an `integer` value or a `character` flag that specifies the norm type, as follows. It is an `intent(in)` argument.
1725+
1726+
| Integer input | Character Input | Norm type |
1727+
|------------------|---------------------------------|-----------------------------------------------------------------------------|
1728+
| `1` | `'1'` | 1-norm (maximum column sum) \( \max_j \sum_i{ \left|a_{i,j}\right| } \) |
1729+
| `2` | `'2'` | 2-norm (largest singular value) |
1730+
| (not prov.) | `'Euclidean','Frobenius','Fro'` | Frobenius norm \( \sqrt{\sum_{i,j}{ \left|a_{i,j}\right|^2 }} \) |
1731+
| `huge(0)` | `'inf', 'Inf', 'INF'` | Infinity norm (maximum row sum) \( \max_i \sum_j{ \left|a_{i,j}\right| } \) |
1732+
1733+
`dim` (optional): For arrays of rank > 2, shall be an integer array of size 2 specifying the dimensions over which to compute the matrix norm. Default value is `[1,2]`. It is an `intent(in)` argument.
1734+
1735+
`err` (optional): Shall be a `type(linalg_state_type)` value. This is an `intent(out)` argument.
1736+
1737+
### Return value
1738+
1739+
For rank-2 input arrays, the return value `x` is a scalar containing the matrix norm.
1740+
For arrays of rank > 2, if the optional `dim` argument is present, `x` is a rank `n-2` array with the same shape as \( A \) except
1741+
for dimensions `dim(1)` and `dim(2)`, which are dropped. Each element of `x` contains the matrix norm of the corresponding submatrix of \( A \),
1742+
evaluated over the specified dimensions only, with the given order.
1743+
1744+
If an invalid norm type is provided, defaults to 1-norm and raises `LINALG_ERROR`.
1745+
Raises `LINALG_VALUE_ERROR` if any of the arguments has an invalid size.
1746+
If `err` is not present, exceptions trigger an `error stop`.
1747+
1748+
### Example
1749+
1750+
```fortran
1751+
{!example/linalg/example_mnorm.f90!}
1752+
```
17041753

example/linalg/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ ADD_EXAMPLE(lapack_getrf)
3030
ADD_EXAMPLE(lstsq1)
3131
ADD_EXAMPLE(lstsq2)
3232
ADD_EXAMPLE(norm)
33+
ADD_EXAMPLE(mnorm)
3334
ADD_EXAMPLE(get_norm)
3435
ADD_EXAMPLE(solve1)
3536
ADD_EXAMPLE(solve2)

example/linalg/example_mnorm.f90

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
program example_mnorm
2+
use stdlib_linalg, only: mnorm
3+
use stdlib_kinds, only: sp
4+
implicit none
5+
real(sp) :: a(3,3), na
6+
real(sp) :: b(3,3,4), nb(4) ! Array of 4 3x3 matrices
7+
8+
! Initialize example matrix
9+
a = reshape([1, 2, 3, 4, 5, 6, 7, 8, 9], [3, 3])
10+
11+
! Compute Euclidean norm of single matrix
12+
na = mnorm(a, 'Euclidean')
13+
print *, "Euclidean norm of matrix a:", na
14+
15+
! Initialize array of matrices
16+
b(:,:,1) = a
17+
b(:,:,2) = 2*a
18+
b(:,:,3) = 3*a
19+
b(:,:,4) = 4*a
20+
21+
! Compute infinity norm of each 3x3 matrix in b
22+
nb = mnorm(b, 'inf', dim=[1,2])
23+
24+
! 18.0000000 36.0000000 54.0000000 72.0000000
25+
print *, "Infinity norms of matrices in b:", nb
26+
end program example_mnorm

include/common.fypp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,22 @@ $:"s" if cmplx=="c" else "d" if cmplx=="z" else "x" if cmplx=="y" else "q" if cm
157157
#{if rank > 0}#(${"0" + ",0" * (rank - 1)}$)#{endif}#
158158
#:enddef
159159

160+
#! Generates an array rank suffix with a fixed integer size for all dimensions.
161+
#!
162+
#! Args:
163+
#! rank (int): Rank of the variable
164+
#! size (int): Size along each dimension
165+
#!
166+
#! Returns:
167+
#! Array rank suffix string
168+
#! E.g.,
169+
#! fixedranksuffix(3,4)
170+
#! -> (4,4,4)
171+
#!
172+
#:def fixedranksuffix(rank,size)
173+
#{if rank > 0}#(${str(size) + (","+str(size)) * (rank - 1)}$)#{endif}#
174+
#:enddef
175+
160176
#! Joins stripped lines with given character string
161177
#!
162178
#! Args:
@@ -227,7 +243,7 @@ ${prefix + joinstr.join([line.strip() for line in txt.split("\n")]) + suffix}$
227243
#! Array rank suffix string enclosed in braces
228244
#!
229245
#! E.g.,
230-
#! select_subarray(5 , [(4, 'i'), (5, 'j')])}$
246+
#! select_subarray(5 , [(4, 'i'), (5, 'j')])
231247
#! -> (:, :, :, i, j)
232248
#!
233249
#:def select_subarray(rank, selectors)
@@ -327,6 +343,34 @@ ${prefix + joinstr.join([line.strip() for line in txt.split("\n")]) + suffix}$
327343
#:endcall
328344
#:enddef
329345

346+
#!
347+
#! Generates a list of loop variables from an array
348+
#!
349+
#! Args:
350+
#! varname(str): Name of the array variable to be used as prefix
351+
#! n (int): Number of loop variables to be created
352+
#! offset (int): Optional index offset
353+
#!
354+
#! Returns:
355+
#! Variable definition string
356+
#!
357+
#! E.g.,
358+
#! loop_array_variables('j', 5)
359+
#! -> "j(1), j(2), j(3), j(4), j(5)
360+
#!
361+
#! loop_array_variables('j', 5, 2)
362+
#! -> "j(3), j(4), j(5), j(6), j(7)
363+
#!
364+
#:def loop_array_variables(varname, n, offset=0)
365+
#:assert n > 0
366+
#:call join_lines(joinstr=", ")
367+
#:for i in range(1, n + 1)
368+
${varname}$(${i+offset}$)
369+
#:endfor
370+
#:endcall
371+
#:enddef
372+
373+
330374
#! Generates an array shape specifier from an N-D array size
331375
#!
332376
#! Args:

src/stdlib_ascii.fypp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,35 +70,35 @@ module stdlib_ascii
7070

7171
!> Returns a new character sequence which is the lower case
7272
!> version of the input character sequence
73-
!> This method is pure and returns a character sequence
73+
!> This method is elemental and returns a character sequence
7474
interface to_lower
7575
module procedure :: to_lower
7676
end interface to_lower
7777

7878
!> Returns a new character sequence which is the upper case
7979
!> version of the input character sequence
80-
!> This method is pure and returns a character sequence
80+
!> This method is elemental and returns a character sequence
8181
interface to_upper
8282
module procedure :: to_upper
8383
end interface to_upper
8484

8585
!> Returns a new character sequence which is the title case
8686
!> version of the input character sequence
87-
!> This method is pure and returns a character sequence
87+
!> This method is elemental and returns a character sequence
8888
interface to_title
8989
module procedure :: to_title
9090
end interface to_title
9191

9292
!> Returns a new character sequence which is the sentence case
9393
!> version of the input character sequence
94-
!> This method is pure and returns a character sequence
94+
!> This method is elemental and returns a character sequence
9595
interface to_sentence
9696
module procedure :: to_sentence
9797
end interface to_sentence
9898

9999
!> Returns a new character sequence which is reverse of
100100
!> the input charater sequence
101-
!> This method is pure and returns a character sequence
101+
!> This method is elemental and returns a character sequence
102102
interface reverse
103103
module procedure :: reverse
104104
end interface reverse
@@ -220,7 +220,7 @@ contains
220220

221221
!> Returns the corresponding lowercase letter, if `c` is an uppercase
222222
!> ASCII character, otherwise `c` itself.
223-
pure function char_to_lower(c) result(t)
223+
elemental function char_to_lower(c) result(t)
224224
character(len=1), intent(in) :: c !! A character.
225225
character(len=1) :: t
226226
integer, parameter :: wp= iachar('a')-iachar('A'), BA=iachar('A'), BZ=iachar('Z')
@@ -234,7 +234,7 @@ contains
234234

235235
!> Returns the corresponding uppercase letter, if `c` is a lowercase
236236
!> ASCII character, otherwise `c` itself.
237-
pure function char_to_upper(c) result(t)
237+
elemental function char_to_upper(c) result(t)
238238
character(len=1), intent(in) :: c !! A character.
239239
character(len=1) :: t
240240
integer, parameter :: wp= iachar('a')-iachar('A'), la=iachar('a'), lz=iachar('z')
@@ -250,7 +250,7 @@ contains
250250
!> ([Specification](../page/specs/stdlib_ascii.html#to_lower))
251251
!>
252252
!> Version: experimental
253-
pure function to_lower(string) result(lower_string)
253+
elemental function to_lower(string) result(lower_string)
254254
character(len=*), intent(in) :: string
255255
character(len=len(string)) :: lower_string
256256
integer :: i
@@ -265,7 +265,7 @@ contains
265265
!> ([Specification](../page/specs/stdlib_ascii.html#to_upper))
266266
!>
267267
!> Version: experimental
268-
pure function to_upper(string) result(upper_string)
268+
elemental function to_upper(string) result(upper_string)
269269
character(len=*), intent(in) :: string
270270
character(len=len(string)) :: upper_string
271271
integer :: i
@@ -280,7 +280,7 @@ contains
280280
!> ([Specification](../page/specs/stdlib_ascii.html#to_title))
281281
!>
282282
!> Version: experimental
283-
pure function to_title(string) result(title_string)
283+
elemental function to_title(string) result(title_string)
284284
character(len=*), intent(in) :: string
285285
character(len=len(string)) :: title_string
286286
integer :: i
@@ -307,7 +307,7 @@ contains
307307
!> ([Specification](../page/specs/stdlib_ascii.html#to_sentence))
308308
!>
309309
!> Version: experimental
310-
pure function to_sentence(string) result(sentence_string)
310+
elemental function to_sentence(string) result(sentence_string)
311311
character(len=*), intent(in) :: string
312312
character(len=len(string)) :: sentence_string
313313
integer :: i, n
@@ -333,7 +333,7 @@ contains
333333
!> ([Specification](../page/specs/stdlib_ascii.html#reverse))
334334
!>
335335
!> Version: experimental
336-
pure function reverse(string) result(reverse_string)
336+
elemental function reverse(string) result(reverse_string)
337337
character(len=*), intent(in) :: string
338338
character(len=len(string)) :: reverse_string
339339
integer :: i, n

0 commit comments

Comments
 (0)