5 QDateTime
elapsedd = QDateTime::currentDateTime();
6 #define ELAPSEDNOW (elapsedd.msecsTo(QDateTime::currentDateTime()))
7 #define ELAPSEDSEC (elapsedd.secsTo(QDateTime::currentDateTime()))
8 #define DbTimMsg(a) DbTiming << my_rank << generation << ELAPSEDNOW << a;
9 #define DRTiming DbTiming << my_rank
21 static const double BASE_SIG = 0.2;
22 static const int GR_INCR = 10;
26 p_grid = ( keys.contains(
"p_grid" ) )
31 base_sig = s_bsig .isEmpty() ? BASE_SIG : s_bsig .toDouble();
32 g_redo_inc = s_grinc.isEmpty() ? GR_INCR : s_grinc.toInt();
52 int ntscan =
data_sets[ 0 ]->run_data.scanCount();
53 for (
int ii = 1; ii <
data_sets.size(); ii++ )
54 ntscan +=
data_sets[ ii ]->run_data.scanCount();
62 QString cmfname =
"../" +
parameters[
"DC_model" ];
66 DbgLv(1) <<
my_rank <<
"dmga_worker: cmfname" << cmfname;
72 bool finished =
false;
92 DbgLv(1) <<
my_rank <<
"dmga_worker: nfloatc nfvari do_astfem"
102 DbgLv(0) <<
"Deme" << grp_nbr << deme_nbr
103 <<
": Generations finished, second" <<
ELAPSEDSEC;
114 for (
int ii=0; ii<
nfvari; ii++ )
128 DbgLv(1) <<
my_rank <<
"dmgw: job offs count len" << dataset << count << length
129 <<
"tag" << status.MPI_TAG;
132 switch ( status.MPI_TAG )
136 DbgLv(0) <<
" Deme" << grp_nbr << deme_nbr <<
":"
138 <<
"fitness checks maxrss" <<
maxrss;
157 for (
int e = dataset; e < dataset + count; e++ )
164 for (
int s = 0; s < scan_count; s++ )
168 for (
int r = 0; r < radius_points; r++ )
192 abort(
"Unknown message at end of GA worker loop" );
218 empty_fitness.
index = ii;
230 int p_plague = p_crossover +
plague;
240 QDateTime
start = QDateTime::currentDateTime();
247 DbTimMsg(
"Worker start rank/generation/elapsed-secs");
253 DbgLv(1) <<
my_rank <<
"dg:getf: ii" << ii <<
" fitness"
259 DbTimMsg(
"Worker after get_fitness loop + sort");
264 DbgLv(
DL) <<
"Deme" << grp_nbr << deme_nbr
265 <<
": At last generation minimize.";
266 DbTimMsg(
"Worker before gsm rank/generation/elapsed");
271 DbgLv(
DL) <<
"Deme" << grp_nbr << deme_nbr
272 <<
": last generation minimize fitness=" << fitness[0].fitness;
273 DbTimMsg(
"Worker after gsm rank/generation/elapsed");
280 if((deme_nbr%10)==1) {
281 DbgLv(1) <<
"Best gene to master: gen" <<
generation <<
"worker" << deme_nbr
282 <<
"fitness" <<
fitness[0].fitness;
288 msg.
fitness = fitness[ 0 ].fitness;
304 DbTimMsg(
"Worker after send fitness,genes");
315 DbTimMsg(
"Worker after receive instructions");
321 DbgLv(0) <<
"Deme" << grp_nbr << deme_nbr
322 <<
": Finish signalled at deme generation" <<
generation + 1;
329 DbgLv(0) <<
"Deme" << grp_nbr << deme_nbr
330 <<
": At last generation";
338 const double NEAR_MATCH = 1.0e-8;
339 const double EPSF_SCALE = 1.0e-3;
340 double fitpwr = (double)qRound( log10( fitness[ 0 ].fitness ) );
341 double epsilon_f = pow( 10.0, fitpwr ) * EPSF_SCALE;
342 DbgLv(1) <<
"gw:" <<
my_rank <<
": Dup best-gene clean: fitness0 fitpwr epsilon_f"
343 << fitness[0].fitness << fitpwr << epsilon_f;
345 while ( f1 < population )
347 double fitdiff = qAbs( fitness[ f0 ].fitness - fitness[ f1 ].fitness );
349 if ( fitdiff < epsilon_f )
352 int g0 = fitness[ f0 ].index;
353 int g1 = fitness[ f1 ].index;
357 for (
int ii = 0; ii <
nfloatc; ii++ )
363 int mcompx =
cns_flt[ ii ].mcompx;
368 double difv = qAbs( ( val0 - val1 ) / val0 );
370 if ( difv > NEAR_MATCH )
372 DbgLv(1) <<
"gw:" <<
my_rank <<
": Dup NOT cleaned: f0 f1 fit0 fit1"
373 << f0 << f1 << fitness[f0].fitness << fitness[f1].fitness <<
"ii g0 g1 g0v g1v"
374 << ii << g0 << g1 << val0 << val1;
383 DbgLv(1) <<
"gw:" <<
my_rank <<
": Dup cleaned: f0 f1 fit0 fit1"
384 << f0 << f1 << fitness[f0].fitness << fitness[f1].fitness;
385 fitness[ f1 ].fitness =
LARGE;
398 QList< DGene > old_genes =
dgenes;
403 double fit0 = fitness[ 0 ].fitness;
405 fitness[ 0 ].fitness );
406 double fit1 = fitness[ 0 ].fitness;
408 old_genes[0] =
dgene;
411 for (
int ii = 0; ii <
nfloatc; ii++ )
415 int mcompx =
cns_flt[ ii ].mcompx;
416 double vmin =
cns_flt[ ii ].low;
417 double vmax =
cns_flt[ ii ].high;
420 if ( aval < vmin || aval > vmax )
424 <<
"aval vmin vmax" << aval << vmin << vmax;
425 aval = qMax( vmin, qMin( vmax, aval ) );
433 old_genes[ gg ] =
dgene;
436 <<
"gen fitness" << fit0 <<
"post-min fitness" << fit1;
443 for (
int gg = 0; gg <
elitism; gg++ )
444 dgenes[ gg ] = old_genes[ fitness[ gg ].index ];
448 DbgLv(1) <<
"gw:" <<
my_rank <<
": immigr_count" << immigr_count
451 DbTimMsg(
"Worker before elitism loop");
453 for (
int gg = elitism + immigr_count; gg <
population; gg++ )
458 int probability =
u_random( p_plague );
459 DbgLv(1) <<
"gw:" <<
my_rank <<
": gg" << gg <<
"gene_index" << gene_index
460 <<
"probability" << probability;
461 dgene = old_genes[ gene_index ];
474 DbTimMsg(
"Worker after elitism loop");
481 DbTimMsg(
" +++Worker after generation loop");
488 double extn_p = (double)(
p_grid - 1 );
491 for (
int ii = 0; ii <
nfloatc; ii++ )
496 int mcompx =
cns_flt[ ii ].mcompx;
497 bool logscl =
cns_flt[ ii ].logscl;
498 double vmin =
cns_flt[ ii ].low;
499 double vmax =
cns_flt[ ii ].high;
501 <<
"vmin vmax" << vmin << vmax;
511 double aval = vmin + ( ( vmax - vmin ) * delta / extn_p );
512 aval = qMax( vmin, qMin( vmax, aval ) );
514 aval = logscl ? exp( aval ) : aval;
516 <<
"delta" << delta <<
"aval" << aval;
528 const double extn_p = (double)(
p_grid - 1 );
529 const double sigfact = pow( 10.0, (
mutate_sigma * 0.1 ) );
533 double genterm = log2( (
double)
generation * sigfact + 2.0 );
534 double sigma =
base_sig * extn_p / genterm;
541 for (
int ii = 0; ii <
nfloatc; ii++ )
544 if ( ( ( 1 << ii ) & smask ) == 0 )
551 int mcompx =
cns_flt[ ii ].mcompx;
552 bool logscl =
cns_flt[ ii ].logscl;
557 double vh =
cns_flt[ ii ].high;
559 <<
"vl vh" << vl << vh <<
"vv" << vv;
570 double delta = qRound( xx );
571 vv += ( delta * ( vh - vl ) / extn_p );
574 vv = logscl ? exp( vv ) : vv;
575 DbgLv(1) <<
my_rank <<
"dg:mutg: ii" << ii <<
" xx" << xx
576 <<
"delta" << delta <<
"vv" << vv;
593 DbgLv(1) <<
"dg:crsg: gndx" << gndx <<
"smask" << smask;
595 for (
int ii = 0; ii <
nfloatc; ii++ )
598 if ( ( ( 1 << ii ) & smask ) == 0 )
605 int mcompx =
cns_flt[ ii ].mcompx;
616 static const int migrate_pcent =
parameters[
"migration" ].toInt();
617 static const int elitism_count =
parameters[
"elitism" ].toInt();
619 QList < DGene > emmigres;
621 int doubles_count = migrate_count *
nfloatc;
622 QVector< double > emmigrants( doubles_count );
623 DbgLv(1) <<
my_rank <<
"dg:migrdg: migrate_count doubles_count" << migrate_count << doubles_count;
635 DbgLv(1) <<
my_rank <<
"dg:migrdg: emmigres size" << emmigres.size() <<
"emmigrants size" << emmigrants.size();
649 MPI_Send( emmigrants.data(),
657 QVector< double > immigres( doubles_count );
660 MPI_Recv( immigres.data(),
669 MPI_Get_count( &status, MPI_DOUBLE, &doubles_sent );
670 int mgenes_count = doubles_sent /
nfloatc;
671 DbgLv(1) <<
my_rank <<
"dg:migrdg: immigres size" << immigres.size() <<
"doubles_sent" << doubles_sent;
674 if ( mgenes_count > 0 )
685 int vsize = vv.
size();
690 for (
int ii = 0; ii < vsize; ii++ )
692 dgmarker[ ii ] = vv[ ii ] / zz[ ii ];
706 static const double hh = 0.01;
707 static const double h2_recip = 0.5 / hh;
712 for (
int ii = 0; ii < tt.
size(); ii++ )
714 double save = tt[ ii ];
716 tt.
assign( ii, save - hh );
719 tt.
assign( ii, save + hh );
722 vd.
assign( ii, ( y2 - y0 ) * h2_recip );
731 DbgLv(1) <<
my_rank <<
"dg:IHM:minimize dgene comps" << dgene.components.size() <<
fitness;
738 QVector< QVector< double > > hessian( vsize );
740 for (
int ii = 0; ii < vsize; ii++ )
742 hessian[ ii ] = QVector< double >( vsize, 0.0 );
743 hessian[ ii ][ ii ] = 1.0;
750 for (
int ii = 0; ii < vsize; ii++ )
753 double vpwr = (double)qFloor( log10( vval ) );
754 double vnorm = pow( 10.0, -vpwr );
755 vv.
assign( ii, vval * vnorm );
757 DbgLv(1) <<
my_rank <<
"dg:IHM: ii" << ii <<
"vval vnorm" << vval << vnorm
758 <<
"vpwr" << vpwr <<
"vvi" << vv[ii];
763 static const double epsilon_f = 1.0e-7;
766 double epsilon = epsilon_f * fitness * 4.0;
767 bool neg_cnstr = ( vv[ 0 ] < 0.1 );
772 if ( fitness == 0.0 )
break;
785 if ( neg_cnstr && v_s2[ 0 ] < 0.1 )
794 while ( s2 > epsilon && g_s2 > g_s1 )
801 if ( neg_cnstr && v_s2[ 0 ] < 0.1 )
811 if ( s2 <= epsilon || ( s3 - s2 ) < epsilon )
break;
818 if ( neg_cnstr && v_s3[ 0 ] < 0.1 )
826 static const int max_reps = 100;
828 while ( ( ( s2 - s1 ) > epsilon ) &&
829 ( ( s3 - s2 ) > epsilon ) &&
830 ( reps++ < max_reps ) )
832 double s1_s2 = 1.0 / ( s1 - s2 );
833 double s1_s3 = 1.0 / ( s1 - s3 );
834 double s2_s3 = 1.0 / ( s2 - s3 );
836 double s1_2 =
sq( s1 );
837 double s2_2 =
sq( s2 );
838 double s3_2 =
sq( s3 );
840 double aa = ( ( g_s1 - g_s3 ) * s1_s3 -
841 ( g_s2 - g_s3 ) * s2_s3
844 double bb = ( g_s3 * ( s2_2 - s1_2 ) +
845 g_s2 * ( s1_2 - s3_2 ) +
846 g_s1 * ( s3_2 - s2_2 )
848 s1_s2 * s1_s3 * s2_s3;
850 static const double max_a = 1.0e-25;
852 if ( qAbs( aa ) < max_a )
855 for (
int ii = 0; ii < vsize; ii++ )
857 dgmarker[ ii ] = vv[ ii ] / zz[ ii ];
865 double xx = -bb / ( 2.0 * aa );
866 double prev_g_s2 = g_s2;
870 if ( xx < ( s1 + s1 - s2 ) )
873 if ( xx < 0 ) xx = s1 / 2.0;
878 if ( s1 < 0 ) s1 = 0.0;
894 if ( neg_cnstr && v_s1[ 0 ] < 0.1 )
911 if ( neg_cnstr && v_s2[ 0 ] < 0.1 )
928 if ( neg_cnstr && v_s2[ 0 ] < 0.1 )
937 if ( xx > ( s3 + s3 - s2 ) )
943 if ( neg_cnstr && v_s4[ 0 ] < 0.1 )
950 if ( g_s4 > g_s2 && g_s4 > g_s3 && g_s4 > g_s1 )
968 if ( neg_cnstr && v_s3[ 0 ] < 0.1 )
976 if ( qAbs( prev_g_s2 - g_s2 ) < epsilon )
break;
981 if ( g_s2 < g_s3 && g_s2 < g_s1 )
986 else if ( g_s1 < g_s3 )
1014 for (
int ii = 0; ii < vsize; ii++ )
1016 double dotprod = 0.0;
1018 for (
int jj = 0; jj < vsize; jj++ )
1019 dotprod += ( hessian[ ii ][ jj ] * v_dg[ jj ] );
1021 v_hdg.
assign( ii, dotprod );
1024 double fac = v_dg.
dot( v_dx );
1025 double fae = v_dg.
dot( v_hdg );
1026 double sumdg = v_dg.
dot( v_dg );
1027 double sumxi = v_dx.
dot( v_dx );
1029 if ( fac > sqrt( epsilon * sumdg * sumxi ) )
1032 double fad = 1.0 / fae;
1034 for (
int ii = 0; ii < vsize; ii++ )
1036 v_dg.
assign( ii, fac * v_dx[ ii ] - fad * v_hdg[ ii ] );
1039 for (
int ii = 0; ii < vsize; ii++ )
1041 for (
int jj = ii; jj < vsize; jj++ )
1043 hessian[ ii ][ jj ] +=
1044 fac * v_dx [ ii ] * v_dx [ jj ] -
1045 fad * v_hdg[ ii ] * v_hdg[ jj ] +
1046 fae * v_dg [ ii ] * v_dg [ jj ];
1049 hessian[ jj ][ ii ] = hessian[ ii ][ jj ];
1055 for (
int ii = 0; ii < vsize; ii++ )
1057 double dotprod = 0.0;
1059 for (
int jj = 0; jj < vsize; jj++ )
1060 dotprod += ( hessian[ ii ][ jj ] * v_g[ jj ] );
1062 uu.
assign( ii, dotprod );
1068 for (
int ii = 0; ii < vsize; ii++ )
1070 dgmarker[ ii ] = vv[ ii ] / zz[ ii ];
1071 DbgLv(1) <<
my_rank <<
"dg:IHM: ii" << ii <<
"vvi zzi dgmi"
1072 << vv[ii] << zz[ii] <<
dgmarker[ii];
1114 QString fkey = str.sprintf(
"%.5e",
dgmarker[ 0 ] );
1116 for (
int ii = 1; ii <
nfloatc; ii++ )
1117 fkey += str.sprintf(
" %.5e",
dgmarker[ ii ] );
1127 int lim_offs = offset + dset_count;
1134 for (
int ee = offset; ee < lim_offs; ee++ )
1157 for (
int cc = 0; cc < model.
components.size(); cc++ )
1166 if(my_rank<2 && dbg_level>0) {
1211 for (
int ss = 0; ss < nscans; ss++ )
1219 double variance = 0.0;
1222 for (
int ee = 0; ee < lim_offs; ee++ )
1230 for (
int ss = 0; ss < nscans; ss++, ks++ )
1234 for (
int rr = 0; rr < npoints; rr++ )
1236 double resval = edata->
value( ss, rr )
1237 - sdata->
value( ks, rr );
1238 variance +=
sq( resval );
1253 QString value(
"" );
1254 int keyx = kvtext.indexOf( key );
1255 value = ( keyx < 0 ) ? value
1256 : QString( kvtext ).mid( keyx ).section(
" ", 1, 1 );
1258 DbgLv(0) <<
my_rank <<
": p_k_v key" << key <<
"value" << value <<
"kvtext" << kvtext;