Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d1d665b

Browse files
committedJan 21, 2020
Addition of stdlib_experimental_stats function mean
Squashed commit of the following: commit 3266163 Merge: e96c12d 4274f0d Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 20:47:32 2020 +0100 modification of CMake and Makefile Merge branch 'stat_cmake' into stat_dev commit 4274f0d Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 20:44:24 2020 +0100 stat_cmake: update Makefile commit 17e3d16 Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 20:35:19 2020 +0100 second try cmake commit 397eb18 Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 20:18:37 2020 +0100 Modifications of CMake for tests on Ubuntu 7 commit e96c12d Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 19:40:05 2020 +0100 small change in md commit 7eec9ae Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 19:37:06 2020 +0100 stat_dev: renamed stat to stats commit 8199b6d Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 19:26:20 2020 +0100 stat_dev: changed spec commit b1c481d Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 19:15:25 2020 +0100 stat_dev: modifs following comments commit e64657c Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 14:23:59 2020 +0100 stat_dev: addition of .md file for mean commit ad504e8 Merge: 5a1adcb bab50e3 Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 13:16:21 2020 +0100 Merge remote-tracking branch 'jvdp1/stat_dev_1' into stat_dev commit bab50e3 Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 13:13:00 2020 +0100 stat_dev_1: changed all to iterations commit 8d4c11f Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 10:31:26 2020 +0100 stat_dev_1:moved all calls to mean functions to loops commit 922e523 Author: Vandenplas, Jeremie <[email protected]> Date: Tue Jan 21 09:13:10 2020 +0100 stat_dev_1: update test_mean commit 5a1adcb Author: Vandenplas, Jeremie <[email protected]> Date: Mon Jan 20 23:55:15 2020 +0100 stat_dev: inverting loops for efficiency commit 86970ae Author: Vandenplas, Jeremie <[email protected]> Date: Mon Jan 20 22:54:55 2020 +0100 stat_dev: use specific interface commit 6574a67 Author: Vandenplas, Jeremie <[email protected]> Date: Mon Jan 20 22:36:33 2020 +0100 stat_dev: addition of calls to error_stop commit e98090b Author: Vandenplas, Jeremie <[email protected]> Date: Mon Jan 20 21:32:27 2020 +0100 stat_dev: extension to rank 15 commit e0e3092 Author: Vandenplas, Jeremie <[email protected]> Date: Mon Jan 20 12:46:44 2020 +0100 stat_dev: simplified merge commit 22ff6e4 Author: Vandenplas, Jeremie <[email protected]> Date: Mon Jan 20 10:38:41 2020 +0100 stat_dev: progress rank 3 commit 7612613 Author: Vandenplas, Jeremie <[email protected]> Date: Mon Jan 20 10:34:06 2020 +0100 stat_dev: add rank 3 commit 60ab523 Author: Vandenplas, Jeremie <[email protected]> Date: Sun Jan 19 22:14:51 2020 +0100 stat_dev: addition of integer cases commit 6fb6ca5 Author: Vandenplas, Jeremie <[email protected]> Date: Sun Jan 19 21:03:46 2020 +0100 stat_dev: avoid allocatable functions commit a1c6353 Author: Vandenplas, Jeremie <[email protected]> Date: Sun Jan 19 20:11:49 2020 +0100 modification to have the same behaviour as Fortran sum commit 72500e1 Author: Vandenplas, Jeremie <[email protected]> Date: Sun Jan 19 15:23:34 2020 +0100 stat_dev: add error_stop commit 1272574 Author: Vandenplas, Jeremie <[email protected]> Date: Sun Jan 19 15:02:52 2020 +0100 stat_dev: update Makefile commit 426d43f Author: Vandenplas, Jeremie <[email protected]> Date: Sun Jan 19 12:21:09 2020 +0100 stat_dev: addition of test and creation of modules and submodules with fypp how to use pure functions inside submodules commit 965f37b Author: Vandenplas, Jeremie <[email protected]> Date: Sun Jan 19 11:35:11 2020 +0100 moved to submodules how to use pure functions in submodules commit d9af336 Author: Vandenplas, Jeremie <[email protected]> Date: Sun Jan 19 11:22:52 2020 +0100 stat_dev: init commit dc7e49b Merge: f300f4a cb7cf71 Author: Ondřej Čertík <[email protected]> Date: Tue Jan 14 11:11:12 2020 -0700 Merge pull request fortran-lang#109 from nncarlson/target-include Update CMakeLists handling of .mod files commit cb7cf71 Author: Neil Carlson <[email protected]> Date: Mon Jan 13 16:38:12 2020 -0700 Update CMakeLists handling of .mod files commit f300f4a Merge: 12bd060 0ea0ee1 Author: Milan Curcic <[email protected]> Date: Wed Jan 8 18:20:09 2020 -0500 Merge pull request fortran-lang#54 from scivision/systemlib add system module commit 0ea0ee1 Author: Michael Hirsch, Ph.D <[email protected]> Date: Mon Jan 6 11:41:46 2020 -0500 make sleep test automated check with system_clock commit c8974dc Author: Michael Hirsch, Ph.D <[email protected]> Date: Mon Dec 30 16:20:55 2019 -0500 add system module There are a number of capabilities it would be useful to bring from cstdlib and STL. This is an initial demonstration, replacing the non-cross-compiler sleep() with a standard implmeentation that works across compilers and operating systems, with millisecond integer input. commit 12bd060 Merge: 006beda e1d861d Author: Ondřej Čertík <[email protected]> Date: Wed Jan 8 11:52:06 2020 -0700 Merge pull request fortran-lang#97 from certik/goals Add Goals and Motivation section into README commit e1d861d Author: Ondřej Čertík <[email protected]> Date: Wed Jan 8 10:00:27 2020 -0700 Update README.md commit ca4554a Author: Ondřej Čertík <[email protected]> Date: Wed Jan 8 09:49:39 2020 -0700 Add Goals and Motivation section into README commit 006beda Merge: 1926ade e81d295 Author: Ondřej Čertík <[email protected]> Date: Tue Jan 7 15:41:39 2020 -0700 Merge pull request fortran-lang#94 from certik/workflow Document workflow based on the discussion in #5 commit e81d295 Author: Ondřej Čertík <[email protected]> Date: Tue Jan 7 08:20:24 2020 -0700 Update the workflow based on feedback commit 1926ade Merge: 7a6108e f857482 Author: Ondřej Čertík <[email protected]> Date: Tue Jan 7 08:01:39 2020 -0700 Merge pull request fortran-lang#96 from nshaffer/dev-optval Make optval pure or pure elemental where possible commit f857482 Merge: 274a2bb 7a6108e Author: Ondřej Čertík <[email protected]> Date: Tue Jan 7 07:48:17 2020 -0700 Merge branch 'master' into dev-optval commit 274a2bb Author: Nathaniel Shaffer <[email protected]> Date: Tue Jan 7 07:00:21 2020 -0700 add tests for 1d arrays (reals, ints, logical) commit e06e322 Author: Nathaniel Shaffer <[email protected]> Date: Tue Jan 7 06:58:14 2020 -0700 add "elemental" and/or "pure" attributes where possible commit 92926e0 Author: Ondřej Čertík <[email protected]> Date: Mon Jan 6 15:01:31 2020 -0700 Make the specification requirement part of step 3. commit 1f56d0d Author: Ondřej Čertík <[email protected]> Date: Mon Jan 6 12:09:48 2020 -0700 Document workflow based on the discussion in #5 commit 7a6108e Merge: e2b0cda a606606 Author: Izaak "Zaak" Beekman <[email protected]> Date: Mon Jan 6 13:02:55 2020 -0500 ci ctest enhancements (fortran-lang#92) Merge [scivision:citime] into master [scivision:citime]: https://github.com/scivision/stdlib/tree/citime commit a606606 Author: Michael Hirsch, Ph.D <[email protected]> Date: Mon Jan 6 11:50:17 2020 -0500 ci ctest enhancements commit e2b0cda Merge: 57d99f8 f0a6886 Author: Ondřej Čertík <[email protected]> Date: Mon Jan 6 08:01:24 2020 -0700 Merge pull request fortran-lang#90 from certik/stream Use access = "stream" by default commit f0a6886 Author: Ondřej Čertík <[email protected]> Date: Mon Jan 6 07:56:18 2020 -0700 Update src/stdlib_experimental_io.f90 Co-Authored-By: Jeremie Vandenplas <[email protected]> commit 05540fd Author: Ondřej Čertík <[email protected]> Date: Mon Jan 6 07:52:24 2020 -0700 Use access = "stream" by default commit 57d99f8 Merge: c3e4816 d845f2d Author: Ondřej Čertík <[email protected]> Date: Mon Jan 6 07:42:42 2020 -0700 Merge pull request fortran-lang#89 from pdebuyl/qsavetxt_format_string Use explicit formatting in qsavetxt commit d845f2d Author: Pierre de Buyl <[email protected]> Date: Mon Jan 6 10:35:55 2020 +0100 Use explicit formatting in qsavetxt
1 parent c3e4816 commit d1d665b

27 files changed

+33319
-50
lines changed
 

‎.github/workflows/CI.yml

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ env:
77
CMAKE_BUILD_PARALLEL_LEVEL: "2" # 2 cores on each GHA VM, enable parallel builds
88
CTEST_OUTPUT_ON_FAILURE: "ON" # This way we don't need a flag to ctest
99
CTEST_PARALLEL_LEVEL: "2"
10+
CTEST_TIME_TIMEOUT: "5" # some failures hang forever
1011
HOMEBREW_NO_ANALYTICS: "ON" # Make Homebrew installation a little quicker
1112
HOMEBREW_NO_AUTO_UPDATE: "ON"
1213
HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: "ON"
@@ -55,10 +56,15 @@ jobs:
5556
run: cmake -Wdev -DCMAKE_BUILD_TYPE=Release -S . -B build
5657

5758
- name: Build and compile
58-
run: cmake --build build || cmake --build build --verbose --parallel 1
59+
run: cmake --build build
60+
61+
- name: catch build fail
62+
run: cmake --build build --verbose --parallel 1
63+
if: failure()
5964

6065
- name: test
61-
run: cmake --build build --target test
66+
run: ctest --parallel --output-on-failure
67+
working-directory: build
6268

6369
- name: Test in-tree builds
6470
if: contains( matrix.gcc_v, '9') # Only test one compiler on each platform

‎.github/workflows/ci_windows.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on: [push, pull_request]
44

55
env:
66
CI: "ON"
7+
CTEST_TIME_TIMEOUT: "5" # some failures hang forever
78

89
jobs:
910
Build:
@@ -24,7 +25,8 @@ jobs:
2425
- name: CMake build
2526
run: cmake --build build --parallel
2627

27-
- run: cmake --build build --verbose --parallel 1
28+
- name: catch build fail
29+
run: cmake --build build --verbose --parallel 1
2830
if: failure()
2931

3032
- name: CTest

‎CMakeLists.txt

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@ cmake_minimum_required(VERSION 3.14.0)
22
project(stdlib Fortran)
33
enable_testing()
44

5-
# this avoids stdlib and projects using stdlib from having to introspect stdlib's directory structure
6-
# FIXME: this eventually needs to be handled more precisely, as this spills all .mod/.smod into one directory
7-
# and thereby can clash if module/submodule names are the same in different parts of library
8-
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR})
9-
105
# --- compiler options
116
if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)
127
add_compile_options(-fimplicit-none)
@@ -20,6 +15,7 @@ endif()
2015
include(CheckFortranSourceCompiles)
2116
include(CheckFortranSourceRuns)
2217
check_fortran_source_compiles("error stop i; end" f18errorstop SRC_EXT f90)
18+
check_fortran_source_compiles("real, allocatable :: array(:, :, :, :, :, :, :, :, :, :); end" f03rank SRC_EXT f90)
2319
check_fortran_source_runs("use, intrinsic :: iso_fortran_env, only : real128; real(real128) :: x; x = x+1; end" f03real128)
2420

2521
add_subdirectory(src)

‎README.md

+26-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Fortran Standard Library
22

3+
[![Actions Status](https://github.com/fortran-lang/stdlib/workflows/CI/badge.svg)](https://github.com/fortran-lang/stdlib/actions)
4+
[![Actions Status](https://github.com/fortran-lang/stdlib/workflows/CI_windows/badge.svg)](https://github.com/fortran-lang/stdlib/actions)
5+
6+
7+
## Goals and Motivation
8+
9+
The Fortran Standard, as published by the ISO (https://wg5-fortran.org/), does
10+
not have a Standard Library. The goal of this project is to provide a community
11+
driven and agreed upon *de facto* "standard" library for Fortran, called a
12+
Fortran Standard Library (`stdlib`). We have a rigorous process how `stdlib` is
13+
developed as documented in our [Workflow](WORKFLOW.md). `stdlib` is both a
14+
specification and a reference implementation. We are cooperating with the
15+
Fortran Standards Committee (e.g., the effort
16+
[started](https://github.com/j3-fortran/fortran_proposals/issues/104) at the J3
17+
committee repository) and the plan is to continue working with the Committee in
18+
the future (such as in the step 5. in the [Workflow](WORKFLOW.md) document), so
19+
that if the Committee wants to standardize some feature already available in `stdlib`, it would
20+
base it on `stdlib`'s implementation.
21+
322
## Scope
423

524
The goal of the Fortran Standard Library is to achieve the following general scope:
@@ -16,19 +35,19 @@ The goal of the Fortran Standard Library is to achieve the following general sco
1635

1736
### Get the code
1837

19-
```
38+
```sh
2039
git clone https://github.com/fortran-lang/stdlib
2140
cd stdlib
2241
```
2342

2443
### Build with CMake
2544

26-
```
27-
mkdir build
28-
cd build
29-
cmake ..
30-
make
31-
ctest
45+
```sh
46+
cmake -B build
47+
48+
cmake --build build
49+
50+
cmake --build build --target test
3251
```
3352

3453
### Build with make

‎WORKFLOW.md

+55-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,57 @@
11
# Workflow for the Fortran stdlib contributors
22

3-
This document will describe the workflow we'll follow when developing the Fortran stdlib.
4-
It's largely to be discussed and decided.
5-
For now, take a look at the [issues](https://github.com/fortran-lang/stdlib).
3+
This document describes our current workflow.
4+
5+
We welcome everyone and anyone to participate and propose additions to stdlib.
6+
It is okay if you do not have experience for specification or implementation,
7+
but have an idea for stdlib. If the idea is popular among the community, more
8+
experienced contributors will help it through all 5 steps.
9+
10+
11+
1. **Idea**: You have an idea or a proposal. Open an
12+
[issue](https://github.com/fortran-lang/stdlib/issues) to discuss it. This
13+
is on the level of "is there interest in having image reader/writer
14+
functions in stdlib?" The goal of this step is to find out if the community
15+
is interested in having this functionality as part of stdlib.
16+
17+
2. **API**: When there seems to be significant interest in the proposal (vast
18+
majority of participants think it is a good idea), move on to discuss the
19+
specific API. It's OK to propose the API off the bat if you already have an
20+
idea for it. This step is exploratory and its goal is to find out what the
21+
API should *look* and *feel* like.
22+
23+
3. **Specification**: Discuss the API and iterate. When there is vast majority
24+
approval for the API, move on to implement it and submit a PR. Small PRs are
25+
always better than large. It is OK to implement only a few functions of a
26+
new module, and continue work on the others in a later PR. All new
27+
functionality goes into an "experimental" namespace
28+
(`stdlib_experimental_*.f90`). As part of the PR, when submitting a new
29+
public facing API, please provide the initial draft of the specification
30+
document as well as the the initial reference implementation of this
31+
specification. The specification is a document that describes the API and
32+
the functionality, so that anyone can use it to create an implementation
33+
from scratch without looking at `stdlib`. The `stdlib` library then provides
34+
the reference implementation.
35+
36+
4. **Implementation** in experimental: When opening a PR, request reviews from
37+
one or more people that are most relevant to it. These are likely to be
38+
people involved in prior steps of the workflow. Other contributors (not
39+
explicitly invited) are encouraged to provide reviews and suggestions as
40+
well. Iterate until all (or most) participants are on the same page.
41+
We can merge when there is vast majority approval of the PR.
42+
43+
5. **Release**: Moving from experimental to release. The experimental
44+
"namespace" contains new functionality together with its specification. In
45+
order to move from experimental to release, the specification document must
46+
be approved by the wide community and the standards committee (informally).
47+
If that happens, it has now been blessed for broad use and we can move the
48+
code into the main section of `stdlib`, and the particular specification
49+
document becomes part of the Fortran Standard Library.
50+
51+
52+
Note: the general term "vast majority" above means at least 80%, but ultimately
53+
it is left to our best judgement to ensure that the community agrees that each
54+
PR and proposal was approved by "vast majority".
55+
56+
You are welcome to propose changes to this workflow by opening an
57+
[issue](https://github.com/fortran-lang/stdlib/issues).

‎src/CMakeLists.txt

+19-1
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,40 @@ set(SRC
22
stdlib_experimental_ascii.f90
33
stdlib_experimental_io.f90
44
stdlib_experimental_error.f90
5-
stdlib_experimental_optval.f90
65
stdlib_experimental_kinds.f90
6+
stdlib_experimental_optval.f90
7+
stdlib_experimental_system.F90
78
)
89

910
add_library(fortran_stdlib ${SRC})
1011

12+
set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/)
13+
set_target_properties(fortran_stdlib PROPERTIES
14+
Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR})
15+
target_include_directories(fortran_stdlib PUBLIC
16+
$<BUILD_INTERFACE:${LIB_MOD_DIR}>
17+
$<INSTALL_INTERFACE:include>
18+
)
19+
1120
if(f18errorstop)
1221
target_sources(fortran_stdlib PRIVATE f18estop.f90)
1322
else()
1423
target_sources(fortran_stdlib PRIVATE f08estop.f90)
1524
endif()
1625

26+
if(f03rank)
27+
target_sources(fortran_stdlib PRIVATE f03_stdlib_experimental_stats.f90)
28+
target_sources(fortran_stdlib PRIVATE f03_stdlib_experimental_stats_mean.f90)
29+
else()
30+
target_sources(fortran_stdlib PRIVATE f90_stdlib_experimental_stats.f90)
31+
target_sources(fortran_stdlib PRIVATE f90_stdlib_experimental_stats_mean.f90)
32+
endif()
33+
1734
add_subdirectory(tests)
1835

1936
install(TARGETS fortran_stdlib
2037
RUNTIME DESTINATION bin
2138
ARCHIVE DESTINATION lib
2239
LIBRARY DESTINATION lib
2340
)
41+
install(DIRECTORY ${LIB_MOD_DIR} DESTINATION include)

‎src/Makefile.manual

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ SRC = stdlib_experimental_ascii.f90 \
33
stdlib_experimental_io.f90 \
44
stdlib_experimental_optval.f90 \
55
stdlib_experimental_kinds.f90 \
6-
f18estop.f90
6+
f18estop.f90 \
7+
f03_stdlib_experimental_stats.f90 \
8+
f03_stdlib_experimental_stats_mean.f90
79

810
LIB = libstdlib.a
911

@@ -34,3 +36,7 @@ stdlib_experimental_io.o: \
3436
stdlib_experimental_optval.o \
3537
stdlib_experimental_kinds.o
3638
stdlib_experimental_optval.o: stdlib_experimental_kinds.o
39+
f03_stdlib_experimental_stats_mean.o: \
40+
stdlib_experimental_optval.o \
41+
stdlib_experimental_kinds.o \
42+
f03_stdlib_experimental_stats.o

‎src/f03_stdlib_experimental_stats.f90

+1,667
Large diffs are not rendered by default.

‎src/f03_stdlib_experimental_stats_mean.f90

+25,896
Large diffs are not rendered by default.

‎src/f90_stdlib_experimental_stats.f90

+575
Large diffs are not rendered by default.

‎src/f90_stdlib_experimental_stats_mean.f90

+4,225
Large diffs are not rendered by default.

‎src/stdlib_experimental_io.f90

+7-4
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,12 @@ subroutine qsavetxt(filename, d)
218218
! call savetxt("log.txt", data)
219219

220220
integer :: s, i
221+
character(len=14) :: format_string
222+
223+
write(format_string, '(a1,i06,a7)') '(', size(d, 2), 'f40.34)'
221224
s = open(filename, "w")
222225
do i = 1, size(d, 1)
223-
write(s, *) d(i, :)
226+
write(s, format_string) d(i, :)
224227
end do
225228
close(s)
226229
end subroutine
@@ -332,15 +335,15 @@ integer function open(filename, mode, iostat) result(u)
332335

333336
select case (mode_(3:3))
334337
case('t')
335-
access_='sequential'
336338
form_='formatted'
337-
case('b', 's')
338-
access_='stream'
339+
case('b')
339340
form_='unformatted'
340341
case default
341342
call error_stop("Unsupported mode: "//mode_(3:3))
342343
end select
343344

345+
access_ = 'stream'
346+
344347
if (present(iostat)) then
345348
open(newunit=u, file=filename, &
346349
action = action_, position = position_, status = status_, &

‎src/stdlib_experimental_optval.f90

+8-8
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ module stdlib_experimental_optval
3434
contains
3535

3636

37-
pure function optval_sp(x, default) result(y)
37+
pure elemental function optval_sp(x, default) result(y)
3838
real(sp), intent(in), optional :: x
3939
real(sp), intent(in) :: default
4040
real(sp) :: y
@@ -47,7 +47,7 @@ pure function optval_sp(x, default) result(y)
4747
end function optval_sp
4848

4949

50-
pure function optval_dp(x, default) result(y)
50+
pure elemental function optval_dp(x, default) result(y)
5151
real(dp), intent(in), optional :: x
5252
real(dp), intent(in) :: default
5353
real(dp) :: y
@@ -60,7 +60,7 @@ pure function optval_dp(x, default) result(y)
6060
end function optval_dp
6161

6262

63-
pure function optval_qp(x, default) result(y)
63+
pure elemental function optval_qp(x, default) result(y)
6464
real(qp), intent(in), optional :: x
6565
real(qp), intent(in) :: default
6666
real(qp) :: y
@@ -73,7 +73,7 @@ pure function optval_qp(x, default) result(y)
7373
end function optval_qp
7474

7575

76-
pure function optval_int8(x, default) result(y)
76+
pure elemental function optval_int8(x, default) result(y)
7777
integer(int8), intent(in), optional :: x
7878
integer(int8), intent(in) :: default
7979
integer(int8) :: y
@@ -86,7 +86,7 @@ pure function optval_int8(x, default) result(y)
8686
end function optval_int8
8787

8888

89-
pure function optval_int16(x, default) result(y)
89+
pure elemental function optval_int16(x, default) result(y)
9090
integer(int16), intent(in), optional :: x
9191
integer(int16), intent(in) :: default
9292
integer(int16) :: y
@@ -99,7 +99,7 @@ pure function optval_int16(x, default) result(y)
9999
end function optval_int16
100100

101101

102-
pure function optval_int32(x, default) result(y)
102+
pure elemental function optval_int32(x, default) result(y)
103103
integer(int32), intent(in), optional :: x
104104
integer(int32), intent(in) :: default
105105
integer(int32) :: y
@@ -112,7 +112,7 @@ pure function optval_int32(x, default) result(y)
112112
end function optval_int32
113113

114114

115-
pure function optval_int64(x, default) result(y)
115+
pure elemental function optval_int64(x, default) result(y)
116116
integer(int64), intent(in), optional :: x
117117
integer(int64), intent(in) :: default
118118
integer(int64) :: y
@@ -125,7 +125,7 @@ pure function optval_int64(x, default) result(y)
125125
end function optval_int64
126126

127127

128-
pure function optval_logical(x, default) result(y)
128+
pure elemental function optval_logical(x, default) result(y)
129129
logical, intent(in), optional :: x
130130
logical, intent(in) :: default
131131
logical :: y

‎src/stdlib_experimental_stats.fypp

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
module stdlib_experimental_stats
2+
3+
#:set VERSION90 = defined('VERSION90')
4+
#:set REALKINDS = ["sp", "dp", "qp"]
5+
#:set INTKINDS = ["int8", "int16", "int32", "int64"]
6+
#:set REALTYPES = ["real({})".format(k) for k in REALKINDS]
7+
#:set INTTYPES = ["integer({})".format(k) for k in INTKINDS]
8+
#:set iktr = list(zip(range(len(REALKINDS)), REALKINDS, REALTYPES))
9+
#:set ikti = list(zip(range(len(INTKINDS)), INTKINDS, INTTYPES))
10+
11+
use stdlib_experimental_kinds, only: sp, dp, qp, &
12+
int8, int16, int32, int64
13+
implicit none
14+
private
15+
! Public API
16+
public :: mean
17+
18+
interface mean
19+
#:for i1, k1, t1 in iktr
20+
module function mean_1_${k1}$_${k1}$(x) result(res)
21+
${t1}$, intent(in) :: x(:)
22+
${t1}$ :: res
23+
end function mean_1_${k1}$_${k1}$
24+
#:endfor
25+
26+
#:for i1, k1, t1 in ikti
27+
module function mean_1_${k1}$_dp(x) result(res)
28+
${t1}$, intent(in) :: x(:)
29+
real(dp) :: res
30+
end function mean_1_${k1}$_dp
31+
#:endfor
32+
33+
34+
#:for i1, k1, t1 in iktr
35+
module function mean_2_all_${k1}$_${k1}$(x) result(res)
36+
${t1}$, intent(in) :: x(:,:)
37+
${t1}$ :: res
38+
end function mean_2_all_${k1}$_${k1}$
39+
#:endfor
40+
41+
#:for i1, k1, t1 in ikti
42+
module function mean_2_all_${k1}$_dp(x) result(res)
43+
${t1}$, intent(in) :: x(:,:)
44+
real(dp) :: res
45+
end function mean_2_all_${k1}$_dp
46+
#:endfor
47+
48+
#:for i1, k1, t1 in iktr
49+
module function mean_2_${k1}$_${k1}$(x, dim) result(res)
50+
${t1}$, intent(in) :: x(:,:)
51+
integer, intent(in) :: dim
52+
${t1}$ :: res(size(x)/size(x, dim))
53+
end function mean_2_${k1}$_${k1}$
54+
#:endfor
55+
56+
#:for i1, k1, t1 in ikti
57+
module function mean_2_${k1}$_dp(x, dim) result(res)
58+
${t1}$, intent(in) :: x(:,:)
59+
integer, intent(in) :: dim
60+
real(dp) :: res(size(x)/size(x, dim))
61+
end function mean_2_${k1}$_dp
62+
#:endfor
63+
64+
65+
#:def ranksuffix(rank)
66+
#{if rank > 0}#(${":" + ",:" * (rank - 1)}$)#{endif}#
67+
#:enddef
68+
69+
#:if VERSION90
70+
#:set ranks = range(3,8)
71+
#:else
72+
#:set ranks = range(3,16)
73+
#:endif
74+
75+
76+
#:for i1, k1, t1 in iktr
77+
#:for rank in ranks
78+
module function mean_${rank}$_all_${k1}$_${k1}$(x) result(res)
79+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
80+
${t1}$ :: res
81+
end function mean_${rank}$_all_${k1}$_${k1}$
82+
#:endfor
83+
#:endfor
84+
85+
#:for i1, k1, t1 in ikti
86+
#:for rank in ranks
87+
module function mean_${rank}$_all_${k1}$_dp(x) result(res)
88+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
89+
real(dp) :: res
90+
end function mean_${rank}$_all_${k1}$_dp
91+
#:endfor
92+
#:endfor
93+
94+
#:for i1, k1, t1 in iktr
95+
#:for rank in ranks
96+
module function mean_${rank}$_${k1}$_${k1}$(x, dim) result(res)
97+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
98+
integer, intent(in) :: dim
99+
${t1}$ :: res( &
100+
#:for imerge in range(1,rank-1)
101+
merge(size(x,${imerge}$),size(x,${imerge + 1}$),mask = ${imerge}$ < dim ), &
102+
#:endfor
103+
merge(size(x,${rank-1}$),size(x,${rank}$),mask = ${rank-1}$ < dim ) )
104+
end function mean_${rank}$_${k1}$_${k1}$
105+
#:endfor
106+
#:endfor
107+
108+
#:for i1, k1, t1 in ikti
109+
#:for rank in ranks
110+
module function mean_${rank}$_${k1}$_dp(x, dim) result(res)
111+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
112+
integer, intent(in) :: dim
113+
real(dp) :: res( &
114+
#:for imerge in range(1,rank-1)
115+
merge(size(x,${imerge}$),size(x,${imerge + 1}$),mask = ${imerge}$ < dim ), &
116+
#:endfor
117+
merge(size(x,${rank-1}$),size(x,${rank}$),mask = ${rank-1}$ < dim ) )
118+
end function mean_${rank}$_${k1}$_dp
119+
#:endfor
120+
#:endfor
121+
122+
end interface
123+
124+
end module

‎src/stdlib_experimental_stats.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Descriptive statistics
2+
3+
## Implemented
4+
5+
* `mean`
6+
7+
## MEAN - mean of array elements
8+
9+
### Description:
10+
11+
Returns the mean of all the elements of *array*, or of the elements of *array* along dimension *dim*.
12+
13+
### Syntax:
14+
15+
RESULT = mean(*array*)
16+
17+
RESULT = mean(*array*, *dim*)
18+
19+
### Arguments:
20+
21+
*array*: Shall be an array of type INTEGER, or REAL.
22+
23+
*dim* (optional): Shall be a scalar of type INTEGER with a value in the range from 1 to n, where n is the rank of *array*.
24+
25+
### Return value:
26+
27+
If *array* is of type REAL, the result is of the same type as array.
28+
If *array* is of type INTEGER, the result is of type as *double precision*.
29+
30+
If *dim* is absent, a scalar with the mean of all elements in *array* is returned. Otherwise, an array of rank n-1, where n equals the rank of *array*, and a shape similar to that of *array* with dimension *dim* dropped is returned.
31+
32+
### Example:
33+
34+
```fortran
35+
program test
36+
use stdlib_experimental_stats, only: mean
37+
implicit none
38+
real :: x(1:6) = [ 1., 2., 3., 4., 5., 6. ]
39+
print *, mean(x) !returns 21.
40+
print *, mean( reshape(x, [ 2, 3 ] )) !returns 21.
41+
print *, mean( reshape(x, [ 2, 3 ] ), 1) !returns [ 3., 7., 11. ]
42+
end program
43+
```
+293
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
submodule (stdlib_experimental_stats) stdlib_experimental_stats_mean
2+
3+
#:set VERSION90 = defined('VERSION90')
4+
#:set REALKINDS = ["sp", "dp", "qp"]
5+
#:set INTKINDS = ["int8", "int16", "int32", "int64"]
6+
#:set REALTYPES = ["real({})".format(k) for k in REALKINDS]
7+
#:set INTTYPES = ["integer({})".format(k) for k in INTKINDS]
8+
#:set iktr = list(zip(range(len(REALKINDS)), REALKINDS, REALTYPES))
9+
#:set ikti = list(zip(range(len(INTKINDS)), INTKINDS, INTTYPES))
10+
11+
use stdlib_experimental_error, only: error_stop
12+
implicit none
13+
14+
contains
15+
16+
#:for i1, k1, t1 in iktr
17+
module function mean_1_${k1}$_${k1}$(x) result(res)
18+
${t1}$, intent(in) :: x(:)
19+
${t1}$ :: res
20+
21+
integer :: i
22+
23+
res = 0.0_${k1}$
24+
do i = 1, size(x)
25+
res = res + x(i)
26+
enddo
27+
res = res / real(size(x), ${k1}$)
28+
29+
end function mean_1_${k1}$_${k1}$
30+
#:endfor
31+
32+
#:for i1, k1, t1 in ikti
33+
module function mean_1_${k1}$_dp(x) result(res)
34+
${t1}$, intent(in) :: x(:)
35+
real(dp) :: res
36+
37+
integer :: i
38+
39+
res = 0.0_dp
40+
do i = 1, size(x)
41+
res = res + real(x(i), dp)
42+
enddo
43+
res = res / real(size(x), dp)
44+
45+
end function mean_1_${k1}$_dp
46+
#:endfor
47+
48+
49+
#:for i1, k1, t1 in iktr
50+
module function mean_2_all_${k1}$_${k1}$(x) result(res)
51+
${t1}$, intent(in) :: x(:,:)
52+
${t1}$ :: res
53+
54+
integer :: i, i_
55+
56+
res = 0.0_${k1}$
57+
do i_ = 1, size(x, 2)
58+
do i = 1, size(x, 1)
59+
res = res + x(i,i_)
60+
enddo
61+
enddo
62+
res = res / real(size(x), ${k1}$)
63+
64+
end function mean_2_all_${k1}$_${k1}$
65+
#:endfor
66+
67+
#:for i1, k1, t1 in ikti
68+
module function mean_2_all_${k1}$_dp(x) result(res)
69+
${t1}$, intent(in) :: x(:,:)
70+
real(dp) :: res
71+
72+
integer :: i, i_
73+
74+
res = 0.0_dp
75+
do i_ = 1, size(x, 2)
76+
do i = 1, size(x, 1)
77+
res = res + real(x(i,i_), dp)
78+
enddo
79+
enddo
80+
res = res / real(size(x), dp)
81+
82+
end function mean_2_all_${k1}$_dp
83+
#:endfor
84+
85+
#:for i1, k1, t1 in iktr
86+
module function mean_2_${k1}$_${k1}$(x, dim) result(res)
87+
${t1}$, intent(in) :: x(:,:)
88+
integer, intent(in) :: dim
89+
${t1}$ :: res(size(x)/size(x, dim))
90+
91+
integer :: i, i_
92+
93+
res = 0.0_${k1}$
94+
95+
select case(dim)
96+
case(1)
97+
do i_ = 1, size(x, 2)
98+
do i = 1, size(x, 1)
99+
res(i_) = res(i_) + x(i, i_)
100+
end do
101+
end do
102+
case(2)
103+
do i_ = 1, size(x, 2)
104+
do i = 1, size(x, 1)
105+
res(i) = res(i) + x(i, i_)
106+
end do
107+
end do
108+
case default
109+
call error_stop("ERROR (mean): wrong dimension")
110+
end select
111+
112+
res = res / real(size(x, dim), ${k1}$)
113+
114+
end function mean_2_${k1}$_${k1}$
115+
#:endfor
116+
117+
#:for i1, k1, t1 in ikti
118+
module function mean_2_${k1}$_dp(x, dim) result(res)
119+
${t1}$, intent(in) :: x(:,:)
120+
integer, intent(in) :: dim
121+
real(dp) :: res(size(x)/size(x, dim))
122+
123+
integer :: i, i_
124+
125+
res = 0.0_dp
126+
127+
select case(dim)
128+
case(1)
129+
do i_ = 1, size(x, 2)
130+
do i = 1, size(x, 1)
131+
res(i_) = res(i_) + real(x(i, i_), dp)
132+
end do
133+
end do
134+
case(2)
135+
do i_ = 1, size(x, 2)
136+
do i = 1, size(x, 1)
137+
res(i) = res(i) + real(x(i, i_), dp)
138+
end do
139+
end do
140+
case default
141+
call error_stop("ERROR (mean): wrong dimension")
142+
end select
143+
144+
res = res / real(size(x, dim), dp)
145+
146+
end function mean_2_${k1}$_dp
147+
#:endfor
148+
149+
150+
#:def ranksuffix(rank)
151+
#{if rank > 0}#(${":" + ",:" * (rank - 1)}$)#{endif}#
152+
#:enddef
153+
154+
#:def isuffix(rank)
155+
#:if rank > 0
156+
i#{for i in range(2,rank)}#${",i"+"_" * (i-1)}$#{endfor}#
157+
#:endif
158+
#:enddef
159+
160+
#:def ressuffix(rank,dim)
161+
#:if rank > 0
162+
#{for i in range(1,dim-1)}#${"i" + "_" * (i-1)+","}$#{endfor}##{if dim-1 >0}#i${"_"*(dim-2) }$#{endif}##{if dim -1 >0 and dim <rank}#,#{endif}##{if dim <rank}#i${"_"*(dim) }$#{endif}##{for i in range(dim+1,rank)}#${",i"+"_" * (i)}$#{endfor}#
163+
#:endif
164+
#:enddef
165+
166+
167+
#:if VERSION90
168+
#:set ranks = range(3,8)
169+
#:else
170+
#:set ranks = range(3,16)
171+
#:endif
172+
173+
#:for i1, k1, t1 in iktr
174+
#:for rank in ranks
175+
module function mean_${rank}$_all_${k1}$_${k1}$(x) result(res)
176+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
177+
${t1}$ :: res
178+
179+
integer :: ${isuffix(rank+1)}$
180+
181+
res = 0.0_${k1}$
182+
183+
#:for fj in range(rank,0,-1)
184+
${" "* (rank - fj)}$do i${"_"* (fj-1)}$ = 1, size(x, ${fj}$)
185+
#:endfor
186+
${" "* (rank)}$res = res + x(${isuffix(rank+1)}$)
187+
#:for fj in range(rank,0,-1)
188+
${" "* (fj-1)}$end do
189+
#:endfor
190+
191+
res = res / real(size(x), ${k1}$)
192+
193+
end function mean_${rank}$_all_${k1}$_${k1}$
194+
#:endfor
195+
#:endfor
196+
197+
#:for i1, k1, t1 in ikti
198+
#:for rank in ranks
199+
module function mean_${rank}$_all_${k1}$_dp(x) result(res)
200+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
201+
real(dp) :: res
202+
203+
integer :: ${isuffix(rank+1)}$
204+
205+
res = 0.0_dp
206+
207+
#:for fj in range(rank,0,-1)
208+
${" "* (rank - fj)}$do i${"_"* (fj-1)}$ = 1, size(x, ${fj}$)
209+
#:endfor
210+
${" "* (rank)}$res = res + real(x(${isuffix(rank+1)}$), dp)
211+
#:for fj in range(rank,0,-1)
212+
${" "* (fj-1)}$end do
213+
#:endfor
214+
215+
res = res / real(size(x), dp)
216+
217+
end function mean_${rank}$_all_${k1}$_dp
218+
#:endfor
219+
#:endfor
220+
221+
#:for i1, k1, t1 in iktr
222+
#:for rank in ranks
223+
module function mean_${rank}$_${k1}$_${k1}$(x, dim) result(res)
224+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
225+
integer, intent(in) :: dim
226+
${t1}$ :: res( &
227+
#:for imerge in range(1,rank-1)
228+
merge(size(x,${imerge}$),size(x,${imerge + 1}$),mask = ${imerge}$ < dim ), &
229+
#:endfor
230+
merge(size(x,${rank-1}$),size(x,${rank}$),mask = ${rank-1}$ < dim ) )
231+
232+
integer :: ${isuffix(rank+1)}$
233+
234+
res = 0.0_${k1}$
235+
236+
select case(dim)
237+
#:for fi in range(1,rank+1)
238+
case(${fi}$)
239+
#:for fj in range(rank,0,-1)
240+
${" "* (rank - fj)}$do i${"_"* (fj-1)}$ = 1, size(x, ${fj}$)
241+
#:endfor
242+
${" "* (rank)}$res(${ressuffix(rank,fi)}$) = res(${ressuffix(rank,fi)}$) + x(${isuffix(rank+1)}$)
243+
#:for fj in range(rank,0,-1)
244+
${" "* (fj-1)}$end do
245+
#:endfor
246+
#:endfor
247+
case default
248+
call error_stop("ERROR (mean): wrong dimension")
249+
end select
250+
251+
res = res / real(size(x, dim), ${k1}$)
252+
253+
end function mean_${rank}$_${k1}$_${k1}$
254+
#:endfor
255+
#:endfor
256+
257+
#:for i1, k1, t1 in ikti
258+
#:for rank in ranks
259+
module function mean_${rank}$_${k1}$_dp(x, dim) result(res)
260+
${t1}$, intent(in) :: x${ranksuffix(rank)}$
261+
integer, intent(in) :: dim
262+
real(dp) :: res( &
263+
#:for imerge in range(1,rank-1)
264+
merge(size(x,${imerge}$),size(x,${imerge + 1}$),mask = ${imerge}$ < dim ), &
265+
#:endfor
266+
merge(size(x,${rank-1}$),size(x,${rank}$),mask = ${rank-1}$ < dim ) )
267+
268+
integer :: ${isuffix(rank+1)}$
269+
270+
res = 0.0_dp
271+
272+
select case(dim)
273+
#:for fi in range(1,rank+1)
274+
case(${fi}$)
275+
#:for fj in range(rank,0,-1)
276+
${" "* (rank - fj)}$do i${"_"* (fj-1)}$ = 1, size(x, ${fj}$)
277+
#:endfor
278+
${" "* (rank)}$res(${ressuffix(rank,fi)}$) = res(${ressuffix(rank,fi)}$) + real(x(${isuffix(rank+1)}$), dp)
279+
#:for fj in range(rank,0,-1)
280+
${" "* (fj-1)}$end do
281+
#:endfor
282+
#:endfor
283+
case default
284+
call error_stop("ERROR (mean): wrong dimension")
285+
end select
286+
287+
res = res / real(size(x, dim), dp)
288+
289+
end function mean_${rank}$_${k1}$_dp
290+
#:endfor
291+
#:endfor
292+
293+
end submodule

‎src/stdlib_experimental_system.F90

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module stdlib_experimental_system
2+
use, intrinsic :: iso_c_binding, only : c_int, c_long
3+
implicit none
4+
private
5+
public :: sleep
6+
7+
interface
8+
#ifdef _WIN32
9+
subroutine winsleep(dwMilliseconds) bind (C, name='Sleep')
10+
!! void Sleep(DWORD dwMilliseconds)
11+
!! https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep
12+
import c_long
13+
integer(c_long), value, intent(in) :: dwMilliseconds
14+
end subroutine winsleep
15+
#else
16+
integer(c_int) function usleep(usec) bind (C)
17+
!! int usleep(useconds_t usec);
18+
!! https://linux.die.net/man/3/usleep
19+
import c_int
20+
integer(c_int), value, intent(in) :: usec
21+
end function usleep
22+
#endif
23+
end interface
24+
25+
contains
26+
27+
subroutine sleep(millisec)
28+
integer, intent(in) :: millisec
29+
integer(c_int) :: ierr
30+
31+
#ifdef _WIN32
32+
!! PGI Windows, Ifort Windows, ....
33+
call winsleep(int(millisec, c_long))
34+
#else
35+
!! Linux, Unix, MacOS, MSYS2, ...
36+
ierr = usleep(int(millisec * 1000, c_int))
37+
if (ierr/=0) error stop 'problem with usleep() system call'
38+
#endif
39+
40+
41+
end subroutine sleep
42+
43+
end module stdlib_experimental_system

‎src/tests/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ endmacro(ADDTEST)
99
add_subdirectory(ascii)
1010
add_subdirectory(io)
1111
add_subdirectory(optval)
12+
add_subdirectory(stats)
13+
add_subdirectory(system)
1214

1315
ADDTEST(always_skip)
1416
set_tests_properties(always_skip PROPERTIES SKIP_RETURN_CODE 77)

‎src/tests/Makefile.manual

+3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ all:
44
$(MAKE) -f Makefile.manual --directory=ascii
55
$(MAKE) -f Makefile.manual --directory=io
66
$(MAKE) -f Makefile.manual --directory=optval
7+
$(MAKE) -f Makefile.manual --directory=stats
78

89
test:
910
$(MAKE) -f Makefile.manual --directory=ascii test
1011
$(MAKE) -f Makefile.manual --directory=io test
1112
$(MAKE) -f Makefile.manual --directory=optval test
13+
$(MAKE) -f Makefile.manual --directory=stats test
1214

1315
clean:
1416
$(MAKE) -f Makefile.manual --directory=ascii clean
1517
$(MAKE) -f Makefile.manual --directory=io clean
1618
$(MAKE) -f Makefile.manual --directory=optval clean
19+
$(MAKE) -f Makefile.manual --directory=stats clean

‎src/tests/optval/test_optval.f90

+139-18
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,25 @@ program test_optval
2020

2121
call test_optval_character
2222

23+
24+
call test_optval_sp_arr
25+
call test_optval_dp_arr
26+
call test_optval_qp_arr
27+
28+
call test_optval_int8_arr
29+
call test_optval_int16_arr
30+
call test_optval_int32_arr
31+
call test_optval_int64_arr
32+
2333
contains
2434

25-
2635
subroutine test_optval_sp
2736
print *, "test_optval_sp"
2837
call assert(foo_sp(1.0_sp) == 1.0_sp)
2938
call assert(foo_sp() == 2.0_sp)
3039
end subroutine test_optval_sp
3140

32-
41+
3342
function foo_sp(x) result(z)
3443
real(sp), intent(in), optional :: x
3544
real(sp) :: z
@@ -43,7 +52,7 @@ subroutine test_optval_dp
4352
call assert(foo_dp() == 2.0_dp)
4453
end subroutine test_optval_dp
4554

46-
55+
4756
function foo_dp(x) result(z)
4857
real(dp), intent(in), optional :: x
4958
real(dp) :: z
@@ -57,95 +66,207 @@ subroutine test_optval_qp
5766
call assert(foo_qp() == 2.0_qp)
5867
end subroutine test_optval_qp
5968

60-
69+
6170
function foo_qp(x) result(z)
6271
real(qp), intent(in), optional :: x
6372
real(qp) :: z
6473
z = optval(x, 2.0_qp)
6574
endfunction foo_qp
66-
67-
75+
76+
6877
subroutine test_optval_int8
6978
print *, "test_optval_int8"
7079
call assert(foo_int8(1_int8) == 1_int8)
7180
call assert(foo_int8() == 2_int8)
7281
end subroutine test_optval_int8
7382

74-
83+
7584
function foo_int8(x) result(z)
7685
integer(int8), intent(in), optional :: x
7786
integer(int8) :: z
7887
z = optval(x, 2_int8)
7988
endfunction foo_int8
80-
89+
8190

8291
subroutine test_optval_int16
8392
print *, "test_optval_int16"
8493
call assert(foo_int16(1_int16) == 1_int16)
8594
call assert(foo_int16() == 2_int16)
8695
end subroutine test_optval_int16
8796

88-
97+
8998
function foo_int16(x) result(z)
9099
integer(int16), intent(in), optional :: x
91100
integer(int16) :: z
92101
z = optval(x, 2_int16)
93102
endfunction foo_int16
94103

95-
104+
96105
subroutine test_optval_int32
97106
print *, "test_optval_int32"
98107
call assert(foo_int32(1_int32) == 1_int32)
99108
call assert(foo_int32() == 2_int32)
100109
end subroutine test_optval_int32
101110

102-
111+
103112
function foo_int32(x) result(z)
104113
integer(int32), intent(in), optional :: x
105114
integer(int32) :: z
106115
z = optval(x, 2_int32)
107116
endfunction foo_int32
108117

109-
118+
110119
subroutine test_optval_int64
111120
print *, "test_optval_int64"
112121
call assert(foo_int64(1_int64) == 1_int64)
113122
call assert(foo_int64() == 2_int64)
114123
end subroutine test_optval_int64
115124

116-
125+
117126
function foo_int64(x) result(z)
118127
integer(int64), intent(in), optional :: x
119128
integer(int64) :: z
120129
z = optval(x, 2_int64)
121130
endfunction foo_int64
122-
131+
123132

124133
subroutine test_optval_logical
125134
print *, "test_optval_logical"
126135
call assert(foo_logical(.true.))
127136
call assert(.not.foo_logical())
128137
end subroutine test_optval_logical
129138

130-
139+
131140
function foo_logical(x) result(z)
132141
logical, intent(in), optional :: x
133142
logical :: z
134143
z = optval(x, .false.)
135144
endfunction foo_logical
136-
145+
137146

138147
subroutine test_optval_character
139148
print *, "test_optval_character"
140149
call assert(foo_character("x") == "x")
141150
call assert(foo_character() == "y")
142151
end subroutine test_optval_character
143152

144-
153+
145154
function foo_character(x) result(z)
146155
character(len=*), intent(in), optional :: x
147156
character(len=:), allocatable :: z
148157
z = optval(x, "y")
149158
endfunction foo_character
150-
159+
160+
161+
subroutine test_optval_sp_arr
162+
print *, "test_optval_sp_arr"
163+
call assert(all(foo_sp_arr([1.0_sp, -1.0_sp]) == [1.0_sp, -1.0_sp]))
164+
call assert(all(foo_sp_arr() == [2.0_sp, -2.0_sp]))
165+
end subroutine test_optval_sp_arr
166+
167+
168+
function foo_sp_arr(x) result(z)
169+
real(sp), dimension(2), intent(in), optional :: x
170+
real(sp), dimension(2) :: z
171+
z = optval(x, [2.0_sp, -2.0_sp])
172+
end function foo_sp_arr
173+
174+
175+
subroutine test_optval_dp_arr
176+
print *, "test_optval_dp_arr"
177+
call assert(all(foo_dp_arr([1.0_dp, -1.0_dp]) == [1.0_dp, -1.0_dp]))
178+
call assert(all(foo_dp_arr() == [2.0_dp, -2.0_dp]))
179+
end subroutine test_optval_dp_arr
180+
181+
182+
function foo_dp_arr(x) result(z)
183+
real(dp), dimension(2), intent(in), optional :: x
184+
real(dp), dimension(2) :: z
185+
z = optval(x, [2.0_dp, -2.0_dp])
186+
end function foo_dp_arr
187+
188+
189+
subroutine test_optval_qp_arr
190+
print *, "test_optval_qp_arr"
191+
call assert(all(foo_qp_arr([1.0_qp, -1.0_qp]) == [1.0_qp, -1.0_qp]))
192+
call assert(all(foo_qp_arr() == [2.0_qp, -2.0_qp]))
193+
end subroutine test_optval_qp_arr
194+
195+
196+
function foo_qp_arr(x) result(z)
197+
real(qp), dimension(2), intent(in), optional :: x
198+
real(qp), dimension(2) :: z
199+
z = optval(x, [2.0_qp, -2.0_qp])
200+
end function foo_qp_arr
201+
202+
203+
subroutine test_optval_int8_arr
204+
print *, "test_optval_int8_arr"
205+
call assert(all(foo_int8_arr([1_int8, -1_int8]) == [1_int8, -1_int8]))
206+
call assert(all(foo_int8_arr() == [2_int8, -2_int8]))
207+
end subroutine test_optval_int8_arr
208+
209+
210+
function foo_int8_arr(x) result(z)
211+
integer(int8), dimension(2), intent(in), optional :: x
212+
integer(int8), dimension(2) :: z
213+
z = optval(x, [2_int8, -2_int8])
214+
end function foo_int8_arr
215+
216+
217+
subroutine test_optval_int16_arr
218+
print *, "test_optval_int16_arr"
219+
call assert(all(foo_int16_arr([1_int16, -1_int16]) == [1_int16, -1_int16]))
220+
call assert(all(foo_int16_arr() == [2_int16, -2_int16]))
221+
end subroutine test_optval_int16_arr
222+
223+
224+
function foo_int16_arr(x) result(z)
225+
integer(int16), dimension(2), intent(in), optional :: x
226+
integer(int16), dimension(2) :: z
227+
z = optval(x, [2_int16, -2_int16])
228+
end function foo_int16_arr
229+
230+
231+
subroutine test_optval_int32_arr
232+
print *, "test_optval_int32_arr"
233+
call assert(all(foo_int32_arr([1_int32, -1_int32]) == [1_int32, -1_int32]))
234+
call assert(all(foo_int32_arr() == [2_int32, -2_int32]))
235+
end subroutine test_optval_int32_arr
236+
237+
238+
function foo_int32_arr(x) result(z)
239+
integer(int32), dimension(2), intent(in), optional :: x
240+
integer(int32), dimension(2) :: z
241+
z = optval(x, [2_int32, -2_int32])
242+
end function foo_int32_arr
243+
244+
245+
subroutine test_optval_int64_arr
246+
print *, "test_optval_int64_arr"
247+
call assert(all(foo_int64_arr([1_int64, -1_int64]) == [1_int64, -1_int64]))
248+
call assert(all(foo_int64_arr() == [2_int64, -2_int64]))
249+
end subroutine test_optval_int64_arr
250+
251+
252+
function foo_int64_arr(x) result(z)
253+
integer(int64), dimension(2), intent(in), optional :: x
254+
integer(int64), dimension(2) :: z
255+
z = optval(x, [2_int64, -2_int64])
256+
end function foo_int64_arr
257+
258+
259+
subroutine test_optval_logical_arr
260+
print *, "test_optval_logical_arr"
261+
call assert(all(foo_logical_arr()))
262+
call assert(all(.not.foo_logical_arr()))
263+
end subroutine test_optval_logical_arr
264+
265+
266+
function foo_logical_arr(x) result(z)
267+
logical, dimension(2), intent(in), optional :: x
268+
logical, dimension(2) :: z
269+
z = optval(x, [.false., .false.])
270+
end function foo_logical_arr
271+
151272
end program test_optval

‎src/tests/stats/CMakeLists.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ADDTEST(mean)
2+
3+
if(f03rank)
4+
ADDTEST(mean_f03)
5+
endif()

‎src/tests/stats/Makefile.manual

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
PROGS_SRC = test_mean.f90
2+
3+
include ../Makefile.manual.test.mk

‎src/tests/stats/array3.dat

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
1.000000000000000021e-08 9.199998759392489944e+01
2+
1.024113254885563425e-08 9.199998731474968849e+01
3+
1.048233721895820948e-08 9.199998703587728244e+01
4+
1.072361403187881949e-08 9.199998675729767683e+01
5+
1.096496300919481796e-08 9.199998647900135040e+01
6+
1.120638417249036630e-08 9.199998620097916557e+01
7+
1.144787754335570897e-08 9.199998592322251056e+01
8+
1.168944314338753750e-08 9.199998564572304360e+01
9+
1.193108099418952317e-08 9.199998536847290609e+01
10+
1.217279111737088596e-08 9.199998509146449521e+01
11+
1.241457353454836993e-08 9.199998481469057765e+01
12+
1.265642826734443823e-08 9.199998453814424693e+01
13+
1.289835533738818635e-08 9.199998426181879552e+01
14+
1.314035476631514857e-08 9.199998398570787117e+01
15+
1.338242657576766519e-08 9.199998370980536322e+01
16+
1.362457078739434161e-08 9.199998343410533153e+01

‎src/tests/stats/test_mean.f90

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
program test_mean
2+
use stdlib_experimental_error, only: assert
3+
use stdlib_experimental_kinds, only: sp, dp, int32, int64
4+
use stdlib_experimental_io, only: loadtxt
5+
use stdlib_experimental_stats, only: mean
6+
implicit none
7+
8+
real(sp), allocatable :: s(:, :)
9+
real(dp), allocatable :: d(:, :)
10+
11+
real(dp), allocatable :: d3(:, :, :)
12+
real(dp), allocatable :: d4(:, :, :, :)
13+
14+
15+
!sp
16+
call loadtxt("array3.dat", s)
17+
18+
call assert( mean(s) - sum(s)/real(size(s), sp) == 0.0_sp)
19+
call assert( sum( abs( mean(s,1) - sum(s,1)/real(size(s,1), sp) )) == 0.0_sp)
20+
call assert( sum( abs( mean(s,2) - sum(s,2)/real(size(s,2), sp) )) == 0.0_sp)
21+
22+
23+
!dp
24+
call loadtxt("array3.dat", d)
25+
26+
call assert( mean(d) - sum(d)/real(size(d), dp) == 0.0_dp)
27+
call assert( sum( abs( mean(d,1) - sum(d,1)/real(size(d,1), dp) )) == 0.0_dp)
28+
call assert( sum( abs( mean(d,2) - sum(d,2)/real(size(d,2), dp) )) == 0.0_dp)
29+
30+
31+
!int32
32+
call loadtxt("array3.dat", d)
33+
34+
call assert( mean(int(d, int32)) - sum(real(int(d, int32),dp))/real(size(d), dp) == 0.0_dp)
35+
call assert( sum(abs( mean(int(d, int32),1) - sum(real(int(d, int32),dp),1)/real(size(d,1), dp) )) == 0.0_dp)
36+
call assert( sum(abs( mean(int(d, int32),2) - sum(real(int(d, int32),dp),2)/real(size(d,2), dp) )) == 0.0_dp)
37+
38+
39+
!int64
40+
call loadtxt("array3.dat", d)
41+
42+
call assert( mean(int(d, int64)) - sum(real(int(d, int64),dp))/real(size(d), dp) == 0.0_dp)
43+
call assert( sum(abs( mean(int(d, int64),1) - sum(real(int(d, int64),dp),1)/real(size(d,1), dp) )) == 0.0_dp)
44+
call assert( sum(abs( mean(int(d, int64),2) - sum(real(int(d, int64),dp),2)/real(size(d,2), dp) )) == 0.0_dp)
45+
46+
47+
!dp rank 3
48+
allocate(d3(size(d,1),size(d,2),3))
49+
d3(:,:,1)=d;
50+
d3(:,:,2)=d*1.5_dp;
51+
d3(:,:,3)=d*4._dp;
52+
53+
call assert( mean(d3) - sum(d3)/real(size(d3), dp) == 0.0_dp)
54+
call assert( sum( abs( mean(d3,1) - sum(d3,1)/real(size(d3,1), dp) )) == 0.0_dp)
55+
call assert( sum( abs( mean(d3,2) - sum(d3,2)/real(size(d3,2), dp) )) == 0.0_dp)
56+
call assert( sum( abs( mean(d3,3) - sum(d3,3)/real(size(d3,3), dp) )) == 0.0_dp)
57+
58+
59+
!dp rank 4
60+
allocate(d4(size(d,1),size(d,2),3,9))
61+
d4 = 1.
62+
d4(:,:,1,1)=d;
63+
d4(:,:,2,1)=d*1.5_dp;
64+
d4(:,:,3,1)=d*4._dp;
65+
d4(:,:,3,9)=d*4._dp;
66+
67+
call assert( mean(d4) - sum(d4)/real(size(d4), dp) == 0.0_dp)
68+
call assert( sum( abs( mean(d4,1) - sum(d4,1)/real(size(d4,1), dp) )) == 0.0_dp)
69+
call assert( sum( abs( mean(d4,2) - sum(d4,2)/real(size(d4,2), dp) )) == 0.0_dp)
70+
call assert( sum( abs( mean(d4,3) - sum(d4,3)/real(size(d4,3), dp) )) == 0.0_dp)
71+
call assert( sum( abs( mean(d4,4) - sum(d4,4)/real(size(d4,4), dp) )) == 0.0_dp)
72+
73+
contains
74+
75+
end program

‎src/tests/stats/test_mean_f03.f90

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
program test_mean
2+
use stdlib_experimental_error, only: assert
3+
use stdlib_experimental_kinds, only: sp, dp, int32, int64
4+
use stdlib_experimental_io, only: loadtxt
5+
use stdlib_experimental_stats, only: mean
6+
implicit none
7+
8+
real(dp), allocatable :: d(:, :)
9+
real(dp), allocatable :: d8(:, :, :, :, :, :, :, :)
10+
11+
12+
!dp
13+
call loadtxt("array3.dat", d)
14+
15+
call assert( mean(d) - sum(d)/real(size(d), dp) == 0.0_dp)
16+
call assert( sum( abs( mean(d,1) - sum(d,1)/real(size(d,1), dp) )) == 0.0_dp)
17+
call assert( sum( abs( mean(d,2) - sum(d,2)/real(size(d,2), dp) )) == 0.0_dp)
18+
19+
!dp rank 8
20+
allocate(d8(size(d,1), size(d,2), 3, 4, 5, 6, 7, 8))
21+
d8(:, :, 1, 4, 5 ,6 ,7 ,8)=d;
22+
d8(:, :, 2, 4, 5 ,6 ,7 ,8)=d * 1.5_dp;
23+
d8(:, :, 3, 4, 5 ,6 ,7 ,8)=d * 4._dp;
24+
25+
call assert( mean(d8) - sum(d8)/real(size(d8), dp) == 0.0_dp)
26+
27+
call assert( sum( abs( mean(d8,1) - sum(d8,1)/real(size(d8,1), dp) )) == 0.0_dp)
28+
call assert( sum( abs( mean(d8,2) - sum(d8,2)/real(size(d8,2), dp) )) == 0.0_dp)
29+
call assert( sum( abs( mean(d8,3) - sum(d8,3)/real(size(d8,3), dp) )) == 0.0_dp)
30+
call assert( sum( abs( mean(d8,4) - sum(d8,4)/real(size(d8,4), dp) )) == 0.0_dp)
31+
call assert( sum( abs( mean(d8,5) - sum(d8,5)/real(size(d8,5), dp) )) == 0.0_dp)
32+
call assert( sum( abs( mean(d8,6) - sum(d8,6)/real(size(d8,6), dp) )) == 0.0_dp)
33+
call assert( sum( abs( mean(d8,7) - sum(d8,7)/real(size(d8,7), dp) )) == 0.0_dp)
34+
call assert( sum( abs( mean(d8,8) - sum(d8,8)/real(size(d8,8), dp) )) == 0.0_dp)
35+
36+
contains
37+
38+
end program

‎src/tests/system/CMakeLists.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
add_executable(test_sleep test_sleep.f90)
2+
target_link_libraries(test_sleep fortran_stdlib)
3+
4+
add_test(NAME Sleep COMMAND $<TARGET_FILE:test_sleep> 350)
5+
set_tests_properties(Sleep PROPERTIES TIMEOUT 1)

‎src/tests/system/test_sleep.f90

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
program test_sleep
2+
use, intrinsic :: iso_fortran_env, only : int64, real64
3+
use stdlib_experimental_system, only : sleep
4+
5+
implicit none
6+
7+
integer :: ierr, millisec
8+
character(8) :: argv
9+
integer(int64) :: tic, toc, trate
10+
real(real64) :: t_ms
11+
12+
call system_clock(count_rate=trate)
13+
14+
millisec = 780
15+
call get_command_argument(1, argv, status=ierr)
16+
if (ierr==0) read(argv,*) millisec
17+
18+
if (millisec<0) millisec=0
19+
20+
call system_clock(count=tic)
21+
call sleep(millisec)
22+
call system_clock(count=toc)
23+
24+
t_ms = (toc-tic) * 1000._real64 / trate
25+
26+
if (millisec > 0) then
27+
if (t_ms < 0.5 * millisec) error stop 'actual sleep time was too short'
28+
if (t_ms > 2 * millisec) error stop 'actual sleep time was too long'
29+
endif
30+
31+
print '(A,F8.3)', 'OK: test_sleep: slept for (ms): ',t_ms
32+
33+
end program

0 commit comments

Comments
 (0)
Please sign in to comment.