Error: ‘fmedian’ at (1) is not a variable - fortran

I want to see how this function works.I have tried to write small f77 code
program pic
implicit none
integer c,a
integer b(5)
external fmedian
c=5
b=(/9,2,7,1,6/)
fmedian(a,b,c)
end
real function fmedian(xmed,x,n)
double precision sum
integer i,n,xmed
dimension x(n)
sum=0.d0
do 10 i=1,n
sum=sum+(x(i)-xmed)/abs(x(i)-xmed)
10 continue
fmedian=sum
return
end
What should I change in my pic code
When I try to compile Alexander`s code I got
print *, fmedian(a,b,c)
1
Warning: Type mismatch in argument ‘x’ at (1); passed INTEGER(4) to REAL(4)

fmedian is a function, i.e. it returns something. However, you do not assign the return value anywhere.
You could, e.g., print the result of fmedian to the screen:
print *, fmedian(a,b,c)
Additionally, you need to declare the return value of fmedian
real fmedian
Your program would then look like:
program pic
implicit none
integer c,a
integer b(5)
real fmedian
external fmedian
c=5
b=(/9,2,7,1,6/)
print *, fmedian(a,b,c)
end
real function fmedian(xmed,x,n)
double precision sum
integer i,n,xmed
dimension x(n)
sum=0.d0
do 10 i=1,n
sum=sum+(x(i)-xmed)/abs(x(i)-xmed)
10 continue
fmedian=sum
return
end

Related

How to create functions in Fortran?

I'm sure the solution to this is extremely basic, but I'm having a hard time figuring out how to use functions in Fortran. I have the following simple program:
PROGRAM main
IMPLICIT NONE
INTEGER :: a,b
a = 3
b = 5
PRINT *,funct(a,b)
END PROGRAM
FUNCTION funct(a,b)
IMPLICIT NONE
INTEGER :: funct
INTEGER :: a,b
funct = a + b
END FUNCTION
I've tried several variations of this, including assigning a data type before FUNCTION, assigning the result of funct to another variable in the main program and printing that variable, and moving the FUNCTION block above the PROGRAM block. None of these worked. With the current program I get an error on line 6 (the line with the PRINT statement):
Error: Return type mismatch of function 'funct' (UNKNOWN/INTEGER(4))
Error: Function 'funct' has no IMPLICIT type
From all of the guides I've tried, I seem to be doing it right; at least one of the variations, or a combination of some of them, should have worked. How do I need to change this code to use the function?
Simply putting the function in the file will not make it accessible to the main program.
Traditionally, you could simply declare a function as external and the compiler would simply expect to find a suitable declaration at compile-time.
Modern Fortran organizes code and data in "modules". For your purpose, however, it is simpler to "contain" the function within the scope of the main program as follows:
PROGRAM main
IMPLICIT NONE
INTEGER :: a,b
a = 3
b = 5
PRINT *,funct(a,b)
CONTAINS
FUNCTION funct(a,b)
IMPLICIT NONE
INTEGER :: funct
INTEGER :: a,b
funct = a + b
END FUNCTION funct
END PROGRAM main
A simpler solution can be the following code
PROGRAM main
IMPLICIT NONE
INTEGER :: a,b, funct
a = 3
b = 5
PRINT *,funct(a,b)
END PROGRAM
FUNCTION funct(a,b)
IMPLICIT NONE
INTEGER :: funct
INTEGER :: a,b
funct = a + b
END FUNCTION
where the only difference is in the third line, where I have declared funct as an integer. It compiles and it prints 8 as result.

Invalid character in name `1t`

Here is my code:
!lab 4(a) solution by James Ney
program lab4_a
implicit none
integer :: n
real :: L,R
interface
function testFun (x)
real :: testFun
real, intent (in) :: x
end function testFun
end interface
print *, "lab 4(a) solution by James Ney"
print *, "Enter left and right ends of interval and number of subintervals"
read *, L,R,n
call MeshCalcs(testFun,L,R,n)
contains
subroutine MeshCalcs(F,a,b,n)
implicit none
integer, intent(in) :: n
real, intent(in) :: a,b
real :: del,fVal,xVal
integer :: 1t=0,gr=0,i
real ::F,sum=0,average
del=(b-a)/real(n)
do i=0,n
xVal=a+(i*del)
fVal=F(xVal)
sum=sum+fVal
end do
Average=sum/(n+1.0)
print "('Average is: ',f10.2)",average
do i=0,n
xVal=a+(i*del)
fVal=F(xVal)
if (fVal>average) then
gr=gr+1
else if(fVal<average) then
1t=1t+1
end if
end do
print "('number of function values greater than average =',i4)",gr
print "('number of function values less than average =',i4)",1t
end subroutine MeshCalcs
end Program Lab4_a
real function testFun(x)
real, intent (in) :: x
testFun=-(x-4.0)**2+9.0
end function testFun
and the errors I get when I try to compile with gfortran are:
lab4_2a.f90:27.20:
integer :: 1t=0,gr=0,i
1
Error: Invalid character in name at (1)
lab4_2a.f90:43.5:
1t=1t+1
1
Error: Non-numeric character in statement label at (1)
lab4_2a.f90:43.6:
1t=1t+1
1
Error: Invalid character in name at (1)
lab4_2a.f90:47.62:
print "('number of function values less than average =',i4)",1t
1
Error: Syntax error in PRINT statement at (1)
lab4_2a.f90:41.5:
gr=gr+1
1
Error: Symbol 'gr' at (1) has no IMPLICIT type
lab4_2a.f90:30.12:
do i=0,n
1
Error: Symbol 'i' at (1) has no IMPLICIT type
The first error message is quite clear (well, clear to those who already know this stuff). In this line
integer :: 1t=0,gr=0,i
the first variable declared has a name beginning with the digit 1. Fortran's rules require that all names begin with a letter or an underscore. I believe that this is common in other programming languages too. So the compiler barfs on 1t and the rest of the errors shown are probably direct consequences. Rename that variable and see what happens.

Fortran infinite loop when calling a function

Why am I in an infinite loop?
PROGRAM tayls
USE kertoma
USE tforexp
IMPLICIT NONE
INTEGER :: n= 5
INTEGER :: i
REAL :: x
WRITE(*,*) "f1(x)= (e**x-1)/x"
DO i=1,10
x= 0.01*i
WRITE(*,*)x, (taylexp(x,n)-1)/x
END DO
END PROGRAM tayls
with
MODULE tforexp
USE kertoma
IMPLICIT NONE
CONTAINS
FUNCTION taylexp(x,ord)
REAL :: taylexp, x, sum
INTEGER :: ord, i
sum= 1.0
DO i=1,ord
sum= sum+ x**i/fact(i)
END DO
taylexp= sum
END FUNCTION taylexp
END MODULE tforexp
and
MODULE kertoma
IMPLICIT NONE
CONTAINS
FUNCTION fact(n)
INTEGER :: fact,n,y=1
DO WHILE (n>1)
y= y*n
n= n-1
END DO
fact = y
END FUNCTION fact
END MODULE kertoma
The infinite loop starts right after the first print "f1(x)=...".
So I think it goes to infinite loop when calling the taylexp-function for the first time, but I don't understand why.
I think it has got something to do with fortran using public variables, but I'm clueless how to consistently avoid this.
First I tried to call the function without defining x, just using "0.01*i", and I thought maybe the problem was that this function used the same name for the dummy index, but it clearly it didn't solve the problem.
The problem is inside then function fact(n):
n= n-1
changes the argument and, therefore, the loop counter i in taylexp. In your code i never exceeds 2. I'm surprised the compiler didn't issue a warning (mine didn't either), because anything might happen in this case.
Better specify the intent of dummy arguments to avoid issues like this in the future:
FUNCTION fact(n)
integer,intent(in) :: n
INTEGER :: fact,nn,y
y=1 ! Avoid the implicit save and assign variables separately
nn=n
DO WHILE (nn>1)
y= y*nn
nn= nn-1
END DO
fact = y
END FUNCTION fact
With gfortran, it is possible to catch this error with
the -fcheck=all option:
$ gfortran -fcheck=all 1.f90
$ ./a.out
f1(x)= (e**x-1)/x
At line 22 of file 1.f90
Fortran runtime error: Loop variable has been modified

I can't find my error, in this Fortran code

when I use the INTEGER in declaration in this code, I have no error with gfortran, but when I use REAL in declaration, I have this error:
Error: Type mismatch in argument 'a' at (1); passed INTEGER(4) to REAL(4)
here is my code:
Program workout
IMPLICIT none
REAL :: resultat
resultat = moyen(100,50)
WRITE(*,*) resultat
CONTAINS
REAL FUNCTION moyen(a,b)
IMPLICIT none
REAL,INTENT(IN) :: a, b
moyen = (a - b)/2
END FUNCTION moyen
End Program workout
thanks for your time
The error message is quite explicit, you are passing an integer argument to a function which expects a real argument. You could change this line
resultat = moyen(100,50)
to
resultat = moyen(100.0,50.0)
In fact, as you can see, you are making the same mistake twice in one line, the compiler is just identifying the first occurrence.

Result of GAMMA underflows its kind

I would like to calculate gamma(-170.1) using the program below:
program arithmetic
! program to do a calculation
real(8) :: x
x = GAMMA(-170.1)
print *, x
end program
but I get the error:
test.f95:4.10:
x = GAMMA(-170.1)
1
Error: Result of GAMMA underflows its kind at (1)
when I compile with gfortran. According to Maple gamma(-170.1) = 5.191963205*10^(-172) which I think should be within the range of the exponent of the variable x as I've defined it.
The below modification of your program should work. Remember that in Fortran the RHS is evaluated before assigning to the LHS, and that floating point literals are of default kind, that is single precision. Thus, making the argument to GAMMA double precision the compiler chooses the double precision GAMMA.
program arithmetic
! program to do a calculation
integer, parameter :: dp = kind(1.0d0)
real(dp) :: x
x = GAMMA(-170.1_dp)
print *, x
end program
-170.0 may be treated as a float. If so, changing it to a double should resolve the issue.