107 function dds(eval, obj_func, pini, prange, r, seed, maxiter, maxit, mask, tmp_file, comm, funcbest, history)
109 function dds(eval, obj_func, pini, prange, r, seed, maxiter, maxit, mask, tmp_file, funcbest, history)
124 real(
dp),
dimension(:),
intent(in) :: pini
125 real(
dp),
dimension(:, :),
intent(in) :: prange
126 real(
dp),
optional,
intent(in) :: r
127 integer(i8),
optional,
intent(in) :: seed
128 integer(i8),
optional,
intent(in) :: maxiter
129 logical,
optional,
intent(in) :: maxit
130 logical,
dimension(:),
optional,
intent(in) :: mask
131 character(len = *),
optional,
intent(in) :: tmp_file
133 type(mpi_comm),
optional,
intent(in) :: comm
135 real(
dp),
optional,
intent(out) :: funcbest
136 real(
dp),
dimension(:),
optional,
intent(out), &
137 allocatable :: history
138 real(
dp),
dimension(size(pini)) ::
dds
143 integer(i8) :: imaxiter
146 real(
dp) :: of_new, of_best
147 real(
dp) :: pn, new_value
148 real(
dp),
dimension(size(pini)) :: pnew
151 integer(i4) :: j, dvn_count, dv
152 integer(i4) :: idummy
153 integer,
dimension(8) :: sdate
154 logical,
dimension(size(pini)) :: maske
155 integer(i4),
dimension(:),
allocatable :: truepara
157 integer(i4) :: ierror
158 logical :: do_obj_loop
159 integer(i4) :: iproc, nproc
164 if (
size(prange, 1) /= pnum) stop
'Error DDS: size(prange,1) /= size(pini)'
165 if (
size(prange, 2) /= 2) stop
'Error DDS: size(prange,2) /= 2'
168 if (
present(r)) ir = r
169 if (ir <= 0.0_dp .or. ir > 1.0_dp) stop
'Error DDS: DDS perturbation parameter (0.0, 1.0]'
172 if (
present(maxiter)) imaxiter = maxiter
173 if (imaxiter < 6) stop
'Error DDS: max function evals must be minimum 6'
175 if (
present(history))
then
176 allocate(history(imaxiter))
180 if (
present(maxit))
then
181 if (maxit) imaxit = -1.0_dp
185 if (
present(seed)) iseed = seed
186 iseed = max(iseed, 0_i8)
188 if (
present(mask))
then
189 if (count(mask) .eq. 0_i4)
then
190 stop
'Input argument mask: At least one element has to be true'
198 allocate (truepara(count(maske)))
200 do j = 1,
size(pini, 1)
202 idummy = idummy + 1_i4
209 call date_and_time(values = sdate)
210 iseed = sdate(1) * 31536000000_i8 + sdate(2) * 2592000000_i8 + sdate(3) * 86400000_i8 + &
211 sdate(5) * 3600000_i8 + sdate(6) * 60000_i8 + sdate(7) * 1000_i8 + sdate(8)
220 if(
present(tmp_file))
then
221 open(unit = 999, file = trim(adjustl(tmp_file)), action =
'write', status =
'unknown')
222 write(999, *)
'# settings :: general'
223 write(999, *)
'# nIterations iseed'
224 write(999, *) imaxiter, iseed
225 write(999, *)
'# settings :: dds specific'
226 write(999, *)
'# dds_r'
228 write(999, *)
'# iter bestf (bestx(j),j=1,nopt)'
232 open(unit = 998, file = trim(adjustl( tmp_file )) //
".current" , action =
'write', status =
'unknown')
233 write(998, *)
'# settings :: general'
234 write(998, *)
'# nIterations iseed'
235 write(998, *) imaxiter, iseed
236 write(998, *)
'# settings :: dds specific'
237 write(998, *)
'# dds_r'
239 write(998, *)
'# iter bestf (bestx(j),j=1,nopt)'
249 call mpi_comm_size(comm, nproc, ierror)
250 do iproc = 1, nproc-1
252 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
255 of_new = imaxit * obj_func(pini, eval)
257 if (
present(history)) history(1) = of_new
259 file_write :
if (
present(tmp_file))
then
260 open(unit = 999, file = trim(adjustl(tmp_file)), action =
'write', position =
'append', recl = (pnum + 2) * 30)
261 open(unit = 998, file = trim(adjustl( tmp_file )) //
".current" , action =
'write', position =
'append', &
262 recl = (pnum + 2) * 30)
263 if (imaxit .lt. 0.0_dp)
then
265 write(999, *)
'0', -of_best, pini
266 write(998, *)
'0', -of_best, pini
269 write(999, *)
'0', of_best, pini
270 write(998, *)
'0', of_best, pini
278 do i = 1, imaxiter - 1
280 pn = 1.0_dp - log(real(i,
dp)) / log(real(imaxiter - 1,
dp))
285 do j = 1,
size(truepara)
288 if (ranval < pn)
then
289 dvn_count = dvn_count + 1
291 call neigh_value(
dds(truepara(j)), prange(truepara(j), 1), prange(truepara(j), 2), ir, new_value)
292 pnew(truepara(j)) = new_value
297 if (dvn_count == 0)
then
299 dv = truepara(int((ranval * real(
size(truepara),
dp)) + 1.0_dp,
i4))
301 call neigh_value(
dds(dv), prange(dv, 1), prange(dv, 2), ir, new_value)
308 call mpi_comm_size(comm, nproc, ierror)
309 do iproc = 1, nproc-1
311 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
314 of_new = imaxit * obj_func(pnew, eval)
316 if (of_new <= of_best)
then
320 if (
present(history)) history(i + 1) = of_best
322 file_write2 :
if (
present(tmp_file))
then
323 open(unit = 999, file = trim(adjustl(tmp_file)), action =
'write', position =
'append', recl = (pnum + 2) * 30)
324 open(unit = 998, file = trim(adjustl( tmp_file )) //
".current" , action =
'write', position =
'append', &
325 recl = (pnum + 2) * 30)
326 if (imaxit .lt. 0.0_dp)
then
328 write(999, *) i, -of_best,
dds
329 write(998, *) i, -of_new, pnew
332 write(999, *) i, of_best,
dds
333 write(998, *) i, of_new, pnew
340 if (
present(funcbest)) funcbest = of_best
342 call mpi_comm_size(comm, nproc, ierror)
343 do iproc = 1, nproc-1
344 do_obj_loop = .false.
345 call mpi_send(do_obj_loop,1, mpi_logical,iproc,0,comm,ierror)
422 function mdds(eval, obj_func, pini, prange, seed, maxiter, maxit, mask, tmp_file, funcbest, history)
432 real(
dp),
dimension(:),
intent(in) :: pini
433 real(
dp),
dimension(:, :),
intent(in) :: prange
434 integer(i8),
optional,
intent(in) :: seed
435 integer(i8),
optional,
intent(in) :: maxiter
436 logical,
optional,
intent(in) :: maxit
437 logical,
dimension(:),
optional,
intent(in) :: mask
438 character(len = *),
optional,
intent(in) :: tmp_file
439 real(
dp),
optional,
intent(out) :: funcbest
440 real(
dp),
dimension(:),
optional,
intent(out), &
441 allocatable :: history
442 real(
dp),
dimension(size(pini)) ::
mdds
447 integer(i8) :: imaxiter
450 real(
dp) :: of_new, of_best
451 real(
dp) :: pn, new_value
452 real(
dp),
dimension(size(pini)) :: pnew
455 integer(i4) :: j, dvn_count, dv
456 integer(i4) :: idummy
457 integer,
dimension(8) :: sdate
458 logical,
dimension(size(pini)) :: maske
459 integer(i4),
dimension(:),
allocatable :: truepara
464 if (
size(prange, 1) /= pnum) stop
'Error MDDS: size(prange,1) /= size(pini)'
465 if (
size(prange, 2) /= 2) stop
'Error MDDS: size(prange,2) /= 2'
468 if (
present(maxiter)) imaxiter = maxiter
469 if (imaxiter < 6) stop
'Error MDDS: max function evals must be minimum 6'
471 if (
present(history))
then
472 allocate(history(imaxiter))
476 if (
present(maxit))
then
477 if (maxit) imaxit = -1.0_dp
481 if (
present(seed)) iseed = seed
482 iseed = max(iseed, 0_i8)
486 call date_and_time(values = sdate)
487 iseed = sdate(1) * 31536000000_i8 + sdate(2) * 2592000000_i8 + sdate(3) * 86400000_i8 + &
488 sdate(5) * 3600000_i8 + sdate(6) * 60000_i8 + sdate(7) * 1000_i8 + sdate(8)
497 if (
present(mask))
then
498 if (count(mask) .eq. 0_i4)
then
499 stop
'Input argument mask: At least one element has to be true'
507 allocate (truepara(count(maske)))
509 do j = 1,
size(pini, 1)
511 idummy = idummy + 1_i4
517 if(
present(tmp_file))
then
518 open(unit = 999, file = trim(adjustl(tmp_file)), action =
'write', status =
'unknown')
519 write(999, *)
'# settings :: general'
520 write(999, *)
'# nIterations iseed'
521 write(999, *) imaxiter, iseed
522 write(999, *)
'# settings :: mdds specific'
523 write(999, *)
'# None'
525 write(999, *)
'# iter bestf (bestx(j),j=1,nopt)'
533 of_new = imaxit * obj_func(pini, eval)
535 if (
present(history)) history(1) = of_new
537 file_write :
if (
present(tmp_file))
then
538 open(unit = 999, file = trim(adjustl(tmp_file)), action =
'write', position =
'append', recl = (pnum + 2) * 30)
539 if (imaxit .lt. 0.0_dp)
then
541 write(999, *)
'0', -of_best,
mdds
544 write(999, *)
'0', of_best,
mdds
551 do i = 1, imaxiter - 1
553 pn = 1.0_dp - log(real(i,
dp)) / log(real(imaxiter - 1,
dp))
557 pn = max(pn, 0.05_dp)
558 ir = max(min(0.3_dp, pn), 0.05_dp)
564 if (ranval < pn)
then
565 dvn_count = dvn_count + 1
567 call neigh_value(
mdds(truepara(j)), prange(truepara(j), 1), prange(truepara(j), 2), ir, new_value)
568 pnew(truepara(j)) = new_value
573 if (dvn_count == 0)
then
575 dv = truepara(int((ranval * real(
size(truepara),
dp)) + 1.0_dp,
i4))
577 call neigh_value(
mdds(dv), prange(dv, 1), prange(dv, 2), ir, new_value)
583 of_new = imaxit * obj_func(pnew, eval)
585 if (of_new <= of_best)
then
590 if (exp(-(of_new - of_best) / of_best) > (1.0_dp - ranval * pn))
then
595 if (
present(history))
then
596 if (
present(maxit))
then
598 history(i + 1) = max(history(i), of_best)
600 history(i + 1) = min(history(i), of_best)
603 history(i + 1) = min(history(i), of_best)
607 file_write2 :
if (
present(tmp_file))
then
608 open(unit = 999, file = trim(adjustl(tmp_file)), action =
'write', position =
'append', recl = (pnum + 2) * 30)
609 if (imaxit .lt. 0.0_dp)
then
611 write(999, *) i, -of_best,
mdds
614 write(999, *) i, of_best,
mdds
620 if (
present(funcbest)) funcbest = of_best
638 subroutine neigh_value(x_cur, x_min, x_max, r, new_value)
645 real(
dp),
intent(in) :: x_cur, x_min, x_max, r
646 real(
dp),
intent(out) :: new_value
650 x_range = x_max - x_min
656 new_value = x_cur + zvalue * r * x_range
659 if (new_value < x_min)
then
660 new_value = x_min + (x_min - new_value)
661 if (new_value > x_max)
then
668 else if (new_value > x_max)
then
669 new_value = x_max - (new_value - x_max)
670 if (new_value < x_min)
then
676 end subroutine neigh_value
Interface for evaluation routine.
Interface for objective function.
Uniform XOR4096-based RNG.
Gaussian XOR4096-based RNG.
Dynamically Dimensioned Search (DDS)
real(dp) function, dimension(size(pini)), public dds(eval, obj_func, pini, prange, r, seed, maxiter, maxit, mask, tmp_file, funcbest, history)
DDS.
real(dp) function, dimension(size(pini)), public mdds(eval, obj_func, pini, prange, seed, maxiter, maxit, mask, tmp_file, funcbest, history)
MDDS.
Define number representations.
integer, parameter i4
4 Byte Integer Kind
integer, parameter i8
8 Byte Integer Kind
integer, parameter dp
Double Precision Real Kind.
Utility functions, such as interface definitions, for optimization routines.
XOR4096-based random number generator.