This is the API documentation for statistical hypothesis tests.
fsml_ttest_1sample
The 1-sample t-test determines if the sample mean has the value specified in the null hypothesis.
The null hypothesis and alternative hypothesis can be written as: : , and :
The optional argument h1
lets you specify your alternative hypothesis further as "greater than" (h1 = "gt"
), "less than" (h1 = "lt"
), or "two-sided" (h1 = "two"
).
The test statstic is calculated as follows:
where (x
) are sample observations,
is the sample mean,
is the sample standard deviation,
is the sample size, and
(mu0
) is the population mean (null hypothesis expected value).
The procedure computes the test statistic (t
),
the degrees of freedom df
(), and
the p-value (p
).
call
fsml_ttest_1sample(x, mu0, t, df, p [, h1])
x
: A rank-1 array of type real
.
mu0
: A scalar of type real
.
h1
: An optional argument and character
string. If passed, it must be one of the following: "lt", "gt", or "two". If not passed, it will default to "two".
Invalid argument values will result in the return of a sentinel value.
t
: A scalar of the same type as x
.
df
: A scalar of the same type as x
.
p
: A scalar of the same type as x
.
fsml_ttest_paired
The paired sample t-test (or dependent sample t-test) determines if the mean difference between two sample sets are zero. It is mathematically equivalent to the 1-sample t-test conducted on the difference vector with .
The null hypothesis and alternative hypothesis can be written as: : , and :
The optional argument h1
lets you specify your alternative hypothesis further as "greater than" (h1 = "gt"
), "less than" (h1 = "lt"
), or "two-sided" (h1 = "two"
).
The test statstic is calculated as follows:
where is the mean of the differences between the sample sets (x1
and x2
),
is the standard deviation of the differences, and
is the number of paired samples.
The procedure computes the test statistic (t
),
the degrees of freedom df
(), and
the p-value (p
).
call
fsml_ttest_paired(x1, x2, t, df, p [, h1])
x1
: A rank-1 array of type real
. It must be the same size as x2
.
x2
: A rank-1 array of type real
. It must be the same size as x1
.
h1
: An optional argument and character
string. If passed, it must be one of the following: "lt", "gt", or "two". If not passed, it will default to "two".
Invalid argument values will result in the return of a sentinel value.
t
: A scalar of the same type as x
.
df
: A scalar of the same type as x
.
p
: A scalar of the same type as x
.
fsml_ttest_2sample
The 2-sample t-test determines if two population means and are the same. The procedure handles 2-sample t-tests for equal variances and Welch's t-tests for unequal variances.
The null hypothesis and alternative hypothesis can be written as: : , and :
The optional argument h1
lets you specify your alternative hypothesis further as "greater than" (h1 = "gt"
), "less than" (h1 = "lt"
), or "two-sided" (h1 = "two"
).
The procedure computes the test statistic (t
),
the degrees of freedom (df
), and
the p-value (p
).
The procedure defaults to Welch's t-test for unequal variances (eq_var = .false.
) if not specified differently.
In this case, the test statstic (t
) is calculated as follows:
where and are the sample means
and are the sample standard deviations, and
and are the sample sizes.
The degrees of freedom (df
) is approximated with the Welch–Satterthwaite equation:
If variances are assumed to be equal (eq_var = .true.
),
the procedure conducts a 2 sample t-test for equal variances, using the pooled standard
deviation to calculate the t-statistic:
In case of assumed equal variances, the degrees of freedom (df
) is calculated as follows:
call
fsml_ttest_2sample(x1, x2, t, df, p [, eq_var, h1])
x1
: A rank-1 array of type real
. It must be the same size as x2
.
x2
: A rank-1 array of type real
. It must be the same size as x1
.
eq_var
: An optional argument of type logical
. If not passed, it will default to false.
h1
: An optional argument and character
string. If passed, it must be one of the following: "lt", "gt", or "two". If not passed, it will default to "two".
Invalid argument values will result in the return of a sentinel value.
t
: A scalar of the same type as x
.
df
: A scalar of the same type as x
.
p
: A scalar of the same type as x
.
fsml_anova_1way
The one-way ANOVA (Analysis of Variance) tests whether three or more population means are equal.
The null hypothesis and alternative hypothesis are defined as: : , and : At least one differs from the others.
The data is passed to the procedure as a rank-2 array x
, where each column is a group of observations.
The procedure partitions the total variability in the data ( ) into
variability between groups ( ; variability explained by groups ), and
variability within groups ( ; unexplained or residual variability ), so that
The F-statistic (f
) is the ratio of the mean sum of squares between groups
to the mean sum of squares within groups:
where is the number of groups, is the total number of observations,
is the sum of squares between groups, and
is the sum of squares within groups.
The degrees of freedom are between groups (df_b
)
and within groups (df_w
).
The resulting p-value (p
) is computed from the F-distribution:
The ANOVA makes the assumptions that a) the groups are independent, b) the observations within each group are normally distributed, and c) The variances within groups are equal.
call
fsml_anova_1way(x, f, df_b, df_w, p)
x
: A rank-2 array of type real
. It must have at least 2 rows and 2 columns.
Invalid argument values will result in the return of a sentinel value.
f
: A scalar of the same type as x
.
df_b
: A scalar of the same type as x
.
df_w
: A scalar of the same type as x
.
p
: A scalar of the same type as x
.
fsml_signedrank_1sample
The 1-sample Wilcoxon signed rank test is a non-parametric test that
determines if data (x
) comes from a symmetric population with centre (mu0
).
It can be regarded as a non-parametric version of the 1-sample t-test.
If the data consists of independent and similarly distributed samples from distribution , the null hypothesis can be expressed as:
is symmetric around .
The default alternative hypothesis is two-sided and also be
set explicitly (h1 = "two"
). It can be expressed as:
is symmetric around
If the alternative hypothesis is set to "greater than" (h1 = "gt"
), it is:
is symmetric around
If the alternative hypothesis is set to "less than" (h1 = "lt"
), it is:
is symmetric around
The test statistic (w
) is the smaller of the sum of positive and
negative signed ranks:
The procedure computes the W statistic (w
) and the p-value (p
).
The procedure takes into consideration tied ranks.
call
fsml_signedrank_1sample(x, mu0, w, p [,h1])
x
: A rank-1 array of type real
.
mu0
: A scalar of type real
.
h1
: An optional argument and character
string. If passed, it must be one of the following: "lt", "gt", or "two". If not passed, it will default to "two".
Invalid argument values will result in the return of a sentinel value.
w
: A scalar of the same type as x
.
p
: A scalar of the same type as x
.
fsml_signedrank_paired
The Wilcoxon signed rank test is a non-parametric test that determines
if two related paired samples and
(x1
and x2
) come from the same distribution.
It can be regarded as a non-parametric version of the paired t-test.
The Wilcoxon signed rank test is mathematically equivalent to the 1-sample Wilcoxon signed rank test conducted on the difference vector with set to zero. Consequently, the the null hypothesis can be expressed as:
Samples are symmetric around .
The default alternative hypothesis is two-sided and also be
set explicitly (h1 = "two"
). It can be expressed as:
Samples are symmetric around
If the alternative hypothesis is set to "greater than" (h1 = "gt"
), it is:
Samples are symmetric around
If the alternative hypothesis is set to "less than" (h1 = "lt"
), it is:
Samples are symmetric around
The test statistic (w
) is the smaller of the sum of positive and
negative signed ranks:
The procedure computes the W statistic (w
) and the p-value (p
).
The procedure takes into consideration tied ranks.
call
fsml_signedrank_paired(x1, x2, w, p [,h1])
x1
: A rank-1 array of type real
. It must be the same size as x2
.
x2
: A rank-1 array of type real
. It must be the same size as x1
.
h1
: An optional argument and character
string. If passed, it must be one of the following: "lt", "gt", or "two". If not passed, it will default to "two".
Invalid argument values will result in the return of a sentinel value.
w
: A scalar of the same type as x
.
p
: A scalar of the same type as x
.
fsml_ranksum
The ranks sum test (Wilcoxon rank-sum test or Mann–Whitney U test) is a
non-parametric test to determine if two independent samples and
(x1
and x2
) are have the same distribution.
It is the non-parametric equivalent of the 2-sample t-test.
The null hypothesis and alternative hypothesis can be written as: : the distributions of and are equal. : the distributions of and are not equal.
The Mann–Whitney U statistic is calculated for each sample as follows: where is the sum of ranks of sample set and is the sample size of sample set . The final U statistic is:
The procedure computes the U statistic (u
) and the p-value (p
).
The procedure takes into consideration tied ranks.
call
fsml_ranksum(x1, x2, u, p [,h1])
x1
: A rank-1 array of type real
. It must be the same size as x2
.
x2
: A rank-1 array of type real
. It must be the same size as x1
.
h1
: An optional argument and character
string. If passed, it must be one of the following: "lt", "gt", or "two". If not passed, it will default to "two".
Invalid argument values will result in the return of a sentinel value.
u
: A scalar of the same type as x
.
p
: A scalar of the same type as x
.
fsml_kruskalwallis
The Kruskal-Wallis H-test is used to determine whether samples originate from the same distribution without assuming normality. It is therefore considered a nonparametric alternative to the one-way ANOVA (Analysis of Variance).
The null hypothesis and alternative hypothesis are defined as: : The populations have the same distribution (medians are equal), and : At least one population differs from the others.
The data is passed to the procedure as a rank-2 array x
, where each column is a group of observations.
All values are ranked across the entire dataset, with tied values assigned the average rank.
The Kruskal-Wallis H-statistic (h
) is computed as:
where: - is the total number of observations, - is the number of groups, - is the number of observations in group , and - is the sum of ranks in group .
The degrees of freedom are:
and returned as df
.
The p-value (p
) is computed from the chi-squared distribution:
The Kruskal-Wallis test assumes that: a) all groups are independent, b) the response variable is ordinal or continuous, c) the group distributions have the same shape, and d) observations are independent both within and between groups.
call
fsml_kruskalwallis(x, h, df, p)
x
: A rank-2 array of type real
. It must have at least 2 rows and 2 columns.
Invalid argument values will result in the return of a sentinel value.
h
: A scalar of the same type as x
.
df
: A scalar of the same type as x
.
p
: A scalar of the same type as x
.
program example_tst
! |--------------------------------------------------------------------|
! | fsml - fortran statistics and machine learning library |
! | |
! | about |
! | ----- |
! | Examples for statistical tests (tst module). |
! | |
! | license : MIT |
! | author : Sebastian G. Mutz (sebastian@sebastianmutz.com) |
! |--------------------------------------------------------------------|
use :: fsml
use :: fsml_ini ! import wp; alternatively: iso_fortran_env, wp => real64
implicit none
! ==== Description
!! The programme demonstrates the use of all statistical tests based on
!! the same few data vectors.
! ==== Declarations
integer(i4), parameter :: n1 = 10, n2 = 13
real(wp) , parameter :: mu = 1.25_wp
real(wp) , parameter :: x1(n1) = &
[1.10_wp, &
1.02_wp, &
1.12_wp, &
2.01_wp, &
1.92_wp, &
1.01_wp, &
1.10_wp, &
1.26_wp, &
1.51_wp, &
1.01_wp]
real(wp) , parameter :: x2(n2) = &
[2.10_wp, &
1.02_wp, &
1.22_wp, &
1.05_wp, &
0.95_wp, &
1.02_wp, &
2.00_wp, &
1.05_wp, &
1.12_wp, &
1.20_wp, &
1.12_wp, &
1.01_wp, &
1.12_wp]
real(wp) , parameter :: x2d(5,3) = reshape([ &
& 2.1_wp, 2.5_wp, 1.9_wp, 2.3_wp, 2.0_wp, & ! Group 1
& 2.4_wp, 2.8_wp, 2.6_wp, 3.2_wp, 2.9_wp, & ! Group 2
& 2.0_wp, 2.8_wp, 2.1_wp, 2.3_wp, 2.9_wp & ! Group 3
& ], shape=[5,3])
real(wp) :: t, p, df, df1, df2
! ==== Instructions
! ---- Parametric Tests
print*
write(*,'(A)') " Parametric Tests"
write(*,'(A)') " ================"
print*
! 1-sample t-test
call fsml_ttest_1sample(x1, mu, t, df, p, h1="two")
write(*,'(A)') "> 1-sample student's t-test"
write(*,'(A,10F10.4)') " samples: ", x1
write(*,'(A,F10.4)') " test statistic (t): ", t
write(*,'(A,F10.4)') " degrees of freedom: ", df
write(*,'(A,F10.4)') " p-value: ", p
print*
! test statistic (t): 0.4672
! degrees of freedom: 9.0000
! p-value: 0.6514
! paired t-test
call fsml_ttest_paired(x1, x2(:n1), t, df, p, h1="two")
write(*,'(A)') "> 2-sample paired t-test"
write(*,'(A,10F10.4)') " samples 1: ", x1
write(*,'(A,10F10.4)') " samples 2: ", x2(:n1)
write(*,'(A,F10.4)') " test statistic (t): ", t
write(*,'(A,F10.4)') " degrees of freedom: ", df
write(*,'(A,F10.4)') " p-value: ", p
print*
! test statistic (t): 0.1584
! degrees of freedom: 9.0000
! p-value: 0.8776
! 2-sample pooled t-test (assume equal variances)
call fsml_ttest_2sample(x1, x2, t, df, p, eq_var=.true., h1="two")
write(*,'(A)') "> 2-sample pooled t-test"
write(*,'(A,10F10.4)') " samples 1: ", x1
write(*,'(A,13F10.4)') " samples 2: ", x2
write(*,'(A,F10.4)') " test statistic (t): ", t
write(*,'(A,F10.4)') " degrees of freedom: ", df
write(*,'(A,F10.4)') " p-value: ", p
print*
! test statistic (t): 0.4862
! degrees of freedom: 21.0000
! p-value: 0.6319
! 2-sample t-test for unequal variances (Welch's t-test)
call fsml_ttest_2sample(x1, x2, t, df, p, eq_var=.false., h1="two")
write(*,'(A)') "> 2-sample Welch's t-test"
write(*,'(A,10F10.4)') " samples 1: ", x1
write(*,'(A,13F10.4)') " samples 2: ", x2
write(*,'(A,F10.4)') " test statistic (t): ", t
write(*,'(A,F10.4)') " degrees of freedom: ", df
write(*,'(A,F10.4)') " p-value: ", p
print*
! test statistic (t): 0.4850
! degrees of freedom: 19.3423
! p-value: 0.6331
! 1-way ANOVA
call fsml_anova_1way(x2d, t, df1, df2, p)
write(*,'(A)') "> 1-way ANOVA"
write(*,'(A,5F10.4)') " group 1: ", x2d(:, 1)
write(*,'(A,5F10.4)') " group 2: ", x2d(:, 2)
write(*,'(A,5F10.4)') " group 3: ", x2d(:, 3)
write(*,'(A,F10.4)') " test statistic (F): ", t
write(*,'(A,F10.4)') " df between: ", df1
write(*,'(A,F10.4)') " df within: ", df2
write(*,'(A,F10.4)') " p-value: ", p
! test statistic (F): 4.5868
! df between: 2.0000
! df within: 12.0000
! p-value: 0.0331
! ---- Non-Parametric Tests
print*
write(*,'(A)') " Non-Parametric Tests"
write(*,'(A)') " ===================="
print*
! 1-sample Wilcoxon signed rank test
call fsml_signedrank_1sample(x1, mu, t, p, h1="two")
write(*,'(A)') "> 1-sample Wilcoxon signed rank test"
write(*,'(A,10F10.4)') " samples: ", x1
write(*,'(A,F10.4)') " test statistic (w): ", t
write(*,'(A,F10.4)') " p-value: ", p
print*
! test statistic (w): 27.0000
! p-value: 0.9594
! 2-sample (paired sample) Wilcoxon signed rank test
call fsml_signedrank_paired(x1, x2(:n1), t, p, h1="two")
write(*,'(A)') "> paired sample Wilcoxon signed rank test"
write(*,'(A,10F10.4)') " samples 1: ", x1
write(*,'(A,10F10.4)') " samples 2: ", x2(:n1)
write(*,'(A,F10.4)') " test statistic (w): ", t
write(*,'(A,F10.4)') " p-value: ", p
print*
! test statistic (w): 21.0000
! p-value: 0.8590
! 2-sample Wilcoxon Mann-Whitney U rank sum test
call fsml_ranksum(x1, x2, t, p, h1="two")
write(*,'(A)') "> Mann-Whitney U rank sum test"
write(*,'(A,10F10.4)') " samples 1: ", x1
write(*,'(A,13F10.4)') " samples 2: ", x2
write(*,'(A,F10.4)') " test statistic (U): ", t
write(*,'(A,F10.4)') " p-value: ", p
print*
! test statistic (U): 59.5000
! p-value: 0.7330
! Kruskal Wallis H test
call fsml_kruskalwallis(x2d, t, df, p)
write(*,'(A)') "> Kruskal Wallis H test"
write(*,'(A,5F10.4)') " group 1: ", x2d(:, 1)
write(*,'(A,5F10.4)') " group 2: ", x2d(:, 2)
write(*,'(A,5F10.4)') " group 3: ", x2d(:, 3)
write(*,'(A,F10.4)') " test statistic (H): ", t
write(*,'(A,F10.4)') " degrees of freedom ", df
write(*,'(A,F10.4)') " p-value: ", p
! test statistic (H): 5.9850
! degrees of freedom 2.0000
! p-value: 0.0502
end program example_tst