From 65d8d595f1e03ccc2e073dc2074597d38e687b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Thu, 19 Dec 2019 11:18:21 -0700 Subject: [PATCH 01/10] Move Makefile -> Makefile.manual So that it does not conflict with CMake generated makefiles. To use them, execute make with: make -f Makefile.manual --- Makefile | 18 ------------------ Makefile.manual | 18 ++++++++++++++++++ src/lib/{Makefile => Makefile.manual} | 0 src/tests/{Makefile => Makefile.manual} | 0 4 files changed, 18 insertions(+), 18 deletions(-) delete mode 100644 Makefile create mode 100644 Makefile.manual rename src/lib/{Makefile => Makefile.manual} (100%) rename src/tests/{Makefile => Makefile.manual} (100%) diff --git a/Makefile b/Makefile deleted file mode 100644 index 95845cb92..000000000 --- a/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# Fortran stdlib Makefile - -FC = gfortran -FCFLAGS=-O0 - -.PHONY: all clean - -all: stdlib tests - -stdlib: - $(MAKE) FC=${FC} FCFLAGS=${FCFLAGS} --directory=src/lib - -tests: stdlib - $(MAKE) FC=${FC} FCFLAGS=${FCFLAGS} --directory=src/tests - -clean: - $(MAKE) clean --directory=src/lib - $(MAKE) clean --directory=src/tests diff --git a/Makefile.manual b/Makefile.manual new file mode 100644 index 000000000..c7f45bc74 --- /dev/null +++ b/Makefile.manual @@ -0,0 +1,18 @@ +# Fortran stdlib Makefile + +FC = gfortran +FCFLAGS=-O0 + +.PHONY: all clean + +all: stdlib tests + +stdlib: + $(MAKE) -f Makefile.manual FC=${FC} FCFLAGS=${FCFLAGS} --directory=src/lib + +tests: stdlib + $(MAKE) -f Makefile.manual FC=${FC} FCFLAGS=${FCFLAGS} --directory=src/tests + +clean: + $(MAKE) -f Makefile.manual clean --directory=src/lib + $(MAKE) -f Makefile.manual clean --directory=src/tests diff --git a/src/lib/Makefile b/src/lib/Makefile.manual similarity index 100% rename from src/lib/Makefile rename to src/lib/Makefile.manual diff --git a/src/tests/Makefile b/src/tests/Makefile.manual similarity index 100% rename from src/tests/Makefile rename to src/tests/Makefile.manual From 7a7ca5f3e2ae5b49f58e14f510b7e4f17d46bd18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Thu, 19 Dec 2019 10:56:06 -0700 Subject: [PATCH 02/10] Implement loadtxt and savetxt This also includes a minimal CMake build system. We can improve the build system in further PRs. Fixes #16. --- CMakeLists.txt | 9 ++++ src/CMakeLists.txt | 12 +++++ src/stdlib_io.f90 | 104 +++++++++++++++++++++++++++++++++++++++++++ src/stdlib_types.f90 | 10 +++++ 4 files changed, 135 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 src/CMakeLists.txt create mode 100644 src/stdlib_io.f90 create mode 100644 src/stdlib_types.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..b9706da13 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.5.0 FATAL_ERROR) + +enable_language(Fortran) + +project(stdlib) + +enable_testing() + +add_subdirectory(src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 000000000..7412e9da2 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,12 @@ +set(SRC + stdlib_types.f90 + stdlib_io.f90 +) + +add_library(fortran_stdlib ${SRC}) + +install(TARGETS fortran_stdlib + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + ) diff --git a/src/stdlib_io.f90 b/src/stdlib_io.f90 new file mode 100644 index 000000000..b26c29b90 --- /dev/null +++ b/src/stdlib_io.f90 @@ -0,0 +1,104 @@ +module stdlib_io +use stdlib_types +implicit none +private +public loadtxt, savetxt + +contains + +subroutine loadtxt(filename, d) +! Loads a 2D array from a text file. +! +! Arguments +! --------- +! +! Filename to load the array from +character(len=*), intent(in) :: filename +! The array 'd' will be automatically allocated with the correct dimensions +real(dp), allocatable, intent(out) :: d(:, :) +! +! Example +! ------- +! +! real(dp), allocatable :: data(:, :) +! call loadtxt("log.txt", data) ! 'data' will be automatically allocated +! +! Where 'log.txt' contains for example:: +! +! 1 2 3 +! 2 4 6 +! 8 9 10 +! 11 12 13 +! ... +! +character :: c +integer :: s, ncol, nrow, ios, i +logical :: lastwhite +real(dp) :: r + +open(newunit=s, file=filename, status="old") + +! determine number of columns +ncol = 0 +lastwhite = .true. +do + read(s, '(a)', advance='no', iostat=ios) c + if (ios /= 0) exit + if (lastwhite .and. .not. whitechar(c)) ncol = ncol + 1 + lastwhite = whitechar(c) +end do + +rewind(s) + +! determine number or rows +nrow = 0 +do + read(s, *, iostat=ios) r + if (ios /= 0) exit + nrow = nrow + 1 +end do + +rewind(s) + +allocate(d(nrow, ncol)) +do i = 1, nrow + read(s, *) d(i, :) +end do +close(s) +end subroutine + +subroutine savetxt(filename, d) +! Saves a 2D array into a textfile. +! +! Arguments +! --------- +! +character(len=*), intent(in) :: filename ! File to save the array to +real(dp), intent(in) :: d(:, :) ! The 2D array to save +! +! Example +! ------- +! +! real(dp) :: data(3, 2) +! call savetxt("log.txt", data) + +integer :: s, i +open(newunit=s, file=filename, status="replace") +do i = 1, size(d, 1) + write(s, *) d(i, :) +end do +close(s) +end subroutine + + +logical function whitechar(char) ! white character +! returns .true. if char is space (32) or tab (9), .false. otherwise +character, intent(in) :: char +if (iachar(char) == 32 .or. iachar(char) == 9) then + whitechar = .true. +else + whitechar = .false. +end if +end function + +end module diff --git a/src/stdlib_types.f90 b/src/stdlib_types.f90 new file mode 100644 index 000000000..ee9968a73 --- /dev/null +++ b/src/stdlib_types.f90 @@ -0,0 +1,10 @@ +module stdlib_types +implicit none +private +public sp, dp, qp + +integer, parameter :: sp=kind(0.), & ! single precision + dp=kind(0.d0), & ! double precision + qp=selected_real_kind(32) ! quadruple precision + +end module From 9d0d3aae9f2f57296a3c3193c9d80c0205c0ebdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Thu, 19 Dec 2019 11:11:38 -0700 Subject: [PATCH 03/10] Add tests for loadtxt and savetxt --- src/CMakeLists.txt | 3 +++ src/stdlib_error.f90 | 41 ++++++++++++++++++++++++++++++ src/tests/CMakeLists.txt | 1 + src/tests/loadtxt/CMakeLists.txt | 12 +++++++++ src/tests/loadtxt/array1.dat | 4 +++ src/tests/loadtxt/array2.dat | 4 +++ src/tests/loadtxt/array3.dat | 16 ++++++++++++ src/tests/loadtxt/array4.dat | 3 +++ src/tests/loadtxt/test_loadtxt.f90 | 30 ++++++++++++++++++++++ src/tests/loadtxt/test_savetxt.f90 | 21 +++++++++++++++ 10 files changed, 135 insertions(+) create mode 100644 src/stdlib_error.f90 create mode 100644 src/tests/CMakeLists.txt create mode 100644 src/tests/loadtxt/CMakeLists.txt create mode 100644 src/tests/loadtxt/array1.dat create mode 100644 src/tests/loadtxt/array2.dat create mode 100644 src/tests/loadtxt/array3.dat create mode 100644 src/tests/loadtxt/array4.dat create mode 100644 src/tests/loadtxt/test_loadtxt.f90 create mode 100644 src/tests/loadtxt/test_savetxt.f90 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7412e9da2..1e26d59bf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,10 +1,13 @@ set(SRC stdlib_types.f90 stdlib_io.f90 + stdlib_error.f90 ) add_library(fortran_stdlib ${SRC}) +add_subdirectory(tests) + install(TARGETS fortran_stdlib RUNTIME DESTINATION bin ARCHIVE DESTINATION lib diff --git a/src/stdlib_error.f90 b/src/stdlib_error.f90 new file mode 100644 index 000000000..ffeb58129 --- /dev/null +++ b/src/stdlib_error.f90 @@ -0,0 +1,41 @@ +module stdlib_error +implicit none +private +public assert, error_stop + +contains + +subroutine assert(condition) +! If condition == .false., it aborts the program. +! +! Arguments +! --------- +! +logical, intent(in) :: condition +! +! Example +! ------- +! +! call assert(a == 5) + +if (.not. condition) call error_stop("Assert failed.") +end subroutine + +subroutine error_stop(msg) +! Aborts the program with nonzero exit code +! +! The statement "stop msg" will return 0 exit code when compiled using +! gfortran. error_stop() uses the statement "stop 1" which returns an exit code +! 1 and a print statement to print the message. +! +! Example +! ------- +! +! call error_stop("Invalid argument") + +character(len=*) :: msg ! Message to print on stdout +print *, msg +stop 1 +end subroutine + +end module diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt new file mode 100644 index 000000000..c6f586e91 --- /dev/null +++ b/src/tests/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(loadtxt) diff --git a/src/tests/loadtxt/CMakeLists.txt b/src/tests/loadtxt/CMakeLists.txt new file mode 100644 index 000000000..de771e0b3 --- /dev/null +++ b/src/tests/loadtxt/CMakeLists.txt @@ -0,0 +1,12 @@ +include_directories(${PROJECT_BINARY_DIR}/src) + +project(loadtxt) + +add_executable(test_loadtxt test_loadtxt.f90) +target_link_libraries(test_loadtxt fortran_stdlib) + +add_executable(test_savetxt test_savetxt.f90) +target_link_libraries(test_savetxt fortran_stdlib) + +add_test(test_loadtxt ${PROJECT_BINARY_DIR}/test_loadtxt) +add_test(test_savetxt ${PROJECT_BINARY_DIR}/test_savetxt) diff --git a/src/tests/loadtxt/array1.dat b/src/tests/loadtxt/array1.dat new file mode 100644 index 000000000..9ed9e364d --- /dev/null +++ b/src/tests/loadtxt/array1.dat @@ -0,0 +1,4 @@ +1 2 +3 4 +5 6 +7 8 diff --git a/src/tests/loadtxt/array2.dat b/src/tests/loadtxt/array2.dat new file mode 100644 index 000000000..8136afcc4 --- /dev/null +++ b/src/tests/loadtxt/array2.dat @@ -0,0 +1,4 @@ +1 2 9 +3 4 10 +5 6 11 +7 8 12 diff --git a/src/tests/loadtxt/array3.dat b/src/tests/loadtxt/array3.dat new file mode 100644 index 000000000..13b583f89 --- /dev/null +++ b/src/tests/loadtxt/array3.dat @@ -0,0 +1,16 @@ +1.000000000000000021e-08 9.199998759392489944e+01 +1.024113254885563425e-08 9.199998731474968849e+01 +1.048233721895820948e-08 9.199998703587728244e+01 +1.072361403187881949e-08 9.199998675729767683e+01 +1.096496300919481796e-08 9.199998647900135040e+01 +1.120638417249036630e-08 9.199998620097916557e+01 +1.144787754335570897e-08 9.199998592322251056e+01 +1.168944314338753750e-08 9.199998564572304360e+01 +1.193108099418952317e-08 9.199998536847290609e+01 +1.217279111737088596e-08 9.199998509146449521e+01 +1.241457353454836993e-08 9.199998481469057765e+01 +1.265642826734443823e-08 9.199998453814424693e+01 +1.289835533738818635e-08 9.199998426181879552e+01 +1.314035476631514857e-08 9.199998398570787117e+01 +1.338242657576766519e-08 9.199998370980536322e+01 +1.362457078739434161e-08 9.199998343410533153e+01 diff --git a/src/tests/loadtxt/array4.dat b/src/tests/loadtxt/array4.dat new file mode 100644 index 000000000..988e9b6cb --- /dev/null +++ b/src/tests/loadtxt/array4.dat @@ -0,0 +1,3 @@ + 1.56367173122998851E-010 4.51568171776229776E-007 4.96568621780730290E-006 5.01068666781180638E-005 5.01518671281225327E-004 5.01763629287519872E-003 5.58487648776459511E-002 0.32618374746711520 1.7639051761733842 9.4101331514118236 + 8.23481961129666271E-010 4.58239319656296504E-007 5.03239769660796763E-006 5.07739814661247314E-005 5.08189819161291786E-004 5.09287863145356859E-003 5.62489258981838380E-002 0.32831192218075922 1.7752234390209392 9.4703270222745211 + 2.02201163784892633E-009 4.70224616423489051E-007 5.15225066427989480E-006 5.19725111428439625E-005 5.20175115928484585E-004 5.22805802989171828E-003 5.69678499382489378E-002 0.33213537295325257 1.7955576815764616 9.5784705410250410 diff --git a/src/tests/loadtxt/test_loadtxt.f90 b/src/tests/loadtxt/test_loadtxt.f90 new file mode 100644 index 000000000..4ae4c41b0 --- /dev/null +++ b/src/tests/loadtxt/test_loadtxt.f90 @@ -0,0 +1,30 @@ +program test_loadtxt +use stdlib_types, only: dp +use stdlib_io, only: loadtxt +implicit none + +real(dp), allocatable :: d(:, :) +call loadtxt("array1.dat", d) +call print_array(d) + +call loadtxt("array2.dat", d) +call print_array(d) + +call loadtxt("array3.dat", d) +call print_array(d) + +call loadtxt("array4.dat", d) +call print_array(d) + +contains + +subroutine print_array(a) +real(dp) :: a(:, :) +integer :: i +print *, "Array, shape=(", size(a, 1), ",", size(a, 2), ")" +do i = 1, size(a, 1) + print *, a(i, :) +end do +end subroutine + +end program diff --git a/src/tests/loadtxt/test_savetxt.f90 b/src/tests/loadtxt/test_savetxt.f90 new file mode 100644 index 000000000..7ff4654d9 --- /dev/null +++ b/src/tests/loadtxt/test_savetxt.f90 @@ -0,0 +1,21 @@ +program test_loadtxt +use stdlib_types, only: dp +use stdlib_io, only: loadtxt, savetxt +use stdlib_error, only: assert +implicit none + +real(dp) :: d(3, 2), e(2, 3) +real(dp), allocatable :: d2(:, :) +d = reshape([1, 2, 3, 4, 5, 6], [3, 2]) +call savetxt("tmp.dat", d) +call loadtxt("tmp.dat", d2) +call assert(all(shape(d2) == [3, 2])) +call assert(all(abs(d-d2) < epsilon(1._dp))) + +e = reshape([1, 2, 3, 4, 5, 6], [2, 3]) +call savetxt("tmp.dat", e) +call loadtxt("tmp.dat", d2) +call assert(all(shape(d2) == [2, 3])) +call assert(all(abs(e-d2) < epsilon(1._dp))) + +end program From 8d33ead73e9252c0bbc154005788df480a288302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Fri, 20 Dec 2019 16:24:03 -0700 Subject: [PATCH 04/10] Update src/stdlib_io.f90 --- src/stdlib_io.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdlib_io.f90 b/src/stdlib_io.f90 index b26c29b90..cbf9b3e3a 100644 --- a/src/stdlib_io.f90 +++ b/src/stdlib_io.f90 @@ -2,7 +2,7 @@ module stdlib_io use stdlib_types implicit none private -public loadtxt, savetxt +public :: loadtxt, savetxt contains From 43ed8374a6038cc7f4e087c21a3faf857249f4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Fri, 20 Dec 2019 21:40:35 -0700 Subject: [PATCH 05/10] Use :: after public --- src/stdlib_error.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdlib_error.f90 b/src/stdlib_error.f90 index ffeb58129..89551f595 100644 --- a/src/stdlib_error.f90 +++ b/src/stdlib_error.f90 @@ -1,7 +1,7 @@ module stdlib_error implicit none private -public assert, error_stop +public :: assert, error_stop contains From eff8a6f30c9008368b2a69ea6bbd39dd88d011c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Fri, 20 Dec 2019 21:47:41 -0700 Subject: [PATCH 06/10] Remove stdlib_types, use iso_fortran_env instead --- src/CMakeLists.txt | 1 - src/stdlib_io.f90 | 2 +- src/stdlib_types.f90 | 10 ---------- src/tests/loadtxt/test_loadtxt.f90 | 2 +- src/tests/loadtxt/test_savetxt.f90 | 2 +- 5 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 src/stdlib_types.f90 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1e26d59bf..f1159e594 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,4 @@ set(SRC - stdlib_types.f90 stdlib_io.f90 stdlib_error.f90 ) diff --git a/src/stdlib_io.f90 b/src/stdlib_io.f90 index cbf9b3e3a..218b6e656 100644 --- a/src/stdlib_io.f90 +++ b/src/stdlib_io.f90 @@ -1,5 +1,5 @@ module stdlib_io -use stdlib_types +use iso_fortran_env, only: dp=>real64 implicit none private public :: loadtxt, savetxt diff --git a/src/stdlib_types.f90 b/src/stdlib_types.f90 deleted file mode 100644 index ee9968a73..000000000 --- a/src/stdlib_types.f90 +++ /dev/null @@ -1,10 +0,0 @@ -module stdlib_types -implicit none -private -public sp, dp, qp - -integer, parameter :: sp=kind(0.), & ! single precision - dp=kind(0.d0), & ! double precision - qp=selected_real_kind(32) ! quadruple precision - -end module diff --git a/src/tests/loadtxt/test_loadtxt.f90 b/src/tests/loadtxt/test_loadtxt.f90 index 4ae4c41b0..6aae1e24b 100644 --- a/src/tests/loadtxt/test_loadtxt.f90 +++ b/src/tests/loadtxt/test_loadtxt.f90 @@ -1,5 +1,5 @@ program test_loadtxt -use stdlib_types, only: dp +use iso_fortran_env, only: dp=>real64 use stdlib_io, only: loadtxt implicit none diff --git a/src/tests/loadtxt/test_savetxt.f90 b/src/tests/loadtxt/test_savetxt.f90 index 7ff4654d9..058a0efef 100644 --- a/src/tests/loadtxt/test_savetxt.f90 +++ b/src/tests/loadtxt/test_savetxt.f90 @@ -1,5 +1,5 @@ program test_loadtxt -use stdlib_types, only: dp +use iso_fortran_env, only: dp=>real64 use stdlib_io, only: loadtxt, savetxt use stdlib_error, only: assert implicit none From 559bfd75caa40ad0500b8493c3cb7a4640be211c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Fri, 20 Dec 2019 21:54:04 -0700 Subject: [PATCH 07/10] Move the code to stdlib_experimental --- src/CMakeLists.txt | 4 ++-- src/{stdlib_error.f90 => stdlib_experimental_error.f90} | 2 +- src/{stdlib_io.f90 => stdlib_experimental_io.f90} | 2 +- src/tests/loadtxt/test_loadtxt.f90 | 2 +- src/tests/loadtxt/test_savetxt.f90 | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) rename src/{stdlib_error.f90 => stdlib_experimental_error.f90} (95%) rename src/{stdlib_io.f90 => stdlib_experimental_io.f90} (98%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f1159e594..faa30df06 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ set(SRC - stdlib_io.f90 - stdlib_error.f90 + stdlib_experimental_io.f90 + stdlib_experimental_error.f90 ) add_library(fortran_stdlib ${SRC}) diff --git a/src/stdlib_error.f90 b/src/stdlib_experimental_error.f90 similarity index 95% rename from src/stdlib_error.f90 rename to src/stdlib_experimental_error.f90 index 89551f595..1c82d6539 100644 --- a/src/stdlib_error.f90 +++ b/src/stdlib_experimental_error.f90 @@ -1,4 +1,4 @@ -module stdlib_error +module stdlib_experimental_error implicit none private public :: assert, error_stop diff --git a/src/stdlib_io.f90 b/src/stdlib_experimental_io.f90 similarity index 98% rename from src/stdlib_io.f90 rename to src/stdlib_experimental_io.f90 index 218b6e656..f2aee538c 100644 --- a/src/stdlib_io.f90 +++ b/src/stdlib_experimental_io.f90 @@ -1,4 +1,4 @@ -module stdlib_io +module stdlib_experimental_io use iso_fortran_env, only: dp=>real64 implicit none private diff --git a/src/tests/loadtxt/test_loadtxt.f90 b/src/tests/loadtxt/test_loadtxt.f90 index 6aae1e24b..490fcea38 100644 --- a/src/tests/loadtxt/test_loadtxt.f90 +++ b/src/tests/loadtxt/test_loadtxt.f90 @@ -1,6 +1,6 @@ program test_loadtxt use iso_fortran_env, only: dp=>real64 -use stdlib_io, only: loadtxt +use stdlib_experimental_io, only: loadtxt implicit none real(dp), allocatable :: d(:, :) diff --git a/src/tests/loadtxt/test_savetxt.f90 b/src/tests/loadtxt/test_savetxt.f90 index 058a0efef..c8cb6f324 100644 --- a/src/tests/loadtxt/test_savetxt.f90 +++ b/src/tests/loadtxt/test_savetxt.f90 @@ -1,7 +1,7 @@ program test_loadtxt use iso_fortran_env, only: dp=>real64 -use stdlib_io, only: loadtxt, savetxt -use stdlib_error, only: assert +use stdlib_experimental_io, only: loadtxt, savetxt +use stdlib_experimental_error, only: assert implicit none real(dp) :: d(3, 2), e(2, 3) From 5e9565e85956ea2860bc1a9a5da55465af1dc1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Fri, 20 Dec 2019 22:02:25 -0700 Subject: [PATCH 08/10] Implement single precision version --- src/stdlib_experimental_io.f90 | 35 +++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/stdlib_experimental_io.f90 b/src/stdlib_experimental_io.f90 index f2aee538c..9506bf234 100644 --- a/src/stdlib_experimental_io.f90 +++ b/src/stdlib_experimental_io.f90 @@ -1,12 +1,31 @@ module stdlib_experimental_io -use iso_fortran_env, only: dp=>real64 +use iso_fortran_env, only: sp=>real32, dp=>real64 implicit none private public :: loadtxt, savetxt +interface loadtxt + module procedure sloadtxt + module procedure dloadtxt +end interface + +interface savetxt + module procedure ssavetxt + module procedure dsavetxt +end interface + contains -subroutine loadtxt(filename, d) +subroutine sloadtxt(filename, d) +character(len=*), intent(in) :: filename +real(sp), allocatable, intent(out) :: d(:,:) +real(dp), allocatable :: tmp(:,:) +call dloadtxt(filename, tmp) +allocate(d(size(tmp,1),size(tmp,2))) +d = real(tmp,sp) +end subroutine + +subroutine dloadtxt(filename, d) ! Loads a 2D array from a text file. ! ! Arguments @@ -15,7 +34,7 @@ subroutine loadtxt(filename, d) ! Filename to load the array from character(len=*), intent(in) :: filename ! The array 'd' will be automatically allocated with the correct dimensions -real(dp), allocatable, intent(out) :: d(:, :) +real(dp), allocatable, intent(out) :: d(:,:) ! ! Example ! ------- @@ -67,14 +86,20 @@ subroutine loadtxt(filename, d) close(s) end subroutine -subroutine savetxt(filename, d) +subroutine ssavetxt(filename, d) +character(len=*), intent(in) :: filename +real(sp), intent(in) :: d(:,:) +call dsavetxt(filename, real(d,dp)) +end subroutine + +subroutine dsavetxt(filename, d) ! Saves a 2D array into a textfile. ! ! Arguments ! --------- ! character(len=*), intent(in) :: filename ! File to save the array to -real(dp), intent(in) :: d(:, :) ! The 2D array to save +real(dp), intent(in) :: d(:,:) ! The 2D array to save ! ! Example ! ------- From 57d517fb4b99857d82b21d87a80afa6b806e48a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Fri, 20 Dec 2019 22:05:46 -0700 Subject: [PATCH 09/10] Refactor the test --- src/tests/loadtxt/test_savetxt.f90 | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/tests/loadtxt/test_savetxt.f90 b/src/tests/loadtxt/test_savetxt.f90 index c8cb6f324..f6f5df0f9 100644 --- a/src/tests/loadtxt/test_savetxt.f90 +++ b/src/tests/loadtxt/test_savetxt.f90 @@ -4,18 +4,24 @@ program test_loadtxt use stdlib_experimental_error, only: assert implicit none -real(dp) :: d(3, 2), e(2, 3) -real(dp), allocatable :: d2(:, :) -d = reshape([1, 2, 3, 4, 5, 6], [3, 2]) -call savetxt("tmp.dat", d) -call loadtxt("tmp.dat", d2) -call assert(all(shape(d2) == [3, 2])) -call assert(all(abs(d-d2) < epsilon(1._dp))) +call test1() -e = reshape([1, 2, 3, 4, 5, 6], [2, 3]) -call savetxt("tmp.dat", e) -call loadtxt("tmp.dat", d2) -call assert(all(shape(d2) == [2, 3])) -call assert(all(abs(e-d2) < epsilon(1._dp))) +contains + + subroutine test1() + real(dp) :: d(3, 2), e(2, 3) + real(dp), allocatable :: d2(:, :) + d = reshape([1, 2, 3, 4, 5, 6], [3, 2]) + call savetxt("tmp.dat", d) + call loadtxt("tmp.dat", d2) + call assert(all(shape(d2) == [3, 2])) + call assert(all(abs(d-d2) < epsilon(1._dp))) + + e = reshape([1, 2, 3, 4, 5, 6], [2, 3]) + call savetxt("tmp.dat", e) + call loadtxt("tmp.dat", d2) + call assert(all(shape(d2) == [2, 3])) + call assert(all(abs(e-d2) < epsilon(1._dp))) + end subroutine end program From 65301b996a592727939a56b436ee1c97e84c30b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Fri, 20 Dec 2019 22:06:56 -0700 Subject: [PATCH 10/10] Add a test for single precision --- src/tests/loadtxt/test_savetxt.f90 | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/tests/loadtxt/test_savetxt.f90 b/src/tests/loadtxt/test_savetxt.f90 index f6f5df0f9..ca6344b83 100644 --- a/src/tests/loadtxt/test_savetxt.f90 +++ b/src/tests/loadtxt/test_savetxt.f90 @@ -1,14 +1,32 @@ program test_loadtxt -use iso_fortran_env, only: dp=>real64 +use iso_fortran_env, only: sp=>real32, dp=>real64 use stdlib_experimental_io, only: loadtxt, savetxt use stdlib_experimental_error, only: assert implicit none -call test1() +call test_sp() +call test_dp() contains - subroutine test1() + subroutine test_sp() + real(sp) :: d(3, 2), e(2, 3) + real(sp), allocatable :: d2(:, :) + d = reshape([1, 2, 3, 4, 5, 6], [3, 2]) + call savetxt("tmp.dat", d) + call loadtxt("tmp.dat", d2) + call assert(all(shape(d2) == [3, 2])) + call assert(all(abs(d-d2) < epsilon(1._sp))) + + e = reshape([1, 2, 3, 4, 5, 6], [2, 3]) + call savetxt("tmp.dat", e) + call loadtxt("tmp.dat", d2) + call assert(all(shape(d2) == [2, 3])) + call assert(all(abs(e-d2) < epsilon(1._sp))) + end subroutine + + + subroutine test_dp() real(dp) :: d(3, 2), e(2, 3) real(dp), allocatable :: d2(:, :) d = reshape([1, 2, 3, 4, 5, 6], [3, 2])