Skip to content

Commit 42af7d5

Browse files
authored
Merge pull request #153 from jvdp1/central_moment
Addition of a function to compute the k-th order central moment of an array
2 parents 4327556 + 9ef4330 commit 42af7d5

8 files changed

+1162
-8
lines changed

src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ set(fppFiles
66
stdlib_experimental_optval.fypp
77
stdlib_experimental_stats.fypp
88
stdlib_experimental_stats_mean.fypp
9+
stdlib_experimental_stats_moment.fypp
910
stdlib_experimental_stats_var.fypp
1011
stdlib_experimental_quadrature.fypp
1112
stdlib_experimental_quadrature_trapz.fypp

src/Makefile.manual

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ SRC = f18estop.f90 \
88
stdlib_experimental_quadrature_trapz.f90 \
99
stdlib_experimental_stats.f90 \
1010
stdlib_experimental_stats_mean.f90 \
11+
stdlib_experimental_stats_moment.f90 \
1112
stdlib_experimental_stats_var.f90
1213

1314
LIB = libstdlib.a
@@ -46,6 +47,10 @@ stdlib_experimental_stats_mean.o: \
4647
stdlib_experimental_optval.o \
4748
stdlib_experimental_kinds.o \
4849
stdlib_experimental_stats.o
50+
stdlib_experimental_stats_moment.o: \
51+
stdlib_experimental_optval.o \
52+
stdlib_experimental_kinds.o \
53+
stdlib_experimental_stats.o
4954
stdlib_experimental_stats_var.o: \
5055
stdlib_experimental_optval.o \
5156
stdlib_experimental_kinds.o \
@@ -56,4 +61,5 @@ stdlib_experimental_io.f90: stdlib_experimental_io.fypp
5661
stdlib_experimental_quadrature.f90: stdlib_experimental_quadrature.fypp
5762
stdlib_experimental_stats.f90: stdlib_experimental_stats.fypp
5863
stdlib_experimental_stats_mean.f90: stdlib_experimental_stats_mean.fypp
64+
stdlib_experimental_stats_moment.f90: stdlib_experimental_stats_moment.fypp
5965
stdlib_experimental_stats_var.f90: stdlib_experimental_stats_var.fypp

src/stdlib_experimental_stats.fypp

+102-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module stdlib_experimental_stats
77
implicit none
88
private
99
! Public API
10-
public :: mean, var
10+
public :: mean, moment, var
1111

1212
interface mean
1313
#:for k1, t1 in RC_KINDS_TYPES
@@ -209,5 +209,106 @@ module stdlib_experimental_stats
209209

210210
end interface var
211211

212+
interface moment
213+
#:for k1, t1 in RC_KINDS_TYPES
214+
#:for rank in RANKS
215+
#:set RName = rname("moment_all",rank, t1, k1)
216+
module function ${RName}$(x, order, mask) result(res)
217+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
218+
integer, intent(in) :: order
219+
logical, intent(in), optional :: mask
220+
${t1}$ :: res
221+
end function ${RName}$
222+
#:endfor
223+
#:endfor
224+
225+
#:for k1, t1 in INT_KINDS_TYPES
226+
#:for rank in RANKS
227+
#:set RName = rname("moment_all",rank, t1, k1, 'dp')
228+
module function ${RName}$(x, order, mask) result(res)
229+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
230+
integer, intent(in) :: order
231+
logical, intent(in), optional :: mask
232+
real(dp) :: res
233+
end function ${RName}$
234+
#:endfor
235+
#:endfor
236+
237+
#:for k1, t1 in RC_KINDS_TYPES
238+
#:for rank in RANKS
239+
#:set RName = rname("moment",rank, t1, k1)
240+
module function ${RName}$(x, order, dim, mask) result(res)
241+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
242+
integer, intent(in) :: order
243+
integer, intent(in) :: dim
244+
logical, intent(in), optional :: mask
245+
${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
246+
end function ${RName}$
247+
#:endfor
248+
#:endfor
249+
250+
#:for k1, t1 in INT_KINDS_TYPES
251+
#:for rank in RANKS
252+
#:set RName = rname("moment",rank, t1, k1, 'dp')
253+
module function ${RName}$(x, order, dim, mask) result(res)
254+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
255+
integer, intent(in) :: order
256+
integer, intent(in) :: dim
257+
logical, intent(in), optional :: mask
258+
real(dp) :: res${reduced_shape('x', rank, 'dim')}$
259+
end function ${RName}$
260+
#:endfor
261+
#:endfor
262+
263+
#:for k1, t1 in RC_KINDS_TYPES
264+
#:for rank in RANKS
265+
#:set RName = rname("moment_mask_all",rank, t1, k1)
266+
module function ${RName}$(x, order, mask) result(res)
267+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
268+
integer, intent(in) :: order
269+
logical, intent(in) :: mask${ranksuffix(rank)}$
270+
${t1}$ :: res
271+
end function ${RName}$
272+
#:endfor
273+
#:endfor
274+
275+
#:for k1, t1 in INT_KINDS_TYPES
276+
#:for rank in RANKS
277+
#:set RName = rname("moment_mask_all",rank, t1, k1, 'dp')
278+
module function ${RName}$(x, order, mask) result(res)
279+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
280+
integer, intent(in) :: order
281+
logical, intent(in) :: mask${ranksuffix(rank)}$
282+
real(dp) :: res
283+
end function ${RName}$
284+
#:endfor
285+
#:endfor
286+
287+
#:for k1, t1 in RC_KINDS_TYPES
288+
#:for rank in RANKS
289+
#:set RName = rname("moment_mask",rank, t1, k1)
290+
module function ${RName}$(x, order, dim, mask) result(res)
291+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
292+
integer, intent(in) :: order
293+
integer, intent(in) :: dim
294+
logical, intent(in) :: mask${ranksuffix(rank)}$
295+
${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
296+
end function ${RName}$
297+
#:endfor
298+
#:endfor
299+
300+
#:for k1, t1 in INT_KINDS_TYPES
301+
#:for rank in RANKS
302+
#:set RName = rname("moment_mask",rank, t1, k1, 'dp')
303+
module function ${RName}$(x, order, dim, mask) result(res)
304+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
305+
integer, intent(in) :: order
306+
integer, intent(in) :: dim
307+
logical, intent(in) :: mask${ranksuffix(rank)}$
308+
real(dp) :: res${reduced_shape('x', rank, 'dim')}$
309+
end function ${RName}$
310+
#:endfor
311+
#:endfor
312+
end interface moment
212313

213314
end module stdlib_experimental_stats

src/stdlib_experimental_stats.md

+80-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
11
# Descriptive statistics
22

3-
## Implemented
43

5-
* `mean`
6-
* `var`
4+
## Implemented
5+
<!-- vim-markdown-toc GFM -->
6+
7+
* [`mean` - mean of array elements](#mean---mean-of-array-elements)
8+
* [Description](#description)
9+
* [Syntax](#syntax)
10+
* [Arguments](#arguments)
11+
* [Return value](#return-value)
12+
* [Example](#example)
13+
* [`moment` - central moment of array elements](#moment---central-moment-of-array-elements)
14+
* [Description](#description-1)
15+
* [Syntax](#syntax-1)
16+
* [Arguments](#arguments-1)
17+
* [Return value](#return-value-1)
18+
* [Example](#example-1)
19+
* [`var` - variance of array elements](#var---variance-of-array-elements)
20+
* [Description](#description-2)
21+
* [Syntax](#syntax-2)
22+
* [Arguments](#arguments-2)
23+
* [Return value](#return-value-2)
24+
* [Example](#example-2)
25+
26+
<!-- vim-markdown-toc -->
727

828
## `mean` - mean of array elements
929

@@ -28,7 +48,7 @@ Returns the mean of all the elements of `array`, or of the elements of `array` a
2848
### Return value
2949

3050
If `array` is of type `real` or `complex`, the result is of the same type as `array`.
31-
If `array` is of type `integer`, the result is of type `double precision`.
51+
If `array` is of type `integer`, the result is of type `real(dp)`.
3252

3353
If `dim` is absent, a scalar with the mean of all elements in `array` is returned. Otherwise, an array of rank n-1, where n equals the rank of `array`, and a shape similar to that of `array` with dimension `dim` dropped is returned.
3454

@@ -49,6 +69,60 @@ program demo_mean
4969
end program demo_mean
5070
```
5171

72+
## `moment` - central moment of array elements
73+
74+
### Description
75+
76+
Returns the _k_-th order central moment of all the elements of `array`, or of the elements of `array` along dimension `dim` if provided, and if the corresponding element in `mask` is `true`.
77+
78+
The _k_-th order central moment is defined as :
79+
80+
```
81+
moment(array) = 1/n sum_i (array(i) - mean(array))^k
82+
```
83+
84+
where n is the number of elements.
85+
86+
### Syntax
87+
88+
`result = moment(array, order [, mask])`
89+
90+
`result = moment(array, order, dim [, mask])`
91+
92+
### Arguments
93+
94+
`array`: Shall be an array of type `integer`, `real`, or `complex`.
95+
96+
`order`: Shall be an scalar of type `integer`.
97+
98+
`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`.
99+
100+
`mask` (optional): Shall be of type `logical` and either by a scalar or an array of the same shape as `array`.
101+
102+
### Return value
103+
104+
If `array` is of type `real` or `complex`, the result is of the same type as `array`.
105+
If `array` is of type `integer`, the result is of type `real(dp)`.
106+
107+
If `dim` is absent, a scalar with the _k_-th central moment of all elements in `array` is returned. Otherwise, an array of rank n-1, where n equals the rank of `array`, and a shape similar to that of `array` with dimension `dim` dropped is returned.
108+
109+
If `mask` is specified, the result is the _k_-th central moment of all elements of `array` corresponding to `true` elements of `mask`. If every element of `mask` is `false`, the result is IEEE `NaN`.
110+
111+
### Example
112+
113+
```fortran
114+
program demo_moment
115+
use stdlib_experimental_stats, only: moment
116+
implicit none
117+
real :: x(1:6) = [ 1., 2., 3., 4., 5., 6. ]
118+
print *, moment(x, 2) !returns 2.9167
119+
print *, moment( reshape(x, [ 2, 3 ] ), 2) !returns 2.9167
120+
print *, moment( reshape(x, [ 2, 3 ] ), 2, 1) !returns [0.25, 0.25, 0.25]
121+
print *, moment( reshape(x, [ 2, 3 ] ), 2, 1,&
122+
reshape(x, [ 2, 3 ] ) > 3.) !returns [NaN, 0., 0.25]
123+
end program demo_moment
124+
```
125+
52126
## `var` - variance of array elements
53127

54128
### Description
@@ -58,7 +132,7 @@ Returns the variance of all the elements of `array`, or of the elements of `arra
58132
Per default, the variance is defined as the best unbiased estimator and is computed as:
59133

60134
```
61-
var(x) = 1/(n-1) sum_i (array(i) - mean(array))^2
135+
var(array) = 1/(n-1) sum_i (array(i) - mean(array))^2
62136
```
63137

64138
where n is the number of elements.
@@ -108,7 +182,7 @@ program demo_var
108182
reshape(x, [ 2, 3 ] ) > 3.) !returns [NaN, NaN, 0.5]
109183
print *, var( reshape(x, [ 2, 3 ] ), 1,&
110184
reshape(x, [ 2, 3 ] ) > 3.,&
111-
corrected=.false.) !returns [NaN, 0., 0.5]
185+
corrected=.false.) !returns [NaN, 0., 0.25]
112186
end program demo_var
113187
```
114188

0 commit comments

Comments
 (0)