Skip to content

Commit 4fbb208

Browse files
authored
Merge pull request fortran-lang#191 from jvdp1/corr
Pearson correlation among elements of an array
2 parents a1b9a91 + c833cbc commit 4fbb208

6 files changed

+844
-6
lines changed

doc/specs/stdlib_experimental_stats.md

+48-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,54 @@ title: experimental_stats
66

77
[TOC]
88

9+
## `corr` - Pearson correlation of array elements
10+
11+
### Description
12+
13+
Returns the Pearson correlation of the elements of `array` along dimension `dim` if the corresponding element in `mask` is `true`.
14+
15+
The Pearson correlation between two rows (or columns), say `x` and `y`, of `array` is defined as:
16+
17+
```
18+
corr(x, y) = cov(x, y) / sqrt( var(x) * var(y))
19+
```
20+
21+
### Syntax
22+
23+
`result = [[stdlib_experimental_stats(module):corr(interface)]](array, dim [, mask])`
24+
25+
### Arguments
26+
27+
`array`: Shall be a rank-1 or a rank-2 array of type `integer`, `real`, or `complex`.
28+
29+
`dim`: Shall be a scalar of type `integer` with a value in the range from 1 to `n`, where `n` is the rank of `array`.
30+
31+
`mask` (optional): Shall be of type `logical` and either a scalar or an array of the same shape as `array`.
32+
33+
### Return value
34+
35+
If `array` is of rank 1 and of type `real` or `complex`, the result is of type `real` and has the same kind as `array`.
36+
If `array` is of rank 2 and of type `real` or `complex`, the result is of the same type and kind as `array`.
37+
If `array` is of type `integer`, the result is of type `real(dp)`.
38+
39+
If `array` is of rank 1 and of size larger than 1, a scalar equal to 1 is returned. Otherwise, IEEE `NaN` is returned.
40+
If `array` is of rank 2, a rank-2 array with the corresponding correlations is returned.
41+
42+
If `mask` is specified, the result is the Pearson correlation of all elements of `array` corresponding to `true` elements of `mask`. If every element of `mask` is `false`, the result is IEEE `NaN`.
43+
44+
### Example
45+
46+
```fortran
47+
program demo_corr
48+
use stdlib_experimental_stats, only: corr
49+
implicit none
50+
real :: x(1:6) = [ 1., 2., 3., 4., 5., 6. ]
51+
real :: y(1:2, 1:3) = reshape([ -1., 40., -3., 4., 10., 6. ], [ 2, 3])
52+
print *, corr(x, 1) !returns 1.
53+
print *, corr(y, 2) !returns reshape([ 1., -.32480, -.32480, 1. ], [ 2, 3])
54+
end program demo_corr
55+
```
56+
957
## `cov` - covariance of array elements
1058

1159
### Description
@@ -233,4 +281,3 @@ program demo_var
233281
print *, var(y, 1, y > 3., corrected=.false.) !returns [NaN, 0., 0.25]
234282
end program demo_var
235283
```
236-

src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set(fppFiles
77
stdlib_experimental_linalg_diag.fypp
88
stdlib_experimental_optval.fypp
99
stdlib_experimental_stats.fypp
10+
stdlib_experimental_stats_corr.fypp
1011
stdlib_experimental_stats_cov.fypp
1112
stdlib_experimental_stats_mean.fypp
1213
stdlib_experimental_stats_moment.fypp

src/stdlib_experimental_stats.fypp

+96-5
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,102 @@ module stdlib_experimental_stats
1111
implicit none
1212
private
1313
! Public API
14-
public :: cov, mean, moment, var
14+
public :: corr, cov, mean, moment, var
15+
16+
17+
interface corr
18+
!! Pearson correlation of array elements
19+
!! ([Specification](../page/specs/stdlib_experimental_stats.html#description))
20+
#:for k1, t1 in RC_KINDS_TYPES
21+
#:set RName = rname("corr",1, t1, k1)
22+
module function ${RName}$(x, dim, mask) result(res)
23+
${t1}$, intent(in) :: x(:)
24+
integer, intent(in) :: dim
25+
logical, intent(in), optional :: mask
26+
real(${k1}$) :: res
27+
end function ${RName}$
28+
#:endfor
29+
30+
#:for k1, t1 in INT_KINDS_TYPES
31+
#:set RName = rname("corr",1, t1, k1, 'dp')
32+
module function ${RName}$(x, dim, mask) result(res)
33+
${t1}$, intent(in) :: x(:)
34+
integer, intent(in) :: dim
35+
logical, intent(in), optional :: mask
36+
real(dp) :: res
37+
end function ${RName}$
38+
#:endfor
39+
40+
#:for k1, t1 in RC_KINDS_TYPES
41+
#:set RName = rname("corr_mask",1, t1, k1)
42+
module function ${RName}$(x, dim, mask) result(res)
43+
${t1}$, intent(in) :: x(:)
44+
integer, intent(in) :: dim
45+
logical, intent(in) :: mask(:)
46+
real(${k1}$) :: res
47+
end function ${RName}$
48+
#:endfor
49+
50+
#:for k1, t1 in INT_KINDS_TYPES
51+
#:set RName = rname("corr_mask",1, t1, k1, 'dp')
52+
module function ${RName}$(x, dim, mask) result(res)
53+
${t1}$, intent(in) :: x(:)
54+
integer, intent(in) :: dim
55+
logical, intent(in) :: mask(:)
56+
real(dp) :: res
57+
end function ${RName}$
58+
#:endfor
59+
60+
#:for k1, t1 in RC_KINDS_TYPES
61+
#:set RName = rname("corr",2, t1, k1)
62+
module function ${RName}$(x, dim, mask) result(res)
63+
${t1}$, intent(in) :: x(:, :)
64+
integer, intent(in) :: dim
65+
logical, intent(in), optional :: mask
66+
${t1}$ :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
67+
, merge(size(x, 1), size(x, 2), mask = 1<dim))
68+
end function ${RName}$
69+
#:endfor
70+
71+
#:for k1, t1 in INT_KINDS_TYPES
72+
#:set RName = rname("corr",2, t1, k1, 'dp')
73+
module function ${RName}$(x, dim, mask) result(res)
74+
${t1}$, intent(in) :: x(:, :)
75+
integer, intent(in) :: dim
76+
logical, intent(in), optional :: mask
77+
real(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
78+
, merge(size(x, 1), size(x, 2), mask = 1<dim))
79+
end function ${RName}$
80+
#:endfor
81+
82+
#:for k1, t1 in RC_KINDS_TYPES
83+
#:set RName = rname("corr_mask",2, t1, k1)
84+
module function ${RName}$(x, dim, mask) result(res)
85+
${t1}$, intent(in) :: x(:, :)
86+
integer, intent(in) :: dim
87+
logical, intent(in) :: mask(:,:)
88+
${t1}$ :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
89+
, merge(size(x, 1), size(x, 2), mask = 1<dim))
90+
end function ${RName}$
91+
#:endfor
92+
93+
#:for k1, t1 in INT_KINDS_TYPES
94+
#:set RName = rname("corr_mask",2, t1, k1, 'dp')
95+
module function ${RName}$(x, dim, mask) result(res)
96+
${t1}$, intent(in) :: x(:, :)
97+
integer, intent(in) :: dim
98+
logical, intent(in) :: mask(:,:)
99+
real(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
100+
, merge(size(x, 1), size(x, 2), mask = 1<dim))
101+
end function ${RName}$
102+
#:endfor
103+
104+
end interface corr
105+
15106

16107
interface cov
17108
!! Covariance of array elements
18-
!! ([Specification](../page/specs/stdlib_experimental_stats.html#description))
109+
!! ([Specification](../page/specs/stdlib_experimental_stats.html#description_1))
19110
#:for k1, t1 in RC_KINDS_TYPES
20111
#:set RName = rname("cov",1, t1, k1)
21112
module function ${RName}$(x, dim, mask, corrected) result(res)
@@ -112,7 +203,7 @@ module stdlib_experimental_stats
112203

113204
interface mean
114205
!! Mean of array elements
115-
!! ([Specification](../page/specs/stdlib_experimental_stats.html#description_1))
206+
!! ([Specification](../page/specs/stdlib_experimental_stats.html#description_2))
116207
#:for k1, t1 in RC_KINDS_TYPES
117208
#:for rank in RANKS
118209
#:set RName = rname("mean_all",rank, t1, k1)
@@ -210,7 +301,7 @@ module stdlib_experimental_stats
210301

211302
interface var
212303
!! Variance of array elements
213-
!! ([Specification](../page/specs/stdlib_experimental_stats.html#description_3))
304+
!! ([Specification](../page/specs/stdlib_experimental_stats.html#description_4))
214305

215306
#:for k1, t1 in RC_KINDS_TYPES
216307
#:for rank in RANKS
@@ -317,7 +408,7 @@ module stdlib_experimental_stats
317408

318409
interface moment
319410
!! Central moment of array elements
320-
!! ([Specification](../page/specs/stdlib_experimental_stats.html#description_2))
411+
!! ([Specification](../page/specs/stdlib_experimental_stats.html#description_3))
321412
#:for k1, t1 in RC_KINDS_TYPES
322413
#:for rank in RANKS
323414
#:set RName = rname("moment_all",rank, t1, k1)

0 commit comments

Comments
 (0)