使用MKL求解非线性方程组,其目标函数存储在另一个模块中

时间:2017-04-05 16:30:47

标签: fortran intel-fortran intel-mkl nonlinear-optimization

我正在尝试使用MKL信任域算法来解决Fortran程序中的非线性方程组。我从在线提供的示例(ex_nlsqp_f90_x.f90 https://software.intel.com/en-us/node/501498)开始,一切正常。现在,因为我必须在一个更大的程序中使用它,我需要从一个单独的模块加载用户定义的目标函数。因此,我将示例拆分为2个单独的文件,但我无法使其正确编译。

所以这里是模块的代码,它包含用户定义的数据结构和目标函数

module modFun
implicit none
private
public my_data, extended_powell

type :: my_data
      integer a
      integer sum
end type my_data


contains

subroutine extended_powell (m, n, x, f, user_data)
    implicit none
    integer, intent(in) :: m, n
    real*8 , intent(in) :: x(n)
    real*8, intent(out) :: f(m)
    type(my_data) :: user_data
    integer i

    user_data%sum = user_data%sum + user_data%a
    do i = 1, n/4
        f(4*(i-1)+1) = x(4*(i-1)+1) + 10.0 * x(4*(i-1)+2)
        f(4*(i-1)+2) = 2.2360679774998 * (x(4*(i-1)+3) - x(4*(i-1)+4))
        f(4*(i-1)+3) = ( x(4*(i-1)+2) - 2.0 * x(4*(i-1)+3) )**2
        f(4*(i-1)+4) = 3.1622776601684 * (x(4*(i-1)+1) - x(4*(i-1)+4))**2
    end do
end subroutine extended_powell

end module modFun

这里是调用它的主程序部分

    include 'mkl_rci.f90'
program EXAMPLE_EX_NLSQP_F90_X
    use MKL_RCI
    use MKL_RCI_type
    use modFun

!   user's objective function
!   n - number of function variables
!   m - dimension of function value
    integer n, m
    parameter (n = 4)
    parameter (m = 4)
!   precisions for stop-criteria (see manual for more details)
    real*8 eps(6)
    real*8 x(n)
    real*8 fjac(m*n)
!   number of iterations
    integer fun

!   Additional users data
    type(my_data) :: m_data

    m_data%a = 1
    m_data%sum = 0
    rs = 0.0


   fun =  djacobix(extended_powell,n,m,fjac,x,eps(1),%val(loc(m_data)))

end program EXAMPLE_EX_NLSQP_F90_X

还有djacobix代码

  INTERFACE
    INTEGER FUNCTION DJACOBIX(fcn, n, m, fjac, x, eps, user_data)
    USE, INTRINSIC :: ISO_C_BINDING
    INTEGER, INTENT(IN)   :: n
    INTEGER, INTENT(IN)   :: m
    DOUBLE PRECISION, INTENT(IN)      :: eps
    DOUBLE PRECISION, INTENT(IN), DIMENSION(*)     :: x
    DOUBLE PRECISION, INTENT(OUT), DIMENSION(m, *) :: fjac
    INTEGER(C_INTPTR_T)   :: user_data
    INTERFACE
        SUBROUTINE fcn(m, n, x, f, user_data)
            USE, INTRINSIC :: ISO_C_BINDING
            INTEGER, INTENT(IN) :: n
            INTEGER, INTENT(IN) :: m
            DOUBLE PRECISION, INTENT(IN), DIMENSION(*) :: x
            DOUBLE PRECISION, INTENT(OUT), DIMENSION(*) :: f
            INTEGER(C_INTPTR_T), INTENT(IN) :: user_data
        END SUBROUTINE
    END INTERFACE
    END FUNCTION
  END INTERFACE

编译时会产生以下错误:

mpiifort  -g -t -mkl  -I/apps/rhel6/intel/composer_xe_2015.3.187/mkl/include/intel64/lp64 -c modFun.f90
mpiifort  -g -t -mkl  -I/apps/rhel6/intel/composer_xe_2015.3.187/mkl/include/intel64/lp64 -c main.f90
main.f90(30): error #7065: The characteristics of dummy argument 5 of the associated actual procedure differ from the characteristics of dummy argument 5 of the dummy procedure.   [EXTENDED_POWELL]
   fun =  djacobix(extended_powell,n,m,fjac,x,eps(1),%val(loc(m_data)))
-------------------^

我觉得我必须创建一个界面来覆盖对m_data的检查,但我无法弄清楚在哪里以及如何。任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:-1)

我猜原因是函数djacobix 传递的是指针而不是变量user_data的真实值。 您可以查看 https://software.intel.com/content/www/us/en/develop/documentation/onemkl-developer-reference-c/top/nonlinear-optimization-problem-solvers/jacobian-matrix-calculation-routines/jacobix.html 处的手册,其中有一句话显示“您需要在调用程序中将 fcn 声明为 extern。