00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <math.h>
00017
00018 #include "CTB.hxx"
00019 #include "CTBveri.hxx"
00020
00021 #include "CTBsystem.hxx"
00022 #include "CTBprintf.hxx"
00023
00040
00042
00043 CTBveri::CTBveri()
00044 : mi_nalloc(0),
00045 mp_vp(0),
00046 mc_text(0),
00047 mb_active(0),
00048 mi_verbosity(0)
00049 {
00050 RandomSeed(0);
00051 }
00052
00053
00055
00056 CTBveri::~CTBveri()
00057 {
00058 delete mp_vp;
00059 delete mc_text;
00060 delete mb_active;
00061 }
00062
00063
00065
00071 void CTBveri::Register(CTBint i_ind, pveriproc_t p_vp, const char* c_text)
00072 {
00073 if (i_ind <= 0) return;
00074
00075 if (i_ind >= mi_nalloc-1) {
00076
00077 if (mi_nalloc == 0) {
00078 mi_nalloc = 4;
00079 if (mi_nalloc <= i_ind) mi_nalloc = i_ind + 1;
00080 mp_vp = new pveriproc_t [mi_nalloc];
00081 mc_text = new const char* [mi_nalloc];
00082 for (CTBint i = 0; i < mi_nalloc; i++) {
00083 mp_vp[i] = 0;
00084 mc_text[i] = 0;
00085 }
00086
00087 } else {
00088 pveriproc_t* p_vp_old = mp_vp;
00089 const char** c_text_old = mc_text;
00090 CTBint i_nalloc_old = mi_nalloc;
00091
00092 mi_nalloc *= 2;
00093 if (mi_nalloc <= i_ind) mi_nalloc = i_ind + 1;
00094 mp_vp = new pveriproc_t [mi_nalloc];
00095 mc_text = new const char* [mi_nalloc];
00096
00097 for (CTBint i = 0; i < i_nalloc_old; i++) {
00098 mp_vp[i] = p_vp_old[i];
00099 mc_text[i] = c_text_old[i];
00100 }
00101
00102 for (CTBint i = i_nalloc_old; i < mi_nalloc; i++) {
00103 mp_vp[i] = 0;
00104 mc_text[i] = 0;
00105 }
00106
00107 delete p_vp_old;
00108 delete c_text_old;
00109 }
00110 }
00111
00112 mp_vp[i_ind] = p_vp;
00113 mc_text[i_ind] = c_text;
00114
00115 return;
00116 }
00117
00118
00120
00136 int CTBveri::Exec(int argc, char *argv[])
00137 {
00138 int i_rc = 0;
00139 bool b_help = false;
00140 bool b_all = true;
00141
00142 if (mi_nalloc > 0) {
00143 mb_active = new bool [mi_nalloc];
00144 for (CTBint i = 0; i < mi_nalloc; i++) mb_active[i] = true;
00145 }
00146
00147 for (CTBint i = 1; i < argc; i++) {
00148
00149 if (argv[i][0] == '-') {
00150 if (strcmp(argv[i],"-?") == 0) b_help = true;
00151 if (strcmp(argv[i],"-v") == 0 && mi_verbosity < 1) mi_verbosity = 1;
00152 if (strcmp(argv[i],"-v1") == 0 && mi_verbosity < 1) mi_verbosity = 1;
00153 if (strcmp(argv[i],"-v2") == 0 && mi_verbosity < 2) mi_verbosity = 2;
00154 if (strcmp(argv[i],"-v3") == 0 && mi_verbosity < 3) mi_verbosity = 3;
00155 if (strcmp(argv[i],"-v4") == 0 && mi_verbosity < 4) mi_verbosity = 4;
00156
00157 } else {
00158 char* c_end;
00159 CTBint i_ind_b = strtol(argv[i],&c_end,10);
00160 CTBint i_ind_e = i_ind_b;
00161 if (c_end && c_end[0]) {
00162 if (c_end[0] == ':') {
00163 i_ind_e = strtol(c_end+1,&c_end,10);
00164 if (c_end && c_end[0]) {
00165 cerr << "conversion error in \"" << argv[i] << "\"" << endl;
00166 return 1;
00167 }
00168 } else {
00169 cerr << "conversion error in \"" << argv[i] << "\"" << endl;
00170 return 1;
00171 }
00172 }
00173
00174 if (i_ind_b < 1) i_ind_b = 1;
00175 if (i_ind_e < 1) i_ind_e = 1;
00176 if (i_ind_b >= mi_nalloc) i_ind_b = mi_nalloc-1;
00177 if (i_ind_e >= mi_nalloc) i_ind_e = mi_nalloc-1;
00178
00179 if (b_all) {
00180 b_all = false;
00181 for (CTBint j = 1; j < mi_nalloc; j++) mb_active[j] = false;
00182 }
00183
00184 for (CTBint j = i_ind_b; j <= i_ind_e; j++) mb_active[j] = true;
00185 }
00186 }
00187
00188 if (!b_all) {
00189 bool b_select = false;
00190 for (CTBint i = 1; i < mi_nalloc; i++) {
00191 b_select |= (mb_active[i] && mp_vp[i]);
00192 }
00193 if (!b_select) {
00194 cerr << "No tests selected" << endl;
00195 }
00196 }
00197
00198 if (b_help) {
00199 for (CTBint i = 1; i < mi_nalloc; i++) {
00200 if (mp_vp[i]) {
00201 cout << "Test ";
00202 cout << setw(2) << i;
00203 if (mc_text[i]) cout << " : " << mc_text[i];
00204 cout << endl;
00205 }
00206 }
00207 return 0;
00208 }
00209
00210 for (CTBint i = 1; i < mi_nalloc; i++) {
00211 if (mb_active[i] && mp_vp[i]) {
00212 bool b_ok;
00213
00214 cout << "Test " << i;
00215 if (mc_text[i]) cout << " : " << mc_text[i];
00216 cout << endl;
00217
00218 RandomSeed(47110815);
00219
00220 b_ok = (*mp_vp[i])(*this);
00221
00222 if (!b_ok) {
00223 cout << " === FAILED ===" << endl;
00224 i_rc = 1;
00225 }
00226 }
00227 }
00228
00229 return i_rc;
00230 }
00231
00232
00234
00245 bool CTBveri::Verbosity(int i_level) const
00246 {
00247 return mi_verbosity >= i_level;
00248 }
00249
00250
00252
00264 CTBuint32 CTBveri::RandomInt()
00265 {
00266 CTBuint32 i_ran = mi_sz + mi_sn;
00267 CTBuint32 i_s = mi_sx + mi_sc;
00268
00269 if (mi_sy > i_s) {
00270 i_s = mi_sy - i_s;
00271 mi_sc = 0;
00272 } else {
00273 i_s = mi_sy - i_s - 18;
00274 mi_sc = 1;
00275 }
00276 mi_sx = mi_sy;
00277 mi_sy = mi_sz;
00278 mi_sz = i_s;
00279 mi_sn = 69069 * mi_sn + 1013904243;
00280
00281 return i_ran;
00282 }
00283
00284
00286
00290 double CTBveri::Random()
00291 {
00292 return ((double)RandomInt())/(4294967296.);
00293 }
00294
00295
00297
00301 CTBint CTBveri::RandomInt(CTBint i_high)
00302 {
00303 double d_r = (double) i_high * Random();
00304 CTBint i_r = (CTBint) d_r;
00305
00306 if (i_r >= i_high) i_r = i_high-1;
00307 return i_r;
00308 }
00309
00310
00312
00316 CTBint CTBveri::RandomInt(CTBint i_low, CTBint i_high)
00317 {
00318 double d_r = (double (i_high-i_low)) * Random();
00319 CTBint i_r = i_low + (CTBint) d_r;
00320
00321 if (i_r >= i_high) i_r = i_high-1;
00322 return i_r;
00323 }
00324
00325
00327
00332 CTBint CTBveri::RandomInt1X(CTBint i_low, CTBint i_high)
00333 {
00334 double d_log_l;
00335 double d_log_h;
00336 CTBint i_r;
00337
00338 if (i_low <= 0 || i_high <= 0) return 0;
00339
00340 d_log_l = log((double) i_low);
00341 d_log_h = log((double) i_high);
00342
00343 i_r = (CTBint) exp(d_log_l + (d_log_h-d_log_l) * Random());
00344
00345 if (i_r >= i_high) i_r = i_high-1;
00346 return i_r;
00347 }
00348
00349
00351
00352 double CTBveri::Random(double d_low, double d_high)
00353 {
00354 return d_low + (d_high-d_low) * Random();
00355 }
00356
00357
00359
00362 bool CTBveri::RandomBool(double d_prob)
00363 {
00364 return Random() <= d_prob;
00365 }
00366
00367
00369
00373 void CTBveri::RandomVector(CTBint i_ran[], CTBint i_size, CTBint i_high)
00374 {
00375 for (CTBint i = 0; i < i_size; i++) i_ran[i] = RandomInt(i_high);
00376 return;
00377 }
00378
00379
00381
00385 void CTBveri::RandomVector(CTBint i_ran[], CTBint i_size,
00386 CTBint i_low, CTBint i_high)
00387 {
00388 for (CTBint i = 0; i < i_size; i++) i_ran[i] = RandomInt(i_low,i_high);
00389 return;
00390 }
00391
00392
00394
00398 void CTBveri::RandomVector(bool b_ran[], CTBint i_size, double d_prob)
00399 {
00400 for (CTBint i = 0; i < i_size; i++) b_ran[i] = RandomBool(d_prob);
00401 return;
00402 }
00403
00404
00406
00410 void CTBveri::RandomPermutation(CTBint i_perm[], CTBint i_size)
00411 {
00412 for (CTBint i = 0; i < i_size; i++) i_perm[i] = i;
00413
00414 for (CTBint i = 0; i < i_size-1; i++) {
00415 CTBint i_ind = i + RandomInt(i_size-1-i);
00416 CTBint i_temp = i_perm[i];
00417 i_perm[i] = i_perm[i_ind];
00418 i_perm[i_ind] = i_temp;
00419 }
00420
00421 return;
00422 }
00423
00424
00425
00426
00427
00428
00429
00430 CTBuint32 cong32b(CTBuint32& i_seed)
00431 {
00432 CTBuint32 i_ran = 0;
00433 CTBuint32 i_s = i_seed;
00434
00435 for (int i_b = 32; i_b > 0; i_b--) {
00436 i_ran = (i_ran >> 1) | (i_s & 0x80000000);
00437 i_s = 69069 * i_s + 1013904243;
00438 }
00439
00440 i_seed = i_s;
00441 return i_ran;
00442 }
00443
00444
00445 void CTBveri::RandomSeed(CTBuint32 i_seed)
00446 {
00447 mi_seed = i_seed;
00448
00449 mi_sn = mi_seed;
00450 mi_sx = cong32b(mi_sn);
00451 mi_sy = cong32b(mi_sn);
00452 mi_sz = cong32b(mi_sn);
00453 if (mi_sx > 4294967277u) mi_sx = 4294967277u;
00454 if (mi_sy > 4294967277u) mi_sy = 4294967277u;
00455 if (mi_sz > 4294967277u) mi_sz = 4294967277u;
00456 mi_sc = mi_sy > mi_sz;
00457
00458
00459 return;
00460 }
00461
00462
00463 #if (defined(CTB__OutLine) || defined(CTBveri__OutLine))
00464 #define inline
00465
00466 #undef inline
00467 #endif