Skip to content

Commit 426d43f

Browse files
committed
stat_dev: addition of test and creation of modules and submodules with fypp
how to use pure functions inside submodules
1 parent 965f37b commit 426d43f

File tree

5 files changed

+175
-44
lines changed

5 files changed

+175
-44
lines changed

src/stdlib_experimental_stat.f90

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
module stdlib_experimental_stat
2+
3+
24
use stdlib_experimental_kinds, only: sp, dp, qp
35
implicit none
46
private
@@ -7,15 +9,34 @@ module stdlib_experimental_stat
79

810

911
interface mean
12+
module function mean_1_sp_sp(mat) result(res)
13+
real(sp), intent(in) :: mat(:)
14+
real(sp) ::res
15+
end function mean_1_sp_sp
1016
module function mean_1_dp_dp(mat) result(res)
1117
real(dp), intent(in) :: mat(:)
1218
real(dp) ::res
13-
end function
19+
end function mean_1_dp_dp
20+
module function mean_1_qp_qp(mat) result(res)
21+
real(qp), intent(in) :: mat(:)
22+
real(qp) ::res
23+
end function mean_1_qp_qp
24+
25+
module function mean_2_sp_sp(mat, dim) result(res)
26+
real(sp), intent(in) :: mat(:,:)
27+
integer, intent(in), optional :: dim
28+
real(sp), allocatable ::res(:)
29+
end function mean_2_sp_sp
1430
module function mean_2_dp_dp(mat, dim) result(res)
1531
real(dp), intent(in) :: mat(:,:)
1632
integer, intent(in), optional :: dim
1733
real(dp), allocatable ::res(:)
18-
end function
34+
end function mean_2_dp_dp
35+
module function mean_2_qp_qp(mat, dim) result(res)
36+
real(qp), intent(in) :: mat(:,:)
37+
integer, intent(in), optional :: dim
38+
real(qp), allocatable ::res(:)
39+
end function mean_2_qp_qp
1940
end interface
2041

2142
end module

src/stdlib_experimental_stat.fypp.f90

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module stdlib_experimental_stat
2+
3+
#:set REALKINDS = ["sp", "dp", "qp"]
4+
#:set KINDS = REALKINDS
5+
#:set TYPES = ["real({})".format(k) for k in REALKINDS]
6+
#:set ikt = list(zip(range(len(KINDS)), KINDS, TYPES))
7+
8+
use stdlib_experimental_kinds, only: sp, dp, qp
9+
implicit none
10+
private
11+
! Public API
12+
public :: mean
13+
14+
15+
interface mean
16+
#:for i1, k1, t1 in ikt
17+
module function mean_1_${k1}$_${k1}$(mat) result(res)
18+
${t1}$, intent(in) :: mat(:)
19+
${t1}$ ::res
20+
end function mean_1_${k1}$_${k1}$
21+
#:endfor
22+
23+
#:for i1, k1, t1 in ikt
24+
module function mean_2_${k1}$_${k1}$(mat, dim) result(res)
25+
${t1}$, intent(in) :: mat(:,:)
26+
integer, intent(in), optional :: dim
27+
${t1}$, allocatable ::res(:)
28+
end function mean_2_${k1}$_${k1}$
29+
#:endfor
30+
end interface
31+
32+
end module

src/stdlib_experimental_stat_mean.f90

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,56 @@
11
submodule (stdlib_experimental_stat) stdlib_experimental_stat_mean
2+
3+
24
use stdlib_experimental_optval, only: optval
35
implicit none
46

57
contains
68

9+
module function mean_1_sp_sp(mat) result(res)
10+
real(sp), intent(in) :: mat(:)
11+
real(sp) ::res
12+
13+
res = sum(mat) / real(size(mat), sp)
14+
15+
end function mean_1_sp_sp
716
module function mean_1_dp_dp(mat) result(res)
817
real(dp), intent(in) :: mat(:)
918
real(dp) ::res
1019

1120
res = sum(mat) / real(size(mat), dp)
1221

1322
end function mean_1_dp_dp
23+
module function mean_1_qp_qp(mat) result(res)
24+
real(qp), intent(in) :: mat(:)
25+
real(qp) ::res
26+
27+
res = sum(mat) / real(size(mat), qp)
28+
29+
end function mean_1_qp_qp
30+
31+
module function mean_2_sp_sp(mat, dim) result(res)
32+
real(sp), intent(in) :: mat(:,:)
33+
integer, intent(in), optional :: dim
34+
real(sp), allocatable ::res(:)
35+
36+
integer :: i
37+
integer :: dim_
38+
39+
dim_ = optval(dim, 1)
40+
41+
allocate(res(size(mat, dim_)))
42+
43+
if (dim_ == 1) then
44+
do i=1, size(mat, dim_)
45+
res(i) = mean_1_sp_sp(mat(i,:))
46+
end do
47+
else if (dim_ == 2) then
48+
do i=1, size(mat, dim_)
49+
res(i) = mean_1_sp_sp(mat(:,i))
50+
end do
51+
end if
1452

53+
end function mean_2_sp_sp
1554
module function mean_2_dp_dp(mat, dim) result(res)
1655
real(dp), intent(in) :: mat(:,:)
1756
integer, intent(in), optional :: dim
@@ -35,5 +74,28 @@ module function mean_2_dp_dp(mat, dim) result(res)
3574
end if
3675

3776
end function mean_2_dp_dp
77+
module function mean_2_qp_qp(mat, dim) result(res)
78+
real(qp), intent(in) :: mat(:,:)
79+
integer, intent(in), optional :: dim
80+
real(qp), allocatable ::res(:)
81+
82+
integer :: i
83+
integer :: dim_
84+
85+
dim_ = optval(dim, 1)
86+
87+
allocate(res(size(mat, dim_)))
88+
89+
if (dim_ == 1) then
90+
do i=1, size(mat, dim_)
91+
res(i) = mean_1_qp_qp(mat(i,:))
92+
end do
93+
else if (dim_ == 2) then
94+
do i=1, size(mat, dim_)
95+
res(i) = mean_1_qp_qp(mat(:,i))
96+
end do
97+
end if
98+
99+
end function mean_2_qp_qp
38100

39101
end submodule
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
submodule (stdlib_experimental_stat) stdlib_experimental_stat_mean
2+
3+
#:set REALKINDS = ["sp", "dp", "qp"]
4+
#:set KINDS = REALKINDS
5+
#:set TYPES = ["real({})".format(k) for k in REALKINDS]
6+
#:set ikt = list(zip(range(len(KINDS)), KINDS, TYPES))
7+
8+
use stdlib_experimental_optval, only: optval
9+
implicit none
10+
11+
contains
12+
13+
#:for i1, k1, t1 in ikt
14+
module function mean_1_${k1}$_${k1}$(mat) result(res)
15+
${t1}$, intent(in) :: mat(:)
16+
${t1}$ ::res
17+
18+
res = sum(mat) / real(size(mat), ${k1}$)
19+
20+
end function mean_1_${k1}$_${k1}$
21+
#:endfor
22+
23+
#:for i1, k1, t1 in ikt
24+
module function mean_2_${k1}$_${k1}$(mat, dim) result(res)
25+
${t1}$, intent(in) :: mat(:,:)
26+
integer, intent(in), optional :: dim
27+
${t1}$, allocatable ::res(:)
28+
29+
integer :: i
30+
integer :: dim_
31+
32+
dim_ = optval(dim, 1)
33+
34+
allocate(res(size(mat, dim_)))
35+
36+
if (dim_ == 1) then
37+
do i=1, size(mat, dim_)
38+
res(i) = mean_1_${k1}$_${k1}$(mat(i,:))
39+
end do
40+
else if (dim_ == 2) then
41+
do i=1, size(mat, dim_)
42+
res(i) = mean_1_${k1}$_${k1}$(mat(:,i))
43+
end do
44+
end if
45+
46+
end function mean_2_${k1}$_${k1}$
47+
#:endfor
48+
49+
end submodule

src/tests/stat/test_mean.f90

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,57 +3,24 @@ program test_mean
33
use stdlib_experimental_kinds, only: sp, dp
44
use stdlib_experimental_io, only: loadtxt
55
use stdlib_experimental_stat, only: mean
6-
use stdlib_experimental_error, only: error_stop
76
implicit none
87

98
real(sp), allocatable :: s(:, :)
109
real(dp), allocatable :: d(:, :)
11-
real(dp), allocatable :: res(:)
1210

13-
!call loadtxt("array1.dat", s)
14-
!call print_array(s)
11+
!sp
12+
call loadtxt("array1.dat", s)
1513

14+
call assert(sum( mean(s) - [1.5_sp, 3.5_sp, 5.5_sp, 7.5_sp] ) == 0.0_sp)
15+
call assert(sum( mean(s, dim = 2) - [4.0_sp, 5.0_sp] ) == 0.0_sp)
16+
17+
!dp
1618
call loadtxt("array1.dat", d)
1719

18-
res = mean(d)
19-
call print_array(d)
20-
print *,'Mean = ', res
21-
call assert(sum( res - [1.5_dp, 3.5_dp, 5.5_dp, 7.5_dp] ) == 0.0_dp)
22-
23-
res = mean(d, dim = 2)
24-
call print_array(d)
25-
print *,'Mean = ', res
26-
call assert(sum( res - [4.0_dp, 5.0_dp] ) == 0.0_dp)
27-
28-
!call loadtxt("array2.dat", d)
29-
!call print_array(d)
30-
!
31-
!call loadtxt("array3.dat", d)
32-
!call print_array(d)
33-
!
34-
!call loadtxt("array4.dat", d)
35-
!call print_array(d)
20+
call assert(sum( mean(d) - [1.5_dp, 3.5_dp, 5.5_dp, 7.5_dp] ) == 0.0_dp)
21+
call assert(sum( mean(d, dim = 2) - [4.0_dp, 5.0_dp] ) == 0.0_dp)
3622

37-
contains
3823

39-
subroutine print_array(a)
40-
class(*),intent(in) :: a(:, :)
41-
integer :: i
42-
print *, "Array, shape=(", size(a, 1), ",", size(a, 2), ")"
43-
44-
select type(a)
45-
type is(real(sp))
46-
do i = 1, size(a, 1)
47-
print *, a(i, :)
48-
end do
49-
type is(real(dp))
50-
do i = 1, size(a, 1)
51-
print *, a(i, :)
52-
end do
53-
class default
54-
call error_stop('The proposed type is not supported')
55-
end select
56-
57-
end subroutine
24+
contains
5825

5926
end program

0 commit comments

Comments
 (0)