Audito is an automatic differentiation tool for fortran. The mathematical operators have been overloaded to work with the newly defined types, which include not only the function value, but also the gradient, Hessian and Laplacian. This repository contains 3 modules, FG_m, FGL_m, and FGH_m, where FG calculates the value and gradient; FGL the value, gradient, and Laplacian; and FGH the value, gradient, and Hessian. You can use which ever you want, they do not depend on each other!
Let's define
The FG_t or FGX_t types currently can only be defined for 64 bit reals! This will however be expanded in future releases.
Overloading the operators enables a very easy implementation of functions! The comlicated part is the initialization of the variables. Please consider the following example:
We have two atoms, each with
Let's define a function
Let's initialize the coordinates as an FG_t type. Each coordinate will have its function value x%f and its gradient x%g. Thus,
For each variable, its component in the gradient is set to 1 and the rest to zero. This is the result of the function
iniGrad = 0._r8 !Has size 6
do i = 1, SIZE(x)
iniGrad(i) = 1._r8
x(i) = FG_t(0._r8, iniGrad) !x has size 6 and represents the positons vector (type(FG_t) :: x(6))
iniGrad = 0._r8
end do
Now we can set each coordinate with
type(FG_t) :: f
f = SQRT((x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2)
f%print()
For the FG_t type, this print the function value and its gradient (for FGH_t and FGL_t it also prints the Hessian and Laplacian respectively)
value:
gradient:
If you want to use FGH_t or FGL_t you need to initialize the Hessian to all zeroes or the Laplacian to 0:
FGH_t:
iniGrad = 0._r8 !Has size 6
iniHess = 0._r8 !Has size 6x6
do i = 1, SIZE(x)
iniGrad(i) = 1._r8
x(i) = FGH_t(0._r8, iniGrad, iniHess) !x has size 6 and represents the positons vector (type(FGH_t) :: x(6))
iniGrad = 0._r8
end do
FGL_t:
iniGrad = 0._r8 !Has size 6
do i = 1, SIZE(x)
iniGrad(i) = 1._r8
x(i) = FGL_t(0._r8, iniGrad, 0._r8) !x has size 6 and represents the positons vector (type(FGL_t) :: x(6))
iniGrad = 0._r8
end do
There are examples for each type. They will be explained in the next section.
3 Examples are included, one for the FG module (value and gradient), one for the FGL module (value, gradient, and Laplacian), and one for the FGH module (value, gradient, and Hessian). The Example code is the optimization of Lennard-Jones clusters and it is commented. If you wish to use the modules for your own code, you will understand how to use it by reading the comments in the examples codes. In order to compile the examples use the following command (compiler (latest version): ifort, ifx, or gfortran; module: FG_m.F90, FGL_m.F90, FGH_m.F90; Example: ExampleFG.f90, ExampleFGL.f90, ExampleFGH.f90; Mathlibrary: -qmkl, -llapack):
<compiler> <module> <Example> <Mathlibrary>
Examples:
ifort FGH_m.F90 ExampleFGH.f90 -qmkl
ifx FGH_m.F90 ExampleFGH.f90 -qmkl
gfortran FGH_m.F90 ExampleFGH.f90 -llapack
No other compilers have been tested, so use them at your own risk!
This program is work in progress! The code has been tested by myself, however there is the possibility of wrong results! If there are any bugs or questions about the code and/or how to use it, feel free to write me.
NEW Release v0.2.0:
- The FG_t type is now approximately 3 times faster, FGH_t, and FGL_t also are significantly faster!
- Use of the c preprocessor to shorten the code and to facilitate editing it.
- Implementation of new operations.