Skip to content

Commit e966e7b

Browse files
committed
addition of variance
1 parent 71c30d1 commit e966e7b

9 files changed

+804
-3
lines changed

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
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_var.fypp
910
)
1011

1112

src/Makefile.manual

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ SRC = stdlib_experimental_ascii.f90 \
55
stdlib_experimental_kinds.f90 \
66
f18estop.f90 \
77
stdlib_experimental_stats.f90 \
8-
stdlib_experimental_stats_mean.f90
8+
stdlib_experimental_stats_mean.f90 \
9+
stdlib_experimental_stats_var.f90
910

1011
LIB = libstdlib.a
1112

@@ -42,6 +43,11 @@ stdlib_experimental_stats_mean.o: \
4243
stdlib_experimental_optval.o \
4344
stdlib_experimental_kinds.o \
4445
stdlib_experimental_stats.o
46+
stdlib_experimental_stats_var.o: \
47+
stdlib_experimental_optval.o \
48+
stdlib_experimental_kinds.o \
49+
stdlib_experimental_stats.o
4550
stdlib_experimental_io.f90: stdlib_experimental_io.fypp
4651
stdlib_experimental_stats.f90: stdlib_experimental_stats.fypp
4752
stdlib_experimental_stats_mean.f90: stdlib_experimental_stats_mean.fypp
53+
stdlib_experimental_stats_var.f90: stdlib_experimental_stats_var.fypp

src/common.fypp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,19 @@ ${prefix + joinstr.join([line.strip() for line in txt.split("\n")]) + suffix}$
113113
$:"{0}_{1}_{2}{3}_{2}{3}".format(gname, rank, type[0], kind) if suffix == '' else "{0}_{1}_{2}{3}_{4}".format(gname, rank, type[0], kind, suffix)
114114
#:enddef
115115

116+
#:def rankindice(varname, varname1, origrank, dim)
117+
#:assert origrank > 0
118+
#:if origrank > 0
119+
#:call join_lines(joinstr=", ", prefix="(", suffix=")")
120+
#:for i in range(1, origrank+1)
121+
#:if i == dim
122+
${varname1}$
123+
#:else
124+
${varname}$
125+
#:endif
126+
#:endfor
127+
#:endcall
128+
#:endif
129+
#:enddef
130+
116131
#:endmute

src/stdlib_experimental_stats.fypp

Lines changed: 95 additions & 1 deletion
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
10+
public :: mean, var
1111

1212
interface mean
1313
#:for k1, t1 in RC_KINDS_TYPES
@@ -104,4 +104,98 @@ module stdlib_experimental_stats
104104

105105
end interface mean
106106

107+
108+
interface var
109+
110+
#:for k1, t1 in REAL_KINDS_TYPES
111+
#:for rank in RANKS
112+
module function var_${rank}$_all_${k1}$_${k1}$(x, mask) result(res)
113+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
114+
logical, intent(in), optional :: mask
115+
${t1}$ :: res
116+
end function var_${rank}$_all_${k1}$_${k1}$
117+
#:endfor
118+
#:endfor
119+
120+
#:for k1, t1 in INT_KINDS_TYPES
121+
#:for rank in RANKS
122+
module function var_${rank}$_all_${k1}$_dp(x, mask) result(res)
123+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
124+
logical, intent(in), optional :: mask
125+
real(dp) :: res
126+
end function var_${rank}$_all_${k1}$_dp
127+
#:endfor
128+
#:endfor
129+
130+
#:for k1, t1 in REAL_KINDS_TYPES
131+
#:for rank in RANKS
132+
module function var_${rank}$_${k1}$_${k1}$(x, dim, mask) result(res)
133+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
134+
integer, intent(in) :: dim
135+
logical, intent(in), optional :: mask
136+
${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
137+
end function var_${rank}$_${k1}$_${k1}$
138+
#:endfor
139+
#:endfor
140+
141+
#:for k1, t1 in INT_KINDS_TYPES
142+
#:for rank in RANKS
143+
module function var_${rank}$_${k1}$_dp(x, dim, mask) result(res)
144+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
145+
integer, intent(in) :: dim
146+
logical, intent(in), optional :: mask
147+
real(dp) :: res${reduced_shape('x', rank, 'dim')}$
148+
end function var_${rank}$_${k1}$_dp
149+
#:endfor
150+
#:endfor
151+
152+
153+
#:for k1, t1 in REAL_KINDS_TYPES
154+
#:for rank in RANKS
155+
module function var_${rank}$_mask_all_${k1}$_${k1}$(x, mask) result(res)
156+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
157+
logical, intent(in) :: mask${ranksuffix(rank)}$
158+
${t1}$ :: res
159+
end function var_${rank}$_mask_all_${k1}$_${k1}$
160+
#:endfor
161+
#:endfor
162+
163+
164+
#:for k1, t1 in INT_KINDS_TYPES
165+
#:for rank in RANKS
166+
module function var_${rank}$_mask_all_${k1}$_dp(x, mask) result(res)
167+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
168+
logical, intent(in) :: mask${ranksuffix(rank)}$
169+
real(dp) :: res
170+
end function var_${rank}$_mask_all_${k1}$_dp
171+
#:endfor
172+
#:endfor
173+
174+
175+
#:for k1, t1 in REAL_KINDS_TYPES
176+
#:for rank in RANKS
177+
module function var_${rank}$_mask_${k1}$_${k1}$(x, dim, mask) result(res)
178+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
179+
integer, intent(in) :: dim
180+
logical, intent(in) :: mask${ranksuffix(rank)}$
181+
${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
182+
end function var_${rank}$_mask_${k1}$_${k1}$
183+
#:endfor
184+
#:endfor
185+
186+
187+
#:for k1, t1 in INT_KINDS_TYPES
188+
#:for rank in RANKS
189+
module function var_${rank}$_mask_${k1}$_dp(x, dim, mask) result(res)
190+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
191+
integer, intent(in) :: dim
192+
logical, intent(in) :: mask${ranksuffix(rank)}$
193+
real(dp) :: res${reduced_shape('x', rank, 'dim')}$
194+
end function var_${rank}$_mask_${k1}$_dp
195+
#:endfor
196+
#:endfor
197+
198+
end interface var
199+
200+
107201
end module stdlib_experimental_stats

src/stdlib_experimental_stats.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Implemented
44

55
* `mean`
6+
* `var`
67

78
## `mean` - mean of array elements
89

@@ -47,3 +48,55 @@ program demo_mean
4748
reshape(x, [ 2, 3 ] ) > 3.) !returns [ NaN, 4.0, 5.5 ]
4849
end program demo_mean
4950
```
51+
52+
## `var` - variance of array elements
53+
54+
### Description
55+
56+
Returns the variance 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`.
57+
58+
The variance is defined as the best unbiased estimator and is computed as:
59+
60+
```
61+
var(x) = 1/(n-1) sum_i (array(i) - mean(array))^2
62+
```
63+
64+
### Syntax
65+
66+
`result = var(array [, mask])`
67+
68+
`result = var(array, dim [, mask])`
69+
70+
### Arguments
71+
72+
`array`: Shall be an array of type `integer`, or `real`.
73+
74+
`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`.
75+
76+
`mask` (optional): Shall be of type `logical` and either by a scalar or an array of the same shape as `array`.
77+
78+
### Return value
79+
80+
If `array` is of type `real`, the result is of the same type as `array`.
81+
If `array` is of type `integer`, the result is of type `double precision`.
82+
83+
If `dim` is absent, a scalar with the variance 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 `ar
84+
ray` with dimension `dim` dropped is returned.
85+
86+
If `mask` is specified, the result is the variance of all elements of `array` corresponding to `true` elements of `mask`. If every element of `mask` is `false`, the result is IEEE `NaN`.
87+
88+
### Example
89+
90+
```fortran
91+
program demo_var
92+
use stdlib_experimental_stats, only: var
93+
implicit none
94+
real :: x(1:6) = [ 1., 2., 3., 4., 5., 6. ]
95+
print *, var(x) !returns 3.5
96+
print *, var( reshape(x, [ 2, 3 ] )) !returns 3.5
97+
print *, var( reshape(x, [ 2, 3 ] ), 1) !returns [0.5, 0.5, 0.5]
98+
print *, var( reshape(x, [ 2, 3 ] ), 1,&
99+
reshape(x, [ 2, 3 ] ) > 3.) !returns [0., NaN, 0.5]
100+
end program demo_var
101+
```
102+

0 commit comments

Comments
 (0)