tpb wrote: |
---|
The writes are somewhat obscure. I can't quite figure them out. |
Each write is of the form
write( where_to, what_format ) output_list |
where_to can be a file number, character variable, or * (meaning standard out; e.g. console)
The first write
write( fmt, "( '( ', i0, '( g10.3, 1x ) )' )" ) ncol |
is just to create the format for the second. It writes the necessary bits into the character variable
fmt - a bit like a stringstream in c++, I guess - and the only edit descriptor is the i0, which will absorb the value of ncol. If ncol is 4 then I'm trying to get "( 4( g10.3, 1x ) )" in
fmt, but that 4 depends on the number of items in a row, so I have to create this string on the fly. The edit descriptor i0 means "integer in whatever width is needed"; g10.3 means a generalised floating or fixed point real with width 10 and 3 sig figs; 1x means one space.
The second write
write( *, fmt ) ( A(i,:), i = 1, nrow ) |
uses the format inside variable
fmt to write out the array A. Then A(i,:) is an "array section", meaning the i
th row, or A(i,1),A(i,2) ... A(i,ncol) here. Then there's an outer "implied do loop" over i. (I originally had nested implied do loops, but I edited it to use the shorter form with an array section). If written as a single write statement like this it will use the format repeatedly, with a line feed between each use, until all elements are output. The format was set up in the first write statement to give exactly the right number of elements in a row.
For the record, the input file that I was using, matrix.txt, looked like this:
3
4
1 2 3 4
5 6 7 8
9 10 11 12 |
It's a list-directed single read statement, so it doesn't matter whether the initial 3 and 4 are on the same line or successive lines.
If you wanted a more general matrix-writing routine, you could do something like the following. Note that the module MyMod could be extended to contain any other fancy array routines. However, fortran has so many built into the standard that there wouldn't be many here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
module MyMod
implicit none
contains
subroutine printMatrix( A, basefmt )
real, intent( in ) :: A(:,:)
character (len=*) basefmt
integer i, nrow, ncol
character (len=30) fmt
nrow = ubound( A, 1 )
ncol = ubound( A, 2 )
write( fmt, "( '( ', i0, '( ', a, ', 1x ) )' )" ) ncol, basefmt
write( *, fmt ) ( A(i,:), i = 1, nrow )
end subroutine printMatrix
end module MyMod
program demo
use MyMod
implicit none
real, allocatable :: A(:,:)
integer nrow, ncol
open( 10, file = "matrix.txt" )
read( 10, * ) nrow, ncol
allocate( A(ncol,nrow) )
read( 10, * ) A
A = transpose( A ) ! column-major -> row-major
call printMatrix( A, "g10.3" )
end program demo
|