Skip to content

Commit c2edbaf

Browse files
committed
stdlib_experimental_io: modification of sp case + addition of qp
*Modification of the sp case to avoid additional temporary arrays (+ to make it more general) *Addition of qp case *Proposition of using unlimited polymorphic objects
1 parent 15c47e9 commit c2edbaf

File tree

3 files changed

+278
-34
lines changed

3 files changed

+278
-34
lines changed

src/stdlib_experimental_io.f90

Lines changed: 214 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,66 @@
11
module stdlib_experimental_io
2-
use iso_fortran_env, only: sp=>real32, dp=>real64
2+
use iso_fortran_env, only: sp=>real32, dp=>real64 ,qp=>real128
33
implicit none
44
private
55
public :: loadtxt, savetxt
6+
public :: savetxt_poly
67

78
interface loadtxt
89
module procedure sloadtxt
910
module procedure dloadtxt
11+
module procedure qloadtxt
1012
end interface
1113

1214
interface savetxt
1315
module procedure ssavetxt
1416
module procedure dsavetxt
17+
module procedure qsavetxt
1518
end interface
1619

1720
contains
1821

22+
!PUBLIC
1923
subroutine sloadtxt(filename, d)
24+
! Loads a 2D array from a text file.
25+
!
26+
! Arguments
27+
! ---------
28+
!
29+
! Filename to load the array from
2030
character(len=*), intent(in) :: filename
31+
! The array 'd' will be automatically allocated with the correct dimensions
2132
real(sp), allocatable, intent(out) :: d(:,:)
22-
real(dp), allocatable :: tmp(:,:)
23-
call dloadtxt(filename, tmp)
24-
allocate(d(size(tmp,1),size(tmp,2)))
25-
d = real(tmp,sp)
33+
!
34+
! Example
35+
! -------
36+
!
37+
! real(sp), allocatable :: data(:, :)
38+
! call loadtxt("log.txt", data) ! 'data' will be automatically allocated
39+
!
40+
! Where 'log.txt' contains for example::
41+
!
42+
! 1 2 3
43+
! 2 4 6
44+
! 8 9 10
45+
! 11 12 13
46+
! ...
47+
!
48+
integer :: s
49+
integer ::nrow,ncol,i
50+
51+
open(newunit=s, file=filename, status="old")
52+
53+
! determine number of columns
54+
ncol=number_of_columns(s)
55+
56+
! determine number or rows
57+
nrow = number_of_rows_numeric(s)
58+
59+
allocate(d(nrow, ncol))
60+
do i = 1, nrow
61+
read(s, *) d(i, :)
62+
end do
63+
close(s)
2664
end subroutine
2765

2866
subroutine dloadtxt(filename, d)
@@ -50,34 +88,59 @@ subroutine dloadtxt(filename, d)
5088
! 11 12 13
5189
! ...
5290
!
53-
character :: c
54-
integer :: s, ncol, nrow, ios, i
55-
logical :: lastwhite
56-
real(dp) :: r
91+
integer :: s
92+
integer ::nrow,ncol,i
5793

5894
open(newunit=s, file=filename, status="old")
5995

6096
! determine number of columns
61-
ncol = 0
62-
lastwhite = .true.
63-
do
64-
read(s, '(a)', advance='no', iostat=ios) c
65-
if (ios /= 0) exit
66-
if (lastwhite .and. .not. whitechar(c)) ncol = ncol + 1
67-
lastwhite = whitechar(c)
68-
end do
69-
70-
rewind(s)
97+
ncol=number_of_columns(s)
7198

7299
! determine number or rows
73-
nrow = 0
74-
do
75-
read(s, *, iostat=ios) r
76-
if (ios /= 0) exit
77-
nrow = nrow + 1
100+
nrow = number_of_rows_numeric(s)
101+
102+
allocate(d(nrow, ncol))
103+
do i = 1, nrow
104+
read(s, *) d(i, :)
78105
end do
106+
close(s)
107+
end subroutine
108+
109+
subroutine qloadtxt(filename, d)
110+
! Loads a 2D array from a text file.
111+
!
112+
! Arguments
113+
! ---------
114+
!
115+
! Filename to load the array from
116+
character(len=*), intent(in) :: filename
117+
! The array 'd' will be automatically allocated with the correct dimensions
118+
real(qp), allocatable, intent(out) :: d(:,:)
119+
!
120+
! Example
121+
! -------
122+
!
123+
! real(qp), allocatable :: data(:, :)
124+
! call loadtxt("log.txt", data) ! 'data' will be automatically allocated
125+
!
126+
! Where 'log.txt' contains for example::
127+
!
128+
! 1 2 3
129+
! 2 4 6
130+
! 8 9 10
131+
! 11 12 13
132+
! ...
133+
!
134+
integer :: s
135+
integer ::nrow,ncol,i
136+
137+
open(newunit=s, file=filename, status="old")
138+
139+
! determine number of columns
140+
ncol=number_of_columns(s)
79141

80-
rewind(s)
142+
! determine number or rows
143+
nrow = number_of_rows_numeric(s)
81144

82145
allocate(d(nrow, ncol))
83146
do i = 1, nrow
@@ -86,10 +149,28 @@ subroutine dloadtxt(filename, d)
86149
close(s)
87150
end subroutine
88151

152+
89153
subroutine ssavetxt(filename, d)
90-
character(len=*), intent(in) :: filename
91-
real(sp), intent(in) :: d(:,:)
92-
call dsavetxt(filename, real(d,dp))
154+
! Saves a 2D array into a textfile.
155+
!
156+
! Arguments
157+
! ---------
158+
!
159+
character(len=*), intent(in) :: filename ! File to save the array to
160+
real(sp), intent(in) :: d(:,:) ! The 2D array to save
161+
!
162+
! Example
163+
! -------
164+
!
165+
! real(sp) :: data(3, 2)
166+
! call savetxt("log.txt", data)
167+
168+
integer :: s, i
169+
open(newunit=s, file=filename, status="replace")
170+
do i = 1, size(d, 1)
171+
write(s, *) d(i, :)
172+
end do
173+
close(s)
93174
end subroutine
94175

95176
subroutine dsavetxt(filename, d)
@@ -115,6 +196,111 @@ subroutine dsavetxt(filename, d)
115196
close(s)
116197
end subroutine
117198

199+
subroutine qsavetxt(filename, d)
200+
! Saves a 2D array into a textfile.
201+
!
202+
! Arguments
203+
! ---------
204+
!
205+
character(len=*), intent(in) :: filename ! File to save the array to
206+
real(qp), intent(in) :: d(:,:) ! The 2D array to save
207+
!
208+
! Example
209+
! -------
210+
!
211+
! real(dp) :: data(3, 2)
212+
! call savetxt("log.txt", data)
213+
214+
integer :: s, i
215+
open(newunit=s, file=filename, status="replace")
216+
do i = 1, size(d, 1)
217+
write(s, *) d(i, :)
218+
end do
219+
close(s)
220+
end subroutine
221+
222+
!OR
223+
224+
subroutine savetxt_poly(filename, d)
225+
! Saves a 2D array into a textfile.
226+
!
227+
! Arguments
228+
! ---------
229+
!
230+
character(len=*), intent(in) :: filename ! File to save the array to
231+
class(*), intent(in) :: d(:,:) ! The 2D array to save
232+
!
233+
! Example
234+
! -------
235+
!
236+
! real(sp) :: data(3, 2)
237+
! call savetxt("log.txt", data)
238+
239+
integer :: s, i
240+
open(newunit=s, file=filename, status="replace")
241+
242+
select type(d)
243+
type is(real(sp))
244+
do i = 1, size(d, 1)
245+
write(s, *) d(i, :)
246+
end do
247+
type is(real(dp))
248+
do i = 1, size(d, 1)
249+
write(s, *) d(i, :)
250+
end do
251+
type is(real(qp))
252+
do i = 1, size(d, 1)
253+
write(s, *) d(i, :)
254+
end do
255+
class default
256+
write(*,'(a)')'The proposed type is not supported'
257+
error stop
258+
end select
259+
260+
close(s)
261+
262+
end subroutine
263+
264+
!PRIVATE
265+
integer function number_of_columns(s)
266+
! determine number of columns
267+
integer,intent(in)::s
268+
269+
integer :: ios
270+
character :: c
271+
logical :: lastwhite
272+
273+
rewind(s)
274+
number_of_columns = 0
275+
lastwhite = .true.
276+
do
277+
read(s, '(a)', advance='no', iostat=ios) c
278+
if (ios /= 0) exit
279+
if (lastwhite .and. .not. whitechar(c)) number_of_columns = number_of_columns + 1
280+
lastwhite = whitechar(c)
281+
end do
282+
rewind(s)
283+
284+
end function
285+
286+
integer function number_of_rows_numeric(s)
287+
! determine number or rows
288+
integer,intent(in)::s
289+
integer :: ios
290+
291+
real::r
292+
293+
rewind(s)
294+
number_of_rows_numeric = 0
295+
do
296+
read(s, *, iostat=ios) r
297+
if (ios /= 0) exit
298+
number_of_rows_numeric = number_of_rows_numeric + 1
299+
end do
300+
301+
rewind(s)
302+
303+
end function
118304

119305
logical function whitechar(char) ! white character
120306
! returns .true. if char is space (32) or tab (9), .false. otherwise

src/tests/loadtxt/test_loadtxt.f90

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
program test_loadtxt
2-
use iso_fortran_env, only: dp=>real64
2+
use iso_fortran_env, only: sp=>real32, dp=>real64 ,qp=>real128
33
use stdlib_experimental_io, only: loadtxt
44
implicit none
55

6+
real(sp), allocatable :: s(:, :)
67
real(dp), allocatable :: d(:, :)
8+
real(qp), allocatable :: q(:, :)
9+
10+
call loadtxt("array1.dat", s)
11+
call print_array(s)
12+
713
call loadtxt("array1.dat", d)
814
call print_array(d)
915

@@ -16,15 +22,34 @@ program test_loadtxt
1622
call loadtxt("array4.dat", d)
1723
call print_array(d)
1824

25+
call loadtxt("array4.dat", q)
26+
call print_array(q)
27+
1928
contains
2029

2130
subroutine print_array(a)
22-
real(dp) :: a(:, :)
31+
class(*),intent(in) :: a(:, :)
2332
integer :: i
2433
print *, "Array, shape=(", size(a, 1), ",", size(a, 2), ")"
25-
do i = 1, size(a, 1)
34+
35+
select type(a)
36+
type is(real(sp))
37+
do i = 1, size(a, 1)
2638
print *, a(i, :)
27-
end do
39+
end do
40+
type is(real(dp))
41+
do i = 1, size(a, 1)
42+
print *, a(i, :)
43+
end do
44+
type is(real(qp))
45+
do i = 1, size(a, 1)
46+
print *, a(i, :)
47+
end do
48+
class default
49+
write(*,'(a)')'The proposed type is not supported'
50+
error stop
51+
end select
52+
2853
end subroutine
2954

3055
end program

0 commit comments

Comments
 (0)