Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stdlib_io] disp(display your data) #445

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions doc/specs/stdlib_io.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,98 @@ program demo_savetxt
call savetxt('example.dat', x)
end program demo_savetxt
```

## `disp` - quickly display your data to the screen (or the default output location)
zoziha marked this conversation as resolved.
Show resolved Hide resolved

### Status

Experimental

### Description
Quickly display strings, scalars and low-dimensional arrays to the screen (or the default output location).
zoziha marked this conversation as resolved.
Show resolved Hide resolved

### Syntax

For 3D arrays:
`call [[stdlib_io(module):disp(interface)]](value, dim [, string])`
For null:
zoziha marked this conversation as resolved.
Show resolved Hide resolved
`call [[stdlib_io(module):disp(interface)]]()`
For others:
`call [[stdlib_io(module):disp(interface)]](value [, string])`
zoziha marked this conversation as resolved.
Show resolved Hide resolved

### Arguments

`value`: Shall be any type of scalar or (<= 3)D `array`.
zoziha marked this conversation as resolved.
Show resolved Hide resolved

`dim`: Shall be a scalar of type `integer` with a value: 1, 2 or 3.
zoziha marked this conversation as resolved.
Show resolved Hide resolved

`string`: Shall be a scalar of type `character` with any length(Usually used to mark data information).
zoziha marked this conversation as resolved.
Show resolved Hide resolved

### Output

The result is to print your data `value` and comments `string` on the screen (or the default output location).
zoziha marked this conversation as resolved.
Show resolved Hide resolved

### Example

```fortran
program demo_io_disp
use, non_intrinsic :: stdlib_io, only: disp
implicit none
real :: r(2, 3)
complex :: c(2, 3), c_3d(2, 3, 2)
integer :: i(2, 3)
logical :: l(2, 3)

r = 1.; c = 1.; c_3d = 2.; i = 1; l = .true.
r(1, 1) = (1.e-11, 1.0e-4)
c(2, 2) = 10.e5
c_3d(1,3,1) = (1000, 0.001)
call disp('string', 'disp(string):')
call disp('It is a note.')
call disp()

call disp(r, 'disp(r):')
call disp(c, 'disp(c):')
call disp(i, 'disp(i):')
call disp(l, 'disp(l):')

call disp(c_3d, 3, 'disp(c_3d, 3):')
call disp(c_3d, 2, 'disp(c_3d, 2):')
zoziha marked this conversation as resolved.
Show resolved Hide resolved
end program demo_io_disp
```
**Result:**
```fortran
disp(string):
string
It is a note.

disp(r):
0.1000E-10 1.000 1.000
1.000 1.000 1.000
disp(c):
(1.000,0.000) (1.000,0.000) (1.000,0.000)
(1.000,0.000) (0.1000E+07,0.000) (1.000,0.000)
disp(i):
1 1 1
1 1 1
disp(l):
T T T
T T T
disp(c_3d, 3):
Slice (:,:,1):
(2.000,0.000) (2.000,0.000) (1000.,0.1000E-02)
(2.000,0.000) (2.000,0.000) (2.000,0.000)
Slice (:,:,2):
(2.000,0.000) (2.000,0.000) (2.000,0.000)
(2.000,0.000) (2.000,0.000) (2.000,0.000)
disp(c_3d, 2):
Slice (:,1,:):
(2.000,0.000) (2.000,0.000)
(2.000,0.000) (2.000,0.000)
Slice (:,2,:):
(2.000,0.000) (2.000,0.000)
(2.000,0.000) (2.000,0.000)
Slice (:,3,:):
(1000.,0.1000E-02) (2.000,0.000)
(2.000,0.000) (2.000,0.000)
```
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ set(fppFiles
stdlib_bitsets_64.fypp
stdlib_bitsets_large.fypp
stdlib_io.fypp
stdlib_io_disp.fypp
stdlib_linalg.fypp
stdlib_linalg_diag.fypp
stdlib_optval.fypp
Expand Down
9 changes: 7 additions & 2 deletions src/Makefile.manual
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ SRCFYPP =\
stdlib_stats_distribution_PRNG.fypp \
stdlib_string_type.fypp \
stdlib_strings.fypp \
stdlib_strings_format_string.fypp
stdlib_strings_format_string.fypp \
stdlib_io_disp.fypp

SRC = f18estop.f90 \
stdlib_error.f90 \
Expand Down Expand Up @@ -69,7 +70,8 @@ stdlib_error.o: stdlib_optval.o
stdlib_io.o: \
stdlib_error.o \
stdlib_optval.o \
stdlib_kinds.o
stdlib_kinds.o \
stdlib_ascii.o
zoziha marked this conversation as resolved.
Show resolved Hide resolved
stdlib_linalg.o: \
stdlib_kinds.o
stdlib_linalg_diag.o: \
Expand Down Expand Up @@ -134,3 +136,6 @@ stdlib_strings.o: stdlib_ascii.o \
stdlib_kinds.o
stdlib_math.o: stdlib_kinds.o
stdlib_strings_format_string.o: stdlib_strings.o
stdlib_io_disp.o: stdlib_error.o \
stdlib_strings.o \
stdlib_io.o
31 changes: 29 additions & 2 deletions src/stdlib_io.fypp
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,45 @@ module stdlib_io
!! ([Specification](../page/specs/stdlib_io.html))

use stdlib_kinds, only: sp, dp, qp, &
int8, int16, int32, int64
int8, int16, int32, int64, lk, c_bool
use stdlib_error, only: error_stop
use stdlib_optval, only: optval
use stdlib_ascii, only: is_blank
implicit none
private
! Public API
public :: loadtxt, savetxt, open
public :: loadtxt, savetxt, open, disp

! Private API that is exposed so that we can test it in tests
public :: parse_mode

interface disp
!!
zoziha marked this conversation as resolved.
Show resolved Hide resolved
#:set DISP_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES &
& + CMPLX_KINDS_TYPES + LOG_KINDS_TYPES
#:set DISP_RANKS = range(0, 4)
#:for kind, type in DISP_KINDS_TYPES
#:for rank in DISP_RANKS
#:if rank != 3
zoziha marked this conversation as resolved.
Show resolved Hide resolved
impure module subroutine disp_${rank}$_${type[0]}$${kind}$(val, string)
${type}$, intent(in) :: val${ranksuffix(rank)}$
character(len=*), intent(in), optional :: string
end subroutine disp_${rank}$_${type[0]}$${kind}$
#:else
impure module subroutine disp_${rank}$_${type[0]}$${kind}$(val, dim, string)
${type}$, intent(in) :: val${ranksuffix(rank)}$
integer, intent(in) :: dim
character(len=*), intent(in), optional :: string
end subroutine disp_${rank}$_${type[0]}$${kind}$
#:endif
#:endfor
#:endfor
impure module subroutine disp_str(val, string)
zoziha marked this conversation as resolved.
Show resolved Hide resolved
character(len=*), intent(in), optional :: val
character(len=*), intent(in), optional :: string
end subroutine disp_str
end interface disp

interface loadtxt
!! version: experimental
!!
Expand Down
125 changes: 125 additions & 0 deletions src/stdlib_io_disp.fypp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#:include "common.fypp"
#:set RIL_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + LOG_KINDS_TYPES

submodule (stdlib_io) stdlib_io_disp

use, non_intrinsic :: stdlib_strings, only: format_string
zoziha marked this conversation as resolved.
Show resolved Hide resolved
implicit none
character(len=*), parameter :: fmt_r = '(*(g11.4, 1x))'
character(len=*), parameter :: fmt_c = '(*(g23.4, 1x))'

contains

#:for kind, type in RIL_KINDS_TYPES
module procedure disp_0_${type[0]}$${kind}$
if(present(string)) print *, trim(string)
zoziha marked this conversation as resolved.
Show resolved Hide resolved
print fmt_r, val
zoziha marked this conversation as resolved.
Show resolved Hide resolved
end procedure disp_0_${type[0]}$${kind}$

module procedure disp_1_${type[0]}$${kind}$
integer :: i, m
m = size(val)
if(present(string)) print *, trim(string)
print fmt_r, (val(i), i=1,m)
end procedure disp_1_${type[0]}$${kind}$

module procedure disp_2_${type[0]}$${kind}$
integer :: i, j, m, n
m = size(val, 1)
n = size(val, 2)
if(present(string)) print *, trim(string)
do i = 1, m
print fmt_r, (val(i,j), j=1, n)
zoziha marked this conversation as resolved.
Show resolved Hide resolved
end do
end procedure disp_2_${type[0]}$${kind}$

module procedure disp_3_${type[0]}$${kind}$
integer :: i, dim1, dim2, dim3
dim1 = size(val, 1)
dim2 = size(val, 2)
dim3 = size(val, 3)
if(present(string)) print *, trim(string)
if(dim == 1) then
zoziha marked this conversation as resolved.
Show resolved Hide resolved
do i = 1, dim1
print *, 'Slice ('//format_string(i)//',:,:):'
zoziha marked this conversation as resolved.
Show resolved Hide resolved
call disp_2_${type[0]}$${kind}$(val(i, :, :))
end do
elseif(dim == 2) then
do i = 1, dim2
print *, 'Slice (:,'//format_string(i)//',:):'
call disp_2_${type[0]}$${kind}$(val(:, i, :))
end do
elseif (dim == 3) then
do i = 1, dim3
print *, 'Slice (:,:,'//format_string(i)//'):'
call disp_2_${type[0]}$${kind}$(val(:, :, i))
end do
else
call error_stop('Error(disp): wrong dimension')
end if
end procedure disp_3_${type[0]}$${kind}$
#:endfor

#:for kind, type in CMPLX_KINDS_TYPES
module procedure disp_0_${type[0]}$${kind}$
if(present(string)) print *, trim(string)
print fmt_c, format_string(cmplx(real(val), &
zoziha marked this conversation as resolved.
Show resolved Hide resolved
aimag(val)), '(g11,4)')
zoziha marked this conversation as resolved.
Show resolved Hide resolved
end procedure disp_0_${type[0]}$${kind}$

module procedure disp_1_${type[0]}$${kind}$
integer :: i, m
m = size(val)
if(present(string)) print *, trim(string)
print fmt_c, (format_string(cmplx(real(val(i)), &
aimag(val(i))), '(g11.4)'), i=1, m)
end procedure disp_1_${type[0]}$${kind}$

module procedure disp_2_${type[0]}$${kind}$
integer :: i, j, m, n
m = size(val, 1)
n = size(val, 2)
if(present(string)) print *, trim(string)
do i = 1, m
print fmt_c, (format_string(cmplx(real(val(i, j)), &
aimag(val(i, j))), '(g11.4)'), j=1, n)
end do
end procedure disp_2_${type[0]}$${kind}$

module procedure disp_3_${type[0]}$${kind}$
integer :: i, dim1, dim2, dim3
dim1 = size(val, 1)
dim2 = size(val, 2)
dim3 = size(val, 3)
if(present(string)) print *, trim(string)
if(dim == 1) then
do i = 1, dim1
print *, 'Slice ('//format_string(i)//',:,:):'
call disp_2_${type[0]}$${kind}$(val(i, :, :))
end do
elseif(dim == 2) then
do i = 1, dim2
print *, 'Slice (:,'//format_string(i)//',:):'
call disp_2_${type[0]}$${kind}$(val(:, i, :))
end do
elseif (dim == 3) then
do i = 1, dim3
print *, 'Slice (:,:,'//format_string(i)//'):'
call disp_2_${type[0]}$${kind}$(val(:, :, i))
end do
else
call error_stop('Error(disp): wrong dimension')
end if
end procedure disp_3_${type[0]}$${kind}$
#:endfor

module procedure disp_str
if(present(string)) print *, trim(string)
if(present(val)) then
print *, trim(val)
else
print *, ''
end if
end procedure disp_str

end submodule stdlib_io_disp
1 change: 1 addition & 0 deletions src/tests/io/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ set_tests_properties(savetxt_qp PROPERTIES LABELS quadruple_precision)

ADDTEST(open)
ADDTEST(parse_mode)
ADDTEST(io_disp)
3 changes: 2 additions & 1 deletion src/tests/io/Makefile.manual
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ PROGS_SRC = test_loadtxt.f90 \
test_loadtxt_qp.f90 \
test_savetxt_qp.f90 \
test_parse_mode.f90 \
test_open.f90
test_open.f90 \
test_io_disp.f90

CLEAN_FILES = tmp.dat tmp_qp.dat io_open.dat io_open.stream

Expand Down
24 changes: 24 additions & 0 deletions src/tests/io/test_io_disp.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
program test_io_disp
zoziha marked this conversation as resolved.
Show resolved Hide resolved
use, non_intrinsic :: stdlib_io, only: disp
implicit none
real :: r(2, 3)
complex :: c(2, 3), c_3d(2, 3, 2)
integer :: i(2, 3)
logical :: l(2, 3)

r = 1.; c = 1.; c_3d = 2.; i = 1; l = .true.
r(1, 1) = (1.e-11, 1.0e-4)
c(2, 2) = 10.e5
c_3d(1,3,1) = (1000, 0.001)
call disp('string', 'disp(string):')
call disp('It is a note.')
call disp()

call disp(r, 'disp(r):')
call disp(c, 'disp(c):')
call disp(i, 'disp(i):')
call disp(l, 'disp(l):')

call disp(c_3d, 3, 'disp(c_3d, 3):')
call disp(c_3d, 2, 'disp(c_3d, 2):')
end program test_io_disp