void test04 ( ) /******************************************************************************/ /* Purpose: TEST04 works with a CC sparse matrix with many repeated index pairs. Discussion: To complete this test, I want to compare AST * X and ACC * X. Licensing: This code is distributed under the GNU LGPL license. Modified: 23 July 2014 Author: John Burkardt */ { double *acc; double *ast; double *b1; double *b2; int *ccc; int i_max; int i_min; int *icc; int *ist; int j_max; int j_min; int *jst; int m; int n; int ncc; int nst; int nx; int ny; double r; int seed; double *x; printf ( "\n" ); printf ( "TEST04\n" ); printf ( " Convert a sparse matrix from ST to CC format.\n" ); printf ( " ST: sparse triplet, I, J, A.\n" ); printf ( " CC: compressed column, I, CC, A.\n" ); printf ( " The ST matrix is the Wathen finite element matrix.\n" ); printf ( " It has many repeated index pairs.\n" ); printf ( " To check, compare ACC*X - AST*X for a random X.\n" ); /* Get the size of the ST matrix. */ nx = 3; ny = 3; nst = wathen_st_size ( nx, ny ); printf ( "\n" ); printf ( " Number of ST values = %d\n", nst ); /* Set the formal matrix size */ m = 3 * nx * ny + 2 * nx + 2 * ny + 1; n = m; /* Set a random vector. */ seed = 123456789; x = r8vec_uniform_01_new ( n, &seed ); /* Allocate space. */ ist = ( int * ) malloc ( nst * sizeof ( int ) ); jst = ( int * ) malloc ( nst * sizeof ( int ) ); /* Create the ST matrix. */ seed = 123456789; ast = wathen_st ( nx, ny, nst, &seed, ist, jst ); i_min = i4vec_min ( nst, ist ); i_max = i4vec_max ( nst, ist ); j_min = i4vec_min ( nst, jst ); j_max = i4vec_max ( nst, jst ); st_header_print ( i_min, i_max, j_min, j_max, m, n, nst ); /* Compute B1 = AST * X */ b1 = st_mv ( m, n, nst, ist, jst, ast, x ); /* Get the CC size. */ ncc = st_to_cc_size ( nst, ist, jst ); printf ( " Number of CC values = %d\n", ncc ); /* Create the CC indices. */ icc = ( int * ) malloc ( ncc * sizeof ( int ) ); ccc = ( int * ) malloc ( ( n + 1 ) * sizeof ( int ) ); st_to_cc_index ( nst, ist, jst, ncc, n, icc, ccc ); /* Create the CC values. */ acc = st_to_cc_values ( nst, ist, jst, ast, ncc, n, icc, ccc ); /* Compute B2 = ACC * X. */ b2 = cc_mv ( m, n, ncc, icc, ccc, acc, x ); /* Compare B1 and B2. */ r = r8vec_diff_norm ( n, b1, b2 ); printf ( " || ACC*X - AST*X|| = %g\n", r ); /* Free memory. */ free ( acc ); free ( ast ); free ( b1 ); free ( b2 ); free ( ccc ); free ( icc ); free ( ist ); free ( jst ); free ( x ); return; }
void test01 ( ) /******************************************************************************/ /* Purpose: TEST01 tests ST_TO_CC using a tiny matrix. Discussion: This test uses a trivial matrix whose full representation is: 2 3 0 0 0 3 0 4 0 6 A = 0 -1 -3 2 0 0 0 1 0 0 0 4 2 0 1 A (1-based) ST representation, reading in order by rows is: I J A -- -- -- 1 1 2 1 2 3 2 1 3 2 3 4 2 5 6 3 2 -1 3 3 -3 3 4 2 4 3 1 5 2 4 5 3 2 5 5 1 The CC representation (which goes in order by columns) is # I JC A -- -- -- -- 1 1 1 2 2 2 3 3 1 3 3 4 3 -1 5 5 4 6 2 6 4 7 3 -3 8 4 1 9 5 2 10 3 10 2 11 2 11 6 12 5 1 13 * 13 Licensing: This code is distributed under the GNU LGPL license. Modified: 23 July 2014 Author: John Burkardt */ { # define NST 12 double *acc; double ast[NST] = { 2.0, 3.0, 3.0, 4.0, 6.0, -1.0, -3.0, 2.0, 1.0, 4.0, 2.0, 1.0 }; int *ccc; int i_max; int i_min; int *icc; int ist[NST] = { 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5 }; int j_max; int j_min; int jst[NST] = { 1, 2, 1, 3, 5, 2, 3, 4, 3, 2, 3, 5 }; int m = 5; int n = 5; int ncc; int nst = NST; printf ( "\n" ); printf ( "TEST01\n" ); printf ( " Convert a sparse matrix from ST to CC format.\n" ); printf ( " ST: sparse triplet, I, J, A.\n" ); printf ( " CC: compressed column, I, CC, A.\n" ); i_min = i4vec_min ( nst, ist ); i_max = i4vec_max ( nst, ist ); j_min = i4vec_min ( nst, jst ); j_max = i4vec_max ( nst, jst ); st_header_print ( i_min, i_max, j_min, j_max, m, n, nst ); /* Decrement the 1-based data. */ i4vec_dec ( nst, ist ); i4vec_dec ( nst, jst ); /* Print the ST matrix. */ st_print ( m, n, nst, ist, jst, ast, " The matrix in ST format:" ); /* Get the CC size. */ ncc = st_to_cc_size ( nst, ist, jst ); printf ( "\n" ); printf ( " Number of CC values = %d\n", ncc ); /* Create the CC indices. */ icc = ( int * ) malloc ( ncc * sizeof ( int ) ); ccc = ( int * ) malloc ( ( n + 1 ) * sizeof ( int ) ); st_to_cc_index ( nst, ist, jst, ncc, n, icc, ccc ); /* Create the CC values. */ acc = st_to_cc_values ( nst, ist, jst, ast, ncc, n, icc, ccc ); /* Print the CC matrix. */ cc_print ( m, n, ncc, icc, ccc, acc, " CC Matrix:" ); /* Free memory. */ free ( acc ); free ( ccc ); free ( icc ); return; # undef NST }
void perm_inverse ( int n, int p[] ) { int base; int i; int i0; int i1; int i2; int is; int p_min; if ( n <= 0 ) { std::cout << "\n"; std::cout << "PERM_INVERSE - Fatal error!\n"; std::cout << " Input value of N = " << n << "\n"; exit ( 1 ); } // // Find the least value, and shift data so it begins at 1. // p_min = i4vec_min ( n, p ); base = 1; for ( i = 0; i < n; i++ ) { p[i] = p[i] - p_min + base; } // // Now we can safely check the permutation. // if ( !perm_check ( n, p, base ) ) { std::cerr << "\n"; std::cerr << "PERM_INVERSE - Fatal error!\n"; std::cerr << " PERM_CHECK rejects this permutation.\n"; exit ( 1 ); } // // Now we can invert the permutation. // is = 1; for ( i = 1; i <= n; i++ ) { i1 = p[i-1]; while ( i < i1 ) { i2 = p[i1-1]; p[i1-1] = -i2; i1 = i2; } is = - i4_sign ( p[i-1] ); p[i-1] = i4_sign ( is ) * abs ( p[i-1] ); } for ( i = 1; i <= n; i++ ) { i1 = - p[i-1]; if ( 0 <= i1 ) { i0 = i; for ( ; ; ) { i2 = p[i1-1]; p[i1-1] = i0; if ( i2 < 0 ) { break; } i0 = i1; i1 = i2; } } } // // Now we can restore the permutation. // for ( i = 0; i < n; i++ ) { p[i] = p[i] + p_min - base; } return; }