1 #ifdef HAVE_CONFIG
2 #include "fsudace_config.h"
3 #endif
4 # ifdef HAVE_STD
5 # include <cstdlib>
6 # include <cmath>
7 # include <ctime>
8 # else
9 # include <stdlib.h>
10 # include <math.h>
11 # include <time.h>
12 # endif
13
14 # include <iostream>
15 # include <iomanip>
16 # include <fstream>
17
18 using namespace std;
19
20 # include "fsu.H"
21
22 int main ( void );
23
24 //*****************************************************************************
25
main(void)26 int main ( void )
27
28 //*****************************************************************************
29 //
30 // Purpose:
31 //
32 // FSU_CVT_STANDALONE computes a centroidal Voronoi Tessellation dataset.
33 //
34 // License:
35 //
36 // Copyright (C) 2004 John Burkardt and Max Gunzburger
37 //
38 // This library is free software; you can redistribute it and/or
39 // modify it under the terms of the GNU Lesser General Public
40 // License as published by the Free Software Foundation; either
41 // version 2.1 of the License, or (at your option) any later version.
42 //
43 // This library is distributed in the hope that it will be useful,
44 // but WITHOUT ANY WARRANTY; without even the implied warranty of
45 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
46 // Lesser General Public License for more details.
47 //
48 // You should have received a copy of the GNU Lesser General Public
49 // License along with this library; if not, write to the Free Software
50 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
51 //
52 // Discussion:
53 //
54 // This program is meant to be used interactively. It's also
55 // possible to prepare a simple input file beforehand and use it
56 // in batch mode.
57 //
58 // The program requests input values from the user:
59 //
60 // * NDIM, the spatial dimension,
61 // * N, the number of points to generate,
62 // * SEED, a seed to use for random number generation;
63 // * INIT, initialize the points:
64 // ** GRID, picking points from a grid;
65 // ** HALTON, from a Halton sequence;
66 // ** RANDOM, using C++ RANDOM function;
67 // ** UNIFORM, using a simple uniform RNG;
68 // * IT_MAX, the maximum number of iterations;
69 // * SAMPLE, how to conduct the sampling:
70 // ** GRID, picking points from a grid;
71 // ** HALTON, from a Halton sequence;
72 // ** RANDOM, using C++ RANDOM function;
73 // ** UNIFORM, using a simple uniform RNG;
74 // * SAMPLE_NUM, the number of sampling points;
75 // * BATCH, the number of sampling points to create at one time;
76 // * OUTPUT, a file in which to store the data;
77 //
78 // To indicate that no further computations are desired, it is
79 // enough to input a nonsensical value, such as -1.
80 //
81 // Modified:
82 //
83 // 04 October 2004
84 //
85 // Author:
86 //
87 // John Burkardt
88 //
89 // Reference:
90 //
91 // Qiang Du, Vance Faber, and Max Gunzburger,
92 // Centroidal Voronoi Tessellations: Applications and Algorithms,
93 // SIAM Review, Volume 41, 1999, pages 637-676.
94 //
95 {
96 int batch;
97 char file_out_name[80];
98 int i;
99 int init;
100 char init_string[80];
101 int it_num;
102 int it_max;
103 int n;
104 int ndim;
105 double *r;
106 bool reset;
107 int sample;
108 char sample_string[80];
109 int sample_num;
110 int seed;
111 int seed_init;
112 char *string;
113 bool success;
114 //
115 // Print introduction and options.
116 //
117 timestamp ( );
118
119 cout << "\n";
120 cout << "FSU_CVT_STANDALONE (C++ version)\n";
121 cout << " Generate a CVT dataset.\n";
122 cout << "\n";
123 cout << " Compiled on " << __DATE__ << " at " << __TIME__ << "\n";
124 cout << "\n";
125 cout << " This program is meant to be used interactively.\n";
126 cout << " It is also possible to prepare a simple input\n";
127 cout << " file beforehand and use it in batch mode.\n";
128 cout << "\n";
129 cout << " The program requests input values from the user:\n";
130 cout << "\n";
131 cout << " * NDIM, the spatial dimension,\n";
132 cout << " * N, the number of points to generate,\n";
133 cout << " * SEED, a seed to use for random number generation,\n";
134 cout << " * INIT, initialize the points:\n";
135 cout << " ** GRID, by picking points from a grid;\n";
136 cout << " ** HALTON, from a Halton sequence;\n";
137 cout << " ** RANDOM, using FORTRAN RANDOM function;\n";
138 cout << " ** UNIFORM, using a simple uniform RNG;\n";
139 cout << " * IT_MAX, the maximum number of iterations.\n";
140 cout << " * SAMPLE, how to conduct the sampling.\n";
141 cout << " ** GRID, by picking points from a grid;\n";
142 cout << " ** HALTON, from a Halton sequence;\n";
143 cout << " ** RANDOM, using FORTRAN RANDOM function;\n";
144 cout << " ** UNIFORM, using a simple uniform RNG;\n";
145 cout << " * SAMPLE_NUM, the number of sample points.\n";
146 cout << " * BATCH, the number of sample points to generate at one time.\n";
147 cout << " * OUTPUT, a file to store the data.\n";
148 cout << "\n";
149 cout << " To indicate that no further computations are\n";
150 cout << " desired, it is enough to input a nonsensical value,\n";
151 cout << " such as -1.\n";
152
153 for ( ; ; )
154 {
155 cout << " *\n";
156 cout << " *\n";
157 cout << "* Ready to generate a new dataset:\n";
158 cout << " *\n";
159 cout << " *\n";
160 cout << " Enter NDIM, the spatial dimension:\n";
161 cout << " (Try '2' if you don't have a preference.)\n";
162 cout << " (0 or any negative value terminates execution).\n";
163
164 cin >> ndim;
165
166 if ( cin.rdstate ( ) )
167 {
168 cin.clear ( );
169
170 cout << "\n";
171 cout << "FSU_CVT_STANDALONE - Fatal error!\n";
172 cout << " An I/O error occurred while trying to read NDIM.\n";
173 cout << " Abnormal end of execution.\n";
174 break;
175 }
176
177 cout << " User input NDIM = " << ndim << "\n";
178
179 if ( ndim < 1 )
180 {
181 cout << "\n";
182 cout << "FSU_CVT_STANDALONE\n";
183 cout << " The input value of NDIM = " << ndim << "\n";
184 cout << " is interpreted as a request for termination.\n";
185 cout << " Normal end of execution.\n";
186 break;
187 }
188
189 cout << "\n";
190 cout << " Enter N, the number of points to generate:\n";
191 cout << " (Try '25' if you don't have a preference.)\n";
192 cout << " (0 or any negative value terminates execution).\n";
193
194 cin >> n;
195
196 if ( cin.rdstate ( ) )
197 {
198 cin.clear ( );
199
200 cout << "\n";
201 cout << "FSU_CVT_STANDALONE - Fatal error!\n";
202 cout << " An I/O error occurred while trying to read N.\n";
203 cout << " Abnormal end of execution.\n";
204 break;
205 }
206
207 cout << " User input N = " << n << "\n";
208
209 if ( n < 1 )
210 {
211 cout << "\n";
212 cout << "FSU_CVT_STANDALONE\n";
213 cout << " The input value of N = " << n << "\n";
214 cout << " is interpreted as a request for termination.\n";
215 cout << " Normal end of execution.\n";
216 break;
217 }
218
219 cout << "\n";
220 cout << " Enter SEED, a seed for the random number generator:\n";
221 cout << " (Try '123456789' if you don't have a preference.)\n";
222 cout << " (Any negative value terminates execution).\n";
223
224 cin >> seed;
225
226 if ( cin.rdstate ( ) )
227 {
228 cin.clear ( );
229
230 cout << "\n";
231 cout << "FSU_CVT_STANDALONE - Fatal error!\n";
232 cout << " An I/O error occurred while trying to read SEED.\n";
233 cout << " Abnormal end of execution.\n";
234 break;
235 }
236
237 cout << " User input SEED = " << seed << "\n";
238
239 if ( seed < 0 )
240 {
241 cout << "\n";
242 cout << "FSU_CVT_STANDALONE\n";
243 cout << " The input value of SEED = " << seed << "\n";
244 cout << " is interpreted as a request for termination.\n";
245 cout << " Normal end of execution.\n";
246 break;
247 }
248
249 cout << "\n";
250 cout << " INIT is the method of initializing the data:\n";
251 cout << "\n";
252 cout << " GRID by picking points from a grid;\n";
253 cout << " HALTON from a Halton sequence;\n";
254 cout << " RANDOM using C++ RANDOM function;\n";
255 cout << " UNIFORM using a simple uniform RNG;\n";
256 cout << "\n";
257 cout << " (A blank value terminates execution).\n";
258 cout << " (Try 'RANDOM' if you don't have a preference.)\n";
259 cout << "\n";
260 cout << " Enter INIT:\n";
261 cin >> init_string;
262
263 if ( cin.rdstate ( ) )
264 {
265 cin.clear ( );
266
267 cout << "\n";
268 cout << "FSU_CVT_STANDALONE - Fatal error!\n";
269 cout << " An I/O error occurred while trying to read INIT.\n";
270 cout << " Abnormal end of execution.\n";
271 break;
272 }
273
274 cout << " User input INIT = \"" << init_string << "\".\n";
275
276 if ( s_eqi ( init_string, "RANDOM" ) )
277 {
278 init = -1;
279 }
280 else if ( s_eqi ( init_string, "UNIFORM" ) )
281 {
282 init = 0;
283 }
284 else if ( s_eqi ( init_string, "HALTON" ) )
285 {
286 init = 1;
287 }
288 else if ( s_eqi ( init_string, "GRID" ) )
289 {
290 init = 2;
291 }
292 else
293 {
294 cout << "\n";
295 cout << "FSU_CVT_STANDALONE\n";
296 cout << " The input value of INIT\n";
297 cout << " is interpreted as a request for termination.\n";
298 cout << " Normal end of execution.\n";
299 break;
300 }
301
302 cout << "\n";
303 cout << " IT_MAX is the maximum number of iterations.\n";
304 cout << "\n";
305 cout << " An iteration carries out the following steps:\n";
306 cout << " * the Voronoi region associated with each\n";
307 cout << " generator is estimated by sampling;\n";
308 cout << " * the centroid of each Voronoi region is estimated.\n";
309 cout << " * the generator is replaced by the centroid.\n";
310 cout << "\n";
311 cout << " If \"enough\" sampling points are used,\n";
312 cout << " and \"enough\" iterations are taken, this process\n";
313 cout << " will converge.\n";
314 cout << "\n";
315 cout << " (Try '50' if you don't have a preference.)\n";
316 cout << " (A negative value terminates execution).\n";
317 cout << "\n";
318 cout << " Enter IT_MAX:\n";
319 cin >> it_max;
320
321 if ( cin.rdstate ( ) )
322 {
323 cin.clear ( );
324
325 cout << "\n";
326 cout << "FSU_CVT_STANDALONE - Fatal error!\n";
327 cout << " An I/O error occurred while trying to read IT_MAX.\n";
328 cout << " Abnormal end of execution.\n";
329 break;
330 }
331
332 cout << " User input IT_MAX = " << it_max << "\n";
333
334 if ( it_max < 0 )
335 {
336 cout << "\n";
337 cout << "FSU_CVT_STANDALONE\n";
338 cout << " The input value of IT_MAX = " << it_max << "\n";
339 cout << " is interpreted as a request for termination.\n";
340 cout << " Normal end of execution.\n";
341 break;
342 }
343
344 cout << "\n";
345 cout << " SAMPLE is the method of sampling the region:\n";
346 cout << "\n";
347 cout << " GRID by picking points from a grid;\n";
348 cout << " HALTON from a Halton sequence;\n";
349 cout << " RANDOM using C++ RANDOM function;\n";
350 cout << " UNIFORM using a simple uniform RNG;\n";
351 cout << "\n";
352 cout << " (Try 'RANDOM' if you don't have a preference.)\n";
353 cout << " (A blank value terminates execution).\n";
354 cout << "\n";
355 cout << " Enter SAMPLE:\n";
356 cin >> sample_string;
357
358 if ( cin.rdstate ( ) )
359 {
360 cin.clear ( );
361
362 cout << "\n";
363 cout << "FSU_CVT_STANDALONE - Fatal error!\n";
364 cout << " An I/O error occurred while trying to read SAMPLE.\n";
365 cout << " Abnormal end of execution.\n";
366 break;
367 }
368
369 cout << " User input SAMPLE = \"" << sample_string << "\".\n";
370
371 if ( s_eqi ( sample_string, "RANDOM" ) )
372 {
373 sample = -1;
374 }
375 else if ( s_eqi ( sample_string, "UNIFORM" ) )
376 {
377 sample = 0;
378 }
379 else if ( s_eqi ( sample_string, "HALTON" ) )
380 {
381 sample = 1;
382 }
383 else if ( s_eqi ( sample_string, "GRID" ) )
384 {
385 sample = 2;
386 }
387 else
388 {
389 cout << "\n";
390 cout << "FSU_CVT_STANDALONE\n";
391 cout << " The input value of SAMPLE\n";
392 cout << " is interpreted as a request for termination.\n";
393 cout << " Normal end of execution.\n";
394 break;
395 }
396
397 cout << "\n";
398 cout << " SAMPLE_NUM is the number of sample points.\n";
399 cout << "\n";
400 cout << " The Voronoi regions will be explored by generating\n";
401 cout << " SAMPLE_NUM points. For each sample point, the\n";
402 cout << " nearest generator is found. Using more points\n";
403 cout << " gives a better estimate of these regions.\n";
404 cout << "\n";
405 cout << " SAMPLE_NUM should be much larger than N, the\n";
406 cout << " number of generators.\n";
407 cout << "\n";
408 cout << " (Try '10000' if you don't have a preference.)\n";
409 cout << " (A zero or negative value terminates execution.)\n";
410 cout << "\n";
411 cout << " Enter SAMPLE_NUM:\n";
412
413 cin >> sample_num;
414
415 if ( cin.rdstate ( ) )
416 {
417 cin.clear ( );
418
419 cout << "\n";
420 cout << "FSU_CVT_STANDALONE - Fatal error!\n";
421 cout << " An I/O error occurred while trying to read SAMPLE_NUM.\n";
422 cout << " Abnormal end of execution.\n";
423 break;
424 }
425
426 cout << " User input SAMPLE_NUM = " << sample_num << "\n";
427
428 if ( sample_num <= 0 )
429 {
430 cout << "\n";
431 cout << "FSU_CVT_STANDALONE\n";
432 cout << " The input value of SAMPLE_NUM = " << sample_num << "\n";
433 cout << " is interpreted as a request for termination.\n";
434 cout << " Normal end of execution.\n";
435 break;
436 }
437 cout << "\n";
438 cout << " BATCH is the number of sample points to create at one time.\n";
439 cout << "\n";
440 cout << " BATCH should be between 1 and SAMPLE_NUM.\n";
441 cout << "\n";
442 cout << " It is FASTER to set BATCH to SAMPLE_NUM;\n";
443 cout << " setting BATCH to 1 requires the least memory.\n";
444 cout << "\n";
445 cout << " (Try '" << sample_num << "' if you don't have a preference.)\n";
446 cout << " (A zero or negative value terminates execution.)\n";
447 cout << "\n";
448 cout << " Enter BATCH:\n";
449
450 cin >> batch;
451
452 if ( cin.rdstate ( ) )
453 {
454 cin.clear ( );
455
456 cout << "\n";
457 cout << "FSU_CVT_STANDALONE - Fatal error!\n";
458 cout << " An I/O error occurred while trying to read BATCH.\n";
459 cout << " Abnormal end of execution.\n";
460 break;
461 }
462
463 cout << " User input BATCH = " << batch << "\n";
464
465 if ( batch <= 0 )
466 {
467 cout << "\n";
468 cout << "FSU_CVT_STANDALONE\n";
469 cout << " The input value of BATCH = " << batch << "\n";
470 cout << " is interpreted as a request for termination.\n";
471 cout << " Normal end of execution.\n";
472 break;
473 }
474
475 cout << "\n";
476 cout << " OUTPUT is a file in which to store the data.\n";
477 cout << "\n";
478 cout << " (Try 'cvt.txt' if you don't have a preference.)\n";
479 cout << " (A blank value terminates execution).\n";
480 cout << "\n";
481 cout << " Enter OUTPUT:\n";
482 cin >> file_out_name;
483
484 if ( cin.rdstate ( ) )
485 {
486 cin.clear ( );
487
488 cout << "\n";
489 cout << "FSU_CVT_STANDALONE - Fatal error!\n";
490 cout << " An I/O error occurred while trying to read OUTPUT.\n";
491 cout << " Abnormal end of execution.\n";
492 break;
493 }
494
495 cout << " User input OUTPUT = \"" << file_out_name << "\".\n";
496
497 if ( s_len_trim ( file_out_name ) <= 0 )
498 {
499 cout << "\n";
500 cout << "FSU_CVT_STANDALONE\n";
501 cout << " The input value of OUTPUT\n";
502 cout << " is interpreted as a request for termination.\n";
503 cout << " Normal end of execution.\n";
504 break;
505 }
506 //
507 // Initialize the data.
508 //
509 r = new double[ndim*n];
510
511 seed_init = seed;
512
513 fsu_cvt ( ndim, n, batch, init, sample, sample_num, it_max,
514 &seed, r, &it_num );
515
516 cvt_write ( ndim, n, batch, seed_init, seed, init_string, it_max,
517 it_num, sample_string, sample_num, r, file_out_name );
518
519 delete [] r;
520
521 cout << "\n";
522 cout << " The data was written to the file \"" << file_out_name << "\"\n";
523 }
524
525 cout << "\n";
526 timestamp ( );
527
528 return 0;
529 }
530