Skip to content

Commit 9655e8d

Browse files
authoredFeb 3, 2020
Merge pull request #138 from fiolj/master
Added complex to io
2 parents 4d66d77 + ff46b12 commit 9655e8d

8 files changed

+112
-31
lines changed
 

‎src/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ fypp_f90("${fyppFlags}" "${fppFiles}" outFiles)
2121

2222
set(SRC
2323
stdlib_experimental_ascii.f90
24-
stdlib_experimental_io.f90
2524
stdlib_experimental_error.f90
2625
stdlib_experimental_kinds.f90
2726
stdlib_experimental_optval.f90

‎src/common.fypp

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99
#! Collected (kind, type) tuples for real types
1010
#:set REAL_KINDS_TYPES = list(zip(REAL_KINDS, REAL_TYPES))
1111

12+
#! Complex kinds to be considered during templating
13+
#:set CMPLX_KINDS = ["sp", "dp", "qp"]
14+
15+
#! Complex types to be considere during templating
16+
#:set CMPLX_TYPES = ["complex({})".format(k) for k in CMPLX_KINDS]
17+
18+
#! Collected (kind, type) tuples for complex types
19+
#:set CMPLX_KINDS_TYPES = list(zip(CMPLX_KINDS, CMPLX_TYPES))
1220

1321
#! Integer kinds to be considered during templating
1422
#:set INT_KINDS = ["int8", "int16", "int32", "int64"]

‎src/stdlib_experimental_io.fypp

+25-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#:include "common.fypp"
22

3-
#:set KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES
3+
#:set KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + CMPLX_KINDS_TYPES
44

55
module stdlib_experimental_io
66

@@ -18,21 +18,21 @@ module stdlib_experimental_io
1818
public :: parse_mode
1919

2020
interface loadtxt
21-
#:for k1, _ in KINDS_TYPES
22-
module procedure loadtxt_${k1}$
21+
#:for k1, t1 in KINDS_TYPES
22+
module procedure loadtxt_${t1[0]}$${k1}$
2323
#:endfor
2424
end interface loadtxt
2525

2626
interface savetxt
27-
#:for k1, _ in KINDS_TYPES
28-
module procedure savetxt_${k1}$
27+
#:for k1, t1 in KINDS_TYPES
28+
module procedure savetxt_${t1[0]}$${k1}$
2929
#:endfor
3030
end interface
3131

3232
contains
3333

3434
#:for k1, t1 in KINDS_TYPES
35-
subroutine loadtxt_${k1}$(filename, d)
35+
subroutine loadtxt_${t1[0]}$${k1}$(filename, d)
3636
! Loads a 2D array from a text file.
3737
!
3838
! Arguments
@@ -58,7 +58,7 @@ contains
5858
! ...
5959
!
6060
integer :: s
61-
integer :: nrow,ncol,i
61+
integer :: nrow, ncol, i
6262

6363
s = open(filename)
6464

@@ -74,12 +74,12 @@ contains
7474
end do
7575
close(s)
7676

77-
end subroutine loadtxt_${k1}$
77+
end subroutine loadtxt_${t1[0]}$${k1}$
7878
#:endfor
7979

8080

8181
#:for k1, t1 in KINDS_TYPES
82-
subroutine savetxt_${k1}$(filename, d)
82+
subroutine savetxt_${t1[0]}$${k1}$(filename, d)
8383
! Saves a 2D array into a text file.
8484
!
8585
! Arguments
@@ -100,13 +100,13 @@ contains
100100
write(s, *) d(i, :)
101101
end do
102102
close(s)
103-
end subroutine savetxt_${k1}$
103+
end subroutine savetxt_${t1[0]}$${k1}$
104104
#:endfor
105105

106106

107107
integer function number_of_columns(s)
108108
! determine number of columns
109-
integer,intent(in)::s
109+
integer,intent(in) :: s
110110

111111
integer :: ios
112112
character :: c
@@ -126,23 +126,33 @@ contains
126126
end function number_of_columns
127127

128128

129-
integer function number_of_rows_numeric(s)
129+
integer function number_of_rows_numeric(s) result(nrows)
130130
! determine number or rows
131131
integer,intent(in)::s
132132
integer :: ios
133133

134-
real::r
134+
real :: r
135+
complex :: z
135136

136137
rewind(s)
137-
number_of_rows_numeric = 0
138+
nrows = 0
138139
do
139140
read(s, *, iostat=ios) r
140141
if (ios /= 0) exit
141-
number_of_rows_numeric = number_of_rows_numeric + 1
142+
nrows = nrows + 1
142143
end do
143144

144145
rewind(s)
145146

147+
! If there are no rows of real numbers, it may be that they are complex
148+
if( nrows == 0) then
149+
do
150+
read(s, *, iostat=ios) z
151+
if (ios /= 0) exit
152+
nrows = nrows + 1
153+
end do
154+
rewind(s)
155+
end if
146156
end function number_of_rows_numeric
147157

148158

‎src/stdlib_experimental_io.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Loads a rank-2 `array` from a text file.
2020

2121
`filename`: Shall be a character expression containing the file name from which to load the rank-2 `array`.
2222

23-
`array`: Shall be an allocatable rank-2 array of type `real` or `integer`.
23+
`array`: Shall be an allocatable rank-2 array of type `real`, `complex` or `integer`.
2424

2525
### Return value
2626

@@ -104,7 +104,7 @@ Saves a rank-2 `array` into a text file.
104104

105105
`filename`: Shall be a character expression containing the name of the file that will contain the 2D `array`.
106106

107-
`array`: Shall be a rank-2 array of type `real` or `integer`.
107+
`array`: Shall be a rank-2 array of type `real`, `complex` or `integer`.
108108

109109
### Output
110110

‎src/tests/io/array5.dat

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
(1.0000000000000000,0.0000000000000000) (3.0000000000000000,0.0000000000000000) (5.0000000000000000,0.0000000000000000)
2+
(2.0000000000000000,0.0000000000000000) (4.0000000000000000,0.0000000000000000) (6.0000000000000000,0.0000000000000000)

‎src/tests/io/test_loadtxt.f90

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ program test_loadtxt
77
integer(int32), allocatable :: i(:, :)
88
real(sp), allocatable :: s(:, :)
99
real(dp), allocatable :: d(:, :)
10+
complex(dp), allocatable :: z(:, :)
1011

1112
call loadtxt("array1.dat", i)
1213
call print_array(i)
@@ -26,6 +27,9 @@ program test_loadtxt
2627
call loadtxt("array4.dat", d)
2728
call print_array(d)
2829

30+
call loadtxt("array5.dat", z)
31+
call print_array(z)
32+
2933
contains
3034

3135
subroutine print_array(a)
@@ -46,6 +50,10 @@ subroutine print_array(a)
4650
do i = 1, size(a, 1)
4751
print *, a(i, :)
4852
end do
53+
type is(complex(dp))
54+
do i = 1, size(a, 1)
55+
print *, a(i, :)
56+
end do
4957
class default
5058
call error_stop('The proposed type is not supported')
5159
end select

‎src/tests/io/test_savetxt.f90

+45-9
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ program test_savetxt
88

99
outpath = get_outpath() // "/tmp.dat"
1010

11-
call test_int32(outpath)
12-
call test_sp(outpath)
13-
call test_dp(outpath)
11+
call test_iint32(outpath)
12+
call test_rsp(outpath)
13+
call test_rdp(outpath)
14+
call test_csp(outpath)
15+
call test_cdp(outpath)
1416

1517
contains
1618

@@ -27,7 +29,7 @@ function get_outpath() result(outpath)
2729
endif
2830
end function get_outpath
2931

30-
subroutine test_int32(outpath)
32+
subroutine test_iint32(outpath)
3133
character(*), intent(in) :: outpath
3234
integer(int32) :: d(3, 2), e(2, 3)
3335
integer(int32), allocatable :: d2(:, :)
@@ -45,7 +47,7 @@ subroutine test_int32(outpath)
4547
end subroutine
4648

4749

48-
subroutine test_sp(outpath)
50+
subroutine test_rsp(outpath)
4951
character(*), intent(in) :: outpath
5052
real(sp) :: d(3, 2), e(2, 3)
5153
real(sp), allocatable :: d2(:, :)
@@ -60,10 +62,10 @@ subroutine test_sp(outpath)
6062
call loadtxt(outpath, d2)
6163
call assert(all(shape(d2) == [2, 3]))
6264
call assert(all(abs(e-d2) < epsilon(1._sp)))
63-
end subroutine
65+
end subroutine test_rsp
6466

6567

66-
subroutine test_dp(outpath)
68+
subroutine test_rdp(outpath)
6769
character(*), intent(in) :: outpath
6870
real(dp) :: d(3, 2), e(2, 3)
6971
real(dp), allocatable :: d2(:, :)
@@ -78,6 +80,40 @@ subroutine test_dp(outpath)
7880
call loadtxt(outpath, d2)
7981
call assert(all(shape(d2) == [2, 3]))
8082
call assert(all(abs(e-d2) < epsilon(1._dp)))
81-
end subroutine
83+
end subroutine test_rdp
84+
85+
subroutine test_csp(outpath)
86+
character(*), intent(in) :: outpath
87+
complex(sp) :: d(3, 2), e(2, 3)
88+
complex(sp), allocatable :: d2(:, :)
89+
d = cmplx(1, 1)* reshape([1, 2, 3, 4, 5, 6], [3, 2])
90+
call savetxt(outpath, d)
91+
call loadtxt(outpath, d2)
92+
call assert(all(shape(d2) == [3, 2]))
93+
call assert(all(abs(d-d2) < epsilon(1._sp)))
94+
95+
e = cmplx(1, 1)* reshape([1, 2, 3, 4, 5, 6], [2, 3])
96+
call savetxt(outpath, e)
97+
call loadtxt(outpath, d2)
98+
call assert(all(shape(d2) == [2, 3]))
99+
call assert(all(abs(e-d2) < epsilon(1._sp)))
100+
end subroutine test_csp
101+
102+
subroutine test_cdp(outpath)
103+
character(*), intent(in) :: outpath
104+
complex(dp) :: d(3, 2), e(2, 3)
105+
complex(dp), allocatable :: d2(:, :)
106+
d = cmplx(1._dp, 1._dp)* reshape([1, 2, 3, 4, 5, 6], [3, 2])
107+
call savetxt(outpath, d)
108+
call loadtxt(outpath, d2)
109+
call assert(all(shape(d2) == [3, 2]))
110+
call assert(all(abs(d-d2) < epsilon(1._dp)))
111+
112+
e = cmplx(1, 1)* reshape([1, 2, 3, 4, 5, 6], [2, 3])
113+
call savetxt(outpath, e)
114+
call loadtxt(outpath, d2)
115+
call assert(all(shape(d2) == [2, 3]))
116+
call assert(all(abs(e-d2) < epsilon(1._dp)))
117+
end subroutine test_cdp
82118

83-
end program
119+
end program test_savetxt

‎src/tests/io/test_savetxt_qp.f90

+22-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ program test_savetxt_qp
88

99
outpath = get_outpath() // "/tmp_qp.dat"
1010

11-
call test_qp(outpath)
11+
call test_rqp(outpath)
12+
call test_cqp(outpath)
1213

1314
contains
1415

@@ -25,7 +26,7 @@ function get_outpath() result(outpath)
2526
endif
2627
end function get_outpath
2728

28-
subroutine test_qp(outpath)
29+
subroutine test_rqp(outpath)
2930
character(*), intent(in) :: outpath
3031
real(qp) :: d(3, 2), e(2, 3)
3132
real(qp), allocatable :: d2(:, :)
@@ -40,6 +41,23 @@ subroutine test_qp(outpath)
4041
call loadtxt(outpath, d2)
4142
call assert(all(shape(d2) == [2, 3]))
4243
call assert(all(abs(e-d2) < epsilon(1._qp)))
43-
end subroutine
44+
end subroutine test_rqp
4445

45-
end program
46+
subroutine test_cqp(outpath)
47+
character(*), intent(in) :: outpath
48+
complex(qp) :: d(3, 2), e(2, 3)
49+
complex(qp), allocatable :: d2(:, :)
50+
d = reshape([1, 2, 3, 4, 5, 6], [3, 2])
51+
call savetxt(outpath, d)
52+
call loadtxt(outpath, d2)
53+
call assert(all(shape(d2) == [3, 2]))
54+
call assert(all(abs(d-d2) < epsilon(1._qp)))
55+
56+
e = reshape([1, 2, 3, 4, 5, 6], [2, 3])
57+
call savetxt(outpath, e)
58+
call loadtxt(outpath, d2)
59+
call assert(all(shape(d2) == [2, 3]))
60+
call assert(all(abs(e-d2) < epsilon(1._qp)))
61+
end subroutine test_cqp
62+
63+
end program test_savetxt_qp

0 commit comments

Comments
 (0)
Please sign in to comment.