Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Subroutine as an argument

Status
Not open for further replies.

swahelian

Technical User
Jun 22, 2010
5
NL
I am new to programming in fortran and am working with the numerical recipes subroutine mrqmin. It takes the following arguments:

mrqmin(x,y,sig,ndata,a,ia,ma,covar,alpha,nca,chisq,funcs,alamda)

The argument funcs is a subroutine wich I declare at the end of my program. Now, when I compile my program (with ifort) it says:

e6.f(57): error #6404: This name does not have a type, and must have an explicit type. [FUNCS]
&fgauss, alamda)
------^
compilation aborted for e6.f (code 1)

I think I am making a simple mistake or I am simply forgetting something.

What am I doing wrong?
 
Try to do what the compiler says: declare the type of the function, for example
Code:
real:: fgauss
 
fgauss is a subroutine in the numerical recipes library (which I link to when I compile the program).

Oke, I declared fgauss as real. It compiles, but when I run the program I get the following error:

forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
Unknown 00007FFF6B2F340C Unknown Unknown Unknown

Where did I go wrong?
 
Sorry, I misedited my original post, causing confusion. The error should have been:

e6.f(57): error #6404: This name does not have a type, and must have an explicit type. [FUNCS]
&funcs, alamda)
------^
compilation aborted for e6.f (code 1)

In other words: fgauss is funcs.
 
Hold on... I'm not sure I'm understanding the problem, but does FUNCS not need the "external" parameter in the declaration?

So, "external :: funcs"?

--------------------------------------
Background: Chemical engineer, familiar mostly with MATLAB, but now branching out into real programming.
 
swahelian said:
Sorry, but how do I declare a subroutine?
I found this link
and that says that funcs is a user suplied function
and I found the source here
where arguments of the subroutine mrqmin are declared
Code:
SUBROUTINE mrqmi(x,y,sig,ndata,a,ia,ma,covar,alpha,nca,chisq,funcs,alamda)  
INTEGER ma,nca,ndata,ia(ma),MMAX  
REAL alamda,chisq,[COLOR=red]funcs[/color],a(ma),alpha(nca,nca),covar(nca,nca),sig(ndata),x(ndata),y(ndata)
So you see that [COLOR=red yellow]funcs is a real function and not subroutine[/color].
 
NickFort:
I tried the external declaration. It compiles and runs but mrqmin fails to give results.

mikrom:
This is the exact text in the "Numerical Recipies" book:

SUBROUTINE mrqmin(x,y,sig,ndata,a,ia,ma,covar,alpha,nca,
* chisq,funcs,alamda)
INTEGER ma,nca,ndata,ia(ma),MMAX
REAL alamda,chisq,funcs,a(ma),alpha(nca,nca),covar(nca,nca),
* sig(ndata),x(ndata),y(ndata)
PARAMETER (MMAX=20) Set to largest number of t parameters.
C USES covsrt,gaussj,mrqcof
Levenberg-Marquardt method, attempting to reduce the value 2 of a t between a set of data points x(1:ndata), (1:ndata) with individual standard deviations sig(1:ndata), and a nonlinear function dependent on ma coefficients a(1:ma). The input array ia(1:ma) indicates by nonzero entries those components of a that should be tted for, and by zero
entries those components that should be held xed at their input values. The program returns current best- t values for the parameters a(1:ma), and 2 = chisq. The arrays
covar(1:nca,1:nca), alpha(1:nca,1:nca) with physical dimension nca (equal or bigger then the number of tted parameters) are used as working space during most iterations. Supply a subroutine funcs(x,a,yfit,dyda,ma) that evaluates the tting function yfit, and its derivatives dyda with respect to the tting parameters a at x. On the rst call provide an initial guess for the parameters a, and set alamda<0 for initialization (which then sets alamda=.001). If a step succeeds chisq becomes smaller and alamda decreases by a
factor of 10. If a step fails alamda grows by a factor of 10. You must call this routine repeatedly until convergence is achieved. Then, make one nal call with alamda=0, so
that covar(1:ma,1:ma) returns the covariance matrix, and alpha the curvature matrix. (Parameters held fixed will return zero covariances.)
 
How to do function declarations in F77
Code:
      subroutine subsub (x)
         real, intent(in):: x
         print *, "subsub called ", x
      end subroutine subsub

      integer function funcfunc (single)
         integer, intent(in):: single
         funcfunc = single + single
      end function funcfunc

      subroutine callsub (subname)
         external subname
         call subname (3.162)
      end subroutine callsub


      subroutine callfunc(funcname)
         integer funcname
         external funcname
         integer ires

         ires = funcname(30)
         print *, "funcname(30) returned ", ires
      end subroutine callfunc

      program funcs
         integer funcfunc
         external subsub, funcfunc
      
         call callsub (subsub)
         call callfunc (funcfunc)
         stop
      end
How to do it in F90
Code:
subroutine subsub (x)
   real, intent(in):: x
   print *, "subsub called ", x
end subroutine subsub

integer function funcfunc (single)
   integer, intent(in):: single
   funcfunc = single + single
end function funcfunc

subroutine callsub (subname)
   interface
      subroutine subname(rr)
         real, intent(in):: rr
      end subroutine subname
   end interface
   call subname (3.162)
end subroutine callsub


subroutine callfunc(funcname)
   interface
      integer function funcname(ii)
         integer, intent(in):: ii
      end function funcname
   end interface

   integer:: ires

   ires = funcname (20)
    print *, "funcname(20) returned ", ires
end subroutine callfunc

subroutine callfuncalt(funcname)
   integer, external:: funcname
   integer:: ires

   ires = funcname(30)
   print *, "funcname(30) returned ", ires
end subroutine callfuncalt

program funcs
   integer funcfunc
   external subsub, funcfunc

   call callsub (subsub)
   call callfunc (funcfunc)
   call callfuncalt (funcfunc) 

   stop
end
 
Indeed, funcs seems to be a subroutine, not a function.
In the Fortran 77 code of mrqmin found here
it is declared as a real function:
Code:
REAL funcs
But then it's used as an argument of the subroutine mrqcof, where it's declared as
Code:
EXTERNAL funcs
and called as a subroutine
Code:
call funcs(x(i),a,ymod,dyda,ma)
IMHO, it's bug in mrqmin, where funcs should be declared as in mrqcof.
It's possible that g77 compiles that (i didn't tried it), but for me it seems to be a bug.
Maybe xwb could say if it's bug or not...

I found the Fortran 90 version of mrqmin too:
and here funcs is declared as an subroutine
Code:
INTERFACE
   SUBROUTINE funcs(x,a,yfit,dyda)
   USE nrtype
   REAL(SP), DIMENSION(:), INTENT(IN) :: x,a
   REAL(SP), DIMENSION(:), INTENT(OUT) :: yfit
   REAL(SP), DIMENSION(:,:), INTENT(OUT) :: dyda
   END SUBROUTINE funcs
END INTERFACE

Now the question @swahelian: what version are you using? The fortran 77 or the Fortran 90 version.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top