Grrr. I'm trying to read in a formatted file of integers such as:
1 1 1
10 10 10
100 100 100
(... three characters wide, one space between each column)
Fortran is giving me junk unless I format my read statement with
10 format(I3,A1,I3,A1,I3)
where I read the single space into a temporary variable declared as:
character(1) :: tmp
This is why I am in a bad mood with Fortran today. I put faith in it, and this is how it repays me. Plus, the fridge has frozen my tomatoes. I wonder if they are in league.
Monday, 22 June 2009
Friday, 19 June 2009
Compiling modules separately
When I have a module declared in mymodule.f90, I can compile it like so:
gfortran -m32 -c mymodule.f90
... I can also compile the main file this way:gfortran -m32 -c mainfile.f90
Finally I must link it, possibly also with the NAG library:gfortran -m32 mymodule.o mainfile.o /opt/NAG/fll3a21dfl/lib/libnag_nag.a -o mainfile
Thursday, 18 June 2009
Fortran array initialization
This webpage here is very helpful for fortran arrays.
I'd forgotten that you can initialize vectors like this:
I'd forgotten that you can initialize vectors like this:
x = (/(i,i=0,maxx-1)/)
Instead of:do i=1,maxx
x(i) = i-1
enddo
x(i) = i-1
enddo
Wednesday, 13 May 2009
gcc fails to find header files
Because I have clearly been neglecting the guts of my gcc installation too much recently (oh happy respite from commandline errors!), my computer decided to throw a wobbly about compiling a C program that included (amongst other friends) io.h, conio.h and dir.h.
A simple "hello world" program would compile when including stdio.h but not when I added io.h, screaming:
A simple "hello world" program would compile when including stdio.h but not when I added io.h, screaming:
error: io.h: No such file or directory
I thought gcc would search /usr/include/sys automatically, but it appears not. I have to tell it on the command line:gcc -o andorsif andorsif.c -I /usr/include/sys -L /usr/include/sys
After I cleared up that heap of doodoo then I still get errors from the program that look like:error: ‘MAXPATH’ was not declared in this scope
but replacing incidences of MAXPATH with FILENAME_MAX seems to clear up that one.
Wednesday, 10 December 2008
Addressing integer bits in Fortran
I want to find out about 8-bit integers (kind = 1) in gfortran.
Apparently they seem to be signed and stored as "two's complement". When you give the integer a value, you can view the bits like so:
integer(kind = 1) I
integer numbit(8) ! stores the bit values as 0 or 1's
I = 5
do j= 1,8
numbit(i) = ibits(I,j-1,1)
enddo
write(*,*) 'bits: ', numbit
...where here IBITS is extracting 1 bit from I at position j-1 and returning it as an integer with the bit value right-justified and the rest of the bits 0. So "1" at position j-1 is returned by ibits(I,j-1,1) as "00000001" which has integer value 1.
Alternatively, I could do this:
integer(kind = 1) I
integer numbit(8) ! stores the bit values as 0 or 1's
I = 5
do j= 1,8
numbit(i) = btest(I,j-1)
enddo
write(*,*) 'bits: ', numbit
...where BTEST returns .true. if the bit in position j-1 is "1", and .false. otherwise. This is implicitly converted to an integer by the gfortran compiler (but not without warnings at compile time), where .true. => 1 and .false. => 0.
Both of these return:
bits: 1 0 1 0 0 0 0 0
I guess the take-home message is that when you write out a bit-string, eg.
5 = [0101]
then the right-most bit is addressed as bit 0, and in general, bit number 1 is the second bit as you move left, etc.
So if you start with all bits set to zero, you can use IBSET to set certain bits to 1 and get whatever number you fancy...
I = 0 ! [00000000]
I = ibset(I,0) ! [00000001]
I = ibset(I,2) ! [00000101]
write(*,*) 'I = ', I
... and we get I = 5, as intended.
I guess this is a stupid post, but it wasn't obvious to me that the bit string would be numbered from the right starting at index 0. The default index for matrices in Fortran 95 starts at 1. Ho hum.
Apparently they seem to be signed and stored as "two's complement". When you give the integer a value, you can view the bits like so:
integer(kind = 1) I
integer numbit(8) ! stores the bit values as 0 or 1's
I = 5
do j= 1,8
numbit(i) = ibits(I,j-1,1)
enddo
write(*,*) 'bits: ', numbit
...where here IBITS is extracting 1 bit from I at position j-1 and returning it as an integer with the bit value right-justified and the rest of the bits 0. So "1" at position j-1 is returned by ibits(I,j-1,1) as "00000001" which has integer value 1.
Alternatively, I could do this:
integer(kind = 1) I
integer numbit(8) ! stores the bit values as 0 or 1's
I = 5
do j= 1,8
numbit(i) = btest(I,j-1)
enddo
write(*,*) 'bits: ', numbit
...where BTEST returns .true. if the bit in position j-1 is "1", and .false. otherwise. This is implicitly converted to an integer by the gfortran compiler (but not without warnings at compile time), where .true. => 1 and .false. => 0.
Both of these return:
bits: 1 0 1 0 0 0 0 0
I guess the take-home message is that when you write out a bit-string, eg.
5 = [0101]
then the right-most bit is addressed as bit 0, and in general, bit number 1 is the second bit as you move left, etc.
So if you start with all bits set to zero, you can use IBSET to set certain bits to 1 and get whatever number you fancy...
I = 0 ! [00000000]
I = ibset(I,0) ! [00000001]
I = ibset(I,2) ! [00000101]
write(*,*) 'I = ', I
... and we get I = 5, as intended.
I guess this is a stupid post, but it wasn't obvious to me that the bit string would be numbered from the right starting at index 0. The default index for matrices in Fortran 95 starts at 1. Ho hum.
Tuesday, 9 December 2008
Incompatible ranks?!
Here's a fun problem that I have encountered. It might be a bug, or it might not (I've run out of patience with google-ing it now I have my program working).
I have a two dimensional matrix. I sum it down one dimension and then find the position of the maximum entry.
subroutine ionfinder(subframe,x_dim,y_dim, irow, icol)
! define imputs, and function type itself
integer, intent(in) :: x_dim, y_dim
integer, intent(in) :: subframe(x_dim,y_dim)
integer, intent(out) :: irow, icol(4) !ion positions
! the code follows...*********************
irow = maxloc(sum(subframe,1))
write(*,*) 'ions in row (y): ', irow
end subroutine ionfinder
...but this causes my compiler (gfortran) to shriek:
irow = maxloc(sum(subframe,1))
1
Error: Incompatible ranks 0 and 1 in assignment at (1)
Huuuurrrmmm. Seems a bit silly, but the following kludge fixes things:
subroutine ionfinder(subframe,x_dim,y_dim, irow, icol)
! define imputs, and function type itself
integer, intent(in) :: x_dim, y_dim
integer, intent(in) :: subframe(x_dim,y_dim)
integer, intent(out) :: irow, icol(4) !ion positions
! define other datum within function
integer tmp(1)
! the code follows...*********************
tmp = maxloc(sum(subframe,1))
irow = tmp(1)
write(*,*) 'ions in row (y): ', irow
end subroutine ionfinder
Well well well. I should probably investigate the cause further but I'm not going to because I have physics to do, not Fortran to fix.
I have a two dimensional matrix. I sum it down one dimension and then find the position of the maximum entry.
subroutine ionfinder(subframe,x_dim,y_dim, irow, icol)
! define imputs, and function type itself
integer, intent(in) :: x_dim, y_dim
integer, intent(in) :: subframe(x_dim,y_dim)
integer, intent(out) :: irow, icol(4) !ion positions
! the code follows...*********************
irow = maxloc(sum(subframe,1))
write(*,*) 'ions in row (y): ', irow
end subroutine ionfinder
...but this causes my compiler (gfortran) to shriek:
irow = maxloc(sum(subframe,1))
1
Error: Incompatible ranks 0 and 1 in assignment at (1)
Huuuurrrmmm. Seems a bit silly, but the following kludge fixes things:
subroutine ionfinder(subframe,x_dim,y_dim, irow, icol)
! define imputs, and function type itself
integer, intent(in) :: x_dim, y_dim
integer, intent(in) :: subframe(x_dim,y_dim)
integer, intent(out) :: irow, icol(4) !ion positions
! define other datum within function
integer tmp(1)
! the code follows...*********************
tmp = maxloc(sum(subframe,1))
irow = tmp(1)
write(*,*) 'ions in row (y): ', irow
end subroutine ionfinder
Well well well. I should probably investigate the cause further but I'm not going to because I have physics to do, not Fortran to fix.
Tuesday, 16 September 2008
Formatted Read Statements
This is not a very exciting problem or solution, but I shall post it anyway.
I was trying to read formatted data from a file like this:
0 9.99929445e-01
1 6.46409406e-05
2 3.80249651e-06
3 1.03999904e-06
4 4.24499610e-07
5 2.23999794e-07
I first tried the following:
integer :: myint(5)
real(kind = 10) :: myreal(5)
open(unit=2,file=filepath,status='OLD',action='READ')
do i = 1,5
read(2,20) myint(i),myreal(i)
end do
close(2)
20 format(I6,E15.8E3)
The I6 refers to the field width of the integer column. But alas, the output was this:
0 0.99992944E+001
1 0.64640941E+001
2 0.38024965E+001
3 0.10399990E+001
4 0.42449961E+001
5 0.22399979E+001
Oddly enough, everything was in order except that it would round powers from e-01 to e-09 up to E+001, and e-10 to e-19 became E+000 etc. Most odd. The solution was to change the format statement to skip the 2 blank spaces between the columns, which I had forgotten to do:
20 format(I6,2X,E15.8E3)
Simple really, but I don't know why it gives such a strange behaviour.
I was trying to read formatted data from a file like this:
0 9.99929445e-01
1 6.46409406e-05
2 3.80249651e-06
3 1.03999904e-06
4 4.24499610e-07
5 2.23999794e-07
I first tried the following:
integer :: myint(5)
real(kind = 10) :: myreal(5)
open(unit=2,file=filepath,status='OLD',action='READ')
do i = 1,5
read(2,20) myint(i),myreal(i)
end do
close(2)
20 format(I6,E15.8E3)
The I6 refers to the field width of the integer column. But alas, the output was this:
0 0.99992944E+001
1 0.64640941E+001
2 0.38024965E+001
3 0.10399990E+001
4 0.42449961E+001
5 0.22399979E+001
Oddly enough, everything was in order except that it would round powers from e-01 to e-09 up to E+001, and e-10 to e-19 became E+000 etc. Most odd. The solution was to change the format statement to skip the 2 blank spaces between the columns, which I had forgotten to do:
20 format(I6,2X,E15.8E3)
Simple really, but I don't know why it gives such a strange behaviour.
Subscribe to:
Posts (Atom)
