【发布时间】:2014-11-22 22:04:07
【问题描述】:
我正在尝试编写一个用于最小化的通用子例程。因为我想要一个通用的子程序,所以目标函数可以有不同的参数,不仅在名称上,而且在维度上。所以我需要一种方法来传递参数结构(我使用结构这个词,因为我的想法是在 Matlab 中使用类似结构类型变量的东西)。 我设法使用了派生数据类型,它工作得很好,但是当我在同一个程序中有两个不同的目标函数时,问题就出现了。这是一个示例代码:
在主程序main.f90中:
MODULE MYPAR
IMPLICIT NONE
TYPE PARPASS1 !! Parameter passing structure 1
INTEGER :: a
REAL :: X(2,2)
END TYPE PARPASS1
TYPE PARPASS2 !! Parameter passing structure 2
REAL :: b
REAL :: Y(3)
END TYPE PARPASS2
END MODULE MYPAR
PROGRAM MAIN
USE MYPAR
USE MYLIB
IMPLICIT NONE
INTEGER :: am
REAL :: bm,Xm(2,2),Ym(3),sol1,sol2
TYPE(PARPASS1) :: PARAM1
TYPE(PARPASS2) :: PARAM2
am = 1
bm = 3.5
Xm(1,:) = [1.0, 2.0]
Xm(2,:) = [0.5, 2.5]
Ym(1:3) = [0.25,0.50,0.75]
PARAM1%a = am
PARAM1%X = Xm
PARAM2%b = bm
PARAM2%Y = Ym
CALL MYSUB(sol1,OBJ1,PARAM1)
CALL MYSUB(sol2,OBJ2,PARAM2)
PRINT *,sol1
PRINT *,sol2
CONTAINS
SUBROUTINE OBJ1(sumval,PARAM)
REAL,INTENT(OUT) :: sumval
TYPE(PARPASS1),INTENT(IN) :: PARAM
INTEGER :: a
REAL,ALLOCATABLE :: X(:,:)
a = PARAM%a
X = PARAM%X
sumval = a+X(1,1)+X(2,2)
END SUBROUTINE OBJ1
SUBROUTINE OBJ2(divval,PARAM)
REAL,INTENT(OUT) :: divval
TYPE(PARPASS2),INTENT(IN) :: PARAM
REAL :: b
REAL,ALLOCATABLE :: Y(:)
b = PARAM%b
Y = PARAM%Y
divval = b / (Y(1)+Y(2))
END SUBROUTINE OBJ2
END PROGRAM MAIN
还有一个名为 mylib.90 的模块
MODULE MYLIB
USE MYPAR
IMPLICIT NONE
CONTAINS
SUBROUTINE MYSUB(sol,FN,PARAM)
REAL,INTENT(OUT) :: sol
TYPE(PARPASS1), INTENT(IN) :: PARAM
CALL FN(sol,PARAM)
sol = 2*sol
END SUBROUTINE MYSUB
END MODULE MYLIB
显然,如果我用CALL MYSUB(sol2,OBJ2,PARAM2) 和PRINT *,sol2 注释这些行,我的代码运行顺利。这是我在拥有两个“目标函数”之前拥有的,但现在当我拥有它们时它不起作用,因为 MYSUB 中的派生类型变量 PARPASS1 不能是任意的。
有什么想法吗?
【问题讨论】: