Skip to content

Commit 4008e07

Browse files
authored
Merge branch 'master' into qr
2 parents 478f68d + c8fa301 commit 4008e07

12 files changed

+835
-6
lines changed

API-doc-FORD-file.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ project_website: https://stdlib.fortran-lang.org
4343
favicon: doc/media/favicon.ico
4444
license: by-sa
4545
author: fortran-lang/stdlib contributors
46-
author_pic: https://fortran-lang.org/assets/img/fortran_logo_512x512.png
46+
author_pic: https://fortran-lang.org/en/_static/fortran-logo-256x256.png
4747
email: fortran-lang@groups.io
4848
github: https://github.com/fortran-lang
4949
twitter: https://twitter.com/fortranlang

doc/specs/stdlib_linalg.md

Lines changed: 127 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ end interface axpy
104104
Note that the 128-bit functions are only provided by `stdlib` and always point to the internal implementation.
105105
Because 128-bit precision is identified as [stdlib_kinds(module):qp], initials for 128-bit procedures were
106106
labelled as `q` (quadruple-precision reals) and `w` ("wide" or quadruple-precision complex numbers).
107-
Extended precision ([stdlib_kinds(module):xdp]) calculations are currently not supported.
107+
Extended precision ([stdlib_kinds(module):xdp]) calculations are labelled as `x` (extended-precision reals).
108+
and `y` (extended-precision complex numbers).
108109

109110
### Example
110111

@@ -779,7 +780,7 @@ Result vector `x` returns the approximate solution that minimizes the 2-norm \(
779780

780781
`cond` (optional): Shall be a scalar `real` value cut-off threshold for rank evaluation: `s_i >= cond*maxval(s), i=1:rank`. Shall be a scalar, `intent(in)` argument.
781782

782-
`singvals` (optional): Shall be a `real` rank-1 array of the same kind `a` and size at least `minval(shape(a))`, returning the list of singular values `s(i)>=cond*maxval(s)`, in descending order of magnitude. It is an `intent(out)` argument.
783+
`singvals` (optional): Shall be a `real` rank-1 array of the same kind `a` and size at least `min(m,n)`, returning the list of singular values `s(i)>=cond*maxval(s)` from the internal SVD, in descending order of magnitude. It is an `intent(out)` argument.
783784

784785
`overwrite_a` (optional): Shall be an input `logical` flag. If `.true.`, input matrix `A` will be used as temporary storage and overwritten. This avoids internal data allocation. This is an `intent(in)` argument.
785786

@@ -881,15 +882,15 @@ This interface is equivalent to the `pure` version of determinant [[stdlib_linal
881882

882883
### Syntax
883884

884-
`c = ` [[stdlib_linalg(module):operator(.det.)(interface)]] `(a)`
885+
`c = ` [[stdlib_linalg(module):operator(.det.)(interface)]] `a`
885886

886887
### Arguments
887888

888889
`a`: Shall be a rank-2 square array of any `real` or `complex` kinds. It is an `intent(in)` argument.
889890

890891
### Return value
891892

892-
Returns a real scalar value that represents the determinnt of the matrix.
893+
Returns a real scalar value that represents the determinant of the matrix.
893894

894895
Raises `LINALG_ERROR` if the matrix is singular.
895896
Raises `LINALG_VALUE_ERROR` if the matrix is non-square.
@@ -1241,3 +1242,125 @@ Exceptions trigger an `error stop`, unless argument `err` is present.
12411242
```fortran
12421243
{!example/linalg/example_svdvals.f90!}
12431244
```
1245+
1246+
## `.inv.` - Inverse operator of a square matrix
1247+
1248+
### Status
1249+
1250+
Experimental
1251+
1252+
### Description
1253+
1254+
This operator returns the inverse of a `real` or `complex` square matrix \( A \).
1255+
The inverse \( A^{-1} \) is defined such that \( A \cdot A^{-1} = A^{-1} \cdot A = I_n \).
1256+
1257+
This interface is equivalent to the function [[stdlib_linalg(module):inv(interface)]].
1258+
1259+
### Syntax
1260+
1261+
`b = ` [[stdlib_linalg(module):operator(.inv.)(interface)]] `a`
1262+
1263+
### Arguments
1264+
1265+
`a`: Shall be a rank-2 square array of any `real` or `complex` kinds. It is an `intent(in)` argument.
1266+
1267+
### Return value
1268+
1269+
Returns a rank-2 square array with the same type, kind and rank as `a`, that contains the inverse of `a`.
1270+
1271+
If an exception occurred on input errors, or singular matrix, `NaN`s will be returned.
1272+
For fine-grained error control in case of singular matrices prefer the `subroutine` and the `function`
1273+
interfaces.
1274+
1275+
1276+
### Example
1277+
1278+
```fortran
1279+
{!example/linalg/example_inverse_operator.f90!}
1280+
```
1281+
1282+
## `invert` - Inversion of a square matrix
1283+
1284+
### Status
1285+
1286+
Experimental
1287+
1288+
### Description
1289+
1290+
This subroutine inverts a square `real` or `complex` matrix in-place.
1291+
The inverse \( A^{-1} \) is defined such that \( A \cdot A^{-1} = A^{-1} \cdot A = I_n \).
1292+
1293+
On return, the input matrix `a` is replaced by its inverse.
1294+
The solver is based on LAPACK's `*GETRF` and `*GETRI` backends.
1295+
1296+
### Syntax
1297+
1298+
`call ` [[stdlib_linalg(module):invert(interface)]] `(a, [,inva] [, pivot] [, err])`
1299+
1300+
### Arguments
1301+
1302+
`a`: Shall be a rank-2, square, `real` or `complex` array containing the coefficient matrix.
1303+
If `inva` is provided, it is an `intent(in)` argument.
1304+
If `inva` is not provided, it is an `intent(inout)` argument: on output, it is replaced by the inverse of `a`.
1305+
1306+
`inva` (optional): Shall be a rank-2, square, `real` or `complex` array with the same size, and kind as `a`.
1307+
On output, it contains the inverse of `a`.
1308+
1309+
`pivot` (optional): Shall be a rank-1 array of the same kind and matrix dimension as `a`, that contains the diagonal pivot indices on return. It is an `intent(inout)` argument.
1310+
1311+
`err` (optional): Shall be a `type(linalg_state_type)` value. This is an `intent(out)` argument.
1312+
1313+
### Return value
1314+
1315+
Computes the inverse of the matrix \( A \), \(A^{-1}\, and returns it either in \( A \) or in another matrix.
1316+
1317+
Raises `LINALG_ERROR` if the matrix is singular or has invalid size.
1318+
Raises `LINALG_VALUE_ERROR` if `inva` and `a` do not have the same size.
1319+
If `err` is not present, exceptions trigger an `error stop`.
1320+
1321+
### Example
1322+
1323+
```fortran
1324+
{!example/linalg/example_inverse_inplace.f90!}
1325+
```
1326+
1327+
```fortran
1328+
{!example/linalg/example_inverse_subroutine.f90!}
1329+
```
1330+
1331+
## `inv` - Inverse of a square matrix.
1332+
1333+
### Status
1334+
1335+
Experimental
1336+
1337+
### Description
1338+
1339+
This function returns the inverse of a square `real` or `complex` matrix in-place.
1340+
The inverse, \( A^{-1} \), is defined such that \( A \cdot A^{-1} = A^{-1} \cdot A = I_n \).
1341+
1342+
The solver is based on LAPACK's `*GETRF` and `*GETRI` backends.
1343+
1344+
### Syntax
1345+
1346+
`b ` [[stdlib_linalg(module):inv(interface)]] `(a, [, err])`
1347+
1348+
### Arguments
1349+
1350+
`a`: Shall be a rank-2, square, `real` or `complex` array containing the coefficient matrix. It is an `intent(inout)` argument.
1351+
1352+
`err` (optional): Shall be a `type(linalg_state_type)` value. It is an `intent(out)` argument.
1353+
1354+
### Return value
1355+
1356+
Returns an array value of the same type, kind and rank as `a`, that contains the inverse matrix \(A^{-1}\).
1357+
1358+
Raises `LINALG_ERROR` if the matrix is singular or has invalid size.
1359+
If `err` is not present, exceptions trigger an `error stop`.
1360+
1361+
### Example
1362+
1363+
```fortran
1364+
{!example/linalg/example_inverse_function.f90!}
1365+
```
1366+

example/linalg/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ ADD_EXAMPLE(is_skew_symmetric)
1212
ADD_EXAMPLE(is_square)
1313
ADD_EXAMPLE(is_symmetric)
1414
ADD_EXAMPLE(is_triangular)
15+
ADD_EXAMPLE(inverse_operator)
16+
ADD_EXAMPLE(inverse_function)
17+
ADD_EXAMPLE(inverse_inplace)
18+
ADD_EXAMPLE(inverse_subroutine)
1519
ADD_EXAMPLE(outer_product)
1620
ADD_EXAMPLE(eig)
1721
ADD_EXAMPLE(eigh)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
! Matrix inversion example: function interface
2+
program example_inverse_function
3+
use stdlib_linalg_constants, only: dp
4+
use stdlib_linalg, only: inv,eye
5+
implicit none
6+
7+
real(dp) :: A(2,2), Am1(2,2)
8+
9+
! Input matrix (NB Fortran is column major! input columns then transpose)
10+
A = transpose(reshape( [4, 3, &
11+
3, 2], [2,2] ))
12+
13+
! Invert matrix
14+
Am1 = inv(A)
15+
16+
print *, ' |',Am1(1,:),'|' ! | -2 3 |
17+
print *, ' inv(A)= |',Am1(2,:),'|' ! | 3 -4 |
18+
19+
! Final check
20+
print *, 'CHECK passed? ',matmul(A,Am1)==eye(2)
21+
22+
end program example_inverse_function
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
! Matrix inversion example: in-place inversion
2+
program example_inverse_inplace
3+
use stdlib_linalg_constants, only: dp
4+
use stdlib_linalg, only: invert,eye
5+
implicit none
6+
7+
real(dp) :: A(2,2), Am1(2,2)
8+
9+
! Input matrix (NB Fortran is column major! input columns then transpose)
10+
A = transpose(reshape( [4, 3, &
11+
3, 2], [2,2] ))
12+
Am1 = A
13+
14+
! Invert matrix
15+
call invert(Am1)
16+
17+
print *, ' |',Am1(1,:),'|' ! | -2 3 |
18+
print *, ' inv(A)= |',Am1(2,:),'|' ! | 3 -4 |
19+
20+
! Final check
21+
print *, 'CHECK passed? ',matmul(A,Am1)==eye(2)
22+
23+
end program example_inverse_inplace
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
! Matrix inversion example: operator interface
2+
program example_inverse_operator
3+
use stdlib_linalg_constants, only: dp
4+
use stdlib_linalg, only: operator(.inv.),eye
5+
implicit none
6+
7+
real(dp) :: A(2,2), Am1(2,2)
8+
9+
! Input matrix (NB Fortran is column major! input columns then transpose)
10+
A = transpose(reshape( [4, 3, &
11+
3, 2], [2,2] ))
12+
13+
! Invert matrix
14+
Am1 = .inv.A
15+
16+
print *, ' |',Am1(1,:),'|' ! | -2 3 |
17+
print *, ' inv(A)= |',Am1(2,:),'|' ! | 3 -4 |
18+
19+
! Final check
20+
print *, 'CHECK passed? ',matmul(A,Am1)==eye(2)
21+
22+
end program example_inverse_operator
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
! Matrix inversion example: subroutine interface
2+
program example_inverse_subroutine
3+
use stdlib_linalg_constants, only: dp
4+
use stdlib_linalg, only: invert,eye
5+
implicit none
6+
7+
real(dp) :: A(2,2), Am1(2,2)
8+
9+
! Input matrix (NB Fortran is column major! input columns then transpose)
10+
A = transpose(reshape( [4, 3, &
11+
3, 2], [2,2] ))
12+
13+
! Invert matrix
14+
call invert(A,Am1)
15+
16+
print *, ' |',Am1(1,:),'|' ! | -2 3 |
17+
print *, ' inv(A)= |',Am1(2,:),'|' ! | 3 -4 |
18+
19+
! Final check
20+
print *, 'CHECK passed? ',matmul(A,Am1)==eye(2)
21+
22+
end program example_inverse_subroutine

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ set(fppFiles
3131
stdlib_linalg_solve.fypp
3232
stdlib_linalg_determinant.fypp
3333
stdlib_linalg_qr.fypp
34+
stdlib_linalg_inverse.fypp
3435
stdlib_linalg_state.fypp
3536
stdlib_linalg_svd.fypp
3637
stdlib_optval.fypp

0 commit comments

Comments
 (0)