Skip to content

Commit 61bf91c

Browse files
committed
write specs
1 parent 2e4f1a0 commit 61bf91c

File tree

3 files changed

+144
-8
lines changed

3 files changed

+144
-8
lines changed

doc/specs/stdlib_linalg.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,142 @@ If `err` is not present, exceptions trigger an `error stop`.
14591459
{!example/linalg/example_inverse_function.f90!}
14601460
```
14611461

1462+
## `pinv` - Moore-Penrose pseudo-inverse of a matrix.
1463+
1464+
### Status
1465+
1466+
Experimental
1467+
1468+
### Description
1469+
1470+
This function computes the Moore-Penrose pseudo-inverse of a `real` or `complex` matrix.
1471+
The pseudo-inverse, \( A^{+} \), generalizes the matrix inverse and satisfies the conditions:
1472+
- \( A \cdot A^{+} \cdot A = A \)
1473+
- \( A^{+} \cdot A \cdot A^{+} = A^{+} \)
1474+
- \( (A \cdot A^{+})^T = A \cdot A^{+} \)
1475+
- \( (A^{+} \cdot A)^T = A^{+} \cdot A \)
1476+
1477+
The computation is based on singular value decomposition (SVD). Singular values below a relative
1478+
tolerance threshold \( \text{rtol} \cdot \sigma_{\max} \), where \( \sigma_{\max} \) is the largest
1479+
singular value, are treated as zero.
1480+
1481+
### Syntax
1482+
1483+
`b ` [[stdlib_linalg(module):pinv(interface)]] `(a, [, rtol, err])`
1484+
1485+
### Arguments
1486+
1487+
`a`: Shall be a rank-2, `real` or `complex` array of shape `[m, n]` containing the coefficient matrix.
1488+
It is an `intent(in)` argument.
1489+
1490+
`rtol` (optional): Shall be a scalar `real` value specifying the relative tolerance for singular value cutoff.
1491+
If `rtol` is not provided, the default relative tolerance is \( \text{rtol} = \text{max}(m, n) \cdot \epsilon \),
1492+
where \( \epsilon \) is the machine precision for the element type of `a`. It is an `intent(in)` argument.
1493+
1494+
`err` (optional): Shall be a `type(linalg_state_type)` value. It is an `intent(out)` argument.
1495+
1496+
### Return value
1497+
1498+
Returns an array value of the same type, kind, and rank as `a` with shape `[n, m]`, that contains the pseudo-inverse matrix \( A^{+} \).
1499+
1500+
Raises `LINALG_ERROR` if the underlying SVD did not converge.
1501+
Raises `LINALG_VALUE_ERROR` if `pinva` and `a` have degenerate or incompatible sizes.
1502+
If `err` is not present, exceptions trigger an `error stop`.
1503+
1504+
### Example
1505+
1506+
```fortran
1507+
{!example/linalg/example_pseudoinverse.f90!}
1508+
```
1509+
1510+
## `pseudoinvert` - Moore-Penrose pseudo-inverse of a matrix
1511+
1512+
### Status
1513+
1514+
Experimental
1515+
1516+
### Description
1517+
1518+
This subroutine computes the Moore-Penrose pseudo-inverse of a `real` or `complex` matrix.
1519+
The pseudo-inverse \( A^{+} \) is a generalization of the matrix inverse and satisfies the following properties:
1520+
- \( A \cdot A^{+} \cdot A = A \)
1521+
- \( A^{+} \cdot A \cdot A^{+} = A^{+} \)
1522+
- \( (A \cdot A^{+})^T = A \cdot A^{+} \)
1523+
- \( (A^{+} \cdot A)^T = A^{+} \cdot A \)
1524+
1525+
The computation is based on singular value decomposition (SVD). Singular values below a relative
1526+
tolerance threshold \( \text{rtol} \cdot \sigma_{\max} \), where \( \sigma_{\max} \) is the largest
1527+
singular value, are treated as zero.
1528+
1529+
On return, matrix `pinva` `[n, m]` will store the pseudo-inverse of `a` `[m, n]`.
1530+
1531+
### Syntax
1532+
1533+
`call ` [[stdlib_linalg(module):pseudoinvert(interface)]] `(a, pinva [, rtol] [, err])`
1534+
1535+
### Arguments
1536+
1537+
`a`: Shall be a rank-2, `real` or `complex` array containing the coefficient matrix.
1538+
It is an `intent(in)` argument.
1539+
1540+
`pinva`: Shall be a rank-2 array of the same kind as `a`, and size equal to that of `transpose(a)`.
1541+
On output, it contains the Moore-Penrose pseudo-inverse of `a`.
1542+
1543+
`rtol` (optional): Shall be a scalar `real` value specifying the relative tolerance for singular value cutoff.
1544+
If not provided, the default threshold is \( \text{max}(m, n) \cdot \epsilon \), where \( \epsilon \) is the
1545+
machine precision for the element type of `a`.
1546+
1547+
`err` (optional): Shall be a `type(linalg_state_type)` value. It is an `intent(out)` argument.
1548+
1549+
### Return value
1550+
1551+
Computes the Moore-Penrose pseudo-inverse of the matrix \( A \), \( A^{+} \), and returns it in matrix `pinva`.
1552+
1553+
Raises `LINALG_ERROR` if the underlying SVD did not converge.
1554+
Raises `LINALG_VALUE_ERROR` if `pinva` and `a` have degenerate or incompatible sizes.
1555+
If `err` is not present, exceptions trigger an `error stop`.
1556+
1557+
### Example
1558+
1559+
```fortran
1560+
{!example/linalg/example_pseudoinverse.f90!}
1561+
```
1562+
1563+
## `.pinv.` - Moore-Penrose Pseudo-Inverse operator
1564+
1565+
### Status
1566+
1567+
Experimental
1568+
1569+
### Description
1570+
1571+
This operator returns the Moore-Penrose pseudo-inverse of a `real` or `complex` matrix \( A \).
1572+
The pseudo-inverse \( A^{+} \) is computed using Singular Value Decomposition (SVD), and singular values
1573+
below a given threshold are treated as zero.
1574+
1575+
This interface is equivalent to the function [[stdlib_linalg(module):pinv(interface)]].
1576+
1577+
### Syntax
1578+
1579+
`b = ` [[stdlib_linalg(module):operator(.pinv.)(interface)]] `a`
1580+
1581+
### Arguments
1582+
1583+
`a`: Shall be a rank-2 array of any `real` or `complex` kinds, with arbitrary dimensions \( m \times n \). It is an `intent(in)` argument.
1584+
1585+
### Return value
1586+
1587+
Returns a rank-2 array with the same type, kind, and rank as `a`, that contains the Moore-Penrose pseudo-inverse of `a`.
1588+
1589+
If an exception occurs, or if the input matrix is degenerate (e.g., rank-deficient), the returned matrix will contain `NaN`s.
1590+
For more detailed error handling, it is recommended to use the `subroutine` or `function` interfaces.
1591+
1592+
### Example
1593+
1594+
```fortran
1595+
{!example/linalg/example_pseudoinverse.f90!}
1596+
```
1597+
14621598
## `get_norm` - Computes the vector norm of a generic-rank array.
14631599

14641600
### Status

src/stdlib_linalg.fypp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,7 @@ module stdlib_linalg
817817
!! version: experimental
818818
!!
819819
!! Pseudo-inverse of a matrix
820-
!! ([Specification](../page/specs/stdlib_linalg.html#pinv-pseudo-inverse-of-a-matrix))
820+
!! ([Specification](../page/specs/stdlib_linalg.html#pinv-moore-penrose-pseudo-inverse-of-a-matrix))
821821
!!
822822
!!### Summary
823823
!! This interface provides methods for computing the Moore-Penrose pseudo-inverse of a matrix.
@@ -862,7 +862,7 @@ module stdlib_linalg
862862
!! version: experimental
863863
!!
864864
!! Computation of the Moore-Penrose pseudo-inverse
865-
!! ([Specification](../page/specs/stdlib_linalg.html#pseudoinvert-computation-of-a-matrix-pseudo-inverse))
865+
!! ([Specification](../page/specs/stdlib_linalg.html#pseudoinvert-moore-penrose-pseudo-inverse-of-a-matrix))
866866
!!
867867
!!### Summary
868868
!! This interface provides methods for computing the Moore-Penrose pseudo-inverse of a rectangular
@@ -894,7 +894,7 @@ module stdlib_linalg
894894
#:for rk,rt,ri in RC_KINDS_TYPES
895895
module subroutine stdlib_linalg_pseudoinvert_${ri}$(a,pinva,rtol,err)
896896
!> Input matrix a[m,n]
897-
${rt}$, intent(in) :: a(:,:)
897+
${rt}$, intent(inout) :: a(:,:)
898898
!> Output pseudo-inverse matrix [n,m]
899899
${rt}$, intent(out) :: pinva(:,:)
900900
!> [optional] Relative tolerance for singular value cutoff

src/stdlib_linalg_pinv.fypp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ submodule(stdlib_linalg) stdlib_linalg_pseudoinverse
77
use stdlib_linalg_lapack
88
use stdlib_linalg_state
99
use stdlib_linalg, only: svd
10-
use iso_fortran_env,only:real32,real64,real128,int8,int16,int32,int64,stderr => error_unit
10+
use ieee_arithmetic, only: ieee_value, ieee_quiet_nan
1111
implicit none(type,external)
1212

1313
character(*), parameter :: this = 'pseudo-inverse'
@@ -21,8 +21,8 @@ submodule(stdlib_linalg) stdlib_linalg_pseudoinverse
2121
!> Input matrix a[m,n]
2222
${rt}$, intent(inout) :: a(:,:)
2323
!> Output pseudo-inverse matrix
24-
${rt}$, intent(inout) :: pinva(:,:)
25-
!> [optional] ....
24+
${rt}$, intent(out) :: pinva(:,:)
25+
!> [optional] Relative tolerance for singular value cutoff
2626
real(${rk}$), optional, intent(in) :: rtol
2727
!> [optional] state return flag. On error if not requested, the code will stop
2828
type(linalg_state_type), optional, intent(out) :: err
@@ -89,7 +89,7 @@ submodule(stdlib_linalg) stdlib_linalg_pseudoinverse
8989
module function stdlib_linalg_pseudoinverse_${ri}$(a,rtol,err) result(pinva)
9090
!> Input matrix a[m,n]
9191
${rt}$, intent(in), target :: a(:,:)
92-
!> [optional] ....
92+
!> [optional] Relative tolerance for singular value cutoff
9393
real(${rk}$), optional, intent(in) :: rtol
9494
!> [optional] state return flag. On error if not requested, the code will stop
9595
type(linalg_state_type), optional, intent(out) :: err
@@ -108,7 +108,7 @@ submodule(stdlib_linalg) stdlib_linalg_pseudoinverse
108108
module function stdlib_linalg_pinv_${ri}$_operator(a) result(pinva)
109109
!> Input matrix a[m,n]
110110
${rt}$, intent(in), target :: a(:,:)
111-
!> Result matrix
111+
!> Result pseudo-inverse matrix
112112
${rt}$ :: pinva(size(a,2,kind=ilp),size(a,1,kind=ilp))
113113

114114
type(linalg_state_type) :: err

0 commit comments

Comments
 (0)