![]() |
AGA V1
Asexual Genetic Algorithm Version 1.0
|
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 !-----------------------------------------------------------------------
1.7.4