I have a text file with the following format (11 columns and 8 rows)
Name Chris Kyle Peter Luke Sally (...)
age xxxx xxxx xxxx xxxx xxxx
height xxxx xxxx xxxx xxxx
weight xxxx xxxx xxxx xxxx
class xxxx xxxx xxxx xxxx
The first column (chris) only has data in the first row.
I need to build a program to read this table, this is what I have so far but I can't get it to work...
program readtable
implicit none
integer :: i, j, num_col, num_row
double precision, dimension (2) :: a
character(14), dimension (1) :: variable
num_col = 11
num_row = 8
open(100,file='SSL.dat',status='old')
do j=1, num_row
read(100,*) variable(j), (a(i,j), i=1,num_col)
print*, variable(j), a(i,j)
end do
end program
When I run this piece of code I get a rank mismatch.
I want to read the data in this table so that I can then assign the data to specific variables. For instance, If I want to do some stuff with kyle and Peter I know that for Kyle a(:,2) and for Peter a(:,3)
Here is the error I get when I compile with gfortran as a Fortran 90 code
read(100,*) variable(j), (a(i,j),i=1,num_col))
1
Error: Rank mismatch in array reference at (1) (2/1)
It looks like you assume that dimension(n) makes the array n-dimensional. That is not true! It make s the array one-dimensional and with shape from 1 to n, i.e., (1:n).
If you want to declare a two-dimensional array with 8 rows and 11 columns you have to do:
double precision, dimension(8,11) :: a
or equivalently
double precision :: a(8,11)
Similarly, variable must be something like:
character(14), dimension(8) :: variable
This will not make your program complete and functional, but will fix the immediate issue the compiler is complaining about. Please keep your questions narrow.
Related
I am coding a large Fortran program where performance is extremely crucial. I'm using module to store common parameters and variables. But the problem is where ever there's a module variable is used for some kind of array operation the compiler doesn't vectorize it. Lets take this as an example,
module name
integer :: p
end module name
program name1
use name
real(kind=8) :: x(10,10), y(10)
integer :: i,j
p=9
do i=1,10
do j =1,10
x(i,j) = i+j
enddo
enddo
y = x(:,p)*x(:,p-1)
print *, y
end program name1
Now when I compile it on Cray (XC50) with ftn -eD file.f90, the produced .lst file shows,
9. program name1
10. ! implicit none
11. use name
12. real(kind=8) :: x(10,10), y(10)
13. integer :: i,j
14. do i=1,10
15. do j =1,10
16. x(i,j) = i+j
17. enddo
18. enddo
19.
20. y = x(:,p)*x(:,p-1)
ftn-6263 ftn: VECTOR NAME1, File = test.f90, Line = 20
A loop starting at line 20 was not vectorized because it contains a reference to a non-vector intrinsic on line 20.
21. print *, y
22. end program name1
23.
24.
I always thought that doing array operation with : will be easier for the compiler to vectorize it. But if using module variable is bad for vectorization then is it also bad to use module when performance is critical? Am I confusing something here? How to improve the performance for these cases?
Here is my simple program for 2 by 2 matrix
program matrix
INTEGER :: A(2,2)
integer::i,j
do i = 1,2
write(*,*) A(i,1),A(i,2)
end do
end program
and when I run and compile I get the output of
15866218 1869135244
11 -2
I want to know why this four no. came and how...I was expecting output like
A(1,2) A(1,2)
A(2,1) A(2,2)
But it has value instead. Any help?
You never initialized the values in your matrix. You have to tell the compiler to put some kind of value into the matrix, or you just get whatever number was in those memory addresses before your program ran.
I'm attempting to write a program that utilizes the sobel filter to detect edges in images. So first off, I've written down some of the requirements in some basic code, such as the x and y direction filters as arrays and also an attempt to read in a pgm image:
program edges
implicit none
integer, dimension(:,:), allocatable :: inp, outim, GX, GY
integer, parameter :: dp = selected_real_kind(15,300)
integer :: ky, kx, x, y, out_unit = 10, M, N, sx, sy, i, j
real(kind=dp) :: G
M = 5
N = 5
allocate(inp(M,N))
allocate(outim(M-2,N-2))
allocate(GX(3,3))
allocate(GY(3,3))
open(file = 'clown.pgm',unit=out_unit,status= 'unknown') !opening file to write to inp
read (out_unit,11) 'P2' !pgm magic number
read (out_unit,12) 50,50 !width, height
read (out_unit,13) 1 !max gray value
do M=-25,25
do N=-25,25
read (out_unit,*) inp(M,N)
end do
end do
11 format(a2)
12 format(i3,1x,i3)
13 format(i5)
This is my first time working with image manipulation in FORTRAN, apart from once when I printed an image out as a pbm file. The code for reading the image in is a replicate of what I used to print one out before, except I changed write to read.
So my question is, how can I read in an image that's in pgm format into the "inp" array, so that I can apply the sobel filter? When I run my attempt, I get the following errors:
read (out_unit,11) 'P2' !pgm magic number
1
Error: Expected variable in READ statement at (1)
sobel.f90:41:18:
read (out_unit,12) 50,50 !width, height
1
Error: Expected variable in READ statement at (1)
sobel.f90:42:18:
read (out_unit,13) 1 !max gray value
1
Error: Expected variable in READ statement at (1)
Thank you
The first mistake is, as the compiler states quite clearly, in this line:
read (out_unit,11) 'P2'
The compiler expects, because that's the way that Fortran is defined, to be told to read a value from out_unit into a variable, but 'P2' is a character literal (or whatever the heck the standard calls them), it's a string, it's not a variable.
The same mistake occurs in the next lines too. The compiler expects something like
integer :: p2 ! pgm magic number
...
read (out_unit,11) p2
etc. After execution of this version of the read statement the variable p2 holds the magic number read from the pgm file.
While I'm writing, calling the unit to be read from out_unit is just perverse and will, eventually, confuse you.
I imagine this is something silly I've missed but I've asked my whole class and noone can seem to work it out. Making a simple program calling in a subroutine and I'm having trouble with the do loop reading in the entries of the matrix.
program Householder_Program
use QR_Factorisation
use numeric_kinds
complex(dp), dimension(:,:), allocatable :: A, Q, R, V
integer :: i, j, n, m
print *, 'Enter how many rows in the matrix A'
read *, m
print *, 'Enter how many columns in the matrix A'
read *, n
allocate(A(m,n), Q(m,n), R(n,n), V(n,n))
do i = 1,m
do j = 1,n
Print *, 'Enter row', i, 'and column', j, 'of matrix A'
read *, A(i,j)
end do
end do
call Householder_Triangularization(A,V,R,n,m)
print *, R
end program
It will ask me for A(1,1) but when I type in a number it will not ask me for A(1,2), it will leave a blank line. When I try to put in a 2nd number it will error and say :
Enter row 1 and column 1 of matrix A
1
2
At line 22 of file HouseholderProgram.f90 (unit = 5, file = 'stdin')
Fortran runtime error: Bad repeat count in item 1 of list input
Your variable A is (an array) of type complex. This means that when you attempt to do the list-directed input of the element values you cannot just specify a single number. So, in your case the problem is not with the program but with the input.
From the Fortran 2008 standard, 10.10.3
When the next effective item is of type complex, the input form consists of a left parenthesis followed by an ordered pair of numeric input fields separated by a comma (if the decimal edit mode is POINT) or semicolon (if the decimal edit mode is COMMA), and followed by a right parenthesis.
Input, then, must be something like (1., 12.).
You are trying to read in complex numbers (A is complex)! As such, you should specify complex numbers to the code... Since you are providing just one integer, the program does not know what to do.
Providing (1,0) and (2,0) instead of 1 and 2 will do the trick.
In case the user input is always real, and you want to read it into a complex type array you can do something like this:
Print *, 'Enter row', i, 'and column', j, 'of matrix A'
read *, dummy
A(i,j)=dummy
where dummy is declared real. This will save the user from the need to key in the parenthesis required for complex numbers. ( The conversion to complex is automatic )
I am writing a program in Fortran to find the velocity of a parachuting person in relation to time. I keep getting an error that I can't fix. I am very new to programming and any help is greatly appreciated.
The error is
v(i+1)=v(i)+[32-((c*v(i)*v(i))/m)]*(h)
1
Error: Incompatible ranks 0 and 1 in assignment at (1)
and my program is
PROGRAM para
INTEGER :: i
REAL :: v(11) !velocity
REAL :: q !initial velocity
REAL :: h !time step
REAL :: c !drag coefficient
REAL :: m !mass
! gravity is equal to 32 ft/s^2
WRITE (*,*)'enter time step'
READ(*,*)h
Write(*,*)'enter initial velocity'
READ(*,*)q
WRITE(*,*)'enter drag coefficient'
READ(*,*)c
WRITE(*,*)'enter mass'
READ(*,*)m
DO i=1,10 ! from 1 to 10, with 1 being the interval.
END DO
v(i+1)=v(i)+[32-((c*v(i)*v(i))/m)]*(h)
q=v(1)
END PROGRAM
You cannot use [] as a normal parenthesis in expressions. It is an array constructor, [ items ] means an array with items as elements. Also the end do should be after this line.
Well, you span up a vector using [ ... ] (this is equivalent to (/ ... /)). So, using regular brackets instead of the square ones solves your problem.
BTW: I'm a little confused about your loop... Shouldn't the v(i+1) = ... line be inside the loop?