# include # include # include # include # include # include "rcm.h" int main ( ); void test01 ( ); void test02 ( ); void test03 ( ); void test04 ( ); void test05 ( ); void test06 ( ); void test07 ( ); void test08 ( ); void test09 ( ); void test10 ( ); void test11 ( ); void test12 ( ); void timestamp ( ); /******************************************************************************/ int main ( ) /******************************************************************************/ /* Purpose: rcm_test() tests rcm(). Licensing: This code is distributed under the MIT license. Modified: 03 August 2025 Author: John Burkardt */ { timestamp ( ); printf ( "\n" ); printf ( "rcm_test():\n" ); printf ( " C version\n" ); printf ( " Test rcm().\n" ); test01 ( ); test02 ( ); test03 ( ); test04 ( ); test05 ( ); test06 ( ); test07 ( ); test08 ( ); test09 ( ); test10 ( ); test11 ( ); test12 ( ); /* Terminate. */ printf ( "\n" ); printf ( "rcm_test():\n" ); printf ( " Normal end of execution.\n" ); printf ( "\n" ); timestamp ( ); return 0; } /******************************************************************************/ void test01 ( ) /******************************************************************************/ /* Purpose: TEST01 tests ADJ_SET. Licensing: This code is distributed under the MIT license. Modified: 04 January 2007 Author: John Burkardt */ { # define NODE_NUM 10 # define ADJ_MAX ( NODE_NUM * ( NODE_NUM - 1 ) ) int adj[ADJ_MAX]; int adj_num; int adj_row[NODE_NUM+1]; int i; int j; int k; int n_calls; printf ( "\n" ); printf ( "TEST01\n" ); printf ( " ADJ_SET sets up an adjacency matrix incrementally.\n" ); n_calls = i4_uniform_ab ( 1, ADJ_MAX ); adj_set ( NODE_NUM, ADJ_MAX, &adj_num, adj_row, adj, -1, -1 ); printf ( "\n" ); printf ( " Creating and recording adjacency information:\n" ); printf ( "\n" ); for ( k = 1; k <= n_calls; k++ ) { i = i4_uniform_ab ( 1, NODE_NUM ); j = i4_uniform_ab ( 1, NODE_NUM ); printf ( " %8d %8d\n", i, j ); adj_set ( NODE_NUM, ADJ_MAX, &adj_num, adj_row, adj, i, j ); } adj_print ( NODE_NUM, adj_num, adj_row, adj, " Random adjacency matrix:" ); adj_show ( NODE_NUM, adj_num, adj_row, adj ); return; # undef NODE_NUM # undef ADJ_MAX } /******************************************************************************/ void test02 ( ) /******************************************************************************/ /* Purpose: TEST02 tests GENRCM; Licensing: This code is distributed under the MIT license. Modified: 05 January 2007 Author: John Burkardt */ { int *adj; int adj_num; int *adj_row; int bandwidth; int i; int node_num; int *perm; int *perm_inv; printf ( "\n" ); printf ( "TEST02\n" ); printf ( " GENRCM reorders the nodes in a graph using\n" ); printf ( " the Reverse Cuthill McKee algorithm.\n" ); graph_01_size ( &node_num, &adj_num ); adj_row = ( int * ) malloc ((node_num+1) * sizeof ( int ) ); adj = ( int * ) malloc (adj_num * sizeof ( int ) ); perm = ( int * ) malloc (node_num * sizeof ( int ) ); perm_inv = ( int * ) malloc (node_num * sizeof ( int ) ); graph_01_adj ( node_num, adj_num, adj_row, adj ); adj_print ( node_num, adj_num, adj_row, adj, " Adjacency matrix:" ); adj_show ( node_num, adj_num, adj_row, adj ); bandwidth = adj_bandwidth ( node_num, adj_num, adj_row, adj ); printf ( "\n" ); printf ( " ADJ bandwidth = %d\n", bandwidth ); genrcm ( node_num, adj_num, adj_row, adj, perm ); perm_inverse3 ( node_num, perm, perm_inv ); printf ( "\n" ); printf ( " The RCM permutation and inverse:\n" ); printf ( "\n" ); for ( i = 0; i < node_num; i++ ) { printf ( " %8d %8d %8d\n", i + 1, perm[i], perm_inv[i] ); } printf ( "\n" ); printf ( " Permuted adjacency matrix:\n" ); printf ( "\n" ); adj_perm_show ( node_num, adj_num, adj_row, adj, perm, perm_inv ); bandwidth = adj_perm_bandwidth ( node_num, adj_num, adj_row, adj, perm, perm_inv ); printf ( "\n" ); printf ( " ADJ (permuted) bandwidth = %d\n", bandwidth ); free ( adj ); free ( adj_row ); free ( perm ); free ( perm_inv ); return; } /******************************************************************************/ void test03 ( ) /******************************************************************************/ /* Purpose: TEST03 tests GENRCM Licensing: This code is distributed under the MIT license. Modified: 06 January 2007 Author: John Burkardt */ { int *adj; int adj_num; int *adj_row; int bandwidth; int hole_num; int i; int j; int node; int node_num; double *node_xy; int *perm; int *perm_inv; int test; int triangle_num; int *triangle_neighbor; int *triangle_node; printf ( "\n" ); printf ( "TEST03\n" ); printf ( " GENRCM generates the Reverse Cuthill McKee ordering.\n" ); printf ( "\n" ); printf ( " Do the test twice. On the second test, randomly\n" ); printf ( " permute the initial nodes.\n" ); triangulation_order3_example2_size ( &node_num, &triangle_num, &hole_num ); for ( test = 1; test <= 2; test++ ) { node_xy = ( double * ) malloc ( 2*node_num * sizeof ( double ) ); triangle_node = ( int * ) malloc (3*triangle_num * sizeof ( int ) ); triangle_neighbor = ( int * ) malloc (3*triangle_num * sizeof ( int ) ); triangulation_order3_example2 ( node_num, triangle_num, node_xy, triangle_node, triangle_neighbor ); /* Randomly permute the nodes. */ if ( test == 2 ) { perm = perm_uniform ( node_num ); i4vec_print ( node_num, perm, " The random permutation:" ); for ( i = 0; i < 3; i++ ) { for ( j = 0; j < triangle_num; j++ ) { node = triangle_node[i+j*3]; triangle_node[i+j*3] = perm[node-1]; } } free ( perm ); } i4mat_transpose_print ( 3, triangle_num, triangle_node, " TRIANGLE_NODE:" ); adj_row = ( int * ) malloc (( node_num+1 ) * sizeof ( int ) ); adj_num = triangulation_order3_adj_count ( node_num, triangle_num, triangle_node, triangle_neighbor, adj_row ); adj = triangulation_order3_adj_set ( node_num, triangle_num, triangle_node, triangle_neighbor, adj_num, adj_row ); adj_print ( node_num, adj_num, adj_row, adj, " ADJ array:" ); bandwidth = adj_bandwidth ( node_num, adj_num, adj_row, adj ); printf ( "\n" ); printf ( " ADJ bandwidth = %d\n", bandwidth ); perm = ( int * ) malloc (node_num * sizeof ( int ) ); genrcm ( node_num, adj_num, adj_row, adj, perm ); i4vec_print ( node_num, perm, " The RCM permutation:" ); perm_inv = ( int * ) malloc (node_num * sizeof ( int ) ); perm_inverse3 ( node_num, perm, perm_inv ); bandwidth = adj_perm_bandwidth ( node_num, adj_num, adj_row, adj, perm, perm_inv ); printf ( "\n" ); printf ( " Permuted ADJ bandwidth = %d\n", bandwidth ); free ( adj ); free ( adj_row ); free ( node_xy ); free ( perm ); free ( perm_inv ); free ( triangle_neighbor ); free ( triangle_node ); } return; } /******************************************************************************/ void test04 ( ) /******************************************************************************/ /* Purpose: TEST04 tests GENRCM Licensing: This code is distributed under the MIT license. Modified: 06 January 2007 Author: John Burkardt */ { int *adj; int adj_num; int *adj_row; int bandwidth; int hole_num; int i; int j; int node; int node_num; double *node_xy; int *perm; int *perm_inv; int triangle_num; int *triangle_neighbor; int *triangle_node; int triangle_order = 6; printf ( "\n" ); printf ( "TEST04\n" ); printf ( " GENRCM generates the Reverse Cuthill McKee ordering.\n" ); triangulation_order6_example2_size ( &node_num, &triangle_num, &hole_num ); node_xy = ( double * ) malloc ( 2*node_num * sizeof ( double ) ); triangle_node = ( int * ) malloc (triangle_order*triangle_num * sizeof ( int ) ); triangle_neighbor = ( int * ) malloc (3*triangle_num * sizeof ( int ) ); triangulation_order6_example2 ( node_num, triangle_num, node_xy, triangle_node, triangle_neighbor ); /* Randomly permute the nodes. */ perm = perm_uniform ( node_num ); i4vec_print ( node_num, perm, " The random permutation:" ); for ( i = 0; i < triangle_order; i++ ) { for ( j = 0; j < triangle_num; j++ ) { node = triangle_node[i+j*triangle_order]; triangle_node[i+j*triangle_order] = perm[node-1]; } } i4mat_transpose_print ( triangle_order, triangle_num, triangle_node, " Permuted TRIANGLE_NODE" ); free ( perm ); adj_row = ( int * ) malloc ((node_num+1) * sizeof ( int ) ); adj_num = triangulation_order6_adj_count ( node_num, triangle_num, triangle_node, triangle_neighbor, adj_row ); adj = triangulation_order6_adj_set ( node_num, triangle_num, triangle_node, triangle_neighbor, adj_num, adj_row ); adj_print ( node_num, adj_num, adj_row, adj, " ADJ array:" ); bandwidth = adj_bandwidth ( node_num, adj_num, adj_row, adj ); printf ( "\n" ); printf ( " ADJ bandwidth = %d\n", bandwidth ); perm = ( int * ) malloc (node_num * sizeof ( int ) ); genrcm ( node_num, adj_num, adj_row, adj, perm ); i4vec_print ( node_num, perm, " The RCM permutation:" ); perm_inv = ( int * ) malloc (node_num * sizeof ( int ) ); perm_inverse3 ( node_num, perm, perm_inv ); bandwidth = adj_perm_bandwidth ( node_num, adj_num, adj_row, adj, perm, perm_inv ); printf ( "\n" ); printf ( " Permuted ADJ bandwidth = %d\n", bandwidth ); free ( adj ); free ( adj_row ); free ( node_xy ); free ( perm ); free ( perm_inv ); free ( triangle_neighbor ); free ( triangle_node ); return; } /******************************************************************************/ void test05 ( ) /******************************************************************************/ /* Purpose: TEST05 tests GRAPH_01_ADJ and GRAPH_01_SIZE; Licensing: This code is distributed under the MIT license. Modified: 04 January 2007 Author: John Burkardt */ { int *adj; int adj_num; int *adj_row; int node_num; printf ( "\n" ); printf ( "TEST05\n" ); printf ( " GRAPH_01_SIZE returns the sizes for graph 1.\n" ); printf ( " GRAPH_01_ADJ returns the adjacency for graph 1.\n" ); printf ( " ADJ_PRINT prints the adjacency information.\n" ); graph_01_size ( &node_num, &adj_num ); adj_row = ( int * ) malloc ((node_num+1) * sizeof ( int ) ); adj = ( int * ) malloc (adj_num * sizeof ( int ) ); graph_01_adj ( node_num, adj_num, adj_row, adj ); adj_print ( node_num, adj_num, adj_row, adj, " Adjacency for GRAPH_01:" ); adj_show ( node_num, adj_num, adj_row, adj ); free ( adj ); free ( adj_row ); return; } /******************************************************************************/ void test06 ( ) /******************************************************************************/ /* Purpose: TEST06 tests LEVEL_SET; Licensing: This code is distributed under the MIT license. Modified: 05 January 2007 Author: John Burkardt */ { int *adj; int adj_num; int *adj_row; int i; int j; int *level; int level_num; int *level_row; int *mask; int node_num; int root; printf ( "\n" ); printf ( "TEST06\n" ); printf ( " LEVEL_SET computes the level sets of a graph,\n" ); printf ( " given a root node (which defines level 1).\n" ); graph_01_size ( &node_num, &adj_num ); adj_row = ( int * ) malloc ((node_num+1) * sizeof ( int ) ); adj = ( int * ) malloc (adj_num * sizeof ( int ) ); graph_01_adj ( node_num, adj_num, adj_row, adj ); adj_print ( node_num, adj_num, adj_row, adj, " Adjacency matrix:" ); adj_show ( node_num, adj_num, adj_row, adj ); /* Choose different roots. */ level = ( int * ) malloc (node_num * sizeof ( int ) ); level_row = ( int * ) malloc ((node_num+1) * sizeof ( int ) ); mask = ( int * ) malloc (node_num * sizeof ( int ) ); for ( i = 1; i <= 3; i++ ) { root = i4_uniform_ab ( 1, node_num ); for ( j = 0; j < node_num; j++ ) { mask[j] = 1; } level_set ( root, adj_num, adj_row, adj, mask, &level_num, level_row, level, node_num ); level_set_print ( node_num, level_num, level_row, level ); } free ( adj ); free ( adj_row ); free ( level ); free ( level_row ); free ( mask ); return; } /******************************************************************************/ void test07 ( ) /******************************************************************************/ /* Purpose: TEST07 tests ROOT_FIND; Licensing: This code is distributed under the MIT license. Modified: 07 January 2007 Author: John Burkardt */ { int *adj; int adj_num; int *adj_row; int i; int j; int *level; int level_num; int *level_row; int *mask; int node_num; int root; printf ( "\n" ); printf ( "TEST07\n" ); printf ( " ROOT_FIND is given a node in the graph,\n" ); printf ( " and returns a better node to use as a starting\n" ); printf ( " point for reordering.\n" ); graph_01_size ( &node_num, &adj_num ); adj_row = ( int * ) malloc ((node_num+1) * sizeof ( int ) ); adj = ( int * ) malloc (adj_num * sizeof ( int ) ); graph_01_adj ( node_num, adj_num, adj_row, adj ); adj_print ( node_num, adj_num, adj_row, adj, " Adjacency matrix:" ); adj_show ( node_num, adj_num, adj_row, adj ); level = ( int * ) malloc (node_num * sizeof ( int ) );; level_row = ( int * ) malloc ((node_num+1) * sizeof ( int ) ); mask = ( int * ) malloc (node_num * sizeof ( int ) ); for ( i = 1; i <= node_num; i++ ) { root = i; printf ( "\n" ); printf ( " Starting root = %d\n", root ); for ( j = 0; j < node_num; j++ ) { mask[j] = 1; } root_find ( &root, adj_num, adj_row, adj, mask, &level_num, level_row, level, node_num ); printf ( " Suggested root = %d\n", root ); printf ( " Number of levels = %d\n", level_num ); } free ( adj ); free ( adj_row ); free ( level ); free ( level_row ); free ( mask ); return; } /******************************************************************************/ void test08 ( ) /******************************************************************************/ /* Purpose: TEST08 tests TRIANGULATION_ORDER3_ADJ_COUNT Licensing: This code is distributed under the MIT license. Modified: 04 January 2007 Author: John Burkardt */ { int *adj_row; int hole_num; int node_num; double *node_xy; int triangle_num; int *triangle_neighbor; int *triangle_node; printf ( "\n" ); printf ( "TEST08\n" ); printf ( " TRIANGULATION_ORDER3_ADJ_COUNT counts the (lower)\n" ); printf ( " adjacencies defined by a triangulation.\n" ); triangulation_order3_example2_size ( &node_num, &triangle_num, &hole_num ); node_xy = ( double * ) malloc ( 2*node_num * sizeof ( double ) ); triangle_node = ( int * ) malloc (3*triangle_num * sizeof ( int ) ); triangle_neighbor = ( int * ) malloc (3*triangle_num * sizeof ( int ) ); triangulation_order3_example2 ( node_num, triangle_num, node_xy, triangle_node, triangle_neighbor ); i4mat_transpose_print ( 3, triangle_num, triangle_node, " TRIANGLE_NODE" ); adj_row = ( int * ) malloc ((node_num+1) * sizeof ( int ) ); triangulation_order3_adj_count ( node_num, triangle_num, triangle_node, triangle_neighbor, adj_row ); i4vec_print ( node_num+1, adj_row, " ADJ_ROW" ); free ( adj_row ); free ( node_xy ); free ( triangle_neighbor ); free ( triangle_node ); return; } /******************************************************************************/ void test09 ( ) /******************************************************************************/ /* Purpose: TEST09 tests TRIANGULATION_ORDER3_ADJ_SET Licensing: This code is distributed under the MIT license. Modified: 04 January 2007 Author: John Burkardt */ { int *adj; int adj_num; int *adj_row; int bandwidth; int hole_num; int node_num; double *node_xy; int triangle_num; int *triangle_neighbor; int *triangle_node; printf ( "\n" ); printf ( "TEST09\n" ); printf ( " TRIANGULATION_ORDER3_ADJ_SET sets the (lower)\n" ); printf ( " adjacencies defined by a triangulation.\n" ); triangulation_order3_example2_size ( &node_num, &triangle_num, &hole_num ); node_xy = ( double * ) malloc ( 2*node_num * sizeof ( double ) ); triangle_node = ( int * ) malloc (3*triangle_num * sizeof ( int ) ); triangle_neighbor = ( int * ) malloc (3*triangle_num * sizeof ( int ) ); triangulation_order3_example2 ( node_num, triangle_num, node_xy, triangle_node, triangle_neighbor ); i4mat_transpose_print ( 3, triangle_num, triangle_node, " TRIANGLE_NODE" ); adj_row = ( int * ) malloc ((node_num+1) * sizeof ( int ) );; adj_num = triangulation_order3_adj_count ( node_num, triangle_num, triangle_node, triangle_neighbor, adj_row ); adj = triangulation_order3_adj_set ( node_num, triangle_num, triangle_node, triangle_neighbor, adj_num, adj_row ); adj_print ( node_num, adj_num, adj_row, adj, " ADJ array:" ); bandwidth = adj_bandwidth ( node_num, adj_num, adj_row, adj ); printf ( "\n" ); printf ( " ADJ bandwidth = %d\n", bandwidth ); free ( adj ); free ( adj_row ); free ( node_xy ); free ( triangle_neighbor ); free ( triangle_node ); return; } /******************************************************************************/ void test10 ( ) /******************************************************************************/ /* Purpose: TEST10 tests TRIANGULATION_NEIGHBOR_TRIANGLES. Licensing: This code is distributed under the MIT license. Modified: 28 September 2009 Author: John Burkardt */ { # define TRIANGLE_ORDER 3 # define TRIANGLE_NUM 16 int triangle_node[TRIANGLE_ORDER*TRIANGLE_NUM] = { 3, 4, 1, 3, 1, 2, 3, 2, 8, 2, 1, 5, 8, 2, 13, 8, 13, 9, 3, 8, 9, 13, 2, 5, 9, 13, 7, 7, 13, 5, 6, 7, 5, 9, 7, 6, 10, 9, 6, 6, 5, 12, 11, 6, 12, 10, 6, 11 }; int *triangle_neighbor; printf ( "\n" ); printf ( "TEST10\n" ); printf ( " For a triangulation of a set of nodes,\n" ); printf ( " TRIANGULATION_NEIGHBOR_TRIANGLES determines the\n" ); printf ( " adjacency relationships between triangles.\n" ); i4mat_transpose_print ( TRIANGLE_ORDER, TRIANGLE_NUM, triangle_node, " Triangles:" ); triangle_neighbor = triangulation_neighbor_triangles ( TRIANGLE_ORDER, TRIANGLE_NUM, triangle_node ); i4mat_transpose_print ( 3, TRIANGLE_NUM, triangle_neighbor, " Triangle neighbors:" ); free ( triangle_neighbor ); return; # undef TRIANGLE_NUM # undef TRIANGLE_ORDER } /******************************************************************************/ void test11 ( ) /******************************************************************************/ /* Purpose: TEST11 tests TRIANGULATION_ORDER6_ADJ_COUNT Licensing: This code is distributed under the MIT license. Modified: 04 January 2007 Author: John Burkardt */ { int *adj_row; int hole_num; int node_num; double *node_xy; int triangle_num; int *triangle_neighbor; int *triangle_node; printf ( "\n" ); printf ( "TEST11\n" ); printf ( " TRIANGULATION_ORDER6_ADJ_COUNT counts the (lower)\n" ); printf ( " adjacencies defined by a triangulation.\n" ); triangulation_order6_example2_size ( &node_num, &triangle_num, &hole_num ); node_xy = ( double * ) malloc ( 2*node_num * sizeof ( double ) ); triangle_node = ( int * ) malloc (6*triangle_num * sizeof ( int ) ); triangle_neighbor = ( int * ) malloc (3*triangle_num * sizeof ( int ) ); triangulation_order6_example2 ( node_num, triangle_num, node_xy, triangle_node, triangle_neighbor ); adj_row = ( int * ) malloc ((node_num+1) * sizeof ( int ) ); triangulation_order6_adj_count ( node_num, triangle_num, triangle_node, triangle_neighbor, adj_row ); i4vec_print ( node_num+1, adj_row, " ADJ_ROW" ); free ( adj_row ); free ( node_xy ); free ( triangle_neighbor ); free ( triangle_node ); return; } /******************************************************************************/ void test12 ( ) /******************************************************************************/ /* Purpose: TEST12 tests TRIANGULATION_ORDER6_ADJ_SET Licensing: This code is distributed under the MIT license. Modified: 05 January 2007 Author: John Burkardt */ { int *adj; int adj_num; int *adj_row; int bandwidth; int hole_num; int node_num; double *node_xy; int triangle_num; int *triangle_neighbor; int *triangle_node; printf ( "\n" ); printf ( "TEST12\n" ); printf ( " TRIANGULATION_ORDER6_ADJ_SET sets the (lower)\n" ); printf ( " adjacencies defined by a triangulation.\n" ); triangulation_order6_example2_size ( &node_num, &triangle_num, &hole_num ); node_xy = ( double * ) malloc ( 2*node_num * sizeof ( double ) ); triangle_node = ( int * ) malloc (6*triangle_num * sizeof ( int ) ); triangle_neighbor = ( int * ) malloc (3*triangle_num * sizeof ( int ) ); triangulation_order6_example2 ( node_num, triangle_num, node_xy, triangle_node, triangle_neighbor ); i4mat_transpose_print ( 6, triangle_num, triangle_node, " TRIANGLE_NODE" ); adj_row = ( int * ) malloc ((node_num+1) * sizeof ( int ) ); adj_num = triangulation_order6_adj_count ( node_num, triangle_num, triangle_node, triangle_neighbor, adj_row ); adj = ( int * ) malloc ( adj_num * sizeof ( int ) ); adj = triangulation_order6_adj_set ( node_num, triangle_num, triangle_node, triangle_neighbor, adj_num, adj_row ); adj_print ( node_num, adj_num, adj_row, adj, " ADJ array:" ); bandwidth = adj_bandwidth ( node_num, adj_num, adj_row, adj ); printf ( "\n" ); printf ( " ADJ bandwidth = %d\n", bandwidth ); free ( adj ); free ( adj_row ); free ( node_xy ); free ( triangle_neighbor ); free ( triangle_node ); return; } /******************************************************************************/ void timestamp ( ) /******************************************************************************/ /* Purpose: timestamp() prints the current YMDHMS date as a time stamp. Example: 17 June 2014 09:45:54 AM Licensing: This code is distributed under the MIT license. Modified: 01 May 2021 Author: John Burkardt */ { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct tm *tm; time_t now; now = time ( NULL ); tm = localtime ( &now ); strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); printf ( "%s\n", time_buffer ); return; # undef TIME_SIZE }