0.6.2-dev0
FORCES
FORtran lib for Comp. Env. Sys.
Loading...
Searching...
No Matches
mo_moment.f90
Go to the documentation of this file.
1!> \file mo_moment.f90
2!> \brief \copybrief mo_moment
3!> \details \copydetails mo_moment
4
5!> \brief Statistical moments.
6!> \details This module contains routines for the masked calculation of
7!! statistical properties such as moments and mixed moments of input vectors
8!! \note all except variance and standard deviation are population and not sample moments,
9!! i.e. they are normally divided by n and not (n-1)
10!> \par Literature
11!! Central moments and error variances
12!! LH Benedict & RD Gould, Towards better uncertainty estimates for turbulence statistics,
13!! Experiments in Fluids 22, 129-136, 1996
14!> \changelog
15!! - Matthias Cuntz, Nov 2011
16!! - written
17!! - Matthias Cuntz, Dec 2011
18!! - mod. correlation, covariance
19!! - M. Schroen, Sep 2015
20!! - average/mean for single value
21!! - S. Mueller, Dec 2019
22!! - remove citations for common sence
23!> \copyright Copyright 2005-\today, the CHS Developers, Sabine Attinger: All rights reserved.
24!! FORCES is released under the LGPLv3+ license \license_note
26
27 USE mo_kind, ONLY : i4, sp, dp
28
29 IMPLICIT NONE
30
31 PUBLIC :: absdev ! Mean absolute deviation from mean of an array
32 PUBLIC :: average ! 1st moment of an array (same as mean)
33 PUBLIC :: central_moment ! Arbitrary central moment of an array
34 PUBLIC :: central_moment_var ! Central moment error variance
35 PUBLIC :: correlation ! Correlation between two arrays
36 PUBLIC :: covariance ! Covariance between two arrays
37 PUBLIC :: kurtosis ! 4th moment of an array
38 PUBLIC :: mean ! 1st moment of an array
39 PUBLIC :: mixed_central_moment ! Arbitrary mixed central moment
40 PUBLIC :: mixed_central_moment_var ! Arbitrary mixed central moment error variance
41 PUBLIC :: moment ! 1st to 4th moments of an array
42 PUBLIC :: skewness ! 3rd moment of an array
43 PUBLIC :: stddev ! Sqrt of 2nd moment of an array
44 PUBLIC :: variance ! 2nd moment of an array
45
46 ! ------------------------------------------------------------------
47
48 !> \brief Mean absolute deviation from mean.
49
50 !> \details
51 !! Calculates the mean absolute deviations from the mean
52 !!
53 !! \f[ ABSDEV = \sum_i\frac{|x_i-\bar x|}{N} \f]
54 !!
55 !! If an optinal mask is given, the calculations are over those locations that correspond to true values in the mask.
56 !! \f$ x\f$ can be single or double precision. The result will have the same numerical precision.\n
57 !!
58 !! \b Example
59 !!
60 !! vec = (/ 1., 2, 3., -999., 5., 6. /)
61 !! m = absdev(vec, mask=(vec >= 0.))
62 !!
63 !! See also example in pf_tests directory.
64
65
66 !> \param[in] "real(sp/dp) :: dat(:)" 1D-array with input numbers.
67 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with `size(dat)`.
68 !! If present, only those locations in `vec`
69 !! corresponding to the true values in mask are used.
70 !> \retval "real(sp/dp) :: absdev" Mean absolute deviations from average.
71
72 !> \note Input values must be floating points.
73
74 !> \author Matthias Cuntz
75 !> \date Nov 2011
76
77 ! ------------------------------------------------------------------
78
79 INTERFACE absdev
80 MODULE PROCEDURE absdev_sp, absdev_dp
81 END INTERFACE absdev
82
83 ! ------------------------------------------------------------------
84
85 !> \brief Mean of vector.
86
87 !> \details
88 !! Calculates the average value of a vector, i.e. the first moment of a series of numbers:
89 !!
90 !! \f[ AVE = \sum_i \frac{x_i}{N} \f]
91 !!
92 !! If an optional mask is given, the average is only over those locations that correspond to true values in the mask.
93 !! \f$ x\f$ can be single or double precision. The result will have the same numerical precision.
94 !!
95 !! \b Example
96 !!
97 !! vec = (/ 1., 2, 3., -999., 5., 6. /)
98 !! m = average(vec, mask=(vec >= 0.))
99 !! --> m = 3.4
100 !!
101 !! See also example in pf_tests directory.
102
103 !> \param[in] "real(sp/dp) :: dat(:)" 1D-array with input numbers
104
105 !> \retval "real(sp/dp) :: average" Average of all elements in dat
106
107
108 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with `size(dat)`.
109 !! If present, only those locations in dat
110 !! corresponding to the true values in mask are used.
111
112 !> \note Input values must be floating points.
113
114 !> \author Matthias Cuntz
115 !> \date Nov 2011
116
117 ! ------------------------------------------------------------------
118
119 INTERFACE average
120 MODULE PROCEDURE average_sp, average_dp
121 END INTERFACE average
122
123 ! ------------------------------------------------------------------
124
125 !> \brief R-central moment
126
127 !> \details
128 !! Calculates the central moment of a vector, i.e. the r-central moment of a series of numbers:
129 !!
130 !! \f[ \mu_r = \sum_i\frac{(x_i-\bar x)^r}{N} \f]
131 !!
132 !! Note that the variance is the second central moment: `variance(x) = central_moment(x,2)`\n
133 !!
134 !! If an optinal mask is given, the average is only over those locations that correspond to true values in the mask.
135 !! x can be single or double precision. The result will have the same numerical precision.
136 !!
137 !! \b Example
138 !!
139 !! vec = (/ 1., 2, 3., 4., 5., 6. /)
140 !! m = central_moment(vec, 2, mask=(vec >= 0.))
141 !! --> m = 2.91666
142 !!
143 !! See also example in pf_tests directory.
144 !!
145 !> \b Literature
146 !! 1. LH Benedict & RD Gould, _Towards better uncertainty estimates for turbulence statistics_.
147 !! Experiments in Fluids 22, 129-136, 1996
148 !!
149 !> \param[in] "real(sp/dp) :: dat(:)" 1D-array with input numbers.
150 !> \param[in] "integer(i4) :: r" Order of the central moment, i.e. r=2 is variance.
151 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with size(dat).
152 !! If present, only those locations in `dat`
153 !! corresponding to the true values in mask are used.
154 !> \retval "real(sp/dp) :: central_moment" R-th central moment of elements in `dat`.
155
156 !> \note Input values must be floating points.
157
158 !> \author Matthias Cuntz
159 !> \date Nov 2011
160
161 ! ------------------------------------------------------------------
163 MODULE PROCEDURE central_moment_sp, central_moment_dp
164 END INTERFACE central_moment
165
166 ! ------------------------------------------------------------------
167
168 !> \brief R-central moment variance
169
170 !> \details
171 !! Calculates the sampling variance of the central moment of a vector.
172 !! `central_moment_var` is something like the "error variance" of the r-th order central moment sampling statistic.\n
173 !!
174 !! If an optinal mask is given, the average is only over those locations that correspond to true values in the mask.
175 !! \f$x\f$ can be single or double precision. The result will have the same numerical precision.\n
176 !!
177 !! \b Example
178 !!
179 !! vec = (/ 1., 2, 3., -999., 5., 6. /)
180 !! m = central_moment(vec, 2, mask=(vec >= 0.))
181 !! em = central_moment_var(vec, 2, mask=(vec >= 0.))
182 !!
183 !! See also example in pf_tests directory.
184 !!
185 !! \b Literature
186 !! 1. LH Benedict & RD Gould, _Towards better uncertainty estimates for turbulence statistics_,
187 !! Experiments in Fluids 22, 129-136, 1996
188 !!
189 !> \param[in] "real(sp/dp) :: dat(:)" 1D-array with input numbers.
190 !> \param[in] "integer(i4) :: r" Order of the central moment, i.e. r=2 is variance.
191 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with `size(dat)`.
192 !! If present, only those locations in dat
193 !! corresponding to the true values in mask are used.
194 !> \retval "real(sp/dp) :: central_moment_var" Sampling variance of r-th central moment of elements in dat
195
196 !> \note Input values must be floating points.
197
198 !> \author Matthias Cuntz
199 !> \date Nov 2011
201 MODULE PROCEDURE central_moment_var_sp, central_moment_var_dp
202 END INTERFACE central_moment_var
203
204 ! ------------------------------------------------------------------
205
206 !> \brief Correlation between two vectors.
207
208 !> \details
209 !! Calculates the correlation between two input vectors, i.e. the covariance divided by the standard deviations:\n
210 !!
211 !! \f[\langle x y\rangle = \sum_i\frac{(x_i-\bar x)(y_i-\bar y)}{N\sqrt{\mu_2(x)\mu_2(y)}}\f]
212 !!
213 !! If an optinal mask is given, the average is only over those locations that correspond to true values in the mask.
214 !! \f$x\f$ can be single or double precision. The result will have the same numerical precision.
215 !!
216 !! \b Example
217 !!
218 !! vec1 = (/ 1., 2, 3., -999., 5., 6. /)
219 !! vec2 = (/ 1.3, 2.7, 3.9, 5.1, 6., 8. /)
220 !! m = correlation(vec1, vec2, mask=((vec1 >= 0.) .and. (vec2 >= 0.)))
221 !!
222 !! See also example in pf_tests directory.
223
224 !> \param[in] "real(sp/dp) :: x(:)" First 1D-array with input numbers.
225 !> \param[in] "real(sp/dp) :: y(:)" Second 1D-array with input numbers.
226 !> \retval "real(sp/dp) :: correlation" Correlation between \f$x\f$ and \f$y\f$.
227 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with `size(x)`.
228 !! If present, only those locations in dat
229 !! corresponding to the true values in mask are used.
230
231 !> \note Input values must be floating points.
232
233 !> \author Matthias Cuntz
234 !> \date Nov 2011
235 !> \date Dec 2011
236 !! - covariance as <(x-<x>)(y-<y>)> instead of <xy>-<x><y>
237
238 ! ------------------------------------------------------------------
239
240 INTERFACE correlation
241 MODULE PROCEDURE correlation_sp, correlation_dp
242 END INTERFACE correlation
243
244 ! ------------------------------------------------------------------
245
246 !> \brief Covariance between vectors
247
248 !> \details
249 !! Calculates the covariance between two input vectors:\n
250 !!
251 !! \f[Cov(x,y) = \sum_i\frac{(x_i-\bar x)(y_i-\bar y)}{N}\f]
252 !!
253 !! If an optional mask is given, the average is only over those locations that correspond to true values in the mask.
254 !! \f$x\f$ can be single or double precision. The result will have the same numerical precision.
255 !!
256 !! \b Example
257 !!
258 !! vec1 = (/ 1., 2, 3., -999., 5., 6. /)
259 !! vec2 = (/ 1.3, 2.7, 3.9, 5.1, 6., 8. /)
260 !! m = covariance(vec1, vec2, mask=((vec1 >= 0.) .and. (vec2 >= 0.)))
261 !!
262 !! See also example in test directory.
263
264 !> \param[in] "real(sp/dp) :: x(:)" First 1D-array with input numbers.
265 !> \param[in] "real(sp/dp) :: y(:)" Second 1D-array with input numbers.
266 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with size(x).
267 !! If present, only those locations in dat
268 !! corresponding to the true values in mask are used.
269 !> \retval "real(sp/dp) :: covariance" Covariance between x and y.
270
271 !> \note Input values must be floating points.
272
273 !> \author Matthias Cuntz
274 !> \date Nov 2011
275 !> \date Dec 2011
276 !! - covariance as <(x-<x>)(y-<y>)> instead of <xy>-<x><y>
277
278 ! ------------------------------------------------------------------
279
280 INTERFACE covariance
281 MODULE PROCEDURE covariance_sp, covariance_dp
282 END INTERFACE covariance
283
284 ! ------------------------------------------------------------------
285
286 !> \brief Kurtosis of a vector.
287
288 !> \details
289 !! Calculates the kurtosis of a vector, also called excess kurtosis:
290 !!
291 !! \f[ Kurt(x) = \verb|central_moment(x,4) / variance(x)**2 - 3|
292 !! = \sum_i\frac{1}{N}\left(\frac{(x_i-\bar x)^2}{\mu_2(x)}\right)^2 - 3\f]
293 !!
294 !! If an optional mask is given, the average is only over those locations that correspond to true values in the mask.
295 !! \f$x\f$ can be single or double precision. The result will have the same numerical precision.
296 !!
297 !! \b Example
298 !!
299 !! vec = (/ 1., 2, 3., -999., 5., 6. /)
300 !! m = kurtosis(vec, mask=(vec >= 0.))
301 !!
302 !! See also example in test directory.
303
304
305 !> \param[in] "real(sp/dp) :: dat(:)" 1D-array with input numbers.
306 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with `size(dat)`.
307 !! If present, only those locations in dat
308 !! corresponding to the true values in mask are used.
309 !> \retval "real(sp/dp) :: kurtosis" Kurtosis of all elements in dat.
310
311 !> \note Input values must be floating points.
312
313 !> \authors Matthias Cuntz
314 !> \date Nov 2011
315
316 ! ------------------------------------------------------------------
317
318 INTERFACE kurtosis
319 MODULE PROCEDURE kurtosis_sp, kurtosis_dp
320 END INTERFACE kurtosis
321
322 ! ------------------------------------------------------------------
323
324 !> \brief Mean of a vector.
325
326 !> \details
327 !! Calculates the average value of a vector, i.e. the first moment of a series of numbers:
328 !!
329 !! \f[\bar x = sum_i \frac{x_i}{N}
330 !!
331 !! If an optional mask is given, the mean is only over those locations that correspond to true values in the mask.
332 !! \f$x\f$ can be single or double precision. The result will have the same numerical precision.
333 !!
334 !! \b Example
335 !! \code{.f90}
336 !! vec = (/ 1., 2, 3., -999., 5., 6. /)
337 !! m = mean(vec, mask=(vec >= 0.))
338 !! \endcode
339 !! See also example in test directory.
340 !!
341 !> \param[in] "real(sp/dp) :: dat(:)" 1D-array with input numbers.
342 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with `size(dat)`.
343 !! If present, only those locations in dat
344 !! corresponding to the true values in mask are used.
345 !> \retval "real(sp/dp) :: mean" Average of all elements in dat.
346
347 !> \note Input values must be floating points.
348
349 !> \author Matthias Cuntz
350 !> \date Nov 2011
351
352 ! ------------------------------------------------------------------
353
354 INTERFACE mean
355 MODULE PROCEDURE mean_sp, mean_dp
356 END INTERFACE mean
357
358 ! ------------------------------------------------------------------
359
360 !> \brief R-s mixed central moment between vectors.
361
362 !> \details
363 !! Calculates the r,s-th mixed central moment between two vectors:
364 !!
365 !! \f[\mu_{r-s} = \sum_i\frac{(x_i-\bar{x})^r(y_i-\bar{y})^s}{N}\f]
366 !!
367 !! Note that covariace(x,y) = mixed_central_moment(x,y,1,1)
368 !!
369 !! If an optinal mask is given, the average is only over those locations that correspond to true values in the mask.
370 !! \f$x\f$ can be single or double precision. The result will have the same numerical precision.
371 !!
372 !! \b Example
373 !!
374 !! vec1 = (/ 1., 2, 3., -999., 5., 6. /)
375 !! vec2 = (/ 1.3, 2.7, 3.9, 5.1, 6., 8. /)
376 !! m = mixed_central_moment(vec1, vec2, 2, 2, mask=((vec1 >= 0.) .and. (vec2 >= 0.)))
377 !!
378 !! See also example in test directory.
379 !!
380 !! \b Literature
381 !!
382 !! 1. LH Benedict & RD Gould, _Towards better uncertainty estimates for turbulence statistics_,
383 !! Experiments in Fluids 22, 129-136, 1996
384 !!
385 !> \param[in] "real(sp/dp) :: x(:)" First 1D-array
386 !> \param[in] "real(sp/dp) :: y(:)" Second 1D-array
387 !> \param[in] "integer(i4) :: r" Order of x
388 !> \param[in] "integer(i4) :: s" Order of y
389 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with size(x).
390 !! If present, only those locations in dat
391 !! corresponding to the true values in mask are used.
392 !> \retval "real(sp/dp) :: mixed_central_moment" r,s-th mixed central moment between x and y
393
394 !> \note Input values must be floating points.
395
396 !> \author Matthias Cuntz
397 !> \date Nov 2011
398
399 ! ------------------------------------------------------------------
400
402 MODULE PROCEDURE mixed_central_moment_sp, mixed_central_moment_dp
403 END INTERFACE mixed_central_moment
404
405 ! ------------------------------------------------------------------
406
407 !> \brief Mixed central moment variance.
408
409 !> \details
410 !! Calculates the sample variance of r,s-th mixed central moment between two vectors.
411 !! `mixed_central_moment_var` is something like the "error variance" of
412 !! the r,s-th order mixed central moment sampling statistic.
413 !!
414 !! If an optinal mask is given, the average is only over those locations that correspond to true values in the mask.
415 !! \f$x\f$ can be single or double precision. The result will have the same numerical precision.
416 !!
417 !! \b Example
418 !!
419 !! vec1 = (/ 1., 2, 3., -999., 5., 6. /)
420 !! vec2 = (/ 1.3, 2.7, 3.9, 5.1, 6., 8. /)
421 !! em = mixed_central_moment_var(vec1, vec2, 2, 2, mask=((vec1 >= 0.) .and. (vec2 >= 0.)))
422 !!
423 !! See also example in test directory.
424 !!
425 !! \b Literature
426 !!
427 !! 1. LH Benedict & RD Gould, _Towards better uncertainty estimates for turbulence statistics_,
428 !! Experiments in Fluids 22, 129-136, 1996
429 !!
430 !> \param[in] "real(sp/dp) :: x(:)" First 1D-array
431 !> \param[in] "real(sp/dp) :: y(:)" Second 1D-array
432 !> \param[in] "integer(i4) :: r" Order of x
433 !> \param[in] "integer(i4) :: s" Order of y
434 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with size(x).
435 !! If present, only those locations in dat
436 !! corresponding to the true values in mask are used.
437 !> \retval "real(sp/dp) :: mixed_central_moment_var" Sampling variance of r,s-th mixed central moment between x and y
438
439 !> \note Input values must be floating points.
440
441 !> \author Matthias Cuntz
442 !> \date Nov 2011
443
445 MODULE PROCEDURE mixed_central_moment_var_sp, mixed_central_moment_var_dp
446 END INTERFACE mixed_central_moment_var
447
448 ! ------------------------------------------------------------------
449
450 !> \brief First four moments, stddev and mean absolute devation.
451
452 !> \details
453 !! Calculates the first four sample/population moments of a vector, i.e. mean, variance, skewness, and kurtosis,
454 !! as well as standard deviation and mean absolute devation.\n
455 !!
456 !! All output is optional.
457 !!
458 !! If an optinal mask is given, the calculations are over those locations that correspond to true values in the mask.
459 !! \f$x\f$ can be single or double precision. The result will have the same numerical precision.
460 !!
461 !! \b Example
462 !!
463 !! vec = (/ 1., 2, 3., 4., 5., 6. /)
464 !! call moment(vec, average=average, variance=variance, skewness=skewness, kurtosis=kurtosis, &
465 !! mean=mean, stddev=stddev, absdev=absdev, mask=mask, sample=sample)
466 !! --> average = 3.5
467
468 !> \param[in] "real(sp/dp) :: dat(:)" 1D-array with input numbers.
469 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with `size(dat)`.
470 !! If present, only those locations in vec
471 !! corresponding to the true values in mask are used.
472 !> \param[in] "logical, optional :: sample" Logical value.
473 !! If present and False, the population variance and
474 !! std-dev will be calculated (divide by n).
475
476 !> \param[out] "real(sp/dp), optional :: average" Average of input vector.
477 !> \param[out] "real(sp/dp), optional :: variance" Sample variance of input vector (either a sample or pupulation moment).
478 !> \param[out] "real(sp/dp), optional :: skewness" Skewness of input vector.
479 !> \param[out] "real(sp/dp), optional :: kurtosis" Excess kurtosis of input vector.
480 !> \param[out] "real(sp/dp), optional :: mean" Same as average.
481 !> \param[out] "real(sp/dp), optional :: stddev" Sqaure root of variance (either a sample or pupulation moment).
482 !> \param[out] "real(sp/dp), optional :: absdev" Mean absolute deviations from average.
483
484 !> \note Input values must be floating points. Inpt and all optional outputs must have same kind.
485
486 !> \author Matthias Cuntz
487 !> \date Nov 2011
488 !> \author Sebastian Mueller
489 !> \date Dec 2019
490 !! - added optional sample input-para to switch sample to population variance and std-dev.
491
492 ! ------------------------------------------------------------------
493
494 INTERFACE moment
495 MODULE PROCEDURE moment_sp, moment_dp
496 END INTERFACE moment
497
498 ! ------------------------------------------------------------------
499
500 !> \brief Skewness of a vector
501
502 !> \details
503 !! Calculates the skewness of a vector, i.e. the third standardised moment:
504 !!
505 !! \f[\tilde \mu_3 = \sum_i\left(\frac{(x-\bar x)}{\sigma_x}\right)^3\f]
506 !!
507 !! If an optinal mask is given, the average is only over those locations that correspond to true values in the mask.
508 !! \f$x\f$ can be single or double precision. The result will have the same numerical precision.
509 !!
510 !! \b Example
511 !!
512 !! vec = (/ 1., 2, 3., -999., 5., 6. /)
513 !! m = skewness(vec, mask=(vec >= 0.))
514 !!
515 !! See also example in test directory.
516
517
518 !> \param[in] "real(sp/dp) :: dat(:)" 1D-array with input numbers.
519 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with `size(dat)`.
520 !! If present, only those locations in vec
521 !! corresponding to the true values in mask are used.
522 !> \retval "real(sp/dp) :: skewness" Skewness of all elements in dat.
523
524 !> \note Input values must be floating points.
525
526 !> \author Matthias Cuntz
527 !> \date Nov 2011
528 INTERFACE skewness
529 MODULE PROCEDURE skewness_sp, skewness_dp
530 END INTERFACE skewness
531
532 ! ------------------------------------------------------------------
533
534 !> \brief Standard deviation of a vector.
535
536 !> \details
537 !! Calculates the sample standard deviation of a vector, i.e. the square root of the second moment
538 !!
539 !! \f[\sigma_x = \sqrt{\sum_i\frac{(x_i-\bar x)^2}{N-1}}\f]
540 !!
541 !! If an optinal mask is given, the average is only over those locations that correspond to true values in the mask.
542 !! \f$x\f$ can be single or double precision. The result will have the same numerical precision.
543 !!
544 !! \b Example
545 !!
546 !! vec = (/ 1., 2, 3., -999., 5., 6. /)
547 !! m = stddev(vec, mask=(vec >= 0.))
548 !!
549 !! See also example in test directory
550
551 !> \param[in] "real(sp/dp) :: dat(:)" 1D-array with input numbers.
552 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with `size(dat)`.
553 !! If present, only those locations in vec
554 !! corresponding to the true values in mask are used.
555 !> \retval "real(sp/dp) :: stddev" Sample standard deviation of all elements in dat.
556
557 !> \note
558 !! Input values must be floating points.\n
559 !! This is the sample standard deviation. The population standard deviation is:
560 !! `popstddev = stddev * sqrt((n-1)/n)`
561
562 !> \author Matthias Cuntz
563 !> \date Nov 2011
564
565 ! ------------------------------------------------------------------
566
567 INTERFACE stddev
568 MODULE PROCEDURE stddev_sp, stddev_dp
569 END INTERFACE stddev
570
571 ! ------------------------------------------------------------------
572
573 !> \brief Standard deviation of a vector.
574
575 !> \details
576 !! Calculates the sample variance of a vector, i.e. the second moment
577 !!
578 !! \f[\sigma_x^2 = \sum_i\frac{(x_i-\bar x)^2}{N-1}\f]
579 !!
580 !! If an optional mask is given, the average is only over those locations that correspond to true values in the mask.
581 !! \f$x\f$ can be single or double precision. The result will have the same numerical precision.
582
583 !!
584 !! \b Example
585 !!
586 !! vec = (/ 1., 2, 3., -999., 5., 6. /)
587 !! m = variance(vec, mask=(vec >= 0.))
588 !!
589 !! See also example in test directory
590
591 !> \param[in] "real(sp/dp) :: dat(:)" 1D-array with input numbers.
592 !> \param[in] "logical, optional :: mask(:)" 1D-array of logical values with `size(dat)`.
593 !! If present, only those locations in vec
594 !! corresponding to the true values in mask are used.
595 !> \retval "real(sp/dp) :: variance" Sample variance of all elements in dat.
596
597 !> \note
598 !! Input values must be floating points.\n
599 !! This is the sample variance. The population variance is:
600 !! `var = variance * (n-1)/n`
601
602 !> \author Matthias Cuntz
603 !> \date Nov 2011
604 INTERFACE variance
605 MODULE PROCEDURE variance_sp, variance_dp
606 END INTERFACE variance
607
608 ! ------------------------------------------------------------------
609
610 PRIVATE
611
612 ! ------------------------------------------------------------------
613
614CONTAINS
615
616 ! ------------------------------------------------------------------
617
618 FUNCTION absdev_dp(dat, mask)
619
620 IMPLICIT NONE
621
622 REAL(dp), DIMENSION(:), INTENT(IN) :: dat
623 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
624 REAL(dp) :: absdev_dp
625
626 REAL(dp) :: n
627
628 REAL(dp) :: ave
629 LOGICAL, DIMENSION(size(dat)) :: maske
630
631 if (present(mask)) then
632 if (size(mask) .ne. size(dat)) stop .ne.'Error absdev_dp: size(mask) size(dat)'
633 maske = mask
634 n = real(count(maske), dp)
635 else
636 maske(:) = .true.
637 n = real(size(dat), dp)
638 end if
639 if (n .le. (1.0_dp + tiny(1.0_dp))) stop 'absdev_dp: n must be at least 2'
640
641 ! Average
642 ave = sum(dat(:), mask = maske) / n
643 ! Sum of absolute deviation
644 absdev_dp = sum(abs(dat(:) - ave), mask = maske) / n
645
646 END FUNCTION absdev_dp
647
648
649 FUNCTION absdev_sp(dat, mask)
650
651 IMPLICIT NONE
652
653 REAL(sp), DIMENSION(:), INTENT(IN) :: dat
654 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
655 REAL(sp) :: absdev_sp
656
657 REAL(sp) :: n
658
659 REAL(sp) :: ave
660 LOGICAL, DIMENSION(size(dat)) :: maske
661
662 if (present(mask)) then
663 if (size(mask) .ne. size(dat)) stop .ne.'Error absdev_sp: size(mask) size(dat)'
664 maske = mask
665 n = real(count(maske), sp)
666 else
667 maske(:) = .true.
668 n = real(size(dat), sp)
669 end if
670 if (n .le. (1.0_sp + tiny(1.0_sp))) stop 'absdev_sp: n must be at least 2'
671
672 ! Average
673 ave = sum(dat(:), mask = maske) / n
674 ! Sum of absolute deviation
675 absdev_sp = sum(abs(dat(:) - ave), mask = maske) / n
676
677 END FUNCTION absdev_sp
678
679 ! ------------------------------------------------------------------
680
681 FUNCTION average_dp(dat, mask)
682
683 IMPLICIT NONE
684
685 REAL(dp), DIMENSION(:), INTENT(IN) :: dat
686 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
687 REAL(dp) :: average_dp
688
689 REAL(dp) :: n
690 LOGICAL, DIMENSION(size(dat)) :: maske
691
692 if (present(mask)) then
693 if (size(mask) .ne. size(dat)) stop .ne.'Error average_dp: size(mask) size(dat)'
694 maske = mask
695 n = real(count(maske), dp)
696 else
697 maske(:) = .true.
698 n = real(size(dat), dp)
699 end if
700
701 ! Average
702 average_dp = sum(dat(:), mask = maske) / n
703
704 END FUNCTION average_dp
705
706
707 FUNCTION average_sp(dat, mask)
708
709 IMPLICIT NONE
710
711 REAL(sp), DIMENSION(:), INTENT(IN) :: dat
712 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
713 REAL(sp) :: average_sp
714
715 REAL(sp) :: n
716 LOGICAL, DIMENSION(size(dat)) :: maske
717
718 if (present(mask)) then
719 if (size(mask) .ne. size(dat)) stop .ne.'Error average_sp: size(mask) size(dat)'
720 maske = mask
721 n = real(count(maske), sp)
722 else
723 maske(:) = .true.
724 n = real(size(dat), sp)
725 end if
726
727 ! Average
728 average_sp = sum(dat(:), mask = maske) / n
729
730 END FUNCTION average_sp
731
732 ! ------------------------------------------------------------------
733
734 FUNCTION central_moment_dp(x, r, mask)
735
736 IMPLICIT NONE
737
738 REAL(dp), DIMENSION(:), INTENT(IN) :: x
739 INTEGER(i4), INTENT(IN) :: r
740 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
741 REAL(dp) :: central_moment_dp
742
743 REAL(dp) :: n, mx
744 LOGICAL, DIMENSION(size(x)) :: maske
745
746 if (r .lt. 0) then
747 central_moment_dp = 0.0_dp
748 return
749 end if
750 if (r .eq. 0) then
751 central_moment_dp = 1.0_dp
752 return
753 end if
754
755 if (present(mask)) then
756 if (size(mask) .ne. size(x)) stop .ne.'Error central_moment_dp: size(mask) size(x)'
757 maske = mask
758 n = real(count(maske), dp)
759 else
760 maske(:) = .true.
761 n = real(size(x), dp)
762 end if
763 if (n .le. (2.0_dp + tiny(2.0_dp))) stop 'central_moment_dp: n must be at least 3'
764
765 ! average
766 mx = sum(x, mask = maske) / n
767 ! central moment
768 central_moment_dp = sum((x - mx)**r, mask = maske) / n
769
770 END FUNCTION central_moment_dp
771
772
773 FUNCTION central_moment_sp(x, r, mask)
774
775 IMPLICIT NONE
776
777 REAL(sp), DIMENSION(:), INTENT(IN) :: x
778 INTEGER(i4), INTENT(IN) :: r
779 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
780 REAL(sp) :: central_moment_sp
781
782 REAL(sp) :: n, mx
783 LOGICAL, DIMENSION(size(x)) :: maske
784
785 if (r .lt. 0) then
786 central_moment_sp = 0.0_sp
787 return
788 end if
789 if (r .eq. 0) then
790 central_moment_sp = 1.0_sp
791 return
792 end if
793
794 if (present(mask)) then
795 if (size(mask) .ne. size(x)) stop .ne.'Error central_moment_sp: size(mask) size(x)'
796 maske = mask
797 n = real(count(maske), sp)
798 else
799 maske(:) = .true.
800 n = real(size(x), sp)
801 end if
802 if (n .le. (2.0_sp + tiny(2.0_sp))) stop 'central_moment_sp: n must be at least 3'
803
804 ! average
805 mx = sum(x, mask = maske) / n
806 ! central moment
807 central_moment_sp = sum((x - mx)**r, mask = maske) / n
808
809 END FUNCTION central_moment_sp
810
811 ! ------------------------------------------------------------------
812
813 FUNCTION central_moment_var_dp(x, r, mask)
814
815 IMPLICIT NONE
816
817 REAL(dp), DIMENSION(:), INTENT(IN) :: x
818 INTEGER(i4), INTENT(IN) :: r
819 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
820 REAL(dp) :: central_moment_var_dp
821
822 REAL(dp) :: n, rr, u2r, ur, urm1, urp1, u2
823 LOGICAL, DIMENSION(size(x)) :: maske
824
825 if (r.le.1) then
826 central_moment_var_dp = 0.0_dp
827 return
828 end if
829
830 if (present(mask)) then
831 if (size(mask) .ne. size(x)) stop .ne.'Error central_moment_var_dp: size(mask) size(x)'
832 maske = mask
833 n = real(count(maske), dp)
834 else
835 maske(:) = .true.
836 n = real(size(x), dp)
837 end if
838 if (n .le. (2.0_dp + tiny(2.0_dp))) stop 'central_moment_var_dp: n must be at least 3'
839
840 u2r = central_moment(x, 2 * r, mask = maske)
841 ur = central_moment(x, r, mask = maske)
842 urm1 = central_moment(x, r - 1, mask = maske)
843 u2 = central_moment(x, 2, mask = maske)
844 urp1 = central_moment(x, r + 1, mask = maske)
845 rr = real(r, dp)
846 central_moment_var_dp = (u2r - ur * ur + rr * rr * urm1 * urm1 * u2 - 2.0_dp * rr * urp1 * urm1) / n
847
848 END FUNCTION central_moment_var_dp
849
850
851 FUNCTION central_moment_var_sp(x, r, mask)
852
853 IMPLICIT NONE
854
855 REAL(sp), DIMENSION(:), INTENT(IN) :: x
856 INTEGER(i4), INTENT(IN) :: r
857 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
858 REAL(sp) :: central_moment_var_sp
859
860 REAL(sp) :: n, rr, u2r, ur, urm1, urp1, u2
861 LOGICAL, DIMENSION(size(x)) :: maske
862
863 if (r.le.1) then
864 central_moment_var_sp = 0.0_sp
865 return
866 end if
867
868 if (present(mask)) then
869 if (size(mask) .ne. size(x)) stop .ne.'Error central_moment_var_sp: size(mask) size(x)'
870 maske = mask
871 n = real(count(maske), sp)
872 else
873 maske(:) = .true.
874 n = real(size(x), sp)
875 end if
876 if (n .le. (2.0_sp + tiny(2.0_sp))) stop 'central_moment_var_sp: n must be at least 3'
877
878 u2r = central_moment(x, 2 * r, mask = maske)
879 ur = central_moment(x, r, mask = maske)
880 urm1 = central_moment(x, r - 1, mask = maske)
881 u2 = central_moment(x, 2, mask = maske)
882 urp1 = central_moment(x, r + 1, mask = maske)
883 rr = real(r, sp)
884 central_moment_var_sp = (u2r - ur * ur + rr * rr * urm1 * urm1 * u2 - 2.0_sp * rr * urp1 * urm1) / n
885
886 END FUNCTION central_moment_var_sp
887
888 ! ------------------------------------------------------------------
889
890 FUNCTION correlation_dp(x, y, mask)
891
892 IMPLICIT NONE
893
894 REAL(dp), DIMENSION(:), INTENT(IN) :: x
895 REAL(dp), DIMENSION(:), INTENT(IN) :: y
896 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
897 REAL(dp) :: correlation_dp
898
899 REAL(dp) :: n
900 REAL(dp) :: mx, my
901 REAL(dp) :: sx, sy, covar
902 LOGICAL, DIMENSION(size(x)) :: maske
903
904 if (size(x) .ne. size(y)) stop .ne.'Error correlation_dp: size(x) size(y)'
905 if (present(mask)) then
906 if (size(mask) .ne. size(x)) stop .ne.'Error correlation_dp: size(mask) size(x)'
907 maske = mask
908 n = real(count(maske), dp)
909 else
910 maske(:) = .true.
911 n = real(size(x), dp)
912 end if
913 if (n .le. (1.0_dp + tiny(1.0_dp))) stop 'correlation_dp: n must be at least 2'
914
915 ! Mean and Stddev of x and y
916 call moment(x, mx, stddev = sx, mask = maske)
917 call moment(y, my, stddev = sy, mask = maske)
918 covar = sum((x - mx) * (y - my), mask = maske) / n
919 ! correlation
920 correlation_dp = covar / (sx * sy)
921
922 END FUNCTION correlation_dp
923
924
925 FUNCTION correlation_sp(x, y, mask)
926
927 IMPLICIT NONE
928
929 REAL(sp), DIMENSION(:), INTENT(IN) :: x
930 REAL(sp), DIMENSION(:), INTENT(IN) :: y
931 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
932 REAL(sp) :: correlation_sp
933
934 REAL(sp) :: n
935 REAL(sp) :: mx, my
936 REAL(sp) :: sx, sy, covar
937 LOGICAL, DIMENSION(size(x)) :: maske
938
939 if (size(x) .ne. size(y)) stop .ne.'Error correlation_sp: size(x) size(y)'
940 if (present(mask)) then
941 if (size(mask) .ne. size(x)) stop .ne.'Error correlation_sp: size(mask) size(x)'
942 maske = mask
943 n = real(count(maske), sp)
944 else
945 maske(:) = .true.
946 n = real(size(x), sp)
947 end if
948 if (n .le. (1.0_sp + tiny(1.0_sp))) stop 'correlation_sp: n must be at least 2'
949
950 ! Mean and Stddev of x and y
951 call moment(x, mx, stddev = sx, mask = maske)
952 call moment(y, my, stddev = sy, mask = maske)
953 covar = sum((x - mx) * (y - my), mask = maske) / n
954 ! correlation
955 correlation_sp = covar / (sx * sy)
956
957 END FUNCTION correlation_sp
958
959 ! ------------------------------------------------------------------
960
961 FUNCTION covariance_dp(x, y, mask)
962
963 IMPLICIT NONE
964
965 REAL(dp), DIMENSION(:), INTENT(IN) :: x
966 REAL(dp), DIMENSION(:), INTENT(IN) :: y
967 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
968 REAL(dp) :: covariance_dp
969
970 REAL(dp) :: n
971 REAL(dp) :: mx, my
972 LOGICAL, DIMENSION(size(x)) :: maske
973
974 if (size(x) .ne. size(y)) stop .ne.'Error covariance_dp: size(x) size(y)'
975 if (present(mask)) then
976 if (size(mask) .ne. size(x)) stop .ne.'Error covariance_dp: size(mask) size(x)'
977 maske = mask
978 n = real(count(maske), dp)
979 else
980 maske(:) = .true.
981 n = real(size(x), dp)
982 end if
983 if (n .le. (1.0_dp + tiny(1.0_dp))) stop 'covariance_dp: n must be at least 2'
984
985 ! Mean of x and y
986 mx = mean(x, mask = maske)
987 my = mean(y, mask = maske)
988 covariance_dp = sum((x - mx) * (y - my), mask = maske) / n
989
990 END FUNCTION covariance_dp
991
992
993 FUNCTION covariance_sp(x, y, mask)
994
995 IMPLICIT NONE
996
997 REAL(sp), DIMENSION(:), INTENT(IN) :: x
998 REAL(sp), DIMENSION(:), INTENT(IN) :: y
999 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1000 REAL(sp) :: covariance_sp
1001
1002 REAL(sp) :: n
1003 REAL(sp) :: mx, my
1004 LOGICAL, DIMENSION(size(x)) :: maske
1005
1006 if (size(x) .ne. size(y)) stop .ne.'Error covariance_sp: size(x) size(y)'
1007 if (present(mask)) then
1008 if (size(mask) .ne. size(x)) stop .ne.'Error covariance_sp: size(mask) size(x)'
1009 maske = mask
1010 n = real(count(maske), sp)
1011 else
1012 maske(:) = .true.
1013 n = real(size(x), sp)
1014 end if
1015 if (n .le. (1.0_sp + tiny(1.0_sp))) stop 'covariance_sp: n must be at least 2'
1016
1017 ! Mean of x and y
1018 mx = mean(x, mask = maske)
1019 my = mean(y, mask = maske)
1020 covariance_sp = sum((x - mx) * (y - my), mask = maske) / n
1021
1022 END FUNCTION covariance_sp
1023
1024 ! ------------------------------------------------------------------
1025
1026 FUNCTION kurtosis_dp(dat, mask)
1027
1028 IMPLICIT NONE
1029
1030 REAL(dp), DIMENSION(:), INTENT(IN) :: dat
1031 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1032 REAL(dp) :: kurtosis_dp
1033
1034 REAL(dp) :: n
1035
1036 REAL(dp) :: ep, ave, var
1037 REAL(dp), DIMENSION(size(dat)) :: p, s
1038 LOGICAL, DIMENSION(size(dat)) :: maske
1039
1040 if (present(mask)) then
1041 if (size(mask) .ne. size(dat)) stop .ne.'Error kurtosis_dp: size(mask) size(dat)'
1042 maske = mask
1043 n = real(count(maske), dp)
1044 else
1045 maske(:) = .true.
1046 n = real(size(dat), dp)
1047 end if
1048 if (n .le. (1.0_dp + tiny(1.0_dp))) stop 'kurtosis_dp: n must be at least 2'
1049
1050 ! Average
1051 ave = sum(dat(:), mask = maske) / n
1052 s(:) = dat(:) - ave
1053 ! Variance / Standard deviation
1054 ep = sum(s(:), mask = maske)
1055 p(:) = s(:) * s(:)
1056 var = sum(p(:), mask = maske)
1057 var = (var - ep * ep / n) / (n - 1.0_dp)
1058 if (abs(var) .lt. tiny(0.0_dp)) stop 'kurtosis_dp: no kurtosis when zero variance'
1059 ! Kurtosis
1060 p(:) = p(:) * s(:) * s(:)
1061 kurtosis_dp = sum(p(:), mask = maske)
1062 kurtosis_dp = kurtosis_dp / (n * var * var) - 3.0_dp
1063
1064 END FUNCTION kurtosis_dp
1065
1066
1067 FUNCTION kurtosis_sp(dat, mask)
1068
1069 IMPLICIT NONE
1070
1071 REAL(sp), DIMENSION(:), INTENT(IN) :: dat
1072 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1073 REAL(sp) :: kurtosis_sp
1074
1075 REAL(sp) :: n
1076
1077 REAL(sp) :: ep, ave, var
1078 REAL(sp), DIMENSION(size(dat)) :: p, s
1079 LOGICAL, DIMENSION(size(dat)) :: maske
1080
1081 if (present(mask)) then
1082 if (size(mask) .ne. size(dat)) stop .ne.'Error kurtosis_sp: size(mask) size(dat)'
1083 maske = mask
1084 n = real(count(maske), sp)
1085 else
1086 maske(:) = .true.
1087 n = real(size(dat), sp)
1088 end if
1089 if (n .le. (1.0_sp + tiny(1.0_sp))) stop 'kurtosis_sp: n must be at least 2'
1090
1091 ! Average
1092 ave = sum(dat(:), mask = maske) / n
1093 s(:) = dat(:) - ave
1094 ! Variance / Standard deviation
1095 ep = sum(s(:), mask = maske)
1096 p(:) = s(:) * s(:)
1097 var = sum(p(:), mask = maske)
1098 var = (var - ep * ep / n) / (n - 1.0_sp)
1099 if (abs(var) .lt. tiny(0.0_sp)) stop 'kurtosis_sp: no kurtosis when zero variance'
1100 ! Kurtosis
1101 p(:) = p(:) * s(:) * s(:)
1102 kurtosis_sp = sum(p(:), mask = maske)
1103 kurtosis_sp = kurtosis_sp / (n * var * var) - 3.0_sp
1104
1105 END FUNCTION kurtosis_sp
1106
1107 ! ------------------------------------------------------------------
1108
1109 FUNCTION mean_dp(dat, mask)
1110
1111 IMPLICIT NONE
1112
1113 REAL(dp), DIMENSION(:), INTENT(IN) :: dat
1114 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1115 REAL(dp) :: mean_dp
1116
1117 REAL(dp) :: n
1118
1119 LOGICAL, DIMENSION(size(dat)) :: maske
1120
1121 if (present(mask)) then
1122 if (size(mask) .ne. size(dat)) stop .ne.'Error mean_dp: size(mask) size(dat)'
1123 maske = mask
1124 n = real(count(maske), dp)
1125 else
1126 maske(:) = .true.
1127 n = real(size(dat), dp)
1128 end if
1129
1130 ! Mean
1131 mean_dp = sum(dat(:), mask = maske) / n
1132
1133 END FUNCTION mean_dp
1134
1135 !> \copydoc mean
1136 FUNCTION mean_sp(dat, mask)
1137
1138 IMPLICIT NONE
1139
1140 REAL(sp), DIMENSION(:), INTENT(IN) :: dat
1141 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1142 REAL(sp) :: mean_sp
1143
1144 REAL(sp) :: n
1145
1146 LOGICAL, DIMENSION(size(dat)) :: maske
1147
1148 if (present(mask)) then
1149 if (size(mask) .ne. size(dat)) stop .ne.'Error mean_sp: size(mask) size(dat)'
1150 maske = mask
1151 n = real(count(maske), sp)
1152 else
1153 maske(:) = .true.
1154 n = real(size(dat), sp)
1155 end if
1156
1157 ! Mean
1158 mean_sp = sum(dat(:), mask = maske) / n
1159
1160 END FUNCTION mean_sp
1161
1162 ! ------------------------------------------------------------------
1163
1164 FUNCTION mixed_central_moment_dp(x, y, r, s, mask)
1165
1166 IMPLICIT NONE
1167
1168 REAL(dp), DIMENSION(:), INTENT(IN) :: x
1169 REAL(dp), DIMENSION(:), INTENT(IN) :: y
1170 INTEGER(i4), INTENT(IN) :: r
1171 INTEGER(i4), INTENT(IN) :: s
1172 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1173 REAL(dp) :: mixed_central_moment_dp
1174
1175 REAL(dp) :: n, mx, my
1176 REAL(dp), DIMENSION(size(x)) :: xx, yy
1177 LOGICAL, DIMENSION(size(x)) :: maske
1178
1179 if (r.lt.0 .or. s.lt.0) then
1180 mixed_central_moment_dp = 0.0_dp
1181 return
1182 end if
1183
1184 if (size(x) .ne. size(y)) stop .ne.'Error mixed_central_moment_dp: size(x) size(y)'
1185 if (present(mask)) then
1186 if (size(mask) .ne. size(x)) stop .ne.'Error mixed_central_moment_dp: size(mask) size(x)'
1187 maske = mask
1188 n = real(count(maske), dp)
1189 else
1190 maske(:) = .true.
1191 n = real(size(x), dp)
1192 end if
1193 if (n .le. (2.0_dp + tiny(2.0_dp))) stop 'mixed_central_moment_dp: n must be at least 3'
1194
1195 ! Averages of x and y
1196 mx = sum(x, mask = maske) / n
1197 my = sum(y, mask = maske) / n
1198 ! Mixed central moment
1199 if (r>0) then
1200 xx = (x - mx)**r
1201 else
1202 xx = 1._dp
1203 end if
1204 if (s>0) then
1205 yy = (y - my)**s
1206 else
1207 yy = 1._dp
1208 end if
1209 mixed_central_moment_dp = sum(xx * yy, mask = maske) / n
1210
1211 END FUNCTION mixed_central_moment_dp
1212
1213
1214 FUNCTION mixed_central_moment_sp(x, y, r, s, mask)
1215
1216 IMPLICIT NONE
1217
1218 REAL(sp), DIMENSION(:), INTENT(IN) :: x
1219 REAL(sp), DIMENSION(:), INTENT(IN) :: y
1220 INTEGER(i4), INTENT(IN) :: r
1221 INTEGER(i4), INTENT(IN) :: s
1222 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1223 REAL(sp) :: mixed_central_moment_sp
1224
1225 REAL(sp) :: n, mx, my
1226 REAL(sp), DIMENSION(size(x)) :: xx, yy
1227 LOGICAL, DIMENSION(size(x)) :: maske
1228
1229 if (r.lt.0 .or. s.lt.0) then
1230 mixed_central_moment_sp = 0.0_sp
1231 return
1232 end if
1233
1234 if (size(x) .ne. size(y)) stop .ne.'Error mixed_central_moment_sp: size(x) size(y)'
1235 if (present(mask)) then
1236 if (size(mask) .ne. size(x)) stop .ne.'Error mixed_central_moment_sp: size(mask) size(x)'
1237 maske = mask
1238 n = real(count(maske), sp)
1239 else
1240 maske(:) = .true.
1241 n = real(size(x), sp)
1242 end if
1243 if (n .le. (2.0_sp + tiny(2.0_sp))) stop 'mixed_central_moment_sp: n must be at least 3'
1244
1245 ! Averages of x and y
1246 mx = sum(x, mask = maske) / n
1247 my = sum(y, mask = maske) / n
1248 ! Mixed central moment
1249 if (r>0) then
1250 xx = (x - mx)**r
1251 else
1252 xx = 1._sp
1253 end if
1254 if (s>0) then
1255 yy = (y - my)**s
1256 else
1257 yy = 1._sp
1258 end if
1259 mixed_central_moment_sp = sum(xx * yy, mask = maske) / n
1260
1261 END FUNCTION mixed_central_moment_sp
1262
1263 ! ------------------------------------------------------------------
1264
1265 FUNCTION mixed_central_moment_var_dp(x, y, r, s, mask)
1266 ! Error variance of mixed central moment (Benedict & Gould 1996)
1267 IMPLICIT NONE
1268
1269 REAL(dp), DIMENSION(:), INTENT(IN) :: x
1270 REAL(dp), DIMENSION(:), INTENT(IN) :: y
1271 INTEGER(i4), INTENT(IN) :: r
1272 INTEGER(i4), INTENT(IN) :: s
1273 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1274 REAL(dp) :: mixed_central_moment_var_dp
1275
1276 REAL(dp) :: u2r2s, urs, urm1s, u20, urp1s, ursm1, u02, ursp1, u11
1277 REAL(dp) :: n, rr, ss
1278 LOGICAL, DIMENSION(size(x)) :: maske
1279
1280 if (size(x) .ne. size(y)) stop .ne.'Error mixed_central_moment_var_dp: size(x) size(y)'
1281 if (present(mask)) then
1282 if (size(mask) .ne. size(x)) stop .ne.'Error mixed_central_moment_var_dp: size(mask) size(x)'
1283 maske = mask
1284 n = real(count(maske), dp)
1285 else
1286 maske(:) = .true.
1287 n = real(size(x), dp)
1288 end if
1289 if (n .le. (2.0_dp + tiny(2.0_dp))) stop 'mixed_central_moment_var_dp: n must be at least 3'
1290
1291 u2r2s = mixed_central_moment(x, y, 2 * r, 2 * s, mask = maske)
1292 urs = mixed_central_moment(x, y, r, s, mask = maske)
1293 urm1s = mixed_central_moment(x, y, r - 1, s, mask = maske)
1294 u20 = mixed_central_moment(x, y, 2, 0, mask = maske)
1295 urp1s = mixed_central_moment(x, y, r + 1, s, mask = maske)
1296 ursm1 = mixed_central_moment(x, y, r, s - 1, mask = maske)
1297 u02 = mixed_central_moment(x, y, 0, 2, mask = maske)
1298 ursp1 = mixed_central_moment(x, y, r, s + 1, mask = maske)
1299 u11 = mixed_central_moment(x, y, 1, 1, mask = maske)
1300 rr = real(r, dp)
1301 ss = real(s, dp)
1302
1303 mixed_central_moment_var_dp = (u2r2s - urs * urs &
1304 + rr * rr**u20 * urm1s * urm1s + ss * ss * u02 * ursm1 * ursm1 &
1305 + 2.0_dp * rr * ss * u11 * urm1s * ursm1 &
1306 - 2.0_dp * rr * urp1s * urm1s - 2.0_dp * ss * ursp1 * ursm1) / n
1307
1308 END FUNCTION mixed_central_moment_var_dp
1309
1310
1311 FUNCTION mixed_central_moment_var_sp(x, y, r, s, mask)
1312 ! Error variance of mixed central moment (Benedict & Gould 1996)
1313 IMPLICIT NONE
1314
1315 REAL(sp), DIMENSION(:), INTENT(IN) :: x
1316 REAL(sp), DIMENSION(:), INTENT(IN) :: y
1317 INTEGER(i4), INTENT(IN) :: r
1318 INTEGER(i4), INTENT(IN) :: s
1319 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1320 REAL(sp) :: mixed_central_moment_var_sp
1321
1322 REAL(sp) :: u2r2s, urs, urm1s, u20, urp1s, ursm1, u02, ursp1, u11
1323 REAL(sp) :: n, rr, ss
1324 LOGICAL, DIMENSION(size(x)) :: maske
1325
1326 if (size(x) .ne. size(y)) stop .ne.'Error mixed_central_moment_var_sp: size(x) size(y)'
1327 if (present(mask)) then
1328 if (size(mask) .ne. size(x)) stop .ne.'Error mixed_central_moment_var_sp: size(mask) size(x)'
1329 maske = mask
1330 n = real(count(maske), sp)
1331 else
1332 maske(:) = .true.
1333 n = real(size(x), sp)
1334 end if
1335 if (n .le. (2.0_sp + tiny(2.0_sp))) stop 'mixed_central_moment_var_sp: n must be at least 3'
1336
1337 u2r2s = mixed_central_moment(x, y, 2 * r, 2 * s, mask = maske)
1338 urs = mixed_central_moment(x, y, r, s, mask = maske)
1339 urm1s = mixed_central_moment(x, y, r - 1, s, mask = maske)
1340 u20 = mixed_central_moment(x, y, 2, 0, mask = maske)
1341 urp1s = mixed_central_moment(x, y, r + 1, s, mask = maske)
1342 ursm1 = mixed_central_moment(x, y, r, s - 1, mask = maske)
1343 u02 = mixed_central_moment(x, y, 0, 2, mask = maske)
1344 ursp1 = mixed_central_moment(x, y, r, s + 1, mask = maske)
1345 u11 = mixed_central_moment(x, y, 1, 1, mask = maske)
1346 rr = real(r, sp)
1347 ss = real(s, sp)
1348
1349 mixed_central_moment_var_sp = (u2r2s - urs * urs &
1350 + rr * rr**u20 * urm1s * urm1s + ss * ss * u02 * ursm1 * ursm1 &
1351 + 2.0_sp * rr * ss * u11 * urm1s * ursm1 &
1352 - 2.0_sp * rr * urp1s * urm1s - 2.0_sp * ss * ursp1 * ursm1) / n
1353
1354 END FUNCTION mixed_central_moment_var_sp
1355
1356 ! ------------------------------------------------------------------
1357
1358 SUBROUTINE moment_dp(dat, average, variance, skewness, kurtosis, mean, stddev, absdev, mask, sample)
1359
1360 IMPLICIT NONE
1361
1362 REAL(dp), DIMENSION(:), INTENT(IN) :: dat
1363 REAL(dp), OPTIONAL, INTENT(OUT) :: average
1364 REAL(dp), OPTIONAL, INTENT(OUT) :: variance
1365 REAL(dp), OPTIONAL, INTENT(OUT) :: skewness
1366 REAL(dp), OPTIONAL, INTENT(OUT) :: kurtosis
1367 REAL(dp), OPTIONAL, INTENT(OUT) :: mean
1368 REAL(dp), OPTIONAL, INTENT(OUT) :: stddev
1369 REAL(dp), OPTIONAL, INTENT(OUT) :: absdev
1370 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1371 LOGICAL, OPTIONAL, INTENT(IN) :: sample
1372
1373 REAL(dp) :: n, div_n ! divisor depending if sample or population moments
1374
1375 REAL(dp) :: ep, ave, var
1376 REAL(dp), DIMENSION(size(dat)) :: p, s
1377 LOGICAL, DIMENSION(size(dat)) :: maske
1378
1379 if (present(mask)) then
1380 if (size(mask) .ne. size(dat)) stop .ne.'Error moment_dp: size(mask) size(dat)'
1381 maske = mask
1382 n = real(count(maske), sp)
1383 else
1384 maske(:) = .true.
1385 n = real(size(dat), sp)
1386 end if
1387 if (n .le. (1.0_sp + tiny(1.0_sp))) stop 'moment_dp: n must be at least 2'
1388
1389 ! set divisor for population (n) or sample (n-1) variance
1390 div_n = n - 1.0_dp
1391 if (present(sample)) then
1392 if (.not. sample) div_n = n
1393 end if
1394
1395 ! Any optional argument
1396 if (.not. (present(average) .or. present(variance) .or. present(skewness) .or. &
1397 present(kurtosis) .or. present(mean) .or. present(stddev) .or. present(absdev))) return
1398 ! Average
1399 ave = sum(dat(:), mask = maske) / n
1400 if (present(average)) average = ave
1401 if (present(mean)) mean = ave
1402 if (.not. (present(variance) .or. present(skewness) .or. &
1403 present(kurtosis) .or. present(stddev) .or. present(absdev))) return
1404 ! Absolute deviation
1405 s(:) = dat(:) - ave
1406 if (present(absdev)) absdev = sum(abs(s(:)), mask = maske) / n
1407 ! Variance / Standard deviation
1408 if (.not. (present(variance) .or. present(skewness) .or. &
1409 present(kurtosis) .or. present(stddev))) return
1410 ep = sum(s(:), mask = maske)
1411 p(:) = s(:) * s(:)
1412 var = sum(p(:), mask = maske)
1413 var = (var - ep * ep / n) / div_n
1414 if (present(variance)) variance = var
1415 ! Standard deviation
1416 if (present(stddev)) stddev = sqrt(var)
1417 if (.not. (present(skewness) .or. present(kurtosis))) return
1418 ! Skewness
1419 if (abs(var) .lt. tiny(0.0_dp)) stop 'moment_dp: no skewness or kurtosis when zero variance'
1420 p(:) = p(:) * s(:)
1421 if (present(skewness)) then
1422 skewness = sum(p(:), mask = maske)
1423 skewness = skewness / (n * stddev * stddev * stddev)
1424 end if
1425 ! Kurtosis
1426 if (present(kurtosis)) then
1427 p(:) = p(:) * s(:)
1428 kurtosis = sum(p(:), mask = maske)
1429 kurtosis = kurtosis / (n * variance * variance) - 3.0_dp
1430 end if
1431
1432 END SUBROUTINE moment_dp
1433
1434
1435 SUBROUTINE moment_sp(dat, average, variance, skewness, kurtosis, mean, stddev, absdev, mask, sample)
1436
1437 IMPLICIT NONE
1438
1439 REAL(sp), DIMENSION(:), INTENT(IN) :: dat
1440 REAL(sp), OPTIONAL, INTENT(OUT) :: average
1441 REAL(sp), OPTIONAL, INTENT(OUT) :: variance
1442 REAL(sp), OPTIONAL, INTENT(OUT) :: skewness
1443 REAL(sp), OPTIONAL, INTENT(OUT) :: kurtosis
1444 REAL(sp), OPTIONAL, INTENT(OUT) :: mean
1445 REAL(sp), OPTIONAL, INTENT(OUT) :: stddev
1446 REAL(sp), OPTIONAL, INTENT(OUT) :: absdev
1447 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1448 LOGICAL, OPTIONAL, INTENT(IN) :: sample
1449
1450 REAL(sp) :: n, div_n ! divisor depending if sample or population moments
1451
1452 REAL(sp) :: ep, ave, var
1453 REAL(sp), DIMENSION(size(dat)) :: p, s
1454 LOGICAL, DIMENSION(size(dat)) :: maske
1455
1456 if (present(mask)) then
1457 if (size(mask) .ne. size(dat)) stop .ne.'Error moment_sp: size(mask) size(dat)'
1458 maske = mask
1459 n = real(count(maske), sp)
1460 else
1461 maske(:) = .true.
1462 n = real(size(dat), sp)
1463 end if
1464 if (n .le. (1.0_sp + tiny(1.0_sp))) stop 'moment_sp: n must be at least 2'
1465
1466 ! set divisor for population (n) or sample (n-1) variance
1467 div_n = n - 1.0_sp
1468 if (present(sample)) then
1469 if (.not. sample) div_n = n
1470 end if
1471
1472 ! Any optional argument
1473 if (.not. (present(average) .or. present(variance) .or. present(skewness) .or. &
1474 present(kurtosis) .or. present(mean) .or. present(stddev) .or. present(absdev))) return
1475 ! Average
1476 ave = sum(dat(:), mask = maske) / n
1477 if (present(average)) average = ave
1478 if (present(mean)) mean = ave
1479 if (.not. (present(variance) .or. present(skewness) .or. &
1480 present(kurtosis) .or. present(stddev) .or. present(absdev))) return
1481 ! Absolute deviation
1482 s(:) = dat(:) - ave
1483 if (present(absdev)) absdev = sum(abs(s(:)), mask = maske) / n
1484 ! Variance / Standard deviation
1485 if (.not. (present(variance) .or. present(skewness) .or. &
1486 present(kurtosis) .or. present(stddev))) return
1487 ep = sum(s(:), mask = maske)
1488 p(:) = s(:) * s(:)
1489 var = sum(p(:), mask = maske)
1490 var = (var - ep * ep / n) / div_n
1491 if (present(variance)) variance = var
1492 ! Standard deviation
1493 if (present(stddev)) stddev = sqrt(var)
1494 if (.not. (present(skewness) .or. present(kurtosis))) return
1495 ! Skewness
1496 if (abs(var) .lt. tiny(0.0_sp)) stop 'moment_sp: no skewness or kurtosis when zero variance'
1497 p(:) = p(:) * s(:)
1498 if (present(skewness)) then
1499 skewness = sum(p(:), mask = maske)
1500 skewness = skewness / (n * stddev * stddev * stddev)
1501 end if
1502 ! Kurtosis
1503 if (present(kurtosis)) then
1504 p(:) = p(:) * s(:)
1505 kurtosis = sum(p(:), mask = maske)
1506 kurtosis = kurtosis / (n * variance * variance) - 3.0_sp
1507 end if
1508
1509 END SUBROUTINE moment_sp
1510
1511 ! ------------------------------------------------------------------
1512
1513 FUNCTION stddev_dp(dat, mask)
1514
1515 IMPLICIT NONE
1516
1517 REAL(dp), DIMENSION(:), INTENT(IN) :: dat
1518 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1519 REAL(dp) :: stddev_dp
1520
1521 REAL(dp) :: n
1522
1523 REAL(dp) :: ep, ave, var
1524 REAL(dp), DIMENSION(size(dat)) :: p, s
1525 LOGICAL, DIMENSION(size(dat)) :: maske
1526
1527 if (present(mask)) then
1528 if (size(mask) .ne. size(dat)) stop .ne.'Error stddev_dp: size(mask) size(dat)'
1529 maske = mask
1530 n = real(count(maske), dp)
1531 else
1532 maske(:) = .true.
1533 n = real(size(dat), dp)
1534 end if
1535 if (n .le. (1.0_dp + tiny(1.0_dp))) stop 'stddev_dp: n must be at least 2'
1536
1537 ! Average
1538 ave = sum(dat(:), mask = maske) / n
1539 s(:) = dat(:) - ave
1540 ! Variance / Standard deviation
1541 ep = sum(s(:), mask = maske)
1542 p(:) = s(:) * s(:)
1543 var = sum(p(:), mask = maske)
1544 var = (var - ep * ep / n) / (n - 1.0_dp)
1545 stddev_dp = sqrt(var)
1546
1547 END FUNCTION stddev_dp
1548
1549
1550 FUNCTION stddev_sp(dat, mask)
1551
1552 IMPLICIT NONE
1553
1554 REAL(sp), DIMENSION(:), INTENT(IN) :: dat
1555 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1556 REAL(sp) :: stddev_sp
1557
1558 REAL(sp) :: n
1559
1560 REAL(sp) :: ep, ave, var
1561 REAL(sp), DIMENSION(size(dat)) :: p, s
1562 LOGICAL, DIMENSION(size(dat)) :: maske
1563
1564 if (present(mask)) then
1565 if (size(mask) .ne. size(dat)) stop .ne.'Error stddev_sp: size(mask) size(dat)'
1566 maske = mask
1567 n = real(count(maske), sp)
1568 else
1569 maske(:) = .true.
1570 n = real(size(dat), sp)
1571 end if
1572 if (n .le. (1.0_sp + tiny(1.0_sp))) stop 'stddev_sp: n must be at least 2'
1573
1574 ! Average
1575 ave = sum(dat(:), mask = maske) / n
1576 s(:) = dat(:) - ave
1577 ! Variance / Standard deviation
1578 ep = sum(s(:), mask = maske)
1579 p(:) = s(:) * s(:)
1580 var = sum(p(:), mask = maske)
1581 var = (var - ep * ep / n) / (n - 1.0_sp)
1582 stddev_sp = sqrt(var)
1583
1584 END FUNCTION stddev_sp
1585
1586 ! ------------------------------------------------------------------
1587
1588 FUNCTION skewness_dp(dat, mask)
1589
1590 IMPLICIT NONE
1591
1592 REAL(dp), DIMENSION(:), INTENT(IN) :: dat
1593 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1594 REAL(dp) :: skewness_dp
1595
1596 REAL(dp) :: n
1597
1598 REAL(dp) :: ep, ave, var, stddev
1599 REAL(dp), DIMENSION(size(dat)) :: p, s
1600 LOGICAL, DIMENSION(size(dat)) :: maske
1601
1602 if (present(mask)) then
1603 if (size(mask) .ne. size(dat)) stop .ne.'Error skewness_dp: size(mask) size(dat)'
1604 maske = mask
1605 n = real(count(maske), dp)
1606 else
1607 maske(:) = .true.
1608 n = real(size(dat), dp)
1609 end if
1610 if (n .le. (1.0_dp + tiny(1.0_dp))) stop 'skewness_dp: n must be at least 2'
1611
1612 ! Average
1613 ave = sum(dat(:), mask = maske) / n
1614 s(:) = dat(:) - ave
1615 ! Variance / Standard deviation
1616 ep = sum(s(:), mask = maske)
1617 p(:) = s(:) * s(:)
1618 var = sum(p(:), mask = maske)
1619 var = (var - ep * ep / n) / (n - 1.0_dp)
1620 stddev = sqrt(var)
1621 ! Skewness
1622 if (abs(var) .lt. tiny(0.0_dp)) stop 'skewness_dp: no skewness when zero variance'
1623 p(:) = p(:) * s(:)
1624 skewness_dp = sum(p(:), mask = maske)
1625 skewness_dp = skewness_dp / (n * stddev * stddev * stddev)
1626
1627 END FUNCTION skewness_dp
1628
1629
1630 FUNCTION skewness_sp(dat, mask)
1631
1632 IMPLICIT NONE
1633
1634 REAL(sp), DIMENSION(:), INTENT(IN) :: dat
1635 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1636 REAL(sp) :: skewness_sp
1637
1638 REAL(sp) :: n
1639
1640 REAL(sp) :: ep, ave, var, stddev
1641 REAL(sp), DIMENSION(size(dat)) :: p, s
1642 LOGICAL, DIMENSION(size(dat)) :: maske
1643
1644 if (present(mask)) then
1645 if (size(mask) .ne. size(dat)) stop .ne.'Error skewness_sp: size(mask) size(dat)'
1646 maske = mask
1647 n = real(count(maske), sp)
1648 else
1649 maske(:) = .true.
1650 n = real(size(dat), sp)
1651 end if
1652 if (n .le. (1.0_sp + tiny(1.0_sp))) stop 'skewness_sp: n must be at least 2'
1653
1654 ! Average
1655 ave = sum(dat(:), mask = maske) / n
1656 s(:) = dat(:) - ave
1657 ! Variance / Standard deviation
1658 ep = sum(s(:), mask = maske)
1659 p(:) = s(:) * s(:)
1660 var = sum(p(:), mask = maske)
1661 var = (var - ep * ep / n) / (n - 1.0_sp)
1662 stddev = sqrt(var)
1663 ! Skewness
1664 if (abs(var) .lt. tiny(0.0_sp)) stop 'skewness_sp: no skewness when zero variance'
1665 p(:) = p(:) * s(:)
1666 skewness_sp = sum(p(:), mask = maske)
1667 skewness_sp = skewness_sp / (n * stddev * stddev * stddev)
1668
1669 END FUNCTION skewness_sp
1670
1671 ! ------------------------------------------------------------------
1672
1673 FUNCTION variance_dp(dat, mask)
1674
1675 IMPLICIT NONE
1676
1677 REAL(dp), DIMENSION(:), INTENT(IN) :: dat
1678 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1679 REAL(dp) :: variance_dp
1680
1681 REAL(dp) :: n
1682
1683 REAL(dp) :: ep, ave, var
1684 REAL(dp), DIMENSION(size(dat)) :: p, s
1685 LOGICAL, DIMENSION(size(dat)) :: maske
1686
1687 if (present(mask)) then
1688 if (size(mask) .ne. size(dat)) stop .ne.'Error variance_dp: size(mask) size(dat)'
1689 maske = mask
1690 n = real(count(maske), dp)
1691 else
1692 maske(:) = .true.
1693 n = real(size(dat), dp)
1694 end if
1695 if (n .le. (1.0_dp + tiny(1.0_dp))) stop 'variance_dp: n must be at least 2'
1696
1697 ! Average
1698 ave = sum(dat(:), mask = maske) / n
1699 s(:) = dat(:) - ave
1700 ! Variance / Standard deviation
1701 ep = sum(s(:), mask = maske)
1702 p(:) = s(:) * s(:)
1703 var = sum(p(:), mask = maske)
1704 variance_dp = (var - ep * ep / n) / (n - 1.0_dp)
1705
1706 END FUNCTION variance_dp
1707
1708
1709 FUNCTION variance_sp(dat, mask)
1710
1711 IMPLICIT NONE
1712
1713 REAL(sp), DIMENSION(:), INTENT(IN) :: dat
1714 LOGICAL, DIMENSION(:), OPTIONAL, INTENT(IN) :: mask
1715 REAL(sp) :: variance_sp
1716
1717 REAL(sp) :: n
1718
1719 REAL(sp) :: ep, ave, var
1720 REAL(sp), DIMENSION(size(dat)) :: p, s
1721 LOGICAL, DIMENSION(size(dat)) :: maske
1722
1723 if (present(mask)) then
1724 if (size(mask) .ne. size(dat)) stop .ne.'Error variance_sp: size(mask) size(dat)'
1725 maske = mask
1726 n = real(count(maske), sp)
1727 else
1728 maske(:) = .true.
1729 n = real(size(dat), sp)
1730 end if
1731 if (n .le. (1.0_sp + tiny(1.0_sp))) stop 'variance_sp: n must be at least 2'
1732
1733 ! Average
1734 ave = sum(dat(:), mask = maske) / n
1735 s(:) = dat(:) - ave
1736 ! Variance / Standard deviation
1737 ep = sum(s(:), mask = maske)
1738 p(:) = s(:) * s(:)
1739 var = sum(p(:), mask = maske)
1740 variance_sp = (var - ep * ep / n) / (n - 1.0_sp)
1741
1742 END FUNCTION variance_sp
1743
1744 ! ------------------------------------------------------------------
1745
1746END MODULE mo_moment
Mean absolute deviation from mean.
Definition mo_moment.f90:79
Mean of vector.
R-central moment variance.
R-central moment.
Correlation between two vectors.
Covariance between vectors.
Kurtosis of a vector.
Mean of a vector.
Mixed central moment variance.
R-s mixed central moment between vectors.
First four moments, stddev and mean absolute devation.
Skewness of a vector.
Standard deviation of a vector.
Standard deviation of a vector.
Define number representations.
Definition mo_kind.F90:17
integer, parameter sp
Single Precision Real Kind.
Definition mo_kind.F90:44
integer, parameter i4
4 Byte Integer Kind
Definition mo_kind.F90:40
integer, parameter dp
Double Precision Real Kind.
Definition mo_kind.F90:46
Statistical moments.
Definition mo_moment.f90:25
real(sp) function mean_sp(dat, mask)
Mean of a vector.