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