NeoPZ
rcm.cpp
Go to the documentation of this file.
1 # include <cstdlib>
2 # include <iostream>
3 # include <iomanip>
4 # include <fstream>
5 # include <cmath>
6 # include <ctime>
7 # include <string>
8 
9 using namespace std;
10 
11 # include "rcm.h"
12 
13 #ifdef WIN32
14 #include <minmax.h>
15 #endif
16 
17 //****************************************************************************80
18 
19 int adj_bandwidth ( int node_num, int adj_num, int adj_row[], int adj[] )
20 
21 //****************************************************************************80
22 //
23 // Purpose:
24 //
25 // ADJ_BANDWIDTH computes the bandwidth of an adjacency matrix.
26 //
27 // Discussion:
28 //
29 // Thanks to Man Yuan, of Southeast University, China, for pointing out
30 // an inconsistency in the indexing of ADJ_ROW, 06 June 2011.
31 //
32 // Licensing:
33 //
34 // This code is distributed under the GNU LGPL license.
35 //
36 // Modified:
37 //
38 // 06 June 2011
39 //
40 // Author:
41 //
42 // John Burkardt
43 //
44 // Reference:
45 //
46 // Alan George, Joseph Liu,
47 // Computer Solution of Large Sparse Positive Definite Systems,
48 // Prentice Hall, 1981.
49 //
50 // Parameters:
51 //
52 // Input, int NODE_NUM, the number of nodes.
53 //
54 // Input, int ADJ_NUM, the number of adjacency entries.
55 //
56 // Input, int ADJ_ROW[NODE_NUM+1]. Information about row I is stored
57 // in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
58 //
59 // Input, int ADJ[ADJ_NUM], the adjacency structure.
60 // For each row, it contains the column indices of the nonzero entries.
61 //
62 // Output, int ADJ_BANDWIDTH, the bandwidth of the adjacency
63 // matrix.
64 //
65 {
66  int band_hi;
67  int band_lo;
68  int col;
69  int i;
70  int j;
71  int value;
72 
73  band_lo = 0;
74  band_hi = 0;
75 
76  for ( i = 0; i < node_num; i++ )
77  {
78  for ( j = adj_row[i]; j <= adj_row[i+1]-1; j++ )
79  {
80  col = adj[j-1] - 1;
81  band_lo = i4_max ( band_lo, i - col );
82  band_hi = i4_max ( band_hi, col - i );
83  }
84  }
85 
86  value = band_lo + 1 + band_hi;
87 
88  return value;
89 }
90 //****************************************************************************80
91 
92 bool adj_contains_ij ( int node_num, int adj_num, int adj_row[], int adj[],
93  int i, int j )
94 
95 //****************************************************************************80
96 //
97 // Purpose:
98 //
99 // ADJ_CONTAINS_IJ determines if (I,J) is in an adjacency structure.
100 //
101 // Licensing:
102 //
103 // This code is distributed under the GNU LGPL license.
104 //
105 // Modified:
106 //
107 // 03 January 2007
108 //
109 // Author:
110 //
111 // John Burkardt
112 //
113 // Parameters:
114 //
115 // Input, int NODE_NUM, the number of nodes.
116 //
117 // Input, int ADJ_NUM, the number of adjacency entries.
118 //
119 // Input, int ADJ_ROW[NODE_NUM+1]. Information about row I is stored
120 // in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
121 //
122 // Input, int ADJ[ADJ_NUM], the adjacency structure.
123 //
124 // Input, int I, J, the two nodes, for which we want to know
125 // whether I is adjacent to J.
126 //
127 // Output, bool ADJ_CONTAINS_IJ, is TRUE if I = J, or the adjacency
128 // structure contains the information that I is adjacent to J.
129 //
130 {
131  int k;
132  int khi;
133  int klo;
134  bool value;
135 //
136 // Symmetric entries are not stored.
137 //
138  if ( i == j )
139  {
140  value = true;
141  return value;
142  }
143 //
144 // Illegal I, J entries.
145 //
146  if ( node_num < i )
147  {
148  value = false;
149  return value;
150  }
151  else if ( i < 1 )
152  {
153  value = false;
154  return value;
155  }
156  else if ( node_num < j )
157  {
158  value = false;
159  return value;
160  }
161  else if ( j < 1 )
162  {
163  value = false;
164  return value;
165  }
166 //
167 // Search the adjacency entries already stored for row I,
168 // to see if J has already been stored.
169 //
170  klo = adj_row[i-1];
171  khi = adj_row[i]-1;
172 
173  for ( k = klo; k <= khi; k++ )
174  {
175  if ( adj[k-1] == j )
176  {
177  value = true;
178  return value;
179  }
180  }
181  value = false;
182 
183  return value;
184 }
185 //****************************************************************************80
186 
187 void adj_insert_ij ( int node_num, int adj_max, int *adj_num, int adj_row[],
188  int adj[], int i, int j )
189 
190 //****************************************************************************80
191 //
192 // Purpose:
193 //
194 // ADJ_INSERT_IJ inserts (I,J) into an adjacency structure.
195 //
196 // Licensing:
197 //
198 // This code is distributed under the GNU LGPL license.
199 //
200 // Modified:
201 //
202 // 04 January 2007
203 //
204 // Author:
205 //
206 // John Burkardt
207 //
208 // Parameters:
209 //
210 // Input, int NODE_NUM, the number of nodes.
211 //
212 // Input, int ADJ_MAX, the maximum number of adjacency entries.
213 //
214 // Input/output, int ADJ_NUM, the number of adjacency entries.
215 //
216 // Input/output, int ADJ_ROW[NODE_NUM+1]. Information about row I is stored
217 // in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
218 //
219 // Input/output, int ADJ[ADJ_NUM], the adjacency structure.
220 //
221 // Input, int I, J, the two nodes which are adjacent.
222 //
223 {
224  int j_spot;
225  int k;
226 //
227 // A new adjacency entry must be made.
228 // Check that we're not exceeding the storage allocation for ADJ.
229 //
230  if ( adj_max < *adj_num + 1 )
231  {
232  cout << "\n";
233  cout << "ADJ_INSERT_IJ - Fatal error!\n";
234  cout << " All available storage has been used.\n";
235  cout << " No more information can be stored!\n";
236  cout << " This error occurred for \n";
237  cout << " Row I = " << i << "\n";
238  cout << " Column J = " << j << "\n";
239  exit ( 1 );
240  }
241 //
242 // The action is going to occur between ADJ_ROW(I) and ADJ_ROW(I+1)-1:
243 //
244  j_spot = adj_row[i-1];
245 
246  for ( k = adj_row[i-1]; k <= adj_row[i]-1; k++ )
247  {
248  if ( adj[k-1] == j )
249  {
250  return;
251  }
252  else if ( adj[k-1] < j )
253  {
254  j_spot = k + 1;
255  }
256  else
257  {
258  break;
259  }
260  }
261 
262  for ( k = *adj_num; j_spot <= k; k-- )
263  {
264  adj[k] = adj[k-1];
265  }
266  adj[j_spot-1] = j;
267 
268  for ( k = i; k <= node_num; k++ )
269  {
270  adj_row[k] = adj_row[k] + 1;
271  }
272 
273  *adj_num = *adj_num + 1;
274 
275  return;
276 }
277 //****************************************************************************80
278 
279 int adj_perm_bandwidth ( int node_num, int adj_num, int adj_row[], int adj[],
280  int perm[], int perm_inv[] )
281 
282 //****************************************************************************80
283 //
284 // Purpose:
285 //
286 // ADJ_PERM_BANDWIDTH computes the bandwidth of a permuted adjacency matrix.
287 //
288 // Discussion:
289 //
290 // The matrix is defined by the adjacency information and a permutation.
291 //
292 // The routine also computes the bandwidth and the size of the envelope.
293 //
294 // Licensing:
295 //
296 // This code is distributed under the GNU LGPL license.
297 //
298 // Modified:
299 //
300 // 05 January 2007
301 //
302 // Author:
303 //
304 // John Burkardt
305 //
306 // Reference:
307 //
308 // Alan George, Joseph Liu,
309 // Computer Solution of Large Sparse Positive Definite Systems,
310 // Prentice Hall, 1981.
311 //
312 // Parameters:
313 //
314 // Input, int NODE_NUM, the number of nodes.
315 //
316 // Input, int ADJ_NUM, the number of adjacency entries.
317 //
318 // Input, int ADJ_ROW[NODE_NUM+1]. Information about row I is stored
319 // in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
320 //
321 // Input, int ADJ[ADJ_NUM], the adjacency structure.
322 // For each row, it contains the column indices of the nonzero entries.
323 //
324 // Input, int PERM[NODE_NUM], PERM_INV(NODE_NUM), the permutation
325 // and inverse permutation.
326 //
327 // Output, int ADJ_PERM_BANDWIDTH, the bandwidth of the permuted
328 // adjacency matrix.
329 //
330 {
331  int band_hi;
332  int band_lo;
333  int bandwidth;
334  int col;
335  int i;
336  int j;
337 
338  band_lo = 0;
339  band_hi = 0;
340 
341  for ( i = 0; i < node_num; i++ )
342  {
343  for ( j = adj_row[perm[i]-1]; j <= adj_row[perm[i]]-1; j++ )
344  {
345  col = perm_inv[adj[j-1]-1];
346  band_lo = i4_max ( band_lo, i - col );
347  band_hi = i4_max ( band_hi, col - i );
348  }
349  }
350 
351  bandwidth = band_lo + 1 + band_hi;
352 
353  return bandwidth;
354 }
355 //****************************************************************************80
356 
357 void adj_perm_show ( int node_num, int adj_num, int adj_row[], int adj[],
358  int perm[], int perm_inv[] )
359 
360 //****************************************************************************80
361 //
362 // Purpose:
363 //
364 // ADJ_PERM_SHOW displays a symbolic picture of a permuted adjacency matrix.
365 //
366 // Discussion:
367 //
368 // The matrix is defined by the adjacency information and a permutation.
369 //
370 // The routine also computes the bandwidth and the size of the envelope.
371 //
372 // If no permutation has been done, you must set PERM(I) = PERM_INV(I) = I
373 // before calling this routine.
374 //
375 // Licensing:
376 //
377 // This code is distributed under the GNU LGPL license.
378 //
379 // Modified:
380 //
381 // 07 January 2007
382 //
383 // Author:
384 //
385 // John Burkardt
386 //
387 // Reference:
388 //
389 // Alan George, Joseph Liu,
390 // Computer Solution of Large Sparse Positive Definite Systems,
391 // Prentice Hall, 1981.
392 //
393 // Parameters:
394 //
395 // Input, int NODE_NUM, the number of nodes.
396 //
397 // Input, int ADJ_NUM, the number of adjacency entries.
398 //
399 // Input, int ADJ_ROW[NODE_NUM+1]. Information about row I is stored
400 // in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
401 //
402 // Input, int ADJ[ADJ_NUM], the adjacency structure.
403 // For each row, it contains the column indices of the nonzero entries.
404 //
405 // Input, int PERM[NODE_NUM], PERM_INV[NODE_NUM], the permutation
406 // and inverse permutation.
407 //
408 {
409  char *band;
410  int band_lo;
411  int col;
412  int i;
413  int j;
414  int k;
415  int nonzero_num;
416 
417  band = new char[node_num];
418 
419  band_lo = 0;
420  nonzero_num = 0;
421 
422  cout << "\n";
423  cout << " Nonzero structure of matrix:\n";
424  cout << "\n";
425 
426  for ( i = 0; i < node_num; i++ )
427  {
428  for ( k = 0; k < node_num; k++ )
429  {
430  band[k] = '.';
431  }
432 
433  band[i] = 'D';
434 
435  for ( j = adj_row[perm[i]-1]; j <= adj_row[perm[i]]-1; j++ )
436  {
437  col = perm_inv[adj[j-1]-1] - 1;
438 
439  if ( col < i )
440  {
441  nonzero_num = nonzero_num + 1;
442  }
443 
444  band_lo = i4_max ( band_lo, i - col );
445 
446  if ( col != i )
447  {
448  band[col] = 'X';
449  }
450  }
451  cout << " " << setw(8) << i + 1 << " ";
452  for ( j = 0; j < node_num; j++ )
453  {
454  cout << band[j];
455  }
456  cout << "\n";
457  }
458 
459  cout << "\n";
460  cout << " Lower bandwidth = " << band_lo << "\n";
461  cout << " Lower envelope contains " << nonzero_num << " nonzeros.\n";
462 
463 
464  return;
465 }
466 //****************************************************************************80
467 
468 void adj_print ( int node_num, int adj_num, int adj_row[], int adj[],
469  string title )
470 
471 //****************************************************************************80
472 //
473 // Purpose:
474 //
475 // ADJ_PRINT prints adjacency information.
476 //
477 // Discussion:
478 //
479 // The list has the form:
480 //
481 // Row Nonzeros
482 //
483 // 1 2 5 9
484 // 2 7 8 9 15 78 79 81 86 91 99
485 // 100 103
486 // 3 48 49 53
487 //
488 // Licensing:
489 //
490 // This code is distributed under the GNU LGPL license.
491 //
492 // Modified:
493 //
494 // 18 December 2002
495 //
496 // Author:
497 //
498 // John Burkardt
499 //
500 // Parameters:
501 //
502 // Input, int NODE_NUM, the number of nodes.
503 //
504 // Input, int ADJ_NUM, the number of adjacency entries.
505 //
506 // Input, int ADJ_ROW[NODE_NUM+1], organizes the adjacency entries
507 // into rows. The entries for row I are in entries ADJ_ROW(I)
508 // through ADJ_ROW(I+1)-1.
509 //
510 // Input, int ADJ[ADJ_NUM], the adjacency structure, which contains,
511 // for each row, the column indices of the nonzero entries.
512 //
513 // Input, string TITLE, a title to be printed.
514 //
515 {
516  adj_print_some ( node_num, 1, node_num, adj_num, adj_row, adj, title );
517 
518  return;
519 }
520 //****************************************************************************80
521 
522 void adj_print_some ( int node_num, int node_lo, int node_hi, int adj_num,
523  int adj_row[], int adj[], string title )
524 
525 //****************************************************************************80
526 //
527 // Purpose:
528 //
529 // ADJ_PRINT_SOME prints some adjacency information.
530 //
531 // Discussion:
532 //
533 // The list has the form:
534 //
535 // Row Nonzeros
536 //
537 // 1 2 5 9
538 // 2 7 8 9 15 78 79 81 86 91 99
539 // 100 103
540 // 3 48 49 53
541 //
542 // Licensing:
543 //
544 // This code is distributed under the GNU LGPL license.
545 //
546 // Modified:
547 //
548 // 04 January 2007
549 //
550 // Author:
551 //
552 // John Burkardt
553 //
554 // Parameters:
555 //
556 // Input, int NODE_NUM, the number of nodes.
557 //
558 // Input, int NODE_LO, NODE_HI, the first and last nodes for
559 // which the adjacency information is to be printed.
560 //
561 // Input, int ADJ_NUM, the number of adjacency entries.
562 //
563 // Input, int ADJ_ROW[NODE_NUM+1], organizes the adjacency entries
564 // into rows. The entries for row I are in entries ADJ_ROW(I)
565 // through ADJ_ROW(I+1)-1.
566 //
567 // Input, int ADJ[ADJ_NUM], the adjacency structure, which contains,
568 // for each row, the column indices of the nonzero entries.
569 //
570 // Input, string TITLE, a title.
571 //
572 {
573  int i;
574  int j;
575  int jhi;
576  int jlo;
577  int jmax;
578  int jmin;
579 
580  cout << "\n";
581  cout << title << "\n";
582  cout << "\n";
583  cout << " Sparse adjacency structure:\n";
584  cout << "\n";
585  cout << " Number of nodes = " << node_num << "\n";
586  cout << " Number of adjacencies = " << adj_num << "\n";
587  cout << "\n";
588  cout << " Node Min Max Nonzeros \n";
589  cout << "\n";
590 
591  for ( i = node_lo; i <= node_hi; i++ )
592  {
593  jmin = adj_row[i-1];
594  jmax = adj_row[i] - 1;
595 
596  if ( jmax < jmin )
597  {
598  cout << " " << setw(4) << i
599  << " " << setw(4) << jmin
600  << " " << setw(4) << jmax << "\n";
601  }
602  else
603  {
604  for ( jlo = jmin; jlo <= jmax; jlo = jlo + 5 )
605  {
606  jhi = i4_min ( jlo + 4, jmax );
607 
608  if ( jlo == jmin )
609  {
610  cout << " " << setw(4) << i
611  << " " << setw(4) << jmin
612  << " " << setw(4) << jmax
613  << " ";
614  for ( j = jlo; j <= jhi; j++ )
615  {
616  cout << setw(8) << adj[j-1];
617  }
618  cout << "\n";
619  }
620  else
621  {
622  cout << " ";
623  for ( j = jlo; j <= jhi; j++ )
624  {
625  cout << setw(8) << adj[j-1];
626  }
627  cout << "\n";
628  }
629  }
630  }
631  }
632 
633  return;
634 }
635 //****************************************************************************80
636 
637 void adj_set ( int node_num, int adj_max, int *adj_num, int adj_row[],
638  int adj[], int irow, int jcol )
639 
640 //****************************************************************************80
641 //
642 // Purpose:
643 //
644 // ADJ_SET sets up the adjacency information.
645 //
646 // Discussion:
647 //
648 // The routine records the locations of each nonzero element,
649 // one at a time.
650 //
651 // The first call for a given problem should be with IROW or ICOL
652 // negative. This is a signal indicating the data structure should
653 // be initialized.
654 //
655 // Then, for each case in which A(IROW,JCOL) is nonzero, or
656 // in which IROW is adjacent to JCOL, call this routine once
657 // to record that fact.
658 //
659 // Diagonal entries are not to be stored.
660 //
661 // The matrix is assumed to be symmetric, so setting I adjacent to J
662 // will also set J adjacent to I.
663 //
664 // Repeated calls with the same values of IROW and JCOL do not
665 // actually hurt. No extra storage will be allocated.
666 //
667 // Licensing:
668 //
669 // This code is distributed under the GNU LGPL license.
670 //
671 // Modified:
672 //
673 // 07 January 2007
674 //
675 // Author:
676 //
677 // John Burkardt
678 //
679 // Parameters:
680 //
681 // Input, int NODE_NUM, the number of nodes.
682 //
683 // Input, int ADJ_MAX, the maximum dimension of the adjacency array.
684 //
685 // Input/output, int *ADJ_NUM, the number of adjaceny entries.
686 //
687 // Input/output, int ADJ_ROW[NODE_NUM+1]. Information about
688 // row I is stored in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
689 //
690 // Input/output, int ADJ[ADJ_NUM], the adjacency structure.
691 //
692 // Input, int IROW, JCOL, the row and column indices of a nonzero
693 // entry of the matrix.
694 //
695 {
696  int i;
697 //
698 // Negative IROW or JCOL indicates the data structure should be initialized.
699 //
700  if ( irow < 0 || jcol < 0 )
701  {
702  cout << "\n";
703  cout << "ADJ_SET - Note:\n";
704  cout << " Initializing adjacency information.\n";
705  cout << " Number of nodes NODE_NUM = " << node_num << "\n";
706  cout << " Maximum adjacency ADJ_MAX = " << adj_max << "\n";
707 
708  *adj_num = 0;
709  for ( i = 0; i < node_num + 1; i++ )
710  {
711  adj_row[i] = 1;
712  }
713  for ( i = 0; i < adj_max; i++ )
714  {
715  adj[i] = 0;
716  }
717  return;
718  }
719 //
720 // Diagonal entries are not stored.
721 //
722  if ( irow == jcol )
723  {
724  return;
725  }
726 
727  if ( node_num < irow )
728  {
729  cout << "\n";
730  cout << "ADJ_SET - Fatal error!\n";
731  cout << " NODE_NUM < IROW.\n";
732  cout << " IROW = " << irow << "\n";
733  cout << " NODE_NUM = " << node_num << "\n";
734  exit ( 1 );
735  }
736  else if ( irow < 1 )
737  {
738  cout << "\n";
739  cout << "ADJ_SET - Fatal error!\n";
740  cout << " IROW < 1.\n";
741  cout << " IROW = " << irow << "\n";
742  exit ( 1 );
743  }
744  else if ( node_num < jcol )
745  {
746  cout << "\n";
747  cout << "ADJ_SET - Fatal error!\n";
748  cout << " NODE_NUM < JCOL.\n";
749  cout << " JCOL = " << jcol << "\n";
750  cout << " NODE_NUM = " << node_num << "\n";
751  exit ( 1 );
752  }
753  else if ( jcol < 1 )
754  {
755  cout << "\n";
756  cout << "ADJ_SET - Fatal error!\n";
757  cout << " JCOL < 1.\n";
758  cout << " JCOL = " << jcol << "\n";
759  exit ( 1 );
760  }
761 
762  if ( !adj_contains_ij ( node_num, *adj_num, adj_row, adj, irow, jcol ) )
763  {
764  adj_insert_ij ( node_num, adj_max, adj_num, adj_row, adj, irow, jcol );
765  }
766 
767  if ( !adj_contains_ij ( node_num, *adj_num, adj_row, adj, jcol, irow ) )
768  {
769  adj_insert_ij ( node_num, adj_max, adj_num, adj_row, adj, jcol, irow );
770  }
771 
772  return;
773 }
774 //****************************************************************************80
775 
776 void adj_show ( int node_num, int adj_num, int adj_row[], int adj[] )
777 
778 //****************************************************************************80
779 //
780 // Purpose:
781 //
782 // ADJ_SHOW displays a symbolic picture of an adjacency matrix.
783 //
784 // Discussion:
785 //
786 // The matrix is defined by the adjacency information and a permutation.
787 //
788 // The routine also computes the bandwidth and the size of the envelope.
789 //
790 // Licensing:
791 //
792 // This code is distributed under the GNU LGPL license.
793 //
794 // Modified:
795 //
796 // 04 January 2007
797 //
798 // Author:
799 //
800 // John Burkardt
801 //
802 // Reference:
803 //
804 // Alan George, Joseph Liu,
805 // Computer Solution of Large Sparse Positive Definite Systems,
806 // Prentice Hall, 1981.
807 //
808 // Parameters:
809 //
810 // Input, int NODE_NUM, the number of nodes.
811 //
812 // Input, int ADJ_NUM, the number of adjacency entries.
813 //
814 // Input, int ADJ_ROW[NODE_NUM+1]. Information about row I is stored
815 // in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
816 //
817 // Input, int ADJ[ADJ_NUM], the adjacency structure.
818 // For each row, it contains the column indices of the nonzero entries.
819 //
820 {
821  char *band;
822  int band_lo;
823  int col;
824  int i;
825  int j;
826  int k;
827  int nonzero_num;
828 
829  band = new char[node_num];
830 
831  band_lo = 0;
832  nonzero_num = 0;
833 
834  cout << "\n";
835  cout << " Nonzero structure of matrix:\n";
836  cout << "\n";
837 
838  for ( i = 0; i < node_num; i++ )
839  {
840  for ( k = 0; k < node_num; k++ )
841  {
842  band[k] = '.';
843  }
844 
845  band[i] = 'D';
846 
847  for ( j = adj_row[i]; j <= adj_row[i+1]-1; j++ )
848  {
849  col = adj[j-1] - 1;
850  if ( col < i )
851  {
852  nonzero_num = nonzero_num + 1;
853  }
854  band_lo = max ( band_lo, i - col );
855  band[col] = 'X';
856  }
857  cout << " " << setw(8) << i + 1 << " ";
858  for ( j = 0; j < node_num; j++ )
859  {
860  cout << band[j];
861  }
862  cout << "\n";
863  }
864 
865  cout << "\n";
866  cout << " Lower bandwidth = " << band_lo << "\n";
867  cout << " Lower envelope contains " << nonzero_num << " nonzeros.\n";
868 
869  delete [] band;
870 
871  return;
872 }
873 //****************************************************************************80
874 
875 void degree ( int root, int adj_num, int adj_row[], int adj[], int mask[],
876  int deg[], int *iccsze, int ls[], int node_num )
877 
878 //****************************************************************************80
879 //
880 // Purpose:
881 //
882 // DEGREE computes the degrees of the nodes in the connected component.
883 //
884 // Discussion:
885 //
886 // The connected component is specified by MASK and ROOT.
887 // Nodes for which MASK is zero are ignored.
888 //
889 // Licensing:
890 //
891 // This code is distributed under the GNU LGPL license.
892 //
893 // Modified:
894 //
895 // 05 January 2007
896 //
897 // Author:
898 //
899 // Original FORTRAN77 version by Alan George, Joseph Liu.
900 // C++ version by John Burkardt.
901 //
902 // Reference:
903 //
904 // Alan George, Joseph Liu,
905 // Computer Solution of Large Sparse Positive Definite Systems,
906 // Prentice Hall, 1981.
907 //
908 // Parameters:
909 //
910 // Input, int ROOT, the node that defines the connected component.
911 //
912 // Input, int ADJ_NUM, the number of adjacency entries.
913 //
914 // Input, int ADJ_ROW[NODE_NUM+1]. Information about row I is stored
915 // in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
916 //
917 // Input, int ADJ[ADJ_NUM], the adjacency structure.
918 // For each row, it contains the column indices of the nonzero entries.
919 //
920 // Input, int MASK[NODE_NUM], is nonzero for those nodes which are
921 // to be considered.
922 //
923 // Output, int DEG[NODE_NUM], contains, for each node in the connected
924 // component, its degree.
925 //
926 // Output, int *ICCSIZE, the number of nodes in the connected component.
927 //
928 // Output, int LS[NODE_NUM], stores in entries 1 through ICCSIZE the nodes
929 // in the connected component, starting with ROOT, and proceeding
930 // by levels.
931 //
932 // Input, int NODE_NUM, the number of nodes.
933 //
934 {
935  int i;
936  int ideg;
937  int j;
938  int jstop;
939  int jstrt;
940  int lbegin;
941  int lvlend;
942  int lvsize;
943  int nbr;
944  int node;
945 //
946 // The sign of ADJ_ROW(I) is used to indicate if node I has been considered.
947 //
948  ls[0] = root;
949  adj_row[root-1] = -adj_row[root-1];
950  lvlend = 0;
951  *iccsze = 1;
952 //
953 // LBEGIN is the pointer to the beginning of the current level, and
954 // LVLEND points to the end of this level.
955 //
956  for ( ; ; )
957  {
958  lbegin = lvlend + 1;
959  lvlend = *iccsze;
960 //
961 // Find the degrees of nodes in the current level,
962 // and at the same time, generate the next level.
963 //
964  for ( i = lbegin; i <= lvlend; i++ )
965  {
966  node = ls[i-1];
967  jstrt = -adj_row[node-1];
968  jstop = abs ( adj_row[node] ) - 1;
969  ideg = 0;
970 
971  for ( j = jstrt; j <= jstop; j++ )
972  {
973  nbr = adj[j-1];
974 
975  if ( mask[nbr-1] != 0 )
976  {
977  ideg = ideg + 1;
978 
979  if ( 0 <= adj_row[nbr-1] )
980  {
981  adj_row[nbr-1] = -adj_row[nbr-1];
982  *iccsze = *iccsze + 1;
983  ls[*iccsze-1] = nbr;
984  }
985  }
986  }
987  deg[node-1] = ideg;
988  }
989 //
990 // Compute the current level width.
991 //
992  lvsize = *iccsze - lvlend;
993 //
994 // If the current level width is nonzero, generate another level.
995 //
996  if ( lvsize == 0 )
997  {
998  break;
999  }
1000  }
1001 //
1002 // Reset ADJ_ROW to its correct sign and return.
1003 //
1004  for ( i = 0; i < *iccsze; i++ )
1005  {
1006  node = ls[i] - 1;
1007  adj_row[node] = -adj_row[node];
1008  }
1009 
1010  return;
1011 }
1012 //****************************************************************************80
1013 
1014 void genrcm ( int node_num, int adj_num, int adj_row[], int adj[], int perm[] )
1015 
1016 //****************************************************************************80
1017 //
1018 // Purpose:
1019 //
1020 // GENRCM finds the reverse Cuthill-Mckee ordering for a general graph.
1021 //
1022 // Discussion:
1023 //
1024 // For each connected component in the graph, the routine obtains
1025 // an ordering by calling RCM.
1026 //
1027 // Licensing:
1028 //
1029 // This code is distributed under the GNU LGPL license.
1030 //
1031 // Modified:
1032 //
1033 // 05 January 2007
1034 //
1035 // Author:
1036 //
1037 // Original FORTRAN77 version by Alan George, Joseph Liu.
1038 // C++ version by John Burkardt.
1039 //
1040 // Reference:
1041 //
1042 // Alan George, Joseph Liu,
1043 // Computer Solution of Large Sparse Positive Definite Systems,
1044 // Prentice Hall, 1981.
1045 //
1046 // Parameters:
1047 //
1048 // Input, int NODE_NUM, the number of nodes.
1049 //
1050 // Input, int ADJ_NUM, the number of adjacency entries.
1051 //
1052 // Input, int ADJ_ROW[NODE_NUM+1]. Information about row I is stored
1053 // in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
1054 //
1055 // Input, int ADJ[ADJ_NUM], the adjacency structure.
1056 // For each row, it contains the column indices of the nonzero entries.
1057 //
1058 // Output, int PERM[NODE_NUM], the RCM ordering.
1059 //
1060 // Local Parameters:
1061 //
1062 // Local, int LEVEL_ROW[NODE_NUM+1], the index vector for a level
1063 // structure. The level structure is stored in the currently unused
1064 // spaces in the permutation vector PERM.
1065 //
1066 // Local, int MASK[NODE_NUM], marks variables that have been numbered.
1067 //
1068 {
1069  int i;
1070  int iccsze;
1071  int level_num;
1072  int *level_row;
1073  int *mask;
1074  int num;
1075  int root;
1076 
1077  level_row = new int[node_num+1];
1078  mask = new int[node_num];
1079 
1080  for ( i = 0; i < node_num; i++ )
1081  {
1082  mask[i] = 1;
1083  }
1084 
1085  num = 1;
1086 
1087  for ( i = 0; i < node_num; i++ )
1088  {
1089 //
1090 // For each masked connected component...
1091 //
1092  if ( mask[i] != 0 )
1093  {
1094  root = i + 1;
1095 //
1096 // Find a pseudo-peripheral node ROOT. The level structure found by
1097 // ROOT_FIND is stored starting at PERM(NUM).
1098 //
1099  root_find ( &root, adj_num, adj_row, adj, mask, &level_num,
1100  level_row, perm+num-1, node_num );
1101 //
1102 // RCM orders the component using ROOT as the starting node.
1103 //
1104  rcm ( root, adj_num, adj_row, adj, mask, perm+num-1, &iccsze,
1105  node_num );
1106 
1107  num = num + iccsze;
1108 //
1109 // We can stop once every node is in one of the connected components.
1110 //
1111  if ( node_num < num )
1112  {
1113  delete [] level_row;
1114  delete [] mask;
1115  return;
1116  }
1117  }
1118  }
1119 
1120  delete [] level_row;
1121  delete [] mask;
1122 
1123  return;
1124 }
1125 //****************************************************************************80
1126 
1127 void graph_01_adj ( int node_num, int adj_num, int adj_row[], int adj[] )
1128 
1129 //****************************************************************************80
1130 //
1131 // Purpose:
1132 //
1133 // GRAPH_01_ADJ returns the adjacency vector for graph 1.
1134 //
1135 // Licensing:
1136 //
1137 // This code is distributed under the GNU LGPL license.
1138 //
1139 // Modified:
1140 //
1141 // 04 January 2007
1142 //
1143 // Author:
1144 //
1145 // John Burkardt
1146 //
1147 // Reference:
1148 //
1149 // Alan George, Joseph Liu,
1150 // Computer Solution of Large Sparse Positive Definite Systems,
1151 // Prentice Hall, 1981.
1152 //
1153 // Parameters:
1154 //
1155 // Input, int NODE_NUM, the number of nodes.
1156 //
1157 // Input, int ADJ_NUM, the number of adjacencies.
1158 //
1159 // Output, int ADJ_ROW[NODE_NUM+1], node pointers into ADJ.
1160 //
1161 // Output, int ADJ[ADJ_NUM], the adjacency information.
1162 //
1163 {
1164 # define ADJ_NUM 28
1165 # define NODE_NUM 10
1166 
1167  static int adj_save[ADJ_NUM] = {
1168  4, 6,
1169  3, 5, 7, 10,
1170  2, 4, 5,
1171  1, 3, 6, 9,
1172  2, 3, 7,
1173  1, 4, 7, 8,
1174  2, 5, 6, 8,
1175  6, 7,
1176  4,
1177  2 };
1178  static int adj_row_save[NODE_NUM+1] = {
1179  1, 3, 7, 10, 14, 17, 21, 25, 27, 28, 29
1180  };
1181  int i;
1182 
1183  for ( i = 0; i < ADJ_NUM; i++ )
1184  {
1185  adj[i] = adj_save[i];
1186  }
1187 
1188  for ( i = 0; i < NODE_NUM + 1; i++ )
1189  {
1190  adj_row[i] = adj_row_save[i];
1191  }
1192  return;
1193 # undef ADJ_NUM
1194 # undef NODE_NUM
1195 }
1196 //****************************************************************************80
1197 
1198 void graph_01_size ( int *node_num, int *adj_num )
1199 
1200 //****************************************************************************80
1201 //
1202 // Purpose:
1203 //
1204 // GRAPH_01_SIZE returns the number of adjacencies for graph 1.
1205 //
1206 // Licensing:
1207 //
1208 // This code is distributed under the GNU LGPL license.
1209 //
1210 // Modified:
1211 //
1212 // 04 January 2007
1213 //
1214 // Author:
1215 //
1216 // John Burkardt
1217 //
1218 // Reference:
1219 //
1220 // Alan George, Joseph Liu,
1221 // Computer Solution of Large Sparse Positive Definite Systems,
1222 // Prentice Hall, 1981.
1223 //
1224 // Parameters:
1225 //
1226 // Output, int *NODE_NUM, the number of items that can be adjacent.
1227 //
1228 // Output, int *ADJ_NUM, the number of adjacencies.
1229 //
1230 {
1231  *node_num = 10;
1232  *adj_num = 28;
1233 
1234  return;
1235 }
1236 //****************************************************************************80
1237 
1238 int i4_max ( int i1, int i2 )
1239 
1240 //****************************************************************************80
1241 //
1242 // Purpose:
1243 //
1244 // I4_MAX returns the maximum of two I4's.
1245 //
1246 // Licensing:
1247 //
1248 // This code is distributed under the GNU LGPL license.
1249 //
1250 // Modified:
1251 //
1252 // 13 October 1998
1253 //
1254 // Author:
1255 //
1256 // John Burkardt
1257 //
1258 // Parameters:
1259 //
1260 // Input, int I1, I2, are two integers to be compared.
1261 //
1262 // Output, int I4_MAX, the larger of I1 and I2.
1263 //
1264 {
1265  if ( i2 < i1 )
1266  {
1267  return i1;
1268  }
1269  else
1270  {
1271  return i2;
1272  }
1273 
1274 }
1275 //****************************************************************************80
1276 
1277 int i4_min ( int i1, int i2 )
1278 
1279 //****************************************************************************80
1280 //
1281 // Purpose:
1282 //
1283 // I4_MIN returns the smaller of two I4's.
1284 //
1285 // Licensing:
1286 //
1287 // This code is distributed under the GNU LGPL license.
1288 //
1289 // Modified:
1290 //
1291 // 13 October 1998
1292 //
1293 // Author:
1294 //
1295 // John Burkardt
1296 //
1297 // Parameters:
1298 //
1299 // Input, int I1, I2, two integers to be compared.
1300 //
1301 // Output, int I4_MIN, the smaller of I1 and I2.
1302 //
1303 {
1304  if ( i1 < i2 )
1305  {
1306  return i1;
1307  }
1308  else
1309  {
1310  return i2;
1311  }
1312 
1313 }
1314 //****************************************************************************80
1315 
1316 int i4_sign ( int i )
1317 
1318 //****************************************************************************80
1319 //
1320 // Purpose:
1321 //
1322 // I4_SIGN returns the sign of an I4.
1323 //
1324 // Licensing:
1325 //
1326 // This code is distributed under the GNU LGPL license.
1327 //
1328 // Modified:
1329 //
1330 // 27 March 2004
1331 //
1332 // Author:
1333 //
1334 // John Burkardt
1335 //
1336 // Parameters:
1337 //
1338 // Input, int I, the integer whose sign is desired.
1339 //
1340 // Output, int I4_SIGN, the sign of I.
1341 {
1342  int value;
1343 
1344  if ( i < 0 )
1345  {
1346  value = -1;
1347  }
1348  else
1349  {
1350  value = 1;
1351  }
1352  return value;
1353 }
1354 //****************************************************************************80
1355 
1356 void i4_swap ( int *i, int *j )
1357 
1358 //****************************************************************************80
1359 //
1360 // Purpose:
1361 //
1362 // I4_SWAP switches two I4's.
1363 //
1364 // Licensing:
1365 //
1366 // This code is distributed under the GNU LGPL license.
1367 //
1368 // Modified:
1369 //
1370 // 07 January 2002
1371 //
1372 // Author:
1373 //
1374 // John Burkardt
1375 //
1376 // Parameters:
1377 //
1378 // Input/output, int *I, *J. On output, the values of I and
1379 // J have been interchanged.
1380 //
1381 {
1382  int k;
1383 
1384  k = *i;
1385  *i = *j;
1386  *j = k;
1387 
1388  return;
1389 }
1390 //****************************************************************************80
1391 
1392 int i4_uniform ( int a, int b, int *seed )
1393 
1394 //****************************************************************************80
1395 //
1396 // Purpose:
1397 //
1398 // I4_UNIFORM returns a scaled pseudorandom I4.
1399 //
1400 // Discussion:
1401 //
1402 // The pseudorandom number should be uniformly distributed
1403 // between A and B.
1404 //
1405 // Licensing:
1406 //
1407 // This code is distributed under the GNU LGPL license.
1408 //
1409 // Modified:
1410 //
1411 // 12 November 2006
1412 //
1413 // Author:
1414 //
1415 // John Burkardt
1416 //
1417 // Reference:
1418 //
1419 // Paul Bratley, Bennett Fox, Linus Schrage,
1420 // A Guide to Simulation,
1421 // Springer Verlag, pages 201-202, 1983.
1422 //
1423 // Pierre L'Ecuyer,
1424 // Random Number Generation,
1425 // in Handbook of Simulation,
1426 // edited by Jerry Banks,
1427 // Wiley Interscience, page 95, 1998.
1428 //
1429 // Bennett Fox,
1430 // Algorithm 647:
1431 // Implementation and Relative Efficiency of Quasirandom
1432 // Sequence Generators,
1433 // ACM Transactions on Mathematical Software,
1434 // Volume 12, Number 4, pages 362-376, 1986.
1435 //
1436 // Peter Lewis, Allen Goodman, James Miller
1437 // A Pseudo-Random Number Generator for the System/360,
1438 // IBM Systems Journal,
1439 // Volume 8, pages 136-143, 1969.
1440 //
1441 // Parameters:
1442 //
1443 // Input, int A, B, the limits of the interval.
1444 //
1445 // Input/output, int *SEED, the "seed" value, which should NOT be 0.
1446 // On output, SEED has been updated.
1447 //
1448 // Output, int I4_UNIFORM, a number between A and B.
1449 //
1450 {
1451  int k;
1452  float r;
1453  int value;
1454 
1455  if ( *seed == 0 )
1456  {
1457  cerr << "\n";
1458  cerr << "I4_UNIFORM - Fatal error!\n";
1459  cerr << " Input value of SEED = 0.\n";
1460  exit ( 1 );
1461  }
1462 
1463  k = *seed / 127773;
1464 
1465  *seed = 16807 * ( *seed - k * 127773 ) - k * 2836;
1466 
1467  if ( *seed < 0 )
1468  {
1469  *seed = *seed + 2147483647;
1470  }
1471 
1472  r = ( float ) ( *seed ) * 4.656612875E-10;
1473 //
1474 // Scale R to lie between A-0.5 and B+0.5.
1475 //
1476  r = ( 1.0 - r ) * ( ( float ) ( i4_min ( a, b ) ) - 0.5 )
1477  + r * ( ( float ) ( i4_max ( a, b ) ) + 0.5 );
1478 //
1479 // Use rounding to convert R to an integer between A and B.
1480 //
1481  value = r4_nint ( r );
1482 
1483  value = i4_max ( value, i4_min ( a, b ) );
1484  value = i4_min ( value, i4_max ( a, b ) );
1485 
1486  return value;
1487 }
1488 //****************************************************************************80
1489 
1490 int i4col_compare ( int m, int n, int a[], int i, int j )
1491 
1492 //****************************************************************************80
1493 //
1494 // Purpose:
1495 //
1496 // I4COL_COMPARE compares columns I and J of an I4COL.
1497 //
1498 // Example:
1499 //
1500 // Input:
1501 //
1502 // M = 3, N = 4, I = 2, J = 4
1503 //
1504 // A = (
1505 // 1 2 3 4
1506 // 5 6 7 8
1507 // 9 10 11 12 )
1508 //
1509 // Output:
1510 //
1511 // I4COL_COMPARE = -1
1512 //
1513 // Licensing:
1514 //
1515 // This code is distributed under the GNU LGPL license.
1516 //
1517 // Modified:
1518 //
1519 // 12 June 2005
1520 //
1521 // Author:
1522 //
1523 // John Burkardt
1524 //
1525 // Parameters:
1526 //
1527 // Input, int M, N, the number of rows and columns.
1528 //
1529 // Input, int A[M*N], an array of N columns of vectors of length M.
1530 //
1531 // Input, int I, J, the columns to be compared.
1532 // I and J must be between 1 and N.
1533 //
1534 // Output, int I4COL_COMPARE, the results of the comparison:
1535 // -1, column I < column J,
1536 // 0, column I = column J,
1537 // +1, column J < column I.
1538 //
1539 {
1540  int k;
1541 //
1542 // Check.
1543 //
1544  if ( i < 1 )
1545  {
1546  cout << "\n";
1547  cout << "I4COL_COMPARE - Fatal error!\n";
1548  cout << " Column index I = " << i << " is less than 1.\n";
1549  exit ( 1 );
1550  }
1551 
1552  if ( n < i )
1553  {
1554  cout << "\n";
1555  cout << "I4COL_COMPARE - Fatal error!\n";
1556  cout << " N = " << n << " is less than column index I = " << i << ".\n";
1557  exit ( 1 );
1558  }
1559 
1560  if ( j < 1 )
1561  {
1562  cout << "\n";
1563  cout << "I4COL_COMPARE - Fatal error!\n";
1564  cout << " Column index J = " << j << " is less than 1.\n";
1565  exit ( 1 );
1566  }
1567 
1568  if ( n < j )
1569  {
1570  cout << "\n";
1571  cout << "I4COL_COMPARE - Fatal error!\n";
1572  cout << " N = " << n << " is less than column index J = " << j << ".\n";
1573  exit ( 1 );
1574  }
1575 
1576  if ( i == j )
1577  {
1578  return 0;
1579  }
1580 
1581  k = 1;
1582 
1583  while ( k <= m )
1584  {
1585  if ( a[k-1+(i-1)*m] < a[k-1+(j-1)*m] )
1586  {
1587  return (-1);
1588  }
1589  else if ( a[k-1+(j-1)*m] < a[k-1+(i-1)*m] )
1590  {
1591  return 1;
1592  }
1593  k = k + 1;
1594  }
1595 
1596  return 0;
1597 }
1598 //****************************************************************************80
1599 
1600 void i4col_sort_a ( int m, int n, int a[] )
1601 
1602 //****************************************************************************80
1603 //
1604 // Purpose:
1605 //
1606 // I4COL_SORT_A ascending sorts the columns of an I4COL.
1607 //
1608 // Discussion:
1609 //
1610 // In lexicographic order, the statement "X < Y", applied to two
1611 // vectors X and Y of length M, means that there is some index I, with
1612 // 1 <= I <= M, with the property that
1613 //
1614 // X(J) = Y(J) for J < I,
1615 // and
1616 // X(I) < Y(I).
1617 //
1618 // In other words, X is less than Y if, at the first index where they
1619 // differ, the X value is less than the Y value.
1620 //
1621 // Licensing:
1622 //
1623 // This code is distributed under the GNU LGPL license.
1624 //
1625 // Modified:
1626 //
1627 // 12 June 2005
1628 //
1629 // Author:
1630 //
1631 // John Burkardt
1632 //
1633 // Parameters:
1634 //
1635 // Input, int M, the number of rows of A.
1636 //
1637 // Input, int N, the number of columns of A.
1638 //
1639 // Input/output, int A[M*N].
1640 // On input, the array of N columns of M vectors;
1641 // On output, the columns of A have been sorted in ascending
1642 // lexicographic order.
1643 //
1644 {
1645  int i;
1646  int indx;
1647  int isgn;
1648  int j;
1649 //
1650 // Initialize.
1651 //
1652  i = 0;
1653  indx = 0;
1654  isgn = 0;
1655  j = 0;
1656 //
1657 // Call the external heap sorter.
1658 //
1659  for ( ; ; )
1660  {
1661  sort_heap_external ( n, &indx, &i, &j, isgn );
1662 //
1663 // Interchange the I and J objects.
1664 //
1665  if ( 0 < indx )
1666  {
1667  i4col_swap ( m, n, a, i, j );
1668  }
1669 //
1670 // Compare the I and J objects.
1671 //
1672  else if ( indx < 0 )
1673  {
1674  isgn = i4col_compare ( m, n, a, i, j );
1675  }
1676  else if ( indx == 0 )
1677  {
1678  break;
1679  }
1680 
1681  }
1682 
1683  return;
1684 }
1685 //****************************************************************************80
1686 
1687 void i4col_swap ( int m, int n, int a[], int icol1, int icol2 )
1688 
1689 //****************************************************************************80
1690 //
1691 // Purpose:
1692 //
1693 // I4COL_SWAP swaps two columns of an I4COL.
1694 //
1695 // Discussion:
1696 //
1697 // The two dimensional information is stored as a one dimensional
1698 // array, by columns.
1699 //
1700 // The row indices are 1 based, NOT 0 based// However, a preprocessor
1701 // variable, called OFFSET, can be reset from 1 to 0 if you wish to
1702 // use 0-based indices.
1703 //
1704 // Licensing:
1705 //
1706 // This code is distributed under the GNU LGPL license.
1707 //
1708 // Modified:
1709 //
1710 // 03 April 2005
1711 //
1712 // Author:
1713 //
1714 // John Burkardt
1715 //
1716 // Parameters:
1717 //
1718 // Input, int M, N, the number of rows and columns.
1719 //
1720 // Input/output, int A[M*N], an array of data.
1721 //
1722 // Input, int ICOL1, ICOL2, the two columns to swap.
1723 // These indices should be between 1 and N.
1724 //
1725 {
1726 # define OFFSET 1
1727 
1728  int i;
1729  int t;
1730 //
1731 // Check.
1732 //
1733  if ( icol1 - OFFSET < 0 || n-1 < icol1 - OFFSET )
1734  {
1735  cout << "\n";
1736  cout << "I4COL_SWAP - Fatal error!\n";
1737  cout << " ICOL1 is out of range.\n";
1738  exit ( 1 );
1739  }
1740 
1741  if ( icol2 - OFFSET < 0 || n-1 < icol2 - OFFSET )
1742  {
1743  cout << "\n";
1744  cout << "I4COL_SWAP - Fatal error!\n";
1745  cout << " ICOL2 is out of range.\n";
1746  exit ( 1 );
1747  }
1748 
1749  if ( icol1 == icol2 )
1750  {
1751  return;
1752  }
1753  for ( i = 0; i < m; i++ )
1754  {
1755  t = a[i+(icol1-OFFSET)*m];
1756  a[i+(icol1-OFFSET)*m] = a[i+(icol2-OFFSET)*m];
1757  a[i+(icol2-OFFSET)*m] = t;
1758  }
1759 
1760  return;
1761 # undef OFFSET
1762 }
1763 //****************************************************************************80
1764 
1765 void i4mat_print_some ( int m, int n, int a[], int ilo, int jlo, int ihi,
1766  int jhi, string title )
1767 
1768 //****************************************************************************80
1769 //
1770 // Purpose:
1771 //
1772 // I4MAT_PRINT_SOME prints some of an I4MAT.
1773 //
1774 // Licensing:
1775 //
1776 // This code is distributed under the GNU LGPL license.
1777 //
1778 // Modified:
1779 //
1780 // 14 June 2005
1781 //
1782 // Author:
1783 //
1784 // John Burkardt
1785 //
1786 // Parameters:
1787 //
1788 // Input, int M, the number of rows of the matrix.
1789 // M must be positive.
1790 //
1791 // Input, int N, the number of columns of the matrix.
1792 // N must be positive.
1793 //
1794 // Input, int A[M*N], the matrix.
1795 //
1796 // Input, int ILO, JLO, IHI, JHI, designate the first row and
1797 // column, and the last row and column to be printed.
1798 //
1799 // Input, string TITLE, a title.
1800 {
1801 # define INCX 10
1802 
1803  int i;
1804  int i2hi;
1805  int i2lo;
1806  int j;
1807  int j2hi;
1808  int j2lo;
1809 
1810  cout << "\n";
1811  cout << title << "\n";
1812 //
1813 // Print the columns of the matrix, in strips of INCX.
1814 //
1815  for ( j2lo = jlo; j2lo <= jhi; j2lo = j2lo + INCX )
1816  {
1817  j2hi = j2lo + INCX - 1;
1818  j2hi = i4_min ( j2hi, n );
1819  j2hi = i4_min ( j2hi, jhi );
1820 
1821  cout << "\n";
1822 //
1823 // For each column J in the current range...
1824 //
1825 // Write the header.
1826 //
1827  cout << " Col: ";
1828  for ( j = j2lo; j <= j2hi; j++ )
1829  {
1830  cout << setw(6) << j << " ";
1831  }
1832  cout << "\n";
1833  cout << " Row\n";
1834  cout << "\n";
1835 //
1836 // Determine the range of the rows in this strip.
1837 //
1838  i2lo = i4_max ( ilo, 1 );
1839  i2hi = i4_min ( ihi, m );
1840 
1841  for ( i = i2lo; i <= i2hi; i++ )
1842  {
1843 //
1844 // Print out (up to INCX) entries in row I, that lie in the current strip.
1845 //
1846  cout << setw(5) << i << " ";
1847  for ( j = j2lo; j <= j2hi; j++ )
1848  {
1849  cout << setw(6) << a[i-1+(j-1)*m] << " ";
1850  }
1851  cout << "\n";
1852  }
1853 
1854  }
1855 
1856  cout << "\n";
1857 
1858  return;
1859 # undef INCX
1860 }
1861 //****************************************************************************80
1862 
1863 void i4mat_transpose_print ( int m, int n, int a[], string title )
1864 
1865 //****************************************************************************80
1866 //
1867 // Purpose:
1868 //
1869 // I4MAT_TRANSPOSE_PRINT prints an I4MAT, transposed.
1870 //
1871 // Licensing:
1872 //
1873 // This code is distributed under the GNU LGPL license.
1874 //
1875 // Modified:
1876 //
1877 // 31 January 2005
1878 //
1879 // Author:
1880 //
1881 // John Burkardt
1882 //
1883 // Parameters:
1884 //
1885 // Input, int M, the number of rows in A.
1886 //
1887 // Input, int N, the number of columns in A.
1888 //
1889 // Input, int A[M*N], the M by N matrix.
1890 //
1891 // Input, string TITLE, a title.
1892 //
1893 {
1894 
1895  i4mat_transpose_print_some ( m, n, a, 1, 1, m, n, title );
1896 
1897  return;
1898 }
1899 //****************************************************************************80
1900 
1901 void i4mat_transpose_print_some ( int m, int n, int a[], int ilo, int jlo,
1902  int ihi, int jhi, string title )
1903 
1904 //****************************************************************************80
1905 //
1906 // Purpose:
1907 //
1908 // I4MAT_TRANSPOSE_PRINT_SOME prints some of an I4MAT, transposed.
1909 //
1910 // Licensing:
1911 //
1912 // This code is distributed under the GNU LGPL license.
1913 //
1914 // Modified:
1915 //
1916 // 09 February 2005
1917 //
1918 // Author:
1919 //
1920 // John Burkardt
1921 //
1922 // Parameters:
1923 //
1924 // Input, int M, the number of rows of the matrix.
1925 // M must be positive.
1926 //
1927 // Input, int N, the number of columns of the matrix.
1928 // N must be positive.
1929 //
1930 // Input, int A[M*N], the matrix.
1931 //
1932 // Input, int ILO, JLO, IHI, JHI, designate the first row and
1933 // column, and the last row and column to be printed.
1934 //
1935 // Input, string TITLE, a title.
1936 {
1937 # define INCX 10
1938 
1939  int i;
1940  int i2hi;
1941  int i2lo;
1942  int j;
1943  int j2hi;
1944  int j2lo;
1945 
1946  cout << "\n";
1947  cout << title << "\n";
1948 //
1949 // Print the columns of the matrix, in strips of INCX.
1950 //
1951  for ( i2lo = ilo; i2lo <= ihi; i2lo = i2lo + INCX )
1952  {
1953  i2hi = i2lo + INCX - 1;
1954  i2hi = i4_min ( i2hi, m );
1955  i2hi = i4_min ( i2hi, ihi );
1956 
1957  cout << "\n";
1958 //
1959 // For each row I in the current range...
1960 //
1961 // Write the header.
1962 //
1963  cout << " Row: ";
1964  for ( i = i2lo; i <= i2hi; i++ )
1965  {
1966  cout << setw(6) << i << " ";
1967  }
1968  cout << "\n";
1969  cout << " Col\n";
1970  cout << "\n";
1971 //
1972 // Determine the range of the rows in this strip.
1973 //
1974  j2lo = i4_max ( jlo, 1 );
1975  j2hi = i4_min ( jhi, n );
1976 
1977  for ( j = j2lo; j <= j2hi; j++ )
1978  {
1979 //
1980 // Print out (up to INCX) entries in column J, that lie in the current strip.
1981 //
1982  cout << setw(5) << j << " ";
1983  for ( i = i2lo; i <= i2hi; i++ )
1984  {
1985  cout << setw(6) << a[i-1+(j-1)*m] << " ";
1986  }
1987  cout << "\n";
1988  }
1989 
1990  }
1991 
1992  cout << "\n";
1993 
1994  return;
1995 # undef INCX
1996 }
1997 //****************************************************************************80
1998 
1999 void i4vec_heap_d ( int n, int a[] )
2000 
2001 //****************************************************************************80
2002 //
2003 // Purpose:
2004 //
2005 // I4VEC_HEAP_D reorders an I4VEC into a descending heap.
2006 //
2007 // Discussion:
2008 //
2009 // A heap is an array A with the property that, for every index J,
2010 // A[J] >= A[2*J+1] and A[J] >= A[2*J+2], (as long as the indices
2011 // 2*J+1 and 2*J+2 are legal).
2012 //
2013 // Diagram:
2014 //
2015 // A(0)
2016 // / \
2017 // A(1) A(2)
2018 // / \ / \
2019 // A(3) A(4) A(5) A(6)
2020 // / \ / \
2021 // A(7) A(8) A(9) A(10)
2022 //
2023 // Licensing:
2024 //
2025 // This code is distributed under the GNU LGPL license.
2026 //
2027 // Modified:
2028 //
2029 // 30 April 1999
2030 //
2031 // Author:
2032 //
2033 // John Burkardt
2034 //
2035 // Reference:
2036 //
2037 // Albert Nijenhuis, Herbert Wilf,
2038 // Combinatorial Algorithms,
2039 // Academic Press, 1978, second edition,
2040 // ISBN 0-12-519260-6.
2041 //
2042 // Parameters:
2043 //
2044 // Input, int N, the size of the input array.
2045 //
2046 // Input/output, int A[N].
2047 // On input, an unsorted array.
2048 // On output, the array has been reordered into a heap.
2049 //
2050 {
2051  int i;
2052  int ifree;
2053  int key;
2054  int m;
2055 //
2056 // Only nodes (N/2)-1 down to 0 can be "parent" nodes.
2057 //
2058  for ( i = (n/2)-1; 0 <= i; i-- )
2059  {
2060 //
2061 // Copy the value out of the parent node.
2062 // Position IFREE is now "open".
2063 //
2064  key = a[i];
2065  ifree = i;
2066 
2067  for ( ;; )
2068  {
2069 //
2070 // Positions 2*IFREE + 1 and 2*IFREE + 2 are the descendants of position
2071 // IFREE. (One or both may not exist because they equal or exceed N.)
2072 //
2073  m = 2 * ifree + 1;
2074 //
2075 // Does the first position exist?
2076 //
2077  if ( n <= m )
2078  {
2079  break;
2080  }
2081  else
2082  {
2083 //
2084 // Does the second position exist?
2085 //
2086  if ( m + 1 < n )
2087  {
2088 //
2089 // If both positions exist, take the larger of the two values,
2090 // and update M if necessary.
2091 //
2092  if ( a[m] < a[m+1] )
2093  {
2094  m = m + 1;
2095  }
2096  }
2097 //
2098 // If the large descendant is larger than KEY, move it up,
2099 // and update IFREE, the location of the free position, and
2100 // consider the descendants of THIS position.
2101 //
2102  if ( key < a[m] )
2103  {
2104  a[ifree] = a[m];
2105  ifree = m;
2106  }
2107  else
2108  {
2109  break;
2110  }
2111 
2112  }
2113 
2114  }
2115 //
2116 // When you have stopped shifting items up, return the item you
2117 // pulled out back to the heap.
2118 //
2119  a[ifree] = key;
2120 
2121  }
2122 
2123  return;
2124 }
2125 //****************************************************************************80
2126 
2127 int *i4vec_indicator ( int n )
2128 
2129 //****************************************************************************80
2130 //
2131 // Purpose:
2132 //
2133 // I4VEC_INDICATOR sets an I4VEC to the indicator vector.
2134 //
2135 // Licensing:
2136 //
2137 // This code is distributed under the GNU LGPL license.
2138 //
2139 // Modified:
2140 //
2141 // 25 February 2003
2142 //
2143 // Author:
2144 //
2145 // John Burkardt
2146 //
2147 // Parameters:
2148 //
2149 // Input, int N, the number of elements of A.
2150 //
2151 // Output, int I4VEC_INDICATOR(N), the initialized array.
2152 //
2153 {
2154  int *a;
2155  int i;
2156 
2157  a = new int[n];
2158 
2159  for ( i = 0; i < n; i++ )
2160  {
2161  a[i] = i + 1;
2162  }
2163 
2164  return a;
2165 }
2166 //****************************************************************************80
2167 
2168 void i4vec_print ( int n, int a[], string title )
2169 
2170 //****************************************************************************80
2171 //
2172 // Purpose:
2173 //
2174 // I4VEC_PRINT prints an I4VEC.
2175 //
2176 // Licensing:
2177 //
2178 // This code is distributed under the GNU LGPL license.
2179 //
2180 // Modified:
2181 //
2182 // 25 February 2003
2183 //
2184 // Author:
2185 //
2186 // John Burkardt
2187 //
2188 // Parameters:
2189 //
2190 // Input, int N, the number of components of the vector.
2191 //
2192 // Input, int A[N], the vector to be printed.
2193 //
2194 // Input, string TITLE, a title.
2195 //
2196 {
2197  int i;
2198 
2199  cout << "\n";
2200  cout << title << "\n";
2201  cout << "\n";
2202  for ( i = 0; i <= n-1; i++ )
2203  {
2204  cout << " " << setw(8) << i + 1
2205  << " " << setw(8) << a[i] << "\n";
2206  }
2207 
2208  return;
2209 }
2210 //****************************************************************************80
2211 
2212 void i4vec_reverse ( int n, int a[] )
2213 
2214 //****************************************************************************80
2215 //
2216 // Purpose:
2217 //
2218 // I4VEC_REVERSE reverses the elements of an I4VEC.
2219 //
2220 // Example:
2221 //
2222 // Input:
2223 //
2224 // N = 5,
2225 // A = ( 11, 12, 13, 14, 15 ).
2226 //
2227 // Output:
2228 //
2229 // A = ( 15, 14, 13, 12, 11 ).
2230 //
2231 // Licensing:
2232 //
2233 // This code is distributed under the GNU LGPL license.
2234 //
2235 // Modified:
2236 //
2237 // 22 September 2005
2238 //
2239 // Author:
2240 //
2241 // John Burkardt
2242 //
2243 // Parameters:
2244 //
2245 // Input, int N, the number of entries in the array.
2246 //
2247 // Input/output, int A(N), the array to be reversed.
2248 //
2249 {
2250  int i;
2251  int j;
2252 
2253  for ( i = 0; i < n / 2; i++ )
2254  {
2255  j = a[i];
2256  a[i] = a[n-1-i];
2257  a[n-1-i] = j;
2258  }
2259 
2260  return;
2261 }
2262 //****************************************************************************80
2263 
2264 void i4vec_sort_heap_a ( int n, int a[] )
2265 
2266 //****************************************************************************80
2267 //
2268 // Purpose:
2269 //
2270 // I4VEC_SORT_HEAP_A ascending sorts an I4VEC using heap sort.
2271 //
2272 // Licensing:
2273 //
2274 // This code is distributed under the GNU LGPL license.
2275 //
2276 // Modified:
2277 //
2278 // 30 April 1999
2279 //
2280 // Author:
2281 //
2282 // John Burkardt
2283 //
2284 // Reference:
2285 //
2286 // Albert Nijenhuis, Herbert Wilf,
2287 // Combinatorial Algorithms,
2288 // Academic Press, 1978, second edition,
2289 // ISBN 0-12-519260-6.
2290 //
2291 // Parameters:
2292 //
2293 // Input, int N, the number of entries in the array.
2294 //
2295 // Input/output, int A[N].
2296 // On input, the array to be sorted;
2297 // On output, the array has been sorted.
2298 //
2299 {
2300  int n1;
2301  int temp;
2302 
2303  if ( n <= 1 )
2304  {
2305  return;
2306  }
2307 //
2308 // 1: Put A into descending heap form.
2309 //
2310  i4vec_heap_d ( n, a );
2311 //
2312 // 2: Sort A.
2313 //
2314 // The largest object in the heap is in A[0].
2315 // Move it to position A[N-1].
2316 //
2317  temp = a[0];
2318  a[0] = a[n-1];
2319  a[n-1] = temp;
2320 //
2321 // Consider the diminished heap of size N1.
2322 //
2323  for ( n1 = n-1; 2 <= n1; n1-- )
2324  {
2325 //
2326 // Restore the heap structure of the initial N1 entries of A.
2327 //
2328  i4vec_heap_d ( n1, a );
2329 //
2330 // Take the largest object from A[0] and move it to A[N1-1].
2331 //
2332  temp = a[0];
2333  a[0] = a[n1-1];
2334  a[n1-1] = temp;
2335  }
2336 
2337  return;
2338 }
2339 //****************************************************************************80
2340 
2341 void level_set ( int root, int adj_num, int adj_row[], int adj[], int mask[],
2342  int *level_num, int level_row[], int level[], int node_num )
2343 
2344 //****************************************************************************80
2345 //
2346 // Purpose:
2347 //
2348 // LEVEL_SET generates the connected level structure rooted at a given node.
2349 //
2350 // Discussion:
2351 //
2352 // Only nodes for which MASK is nonzero will be considered.
2353 //
2354 // The root node chosen by the user is assigned level 1, and masked.
2355 // All (unmasked) nodes reachable from a node in level 1 are
2356 // assigned level 2 and masked. The process continues until there
2357 // are no unmasked nodes adjacent to any node in the current level.
2358 // The number of levels may vary between 2 and NODE_NUM.
2359 //
2360 // Licensing:
2361 //
2362 // This code is distributed under the GNU LGPL license.
2363 //
2364 // Modified:
2365 //
2366 // 05 January 2007
2367 //
2368 // Author:
2369 //
2370 // Original FORTRAN77 version by Alan George, Joseph Liu.
2371 // C++ version by John Burkardt.
2372 //
2373 // Reference:
2374 //
2375 // Alan George, Joseph Liu,
2376 // Computer Solution of Large Sparse Positive Definite Systems,
2377 // Prentice Hall, 1981.
2378 //
2379 // Parameters:
2380 //
2381 // Input, int ROOT, the node at which the level structure
2382 // is to be rooted.
2383 //
2384 // Input, int ADJ_NUM, the number of adjacency entries.
2385 //
2386 // Input, int ADJ_ROW[NODE_NUM+1]. Information about row I is stored
2387 // in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
2388 //
2389 // Input, int ADJ[ADJ_NUM], the adjacency structure.
2390 // For each row, it contains the column indices of the nonzero entries.
2391 //
2392 // Input/output, int MASK[NODE_NUM]. On input, only nodes with nonzero
2393 // MASK are to be processed. On output, those nodes which were included
2394 // in the level set have MASK set to 1.
2395 //
2396 // Output, int *LEVEL_NUM, the number of levels in the level
2397 // structure. ROOT is in level 1. The neighbors of ROOT
2398 // are in level 2, and so on.
2399 //
2400 // Output, int LEVEL_ROW[NODE_NUM+1], LEVEL[NODE_NUM], the rooted
2401 // level structure.
2402 //
2403 // Input, int NODE_NUM, the number of nodes.
2404 //
2405 {
2406  int i;
2407  int iccsze;
2408  int j;
2409  int jstop;
2410  int jstrt;
2411  int lbegin;
2412  int lvlend;
2413  int lvsize;
2414  int nbr;
2415  int node;
2416 
2417  mask[root-1] = 0;
2418  level[0] = root;
2419  *level_num = 0;
2420  lvlend = 0;
2421  iccsze = 1;
2422 //
2423 // LBEGIN is the pointer to the beginning of the current level, and
2424 // LVLEND points to the end of this level.
2425 //
2426  for ( ; ; )
2427  {
2428  lbegin = lvlend + 1;
2429  lvlend = iccsze;
2430  *level_num = *level_num + 1;
2431  level_row[*level_num-1] = lbegin;
2432 //
2433 // Generate the next level by finding all the masked neighbors of nodes
2434 // in the current level.
2435 //
2436  for ( i = lbegin; i <= lvlend; i++ )
2437  {
2438  node = level[i-1];
2439  jstrt = adj_row[node-1];
2440  jstop = adj_row[node] - 1;
2441 
2442  for ( j = jstrt; j <= jstop; j++ )
2443  {
2444  nbr = adj[j-1];
2445 
2446  if ( mask[nbr-1] != 0 )
2447  {
2448  iccsze = iccsze + 1;
2449  level[iccsze-1] = nbr;
2450  mask[nbr-1] = 0;
2451  }
2452  }
2453  }
2454 //
2455 // Compute the current level width (the number of nodes encountered.)
2456 // If it is positive, generate the next level.
2457 //
2458  lvsize = iccsze - lvlend;
2459 
2460  if ( lvsize <= 0 )
2461  {
2462  break;
2463  }
2464  }
2465 
2466  level_row[*level_num] = lvlend + 1;
2467 //
2468 // Reset MASK to 1 for the nodes in the level structure.
2469 //
2470  for ( i = 0; i < iccsze; i++ )
2471  {
2472  mask[level[i]-1] = 1;
2473  }
2474 
2475  return;
2476 }
2477 //****************************************************************************80
2478 
2479 void level_set_print ( int node_num, int level_num, int level_row[],
2480  int level[] )
2481 
2482 //****************************************************************************80
2483 //
2484 // Purpose:
2485 //
2486 // LEVEL_SET_PRINT prints level set information.
2487 //
2488 // Licensing:
2489 //
2490 // This code is distributed under the GNU LGPL license.
2491 //
2492 // Modified:
2493 //
2494 // 05 January 2007
2495 //
2496 // Author:
2497 //
2498 // John Burkardt
2499 //
2500 // Parameters:
2501 //
2502 // Input, int NODE_NUM, the number of nodes.
2503 //
2504 // Input, int LEVEL_NUM, the number of levels.
2505 //
2506 // Input, int LEVEL_ROW[LEVEL_NUM+1], organizes the entries of LEVEL.
2507 // The entries for level I are in entries LEVEL_ROW(I)
2508 // through LEVEL_ROW(I+1)-1.
2509 //
2510 // Input, integer LEVEL[NODE_NUM], is simply a list of the nodes in an
2511 // order induced by the levels.
2512 //
2513 {
2514  int i;
2515  int j;
2516  int jhi;
2517  int jlo;
2518  int jmax;
2519  int jmin;
2520 
2521  cout << "\n";
2522  cout << "LEVEL_SET_PRINT\n";
2523  cout << " Show the level set structure of a rooted graph.\n";
2524  cout << " The number of nodes is " << node_num << "\n";
2525  cout << " The number of levels is " << level_num << "\n";
2526  cout << "\n";
2527  cout << " Level Min Max Nonzeros\n";
2528  cout << "\n";
2529 
2530  for ( i = 0; i < level_num; i++ )
2531  {
2532  jmin = level_row[i];
2533  jmax = level_row[i+1] - 1;
2534 
2535  if ( jmax < jmin )
2536  {
2537  cout << " " << setw(4) << i+1
2538  << " " << setw(4) << jmin
2539  << " " << setw(4) << jmax << "\n";
2540  }
2541  else
2542  {
2543  for ( jlo = jmin; jlo <= jmax; jlo = jlo + 5 )
2544  {
2545  jhi = i4_min ( jlo + 4, jmax );
2546 
2547  if ( jlo == jmin )
2548  {
2549  cout << " " << setw(4) << i+1
2550  << " " << setw(4) << jmin
2551  << " " << setw(4) << jmax
2552  << " ";
2553  for ( j = jlo; j <= jhi; j++ )
2554  {
2555  cout << setw(8) << level[j-1];
2556  }
2557  cout << "\n";
2558  }
2559  else
2560  {
2561  cout << " ";
2562  for ( j = jlo; j <= jhi; j++ )
2563  {
2564  cout << setw(8) << level[j-1];
2565  }
2566  cout << "\n";
2567  }
2568 
2569  }
2570  }
2571  }
2572 
2573  return;
2574 }
2575 //****************************************************************************80
2576 
2577 bool perm_check ( int n, int p[] )
2578 
2579 //****************************************************************************80
2580 //
2581 // Purpose:
2582 //
2583 // PERM_CHECK checks that a vector represents a permutation.
2584 //
2585 // Discussion:
2586 //
2587 // The routine verifies that each of the integers from 1
2588 // to N occurs among the N entries of the permutation.
2589 //
2590 // Licensing:
2591 //
2592 // This code is distributed under the GNU LGPL license.
2593 //
2594 // Modified:
2595 //
2596 // 13 January 2004
2597 //
2598 // Author:
2599 //
2600 // John Burkardt
2601 //
2602 // Parameters:
2603 //
2604 // Input, int N, the number of entries.
2605 //
2606 // Input, int P[N], the array to check.
2607 //
2608 // Output, bool PERM_CHECK, is TRUE if the permutation is OK.
2609 //
2610 {
2611  bool found;
2612  int i;
2613  int seek;
2614 
2615  for ( seek = 1; seek <= n; seek++ )
2616  {
2617  found = false;
2618 
2619  for ( i = 0; i < n; i++ )
2620  {
2621  if ( p[i] == seek )
2622  {
2623  found = true;
2624  break;
2625  }
2626  }
2627 
2628  if ( !found )
2629  {
2630  return false;
2631  }
2632 
2633  }
2634 
2635  return true;
2636 }
2637 //****************************************************************************80
2638 
2639 void perm_inverse3 ( int n, int perm[], int perm_inv[] )
2640 
2641 //****************************************************************************80
2642 //
2643 // Purpose:
2644 //
2645 // PERM_INVERSE3 produces the inverse of a given permutation.
2646 //
2647 // Licensing:
2648 //
2649 // This code is distributed under the GNU LGPL license.
2650 //
2651 // Modified:
2652 //
2653 // 05 January 2007
2654 //
2655 // Author:
2656 //
2657 // John Burkardt
2658 //
2659 // Parameters:
2660 //
2661 // Input, int N, the number of items permuted.
2662 //
2663 // Input, int PERM[N], a permutation.
2664 //
2665 // Output, int PERM_INV[N], the inverse permutation.
2666 //
2667 {
2668  int i;
2669 
2670  for ( i = 0; i < n; i++ )
2671  {
2672  perm_inv[perm[i]-1] = i + 1;
2673  }
2674 
2675  return;
2676 }
2677 //****************************************************************************80
2678 
2679 int *perm_uniform ( int n, int *seed )
2680 
2681 //****************************************************************************80
2682 //
2683 // Purpose:
2684 //
2685 // PERM_UNIFORM selects a random permutation of N objects.
2686 //
2687 // Licensing:
2688 //
2689 // This code is distributed under the GNU LGPL license.
2690 //
2691 // Modified:
2692 //
2693 // 13 January 2004
2694 //
2695 // Author:
2696 //
2697 // John Burkardt
2698 //
2699 // Reference:
2700 //
2701 // Albert Nijenhuis, Herbert Wilf,
2702 // Combinatorial Algorithms,
2703 // Academic Press, 1978, second edition,
2704 // ISBN 0-12-519260-6.
2705 //
2706 // Parameters:
2707 //
2708 // Input, int N, the number of objects to be permuted.
2709 //
2710 // Input/output, int *SEED, a seed for the random number generator.
2711 //
2712 // Output, int PERM_UNIFORM[N], a permutation of (1,, 1, ..., N).
2713 //
2714 {
2715  int i;
2716  int j;
2717  int *p;
2718 
2719  p = new int[n];
2720 
2721  for ( i = 1; i <= n; i++ )
2722  {
2723  p[i-1] = i;
2724  }
2725 
2726  for ( i = 1; i <= n; i++ )
2727  {
2728  j = i4_uniform ( i, n, seed );
2729  i4_swap ( &p[i-1], &p[j-1] );
2730  }
2731 
2732  return p;
2733 }
2734 //****************************************************************************80
2735 
2736 float r4_abs ( float x )
2737 
2738 //****************************************************************************80
2739 //
2740 // Purpose:
2741 //
2742 // R4_ABS returns the absolute value of an R4.
2743 //
2744 // Licensing:
2745 //
2746 // This code is distributed under the GNU LGPL license.
2747 //
2748 // Modified:
2749 //
2750 // 01 December 2006
2751 //
2752 // Author:
2753 //
2754 // John Burkardt
2755 //
2756 // Parameters:
2757 //
2758 // Input, float X, the quantity whose absolute value is desired.
2759 //
2760 // Output, float R4_ABS, the absolute value of X.
2761 //
2762 {
2763  float value;
2764 
2765  if ( 0.0 <= x )
2766  {
2767  value = x;
2768  }
2769  else
2770  {
2771  value = -x;
2772  }
2773  return value;
2774 }
2775 //****************************************************************************80
2776 
2777 int r4_nint ( float x )
2778 
2779 //****************************************************************************80
2780 //
2781 // Purpose:
2782 //
2783 // R4_NINT returns the nearest integer to an R4.
2784 //
2785 // Examples:
2786 //
2787 // X R4_NINT
2788 //
2789 // 1.3 1
2790 // 1.4 1
2791 // 1.5 1 or 2
2792 // 1.6 2
2793 // 0.0 0
2794 // -0.7 -1
2795 // -1.1 -1
2796 // -1.6 -2
2797 //
2798 // Licensing:
2799 //
2800 // This code is distributed under the GNU LGPL license.
2801 //
2802 // Modified:
2803 //
2804 // 14 November 2006
2805 //
2806 // Author:
2807 //
2808 // John Burkardt
2809 //
2810 // Parameters:
2811 //
2812 // Input, float X, the value.
2813 //
2814 // Output, int R4_NINT, the nearest integer to X.
2815 //
2816 {
2817  int value;
2818 
2819  if ( x < 0.0 )
2820  {
2821  value = - ( int ) ( r4_abs ( x ) + 0.5 );
2822  }
2823  else
2824  {
2825  value = ( int ) ( r4_abs ( x ) + 0.5 );
2826  }
2827 
2828  return value;
2829 }
2830 //****************************************************************************80
2831 
2832 void r82vec_permute ( int n, double a[], int p[] )
2833 
2834 //****************************************************************************80
2835 //
2836 // Purpose:
2837 //
2838 // R82VEC_PERMUTE permutes an R82VEC in place.
2839 //
2840 // Discussion:
2841 //
2842 // An R82VEC is a vector whose entries are R82's.
2843 // An R82 is a vector of type double precision with two entries.
2844 // An R82VEC may be stored as a 2 by N array.
2845 //
2846 // This routine permutes an array of real "objects", but the same
2847 // logic can be used to permute an array of objects of any arithmetic
2848 // type, or an array of objects of any complexity. The only temporary
2849 // storage required is enough to store a single object. The number
2850 // of data movements made is N + the number of cycles of order 2 or more,
2851 // which is never more than N + N/2.
2852 //
2853 // Example:
2854 //
2855 // Input:
2856 //
2857 // N = 5
2858 // P = ( 2, 4, 5, 1, 3 )
2859 // A = ( 1.0, 2.0, 3.0, 4.0, 5.0 )
2860 // (11.0, 22.0, 33.0, 44.0, 55.0 )
2861 //
2862 // Output:
2863 //
2864 // A = ( 2.0, 4.0, 5.0, 1.0, 3.0 )
2865 // ( 22.0, 44.0, 55.0, 11.0, 33.0 ).
2866 //
2867 // Licensing:
2868 //
2869 // This code is distributed under the GNU LGPL license.
2870 //
2871 // Modified:
2872 //
2873 // 19 February 2004
2874 //
2875 // Author:
2876 //
2877 // John Burkardt
2878 //
2879 // Parameters:
2880 //
2881 // Input, int N, the number of objects.
2882 //
2883 // Input/output, double A[2*N], the array to be permuted.
2884 //
2885 // Input, int P[N], the permutation. P(I) = J means
2886 // that the I-th element of the output array should be the J-th
2887 // element of the input array. P must be a legal permutation
2888 // of the integers from 1 to N, otherwise the algorithm will
2889 // fail catastrophically.
2890 //
2891 {
2892  double a_temp[2];
2893  int i;
2894  int iget;
2895  int iput;
2896  int istart;
2897 
2898  if ( !perm_check ( n, p ) )
2899  {
2900  cout << "\n";
2901  cout << "R82VEC_PERMUTE - Fatal error!\n";
2902  cout << " The input array does not represent\n";
2903  cout << " a proper permutation.\n";
2904  i4vec_print ( n, p, " The faulty permutation:" );
2905  exit ( 1 );
2906  }
2907 //
2908 // Search for the next element of the permutation that has not been used.
2909 //
2910  for ( istart = 1; istart <= n; istart++ )
2911  {
2912  if ( p[istart-1] < 0 )
2913  {
2914  continue;
2915  }
2916  else if ( p[istart-1] == istart )
2917  {
2918  p[istart-1] = -p[istart-1];
2919  continue;
2920  }
2921  else
2922  {
2923  a_temp[0] = a[0+(istart-1)*2];
2924  a_temp[1] = a[1+(istart-1)*2];
2925  iget = istart;
2926 //
2927 // Copy the new value into the vacated entry.
2928 //
2929  for ( ; ; )
2930  {
2931  iput = iget;
2932  iget = p[iget-1];
2933 
2934  p[iput-1] = -p[iput-1];
2935 
2936  if ( iget < 1 || n < iget )
2937  {
2938  cout << "\n";
2939  cout << "R82VEC_PERMUTE - Fatal error!\n";
2940  cout << " Entry IPUT = " << iput << " of the permutation has\n";
2941  cout << " an illegal value IGET = " << iget << ".\n";
2942  exit ( 1 );
2943  }
2944 
2945  if ( iget == istart )
2946  {
2947  a[0+(iput-1)*2] = a_temp[0];
2948  a[1+(iput-1)*2] = a_temp[1];
2949  break;
2950  }
2951  a[0+(iput-1)*2] = a[0+(iget-1)*2];
2952  a[1+(iput-1)*2] = a[1+(iget-1)*2];
2953  }
2954  }
2955  }
2956 //
2957 // Restore the signs of the entries.
2958 //
2959  for ( i = 0; i < n; i++ )
2960  {
2961  p[i] = -p[i];
2962  }
2963 
2964  return;
2965 }
2966 //****************************************************************************80
2967 
2968 void r8mat_print_some ( int m, int n, double a[], int ilo, int jlo, int ihi,
2969  int jhi, string title )
2970 
2971 //****************************************************************************80
2972 //
2973 // Purpose:
2974 //
2975 // R8MAT_PRINT_SOME prints some of an R8MAT.
2976 //
2977 // Licensing:
2978 //
2979 // This code is distributed under the GNU LGPL license.
2980 //
2981 // Modified:
2982 //
2983 // 09 April 2004
2984 //
2985 // Author:
2986 //
2987 // John Burkardt
2988 //
2989 // Parameters:
2990 //
2991 // Input, int M, the number of rows of the matrix.
2992 // M must be positive.
2993 //
2994 // Input, int N, the number of columns of the matrix.
2995 // N must be positive.
2996 //
2997 // Input, double A[M*N], the matrix.
2998 //
2999 // Input, int ILO, JLO, IHI, JHI, designate the first row and
3000 // column, and the last row and column to be printed.
3001 //
3002 // Input, string TITLE, a title.
3003 {
3004 # define INCX 5
3005 
3006  int i;
3007  int i2hi;
3008  int i2lo;
3009  int j;
3010  int j2hi;
3011  int j2lo;
3012 
3013  cout << "\n";
3014  cout << title << "\n";
3015 //
3016 // Print the columns of the matrix, in strips of 5.
3017 //
3018  for ( j2lo = jlo; j2lo <= jhi; j2lo = j2lo + INCX )
3019  {
3020  j2hi = j2lo + INCX - 1;
3021  j2hi = i4_min ( j2hi, n );
3022  j2hi = i4_min ( j2hi, jhi );
3023 
3024  cout << "\n";
3025 //
3026 // For each column J in the current range...
3027 //
3028 // Write the header.
3029 //
3030  cout << " Col: ";
3031  for ( j = j2lo; j <= j2hi; j++ )
3032  {
3033  cout << setw(7) << j << " ";
3034  }
3035  cout << "\n";
3036  cout << " Row\n";
3037  cout << "\n";
3038 //
3039 // Determine the range of the rows in this strip.
3040 //
3041  i2lo = i4_max ( ilo, 1 );
3042  i2hi = i4_min ( ihi, m );
3043 
3044  for ( i = i2lo; i <= i2hi; i++ )
3045  {
3046 //
3047 // Print out (up to) 5 entries in row I, that lie in the current strip.
3048 //
3049  cout << setw(5) << i << " ";
3050  for ( j = j2lo; j <= j2hi; j++ )
3051  {
3052  cout << setw(12) << a[i-1+(j-1)*m] << " ";
3053  }
3054  cout << "\n";
3055  }
3056 
3057  }
3058 
3059  cout << "\n";
3060 
3061  return;
3062 # undef INCX
3063 }
3064 //****************************************************************************80
3065 
3066 void r8mat_transpose_print_some ( int m, int n, double a[], int ilo, int jlo,
3067  int ihi, int jhi, string title )
3068 
3069 //****************************************************************************80
3070 //
3071 // Purpose:
3072 //
3073 // R8MAT_TRANSPOSE_PRINT_SOME prints some of an R8MAT, transposed.
3074 //
3075 // Licensing:
3076 //
3077 // This code is distributed under the GNU LGPL license.
3078 //
3079 // Modified:
3080 //
3081 // 11 August 2004
3082 //
3083 // Author:
3084 //
3085 // John Burkardt
3086 //
3087 // Parameters:
3088 //
3089 // Input, int M, N, the number of rows and columns.
3090 //
3091 // Input, double A[M*N], an M by N matrix to be printed.
3092 //
3093 // Input, int ILO, JLO, the first row and column to print.
3094 //
3095 // Input, int IHI, JHI, the last row and column to print.
3096 //
3097 // Input, string TITLE, a title.
3098 //
3099 {
3100 # define INCX 5
3101 
3102  int i;
3103  int i2;
3104  int i2hi;
3105  int i2lo;
3106  int inc;
3107  int j;
3108  int j2hi;
3109  int j2lo;
3110 
3111  cout << "\n";
3112  cout << title << "\n";
3113 
3114  for ( i2lo = i4_max ( ilo, 1 ); i2lo <= i4_min ( ihi, m ); i2lo = i2lo + INCX )
3115  {
3116  i2hi = i2lo + INCX - 1;
3117  i2hi = i4_min ( i2hi, m );
3118  i2hi = i4_min ( i2hi, ihi );
3119 
3120  inc = i2hi + 1 - i2lo;
3121 
3122  cout << "\n";
3123  cout << " Row: ";
3124  for ( i = i2lo; i <= i2hi; i++ )
3125  {
3126  cout << setw(7) << i << " ";
3127  }
3128  cout << "\n";
3129  cout << " Col\n";
3130  cout << "\n";
3131 
3132  j2lo = i4_max ( jlo, 1 );
3133  j2hi = i4_min ( jhi, n );
3134 
3135  for ( j = j2lo; j <= j2hi; j++ )
3136  {
3137  cout << setw(5) << j << " ";
3138  for ( i2 = 1; i2 <= inc; i2++ )
3139  {
3140  i = i2lo - 1 + i2;
3141  cout << setw(14) << a[(i-1)+(j-1)*m];
3142  }
3143  cout << "\n";
3144  }
3145  }
3146  cout << "\n";
3147 
3148  return;
3149 # undef INCX
3150 }
3151 //****************************************************************************80
3152 
3153 void rcm ( int root, int adj_num, int adj_row[], int adj[], int mask[],
3154  int perm[], int *iccsze, int node_num )
3155 
3156 //****************************************************************************80
3157 //
3158 // Purpose:
3159 //
3160 // RCM renumbers a connected component by the reverse Cuthill McKee algorithm.
3161 //
3162 // Discussion:
3163 //
3164 // The connected component is specified by a node ROOT and a mask.
3165 // The numbering starts at the root node.
3166 //
3167 // An outline of the algorithm is as follows:
3168 //
3169 // X(1) = ROOT.
3170 //
3171 // for ( I = 1 to N-1)
3172 // Find all unlabeled neighbors of X(I),
3173 // assign them the next available labels, in order of increasing degree.
3174 //
3175 // When done, reverse the ordering.
3176 //
3177 // Licensing:
3178 //
3179 // This code is distributed under the GNU LGPL license.
3180 //
3181 // Modified:
3182 //
3183 // 05 January 2007
3184 //
3185 // Author:
3186 //
3187 // Original FORTRAN77 version by Alan George, Joseph Liu.
3188 // C++ version by John Burkardt.
3189 //
3190 // Reference:
3191 //
3192 // Alan George, Joseph Liu,
3193 // Computer Solution of Large Sparse Positive Definite Systems,
3194 // Prentice Hall, 1981.
3195 //
3196 // Parameters:
3197 //
3198 // Input, int ROOT, the node that defines the connected component.
3199 // It is used as the starting point for the RCM ordering.
3200 //
3201 // Input, int ADJ_NUM, the number of adjacency entries.
3202 //
3203 // Input, int ADJ_ROW(NODE_NUM+1). Information about row I is stored
3204 // in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
3205 //
3206 // Input, int ADJ(ADJ_NUM), the adjacency structure.
3207 // For each row, it contains the column indices of the nonzero entries.
3208 //
3209 // Input/output, int MASK(NODE_NUM), a mask for the nodes. Only
3210 // those nodes with nonzero input mask values are considered by the
3211 // routine. The nodes numbered by RCM will have their mask values
3212 // set to zero.
3213 //
3214 // Output, int PERM(NODE_NUM), the RCM ordering.
3215 //
3216 // Output, int ICCSZE, the size of the connected component
3217 // that has been numbered.
3218 //
3219 // Input, int NODE_NUM, the number of nodes.
3220 //
3221 // Local Parameters:
3222 //
3223 // Workspace, int DEG[NODE_NUM], a temporary vector used to hold
3224 // the degree of the nodes in the section graph specified by mask and root.
3225 //
3226 {
3227  int *deg;
3228  int fnbr;
3229  int i;
3230  int j;
3231  int jstop;
3232  int jstrt;
3233  int k;
3234  int l;
3235  int lbegin;
3236  int lnbr;
3237  int lperm;
3238  int lvlend;
3239  int nbr;
3240  int node;
3241 //
3242 // Find the degrees of the nodes in the component specified by MASK and ROOT.
3243 //
3244  deg = new int[node_num];
3245 
3246  degree ( root, adj_num, adj_row, adj, mask, deg, iccsze, perm, node_num );
3247 
3248  mask[root-1] = 0;
3249 
3250  if ( *iccsze <= 1 )
3251  {
3252  delete [] deg;
3253  return;
3254  }
3255 
3256  lvlend = 0;
3257  lnbr = 1;
3258 //
3259 // LBEGIN and LVLEND point to the beginning and
3260 // the end of the current level respectively.
3261 //
3262  while ( lvlend < lnbr )
3263  {
3264  lbegin = lvlend + 1;
3265  lvlend = lnbr;
3266 
3267  for ( i = lbegin; i <= lvlend; i++ )
3268  {
3269 //
3270 // For each node in the current level...
3271 //
3272  node = perm[i-1];
3273  jstrt = adj_row[node-1];
3274  jstop = adj_row[node] - 1;
3275 //
3276 // Find the unnumbered neighbors of NODE.
3277 //
3278 // FNBR and LNBR point to the first and last neighbors
3279 // of the current node in PERM.
3280 //
3281  fnbr = lnbr + 1;
3282 
3283  for ( j = jstrt; j <= jstop; j++ )
3284  {
3285  nbr = adj[j-1];
3286 
3287  if ( mask[nbr-1] != 0 )
3288  {
3289  lnbr = lnbr + 1;
3290  mask[nbr-1] = 0;
3291  perm[lnbr-1] = nbr;
3292  }
3293  }
3294 //
3295 // If no neighbors, skip to next node in this level.
3296 //
3297  if ( lnbr <= fnbr )
3298  {
3299  continue;
3300  }
3301 //
3302 // Sort the neighbors of NODE in increasing order by degree.
3303 // Linear insertion is used.
3304 //
3305  k = fnbr;
3306 
3307  while ( k < lnbr )
3308  {
3309  l = k;
3310  k = k + 1;
3311  nbr = perm[k-1];
3312 
3313  while ( fnbr < l )
3314  {
3315  lperm = perm[l-1];
3316 
3317  if ( deg[lperm-1] <= deg[nbr-1] )
3318  {
3319  break;
3320  }
3321 
3322  perm[l] = lperm;
3323  l = l - 1;
3324  }
3325  perm[l] = nbr;
3326  }
3327  }
3328  }
3329 //
3330 // We now have the Cuthill-McKee ordering. Reverse it.
3331 //
3332  i4vec_reverse ( *iccsze, perm );
3333 
3334  delete [] deg;
3335 
3336  return;
3337 }
3338 //****************************************************************************80
3339 
3340 void root_find ( int *root, int adj_num, int adj_row[], int adj[], int mask[],
3341  int *level_num, int level_row[], int level[], int node_num )
3342 
3343 //****************************************************************************80
3344 //
3345 // Purpose:
3346 //
3347 // ROOT_FIND finds a pseudo-peripheral node.
3348 //
3349 // Discussion:
3350 //
3351 // The diameter of a graph is the maximum distance (number of edges)
3352 // between any two nodes of the graph.
3353 //
3354 // The eccentricity of a node is the maximum distance between that
3355 // node and any other node of the graph.
3356 //
3357 // A peripheral node is a node whose eccentricity equals the
3358 // diameter of the graph.
3359 //
3360 // A pseudo-peripheral node is an approximation to a peripheral node;
3361 // it may be a peripheral node, but all we know is that we tried our
3362 // best.
3363 //
3364 // The routine is given a graph, and seeks pseudo-peripheral nodes,
3365 // using a modified version of the scheme of Gibbs, Poole and
3366 // Stockmeyer. It determines such a node for the section subgraph
3367 // specified by MASK and ROOT.
3368 //
3369 // The routine also determines the level structure associated with
3370 // the given pseudo-peripheral node; that is, how far each node
3371 // is from the pseudo-peripheral node. The level structure is
3372 // returned as a list of nodes LS, and pointers to the beginning
3373 // of the list of nodes that are at a distance of 0, 1, 2, ...,
3374 // NODE_NUM-1 from the pseudo-peripheral node.
3375 //
3376 // Licensing:
3377 //
3378 // This code is distributed under the GNU LGPL license.
3379 //
3380 // Modified:
3381 //
3382 // 05 January 2007
3383 //
3384 // Author:
3385 //
3386 // Original FORTRAN77 version by Alan George, Joseph Liu.
3387 // C++ version by John Burkardt.
3388 //
3389 // Reference:
3390 //
3391 // Alan George, Joseph Liu,
3392 // Computer Solution of Large Sparse Positive Definite Systems,
3393 // Prentice Hall, 1981.
3394 //
3395 // Norman Gibbs, William Poole, Paul Stockmeyer,
3396 // An Algorithm for Reducing the Bandwidth and Profile of a Sparse Matrix,
3397 // SIAM Journal on Numerical Analysis,
3398 // Volume 13, pages 236-250, 1976.
3399 //
3400 // Norman Gibbs,
3401 // Algorithm 509: A Hybrid Profile Reduction Algorithm,
3402 // ACM Transactions on Mathematical Software,
3403 // Volume 2, pages 378-387, 1976.
3404 //
3405 // Parameters:
3406 //
3407 // Input/output, int *ROOT. On input, ROOT is a node in the
3408 // the component of the graph for which a pseudo-peripheral node is
3409 // sought. On output, ROOT is the pseudo-peripheral node obtained.
3410 //
3411 // Input, int ADJ_NUM, the number of adjacency entries.
3412 //
3413 // Input, int ADJ_ROW[NODE_NUM+1]. Information about row I is stored
3414 // in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.
3415 //
3416 // Input, int ADJ[ADJ_NUM], the adjacency structure.
3417 // For each row, it contains the column indices of the nonzero entries.
3418 //
3419 // Input, int MASK[NODE_NUM], specifies a section subgraph. Nodes
3420 // for which MASK is zero are ignored by FNROOT.
3421 //
3422 // Output, int *LEVEL_NUM, is the number of levels in the level structure
3423 // rooted at the node ROOT.
3424 //
3425 // Output, int LEVEL_ROW(NODE_NUM+1), LEVEL(NODE_NUM), the
3426 // level structure array pair containing the level structure found.
3427 //
3428 // Input, int NODE_NUM, the number of nodes.
3429 //
3430 {
3431  int iccsze;
3432  int j;
3433  int jstrt;
3434  int k;
3435  int kstop;
3436  int kstrt;
3437  int level_num2;
3438  int mindeg;
3439  int nabor;
3440  int ndeg;
3441  int node;
3442 //
3443 // Determine the level structure rooted at ROOT.
3444 //
3445  level_set ( *root, adj_num, adj_row, adj, mask, level_num,
3446  level_row, level, node_num );
3447 //
3448 // Count the number of nodes in this level structure.
3449 //
3450  iccsze = level_row[*level_num] - 1;
3451 //
3452 // Extreme case:
3453 // A complete graph has a level set of only a single level.
3454 // Every node is equally good (or bad).
3455 //
3456  if ( *level_num == 1 )
3457  {
3458  return;
3459  }
3460 //
3461 // Extreme case:
3462 // A "line graph" 0--0--0--0--0 has every node in its only level.
3463 // By chance, we've stumbled on the ideal root.
3464 //
3465  if ( *level_num == iccsze )
3466  {
3467  return;
3468  }
3469 //
3470 // Pick any node from the last level that has minimum degree
3471 // as the starting point to generate a new level set.
3472 //
3473  for ( ; ; )
3474  {
3475  mindeg = iccsze;
3476 
3477  jstrt = level_row[*level_num-1];
3478  *root = level[jstrt-1];
3479 
3480  if ( jstrt < iccsze )
3481  {
3482  for ( j = jstrt; j <= iccsze; j++ )
3483  {
3484  node = level[j-1];
3485  ndeg = 0;
3486  kstrt = adj_row[node-1];
3487  kstop = adj_row[node] - 1;
3488 
3489  for ( k = kstrt; k <= kstop; k++ )
3490  {
3491  nabor = adj[k-1];
3492  if ( 0 < mask[nabor-1] )
3493  {
3494  ndeg = ndeg + 1;
3495  }
3496  }
3497 
3498  if ( ndeg < mindeg )
3499  {
3500  *root = node;
3501  mindeg = ndeg;
3502  }
3503  }
3504  }
3505 //
3506 // Generate the rooted level structure associated with this node.
3507 //
3508  level_set ( *root, adj_num, adj_row, adj, mask, &level_num2,
3509  level_row, level, node_num );
3510 //
3511 // If the number of levels did not increase, accept the new ROOT.
3512 //
3513  if ( level_num2 <= *level_num )
3514  {
3515  break;
3516  }
3517 
3518  *level_num = level_num2;
3519 //
3520 // In the unlikely case that ROOT is one endpoint of a line graph,
3521 // we can exit now.
3522 //
3523  if ( iccsze <= *level_num )
3524  {
3525  break;
3526  }
3527  }
3528 
3529  return;
3530 }
3531 //****************************************************************************80
3532 
3533 void sort_heap_external ( int n, int *indx, int *i, int *j, int isgn )
3534 
3535 //****************************************************************************80
3536 //
3537 // Purpose:
3538 //
3539 // SORT_HEAP_EXTERNAL externally sorts a list of items into ascending order.
3540 //
3541 // Discussion:
3542 //
3543 // The actual list is not passed to the routine. Hence it may
3544 // consist of integers, reals, numbers, names, etc. The user,
3545 // after each return from the routine, will be asked to compare or
3546 // interchange two items.
3547 //
3548 // The current version of this code mimics the FORTRAN version,
3549 // so the values of I and J, in particular, are FORTRAN indices.
3550 //
3551 // Licensing:
3552 //
3553 // This code is distributed under the GNU LGPL license.
3554 //
3555 // Modified:
3556 //
3557 // 05 February 2004
3558 //
3559 // Author:
3560 //
3561 // Original FORTRAN77 version by Albert Nijenhuis, Herbert Wilf.
3562 // C++ version by John Burkardt.
3563 //
3564 // Parameters:
3565 //
3566 // Input, int N, the length of the input list.
3567 //
3568 // Input/output, int *INDX.
3569 // The user must set INDX to 0 before the first call.
3570 // On return,
3571 // if INDX is greater than 0, the user must interchange
3572 // items I and J and recall the routine.
3573 // If INDX is less than 0, the user is to compare items I
3574 // and J and return in ISGN a negative value if I is to
3575 // precede J, and a positive value otherwise.
3576 // If INDX is 0, the sorting is done.
3577 //
3578 // Output, int *I, *J. On return with INDX positive,
3579 // elements I and J of the user's list should be
3580 // interchanged. On return with INDX negative, elements I
3581 // and J are to be compared by the user.
3582 //
3583 // Input, int ISGN. On return with INDX negative, the
3584 // user should compare elements I and J of the list. If
3585 // item I is to precede item J, set ISGN negative,
3586 // otherwise set ISGN positive.
3587 //
3588 {
3589  static int i_save = 0;
3590  static int j_save = 0;
3591  static int k = 0;
3592  static int k1 = 0;
3593  static int n1 = 0;
3594 //
3595 // INDX = 0: This is the first call.
3596 //
3597  if ( *indx == 0 )
3598  {
3599 
3600  i_save = 0;
3601  j_save = 0;
3602  k = n / 2;
3603  k1 = k;
3604  n1 = n;
3605  }
3606 //
3607 // INDX < 0: The user is returning the results of a comparison.
3608 //
3609  else if ( *indx < 0 )
3610  {
3611  if ( *indx == -2 )
3612  {
3613  if ( isgn < 0 )
3614  {
3615  i_save = i_save + 1;
3616  }
3617  j_save = k1;
3618  k1 = i_save;
3619  *indx = -1;
3620  *i = i_save;
3621  *j = j_save;
3622  return;
3623  }
3624 
3625  if ( 0 < isgn )
3626  {
3627  *indx = 2;
3628  *i = i_save;
3629  *j = j_save;
3630  return;
3631  }
3632 
3633  if ( k <= 1 )
3634  {
3635  if ( n1 == 1 )
3636  {
3637  i_save = 0;
3638  j_save = 0;
3639  *indx = 0;
3640  }
3641  else
3642  {
3643  i_save = n1;
3644  j_save = 1;
3645  n1 = n1 - 1;
3646  *indx = 1;
3647  }
3648  *i = i_save;
3649  *j = j_save;
3650  return;
3651  }
3652 
3653  k = k - 1;
3654  k1 = k;
3655 
3656  }
3657 //
3658 // 0 < INDX: the user was asked to make an interchange.
3659 //
3660  else if ( *indx == 1 )
3661  {
3662  k1 = k;
3663  }
3664 
3665  for ( ;; )
3666  {
3667 
3668  i_save = 2 * k1;
3669 
3670  if ( i_save == n1 )
3671  {
3672  j_save = k1;
3673  k1 = i_save;
3674  *indx = -1;
3675  *i = i_save;
3676  *j = j_save;
3677  return;
3678  }
3679  else if ( i_save <= n1 )
3680  {
3681  j_save = i_save + 1;
3682  *indx = -2;
3683  *i = i_save;
3684  *j = j_save;
3685  return;
3686  }
3687 
3688  if ( k <= 1 )
3689  {
3690  break;
3691  }
3692 
3693  k = k - 1;
3694  k1 = k;
3695  }
3696 
3697  if ( n1 == 1 )
3698  {
3699  i_save = 0;
3700  j_save = 0;
3701  *indx = 0;
3702  *i = i_save;
3703  *j = j_save;
3704  }
3705  else
3706  {
3707  i_save = n1;
3708  j_save = 1;
3709  n1 = n1 - 1;
3710  *indx = 1;
3711  *i = i_save;
3712  *j = j_save;
3713  }
3714 
3715  return;
3716 }
3717 //****************************************************************************80
3718 
3719 void timestamp ( void )
3720 
3721 //****************************************************************************80
3722 //
3723 // Purpose:
3724 //
3725 // TIMESTAMP prints the current YMDHMS date as a time stamp.
3726 //
3727 // Example:
3728 //
3729 // May 31 2001 09:45:54 AM
3730 //
3731 // Licensing:
3732 //
3733 // This code is distributed under the GNU LGPL license.
3734 //
3735 // Modified:
3736 //
3737 // 03 October 2003
3738 //
3739 // Author:
3740 //
3741 // John Burkardt
3742 //
3743 // Parameters:
3744 //
3745 // None
3746 //
3747 {
3748 # define TIME_SIZE 40
3749 
3750  static char time_buffer[TIME_SIZE];
3751  const struct tm *tm;
3752  size_t len;
3753  time_t now;
3754 
3755  now = time ( NULL );
3756  tm = localtime ( &now );
3757 
3758  len = strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm );
3759 
3760  cout << time_buffer << "\n";
3761 
3762  return;
3763 # undef TIME_SIZE
3764 }
3765 //****************************************************************************80
3766 
3767 int *triangulation_neighbor_triangles ( int triangle_order, int triangle_num,
3768  int triangle_node[] )
3769 
3770 //****************************************************************************80
3771 //
3772 // Purpose:
3773 //
3774 // TRIANGULATION_ORDER3_NEIGHBOR_TRIANGLES determines triangle neighbors.
3775 //
3776 // Discussion:
3777 //
3778 // A triangulation of a set of nodes can be completely described by
3779 // the coordinates of the nodes, and the list of nodes that make up
3780 // each triangle. However, in some cases, it is necessary to know
3781 // triangle adjacency information, that is, which triangle, if any,
3782 // is adjacent to a given triangle on a particular side.
3783 //
3784 // This routine creates a data structure recording this information.
3785 //
3786 // The primary amount of work occurs in sorting a list of 3 * TRIANGLE_NUM
3787 // data items.
3788 //
3789 // This routine was modified to work with columns rather than rows.
3790 //
3791 // Example:
3792 //
3793 // The input information from TRIANGLE_NODE:
3794 //
3795 // Triangle Nodes
3796 // -------- ---------------
3797 // 1 3 4 1
3798 // 2 3 1 2
3799 // 3 3 2 8
3800 // 4 2 1 5
3801 // 5 8 2 13
3802 // 6 8 13 9
3803 // 7 3 8 9
3804 // 8 13 2 5
3805 // 9 9 13 7
3806 // 10 7 13 5
3807 // 11 6 7 5
3808 // 12 9 7 6
3809 // 13 10 9 6
3810 // 14 6 5 12
3811 // 15 11 6 12
3812 // 16 10 6 11
3813 //
3814 // The output information in TRIANGLE_NEIGHBOR:
3815 //
3816 // Triangle Neighboring Triangles
3817 // -------- ---------------------
3818 //
3819 // 1 -1 -1 2
3820 // 2 1 4 3
3821 // 3 2 5 7
3822 // 4 2 -1 8
3823 // 5 3 8 6
3824 // 6 5 9 7
3825 // 7 3 6 -1
3826 // 8 5 4 10
3827 // 9 6 10 12
3828 // 10 9 8 11
3829 // 11 12 10 14
3830 // 12 9 11 13
3831 // 13 -1 12 16
3832 // 14 11 -1 15
3833 // 15 16 14 -1
3834 // 16 13 15 -1
3835 //
3836 // Licensing:
3837 //
3838 // This code is distributed under the GNU LGPL license.
3839 //
3840 // Modified:
3841 //
3842 // 07 September 2009
3843 //
3844 // Author:
3845 //
3846 // John Burkardt
3847 //
3848 // Parameters:
3849 //
3850 // Input, int TRIANGLE_ORDER, the order of the triangles.
3851 //
3852 // Input, int TRIANGLE_NUM, the number of triangles.
3853 //
3854 // Input, int TRIANGLE_NODE[TRIANGLE_ORDER*TRIANGLE_NUM], the nodes that
3855 // make up each triangle.
3856 //
3857 // Output, int TRIANGLE_ORDER3_NEIGHBOR_TRIANGLES[3*TRIANGLE_NUM],
3858 // the three triangles
3859 // that are direct neighbors of a given triangle. TRIANGLE_NEIGHBOR(1,I)
3860 // is the index of the triangle which touches side 1, defined by nodes 2
3861 // and 3, and so on. TRIANGLE_NEIGHBOR(1,I) is negative if there is no
3862 // neighbor on that side. In this case, that side of the triangle lies
3863 // on the boundary of the triangulation.
3864 //
3865 {
3866  int *col;
3867  int i;
3868  int icol;
3869  int j;
3870  int k;
3871  int side1;
3872  int side2;
3873  int tri;
3874  int tri1;
3875  int tri2;
3876  int *triangle_neighbor;
3877 
3878  triangle_neighbor = new int[3*triangle_num];
3879  col = new int[4*(3*triangle_num)];
3880 //
3881 // Step 1.
3882 // From the list of nodes for triangle T, of the form: (I,J,K)
3883 // construct the three neighbor relations:
3884 //
3885 // (I,J,3,T) or (J,I,3,T),
3886 // (J,K,1,T) or (K,J,1,T),
3887 // (K,I,2,T) or (I,K,2,T)
3888 //
3889 // where we choose (I,J,3,T) if I < J, or else (J,I,3,T)
3890 //
3891  for ( tri = 0; tri < triangle_num; tri++ )
3892  {
3893  i = triangle_node[0+tri*triangle_order];
3894  j = triangle_node[1+tri*triangle_order];
3895  k = triangle_node[2+tri*triangle_order];
3896 
3897  if ( i < j )
3898  {
3899  col[0+(3*tri+0)*4] = i;
3900  col[1+(3*tri+0)*4] = j;
3901  col[2+(3*tri+0)*4] = 3;
3902  col[3+(3*tri+0)*4] = tri + 1;
3903  }
3904  else
3905  {
3906  col[0+(3*tri+0)*4] = j;
3907  col[1+(3*tri+0)*4] = i;
3908  col[2+(3*tri+0)*4] = 3;
3909  col[3+(3*tri+0)*4] = tri + 1;
3910  }
3911 
3912  if ( j < k )
3913  {
3914  col[0+(3*tri+1)*4] = j;
3915  col[1+(3*tri+1)*4] = k;
3916  col[2+(3*tri+1)*4] = 1;
3917  col[3+(3*tri+1)*4] = tri + 1;
3918  }
3919  else
3920  {
3921  col[0+(3*tri+1)*4] = k;
3922  col[1+(3*tri+1)*4] = j;
3923  col[2+(3*tri+1)*4] = 1;
3924  col[3+(3*tri+1)*4] = tri + 1;
3925  }
3926 
3927  if ( k < i )
3928  {
3929  col[0+(3*tri+2)*4] = k;
3930  col[1+(3*tri+2)*4] = i;
3931  col[2+(3*tri+2)*4] = 2;
3932  col[3+(3*tri+2)*4] = tri + 1;
3933  }
3934  else
3935  {
3936  col[0+(3*tri+2)*4] = i;
3937  col[1+(3*tri+2)*4] = k;
3938  col[2+(3*tri+2)*4] = 2;
3939  col[3+(3*tri+2)*4] = tri + 1;
3940  }
3941  }
3942 //
3943 // Step 2. Perform an ascending dictionary sort on the neighbor relations.
3944 // We only intend to sort on rows 1 and 2; the routine we call here
3945 // sorts on rows 1 through 4 but that won't hurt us.
3946 //
3947 // What we need is to find cases where two triangles share an edge.
3948 // Say they share an edge defined by the nodes I and J. Then there are
3949 // two columns of COL that start out ( I, J, ?, ? ). By sorting COL,
3950 // we make sure that these two columns occur consecutively. That will
3951 // make it easy to notice that the triangles are neighbors.
3952 //
3953  i4col_sort_a ( 4, 3*triangle_num, col );
3954 //
3955 // Step 3. Neighboring triangles show up as consecutive columns with
3956 // identical first two entries. Whenever you spot this happening,
3957 // make the appropriate entries in TRIANGLE_NEIGHBOR.
3958 //
3959  for ( j = 0; j < triangle_num; j++ )
3960  {
3961  for ( i = 0; i < 3; i++ )
3962  {
3963  triangle_neighbor[i+j*3] = -1;
3964  }
3965  }
3966 
3967  icol = 1;
3968 
3969  for ( ; ; )
3970  {
3971  if ( 3 * triangle_num <= icol )
3972  {
3973  break;
3974  }
3975 
3976  if ( col[0+(icol-1)*4] != col[0+icol*4] ||
3977  col[1+(icol-1)*4] != col[1+icol*4] )
3978  {
3979  icol = icol + 1;
3980  continue;
3981  }
3982 
3983  side1 = col[2+(icol-1)*4];
3984  tri1 = col[3+(icol-1)*4];
3985  side2 = col[2+ icol *4];
3986  tri2 = col[3+ icol *4];
3987 
3988  triangle_neighbor[side1-1+(tri1-1)*3] = tri2;
3989  triangle_neighbor[side2-1+(tri2-1)*3] = tri1;
3990 
3991  icol = icol + 2;
3992  }
3993 
3994  delete [] col;
3995 
3996  return triangle_neighbor;
3997 }
3998 //****************************************************************************80
3999 
4000 int triangulation_order3_adj_count ( int node_num, int triangle_num,
4001  int triangle_node[], int triangle_neighbor[], int adj_col[] )
4002 
4003 //****************************************************************************80
4004 //
4005 // Purpose:
4006 //
4007 // TRIANGULATION_ORDER3_ADJ_COUNT counts adjacencies in a triangulation.
4008 //
4009 // Discussion:
4010 //
4011 // This routine is called to count the adjacencies, so that the
4012 // appropriate amount of memory can be set aside for storage when
4013 // the adjacency structure is created.
4014 //
4015 // The triangulation is assumed to involve 3-node triangles.
4016 //
4017 // Two nodes are "adjacent" if they are both nodes in some triangle.
4018 // Also, a node is considered to be adjacent to itself.
4019 //
4020 // Diagram:
4021 //
4022 // 3
4023 // s |\
4024 // i | \
4025 // d | \
4026 // e | \ side 2
4027 // | \
4028 // 3 | \
4029 // | \
4030 // 1-------2
4031 //
4032 // side 1
4033 //
4034 // The local node numbering
4035 //
4036 //
4037 // 21-22-23-24-25
4038 // |\ |\ |\ |\ |
4039 // | \| \| \| \|
4040 // 16-17-18-19-20
4041 // |\ |\ |\ |\ |
4042 // | \| \| \| \|
4043 // 11-12-13-14-15
4044 // |\ |\ |\ |\ |
4045 // | \| \| \| \|
4046 // 6--7--8--9-10
4047 // |\ |\ |\ |\ |
4048 // | \| \| \| \|
4049 // 1--2--3--4--5
4050 //
4051 // A sample grid.
4052 //
4053 //
4054 // Below, we have a chart that summarizes the adjacency relationships
4055 // in the sample grid. On the left, we list the node, and its neighbors,
4056 // with an asterisk to indicate the adjacency of the node to itself
4057 // (in some cases, you want to count this self adjacency and in some
4058 // you don't). On the right, we list the number of adjancencies to
4059 // lower-indexed nodes, to the node itself, to higher-indexed nodes,
4060 // the total number of adjacencies for this node, and the location
4061 // of the first and last entries required to list this set of adjacencies
4062 // in a single list of all the adjacencies.
4063 //
4064 // N Adjacencies Below Self Above Total First Last
4065 //
4066 // -- -- -- -- -- -- -- -- -- -- -- -- --- 0
4067 // 1: * 2 6 0 1 2 3 1 3
4068 // 2: 1 * 3 6 7 1 1 3 5 4 8
4069 // 3: 2 * 4 7 8 1 1 3 5 9 13
4070 // 4: 3 * 5 8 9 1 1 3 5 14 18
4071 // 5: 4 * 9 10 1 1 2 4 19 22
4072 // 6: 1 2 * 7 11 2 1 2 5 23 27
4073 // 7: 2 3 6 * 8 11 12 3 1 3 7 28 34
4074 // 8: 3 4 7 * 9 12 13 3 1 3 7 35 41
4075 // 9: 4 5 8 * 10 13 14 3 1 3 7 42 48
4076 // 10: 5 9 * 14 15 2 1 2 5 49 53
4077 // 11: 6 7 * 12 16 2 1 2 5 54 58
4078 // 12: 7 8 11 * 13 16 17 3 1 3 7 59 65
4079 // 13: 8 9 12 * 14 17 18 3 1 3 7 66 72
4080 // 14: 9 10 13 * 15 18 19 3 1 3 7 73 79
4081 // 15: 10 14 * 19 20 2 1 2 5 80 84
4082 // 16: 11 12 * 17 21 2 1 2 5 85 89
4083 // 17: 12 13 16 * 18 21 22 3 1 3 7 90 96
4084 // 18: 13 14 17 * 19 22 23 3 1 3 7 97 103
4085 // 19: 14 15 18 * 20 23 24 3 1 3 7 104 110
4086 // 20: 15 19 * 24 25 2 1 2 5 111 115
4087 // 21: 16 17 * 22 2 1 1 4 116 119
4088 // 22: 17 18 21 * 23 3 1 1 5 120 124
4089 // 23: 18 19 22 * 24 3 1 1 5 125 129
4090 // 24: 19 20 23 * 25 3 1 1 5 130 134
4091 // 25: 20 24 * 2 1 0 3 135 137
4092 // -- -- -- -- -- -- -- -- -- -- -- -- 138 ---
4093 //
4094 // Licensing:
4095 //
4096 // This code is distributed under the GNU LGPL license.
4097 //
4098 // Modified:
4099 //
4100 // 25 August 2006
4101 //
4102 // Author:
4103 //
4104 // John Burkardt
4105 //
4106 // Parameters
4107 //
4108 // Input, int NODE_NUM, the number of nodes.
4109 //
4110 // Input, int TRIANGLE_NUM, the number of triangles.
4111 //
4112 // Input, int TRIANGLE_NODE[3*TRIANGLE_NUM], lists the nodes that
4113 // make up each triangle, in counterclockwise order.
4114 //
4115 // Input, int TRIANGLE_NEIGHBOR[3*TRIANGLE_NUM], for each side of
4116 // a triangle, lists the neighboring triangle, or -1 if there is
4117 // no neighbor.
4118 //
4119 // Output, TRIANGULATION_ORDER3_ADJ_COUNT, the number of adjacencies.
4120 //
4121 // Output, int ADJ_COL[NODE_NUM+1]. Information about column J is stored
4122 // in entries ADJ_COL(J) through ADJ_COL(J+1)-1 of ADJ.
4123 //
4124 {
4125  int adj_num;
4126  int i;
4127  int n1;
4128  int n2;
4129  int n3;
4130  int node;
4131  int triangle;
4132  int triangle_order = 3;
4133  int triangle2;
4134 
4135  adj_num = 0;
4136 //
4137 // Set every node to be adjacent to itself.
4138 //
4139  for ( node = 0; node < node_num; node++ )
4140  {
4141  adj_col[node] = 1;
4142  }
4143 //
4144 // Examine each triangle.
4145 //
4146  for ( triangle = 0; triangle < triangle_num; triangle++ )
4147  {
4148  n1 = triangle_node[0+triangle*triangle_order];
4149  n2 = triangle_node[1+triangle*triangle_order];
4150  n3 = triangle_node[2+triangle*triangle_order];
4151 //
4152 // Add edge (1,2) if this is the first occurrence,
4153 // that is, if the edge (1,2) is on a boundary (TRIANGLE2 <= 0)
4154 // or if this triangle is the first of the pair in which the edge
4155 // occurs (TRIANGLE < TRIANGLE2).
4156 //
4157  triangle2 = triangle_neighbor[0+triangle*3];
4158 
4159  if ( triangle2 < 0 || triangle < triangle2 )
4160  {
4161  adj_col[n1-1] = adj_col[n1-1] + 1;
4162  adj_col[n2-1] = adj_col[n2-1] + 1;
4163  }
4164 //
4165 // Add edge (2,3).
4166 //
4167  triangle2 = triangle_neighbor[1+triangle*3];
4168 
4169  if ( triangle2 < 0 || triangle < triangle2 )
4170  {
4171  adj_col[n2-1] = adj_col[n2-1] + 1;
4172  adj_col[n3-1] = adj_col[n3-1] + 1;
4173  }
4174 //
4175 // Add edge (3,1).
4176 //
4177  triangle2 = triangle_neighbor[2+triangle*3];
4178 
4179  if ( triangle2 < 0 || triangle < triangle2 )
4180  {
4181  adj_col[n1-1] = adj_col[n1-1] + 1;
4182  adj_col[n3-1] = adj_col[n3-1] + 1;
4183  }
4184  }
4185 //
4186 // We used ADJ_COL to count the number of entries in each column.
4187 // Convert it to pointers into the ADJ array.
4188 //
4189  for ( node = node_num; 1 <= node; node-- )
4190  {
4191  adj_col[node] = adj_col[node-1];
4192  }
4193  adj_col[0] = 1;
4194  for ( i = 1; i <= node_num; i++ )
4195  {
4196  adj_col[i]= adj_col[i-1] + adj_col[i];
4197  }
4198 
4199  adj_num = adj_col[node_num] - 1;
4200 
4201  return adj_num;
4202 }
4203 //****************************************************************************80
4204 
4205 int *triangulation_order3_adj_set ( int node_num, int triangle_num,
4206  int triangle_node[], int triangle_neighbor[], int adj_num, int adj_col[] )
4207 
4208 //****************************************************************************80
4209 //
4210 // Purpose:
4211 //
4212 // TRIANGULATION_ORDER3_ADJ_SET sets adjacencies in a triangulation.
4213 //
4214 // Discussion:
4215 //
4216 // This routine is called to count the adjacencies, so that the
4217 // appropriate amount of memory can be set aside for storage when
4218 // the adjacency structure is created.
4219 //
4220 // The triangulation is assumed to involve 3-node triangles.
4221 //
4222 // Two nodes are "adjacent" if they are both nodes in some triangle.
4223 // Also, a node is considered to be adjacent to itself.
4224 //
4225 // This routine can be used to create the compressed column storage
4226 // for a linear triangle finite element discretization of
4227 // Poisson's equation in two dimensions.
4228 //
4229 // Diagram:
4230 //
4231 // 3
4232 // s |\
4233 // i | \
4234 // d | \
4235 // e | \ side 2
4236 // | \
4237 // 3 | \
4238 // | \
4239 // 1-------2
4240 //
4241 // side 1
4242 //
4243 // The local node numbering
4244 //
4245 //
4246 // 21-22-23-24-25
4247 // |\ |\ |\ |\ |
4248 // | \| \| \| \|
4249 // 16-17-18-19-20
4250 // |\ |\ |\ |\ |
4251 // | \| \| \| \|
4252 // 11-12-13-14-15
4253 // |\ |\ |\ |\ |
4254 // | \| \| \| \|
4255 // 6--7--8--9-10
4256 // |\ |\ |\ |\ |
4257 // | \| \| \| \|
4258 // 1--2--3--4--5
4259 //
4260 // A sample grid
4261 //
4262 //
4263 // Below, we have a chart that summarizes the adjacency relationships
4264 // in the sample grid. On the left, we list the node, and its neighbors,
4265 // with an asterisk to indicate the adjacency of the node to itself
4266 // (in some cases, you want to count this self adjacency and in some
4267 // you don't). On the right, we list the number of adjancencies to
4268 // lower-indexed nodes, to the node itself, to higher-indexed nodes,
4269 // the total number of adjacencies for this node, and the location
4270 // of the first and last entries required to list this set of adjacencies
4271 // in a single list of all the adjacencies.
4272 //
4273 // N Adjacencies Below Self Above Total First Last
4274 //
4275 // -- -- -- -- -- -- -- -- -- -- -- -- --- 0
4276 // 1: * 2 6 0 1 2 3 1 3
4277 // 2: 1 * 3 6 7 1 1 3 5 4 8
4278 // 3: 2 * 4 7 8 1 1 3 5 9 13
4279 // 4: 3 * 5 8 9 1 1 3 5 14 18
4280 // 5: 4 * 9 10 1 1 2 4 19 22
4281 // 6: 1 2 * 7 11 2 1 2 5 23 27
4282 // 7: 2 3 6 * 8 11 12 3 1 3 7 28 34
4283 // 8: 3 4 7 * 9 12 13 3 1 3 7 35 41
4284 // 9: 4 5 8 * 10 13 14 3 1 3 7 42 48
4285 // 10: 5 9 * 14 15 2 1 2 5 49 53
4286 // 11: 6 7 * 12 16 2 1 2 5 54 58
4287 // 12: 7 8 11 * 13 16 17 3 1 3 7 59 65
4288 // 13: 8 9 12 * 14 17 18 3 1 3 7 66 72
4289 // 14: 9 10 13 * 15 18 19 3 1 3 7 73 79
4290 // 15: 10 14 * 19 20 2 1 2 5 80 84
4291 // 16: 11 12 * 17 21 2 1 2 5 85 89
4292 // 17: 12 13 16 * 18 21 22 3 1 3 7 90 96
4293 // 18: 13 14 17 * 19 22 23 3 1 3 7 97 103
4294 // 19: 14 15 18 * 20 23 24 3 1 3 7 104 110
4295 // 20: 15 19 * 24 25 2 1 2 5 111 115
4296 // 21: 16 17 * 22 2 1 1 4 116 119
4297 // 22: 17 18 21 * 23 3 1 1 5 120 124
4298 // 23: 18 19 22 * 24 3 1 1 5 125 129
4299 // 24: 19 20 23 * 25 3 1 1 5 130 134
4300 // 25: 20 24 * 2 1 0 3 135 137
4301 // -- -- -- -- -- -- -- -- -- -- -- -- 138 ---
4302 //
4303 // Licensing:
4304 //
4305 // This code is distributed under the GNU LGPL license.
4306 //
4307 // Modified:
4308 //
4309 // 25 August 2006
4310 //
4311 // Author:
4312 //
4313 // John Burkardt
4314 //
4315 // Parameters
4316 //
4317 // Input, int NODE_NUM, the number of nodes.
4318 //
4319 // Input, int TRIANGLE_NUM, the number of triangles.
4320 //
4321 // Input, int TRIANGLE_NODE[3*TRIANGLE_NUM], lists the nodes that
4322 // make up each triangle in counterclockwise order.
4323 //
4324 // Input, int TRIANGLE_NEIGHBOR[3*TRIANGLE_NUM], for each side of
4325 // a triangle, lists the neighboring triangle, or -1 if there is
4326 // no neighbor.
4327 //
4328 // Input, int ADJ_NUM, the number of adjacencies.
4329 //
4330 // Input, int ADJ_COL[NODE_NUM+1]. Information about column J is stored
4331 // in entries ADJ_COL(J) through ADJ_COL(J+1)-1 of ADJ.
4332 //
4333 // Output, int TRIANGULATION_ORDER3_ADJ_SET[ADJ_NUM], the adjacency
4334 // information.
4335 //
4336 {
4337  int *adj;
4338  int *adj_copy;
4339  int k;
4340  int k1;
4341  int k2;
4342  int n1;
4343  int n2;
4344  int n3;
4345  int node;
4346  int triangle;
4347  int triangle2;
4348  int triangle_order = 3;
4349 
4350  adj = new int[adj_num];
4351  for ( k = 0; k < adj_num; k++ )
4352  {
4353  adj[k] = -1;
4354  }
4355 
4356  adj_copy = new int[node_num];
4357  for ( node = 0; node < node_num; node++ )
4358  {
4359  adj_copy[node] = adj_col[node];
4360  }
4361 //
4362 // Set every node to be adjacent to itself.
4363 //
4364  for ( node = 1; node <= node_num; node++ )
4365  {
4366  adj[adj_copy[node-1]-1] = node;
4367  adj_copy[node-1] = adj_copy[node-1] + 1;
4368  }
4369 //
4370 // Examine each triangle.
4371 //
4372  for ( triangle = 0; triangle < triangle_num; triangle++ )
4373  {
4374  n1 = triangle_node[0+triangle*triangle_order];
4375  n2 = triangle_node[1+triangle*triangle_order];
4376  n3 = triangle_node[2+triangle*triangle_order];
4377 //
4378 // Add edge (1,2) if this is the first occurrence,
4379 // that is, if the edge (1,2) is on a boundary (TRIANGLE2 <= 0)
4380 // or if this triangle is the first of the pair in which the edge
4381 // occurs (TRIANGLE < TRIANGLE2).
4382 //
4383  triangle2 = triangle_neighbor[0+triangle*3];
4384 
4385  if ( triangle2 < 0 || triangle < triangle2 )
4386  {
4387  adj[adj_copy[n1-1]-1] = n2;
4388  adj_copy[n1-1] = adj_copy[n1-1] + 1;
4389  adj[adj_copy[n2-1]-1] = n1;
4390  adj_copy[n2-1] = adj_copy[n2-1] + 1;
4391  }
4392 //
4393 // Add edge (2,3).
4394 //
4395  triangle2 = triangle_neighbor[1+triangle*3];
4396 
4397  if ( triangle2 < 0 || triangle < triangle2 )
4398  {
4399  adj[adj_copy[n2-1]-1] = n3;
4400  adj_copy[n2-1] = adj_copy[n2-1] + 1;
4401  adj[adj_copy[n3-1]-1] = n2;
4402  adj_copy[n3-1] = adj_copy[n3-1] + 1;
4403  }
4404 //
4405 // Add edge (3,1).
4406 //
4407  triangle2 = triangle_neighbor[2+triangle*3];
4408 
4409  if ( triangle2 < 0 || triangle < triangle2 )
4410  {
4411  adj[adj_copy[n1-1]-1] = n3;
4412  adj_copy[n1-1] = adj_copy[n1-1] + 1;
4413  adj[adj_copy[n3-1]-1] = n1;
4414  adj_copy[n3-1] = adj_copy[n3-1] + 1;
4415  }
4416  }
4417 //
4418 // Ascending sort the entries for each node.
4419 //
4420  for ( node = 1; node <= node_num; node++ )
4421  {
4422  k1 = adj_col[node-1];
4423  k2 = adj_col[node]-1;
4424  i4vec_sort_heap_a ( k2+1-k1, adj+k1-1 );
4425  }
4426 
4427  delete [] adj_copy;
4428 
4429  return adj;
4430 }
4431 //****************************************************************************80
4432 
4433 void triangulation_order3_example2 ( int node_num, int triangle_num,
4434  double node_xy[], int triangle_node[], int triangle_neighbor[] )
4435 
4436 //****************************************************************************80
4437 //
4438 // Purpose:
4439 //
4440 // TRIANGULATION_ORDER3_EXAMPLE2 sets up a sample triangulation.
4441 //
4442 // Discussion:
4443 //
4444 // This triangulation is actually a Delaunay triangulation.
4445 //
4446 // The appropriate input values of NODE_NUM and TRIANGLE_NUM can be
4447 // determined by calling TRIANGULATION_ORDER3_EXAMPLE2_SIZE first.
4448 //
4449 // Diagram:
4450 //
4451 // 21-22-23-24-25
4452 // |\ |\ |\ |\ |
4453 // | \| \| \| \|
4454 // 16-17-18-19-20
4455 // |\ |\ |\ |\ |
4456 // | \| \| \| \|
4457 // 11-12-13-14-15
4458 // |\ |\ |\ |\ |
4459 // | \| \| \| \|
4460 // 6--7--8--9-10
4461 // |\ |\ |\ |\ |
4462 // | \| \| \| \|
4463 // 1--2--3--4--5
4464 //
4465 // Licensing:
4466 //
4467 // This code is distributed under the GNU LGPL license.
4468 //
4469 // Modified:
4470 //
4471 // 03 January 2007
4472 //
4473 // Author:
4474 //
4475 // John Burkardt
4476 //
4477 // Parameters:
4478 //
4479 // Input, int NODE_NUM, the number of nodes.
4480 //
4481 // Input, int TRIANGLE_NUM, the number of triangles.
4482 //
4483 // Output, double NODE_XY[2*NODE_NUM], the coordinates of the nodes.
4484 //
4485 // Output, int TRIANGLE_NODE[3*TRIANGLE_NUM], the nodes that make up the triangles.
4486 //
4487 // Output, int TRIANGLE_NEIGHBOR[3*TRIANGLE_NUM], the triangle neighbors on each side.
4488 // Negative values indicate edges that lie on the exterior.
4489 //
4490 {
4491 # define DIM_NUM 2
4492 # define NODE_NUM 25
4493 # define TRIANGLE_NUM 32
4494 # define TRIANGLE_ORDER 3
4495 
4496  int i;
4497  static int triangle_neighbor_save[3*TRIANGLE_NUM] = {
4498  -1, 2, -1,
4499  9, 1, 3,
4500  -1, 4, 2,
4501  11, 3, 5,
4502  -1, 6, 4,
4503  13, 5, 7,
4504  -1, 8, 6,
4505  15, 7, -1,
4506  2, 10, -1,
4507  17, 9, 11,
4508  4, 12, 10,
4509  19, 11, 13,
4510  6, 14, 12,
4511  21, 13, 15,
4512  8, 16, 14,
4513  23, 15, -1,
4514  10, 18, -1,
4515  25, 17, 19,
4516  12, 20, 18,
4517  27, 19, 21,
4518  14, 22, 20,
4519  29, 21, 23,
4520  16, 24, 22,
4521  31, 23, -1,
4522  18, 26, -1,
4523  -1, 25, 27,
4524  20, 28, 26,
4525  -1, 27, 29,
4526  22, 30, 28,
4527  -1, 29, 31,
4528  24, 32, 30,
4529  -1, 31, -1 };
4530  static int triangle_node_save[TRIANGLE_ORDER*TRIANGLE_NUM] = {
4531  1, 2, 6,
4532  7, 6, 2,
4533  2, 3, 7,
4534  8, 7, 3,
4535  3, 4, 8,
4536  9, 8, 4,
4537  4, 5, 9,
4538  10, 9, 5,
4539  6, 7, 11,
4540  12, 11, 7,
4541  7, 8, 12,
4542  13, 12, 8,
4543  8, 9, 13,
4544  14, 13, 9,
4545  9, 10, 14,
4546  15, 14, 10,
4547  11, 12, 16,
4548  17, 16, 12,
4549  12, 13, 17,
4550  18, 17, 13,
4551  13, 14, 18,
4552  19, 18, 14,
4553  14, 15, 19,
4554  20, 19, 15,
4555  16, 17, 21,
4556  22, 21, 17,
4557  17, 18, 22,
4558  23, 22, 18,
4559  18, 19, 23,
4560  24, 23, 19,
4561  19, 20, 24,
4562  25, 24, 20 };
4563  static double node_xy_save[DIM_NUM*NODE_NUM] = {
4564  0.0, 0.0,
4565  1.0, 0.0,
4566  2.0, 0.0,
4567  3.0, 0.0,
4568  4.0, 0.0,
4569  0.0, 1.0,
4570  1.0, 1.0,
4571  2.0, 1.0,
4572  3.0, 1.0,
4573  4.0, 1.0,
4574  0.0, 2.0,
4575  1.0, 2.0,
4576  2.0, 2.0,
4577  3.0, 2.0,
4578  4.0, 2.0,
4579  0.0, 3.0,
4580  1.0, 3.0,
4581  2.0, 3.0,
4582  3.0, 3.0,
4583  4.0, 3.0,
4584  0.0, 4.0,
4585  1.0, 4.0,
4586  2.0, 4.0,
4587  3.0, 4.0,
4588  4.0, 4.0 };
4589 
4590  for ( i = 0; i < 3 * TRIANGLE_NUM; i++ )
4591  {
4592  triangle_neighbor[i] = triangle_neighbor_save[i];
4593  }
4594 
4595  for ( i = 0; i < TRIANGLE_ORDER * TRIANGLE_NUM; i++ )
4596  {
4597  triangle_node[i] = triangle_node_save[i];
4598  }
4599 
4600  for ( i = 0; i < DIM_NUM * NODE_NUM; i++ )
4601  {
4602  node_xy[i] = node_xy_save[i];
4603  }
4604 
4605  return;
4606 # undef DIM_NUM
4607 # undef NODE_NUM
4608 # undef TRIANGLE_NUM
4609 # undef TRIANGLE_ORDER
4610 }
4611 //****************************************************************************80
4612 
4613 void triangulation_order3_example2_size ( int *node_num, int *triangle_num,
4614  int *hole_num )
4615 
4616 //****************************************************************************80
4617 //
4618 // Purpose:
4619 //
4620 // TRIANGULATION_ORDER3_EXAMPLE2_SIZE sets sizes for a sample triangulation.
4621 //
4622 // Diagram:
4623 //
4624 // 21-22-23-24-25
4625 // |\ |\ |\ |\ |
4626 // | \| \| \| \|
4627 // 16-17-18-19-20
4628 // |\ |\ |\ |\ |
4629 // | \| \| \| \|
4630 // 11-12-13-14-15
4631 // |\ |\ |\ |\ |
4632 // | \| \| \| \|
4633 // 6--7--8--9-10
4634 // |\ |\ |\ |\ |
4635 // | \| \| \| \|
4636 // 1--2--3--4--5
4637 //
4638 // Licensing:
4639 //
4640 // This code is distributed under the GNU LGPL license.
4641 //
4642 // Modified:
4643 //
4644 // 03 January 2007
4645 //
4646 // Author:
4647 //
4648 // John Burkardt
4649 //
4650 // Parameters:
4651 //
4652 // Output, int *NODE_NUM, the number of nodes.
4653 //
4654 // Output, int *TRIANGLE_NUM, the number of triangles.
4655 //
4656 // Output, int *HOLE_NUM, the number of holes.
4657 //
4658 {
4659  *node_num = 25;
4660  *triangle_num = 32;
4661  *hole_num = 0;
4662 
4663  return;
4664 }
4665 //****************************************************************************80
4666 
4667 int triangulation_order6_adj_count ( int node_num, int triangle_num,
4668  int triangle_node[], int triangle_neighbor[], int adj_col[] )
4669 
4670 //****************************************************************************80
4671 //
4672 // Purpose:
4673 //
4674 // TRIANGULATION_ORDER6_ADJ_COUNT counts adjacencies in a triangulation.
4675 //
4676 // Discussion:
4677 //
4678 // This routine is called to count the adjacencies, so that the
4679 // appropriate amount of memory can be set aside for storage when
4680 // the adjacency structure is created.
4681 //
4682 // The triangulation is assumed to involve 6-node triangles.
4683 //
4684 // Two nodes are "adjacent" if they are both nodes in some triangle.
4685 // Also, a node is considered to be adjacent to itself.
4686 //
4687 // Diagram:
4688 //
4689 // 3
4690 // s |\
4691 // i | \
4692 // d | \
4693 // e 6 5 side 2
4694 // | \
4695 // 3 | \
4696 // | \
4697 // 1---4---2
4698 //
4699 // side 1
4700 //
4701 // The local node numbering
4702 //
4703 //
4704 // 21-22-23-24-25
4705 // |\ |\ |
4706 // | \ | \ |
4707 // 16 17 18 19 20
4708 // | \ | \ |
4709 // | \| \|
4710 // 11-12-13-14-15
4711 // |\ |\ |
4712 // | \ | \ |
4713 // 6 7 8 9 10
4714 // | \ | \ |
4715 // | \| \|
4716 // 1--2--3--4--5
4717 //
4718 // A sample grid.
4719 //
4720 //
4721 // Below, we have a chart that lists the nodes adjacent to each node, with
4722 // an asterisk to indicate the adjacency of the node to itself
4723 // (in some cases, you want to count this self adjacency and in some
4724 // you don't).
4725 //
4726 // N Adjacencies
4727 //
4728 // 1: * 2 3 6 7 11
4729 // 2: 1 * 3 6 7 11
4730 // 3: 1 2 * 4 5 6 7 8 9 11 12 13
4731 // 4: 3 * 5 8 9 13
4732 // 5: 3 4 * 8 9 10 13 14 15
4733 // 6: 1 2 3 * 7 11
4734 // 7: 1 2 3 6 * 8 11 12 13
4735 // 8: 3 4 5 7 * 9 11 12 13
4736 // 9: 3 4 5 8 * 10 13 14 15
4737 // 10: 5 9 * 13 14 15
4738 // 11: 1 2 3 6 7 8 * 12 13 16 17 21
4739 // 12: 3 7 8 11 * 13 16 17 21
4740 // 13: 3 4 5 7 8 9 10 11 12 * 14 15 16 17 18 19 21 22 23
4741 // 14: 5 9 10 13 * 15 18 19 23
4742 // 15: 5 9 10 13 14 * 18 19 20 23 24 25
4743 // 16: 11 12 13 * 17 21
4744 // 17: 11 12 13 16 * 18 21 22 23
4745 // 18: 13 14 15 17 * 19 21 22 23
4746 // 19: 13 14 15 18 * 20 23 24 25
4747 // 20: 15 19 * 23 24 25
4748 // 21: 11 12 13 16 17 18 * 22 23
4749 // 22: 13 17 18 21 * 23
4750 // 23: 13 14 15 17 18 19 20 21 22 * 24 25
4751 // 24: 15 19 20 23 * 25
4752 // 25: 15 19 20 23 24 *
4753 //
4754 // Below, we list the number of adjancencies to lower-indexed nodes, to
4755 // the node itself, to higher-indexed nodes, the total number of
4756 // adjacencies for this node, and the location of the first and last
4757 // entries required to list this set of adjacencies in a single list
4758 // of all the adjacencies.
4759 //
4760 // N Below Self Above Total First Last
4761 //
4762 // -- -- -- -- -- --- 0
4763 // 1: 0 1 5 6 1 6
4764 // 2: 1 1 4 6 7 12
4765 // 3: 2 1 9 12 13 24
4766 // 4: 1 1 4 6 25 30
4767 // 5: 2 1 6 9 31 39
4768 // 6: 3 1 2 6 40 45
4769 // 7: 4 1 4 9 46 54
4770 // 8: 4 1 4 9 55 63
4771 // 9: 4 1 4 9 62 72
4772 // 10: 2 1 3 6 73 78
4773 // 11: 6 1 5 12 79 90
4774 // 12: 4 1 4 9 91 99
4775 // 13: 9 1 9 19 100 118
4776 // 14: 4 1 4 9 119 127
4777 // 15: 5 1 6 12 128 139
4778 // 16: 3 1 2 6 140 145
4779 // 17: 4 1 4 9 146 154
4780 // 18: 4 1 4 9 155 163
4781 // 19: 4 1 4 9 164 172
4782 // 20: 2 1 3 6 173 178
4783 // 21: 6 1 2 9 179 187
4784 // 22: 4 1 1 6 188 193
4785 // 23: 9 1 2 12 194 205
4786 // 24: 4 1 1 6 206 211
4787 // 25: 5 1 0 6 212 217
4788 // -- -- -- -- -- 218 ---
4789 //
4790 // Licensing:
4791 //
4792 // This code is distributed under the GNU LGPL license.
4793 //
4794 // Modified:
4795 //
4796 // 25 August 2006
4797 //
4798 // Author:
4799 //
4800 // John Burkardt
4801 //
4802 // Parameters
4803 //
4804 // Input, int NODE_NUM, the number of nodes.
4805 //
4806 // Input, int TRIANGLE_NUM, the number of triangles.
4807 //
4808 // Input, int TRIANGLE_NODE[6*TRIANGLE_NUM], lists the nodes that
4809 // make up each triangle. The first three nodes are the vertices,
4810 // in counterclockwise order. The fourth value is the midside
4811 // node between nodes 1 and 2; the fifth and sixth values are
4812 // the other midside nodes in the logical order.
4813 //
4814 // Input, int TRIANGLE_NEIGHBOR[3*TRIANGLE_NUM], for each side of
4815 // a triangle, lists the neighboring triangle, or -1 if there is
4816 // no neighbor.
4817 //
4818 // Output, int TRIANGULATION_ORDER6_ADJ_COUNT, the number of adjacencies.
4819 //
4820 // Output, int ADJ_COL[NODE_NUM+1]. Information about column J is stored
4821 // in entries ADJ_COL(J) through ADJ_COL(J+1)-1 of ADJ.
4822 //
4823 {
4824  int adj_num;
4825  int i;
4826  int n1;
4827  int n2;
4828  int n3;
4829  int n4;
4830  int n5;
4831  int n6;
4832  int node;
4833  int triangle;
4834  int triangle_order = 6;
4835  int triangle2;
4836 
4837  adj_num = 0;
4838 //
4839 // Set every node to be adjacent to itself.
4840 //
4841  for ( node = 0; node < node_num; node++ )
4842  {
4843  adj_col[node] = 1;
4844  }
4845 //
4846 // Examine each triangle.
4847 //
4848  for ( triangle = 0; triangle < triangle_num; triangle++ )
4849  {
4850  n1 = triangle_node[0+triangle*triangle_order];
4851  n2 = triangle_node[1+triangle*triangle_order];
4852  n3 = triangle_node[2+triangle*triangle_order];
4853  n4 = triangle_node[3+triangle*triangle_order];
4854  n5 = triangle_node[4+triangle*triangle_order];
4855  n6 = triangle_node[5+triangle*triangle_order];
4856 //
4857 // For sure, we add the adjacencies:
4858 // 43 / (34)
4859 // 51 / (15)
4860 // 54 / (45)
4861 // 62 / (26)
4862 // 64 / (46)
4863 // 65 / (56)
4864 //
4865  adj_col[n3-1] = adj_col[n3-1] + 1;
4866  adj_col[n4-1] = adj_col[n4-1] + 1;
4867  adj_col[n1-1] = adj_col[n1-1] + 1;
4868  adj_col[n5-1] = adj_col[n5-1] + 1;
4869  adj_col[n4-1] = adj_col[n4-1] + 1;
4870  adj_col[n5-1] = adj_col[n5-1] + 1;
4871  adj_col[n2-1] = adj_col[n2-1] + 1;
4872  adj_col[n6-1] = adj_col[n6-1] + 1;
4873  adj_col[n4-1] = adj_col[n4-1] + 1;
4874  adj_col[n6-1] = adj_col[n6-1] + 1;
4875  adj_col[n5-1] = adj_col[n5-1] + 1;
4876  adj_col[n6-1] = adj_col[n6-1] + 1;
4877 //
4878 // Add edges (1,2), (1,4), (2,4) if this is the first occurrence,
4879 // that is, if the edge (1,4,2) is on a boundary (TRIANGLE2 <= 0)
4880 // or if this triangle is the first of the pair in which the edge
4881 // occurs (TRIANGLE < TRIANGLE2).
4882 //
4883 // Maybe add
4884 // 21 / 12
4885 // 41 / 14
4886 // 42 / 24
4887 //
4888  triangle2 = triangle_neighbor[0+triangle*3];
4889 
4890  if ( triangle2 < 0 || triangle < triangle2 )
4891  {
4892  adj_col[n1-1] = adj_col[n1-1] + 1;
4893  adj_col[n2-1] = adj_col[n2-1] + 1;
4894  adj_col[n1-1] = adj_col[n1-1] + 1;
4895  adj_col[n4-1] = adj_col[n4-1] + 1;
4896  adj_col[n2-1] = adj_col[n2-1] + 1;
4897  adj_col[n4-1] = adj_col[n4-1] + 1;
4898  }
4899 //
4900 // Maybe add
4901 // 32 / 23
4902 // 52 / 25
4903 // 53 / 35
4904 //
4905  triangle2 = triangle_neighbor[1+triangle*3];
4906 
4907  if ( triangle2 < 0 || triangle < triangle2 )
4908  {
4909  adj_col[n2-1] = adj_col[n2-1] + 1;
4910  adj_col[n3-1] = adj_col[n3-1] + 1;
4911  adj_col[n2-1] = adj_col[n2-1] + 1;
4912  adj_col[n5-1] = adj_col[n5-1] + 1;
4913  adj_col[n3-1] = adj_col[n3-1] + 1;
4914  adj_col[n5-1] = adj_col[n5-1] + 1;
4915  }
4916 //
4917 // Maybe add
4918 // 31 / 13
4919 // 61 / 16
4920 // 63 / 36
4921 //
4922  triangle2 = triangle_neighbor[2+triangle*3];
4923 
4924  if ( triangle2 < 0 || triangle < triangle2 )
4925  {
4926  adj_col[n1-1] = adj_col[n1-1] + 1;
4927  adj_col[n3-1] = adj_col[n3-1] + 1;
4928  adj_col[n1-1] = adj_col[n1-1] + 1;
4929  adj_col[n6-1] = adj_col[n6-1] + 1;
4930  adj_col[n3-1] = adj_col[n3-1] + 1;
4931  adj_col[n6-1] = adj_col[n6-1] + 1;
4932  }
4933  }
4934 //
4935 // We used ADJ_COL to count the number of entries in each column.
4936 // Convert it to pointers into the ADJ array.
4937 //
4938  for ( node = node_num; 1 <= node; node-- )
4939  {
4940  adj_col[node] = adj_col[node-1];
4941  }
4942  adj_col[0] = 1;
4943  for ( i = 1; i <= node_num; i++ )
4944  {
4945  adj_col[i]= adj_col[i-1] + adj_col[i];
4946  }
4947 
4948  adj_num = adj_col[node_num] - 1;
4949 
4950  return adj_num;
4951 }
4952 //****************************************************************************80
4953 
4954 int *triangulation_order6_adj_set ( int node_num, int triangle_num,
4955  int triangle_node[], int triangle_neighbor[], int adj_num, int adj_col[] )
4956 
4957 //****************************************************************************80
4958 //
4959 // Purpose:
4960 //
4961 // TRIANGULATION_ORDER6_ADJ_SET sets adjacencies in a triangulation.
4962 //
4963 // Discussion:
4964 //
4965 // This routine is called to count the adjacencies, so that the
4966 // appropriate amount of memory can be set aside for storage when
4967 // the adjacency structure is created.
4968 //
4969 // The triangulation is assumed to involve 6-node triangles.
4970 //
4971 // Two nodes are "adjacent" if they are both nodes in some triangle.
4972 // Also, a node is considered to be adjacent to itself.
4973 //
4974 // This routine can be used to create the compressed column storage
4975 // for a quadratic triangle finite element discretization of
4976 // Poisson's equation in two dimensions.
4977 //
4978 // Diagram:
4979 //
4980 // 3
4981 // s |\
4982 // i | \
4983 // d | \
4984 // e 6 5 side 2
4985 // | \
4986 // 3 | \
4987 // | \
4988 // 1---4---2
4989 //
4990 // side 1
4991 //
4992 // The local node numbering
4993 //
4994 //
4995 // 21-22-23-24-25
4996 // |\ |\ |
4997 // | \ | \ |
4998 // 16 17 18 19 20
4999 // | \ | \ |
5000 // | \| \|
5001 // 11-12-13-14-15
5002 // |\ |\ |
5003 // | \ | \ |
5004 // 6 7 8 9 10
5005 // | \ | \ |
5006 // | \| \|
5007 // 1--2--3--4--5
5008 //
5009 // A sample grid.
5010 //
5011 //
5012 // Below, we have a chart that lists the nodes adjacent to each node, with
5013 // an asterisk to indicate the adjacency of the node to itself
5014 // (in some cases, you want to count this self adjacency and in some
5015 // you don't).
5016 //
5017 // N Adjacencies
5018 //
5019 // 1: * 2 3 6 7 11
5020 // 2: 1 * 3 6 7 11
5021 // 3: 1 2 * 4 5 6 7 8 9 11 12 13
5022 // 4: 3 * 5 8 9 13
5023 // 5: 3 4 * 8 9 10 13 14 15
5024 // 6: 1 2 3 * 7 11
5025 // 7: 1 2 3 6 * 8 11 12 13
5026 // 8: 3 4 5 7 * 9 11 12 13
5027 // 9: 3 4 5 8 * 10 13 14 15
5028 // 10: 5 9 * 13 14 15
5029 // 11: 1 2 3 6 7 8 * 12 13 16 17 21
5030 // 12: 3 7 8 11 * 13 16 17 21
5031 // 13: 3 4 5 7 8 9 10 11 12 * 14 15 16 17 18 19 21 22 23
5032 // 14: 5 9 10 13 * 15 18 19 23
5033 // 15: 5 9 10 13 14 * 18 19 20 23 24 25
5034 // 16: 11 12 13 * 17 21
5035 // 17: 11 12 13 16 * 18 21 22 23
5036 // 18: 13 14 15 17 * 19 21 22 23
5037 // 19: 13 14 15 18 * 20 23 24 25
5038 // 20: 15 19 * 23 24 25
5039 // 21: 11 12 13 16 17 18 * 22 23
5040 // 22: 13 17 18 21 * 23
5041 // 23: 13 14 15 17 18 19 20 21 22 * 24 25
5042 // 24: 15 19 20 23 * 25
5043 // 25: 15 19 20 23 24 *
5044 //
5045 // Below, we list the number of adjancencies to lower-indexed nodes, to
5046 // the node itself, to higher-indexed nodes, the total number of
5047 // adjacencies for this node, and the location of the first and last
5048 // entries required to list this set of adjacencies in a single list
5049 // of all the adjacencies.
5050 //
5051 // N Below Self Above Total First Last
5052 //
5053 // -- -- -- -- -- --- 0
5054 // 1: 0 1 5 6 1 6
5055 // 2: 1 1 4 6 7 12
5056 // 3: 2 1 9 12 13 24
5057 // 4: 1 1 4 6 25 30
5058 // 5: 2 1 6 9 31 39
5059 // 6: 3 1 2 6 40 45
5060 // 7: 4 1 4 9 46 54
5061 // 8: 4 1 4 9 55 63
5062 // 9: 4 1 4 9 62 72
5063 // 10: 2 1 3 6 73 78
5064 // 11: 6 1 5 12 79 90
5065 // 12: 4 1 4 9 91 99
5066 // 13: 9 1 9 19 100 118
5067 // 14: 4 1 4 9 119 127
5068 // 15: 5 1 6 12 128 139
5069 // 16: 3 1 2 6 140 145
5070 // 17: 4 1 4 9 146 154
5071 // 18: 4 1 4 9 155 163
5072 // 19: 4 1 4 9 164 172
5073 // 20: 2 1 3 6 173 178
5074 // 21: 6 1 2 9 179 187
5075 // 22: 4 1 1 6 188 193
5076 // 23: 9 1 2 12 194 205
5077 // 24: 4 1 1 6 206 211
5078 // 25: 5 1 0 6 212 217
5079 // -- -- -- -- -- 218 ---
5080 //
5081 // Licensing:
5082 //
5083 // This code is distributed under the GNU LGPL license.
5084 //
5085 // Modified:
5086 //
5087 // 25 August 2006
5088 //
5089 // Author:
5090 //
5091 // John Burkardt
5092 //
5093 // Parameters
5094 //
5095 // Input, int NODE_NUM, the number of nodes.
5096 //
5097 // Input, int TRIANGLE_NUM, the number of triangles.
5098 //
5099 // Input, int TRIANGLE_NODE[6*TRIANGLE_NUM], lists the nodes that
5100 // make up each triangle. The first three nodes are the vertices,
5101 // in counterclockwise order. The fourth value is the midside
5102 // node between nodes 1 and 2; the fifth and sixth values are
5103 // the other midside nodes in the logical order.
5104 //
5105 // Input, int TRIANGLE_NEIGHBOR[3*TRIANGLE_NUM], for each side of
5106 // a triangle, lists the neighboring triangle, or -1 if there is
5107 // no neighbor.
5108 //
5109 // Input, int ADJ_NUM, the number of adjacencies.
5110 //
5111 // Input, int ADJ_COL[NODE_NUM+1]. Information about column J is stored
5112 // in entries ADJ_COL(J) through ADJ_COL(J+1)-1 of ADJ.
5113 //
5114 // Output, int TRIANGULATION_ORDER6_ADJ_SET[ADJ_NUM], the adjacency
5115 // information.
5116 //
5117 {
5118  int *adj;
5119  int *adj_copy;
5120  int k;
5121  int k1;
5122  int k2;
5123  int n1;
5124  int n2;
5125  int n3;
5126  int n4;
5127  int n5;
5128  int n6;
5129  int node;
5130  int triangle;
5131  int triangle2;
5132  int triangle_order = 6;
5133 
5134  adj = new int[adj_num];
5135  for ( k = 0; k < adj_num; k++ )
5136  {
5137  adj[k] = -1;
5138  }
5139 
5140  adj_copy = new int[node_num];
5141  for ( node = 0; node < node_num; node++ )
5142  {
5143  adj_copy[node] = adj_col[node];
5144  }
5145 //
5146 // Set every node to be adjacent to itself.
5147 //
5148  for ( node = 1; node <= node_num; node++ )
5149  {
5150  adj[adj_copy[node-1]-1] = node;
5151  adj_copy[node-1] = adj_copy[node-1] + 1;
5152  }
5153 //
5154 // Examine each triangle.
5155 //
5156  for ( triangle = 0; triangle < triangle_num; triangle++ )
5157  {
5158  n1 = triangle_node[0+triangle*triangle_order];
5159  n2 = triangle_node[1+triangle*triangle_order];
5160  n3 = triangle_node[2+triangle*triangle_order];
5161  n4 = triangle_node[3+triangle*triangle_order];
5162  n5 = triangle_node[4+triangle*triangle_order];
5163  n6 = triangle_node[5+triangle*triangle_order];
5164 //
5165 // For sure, we add the adjacencies:
5166 // 43 / (34)
5167 // 51 / (15)
5168 // 54 / (45)
5169 // 62 / (26)
5170 // 64 / (46)
5171 // 65 / (56)
5172 //
5173  adj[adj_copy[n3-1]-1] = n4;
5174  adj_copy[n3-1] = adj_copy[n3-1] + 1;
5175  adj[adj_copy[n4-1]-1] = n3;
5176  adj_copy[n4-1] = adj_copy[n4-1] + 1;
5177 
5178  adj[adj_copy[n1-1]-1] = n5;
5179  adj_copy[n1-1] = adj_copy[n1-1] + 1;
5180  adj[adj_copy[n5-1]-1] = n1;
5181  adj_copy[n5-1] = adj_copy[n5-1] + 1;
5182 
5183  adj[adj_copy[n4-1]-1] = n5;
5184  adj_copy[n4-1] = adj_copy[n4-1] + 1;
5185  adj[adj_copy[n5-1]-1] = n4;
5186  adj_copy[n5-1] = adj_copy[n5-1] + 1;
5187 
5188  adj[adj_copy[n2-1]-1] = n6;
5189  adj_copy[n2-1] = adj_copy[n2-1] + 1;
5190  adj[adj_copy[n6-1]-1] = n2;
5191  adj_copy[n6-1] = adj_copy[n6-1] + 1;
5192 
5193  adj[adj_copy[n4-1]-1] = n6;
5194  adj_copy[n4-1] = adj_copy[n4-1] + 1;
5195  adj[adj_copy[n6-1]-1] = n4;
5196  adj_copy[n6-1] = adj_copy[n6-1] + 1;
5197 
5198  adj[adj_copy[n5-1]-1] = n6;
5199  adj_copy[n5-1] = adj_copy[n5-1] + 1;
5200  adj[adj_copy[n6-1]-1] = n5;
5201  adj_copy[n6-1] = adj_copy[n6-1] + 1;
5202 //
5203 // Add edges (1,2), (1,4), (2,4) if this is the first occurrence,
5204 // that is, if the edge (1,4,2) is on a boundary (TRIANGLE2 <= 0)
5205 // or if this triangle is the first of the pair in which the edge
5206 // occurs (TRIANGLE < TRIANGLE2).
5207 //
5208 // Maybe add
5209 // 21 / 12
5210 // 41 / 14
5211 // 42 / 24
5212 //
5213  triangle2 = triangle_neighbor[0+triangle*3];
5214 
5215  if ( triangle2 < 0 || triangle < triangle2 )
5216  {
5217  adj[adj_copy[n1-1]-1] = n2;
5218  adj_copy[n1-1] = adj_copy[n1-1] + 1;
5219  adj[adj_copy[n2-1]-1] = n1;
5220  adj_copy[n2-1] = adj_copy[n2-1] + 1;
5221  adj[adj_copy[n1-1]-1] = n4;
5222  adj_copy[n1-1] = adj_copy[n1-1] + 1;
5223  adj[adj_copy[n4-1]-1] = n1;
5224  adj_copy[n4-1] = adj_copy[n4-1] + 1;
5225  adj[adj_copy[n2-1]-1] = n4;
5226  adj_copy[n2-1] = adj_copy[n2-1] + 1;
5227  adj[adj_copy[n4-1]-1] = n2;
5228  adj_copy[n4-1] = adj_copy[n4-1] + 1;
5229  }
5230 //
5231 // Maybe add
5232 // 32 / 23
5233 // 52 / 25
5234 // 53 / 35
5235 //
5236  triangle2 = triangle_neighbor[1+triangle*3];
5237 
5238  if ( triangle2 < 0 || triangle < triangle2 )
5239  {
5240  adj[adj_copy[n2-1]-1] = n3;
5241  adj_copy[n2-1] = adj_copy[n2-1] + 1;
5242  adj[adj_copy[n3-1]-1] = n2;
5243  adj_copy[n3-1] = adj_copy[n3-1] + 1;
5244  adj[adj_copy[n2-1]-1] = n5;
5245  adj_copy[n2-1] = adj_copy[n2-1] + 1;
5246  adj[adj_copy[n5-1]-1] = n2;
5247  adj_copy[n5-1] = adj_copy[n5-1] + 1;
5248  adj[adj_copy[n3-1]-1] = n5;
5249  adj_copy[n3-1] = adj_copy[n3-1] + 1;
5250  adj[adj_copy[n5-1]-1] = n3;
5251  adj_copy[n5-1] = adj_copy[n5-1] + 1;
5252  }
5253 //
5254 // Maybe add
5255 // 31 / 13
5256 // 61 / 16
5257 // 63 / 36
5258 //
5259  triangle2 = triangle_neighbor[2+triangle*3];
5260 
5261  if ( triangle2 < 0 || triangle < triangle2 )
5262  {
5263  adj[adj_copy[n1-1]-1] = n3;
5264  adj_copy[n1-1] = adj_copy[n1-1] + 1;
5265  adj[adj_copy[n3-1]-1] = n1;
5266  adj_copy[n3-1] = adj_copy[n3-1] + 1;
5267  adj[adj_copy[n1-1]-1] = n6;
5268  adj_copy[n1-1] = adj_copy[n1-1] + 1;
5269  adj[adj_copy[n6-1]-1] = n1;
5270  adj_copy[n6-1] = adj_copy[n6-1] + 1;
5271  adj[adj_copy[n3-1]-1] = n6;
5272  adj_copy[n3-1] = adj_copy[n3-1] + 1;
5273  adj[adj_copy[n6-1]-1] = n3;
5274  adj_copy[n6-1] = adj_copy[n6-1] + 1;
5275  }
5276  }
5277 //
5278 // Ascending sort the entries for each node.
5279 //
5280  for ( node = 1; node <= node_num; node++ )
5281  {
5282  k1 = adj_col[node-1];
5283  k2 = adj_col[node]-1;
5284  i4vec_sort_heap_a ( k2+1-k1, adj+k1-1 );
5285  }
5286 
5287  delete [] adj_copy;
5288 
5289  return adj;
5290 }
5291 //****************************************************************************80
5292 
5293 void triangulation_order6_example2 ( int node_num, int triangle_num,
5294  double node_xy[], int triangle_node[], int triangle_neighbor[] )
5295 
5296 //****************************************************************************80
5297 //
5298 // Purpose:
5299 //
5300 // TRIANGULATION_ORDER6_EXAMPLE2 sets up a sample triangulation.
5301 //
5302 // Discussion:
5303 //
5304 // This triangulation is actually a Delaunay triangulation.
5305 //
5306 // The appropriate input values of NODE_NUM and TRIANGLE_NUM can be
5307 // determined by calling TRIANGULATION_ORDER6_EXAMPLE2_SIZE first.
5308 //
5309 // Diagram:
5310 //
5311 // 21-22-23-24-25
5312 // |\ 6 |\ 8 |
5313 // | \ | \ |
5314 // 16 17 18 19 20
5315 // | \ | \ |
5316 // | 5 \| 7 \|
5317 // 11-12-13-14-15
5318 // |\ 2 |\ 4 |
5319 // | \ | \ |
5320 // 6 7 8 9 10
5321 // | 1 \ | 3 \ |
5322 // | \| \|
5323 // 1--2--3--4--5
5324 //
5325 // Licensing:
5326 //
5327 // This code is distributed under the GNU LGPL license.
5328 //
5329 // Modified:
5330 //
5331 // 07 January 2007
5332 //
5333 // Author:
5334 //
5335 // John Burkardt
5336 //
5337 // Parameters:
5338 //
5339 // Input, int NODE_NUM, the number of nodes.
5340 //
5341 // Input, int TRIANGLE_NUM, the number of triangles.
5342 //
5343 // Output, double NODE_XY[2*NODE_NUM], the coordinates of the nodes.
5344 //
5345 // Output, int TRIANGLE_ORDER[6*TRIANGLE_NUM], the nodes that make up
5346 // the triangles.
5347 //
5348 // Output, int TRIANGLE_NEIGHBOR[3*TRIANGLE_NUM], the triangle neighbors
5349 // on each side. Negative values indicate edges that lie on the exterior.
5350 //
5351 {
5352 # define DIM_NUM 2
5353 # define NODE_NUM 25
5354 # define TRIANGLE_NUM 8
5355 # define TRIANGLE_ORDER 6
5356 
5357  int i;
5358  int j;
5359  static double node_xy_save[DIM_NUM*NODE_NUM] = {
5360  0.0, 0.0,
5361  1.0, 0.0,
5362  2.0, 0.0,
5363  3.0, 0.0,
5364  4.0, 0.0,
5365  0.0, 1.0,
5366  1.0, 1.0,
5367  2.0, 1.0,
5368  3.0, 1.0,
5369  4.0, 1.0,
5370  0.0, 2.0,
5371  1.0, 2.0,
5372  2.0, 2.0,
5373  3.0, 2.0,
5374  4.0, 2.0,
5375  0.0, 3.0,
5376  1.0, 3.0,
5377  2.0, 3.0,
5378  3.0, 3.0,
5379  4.0, 3.0,
5380  0.0, 4.0,
5381  1.0, 4.0,
5382  2.0, 4.0,
5383  3.0, 4.0,
5384  4.0, 4.0 };
5385  static int triangle_node_save[TRIANGLE_ORDER*TRIANGLE_NUM] = {
5386  1, 3, 11, 2, 7, 6,
5387  13, 11, 3, 12, 7, 8,
5388  3, 5, 13, 4, 9, 8,
5389  15, 13, 5, 14, 9, 10,
5390  11, 13, 21, 12, 17, 16,
5391  23, 21, 13, 22, 17, 18,
5392  13, 15, 23, 14, 19, 18,
5393  25, 23, 15, 24, 19, 20 };
5394  static int triangle_neighbor_save[3*TRIANGLE_NUM] = {
5395  -1, 2, -1,
5396  5, 1, 3,
5397  -1, 4, 2,
5398  7, 3, -1,
5399  2, 6, -1,
5400  -1, 5, 7,
5401  4, 8, 6,
5402  -1, 7, -1 };
5403 
5404  for ( j = 0; j < NODE_NUM; j++ )
5405  {
5406  for ( i = 0; i < DIM_NUM; i++ )
5407  {
5408  node_xy[i+j*DIM_NUM] = node_xy_save[i+j*DIM_NUM];
5409  }
5410  }
5411 
5412  for ( j = 0; j < TRIANGLE_NUM; j++ )
5413  {
5414  for ( i = 0; i < TRIANGLE_ORDER; i++ )
5415  {
5416  triangle_node[i+j*TRIANGLE_ORDER] = triangle_node_save[i+j*TRIANGLE_ORDER];
5417  }
5418  }
5419 
5420  for ( j = 0; j < TRIANGLE_NUM; j++ )
5421  {
5422  for ( i = 0; i < 3; i++ )
5423  {
5424  triangle_neighbor[i+j*3] = triangle_neighbor_save[i+j*3];
5425  }
5426  }
5427 
5428  return;
5429 # undef DIM_NUM
5430 # undef NODE_NUM
5431 # undef TRIANGLE_NUM
5432 # undef TRIANGLE_ORDER
5433 }
5434 //****************************************************************************80
5435 
5436 void triangulation_order6_example2_size ( int *node_num, int *triangle_num,
5437  int *hole_num )
5438 
5439 //****************************************************************************80
5440 //
5441 // Purpose:
5442 //
5443 // TRIANGULATION_ORDER6_EXAMPLE2_SIZE sets sizes for a sample triangulation.
5444 //
5445 // Diagram:
5446 //
5447 // 21-22-23-24-25
5448 // |\ 6 |\ 8 |
5449 // | \ | \ |
5450 // 16 17 18 19 20
5451 // | \ | \ |
5452 // | 5 \| 7 \|
5453 // 11-12-13-14-15
5454 // |\ 2 |\ 4 |
5455 // | \ | \ |
5456 // 6 7 8 9 10
5457 // | 1 \ | 3 \ |
5458 // | \| \|
5459 // 1--2--3--4--5
5460 //
5461 // Licensing:
5462 //
5463 // This code is distributed under the GNU LGPL license.
5464 //
5465 // Modified:
5466 //
5467 // 03 January 2007
5468 //
5469 // Author:
5470 //
5471 // John Burkardt
5472 //
5473 // Parameters:
5474 //
5475 // Output, int *NODE_NUM, the number of nodes.
5476 //
5477 // Output, int *TRIANGLE_NUM, the number of triangles.
5478 //
5479 // Output, int *HOLE_NUM, the number of holes.
5480 //
5481 {
5482  *node_num = 25;
5483  *triangle_num = 8;
5484  *hole_num = 0;
5485 
5486  return;
5487 }
int triangulation_order3_adj_count(int node_num, int triangle_num, int triangle_node[], int triangle_neighbor[], int adj_col[])
Definition: rcm.cpp:4000
int * triangulation_order6_adj_set(int node_num, int triangle_num, int triangle_node[], int triangle_neighbor[], int adj_num, int adj_col[])
Definition: rcm.cpp:4954
#define INCX
void level_set_print(int node_num, int level_num, int level_row[], int level[])
Definition: rcm.cpp:2479
int i4_max(int i1, int i2)
Definition: rcm.cpp:1238
#define TRIANGLE_ORDER
#define NODE_NUM
int adj_perm_bandwidth(int node_num, int adj_num, int adj_row[], int adj[], int perm[], int perm_inv[])
Definition: rcm.cpp:279
void r8mat_print_some(int m, int n, double a[], int ilo, int jlo, int ihi, int jhi, string title)
Definition: rcm.cpp:2968
int * triangulation_order3_adj_set(int node_num, int triangle_num, int triangle_node[], int triangle_neighbor[], int adj_num, int adj_col[])
Definition: rcm.cpp:4205
int * perm_uniform(int n, int *seed)
Definition: rcm.cpp:2679
void triangulation_order6_example2(int node_num, int triangle_num, double node_xy[], int triangle_node[], int triangle_neighbor[])
Definition: rcm.cpp:5293
void i4vec_print(int n, int a[], string title)
Definition: rcm.cpp:2168
void r82vec_permute(int n, double a[], int p[])
Definition: rcm.cpp:2832
#define TIME_SIZE
void degree(int root, int adj_num, int adj_row[], int adj[], int mask[], int deg[], int *iccsze, int ls[], int node_num)
Definition: rcm.cpp:875
void adj_insert_ij(int node_num, int adj_max, int *adj_num, int adj_row[], int adj[], int i, int j)
Definition: rcm.cpp:187
int * i4vec_indicator(int n)
Definition: rcm.cpp:2127
int i4col_compare(int m, int n, int a[], int i, int j)
Definition: rcm.cpp:1490
TinyFad< 8, T > abs(const TinyFad< 8, T > &in)
Definition: tinyfadeight.h:846
int adj_bandwidth(int node_num, int adj_num, int adj_row[], int adj[])
Definition: rcm.cpp:19
void perm_inverse3(int n, int perm[], int perm_inv[])
Definition: rcm.cpp:2639
void i4vec_reverse(int n, int a[])
Definition: rcm.cpp:2212
void adj_show(int node_num, int adj_num, int adj_row[], int adj[])
Definition: rcm.cpp:776
bool adj_contains_ij(int node_num, int adj_num, int adj_row[], int adj[], int i, int j)
Definition: rcm.cpp:92
void i4col_swap(int m, int n, int a[], int icol1, int icol2)
Definition: rcm.cpp:1687
void root_find(int *root, int adj_num, int adj_row[], int adj[], int mask[], int *level_num, int level_row[], int level[], int node_num)
Definition: rcm.cpp:3340
void level_set(int root, int adj_num, int adj_row[], int adj[], int mask[], int *level_num, int level_row[], int level[], int node_num)
Definition: rcm.cpp:2341
void graph_01_size(int *node_num, int *adj_num)
Definition: rcm.cpp:1198
void i4mat_print_some(int m, int n, int a[], int ilo, int jlo, int ihi, int jhi, string title)
Definition: rcm.cpp:1765
void i4col_sort_a(int m, int n, int a[])
Definition: rcm.cpp:1600
void i4mat_transpose_print_some(int m, int n, int a[], int ilo, int jlo, int ihi, int jhi, string title)
Definition: rcm.cpp:1901
void triangulation_order6_example2_size(int *node_num, int *triangle_num, int *hole_num)
Definition: rcm.cpp:5436
void i4_swap(int *i, int *j)
Definition: rcm.cpp:1356
#define DIM_NUM
void i4mat_transpose_print(int m, int n, int a[], string title)
Definition: rcm.cpp:1863
void triangulation_order3_example2_size(int *node_num, int *triangle_num, int *hole_num)
Definition: rcm.cpp:4613
void i4vec_sort_heap_a(int n, int a[])
Definition: rcm.cpp:2264
void adj_set(int node_num, int adj_max, int *adj_num, int adj_row[], int adj[], int irow, int jcol)
Definition: rcm.cpp:637
void adj_perm_show(int node_num, int adj_num, int adj_row[], int adj[], int perm[], int perm_inv[])
Definition: rcm.cpp:357
#define ADJ_NUM
bool perm_check(int n, int p[])
Definition: rcm.cpp:2577
void r8mat_transpose_print_some(int m, int n, double a[], int ilo, int jlo, int ihi, int jhi, string title)
Definition: rcm.cpp:3066
void genrcm(int node_num, int adj_num, int adj_row[], int adj[], int perm[])
Definition: rcm.cpp:1014
float r4_abs(float x)
Definition: rcm.cpp:2736
void i4vec_heap_d(int n, int a[])
Definition: rcm.cpp:1999
void sort_heap_external(int n, int *indx, int *i, int *j, int isgn)
Definition: rcm.cpp:3533
int i4_uniform(int a, int b, int *seed)
Definition: rcm.cpp:1392
int triangulation_order6_adj_count(int node_num, int triangle_num, int triangle_node[], int triangle_neighbor[], int adj_col[])
Definition: rcm.cpp:4667
void timestamp(void)
Definition: rcm.cpp:3719
int i4_sign(int i)
Definition: rcm.cpp:1316
void adj_print_some(int node_num, int node_lo, int node_hi, int adj_num, int adj_row[], int adj[], string title)
Definition: rcm.cpp:522
int r4_nint(float x)
Definition: rcm.cpp:2777
void rcm(int root, int adj_num, int adj_row[], int adj[], int mask[], int perm[], int *iccsze, int node_num)
Definition: rcm.cpp:3153
void graph_01_adj(int node_num, int adj_num, int adj_row[], int adj[])
Definition: rcm.cpp:1127
#define TRIANGLE_NUM
void triangulation_order3_example2(int node_num, int triangle_num, double node_xy[], int triangle_node[], int triangle_neighbor[])
Definition: rcm.cpp:4433
clarg::argString m("-m", "input matrix file name (text format)", "matrix.txt")
#define OFFSET
int * triangulation_neighbor_triangles(int triangle_order, int triangle_num, int triangle_node[])
Definition: rcm.cpp:3767
int i4_min(int i1, int i2)
Definition: rcm.cpp:1277
void adj_print(int node_num, int adj_num, int adj_row[], int adj[], string title)
Definition: rcm.cpp:468