(j3.2006) Why we should have kept macros
Van Snyder
Van.Snyder
Wed Aug 20 17:51:36 EDT 2008
Here's an example of why we should have kept macros.
Richard Maine remarked about ten years ago that integrating type
parameters and type bound procedures would be problematical. It is, at
least for kind type parameters.
I'd like to build a nonlinear solver using Fortran 2003 facilities. I'd
like to use deferred type-bound procedures for each of the
problem-specific things, such as evaluating the function and Jacobian,
factoring the Jacobian, solving for the Newton move, etc.
I'd like to use a type parameter to specify whether the real components
are default real or double precision real. I'd have two solvers, one
for default real and one for double precision real, probably created
from a single file using INCLUDE after some named constants got the
appropriate values.
I'd like to start with these abstract procedure definitions for the
procedures called by the solver when it needs access to user code
abstract interface
subroutine Action_D ( Argument )
class(nonlinear_Base_T(kind(0.0d0))), intent(inout) :: Argument
end subroutine Action
subroutine Action_S ( Argument )
class(nonlinear_Base_T(kind(0.0e0))), intent(inout) :: Argument
end subroutine Action
end interface
and with this abstract base type:
type, abstract :: Nonlinear_Base_T ( Kind )
integer, kind :: Kind
real(kind) :: Cos_DX_DXL ! Cosine of angle between consecutive
! Newton moves
real(kind) :: Cos_G_DX ! Cosine of angle between the Gradient
! and the Newton move
real(kind) :: Minimum_Norm ! Norm of F not in column space of J
real(kind) :: Residual_Norm ! Norm of F
contains
! Specific bindings for double precision
procedure(action_D), pass, deferred :: Evaluate_F_D
procedure(action_D), pass, deferred :: Evaluate_J_D
procedure(action_D), pass, deferred :: Solve_D
procedure(action_D), pass, deferred :: Do_Newton_Move_D
procedure(action_D), pass, deferred :: Do_Gradient_Move_D
! Specific bindings for single precision
procedure(action_S), pass, deferred :: Evaluate_F_S
procedure(action_S), pass, deferred :: Evaluate_J_S
procedure(action_S), pass, deferred :: Solve_S
procedure(action_S), pass, deferred :: Do_Newton_Move_S
procedure(action_S), pass, deferred :: Do_Gradient_Move_S
! Generic bindings
generic :: Evaluate_F => Evaluate_F_D, Evaluate_F_S ! and Residual_Norm
generic :: Evaluate_J => Evaluate_J_D, Evaluate_J_S ! and Minimum_Norm
generic :: Solve => Solve_D, Solve_S ! for Newton Move
generic :: Do_Newton_Move => Do_Newton_Move_D, Do_Newton_Move_S
generic :: Do_Gradient_Move => Do_Gradient_Move_D, Do_Gradient_Move_S
end type Nonlinear_Base_T
The problem is that when I tell the user "Extend the base type and
provide concrete bindings for the deferred procedures," he has to
provide bindings for both default real and double precision real
versions of all the bindings.
Either macros or generic modules would have solved this problem.
Instead, I'm inclined to ignore kind type parameters and provide two
base types, one with default real components, and one with double
precision real components. Instead of macros or generic modules, I'll
end up making imaginative use of INCLUDE.
--
Van Snyder | What fraction of Americans believe
Van.Snyder at jpl.nasa.gov | Wrestling is real and NASA is fake?
Any alleged opinions are my own and have not been approved or
disapproved by JPL, CalTech, NASA, the President, or anybody else.
More information about the J3
mailing list