# include # include # include # include # include using namespace std; # include "asa144.hpp" //****************************************************************************80 int i4_max ( int i1, int i2 ) //****************************************************************************80 // // Purpose: // // I4_MAX returns the maximum of two I4's. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 13 October 1998 // // Author: // // John Burkardt // // Parameters: // // Input, int I1, I2, are two integers to be compared. // // Output, int I4_MAX, the larger of I1 and I2. // { int value; if ( i2 < i1 ) { value = i1; } else { value = i2; } return value; } //****************************************************************************80 int i4_min ( int i1, int i2 ) //****************************************************************************80 // // Purpose: // // I4_MIN returns the minimum of two I4's. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 13 October 1998 // // Author: // // John Burkardt // // Parameters: // // Input, int I1, I2, two integers to be compared. // // Output, int I4_MIN, the smaller of I1 and I2. // { int value; if ( i1 < i2 ) { value = i1; } else { value = i2; } return value; } //****************************************************************************80 void i4mat_print ( int m, int n, int a[], string title ) //****************************************************************************80 // // Purpose: // // I4MAT_PRINT prints an I4MAT. // // Discussion: // // An I4MAT is an MxN array of I4's, stored by (I,J) -> [I+J*M]. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 10 September 2009 // // Author: // // John Burkardt // // Parameters: // // Input, int M, the number of rows in A. // // Input, int N, the number of columns in A. // // Input, int A[M*N], the M by N matrix. // // Input, string TITLE, a title. // { i4mat_print_some ( m, n, a, 1, 1, m, n, title ); return; } //****************************************************************************80 void i4mat_print_some ( int m, int n, int a[], int ilo, int jlo, int ihi, int jhi, string title ) //****************************************************************************80 // // Purpose: // // I4MAT_PRINT_SOME prints some of an I4MAT. // // Discussion: // // An I4MAT is an MxN array of I4's, stored by (I,J) -> [I+J*M]. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 20 August 2010 // // Author: // // John Burkardt // // Parameters: // // Input, int M, the number of rows of the matrix. // M must be positive. // // Input, int N, the number of columns of the matrix. // N must be positive. // // Input, int A[M*N], the matrix. // // Input, int ILO, JLO, IHI, JHI, designate the first row and // column, and the last row and column to be printed. // // Input, string TITLE, a title. // { # define INCX 10 int i; int i2hi; int i2lo; int j; int j2hi; int j2lo; cout << "\n"; cout << title << "\n"; if ( m <= 0 || n <= 0 ) { cout << "\n"; cout << " (None)\n"; return; } // // Print the columns of the matrix, in strips of INCX. // for ( j2lo = jlo; j2lo <= jhi; j2lo = j2lo + INCX ) { j2hi = j2lo + INCX - 1; if ( n < j2hi ) { j2hi = n; } if ( jhi < j2hi ) { j2hi = jhi; } cout << "\n"; // // For each column J in the current range... // // Write the header. // cout << " Col:"; for ( j = j2lo; j <= j2hi; j++ ) { cout << " " << setw(6) << j - 1; } cout << "\n"; cout << " Row\n"; cout << "\n"; // // Determine the range of the rows in this strip. // if ( 1 < ilo ) { i2lo = ilo; } else { i2lo = 1; } if ( ihi < m ) { i2hi = ihi; } else { i2hi = m; } for ( i = i2lo; i <= i2hi; i++ ) { // // Print out (up to INCX) entries in row I, that lie in the current strip. // cout << setw(5) << i - 1 << ":"; for ( j = j2lo; j <= j2hi; j++ ) { cout << " " << setw(6) << a[i-1+(j-1)*m]; } cout << "\n"; } } return; # undef INCX } //****************************************************************************80 void i4vec_print ( int n, int a[], string title ) //****************************************************************************80 // // Purpose: // // I4VEC_PRINT prints an I4VEC. // // Discussion: // // An I4VEC is a vector of I4's. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 14 November 2003 // // Author: // // John Burkardt // // Parameters: // // Input, int N, the number of components of the vector. // // Input, int A[N], the vector to be printed. // // Input, string TITLE, a title. // { int i; cout << "\n"; cout << title << "\n"; cout << "\n"; for ( i = 0; i < n; i++ ) { cout << " " << setw(8) << i << ": " << setw(8) << a[i] << "\n"; } return; } //****************************************************************************80 double r8_uniform_01 ( int *seed ) //****************************************************************************80 // // Purpose: // // R8_UNIFORM_01 is a unit pseudorandom R8. // // Discussion: // // This routine implements the recursion // // seed = 16807 * seed mod ( 2**31 - 1 ) // unif = seed / ( 2**31 - 1 ) // // The integer arithmetic never requires more than 32 bits, // including a sign bit. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 11 August 2004 // // Reference: // // Paul Bratley, Bennett Fox, Linus Schrage, // A Guide to Simulation, // Springer Verlag, pages 201-202, 1983. // // Bennett Fox, // Algorithm 647: // Implementation and Relative Efficiency of Quasirandom // Sequence Generators, // ACM Transactions on Mathematical Software, // Volume 12, Number 4, pages 362-376, 1986. // // Parameters: // // Input/output, int *SEED, a seed for the random number generator. // // Output, double R8_UNIFORM_01, a new pseudorandom variate, strictly between // 0 and 1. // { int k; double r; k = *seed / 127773; *seed = 16807 * ( *seed - k * 127773 ) - k * 2836; if ( *seed < 0 ) { *seed = *seed + 2147483647; } r = ( double ) ( *seed ) * 4.656612875E-10; return r; } //****************************************************************************80 void rcont ( int nrow, int ncol, int nrowt[], int ncolt[], int nsubt[], int matrix[], bool *key, int *ifault ) //****************************************************************************80 // // Purpose: // // RCONT generates a random two-way table with given marginal totals. // // Discussion: // // Each time the program is called, another table will be randomly // generated. // // Note that it should be the case that the sum of the row totals // is equal to the sum of the column totals. However, this program // does not check for that condition. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 28 January 2008 // // Author: // // Original FORTRAN77 version by James Boyett. // C++ version by John Burkardt. // // Reference: // // James Boyett, // Algorithm AS 144: // Random R x C Tables with Given Row and Column Totals, // Applied Statistics, // Volume 28, Number 3, pages 329-332, 1979. // // Parameters: // // Input, int NROW, the number of rows in the observed matrix. // // Input, int NCOL, the number of columns in the observed matrix. // // Input, int NROWT[NROW], the row totals of the observed matrix. // // Input, int NCOLT[NCOL], the column totals of the observed matrix. // // Input/output, int NSUBT[NCOL], used by RCONT for partial column sums. // Must not be changed by the calling program. // // Output, int MATRIX[NROW*NCOL], the randomly generated matrix. // // Input/output, bool *KEY, should be set to FALSE by the user before // the initial call. RCONT will reset it to TRUE, and it should be left // at that value for subsequent calls in which the same values of NROW, // NCOL, NROWT and NCOLT are being used. // // Output, int *IFAULT, fault indicator. // 0, no error occured. // 1, NROW <= 0. // 2, NCOL <= 1. // 3, some entry of NROWT is less than 0. // 4, some entry of NCOLT is less than 0. // { int i; int ii; int j; int k; int limit; int *nnvect; int noct; int ntemp; static int ntotal; static int *nvect = NULL; static int seed = 0; *ifault = 0; if ( !(*key) ) { // // Set KEY for subsequent calls. // *key = true; seed = 123456789; // // Check for faults and prepare for future calls. // if ( nrow <= 0 ) { *ifault = 1; return; } if ( ncol <= 1 ) { *ifault = 2; return; } for ( i = 0; i < nrow; i++ ) { if ( nrowt[i] <= 0 ) { *ifault = 3; return; } } if ( ncolt[0] <= 0 ) { *ifault = 4; return; } nsubt[0] = ncolt[0]; for ( j = 1; j < ncol; j++ ) { if ( ncolt[j] <= 0 ) { *ifault = 4; return; } nsubt[j] = nsubt[j-1] + ncolt[j]; } ntotal = nsubt[ncol-1]; if ( nvect ) { delete [] nvect; } nvect = new int[ntotal]; // // Initialize vector to be permuted. // for ( i = 0; i < ntotal; i++ ) { nvect[i] = i + 1; } } // // Initialize vector to be permuted. // nnvect = new int[ntotal]; for ( i = 0; i < ntotal; i++ ) { nnvect[i] = nvect[i]; } // // Permute vector. // ntemp = ntotal; for ( i = 0; i < ntotal; i++ ) { noct = ( int ) ( r8_uniform_01 ( &seed ) * ( double ) ( ntemp ) + 1.0 ); nvect[i] = nnvect[noct-1]; nnvect[noct-1] = nnvect[ntemp-1]; ntemp = ntemp - 1; } // // Construct random matrix. // for ( j = 0; j < ncol; j++ ) { for ( i = 0; i < nrow; i++ ) { matrix[i+j*nrow] = 0; } } ii = 0; for ( i = 0; i < nrow; i++ ) { limit = nrowt[i]; for ( k = 0; k < limit; k++ ) { for ( j = 0; j < ncol; j++ ) { if ( nvect[ii] <= nsubt[j] ) { ii = ii + 1; matrix[i+j*nrow] = matrix[i+j*nrow] + 1; break; } } } } delete [] nnvect; return; }