Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fortran minimization of a function with additional arguments

Tags:

matlab

fortran

In fortran I have an external optimization routine that takes as an input the function f(x) and the starting point and returns the value for local minimum. For example if the function is called minimum:

minimum(f,x0,xopt)

The problem is that the function I need to minimize depends on some additional arguments that are not part of the minimization routine: f(x,data).

How can I overcome this issue. In matlab I would use anonymous function

g=@(x) f(x,data)

minimum(g, x0, xopt)

However as I understant in fortran 90 there are no anonymous function.

Thanks.

like image 631
CooT Avatar asked Oct 10 '14 10:10

CooT


2 Answers

You don't need anonymous functions for this. Your Matlab example is also not anonymous in the end, it has a name g.

Fortran internal functions are of great use here (Fortran 2008 feature, but supported in gfortran and ifort, not supported in Solaris Studio):

call minimum(g, x0, xopt)

contains

  real function g(x)
    real, intent(in) :: x
    g = f(x,data)
  end function

end
like image 122
Vladimir F Героям слава Avatar answered Nov 19 '22 18:11

Vladimir F Героям слава


You have the right idea from MATLAB in that you can create another function that returns f's value while encapsulating data. Two options come to mind.

If data is fixed at compile-time, you can wrap f in a module that uses it:

Module Foo
    type(blah) :: data = ...
    Contains
        Real Function f(x)
          ! data is visible here.
        End Function f
End Module Foo

If data is more dynamic through user-input or calculation, you can define a function that returns data and call it from within f:

Real Function f(x)
  ...
  Type(blah), Save :: data
  Logical, Save :: data_not_loaded = .True.
  If data_not_loaded Then
    data = load_data(...)
    data_not_loaded = .False.
  End If
  ...
End Function f

Instead of a load_data() function, you could also make a registry-like subroutine to first set the value of data earlier in the program and then retrieve data from within f. However, the logic in f won't change that much.

There might also be a method using procedure pointers, but I've never used that feature in Fortran, so I may be wrong.

like image 2
TroyHaskin Avatar answered Nov 19 '22 18:11

TroyHaskin