AGA V1
Asexual Genetic Algorithm Version 1.0
aga-v1.f90
Go to the documentation of this file.
00001 !=======================================================================
00002 !> @file aga-v1.f90
00003 !> @brief The implementation of AGA
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 Module containing the implementation of the algorithm
00024 !> @details It has to be called from a main program that serves as an 
00025 !! interface if used with a experimental/observational data.
00026 !> @todo Debug OpenMP implementation
00027 module agav1
00028 contains
00029 ! ----------------------------------------------------------------------
00030 !> @brief THE algorithm
00031 !> @details This is the implementation of the Asexual Genetic Algorithm
00032 !! (AGA), it requires that the experimental/observational data have been
00033 !! previously loaded (this is done in the main program, and was left out
00034 !! of the main algorithm to improve flexibility), and if MPI is enabled
00035 !! it also needs to be prevously loaded. The algorithm loads the rest of 
00036 !! the runtime parameters and return the fittest individual and an
00037 !! estimate of the errors.
00038 !> @param[in] xobs(ndata) : Vector of data abscissae
00039 !> @param[in] yobs(ndata) : Vector of data ordinates
00040 !> @param[in] ysigma(ndata) : Vector of uncertainties in the ordinate
00041 !> @param[out] q(npar) : Vector of parameters to be adjusted, at the end
00042 !! returns the fittest individul 
00043 !> @param[out] delta(npar) : Window (hyperbox) half-size, at the end
00044 !! the variable returns the uncertainty of q
00045 !> @param[in] ndata : Number of data points
00046   subroutine Algorithm(xobs,yobs,ysigma,q,delta,npar,ndata)
00047     use input                   ! located in extfunc.f90
00048     use func                    ! located in extfunc.f90
00049     use exfunc                  ! located in extfunc.f90
00050     use mpi_module              ! located in modules.f90
00051     use numgaus                 ! located in modules.f90
00052     implicit none
00053     integer :: npar, ndata, nsteps, nruns, nparent, nind, nerr,         
00054                deltaconst, nmig, ngaussdev, igaus, gensize
00055     real :: beta,reduc,fito,deltafit
00056     real :: mean, sigma
00057     !
00058     real, dimension(:), allocatable :: q0,delta0, q, delta, fit
00059     real, dimension(:), allocatable :: xobs,yobs,ysigma
00060     !
00061     real, dimension(:,:),allocatable :: arrmain,arrpar,arrgen,arrerr,   
00062                                         qbounds
00063     !
00064     integer :: i,j,k,niter,idum,nit,ij,ncrit
00065     integer :: stk, nproc, omp_get_thread_num, KMP_GET_STACKSIZE_S,nprocs
00066     integer :: omp_get_num_threads
00067     !
00068     integer :: rand_size
00069     integer, allocatable, dimension(:) :: rand_seed
00070     character (len=10) :: system_time
00071     real :: rtime
00072     !
00073 #ifdef MPIP
00074     real, dimension(:,:),allocatable :: arrerrtot
00075 #endif
00076     !
00077     !     OpenMP initialization
00078     !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00079     !$    WRITE (6,*) 'Compiled with OpenMP'
00080     !$OMP PARALLEL PRIVATE(NPROC)
00081     !$           stk = KMP_GET_STACKSIZE_S()
00082     !$           nproc = OMP_GET_THREAD_NUM()
00083     !$           WRITE(6,*) 'Processor (thread) #:',nproc,' ready'
00084     !$OMP END PARALLEL
00085     !$           WRITE(6,*) 'Stack size per thread : ', stk/1048576,' Mb'
00086     !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
00087     !
00088     !   initializes seed for random number generator
00089     
00090     call random_seed(size=rand_size)
00091     allocate(rand_seed(1:rand_size))
00092     call date_and_time(time=system_time)
00093     read(system_time,*) rtime
00094     rand_seed=int(rtime*1000.)
00095 #ifdef MPIP
00096     rand_seed=rand_seed*rank
00097 #endif
00098     call random_seed(put=rand_seed)    
00099     deallocate(rand_seed)
00100     !----------------------------------------------
00101     !
00102 #ifdef MPIP
00103     do i=0,np-1
00104                 if (rank.eq.i) then
00105 #endif
00106                         call InitCond(nsteps,nruns,nparent,nind,nerr, deltaconst,   &
00107                                               nmig, ngaussdev, igaus, npar, gensize, reduc, &
00108                                           beta, qbounds,q0,delta0,fit,arrmain,arrpar,arrgen )                     
00109         
00110                         allocate(arrerr(npar,nerr/np),q(npar),delta(npar))
00111                         q(:)=q0
00112                         delta(:)=delta0
00113 #ifdef MPIP
00114                         allocate(arrerrtot(npar,nerr))
00115        endif
00116        call mpi_barrier (mpi_comm_world,err)
00117     enddo
00118 #endif
00119     !
00120     call spawn(npar,nparent,nmig,ngaussdev,delta,q,qbounds,arrpar)
00121     !   
00122     ! Main loop
00123     !  
00124     do j=1,nerr/np
00125           Print *,'Nerr=',j,np
00126        !
00127         if (nerr .ne. 1) call randdata(ndata,yobs,ysigma)
00128        !
00129        nit=1
00130        !
00131        do while(nit.le.nruns)
00132           !
00133           deltafit=1e20
00134           fit(1)=1e20
00135           niter = 1
00136           ncrit=0
00137           !
00138           do while(niter .le. nsteps)
00139  
00140             call deltabox(npar,niter,nind,deltaconst,reduc,arrmain,     &
00141                           delta0,delta)         
00142              !
00143              !$omp parallel shared(arrgen,arrmain,arrpar,fit) &
00144              !$omp           private(nproc,nprocs)
00145              !$ nproc = OMP_GET_THREAD_NUM()
00146              !$ nprocs= omp_get_num_threads()
00147              !$omp do SCHEDULE(static,nparent/nprocs)
00148              !
00149              do i=1,nparent
00150                 call spawn(npar,gensize,nmig,ngaussdev,delta,           &
00151                            arrpar(:,i), qbounds, arrgen )
00152                 !
00153                 arrmain(:,((i-1)*gensize+1):i*gensize)=arrgen(:,:)
00154              enddo
00155              !$omp end do
00156              !
00157              !$omp do SCHEDULE(static,nind/nprocs)
00158              do i=1,nind
00159                 !!   this works only for sums of gaussians
00160                 If (igaus .eq. 1) Then
00161                    !
00162                    call gaussian(ngaus,i,arrmain)
00163                    !
00164                 EndIf
00165                 q(:)=arrmain(:,i)
00166                 fit(i)=meritfunc(xobs,yobs,ysigma,arrmain(:,i),         &
00167                                  npar,ndata)
00168              enddo
00169              !$omp end do
00170              !$omp end parallel
00171              !
00172              call pickbest(npar,nind,nparent,arrmain,fit,arrpar)
00173 
00174              niter = niter+1
00175              deltafit=abs(1-fito/fit(1))
00176              fito=fit(1)
00177 ! CRITERIO NUEVO
00178 !             call criterion(nparn,q,delta,beta,ncrit)
00179 !             print*,nit,niter,ncrit,j
00180 !             if (ncrit .eq. 1) exit
00181 !
00182 !             if (deltafit .lt. beta) exit
00183               print*,niter,nit
00184               if (fit(1) .lt. beta) exit
00185 !
00186           enddo
00187           nit=nit+1
00188           !
00189        enddo
00190       arrerr(:,j)=arrpar(:,1) !c(:)
00191     end do
00192     !
00193 #ifdef MPIP
00194     call mpi_gather (arrerr,    npar*nerr/np, mpi_real8 ,               &
00195                      arrerrtot, npar*nerr/np, mpi_real8 ,               &
00196                       master, mpi_comm_world, err )
00197     if (rank.eq.master) then
00198 #endif
00199     !
00200     open(2,file='coeffit.out')
00201     !
00202     do i=1,npar
00203 #ifndef MPIP
00204        q(i)=med(arrerr(i,:),nerr)
00205        delta(i)=sigm(arrerr(i,:),nerr)
00206 #else
00207        q(i)=med(arrerrtot(i,:),nerr)
00208        delta(i)=sigm(arrerrtot(i,:),nerr)
00209 #endif
00210     enddo
00211     if (rank.eq.master) then
00212        do i=1,npar
00213           write(2,*)q(i),delta(i)
00214        enddo
00215           write(2,*)fit(1)
00216     endif
00217     close(2)
00218 #ifdef MPIP
00219  endif
00220  dellocate(arrerrtot)
00221  call mpi_barrier (mpi_comm_world, err)
00222 #endif
00223  deallocate(fit,arrerr)
00224  
00225 end subroutine Algorithm
00226 end module agav1
00227 !-----------------------------------------------------------------------
 All Namespaces Files Functions Variables