AGA V1
Asexual Genetic Algorithm Version 1.0
extfunc.f90
Go to the documentation of this file.
00001 !=======================================================================
00002 !> @file extfunc.f90
00003 !> @brief User provided functions and subroutines module
00004 !> @authors Ary Rodriguez-Gonzalez & Alejandro Esquivel
00005 !> @date 23/Jun/2011
00006 !
00007 ! Copyright (c) 2011 Ary Rodriguez-Gonzalez & Alejandro Esquivel
00008 !
00009 ! This file is part of AGA-V1.
00010 !
00011 ! AGA-V1 is free software; you can redistribute it and/or modify
00012 ! it under the terms of the GNU General Public License as published by
00013 ! the Free Software Foundation; either version 3 of the License, or
00014 ! (at your option) any later version.
00015 !
00016 ! This program is distributed in the hope that it will be useful,
00017 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 ! GNU General Public License for more details.
00020 ! You should have received a copy of the GNU General Public License
00021 ! along with this program.  If not, see http://www.gnu.org/licenses/.
00022 !=======================================================================
00023 !> @brief Number of Gaussian components
00024 !> @details Short module to implement the number of Gaussian components
00025 !! used for fit (employed for HH34) as a variable of easy global access.
00026 module numgaus
00027 !> @param ngaus : number of Gaussian components to be fit
00028   integer :: ngaus
00029 end module numgaus
00030 !-----------------------------------------------------------------------
00031 !> @brief External functions module 
00032 !> @details Here the user needs to provide a
00033 !> target (tarfunc) and a merit function (meritfunc). We recommend to
00034 !! preserve the names and interface in order to avoid changing code 
00035 !! elsewhere.
00036 module exfunc
00037 contains
00038 !---------------------------------------------------------------
00039 !> @brief Target Function
00040 !> @details User provided target function. \n
00041 !! In case some observational or experimental data is being fit,
00042 !! this is the function adjusted.\n
00043 !! For the example implemented here, finding a maxima of a given 
00044 !! function, the evaluation of the level of fitness can be made directly
00045 !! inside the merit function, thus the target function  returns a zero
00046 !! (and it is actually not called). Three examples of target functions 
00047 !! can be found commented below: several Gaussian components, one
00048 !! or two Lorentzians, and a PNe luminosity function.
00049 !> @param[in] x : Independent variable (abscissa)
00050 !> @param[in] npar : Number of independent parameters
00051 !> @param[in] q(npar) : Vector of independent parameters
00052 !> @return Value of the target function
00053   real function tarfunc(x,npar,q)
00054     !
00055     use numgaus
00056     !
00057     implicit none
00058     integer, intent(in) :: npar
00059     real, dimension(npar), intent(in):: q
00060     real, intent(in) :: x
00061 !    real, sum0,dintg,intg
00062 !    integer, NumPNs
00063 !
00064 ! Funcion Gausianas
00065 !    select case (ngaus)
00066 !    case (1)
00067 !       tarfunc=q(1)*exp(-(x-q(2))**2/q(3))
00068 !    case (2)
00069 !       tarfunc=q(1)*exp(-(x-q(2))**2/q(3))&
00070 !              +q(4)*exp(-(x-q(5))**2/q(6))+q(7)
00071 !    case (3)
00072 !       tarfunc=q(1)*exp(-(x-q(2))**2/q(3))&
00073 !              +q(4)*exp(-(x-q(5))**2/q(6))&
00074 !              +q(7)*exp(-(x-q(8))**2/q(9))
00075 !    case (4)
00076 !       tarfunc=q(1)*exp(-(x-q(2))**2/q(3))&
00077 !             +q(4)*exp(-(x-q(5))**2/q(6))&
00078 !              +q(7)*exp(-(x-q(8))**2/q(9))&
00079 !              +q(10)*exp(-(x-q(11))**2/q(12))
00080 !    case (5)
00081 !       tarfunc=q(1)*exp(-(x-q(2))**2/q(3))&
00082 !              +q(4)*exp(-(x-q(5))**2/q(6))&
00083 !              +q(7)*exp(-(x-q(8))**2/q(9))&
00084 !              +q(10)*exp(-(x-q(11))**2/q(12))&
00085 !              +q(13)*exp(-(x-q(14))**2/q(15))
00086 !    case (6)
00087 !       tarfunc=q(1)*exp(-(x-q(2))**2/q(3))&
00088 !              +q(4)*exp(-(x-q(5))**2/q(6))&
00089 !              +q(7)*exp(-(x-q(8))**2/q(9))&
00090 !              +q(10)*exp(-(x-q(11))**2/q(12))&
00091 !              +q(13)*exp(-(x-q(14))**2/q(15))&
00092 !              +q(16)*exp(-(x-q(17))**2/q(18))
00093 !    end select
00094 
00095 ! Funcion Lorentzians
00096 !    select case (ngaus)
00097 !       pi=3.141592
00098 !    case (1)
00099 !       tarfunc=q(1)/(pi*q(2)*(1.+((x+q(3)))/q(2)))
00100 !    case (2)
00101 !       tarfunc=q(1)/(pi*q(2)*(1.+((x+q(3)))/q(2)))&
00102 !              +q(4)/(pi*q(5)*(1.+((x+q(6)))/q(5)))
00103 !            
00104 !    end select
00105 !
00106 ! Planetary Nebulae Luminosity Function
00107 !    tarfunc=q(1)*exp(0.307*x)*(1.-exp(3.*(q(2)-x)))
00108 !
00109 !    NumPNs=100
00110 !    summ0=0.
00111 !    Do j=0,NumPNs-1 
00112 !       summ0=3.*exp(3*q(1))/(exp(3.*q(1))-exp(3.*A(0,j)))+summ0
00113 !    EndDo
00114 !    dintg=1.114*(exp(3.*q(1)-2.693*ml)-exp(0.307*q(1)))    
00115 !
00116     tarfunc=0.
00117     return
00118   end function tarfunc
00119 !-----------------------------------------------------------------------
00120 !> @brief Merit Function
00121 !> @details User provided merit function. \n
00122 !! This function computes the fitness level of each individual. \n
00123 !! The program assumes that a low value has the highest level of fitness
00124 !! (since its primary application is to fit functions with a merit
00125 !! function that is an error measure, e.g. @f$\chi^2@f$). If one needs
00126 !! to find a maximum of a function, one can use its reciprocal as merit
00127 !! function.\n
00128 !! The interface of the function is designed to adjust a target function
00129 !! to a set of observational/experimental data, there some arguments
00130 !! become dummy if the merit function does not need to be
00131 !! called.
00132 !> @param[in] xobs(ndata) : Vector of data abscissae
00133 !> @param[in] yobs(ndata) : Vector of data ordinates
00134 !> @param[in] ysigma(ndata) : Vector of uncertainties in the ordinate
00135 !> @param[in] q(npar) : Vector of parameters to be adjusted
00136 !> @param[in] npar : Number of parameters adjusted
00137 !> @param[in] ndata : Number of data points
00138 !> @return Value of the merit function (lowest value=fittest individual)
00139     real function meritfunc(xobs,yobs,ysigma,q,npar,ndata)
00140     implicit none
00141     real, dimension(ndata), intent(in) :: xobs,yobs,ysigma
00142     real, dimension(npar), intent(in) :: q
00143     real :: chi2,yfunc,pi,a,b,sig,x0,y0,r
00144     integer, intent(in):: npar,ndata
00145     integer :: i,n
00146 !
00147 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00148 !                 Chi^2 fitting                                    !
00149 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00150 !    chi2=0.
00151 !    do i=1,ndata
00152 !       yfunc=tarfunc(xobs(i),npar,q)
00153 !       chi2=chi2+((yobs(i)-yfunc)/(ysigma(i)))**2
00154 !    enddo
00155 !    meritfunc=chi2
00156 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00157 !                       TEST FUNCTION 1                            !
00158 !       f(x,y)=[16x(1-x)y(1-y)sin(n*pi*x)sin(n*pi*y)]^2            !
00159 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00160     pi=3.141592
00161     n=9
00162     meritfunc=16.*q(1)*(1.-q(1))*q(2)*(1.-q(2))*sin(pi*n*q(1))*sin(pi*n*q(2))
00163     meritfunc=1.-meritfunc
00164 !
00165 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00166 !                      TEST FUNCTION 2                             !
00167 !                    r=sqrt((x-x0)^2+(y-y0)^2)                     !
00168 !                  f(r)=cos^a(b*pi*r)*exp(-r^2/(2*sig^2))           !
00169 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00170 !    a=2.
00171 !    b=3.
00172 !    sig=2.
00173 !    x0=0.25
00174 !    y0=0.25
00175 !    pi=3.141592
00176 !    r=sqrt((q(1)-x0)**2+(q(2)-y0)**2)
00177 !    meritfunc=(cos(b*pi*r))**a*exp(-r**2/(2.*sig))
00178 !    meritfunc=1.-meritfunc
00179 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!     
00180 !                      TEST FUNCTION 3                             !     
00181 !       f(x,y)=(1+cos(12sqrt(x^2+y^2)))/(0.5(x^2+y^2)+2)           ! 
00182 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00183  
00184 !    meritfunc=(1+cos(12*sqrt(q(1)**2+q(2)**2)))/(0.5*(q(1)**2+q(2)**2)+2)
00185 !    meritfunc=1.-meritfunc
00186 !
00187 !
00188     return
00189   end function meritfunc
00190 !-----------------------------------------------------------------------
00191 end module exfunc
00192 !-----------------------------------------------------------------------
00193 !=======================================================================
00194 !> @brief Input from data and options file.
00195 !> @details contains routines to read the input data and run-time
00196 !! parameters.
00197 module input
00198 contains
00199 !> @brief Observational/experimental data input
00200 !> @details Reads experimental/observational data from file. Data are
00201 !! ordered by columns (see example in ObsData.dat)
00202 !> @param[out] xobs(ndata) : vector of abscissae
00203 !> @param[out] yobs(ndata) : vector of ordinates
00204 !> @param[out] ysigma(ndata) : vector of uncertainties of the ordinates
00205 !> @param[out] ndata : number of experimental points.
00206   subroutine ReadData(xobs,yobs,ysigma,ndata)
00207     implicit none
00208     real, dimension(:), allocatable, intent(out) :: xobs,yobs,ysigma
00209     integer, intent(out) :: ndata
00210     !
00211     real, dimension(:), allocatable :: x1,y1,ys1
00212     integer :: i, status
00213     integer, parameter :: n=10000000
00214     !
00215     !   read the input file (3 columns, x,y,sigma_y, and determine the
00216     !   number of lines it contains
00217     open(1,file='ObsData.dat',status='old',iostat=status)
00218     allocate(x1(n),y1(n),ys1(n))
00219     ndata=0
00220     do i=1,n
00221        read(1,*,iostat=status) x1(i),y1(i),ys1(i)
00222        if (status /= 0) exit
00223        ndata=ndata+1
00224     enddo
00225     close(1)
00226     !
00227     !   allocate the arrays (size=number of lines in input file)
00228     allocate(xobs(ndata),yobs(ndata),ysigma(ndata))
00229     !
00230     !   fill the arrays with the temporary buffers and free memory
00231     xobs  (:) = x1 (1:ndata)
00232     yobs  (:) = y1 (1:ndata)
00233     ysigma(:) = ys1(1:ndata)
00234     deallocate(x1,y1,ys1)
00235     !
00236     return
00237   end subroutine ReadData
00238  !---------------------------------------------------------------------
00239 !> @brief  Reads runtime parameters from file and initializes arrays
00240 !> @details  Reads from file (InitCond.dat) all the runtime input 
00241 !! parameters, initializes the values of the hyperboxes, and allocates
00242 !! memory for all the parents and population.
00243 !> @param[out] nsteps : Number of iterations before the hyperboxes are
00244 !!  restored to their initial size
00245 !> @param[out] nruns : Number of times that the hyperboxes are returned
00246 !! to their initial size
00247 !> @param[out] nparent : Number of parents
00248 !> @param[out] nind : Number of individuals
00249 !> @param[out] nerr : Number of realizations performed to obtain an
00250 !! estimate of the errors
00251 !> @param[out] deltaconst : if equal to 1 the reduction of the hyperboxes
00252 !! is at a constant rate (see reduc), otherwise hyperboxes are reduced 
00253 !! with the standard deviation of each parameter.
00254 !> @param[out] nmig : turns on/off migration. If its value is 0, 
00255 !! migration is disabled, otherwise is enabled
00256 !> @param[out] ngaussdev :  : if value equal to 1, offsprinf is obtained
00257 !! with a Gaussian distribution, otherwise they are obtained with
00258 !! uniform random deviates.
00259 !> @param[out] igaus :  ????? Quiza deberia pasarse al modulo de las 
00260 !! gaussianas
00261 !> @param[out] npar :  number of free parameters
00262 !> @param[out] gensize : size of the new generation from each parent.
00263 !! Since the parent is kept gensize=num of sons + 1
00264 !> @param[out] reduc : reducing factor, if a constant speed is chosen the
00265 !! hyper-box is reduced according to: 
00266 !> @param[out] beta : Tolerance value
00267 !> @param[out] qbounds(2,npar) : limits of the original (user provided)
00268 !! hyperbox
00269 !> @param[out] q0(npar) : Initial guess, computed as the position at the 
00270 !! center of the initial hyperbox
00271 !> @param[out] delta0(npar) : Initial window half-size
00272 !> @param[out] fit(nind) : Array to store the fitness level of the
00273 !! population
00274 !> @param[out] arrmain(npar,nind) : Array for the entire population
00275 !> @param[out] arrpar(npar,nparent) : Array for the parents only
00276 !> @param[out] arrgen(npar,gensize) : Array to store a single generation
00277 !! of each parent
00278   subroutine InitCond(nsteps,nruns,nparent,nind,nerr, deltaconst, nmig, &
00279                                           ngaussdev, igaus, npar, gensize, reduc, beta,     &
00280                                           qbounds,q0,delta0,fit,arrmain,arrpar,arrgen )
00281     implicit none
00282     integer, intent(out):: npar,nsteps,nruns,nparent,nind,gensize,      
00283                            deltaconst,nmig,ngaussdev,nerr,igaus
00284     real, intent(out)   :: reduc,beta
00285     real, dimension(:),   allocatable, intent(out):: q0,delta0,fit
00286     real, dimension(:,:), allocatable, intent(out):: arrmain,arrpar,
00287                                                      arrgen,qbounds
00288     real, dimension(:,:), allocatable :: aux
00289     !
00290         integer :: i,status
00291     integer, parameter :: n=10000
00292     !
00293     open(1,file='InitCond.dat',status='old',iostat=status)
00294     allocate(aux(2,1000))
00295     !
00296     !
00297 2   continue
00298     read(1,*,err=2) nsteps,nruns,nparent,nind,nerr
00299     !
00300 3   continue
00301     read(1,*,err=3) deltaconst, nmig ,ngaussdev, igaus
00302     !
00303 4   continue
00304     read(1,*,err=4) reduc,beta
00305     !
00306 5      continue
00307     read(1,*,err=5)aux(1,1),aux(2,1)
00308     !
00309     npar=1
00310     do i=2,n
00311        read(1,*,iostat=status)aux(1,i),aux(2,i)
00312        if (status/=0)exit
00313        npar=npar+1
00314     enddo
00315     !
00316     close(1)
00317     ! 
00318     allocate(q0(npar),delta0(npar))
00319     allocate(qbounds(2,npar))
00320     qbounds(1,:)=aux(1,1:npar)
00321     qbounds(2,:)=aux(2,1:npar)
00322     q0(:)=(qbounds(1,1:npar)+qbounds(2,1:npar))/2.
00323     delta0(:)=(qbounds(2,1:npar)-qbounds(1,1:npar))/2.
00324         !
00325         deallocate(aux)
00326     !
00327     gensize=nind/nparent
00328     allocate(fit(nind), arrmain(npar,nind),arrpar(npar,nparent),         &
00329              arrgen(npar,gensize))
00330     !
00331     return
00332   end subroutine InitCond
00333   !--------------------------------------------------------------------
00334 end module input
00335 !----------------------------------------------------------------------
 All Namespaces Files Functions Variables