Skip to content

Commit de38699

Browse files
authored
Merge pull request #161 from jvdp1/raw_moment_dev
Addition of optional center in API of moment()
2 parents c8c0a98 + 20f5098 commit de38699

6 files changed

+1096
-232
lines changed

src/stdlib_experimental_stats.fypp

+73-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#:include "common.fypp"
22
#:set RANKS = range(1, MAXRANK + 1)
3+
#:set REDRANKS = range(2, MAXRANK + 1)
34
#:set RC_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES
45
module stdlib_experimental_stats
56
use stdlib_experimental_kinds, only: sp, dp, qp, &
@@ -213,9 +214,10 @@ module stdlib_experimental_stats
213214
#:for k1, t1 in RC_KINDS_TYPES
214215
#:for rank in RANKS
215216
#:set RName = rname("moment_all",rank, t1, k1)
216-
module function ${RName}$(x, order, mask) result(res)
217+
module function ${RName}$(x, order, center, mask) result(res)
217218
${t1}$, intent(in) :: x${ranksuffix(rank)}$
218219
integer, intent(in) :: order
220+
${t1}$, intent(in), optional :: center
219221
logical, intent(in), optional :: mask
220222
${t1}$ :: res
221223
end function ${RName}$
@@ -225,35 +227,66 @@ module stdlib_experimental_stats
225227
#:for k1, t1 in INT_KINDS_TYPES
226228
#:for rank in RANKS
227229
#:set RName = rname("moment_all",rank, t1, k1, 'dp')
228-
module function ${RName}$(x, order, mask) result(res)
230+
module function ${RName}$(x, order, center, mask) result(res)
229231
${t1}$, intent(in) :: x${ranksuffix(rank)}$
230232
integer, intent(in) :: order
233+
real(dp), intent(in), optional :: center
231234
logical, intent(in), optional :: mask
232235
real(dp) :: res
233236
end function ${RName}$
234237
#:endfor
235238
#:endfor
236239

240+
#:for k1, t1 in RC_KINDS_TYPES
241+
#:for rank in REDRANKS
242+
#:set RName = rname("moment_scalar",rank, t1, k1)
243+
module function ${RName}$(x, order, dim, center, mask) result(res)
244+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
245+
integer, intent(in) :: order
246+
integer, intent(in) :: dim
247+
${t1}$, intent(in) :: center
248+
logical, intent(in), optional :: mask
249+
${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
250+
end function ${RName}$
251+
#:endfor
252+
#:endfor
253+
237254
#:for k1, t1 in RC_KINDS_TYPES
238255
#:for rank in RANKS
239256
#:set RName = rname("moment",rank, t1, k1)
240-
module function ${RName}$(x, order, dim, mask) result(res)
257+
module function ${RName}$(x, order, dim, center, mask) result(res)
241258
${t1}$, intent(in) :: x${ranksuffix(rank)}$
242259
integer, intent(in) :: order
243260
integer, intent(in) :: dim
261+
${t1}$, intent(in), optional :: center${reduced_shape('x', rank, 'dim')}$
244262
logical, intent(in), optional :: mask
245263
${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
246264
end function ${RName}$
247265
#:endfor
248266
#:endfor
249267

268+
#:for k1, t1 in INT_KINDS_TYPES
269+
#:for rank in REDRANKS
270+
#:set RName = rname("moment_scalar",rank, t1, k1, 'dp')
271+
module function ${RName}$(x, order, dim, center, mask) result(res)
272+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
273+
integer, intent(in) :: order
274+
integer, intent(in) :: dim
275+
real(dp),intent(in) :: center
276+
logical, intent(in), optional :: mask
277+
real(dp) :: res${reduced_shape('x', rank, 'dim')}$
278+
end function ${RName}$
279+
#:endfor
280+
#:endfor
281+
250282
#:for k1, t1 in INT_KINDS_TYPES
251283
#:for rank in RANKS
252284
#:set RName = rname("moment",rank, t1, k1, 'dp')
253-
module function ${RName}$(x, order, dim, mask) result(res)
285+
module function ${RName}$(x, order, dim, center, mask) result(res)
254286
${t1}$, intent(in) :: x${ranksuffix(rank)}$
255287
integer, intent(in) :: order
256288
integer, intent(in) :: dim
289+
real(dp),intent(in), optional :: center${reduced_shape('x', rank, 'dim')}$
257290
logical, intent(in), optional :: mask
258291
real(dp) :: res${reduced_shape('x', rank, 'dim')}$
259292
end function ${RName}$
@@ -263,9 +296,10 @@ module stdlib_experimental_stats
263296
#:for k1, t1 in RC_KINDS_TYPES
264297
#:for rank in RANKS
265298
#:set RName = rname("moment_mask_all",rank, t1, k1)
266-
module function ${RName}$(x, order, mask) result(res)
299+
module function ${RName}$(x, order, center, mask) result(res)
267300
${t1}$, intent(in) :: x${ranksuffix(rank)}$
268301
integer, intent(in) :: order
302+
${t1}$, intent(in), optional :: center
269303
logical, intent(in) :: mask${ranksuffix(rank)}$
270304
${t1}$ :: res
271305
end function ${RName}$
@@ -275,35 +309,66 @@ module stdlib_experimental_stats
275309
#:for k1, t1 in INT_KINDS_TYPES
276310
#:for rank in RANKS
277311
#:set RName = rname("moment_mask_all",rank, t1, k1, 'dp')
278-
module function ${RName}$(x, order, mask) result(res)
312+
module function ${RName}$(x, order, center, mask) result(res)
279313
${t1}$, intent(in) :: x${ranksuffix(rank)}$
280314
integer, intent(in) :: order
315+
real(dp),intent(in), optional :: center
281316
logical, intent(in) :: mask${ranksuffix(rank)}$
282317
real(dp) :: res
283318
end function ${RName}$
284319
#:endfor
285320
#:endfor
286321

322+
#:for k1, t1 in RC_KINDS_TYPES
323+
#:for rank in REDRANKS
324+
#:set RName = rname("moment_mask_scalar",rank, t1, k1)
325+
module function ${RName}$(x, order, dim, center, mask) result(res)
326+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
327+
integer, intent(in) :: order
328+
integer, intent(in) :: dim
329+
${t1}$, intent(in) :: center
330+
logical, intent(in) :: mask${ranksuffix(rank)}$
331+
${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
332+
end function ${RName}$
333+
#:endfor
334+
#:endfor
335+
287336
#:for k1, t1 in RC_KINDS_TYPES
288337
#:for rank in RANKS
289338
#:set RName = rname("moment_mask",rank, t1, k1)
290-
module function ${RName}$(x, order, dim, mask) result(res)
339+
module function ${RName}$(x, order, dim, center, mask) result(res)
291340
${t1}$, intent(in) :: x${ranksuffix(rank)}$
292341
integer, intent(in) :: order
293342
integer, intent(in) :: dim
343+
${t1}$, intent(in), optional :: center${reduced_shape('x', rank, 'dim')}$
294344
logical, intent(in) :: mask${ranksuffix(rank)}$
295345
${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
296346
end function ${RName}$
297347
#:endfor
298348
#:endfor
299349

350+
#:for k1, t1 in INT_KINDS_TYPES
351+
#:for rank in REDRANKS
352+
#:set RName = rname("moment_mask_scalar",rank, t1, k1, 'dp')
353+
module function ${RName}$(x, order, dim, center, mask) result(res)
354+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
355+
integer, intent(in) :: order
356+
integer, intent(in) :: dim
357+
real(dp), intent(in) :: center
358+
logical, intent(in) :: mask${ranksuffix(rank)}$
359+
real(dp) :: res${reduced_shape('x', rank, 'dim')}$
360+
end function ${RName}$
361+
#:endfor
362+
#:endfor
363+
300364
#:for k1, t1 in INT_KINDS_TYPES
301365
#:for rank in RANKS
302366
#:set RName = rname("moment_mask",rank, t1, k1, 'dp')
303-
module function ${RName}$(x, order, dim, mask) result(res)
367+
module function ${RName}$(x, order, dim, center, mask) result(res)
304368
${t1}$, intent(in) :: x${ranksuffix(rank)}$
305369
integer, intent(in) :: order
306370
integer, intent(in) :: dim
371+
real(dp), intent(in), optional :: center${reduced_shape('x', rank, 'dim')}$
307372
logical, intent(in) :: mask${ranksuffix(rank)}$
308373
real(dp) :: res${reduced_shape('x', rank, 'dim')}$
309374
end function ${RName}$

src/stdlib_experimental_stats.md

+25-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Descriptive statistics
22

33
* [`mean` - mean of array elements](#mean---mean-of-array-elements)
4-
* [`moment` - central moment of array elements](#moment---central-moment-of-array-elements)
4+
* [`moment` - central moments of array elements](#moment---central-moments-of-array-elements)
55
* [`var` - variance of array elements](#var---variance-of-array-elements)
66

77
## `mean` - mean of array elements
@@ -48,12 +48,15 @@ program demo_mean
4848
end program demo_mean
4949
```
5050

51-
## `moment` - central moment of array elements
51+
## `moment` - central moments of array elements
5252

5353
### Description
5454

5555
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`.
5656

57+
If a scalar or an array `center` is provided, the function returns the _k_-th order moment about 'center', 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`.
58+
59+
5760
The _k_-th order central moment is defined as :
5861

5962
```
@@ -62,11 +65,17 @@ The _k_-th order central moment is defined as :
6265

6366
where n is the number of elements.
6467

68+
The _k_-th order moment about `center` is defined as :
69+
70+
```
71+
moment(array) = 1/n sum_i (array(i) - center)^k
72+
```
73+
6574
### Syntax
6675

67-
`result = moment(array, order [, mask])`
76+
`result = moment(array, order [, center [, mask]])`
6877

69-
`result = moment(array, order, dim [, mask])`
78+
`result = moment(array, order, dim [, center [, mask]])`
7079

7180
### Arguments
7281

@@ -76,29 +85,33 @@ where n is the number of elements.
7685

7786
`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`.
7887

88+
`center` (optional): Shall be a scalar of the same type of `result` if `dim` is not provided. If `dim` is provided, `center` shall be a scalar or an array (with a shape similar to that of `array` with dimension `dim` dropped) of the same type of `result`.
89+
7990
`mask` (optional): Shall be of type `logical` and either by a scalar or an array of the same shape as `array`.
8091

8192
### Return value
8293

8394
If `array` is of type `real` or `complex`, the result is of the same type as `array`.
8495
If `array` is of type `integer`, the result is of type `real(dp)`.
8596

86-
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.
97+
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.
8798

88-
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`.
99+
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`.
89100

90101
### Example
91102

92103
```fortran
93104
program demo_moment
94-
use stdlib_experimental_stats, only: moment
105+
use stdlib_experimental_stats, only: mean, moment
95106
implicit none
96107
real :: x(1:6) = [ 1., 2., 3., 4., 5., 6. ]
97-
print *, moment(x, 2) !returns 2.9167
98-
print *, moment( reshape(x, [ 2, 3 ] ), 2) !returns 2.9167
99-
print *, moment( reshape(x, [ 2, 3 ] ), 2, 1) !returns [0.25, 0.25, 0.25]
100-
print *, moment( reshape(x, [ 2, 3 ] ), 2, 1,&
101-
reshape(x, [ 2, 3 ] ) > 3.) !returns [NaN, 0., 0.25]
108+
real :: y(1:2, 1:3) = reshape([ 1., 2., 3., 4., 5., 6. ], [ 2, 3])
109+
print *, moment(x, 2) !returns 2.9167
110+
print *, moment( y, 2) !returns 2.9167
111+
print *, moment( y, 2, 1) !returns [0.25, 0.25, 0.25]
112+
print *, moment( y, 2, 1, mask = (y > 3.)) !returns [NaN, 0., 0.25]
113+
print *, moment(x, 2, center = 0.) !returns 15.1667
114+
print *, moment( y, 1, 1, center = 0.) !returns [1.5, 3.5, 5.5]
102115
end program demo_moment
103116
```
104117

0 commit comments

Comments
 (0)