# include # include # include # include # include # include # include "test_int_nd.h" /******************************************************************************/ char ch_cap ( char ch ) /******************************************************************************/ /* Purpose: ch_cap() capitalizes a single character. Discussion: This routine should be equivalent to the library "toupper" function. Licensing: This code is distributed under the MIT license. Modified: 19 July 1998 Author: John Burkardt Input: char CH, the character to capitalize. Output: char CH_CAP, the capitalized character. */ { if ( 97 <= ch && ch <= 122 ) { ch = ch - 32; } return ch; } /******************************************************************************/ double csevl ( double x, double cs[], int n ) /******************************************************************************/ /* Purpose: csevl() evaluates an N term Chebyshev series. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: Original FORTRAN77 version by Roger Broucke, This version by John Burkardt. Reference: Roger Broucke, Algorithm 446: Ten Subroutines for the Manipulation of Chebyshev Series, Communications of the ACM, Volume 16, 1973, pages 254-256. Leslie Fox, Ian Parker, Chebyshev Polynomials in Numerical Analysis, Oxford Press, 1968, LC: QA297.F65. David Kahaner, Cleve Moler, Steven Nash, Numerical Methods and Software, Prentice Hall, 1989, ISBN: 0-13-627258-4, LC: TA345.K34. Input: double X, the argument at which the series is to be evaluated. X must satisfy -1.0 <= X <= 1.0. double CS(N), the array of N terms of a Chebyshev series. In evaluating CS, only half the first coefficient is summed. int N, the number of terms in array CS. N must be at least 1, and no more than 1000. Output: double CSEVL, the value of the Chebyshev series. */ { double b0; double b1; double b2; int i; double value; if ( n < 1 ) { printf ( "\n" ); printf ( "CSEVL(): Fatal error!\n" ); printf ( " Number of terms N is less than 1.\n" ); exit ( 1 ); } if ( 1000 < n ) { printf ( "\n" ); printf ( "CSEVL(): Fatal error!\n" ); printf ( " The number of terms is more than 1000.\n" ); exit ( 1 ); } if ( x < -1.0 || 1.0 < x ) { printf ( "\n" ); printf ( "CSEVL(): Fatal error!\n" ); printf ( " The input argument X is outside the interval [-1,1].\n" ); exit ( 1 ); } b1 = 0.0; b0 = 0.0; for ( i = n; 1 <= i; i-- ) { b2 = b1; b1 = b0; b0 = 2.0 * x * b1 - b2 + cs[i-1]; } value = 0.5 * ( b0 - b2 ); return value; } /******************************************************************************/ double error_f ( double x ) /******************************************************************************/ /* Purpose: error_f() computes the error function. Discussion: This function was renamed "ERROR_f" from "ERF", to avoid a conflict with the name of a corresponding routine often, but not always, supplied as part of the math support library. The definition of the error function is: ERF(X) = ( 2 / SQRT ( PI ) ) * Integral ( 0 <= T <= X ) EXP ( -T**2 ) dT Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: Original FORTRAN77 version by Wayne Fullerton, This version by John Burkardt. Reference: David Kahaner, Cleve Moler, Steven Nash, Numerical Methods and Software, Prentice Hall, 1989, ISBN: 0-13-627258-4, LC: TA345.K34. Input: double X, the argument of the error function. Output: double ERROR_f, the value of the error function at X. */ { double erfcs[13] = { -0.049046121234691808, -0.14226120510371364, 0.010035582187599796, -0.000576876469976748, 0.000027419931252196, -0.000001104317550734, 0.000000038488755420, -0.000000001180858253, 0.000000000032334215, -0.000000000000799101, 0.000000000000017990, -0.000000000000000371, 0.000000000000000007 }; static int nterf = 0; static double sqeps = 0.0; double sqrtpi = 1.7724538509055160; double value; static double xbig = 0.0; double y; /* Initialize the Chebyshev series. */ if ( nterf == 0 ) { nterf = inits ( erfcs, 13, 0.1 * DBL_EPSILON ); xbig = sqrt ( - log ( sqrtpi * DBL_EPSILON ) ); sqeps = sqrt ( 2.0 * DBL_EPSILON ); } y = fabs ( x ); if ( y <= sqeps ) { value = 2.0 * x / sqrtpi; } else if ( y <= 1.0 ) { value = x * ( 1.0 + csevl ( 2.0 * x * x - 1.0, erfcs, nterf ) ); } else if ( y <= xbig ) { value = ( 1.0 - error_fc ( y ) ) * r8_sign ( x ); } else { value = r8_sign ( x ); } return value; } /******************************************************************************/ double error_fc ( double x ) /******************************************************************************/ /* Purpose: error_fc() computes the complementary error function. Discussion: This function was renamed "ERROR_fC" from "ERFC", to avoid a conflict with the name of a corresponding routine often, but not always, supplied as part of the math support library. The definition of the complementary error function is: ERFC(X) = 1 - ERF(X) where ERF(X) is the error function. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: Original FORTRAN77 version by Wayne Fullerton, This version by John Burkardt. Reference: David Kahaner, Cleve Moler, Steven Nash, Numerical Methods and Software, Prentice Hall, 1989, ISBN: 0-13-627258-4, LC: TA345.K34. Input: double X, the argument of the error function. Output: double ERROR_fC, the value of the complementary error function at X. */ { double erfcs[13] = { -0.049046121234691808, -0.14226120510371364, 0.010035582187599796, -0.000576876469976748, 0.000027419931252196, -0.000001104317550734, 0.000000038488755420, -0.000000001180858253, 0.000000000032334215, -0.000000000000799101, 0.000000000000017990, -0.000000000000000371, 0.000000000000000007 }; double erfccs[24] = { 0.0715179310202925, -0.026532434337606719, 0.001711153977920853, -0.000163751663458512, 0.000019871293500549, -0.000002843712412769, 0.000000460616130901, -0.000000082277530261, 0.000000015921418724, -0.000000003295071356, 0.000000000722343973, -0.000000000166485584, 0.000000000040103931, -0.000000000010048164, 0.000000000002608272, -0.000000000000699105, 0.000000000000192946, -0.000000000000054704, 0.000000000000015901, -0.000000000000004729, 0.000000000000001432, -0.000000000000000439, 0.000000000000000138, -0.000000000000000048 }; double erc2cs[23] = { -0.069601346602309501, -0.041101339362620893, 0.003914495866689626, -0.000490639565054897, 0.000071574790013770, -0.000011530716341312, 0.000001994670590201, -0.000000364266647159, 0.000000069443726100, -0.000000013712209021, 0.000000002788389661, -0.000000000581416472, 0.000000000123892049, -0.000000000026906391, 0.000000000005942614, -0.000000000001332386, 0.000000000000302804, -0.000000000000069666, 0.000000000000016208, -0.000000000000003809, 0.000000000000000904, -0.000000000000000216, 0.000000000000000052 }; double eta; static int nterc2 = 0; static int nterf = 0; static int nterfc = 0; static double sqeps = 0.0; double sqrtpi = 1.7724538509055160; double value; static double xmax = 0.0; static double xsml = 0.0; double y; if ( nterf == 0 ) { eta = 0.1 * DBL_EPSILON; nterf = inits ( erfcs, 13, eta ); nterfc = inits ( erfccs, 24, eta ); nterc2 = inits ( erc2cs, 23, eta ); xsml = -sqrt ( - log ( sqrtpi * DBL_EPSILON ) ); xmax = sqrt ( - log ( sqrtpi * r8_tiny ( ) ) ); xmax = xmax - 0.5 * log ( xmax ) / xmax - 0.01; sqeps = sqrt ( 2.0 * DBL_EPSILON ); } if ( x <= xsml ) { value = 2.0; return value; } /* X so big that ERFC will underflow. */ if ( xmax < x ) { value = 0.0; return value; } y = fabs ( x ); /* erfc(x) = 1.0 - erf(x) for -1 <= x <= 1. */ if ( y <= 1.0 ) { if ( y < sqeps ) { value = 1.0 - 2.0 * x / sqrtpi; } else if ( sqeps <= y ) { value = 1.0 - x * ( 1.0 + csevl ( 2.0 * x * x - 1.0, erfcs, nterf ) ); } return value; } /* For 1 < |x| <= xmax, erfc(x) = 1.0 - erf(x) */ y = y * y; if ( y <= 4.0 ) { value = exp ( -y ) / fabs ( x ) * ( 0.5 + csevl ( ( 8.0 / y - 5.0 ) / 3.0, erc2cs, nterc2 ) ); } else { value = exp ( -y ) / fabs ( x ) * ( 0.5 + csevl ( 8.0 / y - 1.0, erfccs, nterfc ) ); } if ( x < 0.0 ) { value = 2.0 - value; } return value; } /******************************************************************************/ int get_problem_num ( ) /******************************************************************************/ /* Purpose: get_problem_num() returns the number of test integration problems. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: int PROBLEM_NUM, the number of test integration problems. */ { int problem_num; problem_num = 32; return problem_num; } /******************************************************************************/ int i4_huge ( ) /******************************************************************************/ /* Purpose: i4_huge() returns a "huge" I4. Licensing: This code is distributed under the MIT license. Modified: 16 May 2003 Author: John Burkardt Output: int I4_HUGE, a "huge" I4. */ { return 2147483647; } /******************************************************************************/ int i4_power ( int i, int j ) /******************************************************************************/ /* Purpose: i4_power() returns the value of I^J. Licensing: This code is distributed under the MIT license. Modified: 01 April 2004 Author: John Burkardt Input: int I, J, the base and the power. J should be nonnegative. Output: int I4_POWER, the value of I^J. */ { int k; int value; if ( j < 0 ) { if ( i == 1 ) { value = 1; } else if ( i == 0 ) { printf ( "\n" ); printf ( "I4_POWER(): Fatal error!\n" ); printf ( " I^J requested, with I = 0 and J negative.\n" ); exit ( 1 ); } else { value = 0; } } else if ( j == 0 ) { if ( i == 0 ) { printf ( "\n" ); printf ( "I4_POWER(): Fatal error!\n" ); printf ( " I^J requested, with I = 0 and J = 0.\n" ); exit ( 1 ); } else { value = 1; } } else if ( j == 1 ) { value = i; } else { value = 1; for ( k = 1; k <= j; k++ ) { value = value * i; } } return value; } /******************************************************************************/ void i4vec_copy ( int n, int a1[], int a2[] ) /******************************************************************************/ /* Purpose: i4vec_copy() copies an I4VEC. Licensing: This code is distributed under the MIT license. Modified: 29 June 2005 Author: John Burkardt Input: int N, the number of entries in the vectors. int A1[N], the vector to be copied. Output: int A2[N], the copy of A1. */ { int i; for ( i = 0; i < n; i++ ) { a2[i] = a2[i]; } return; } /******************************************************************************/ int i4vec_sum ( int n, int a[] ) /******************************************************************************/ /* Purpose: i4vec_sum() sums the entries of an I4VEC. Example: Input: A = ( 1, 2, 3, 4 ) Output: I4VEC_SUM = 10 Licensing: This code is distributed under the MIT license. Modified: 26 May 1999 Author: John Burkardt Input: int N, the number of entries in the vector. int A[N], the vector to be summed. Output: int I4VEC_SUM, the sum of the entries of A. */ { int i; int sum; sum = 0; for ( i = 0; i < n; i++ ) { sum = sum + a[i]; } return sum; } /******************************************************************************/ int inits ( double os[], int nos, double eta ) /******************************************************************************/ /* Purpose: inits() estimates the order of an orthogonal series for a given accuracy. Discussion: Because this is a function, it is not possible to print out warning error messages. Therefore, if an error condition is detected, a bogus value of INITS is returned. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: Original FORTRAN77 version by Roger Broucke, This version by John Burkardt. Reference: Roger Broucke, Algorithm 446: Ten Subroutines for the Manipulation of Chebyshev Series, Communications of the ACM, Volume 16, 1973, pages 254-256. David Kahaner, Cleve Moler, Steven Nash, Numerical Methods and Software, Prentice Hall, 1989, ISBN: 0-13-627258-4, LC: TA345.K34. Input: double OS[NOS], the coefficients in the series. int NOS, the number of coefficients. NOS must be at least 1, or an error condition arises. double ETA, the requested accuracy of the series. Ordinarily, ETA will be chosen to be one-tenth machine precision. Output: int INITS, the order of the series guaranteeing the given accuracy. However, on error, INITS will be returned as a negative number. */ { double err; int i; int ii; int value; /* Fatal error. Number of coefficients less than 1. But an error message cannot be printed out because this is a function. */ if ( nos < 1 ) { value = - i4_huge ( ); return value; } err = 0.0; i = 0; for ( ii = 1; ii <= nos; ii++ ) { i = nos + 1 - ii; err = err + fabs ( os[i-1] ); if ( eta < err ) { i = nos + 1 - ii; break; } } /* Eta may be too small. Accuracy cannot be guaranteed. But an error message cannot be printed out because this is a function. */ if ( i == 0 ) { i = - nos; } value = i; return value; } /******************************************************************************/ double normal_01_cdf_inv ( double cdf ) /******************************************************************************/ /* Purpose: normal_01_cdf_inv() inverts the Normal 01 CDF. Discussion: Modified to handle cases where R = 0 would result in LOG(0). Licensing: This code is distributed under the MIT license. Modified: 05 June 2007 Author: Original FORTRAN77 version by JD Beasley, SG Springer, This version by John Burkardt. Reference: JD Beasley, SG Springer, Algorithm AS 111: The Percentage Points of the Normal Distribution, Applied Statistics, Volume 26, 1977, pages 118-121. Input: double CDF, the value of the CDF. 0.0 <= CDF <= 1.0. Output: double NORMAL_01_CDF_INV, the corresponding argument. */ { double a0 = 2.50662823884; double a1 = -18.61500062529; double a2 = 41.39119773534; double a3 = -25.44106049637; double b1 = -8.47351093090; double b2 = 23.08336743743; double b3 = -21.06224101826; double b4 = 3.13082909833; double c0 = -2.78718931138; double c1 = -2.29796479134; double c2 = 4.85014127135; double c3 = 2.32121276858; double d1 = 3.54388924762; double d2 = 1.63706781897; double q; double r; double x; if ( cdf < 0.0 || 1.0 < cdf ) { printf ( "\n" ); printf ( "NORMAL_01_CDF_INV(): Fatal error!\n" ); printf ( " CDF < 0 or 1 < CDF.\n" ); exit ( 1 ); } q = cdf - 0.5; q = fmin ( q, 0.5 ); q = fmax ( q, -0.5 ); /* 0.08 < CDF < 0.92 */ if ( fabs ( q ) <= 0.42 ) { r = q * q; x = q * ( ( ( a3 * r + a2 ) * r + a1 ) * r + a0 ) / ( ( ( ( b4 * r + b3 ) * r + b2 ) * r + b1 ) * r + 1.0 ); } /* CDF < 0.08 or 0.92 < CDF. */ else { r = fmin ( cdf, 1.0 - cdf ); r = fmax ( r, 0.0 ); r = fmin ( r, 1.0 ); if ( r <= 0.0 ) { x = HUGE_VAL; } else { r = sqrt ( - log ( r ) ); x = ( ( ( c3 * r + c2 ) * r + c1 ) * r + c0 ) / ( ( d2 * r + d1 ) * r + 1.0 ); } if ( q < 0.0 ) { x = - x; } } return x; } /******************************************************************************/ double p00_box_gl05 ( int problem, int dim_num, int sub_num ) /******************************************************************************/ /* Purpose: p00_box_gl05() uses Gauss-Legendre quadrature in an N-dimensional box. Discussion: The rule is the product of 5-point Gauss-Legendre rules in each spatial dimension. Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Input: int PROBLEM, the problem number. int DIM_NUM, the spatial dimension. int SUB_NUM, the number of subdivisions in each dimension. Output: double P00_BOX_GL05, the approximate integral. */ { # define NORDER 5 double *a; double *a_sub; double *b; double *b_sub; int dim; int *indx; int j; int k; int point; int point_num = 1; double result; int *sub_indx; double *value; double volume; double w; double weight[NORDER] = { 0.236926885056189087514264040720, 0.478628670499366468041291514836, 0.568888888888888888888888888889, 0.478628670499366468041291514836, 0.236926885056189087514264040720 }; double *x; double xtab[NORDER] = { - 0.906179845938663992797626878299, - 0.538469310105683091036314420700, 0.0, 0.538469310105683091036314420700, 0.906179845938663992797626878299 }; /* Get the integration limits, and the weight adjustment factor. */ a = ( double * ) malloc ( dim_num * sizeof ( double ) ); a_sub = ( double * ) malloc ( dim_num * sizeof ( double ) ); b = ( double * ) malloc ( dim_num * sizeof ( double ) ); b_sub = ( double * ) malloc ( dim_num * sizeof ( double ) ); indx = ( int * ) malloc ( dim_num * sizeof ( int ) ); sub_indx = ( int * ) malloc ( dim_num * sizeof ( int ) ); x = ( double * ) malloc ( dim_num * point_num * sizeof ( double ) ); p00_lim ( problem, dim_num, a, b ); /* Carry out the product rule. */ result = 0.0; /* In the outer loop, we pick a sub-box. */ j = 0; for ( ; ; ) { tuple_next ( 1, sub_num, dim_num, &j, sub_indx ); if ( j == 0 ) { break; } for ( dim = 0; dim < dim_num; dim++ ) { a_sub[dim] = ( ( double ) ( sub_num + 1 - sub_indx[dim] ) * a[dim] + ( double ) ( - 1 + sub_indx[dim] ) * b[dim] ) / ( double ) ( sub_num ); b_sub[dim] = ( ( double ) ( sub_num - sub_indx[dim] ) * a[dim] + ( double ) ( sub_indx[dim] ) * b[dim] ) / ( double ) ( sub_num ); } /* In the inner loop, we go through all the points in the cross product of the quadrature rule. */ k = 0; for ( ; ; ) { tuple_next ( 1, NORDER, dim_num, &k, indx ); if ( k == 0 ) { break; } w = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { w = w * weight[indx[dim]-1]; } point = 0; for ( dim = 0; dim < dim_num; dim++ ) { x[dim+point*dim_num] = 0.5 * ( a_sub[dim] * ( 1.0 - xtab[indx[dim]-1] ) + b_sub[dim] * ( 1.0 + xtab[indx[dim]-1] ) ); } value = p00_f ( problem, dim_num, point_num, x ); for ( point = 0; point < point_num; point++ ) { result = result + w * value[point]; } free ( value ); } } /* Get the volume. */ volume = p00_volume ( problem, dim_num ); result = result * volume / ( double ) ( i4_power ( 2 * sub_num, dim_num ) ); free ( a ); free ( a_sub ); free ( b ); free ( b_sub ); free ( indx ); free ( sub_indx ); free ( x ); return result; # undef NORDER } /******************************************************************************/ double p00_box_mc ( int problem, int dim_num, int point_num ) /******************************************************************************/ /* Purpose: p00_box_mc() integrates over an multi-dimensional box using Monte Carlo. Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Input: int PROBLEM, the problem number. int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points to use. Output: double P00_BOX_MC, the approximate integral. */ { double *a; double *b; int dim; int point; double result; int seed = 123456789; double *value; double volume; double *x; /* Get the volume. */ volume = p00_volume ( problem, dim_num ); /* Get the integration limits. */ a = ( double * ) malloc ( dim_num * sizeof ( double ) ); b = ( double * ) malloc ( dim_num * sizeof ( double ) ); p00_lim ( problem, dim_num, a, b ); /* Get the random values. */ x = r8vec_uniform_01 ( dim_num*point_num, &seed ); /* Map them to the integration retion. */ for ( point = 0; point < point_num; point++ ) { for ( dim = 0; dim < dim_num; dim++ ) { x[dim+point*dim_num] = ( a[dim] * ( 1.0 - x[dim+point*dim_num] ) + b[dim] * ( + x[dim+point*dim_num] ) ); } } /* Evaluate the function. */ value = p00_f ( problem, dim_num, point_num, x ); /* Estimate the integral. */ result = r8vec_sum ( point_num, value ) * volume / ( double ) ( point_num ); free ( a ); free ( b ); free ( value ); free ( x ); return result; } /******************************************************************************/ void p00_default ( int problem, int dim_num ) /******************************************************************************/ /* Purpose: p00_default() sets a problem to a default state. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 10 March 2007 Author: John Burkardt Input: int PROBLEM, the number of the desired test problem. int DIM_NUM, the dimension of the problem. */ { if ( problem == 1 ) { p01_default ( dim_num ); } else if ( problem == 2 ) { p02_default ( dim_num ); } else if ( problem == 3 ) { p03_default ( dim_num ); } else if ( problem == 4 ) { p04_default ( dim_num ); } else if ( problem == 5 ) { p05_default ( dim_num ); } else if ( problem == 6 ) { p06_default ( dim_num ); } else if ( problem == 7 ) { p07_default ( dim_num ); } else if ( problem == 8 ) { p08_default ( dim_num ); } else if ( problem == 9 ) { p09_default ( dim_num ); } else if ( problem == 10 ) { p10_default ( dim_num ); } else if ( problem == 11 ) { p11_default ( dim_num ); } else if ( problem == 12 ) { p12_default ( dim_num ); } else if ( problem == 13 ) { p13_default ( dim_num ); } else if ( problem == 14 ) { p14_default ( dim_num ); } else if ( problem == 15 ) { p15_default ( dim_num ); } else if ( problem == 16 ) { p16_default ( dim_num ); } else if ( problem == 17 ) { p17_default ( dim_num ); } else if ( problem == 18 ) { p18_default ( dim_num ); } else if ( problem == 19 ) { p19_default ( dim_num ); } else if ( problem == 20 ) { p20_default ( dim_num ); } else if ( problem == 21 ) { p21_default ( dim_num ); } else if ( problem == 22 ) { p22_default ( dim_num ); } else if ( problem == 23 ) { p23_default ( dim_num ); } else if ( problem == 24 ) { p24_default ( dim_num ); } else if ( problem == 25 ) { p25_default ( dim_num ); } else if ( problem == 26 ) { p26_default ( dim_num ); } else if ( problem == 27 ) { p27_default ( dim_num ); } else if ( problem == 28 ) { p28_default ( dim_num ); } else if ( problem == 29 ) { p29_default ( dim_num ); } else if ( problem == 30 ) { p30_default ( dim_num ); } else if ( problem == 31 ) { p31_default ( dim_num ); } else if ( problem == 32 ) { p32_default ( dim_num ); } else { printf ( "\n" ); printf ( "p00_default(): Fatal error!\n" ); printf ( " Illegal problem number = %d\n", problem ); exit ( 1 ); } return; } /******************************************************************************/ double p00_exact ( int problem, int dim_num ) /******************************************************************************/ /* Purpose: p00_exact() returns the exact integral for any problem. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int PROBLEM, the number of the desired test problem. int DIM_NUM, the dimension of the problem. Output: double P00_exact, the exact value of the integral. */ { double exact; if ( problem == 1 ) { exact = p01_exact ( dim_num ); } else if ( problem == 2 ) { exact = p02_exact ( dim_num ); } else if ( problem == 3 ) { exact = p03_exact ( dim_num ); } else if ( problem == 4 ) { exact = p04_exact ( dim_num ); } else if ( problem == 5 ) { exact = p05_exact ( dim_num ); } else if ( problem == 6 ) { exact = p06_exact ( dim_num ); } else if ( problem == 7 ) { exact = p07_exact ( dim_num ); } else if ( problem == 8 ) { exact = p08_exact ( dim_num ); } else if ( problem == 9 ) { exact = p09_exact ( dim_num ); } else if ( problem == 10 ) { exact = p10_exact ( dim_num ); } else if ( problem == 11 ) { exact = p11_exact ( dim_num ); } else if ( problem == 12 ) { exact = p12_exact ( dim_num ); } else if ( problem == 13 ) { exact = p13_exact ( dim_num ); } else if ( problem == 14 ) { exact = p14_exact ( dim_num ); } else if ( problem == 15 ) { exact = p15_exact ( dim_num ); } else if ( problem == 16 ) { exact = p16_exact ( dim_num ); } else if ( problem == 17 ) { exact = p17_exact ( dim_num ); } else if ( problem == 18 ) { exact = p18_exact ( dim_num ); } else if ( problem == 19 ) { exact = p19_exact ( dim_num ); } else if ( problem == 20 ) { exact = p20_exact ( dim_num ); } else if ( problem == 21 ) { exact = p21_exact ( dim_num ); } else if ( problem == 22 ) { exact = p22_exact ( dim_num ); } else if ( problem == 23 ) { exact = p23_exact ( dim_num ); } else if ( problem == 24 ) { exact = p24_exact ( dim_num ); } else if ( problem == 25 ) { exact = p25_exact ( dim_num ); } else if ( problem == 26 ) { exact = p26_exact ( dim_num ); } else if ( problem == 27 ) { exact = p27_exact ( dim_num ); } else if ( problem == 28 ) { exact = p28_exact ( dim_num ); } else if ( problem == 29 ) { exact = p29_exact ( dim_num ); } else if ( problem == 30 ) { exact = p30_exact ( dim_num ); } else if ( problem == 31 ) { exact = p31_exact ( dim_num ); } else if ( problem == 32 ) { exact = p32_exact ( dim_num ); } else { printf ( "\n" ); printf ( "p00_exact(): Fatal error!\n" ); printf ( " Illegal problem number = %d\n", problem ); exit ( 1 ); } return exact; } /******************************************************************************/ double *p00_f ( int problem, int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p00_f() evaluates the integrand for any problem. Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Input: int PROBLEM, the number of the desired test problem. int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P00_f[POINT_NUM], the integrand values. */ { double *value; if ( problem == 1 ) { value = p01_f ( dim_num, point_num, x ); } else if ( problem == 2 ) { value = p02_f ( dim_num, point_num, x ); } else if ( problem == 3 ) { value = p03_f ( dim_num, point_num, x ); } else if ( problem == 4 ) { value = p04_f ( dim_num, point_num, x ); } else if ( problem == 5 ) { value = p05_f ( dim_num, point_num, x ); } else if ( problem == 6 ) { value = p06_f ( dim_num, point_num, x ); } else if ( problem == 7 ) { value = p07_f ( dim_num, point_num, x ); } else if ( problem == 8 ) { value = p08_f ( dim_num, point_num, x ); } else if ( problem == 9 ) { value = p09_f ( dim_num, point_num, x ); } else if ( problem == 10 ) { value = p10_f ( dim_num, point_num, x ); } else if ( problem == 11 ) { value = p11_f ( dim_num, point_num, x ); } else if ( problem == 12 ) { value = p12_f ( dim_num, point_num, x ); } else if ( problem == 13 ) { value = p13_f ( dim_num, point_num, x ); } else if ( problem == 14 ) { value = p14_f ( dim_num, point_num, x ); } else if ( problem == 15 ) { value = p15_f ( dim_num, point_num, x ); } else if ( problem == 16 ) { value = p16_f ( dim_num, point_num, x ); } else if ( problem == 17 ) { value = p17_f ( dim_num, point_num, x ); } else if ( problem == 18 ) { value = p18_f ( dim_num, point_num, x ); } else if ( problem == 19 ) { value = p19_f ( dim_num, point_num, x ); } else if ( problem == 20 ) { value = p20_f ( dim_num, point_num, x ); } else if ( problem == 21 ) { value = p21_f ( dim_num, point_num, x ); } else if ( problem == 22 ) { value = p22_f ( dim_num, point_num, x ); } else if ( problem == 23 ) { value = p23_f ( dim_num, point_num, x ); } else if ( problem == 24 ) { value = p24_f ( dim_num, point_num, x ); } else if ( problem == 25 ) { value = p25_f ( dim_num, point_num, x ); } else if ( problem == 26 ) { value = p26_f ( dim_num, point_num, x ); } else if ( problem == 27 ) { value = p27_f ( dim_num, point_num, x ); } else if ( problem == 28 ) { value = p28_f ( dim_num, point_num, x ); } else if ( problem == 29 ) { value = p29_f ( dim_num, point_num, x ); } else if ( problem == 30 ) { value = p30_f ( dim_num, point_num, x ); } else if ( problem == 31 ) { value = p31_f ( dim_num, point_num, x ); } else if ( problem == 32 ) { value = p32_f ( dim_num, point_num, x ); } else { printf ( "\n" ); printf ( "p00_f(): Fatal error!\n" ); printf ( " Illegal problem number = %d\n", problem ); exit ( 1 ); } return value; } /******************************************************************************/ void p00_i4 ( int problem, char action, char name, int *value ) /******************************************************************************/ /* Purpose: p00_i4() sets or gets I4 parameter values for any problem. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: int PROBLEM, the number of the desired test problem. char action, 'D' to set a parameter to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int VALUE. * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { if ( problem == 1 ) { p01_i4 ( action, name, value ); } else if ( problem == 2 ) { p02_i4 ( action, name, value ); } else if ( problem == 3 ) { p03_i4 ( action, name, value ); } else if ( problem == 4 ) { p04_i4 ( action, name, value ); } else if ( problem == 5 ) { p05_i4 ( action, name, value ); } else if ( problem == 6 ) { p06_i4 ( action, name, value ); } else if ( problem == 7 ) { p07_i4 ( action, name, value ); } else if ( problem == 8 ) { p08_i4 ( action, name, value ); } else if ( problem == 9 ) { p09_i4 ( action, name, value ); } else if ( problem == 10 ) { p10_i4 ( action, name, value ); } else if ( problem == 11 ) { p11_i4 ( action, name, value ); } else if ( problem == 12 ) { p12_i4 ( action, name, value ); } else if ( problem == 13 ) { p13_i4 ( action, name, value ); } else if ( problem == 14 ) { p14_i4 ( action, name, value ); } else if ( problem == 15 ) { p15_i4 ( action, name, value ); } else if ( problem == 16 ) { p16_i4 ( action, name, value ); } else if ( problem == 17 ) { p17_i4 ( action, name, value ); } else if ( problem == 18 ) { p18_i4 ( action, name, value ); } else if ( problem == 19 ) { p19_i4 ( action, name, value ); } else if ( problem == 20 ) { p20_i4 ( action, name, value ); } else if ( problem == 21 ) { p21_i4 ( action, name, value ); } else if ( problem == 22 ) { p22_i4 ( action, name, value ); } else if ( problem == 23 ) { p23_i4 ( action, name, value ); } else if ( problem == 24 ) { p24_i4 ( action, name, value ); } else if ( problem == 25 ) { p25_i4 ( action, name, value ); } else if ( problem == 26 ) { p26_i4 ( action, name, value ); } else if ( problem == 27 ) { p27_i4 ( action, name, value ); } else if ( problem == 28 ) { p28_i4 ( action, name, value ); } else if ( problem == 29 ) { p29_i4 ( action, name, value ); } else if ( problem == 30 ) { p30_i4 ( action, name, value ); } else if ( problem == 31 ) { p31_i4 ( action, name, value ); } else if ( problem == 32 ) { p32_i4 ( action, name, value ); } else { printf ( "\n" ); printf ( "p00_i4(): Fatal error!\n" ); printf ( " Illegal problem number = %d\n", problem ); exit ( 1 ); } return; } /******************************************************************************/ void p00_lim ( int problem, int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p00_lim() returns the integration limits for any problem. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int PROBLEM, the number of the desired test problem. int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { if ( problem == 1 ) { p01_lim ( dim_num, a, b ); } else if ( problem == 2 ) { p02_lim ( dim_num, a, b ); } else if ( problem == 3 ) { p03_lim ( dim_num, a, b ); } else if ( problem == 4 ) { p04_lim ( dim_num, a, b ); } else if ( problem == 5 ) { p05_lim ( dim_num, a, b ); } else if ( problem == 6 ) { p06_lim ( dim_num, a, b ); } else if ( problem == 7 ) { p07_lim ( dim_num, a, b ); } else if ( problem == 8 ) { p08_lim ( dim_num, a, b ); } else if ( problem == 9 ) { p09_lim ( dim_num, a, b ); } else if ( problem == 10 ) { p10_lim ( dim_num, a, b ); } else if ( problem == 11 ) { p11_lim ( dim_num, a, b ); } else if ( problem == 12 ) { p12_lim ( dim_num, a, b ); } else if ( problem == 13 ) { p13_lim ( dim_num, a, b ); } else if ( problem == 14 ) { p14_lim ( dim_num, a, b ); } else if ( problem == 15 ) { p15_lim ( dim_num, a, b ); } else if ( problem == 16 ) { p16_lim ( dim_num, a, b ); } else if ( problem == 17 ) { p17_lim ( dim_num, a, b ); } else if ( problem == 18 ) { p18_lim ( dim_num, a, b ); } else if ( problem == 19 ) { p19_lim ( dim_num, a, b ); } else if ( problem == 20 ) { p20_lim ( dim_num, a, b ); } else if ( problem == 21 ) { p21_lim ( dim_num, a, b ); } else if ( problem == 22 ) { p22_lim ( dim_num, a, b ); } else if ( problem == 23 ) { p23_lim ( dim_num, a, b ); } else if ( problem == 24 ) { p24_lim ( dim_num, a, b ); } else if ( problem == 25 ) { p25_lim ( dim_num, a, b ); } else if ( problem == 26 ) { p26_lim ( dim_num, a, b ); } else if ( problem == 27 ) { p27_lim ( dim_num, a, b ); } else if ( problem == 28 ) { p28_lim ( dim_num, a, b ); } else if ( problem == 29 ) { p29_lim ( dim_num, a, b ); } else if ( problem == 30 ) { p30_lim ( dim_num, a, b ); } else if ( problem == 31 ) { p31_lim ( dim_num, a, b ); } else if ( problem == 32 ) { p32_lim ( dim_num, a, b ); } else { printf ( "\n" ); printf ( "p00_lim(): Fatal error!\n" ); printf ( " Illegal problem number = %d\n", problem ); exit ( 1 ); } return; } /******************************************************************************/ char *p00_name ( int problem ) /******************************************************************************/ /* Purpose: p00_name() returns the name of the problem. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int PROBLEM, the number of the desired test problem. Output: char *p00_name, the name of the problem. */ { char *value; if ( problem == 1 ) { value = p01_name ( ); } else if ( problem == 2 ) { value = p02_name ( ); } else if ( problem == 3 ) { value = p03_name ( ); } else if ( problem == 4 ) { value = p04_name ( ); } else if ( problem == 5 ) { value = p05_name ( ); } else if ( problem == 6 ) { value = p06_name ( ); } else if ( problem == 7 ) { value = p07_name ( ); } else if ( problem == 8 ) { value = p08_name ( ); } else if ( problem == 9 ) { value = p09_name ( ); } else if ( problem == 10 ) { value = p10_name ( ); } else if ( problem == 11 ) { value = p11_name ( ); } else if ( problem == 12 ) { value = p12_name ( ); } else if ( problem == 13 ) { value = p13_name ( ); } else if ( problem == 14 ) { value = p14_name ( ); } else if ( problem == 15 ) { value = p15_name ( ); } else if ( problem == 16 ) { value = p16_name ( ); } else if ( problem == 17 ) { value = p17_name ( ); } else if ( problem == 18 ) { value = p18_name ( ); } else if ( problem == 19 ) { value = p19_name ( ); } else if ( problem == 20 ) { value = p20_name ( ); } else if ( problem == 21 ) { value = p21_name ( ); } else if ( problem == 22 ) { value = p22_name ( ); } else if ( problem == 23 ) { value = p23_name ( ); } else if ( problem == 24 ) { value = p24_name ( ); } else if ( problem == 25 ) { value = p25_name ( ); } else if ( problem == 26 ) { value = p26_name ( ); } else if ( problem == 27 ) { value = p27_name ( ); } else if ( problem == 28 ) { value = p28_name ( ); } else if ( problem == 29 ) { value = p29_name ( ); } else if ( problem == 30 ) { value = p30_name ( ); } else if ( problem == 31 ) { value = p31_name ( ); } else if ( problem == 32 ) { value = p32_name ( ); } else { printf ( "\n" ); printf ( "p00_name(): Fatal error!\n" ); printf ( " Illegal problem number = %d\n", problem ); exit ( 1 ); } return value; } /******************************************************************************/ void p00_r8vec ( int problem, char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p00_r8vec() sets or gets R8VEC parameter values for any problem. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: int PROBLEM, the number of the desired test problem. char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the should be returned. 'R' means randomize the object and return it. 'S' means the input value of the object should be stored. char name, the name of the variable. int DIM_NUM, the dimension of the variable. double VALUE[DIM_NUM], the value of the variable. Output: double VALUE[DIM_NUM]: the value of the variable. */ { if ( problem == 1 ) { } else if ( problem == 2 ) { } else if ( problem == 3 ) { } else if ( problem == 4 ) { } else if ( problem == 5 ) { } else if ( problem == 6 ) { } else if ( problem == 7 ) { } else if ( problem == 8 ) { } else if ( problem == 9 ) { p09_r8vec ( action, name, dim_num, value ); } else if ( problem == 10 ) { } else if ( problem == 11 ) { } else if ( problem == 12 ) { } else if ( problem == 13 ) { } else if ( problem == 14 ) { } else if ( problem == 15 ) { } else if ( problem == 16 ) { p16_r8vec ( action, name, dim_num, value ); } else if ( problem == 17 ) { p17_r8vec ( action, name, dim_num, value ); } else if ( problem == 18 ) { p18_r8vec ( action, name, dim_num, value ); } else if ( problem == 19 ) { p19_r8vec ( action, name, dim_num, value ); } else if ( problem == 20 ) { } else if ( problem == 21 ) { } else if ( problem == 22 ) { } else if ( problem == 23 ) { } else if ( problem == 24 ) { p24_r8vec ( action, name, dim_num, value ); } else if ( problem == 25 ) { } else if ( problem == 26 ) { p26_r8vec ( action, name, dim_num, value ); } else if ( problem == 27 ) { p27_r8vec ( action, name, dim_num, value ); } else if ( problem == 28 ) { p28_r8vec ( action, name, dim_num, value ); } else if ( problem == 29 ) { p29_r8vec ( action, name, dim_num, value ); } else if ( problem == 30 ) { p30_r8vec ( action, name, dim_num, value ); } else if ( problem == 31 ) { p31_r8vec ( action, name, dim_num, value ); } else if ( problem == 32 ) { p32_r8vec ( action, name, dim_num, value ); } else { printf ( "\n" ); printf ( "p00_r8vec(): Fatal error!\n" ); printf ( " Illegal problem number = %d\n", problem ); exit ( 1 ); } return; } /******************************************************************************/ char *p00_region ( int problem ) /******************************************************************************/ /* Purpose: p00_region() returns the name of the integration region for any problem. Discussion: I thought I was going to use this idea a lot, but most of my test regions are boxes. BALL the interior of a 2D circle, the interior of a 3D sphere, the interior of an ND sphere. BOX a 1D finite line segment, a 2D finite rectangle, a 3D box, an ND box. SIMPLEX a 2D triangle, a 3D tetrahedron, an ND simplex. The "unit simplex" in ND is the set of nonnegative points X such that sum ( X(1:N) ) <= 1. SPACE a 1D infinite line, a 2D infinite place, a 3D space, an ND space. SPHERE the circumference of a 2D circle, the surface of a 3D sphere, the surface of an ND sphere. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: int PROBLEM, the number of the desired test problem. Output: char *REGION, the name of the integration region. */ { char *value; if ( problem == 1 ) { value = p01_region ( ); } else if ( problem == 2 ) { value = p02_region ( ); } else if ( problem == 3 ) { value = p03_region ( ); } else if ( problem == 4 ) { value = p04_region ( ); } else if ( problem == 5 ) { value = p05_region ( ); } else if ( problem == 6 ) { value = p06_region ( ); } else if ( problem == 7 ) { value = p07_region ( ); } else if ( problem == 8 ) { value = p08_region ( ); } else if ( problem == 9 ) { value = p09_region ( ); } else if ( problem == 10 ) { value = p10_region ( ); } else if ( problem == 11 ) { value = p11_region ( ); } else if ( problem == 12 ) { value = p12_region ( ); } else if ( problem == 13 ) { value = p13_region ( ); } else if ( problem == 14 ) { value = p14_region ( ); } else if ( problem == 15 ) { value = p15_region ( ); } else if ( problem == 16 ) { value = p16_region ( ); } else if ( problem == 17 ) { value = p17_region ( ); } else if ( problem == 18 ) { value = p18_region ( ); } else if ( problem == 19 ) { value = p19_region ( ); } else if ( problem == 20 ) { value = p20_region ( ); } else if ( problem == 21 ) { value = p21_region ( ); } else if ( problem == 22 ) { value = p22_region ( ); } else if ( problem == 23 ) { value = p23_region ( ); } else if ( problem == 24 ) { value = p24_region ( ); } else if ( problem == 25 ) { value = p25_region ( ); } else if ( problem == 26 ) { value = p26_region ( ); } else if ( problem == 27 ) { value = p27_region ( ); } else if ( problem == 28 ) { value = p28_region ( ); } else if ( problem == 29 ) { value = p29_region ( ); } else if ( problem == 30 ) { value = p30_region ( ); } else if ( problem == 31 ) { value = p31_region ( ); } else if ( problem == 32 ) { value = p32_region ( ); } else { printf ( "\n" ); printf ( "p00_region(): Fatal error!\n" ); printf ( " Illegal problem number = %d\n", problem ); exit ( 1 ); } return value; } /******************************************************************************/ void p00_remap01 ( int problem, int dim_num, int point_num, double x01[], double xab[] ) /******************************************************************************/ /* Purpose: p00_remap01() remaps points in [0,1]^DIM_NUM into [A(1:DIM_NUM),B(1:DIM_NUM)]. Licensing: This code is distributed under the MIT license. Modified: 08 March 2007 Author: John Burkardt Input: int PROBLEM, the problem number. int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X01[DIM_NUM*N], the points, in [0,1], to be transformed. Output: double XAB[DIM_NUM*N], the transformed points. */ { double *a; double *b; int dim; int point; a = ( double * ) malloc ( dim_num * sizeof ( double ) ); b = ( double * ) malloc ( dim_num * sizeof ( double ) ); p00_lim ( problem, dim_num, a, b ); for ( dim = 0; dim < dim_num; dim++ ) { for ( point = 0; point < point_num; point++ ) { xab[dim+point*dim_num] = a[dim] + ( b[dim] - a[dim] ) * x01[dim+point*dim_num]; } } free ( a ); free ( b ); return; } /******************************************************************************/ void p00_title ( int problem ) /******************************************************************************/ /* Purpose: p00_title() prints a title for any problem. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int PROBLEM, the number of the desired test problem. */ { if ( problem == 1 ) { p01_title ( ); } else if ( problem == 2 ) { p02_title ( ); } else if ( problem == 3 ) { p03_title ( ); } else if ( problem == 4 ) { p04_title ( ); } else if ( problem == 5 ) { p05_title ( ); } else if ( problem == 6 ) { p06_title ( ); } else if ( problem == 7 ) { p07_title ( ); } else if ( problem == 8 ) { p08_title ( ); } else if ( problem == 9 ) { p09_title ( ); } else if ( problem == 10 ) { p10_title ( ); } else if ( problem == 11 ) { p11_title ( ); } else if ( problem == 12 ) { p12_title ( ); } else if ( problem == 13 ) { p13_title ( ); } else if ( problem == 14 ) { p14_title ( ); } else if ( problem == 15 ) { p15_title ( ); } else if ( problem == 16 ) { p16_title ( ); } else if ( problem == 17 ) { p17_title ( ); } else if ( problem == 18 ) { p18_title ( ); } else if ( problem == 19 ) { p19_title ( ); } else if ( problem == 20 ) { p20_title ( ); } else if ( problem == 21 ) { p21_title ( ); } else if ( problem == 22 ) { p22_title ( ); } else if ( problem == 23 ) { p23_title ( ); } else if ( problem == 24 ) { p24_title ( ); } else if ( problem == 25 ) { p25_title ( ); } else if ( problem == 26 ) { p26_title ( ); } else if ( problem == 27 ) { p27_title ( ); } else if ( problem == 28 ) { p28_title ( ); } else if ( problem == 29 ) { p29_title ( ); } else if ( problem == 30 ) { p30_title ( ); } else if ( problem == 31 ) { p31_title ( ); } else if ( problem == 32 ) { p32_title ( ); } else { printf ( "\n" ); printf ( "p00_title(): Fatal error!\n" ); printf ( " Illegal problem number = %d\n", problem ); exit ( 1 ); } return; } /******************************************************************************/ double p00_volume ( int problem, int dim_num ) /******************************************************************************/ /* Purpose: p00_volume() returns the volume of the integration region. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int PROBLEM, the number of the desired test problem. int DIM_NUM, the dimension of the problem. Output: double P00_VOLUME, the volume of the integration region. */ { double *a; double *b; int dim; double r; double volume; if ( 1 <= problem && problem <= 20 ) { a = ( double * ) malloc ( dim_num * sizeof ( double ) ); b = ( double * ) malloc ( dim_num * sizeof ( double ) ); p00_lim ( problem, dim_num, a, b ); volume = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { volume = volume * ( b[dim] - a[dim] ); } free ( a ); free ( b ); } else if ( problem == 21 ) { volume = sphere_unit_area_nd ( dim_num ); } else if ( problem == 22 ) { p22_r8 ( 'G', 'R', &r ); volume = sphere_volume_nd ( dim_num, r ); } else if ( problem == 23 ) { volume = simplex_unit_volume_nd ( dim_num ); } else if ( 24 <= problem && problem <= 32 ) { a = ( double * ) malloc ( dim_num * sizeof ( double ) ); b = ( double * ) malloc ( dim_num * sizeof ( double ) ); p00_lim ( problem, dim_num, a, b ); volume = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { volume = volume * ( b[dim] - a[dim] ); } free ( a ); free ( b ); } else { printf ( "\n" ); printf ( "p00_volume(): Fatal error!\n" ); printf ( " Illegal value of PROBLEM.\n" ); exit ( 1 ); } return volume; } /******************************************************************************/ void p01_default ( int dim_num ) /******************************************************************************/ /* Purpose: p01_default() sets default values for problem 01. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p01_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p01_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p01_exact() returns the exact integral for problem 01. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double p01_exact, the exact value of the integral. */ { double exact; exact = ( double ) ( ( dim_num ) * ( 3 * dim_num + 1 ) ) / 12.0; return exact; } /******************************************************************************/ double *p01_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p01_f evaluates the integrand for problem 01. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: f(x) = ( sum ( x(1:dim_num) ) )**2 Exact Integral: dim_num * ( 3 * dim_num + 1 ) / 12 Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double p01_f[POINT_NUM], the integrand values. */ { int dim; int inc; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] + x[dim+point*dim_num]; } value[point] = pow ( value[point], 2 ); } inc = point_num; p01_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p01_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p01_i4 sets or gets I4 parameter values for problem 01. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parameter to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p01_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p01_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p01_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p01_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p01_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p01_lim returns the integration limits for problem 01. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p01_name ( ) /******************************************************************************/ /* Purpose: p01_name() returns the name of problem 01. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p01_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 10 * sizeof ( char ) ); strcpy ( name, "SquareSum" ); return name; } /******************************************************************************/ char *p01_region ( ) /******************************************************************************/ /* Purpose: p01_region() returns the name of the integration region for problem 01. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p01_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p01_title ( ) /******************************************************************************/ /* Purpose: p01_title prints a title for problem 01. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 01\n" ); printf ( " Name: SquareSum\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = ( sum ( X(i) ) )^2\n" ); return; } /******************************************************************************/ void p02_default ( int dim_num ) /******************************************************************************/ /* Purpose: p02_default() sets default values for problem 02. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p02_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p02_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p02_exact() returns the exact integral for problem 02. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P02_exact, the exact value of the integral. */ { double exact; exact = ( double ) ( dim_num * ( 5 * dim_num - 2 ) ) / 15.0; return exact; } /******************************************************************************/ double *p02_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p02_f evaluates the integrand for problem 02. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: ( sum ( 2 * x(1:dim_num) - 1 ) )**4 Exact Integral: DIM_NUM * (5*DIM_NUM-2) / 15 Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Philip Davis, Philip Rabinowitz, Methods of Numerical Integration, Second Edition, Dover, 2007, ISBN: 0486453391, LC: QA299.3.D28. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P02_f[POINT_NUM], the integrand values. */ { int dim; int inc; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] + ( 2.0 * x[dim+point*dim_num] - 1.0 ); } value[point] = pow ( value[point], 4 ); } inc = point_num; p02_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p02_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p02_i4 sets or gets I4 parameter values for problem 02. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p02_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p02_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p02_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p02_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p02_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p02_lim returns the integration limits for problem 02. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p02_name ( ) /******************************************************************************/ /* Purpose: p02_name() returns the name of problem 02. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p02_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 8 * sizeof ( char ) ); strcpy ( name, "QuadSum" ); return name; } /******************************************************************************/ char *p02_region ( ) /******************************************************************************/ /* Purpose: p02_region() returns the name of the integration region for problem 02. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p02_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p02_title ( ) /******************************************************************************/ /* Purpose: p02_title prints a title for problem 02. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 02\n" ); printf ( " Name: QuadSum\n" ); printf ( " Davis, Rabinowitz, page 370, #1.\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = ( sum ( 2 * X(i) - 1 ) )^4\n" ); return; } /******************************************************************************/ void p03_default ( int dim_num ) /******************************************************************************/ /* Purpose: p03_default() sets default values for problem 03. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p03_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p03_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p03_exact() returns the exact integral for problem 03. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P03_exact, the exact value of the integral. */ { double exact; exact = 0.0; return exact; } /******************************************************************************/ double *p03_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p03_f evaluates the integrand for problem 03. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: ( sum ( 2 * x(1:dim_num) - 1 ) )**5 Exact Integral: 0 Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Philip Davis, Philip Rabinowitz, Methods of Numerical Integration, Second Edition, Dover, 2007, ISBN: 0486453391, LC: QA299.3.D28. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P03_f[POINT_NUM], the integrand values. */ { int dim; int inc; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] + ( 2.0 * x[dim+point*dim_num] - 1.0 ); } value[point] = pow ( value[point], 5 ); } inc = point_num; p03_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p03_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p03_i4 sets or gets I4 parameter values for problem 03. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p03_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p03_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p03_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p03_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p03_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p03_lim returns the integration limits for problem 03. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p03_name ( ) /******************************************************************************/ /* Purpose: p03_name() returns the name of problem 03. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p03_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 9 * sizeof ( char ) ); strcpy ( name, "QuintSum" ); return name; } /******************************************************************************/ char *p03_region ( ) /******************************************************************************/ /* Purpose: p03_region() returns the name of the integration region for problem 03. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p03_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p03_title ( ) /******************************************************************************/ /* Purpose: p03_title prints a title for problem 03. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 03\n" ); printf ( " Name: QuintSum\n" ); printf ( " Davis, Rabinowitz, page 370, #3.\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = ( sum ( X(i) ) )^5\n" ); return; } /******************************************************************************/ void p04_default ( int dim_num ) /******************************************************************************/ /* Purpose: p04_default() sets default values for problem 04. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p04_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p04_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p04_exact() returns the exact integral for problem 04. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P04_exact, the exact value of the integral. */ { double exact; exact = ( double ) ( dim_num * ( 7 * ( dim_num - 1 ) * ( 5 * dim_num - 1 ) + 9 ) ) / 63.0; return exact; } /******************************************************************************/ double *p04_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p04_f evaluates the integrand for problem 04. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: ( sum ( 2 * x(1:dim_num) - 1 ) )**6 Exact Integral: DIM_NUM * ( 7 * (DIM_NUM-1) * (5*DIM_NUM-1) + 9 ) / 63 Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Philip Davis, Philip Rabinowitz, Methods of Numerical Integration, Second Edition, Dover, 2007, ISBN: 0486453391, LC: QA299.3.D28. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P04_f[POINT_NUM], the integrand values. */ { int dim; int inc; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] + ( 2.0 * x[dim+point*dim_num] - 1.0 ); } value[point] = pow ( value[point], 6 ); } inc = point_num; p04_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p04_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p04_i4 sets or gets I4 parameter values for problem 04. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p04_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p04_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p04_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p04_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p04_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p04_lim returns the integration limits for problem 04. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int N, the dimension of the argument. Output: double A(DIM_NUM),B(DIM_NUM), the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p04_name ( ) /******************************************************************************/ /* Purpose: p04_name() returns the name of problem 04. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p04_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 7 * sizeof ( char ) ); strcpy ( name, "HexSum" ); return name; } /******************************************************************************/ char *p04_region ( ) /******************************************************************************/ /* Purpose: p04_region() returns the name of the integration region for problem 04. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p04_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p04_title ( ) /******************************************************************************/ /* Purpose: p04_title prints a title for problem 04. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 04\n" ); printf ( " Name: HexSum\n" ); printf ( " Davis, Rabinowitz, page 370, #2.\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = ( sum ( 2 * X(i) - 1 ) )^6\n" ); return; } /******************************************************************************/ void p05_default ( int dim_num ) /******************************************************************************/ /* Purpose: p05_default() sets default values for problem 05. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p05_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p05_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p05_exact() returns the exact integral for problem 05. Discussion: The exact value is given only for DIM_NUM = 1, 2, 3, 4 and 5. For all other dimensions, the value HUGE_VAL is returned. Licensing: This code is distributed under the MIT license. Modified: 12 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P05_exact, the exact value of the integral. */ { double exact; if ( dim_num == 1 ) { exact = log ( 3.0 ); } else if ( dim_num == 2 ) { exact = 5.0 * log ( 5.0 ) - 6.0 * log ( 3.0 ); } else if ( dim_num == 3 ) { exact = 0.5 * ( 49.0 * log ( 7.0 ) - 75.0 * log ( 5.0 ) + 27.0 * log ( 3.0 ) ); } else if ( dim_num == 4 ) { exact = 225.0 * log ( 3.0 ) + 125.0 * log ( 5.0 ) - 686.0 * log ( 7.0 ) / 3.0; } else if ( dim_num == 5 ) { exact = ( - 65205.0 * log ( 3.0 ) - 6250.0 * log ( 5.0 ) + 24010.0 * log ( 7.0 ) + 14641.0 * log ( 11.0 ) ) / 24.0; } else { exact = HUGE_VAL; } return exact; } /******************************************************************************/ double *p05_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p05_f evaluates the integrand for problem 05. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: 2**DIM_NUM / ( 1 + sum ( 2 * x(1:dim_num) ) ) Exact Integral: For DIM_NUM = 1: ln ( 3 ) For DIM_NUM = 2: ln ( 3125 / 729 ) For DIM_NUM = 3: 0.5 * ( 49 * ln ( 7 ) - 75 * ln ( 5 ) + 27 * ln ( 3 ) ) For DIM_NUM = 4: 225 * ln ( 3 ) + 125 * ln ( 5 ) - 686 * ln ( 7 ) / 3 For DIM_NUM = 5: ( -65205 * ln ( 3 ) - 6250 * ln ( 5 ) + 24010 * ln ( 7 ) + 14641 * ln ( 11 ) ) / 24 Approximate Integral: DIM_NUM VALUE 1 1.098612289 2 1.455514830 3 2.152142833 4 3.402716587 5 5.620255523 Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Arthur Stroud, Approximate Calculation of Multiple Integrals, Prentice Hall, 1971, ISBN: 0130438936, LC: QA311.S85. Arthur Stroud, Don Secrest, Gaussian Quadrature Formulas, Prentice Hall, 1966, LC: QA299.4G3S7. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P05_f[POINT_NUM], the integrand values. */ { double denom; int dim; int inc; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { denom = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { denom = denom + 2.0 * x[dim+point*dim_num]; } value[point] = pow ( 2.0, dim_num ) / denom; } inc = point_num; p05_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p05_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p05_i4 sets or gets I4 parameter values for problem 05. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p05_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p05_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p05_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p05_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p05_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p05_lim returns the integration limits for problem 05. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p05_name ( ) /******************************************************************************/ /* Purpose: p05_name() returns the name of problem 05. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p05_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 5 * sizeof ( char ) ); strcpy ( name, "ST04" ); return name; } /******************************************************************************/ char *p05_region ( ) /******************************************************************************/ /* Purpose: p05_region() returns the name of the integration region for problem 05. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p05_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p05_title ( ) /******************************************************************************/ /* Purpose: p05_title prints a title for problem 05. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 05\n" ); printf ( " Name: ST04\n" ); printf ( " Stroud #4, page 26.\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = 1 / ( 1 + sum ( 2 * X(i) ) )\n" ); return; } /******************************************************************************/ void p06_default ( int dim_num ) /******************************************************************************/ /* Purpose: p06_default() sets default values for problem 06. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p06_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p06_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p06_exact() returns the exact integral for problem 06. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P06_exact, the exact value of the integral. */ { double exact; exact = 1.0; return exact; } /******************************************************************************/ double *p06_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p06_f evaluates the integrand for problem 06. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: product ( 2 * abs ( 2 * x(1:dim_num) - 1 ) ) Exact Integral: 1 Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Paul Bratley, Bennett Fox, Harald Niederreiter, Implementation and Tests of Low-Discrepancy Sequences, ACM Transactions on Modeling and Computer Simulation, Volume 2, Number 3, pages 195-213, 1992. Philip Davis, Philip Rabinowitz, Methods of Numerical Integration, Second Edition, Dover, 2007, ISBN: 0486453391, LC: QA299.3.D28. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P06_f[POINT_NUM], the integrand values. */ { int dim; int inc; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] * 2.0 * fabs ( 2.0 * x[dim+point*dim_num] - 1.0 ); } } inc = point_num; p06_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p06_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p06_i4 sets or gets I4 parameter values for problem 06. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p06_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p06_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p06_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p06_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p06_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p06_lim returns the integration limits for problem 06. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p06_name ( ) /******************************************************************************/ /* Purpose: p06_name() returns the name of problem 06. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p06_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 7 * sizeof ( char ) ); strcpy ( name, "DR4061" ); return name; } /******************************************************************************/ char *p06_region ( ) /******************************************************************************/ /* Purpose: p06_region() returns the name of the integration region for problem 06. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p06_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p06_title ( ) /******************************************************************************/ /* Purpose: p06_title prints a title for problem 06. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 07\n" ); printf ( " Name: DR4061\n" ); printf ( " Davis, Rabinowitz, page 406, #1.\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = product ( abs ( 4 * X(i) - 2 ) )\n" ); return; } /******************************************************************************/ void p07_default ( int dim_num ) /******************************************************************************/ /* Purpose: p07_default() sets default values for problem 07. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p07_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p07_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p07_exact() returns the exact integral for problem 07. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P07_exact, the exact value of the integral. */ { double exact; exact = 1.0; return exact; } /******************************************************************************/ double *p07_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p07_f evaluates the integrand for problem 07. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: product ( pi / 2 ) * sin ( pi * x(1:dim_num) ) Exact Integral: 1 Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Philip Davis, Philip Rabinowitz, Methods of Numerical Integration, Second Edition, Dover, 2007, ISBN: 0486453391, LC: QA299.3.D28. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P07_f[POINT_NUM], the integrand values. */ { int dim; int inc; double pi = 3.141592653589793; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] * ( 0.5 * pi * sin ( pi * x[dim+point*dim_num] ) ); } } inc = point_num; p07_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p07_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p07_i4 sets or gets I4 parameter values for problem 07. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p07_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p07_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p07_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p07_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p07_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p07_lim returns the integration limits for problem 07. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p07_name ( ) /******************************************************************************/ /* Purpose: p07_name() returns the name of problem 07. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p07_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 7 * sizeof ( char ) ); strcpy ( name, "DR4062" ); return name; } /******************************************************************************/ char *p07_region ( ) /******************************************************************************/ /* Purpose: p07_region() returns the name of the integration region for problem 07. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p07_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p07_title ( ) /******************************************************************************/ /* Purpose: p07_title prints a title for problem 07. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 07\n" ); printf ( " Name: DR4062\n" ); printf ( " Davis, Rabinowitz, page 406, #2.\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = product ( pi * sin ( pi * X(i) ) / 2 )\n" ); return; } /******************************************************************************/ void p08_default ( int dim_num ) /******************************************************************************/ /* Purpose: p08_default() sets default values for problem 08. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p08_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p08_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p08_exact() returns the exact integral for problem 08. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P08_exact, the exact value of the integral. */ { double exact; double pi = 3.141592653589793; exact = 0.5 - sqrt ( pow ( 2.0, 3 * dim_num ) ) * cos ( 0.25 * pi * ( double ) ( dim_num ) ) / ( 2.0 * pow ( pi, dim_num ) ); return exact; } /******************************************************************************/ double *p08_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p08_f evaluates the integrand for problem 08. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: ( sin ( (pi/4) * sum ( x(1:dim_num) ) ) )**2 Exact Integral: 1/2 - sqrt ( 2**(3*DIM_NUM) ) * cos ( DIM_NUM * pi / 4 ) ) / ( 2 * pi**DIM_NUM ) Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Richard Crandall, Projects in Scientific Computing, Springer, 2000, ISBN: 0387950095, LC: Q183.9.C733. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P08_f[POINT_NUM], the integrand values. */ { int inc; double pi = 3.141592653589793; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = pow ( sin ( pi * r8vec_sum ( dim_num, x+point*dim_num ) / 4.0 ), 2 ); } inc = point_num; p08_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p08_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p08_i4 sets or gets I4 parameter values for problem 08. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p08_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p08_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p08_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p08_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p08_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p08_lim returns the integration limits for problem 08. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p08_name ( ) /******************************************************************************/ /* Purpose: p08_name() returns the name of problem 08. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p08_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 5 * sizeof ( char ) ); strcpy ( name, "RC01" ); return name; } /******************************************************************************/ char *p08_region ( ) /******************************************************************************/ /* Purpose: p08_region() returns the name of the integration region for problem 08. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p08_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p08_title ( ) /******************************************************************************/ /* Purpose: p08_title prints a title for problem 08. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 08\n" ); printf ( " Name: RC01\n" ); printf ( " Crandall, page 49, #1\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = sin^2 ( pi/4 * sum ( X(i) ) )\n" ); return; } /******************************************************************************/ void p09_default ( int dim_num ) /******************************************************************************/ /* Purpose: p09_default() sets default values for problem 09. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p09_i4 ( 'D', '*', &i4 ); p09_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p09_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p09_exact() returns the exact integral for problem 09. Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P09_exact, the exact value of the integral. */ { double *c; int dim; double exact; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p09_r8vec ( 'G', 'C', dim_num, c ); exact = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { exact = exact * ( ( exp ( c[dim] ) - 1.0 ) / c[dim] ); } free ( c ); return exact; } /******************************************************************************/ double *p09_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p09_f evaluates the integrand for problem 09. Discussion: Thanks to Jeffrey Sax of Extreme Optimization for pointing out a mistake in a previous version of this function, 28 May 2008. The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter Values: The integral depends on a parameter vector C(1:N). The reference suggests choosing C at random in [0,1] and then multiplying by the normalizing factor (60/N). To get or set C, call P09_r8VEC. The default value of C(1:N) is 1/N. Integrand: exp ( sum ( c(1:dim_num) * x(1:dim_num) ) ) Exact Integral: product ( ( exp ( c(1:n) - 1 ) / c(1:n) ) Licensing: This code is distributed under the MIT license. Modified: 28 May 2008 Author: John Burkardt Reference: [Integral #7] Thomas Patterson, On the Construction of a Practical Ermakov-Zolotukhin Multiple Integrator, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D. Reidel, 1987, pages 269-290. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P09_f[POINT_NUM], the integrand values. */ { double *c; int inc; int point; double *value; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p09_r8vec ( 'G', 'C', dim_num, c ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = exp ( r8vec_dot ( dim_num, c, x+point*dim_num ) ); } inc = point_num; p09_i4 ( 'I', '#', &inc ); free ( c ); return value; } /******************************************************************************/ void p09_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p09_i4 sets or gets I4 parameter values for problem 09. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p09_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p09_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p09_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p09_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p09_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p09_lim returns the integration limits for problem 09. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p09_name ( ) /******************************************************************************/ /* Purpose: p09_name() returns the name of problem 09. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p09_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 13 * sizeof ( char ) ); strcpy ( name, "Patterson #7" ); return name; } /******************************************************************************/ void p09_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p09_r8vec() sets or gets R8VEC parameters for problem 09. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'C' is the coefficient vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { static double *c = NULL; int dim; static int dim_num_save = 0; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( c ) { free ( c ); c = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = 1.0 / ( double ) ( dim_num ); } } } else if ( action == 'G' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, c, value ); } else { printf ( "\n" ); printf ( "p09_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = ( double ) rand ( ) * 60.0 / ( double ) RAND_MAX / ( double ) ( dim_num ); } r8vec_copy ( dim_num, c, value ); } else { printf ( "\n" ); printf ( "p09_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, value, c ); } else { printf ( "\n" ); printf ( "p09_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p09_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p09_region ( ) /******************************************************************************/ /* Purpose: p09_region() returns the name of the integration region for problem 09. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p09_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p09_title ( ) /******************************************************************************/ /* Purpose: p09_title prints a title for problem 09. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 09\n" ); printf ( " Name: Patterson #7\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = exp ( sum ( C(i) * X(i) ) )\n" ); printf ( " Parameter:\n" ); printf ( " C(1:DIM_NUM) defaults to 1/DIM_NUM.\n" ); return; } /******************************************************************************/ void p10_default ( int dim_num ) /******************************************************************************/ /* Purpose: p10_default() sets default values for problem 10. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p10_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p10_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p10_exact() returns the exact integral for problem 10. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P10_exact, the exact value of the integral. */ { double exact; exact = ( double ) ( dim_num ) / 4.0; return exact; } /******************************************************************************/ double *p10_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p10_f evaluates the integrand for problem 10. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: sum ( abs ( x(1:dim_num) - 0.5 ) ) Exact Integral: DIM_NUM / 4 Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Philip Davis, Philip Rabinowitz, Methods of Numerical Integration, Second Edition, Dover, 2007, ISBN: 0486453391, LC: QA299.3.D28. [Integral #4], Thomas Patterson, On the Construction of a Practical Ermakov-Zolotukhin Multiple Integrator, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast, Graeme Fairweather, D. Reidel, 1987, pages 269-290. Arthur Stroud, Approximate Calculation of Multiple Integrals, Prentice Hall, 1971, ISBN: 0130438936, LC: QA311.S85. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P10_f[POINT_NUM], the integrand values. */ { int dim; int inc; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] + fabs ( x[dim+point*dim_num] - 0.5 ); } } inc = point_num; p10_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p10_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p10_i4 sets or gets I4 parameter values for problem 10. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p10_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p10_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p10_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p10_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p10_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p10_lim returns the integration limits for problem 10. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p10_name ( ) /******************************************************************************/ /* Purpose: p10_name() returns the name of problem 10. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p10_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 13 * sizeof ( char ) ); strcpy ( name, "Patterson #4" ); return name; } /******************************************************************************/ char *p10_region ( ) /******************************************************************************/ /* Purpose: p10_region() returns the name of the integration region for problem 10. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p10_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p10_title ( ) /******************************************************************************/ /* Purpose: p10_title prints a title for problem 10. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 10\n" ); printf ( " Name: Patterson #4\n" ); printf ( " Stroud, page ?\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = sum ( abs ( X(i) - 0.5 ) )\n" ); return; } /******************************************************************************/ void p11_default ( int dim_num ) /******************************************************************************/ /* Purpose: p11_default() sets default values for problem 11. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p11_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p11_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p11_exact() returns the exact integral for problem 11. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P11_exact, the exact value of the integral. */ { double exact; exact = pow ( exp ( 1.0 ) - 1.0, dim_num ); return exact; } /******************************************************************************/ double *p11_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p11_f evaluates the integrand for problem 11. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: exp ( sum ( abs ( 2 * X(1:DIM_NUM) - 1 ) ) ) Exact Integral: ( E - 1.0 )**DIM_NUM Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: [Integral #2], Thomas Patterson, On the Construction of a Practical Ermakov-Zolotukhin Multiple Integrator, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D. Reidel, 1987, pages 269-290. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P11_f[POINT_NUM], the integrand values. */ { int dim; int inc; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] + fabs ( 2.0 * x[dim+point*dim_num] - 1.0 ); } value[point] = exp ( value[point] ); } inc = point_num; p11_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p11_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p11_i4 sets or gets I4 parameter values for problem 11. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p11_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p11_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p11_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p11_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p11_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p11_lim returns the integration limits for problem 11. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p11_name ( ) /******************************************************************************/ /* Purpose: p11_name() returns the name of problem 11. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p11_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 31 * sizeof ( char ) ); strcpy ( name, "Patterson #2, exp(sum(abs(X)))" ); return name; } /******************************************************************************/ char *p11_region ( ) /******************************************************************************/ /* Purpose: p11_region() returns the name of the integration region for problem 11. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p11_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p11_title ( ) /******************************************************************************/ /* Purpose: p11_title prints a title for problem 11. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 11\n" ); printf ( " Name: Patterson #2, exp(sum(abs(X)))\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = exp ( sum ( abs ( X(i) )))\n" ); return; } /******************************************************************************/ void p12_default ( int dim_num ) /******************************************************************************/ /* Purpose: p12_default() sets default values for problem 12. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p12_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p12_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p12_exact() returns the exact integral for problem 12. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P12_exact, the exact value of the integral. */ { double exact; int i; exact = 1.0; for ( i = 1; i <= dim_num; i++ ) { exact = exact * sin ( ( double ) ( i ) ); } return exact; } /******************************************************************************/ double *p12_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p12_f evaluates the integrand for problem 12. Discussion: The highly oscillatory nature of the integrand makes this a difficult and perhaps even dubious test. The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: product ( 1 <= i <= dim_num ) ( i * cos ( i * x(i) ) ) Exact Integral: product ( 1 <= I <= DIM_NUM ) sin ( i ) Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Paul Bratley, Bennett Fox, Harald Niederreiter, Implementation and Tests of Low-Discrepancy Sequences, ACM Transactions on Modeling and Computer Simulation, Volume 2, Number 3, July 1992, pages 195-213. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P12_f[POINT_NUM], the integrand values. */ { int dim; int inc; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] * ( double ) ( dim + 1 ) * cos ( ( double ) ( dim + 1 ) * x[dim+point*dim_num] ); } } inc = point_num; p12_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p12_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p12_i4 sets or gets I4 parameter values for problem 12. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p12_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p12_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p12_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p12_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p12_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p12_lim returns the integration limits for problem 12. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p12_name ( ) /******************************************************************************/ /* Purpose: p12_name() returns the name of problem 12. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p12_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 6 * sizeof ( char ) ); strcpy ( name, "BFN02" ); return name; } /******************************************************************************/ char *p12_region ( ) /******************************************************************************/ /* Purpose: p12_region() returns the name of the integration region for problem 12. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p12_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p12_title ( ) /******************************************************************************/ /* Purpose: p12_title prints a title for problem 12. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 12\n" ); printf ( " Name: BFN02\n" ); printf ( " Bratley, Fox, Niederreiter, #2\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = product ( i * cos ( X(i) ) )\n" ); return; } /******************************************************************************/ void p13_default ( int dim_num ) /******************************************************************************/ /* Purpose: p13_default() sets default values for problem 13. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p13_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p13_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p13_exact() returns the exact integral for problem 13. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P13_exact, the exact value of the integral. */ { double exact; exact = 0.0; return exact; } /******************************************************************************/ double *p13_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p13_f evaluates the integrand for problem 13. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: product ( 1 <= i <= dim_num ) t(n(i))(2*x(i)-1) where T(N)(X) is the Chebyshev polynomial of order N, and N(I) = mod ( i, 4 ) + 1. Exact Integral: 0 Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Paul Bratley, Bennett Fox, Harald Niederreiter, Implementation and Tests of Low-Discrepancy Sequences, ACM Transactions on Modeling and Computer Simulation, Volume 2, Number 3, July 1992, pages 195-213. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P13_f[POINT_NUM], the integrand values. */ { int dim; double factor; int inc; int k; int point; double t; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { t = 2.0 * x[dim+point*dim_num] - 1.0; k = ( dim + 1 ) % 4; if ( k == 1 ) { factor = t; } else if ( k == 2 ) { factor = 2.0 * t - 1.0; } else if ( k == 3 ) { factor = ( 4.0 * t - 3.0 ) * t; } else if ( k == 4 ) { factor = ( 8.0 * t - 8.0 * t + 1.0 ); } value[point] = value[point] * factor; } } inc = point_num; p13_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p13_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p13_i4 sets or gets I4 parameter values for problem 13. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p13_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p13_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p13_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p13_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p13_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p13_lim returns the integration limits for problem 13. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p13_name ( ) /******************************************************************************/ /* Purpose: p13_name() returns the name of problem 13. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p13_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 6 * sizeof ( char ) ); strcpy ( name, "BFN03" ); return name; } /******************************************************************************/ char *p13_region ( ) /******************************************************************************/ /* Purpose: p13_region() returns the name of the integration region for problem 13. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p13_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p13_title ( ) /******************************************************************************/ /* Purpose: p13_title prints a title for problem 13. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 13\n" ); printf ( " Name: BFN03\n" ); printf ( " Bratley, Fox, Niederreiter, #3\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = product ( low order Chebyshevs )\n" ); return; } /******************************************************************************/ void p14_default ( int dim_num ) /******************************************************************************/ /* Purpose: p14_default() sets default values for problem 14. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p14_i4 ( 'D', '*', &i4 ); return; } /******************************************************************************/ double p14_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p14_exact() returns the exact integral for problem 14. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P14_exact, the exact value of the integral. */ { double exact; exact = ( - 1.0 / 3.0 ) * ( 1.0 - pow ( -1.0 / 2.0, dim_num ) ); return exact; } /******************************************************************************/ double *p14_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p14_f evaluates the integrand for problem 14. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: sum ( 1 <= i <= dim_num ) (-1)**i * product ( 1 <= j <= i ) x(j) Exact Integral: -1/3 ( 1 - (-1/2)**DIM_NUM ) Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Paul Bratley, Bennett Fox, Harald Niederreiter, Implementation and Tests of Low-Discrepancy Sequences, ACM Transactions on Modeling and Computer Simulation, Volume 2, Number 3, July 1992, pages 195-213. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P14_f[POINT_NUM], the integrand values. */ { int dim; double factor; int inc; int point; double *value; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 0.0; factor = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { factor = - factor * x[dim+point*dim_num]; value[point] = value[point] + factor; } } inc = point_num; p14_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p14_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p14_i4 sets or gets I4 parameter values for problem 14. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p14_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p14_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p14_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p14_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p14_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p14_lim returns the integration limits for problem 14. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p14_name ( ) /******************************************************************************/ /* Purpose: p14_name() returns the name of problem 14. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p14_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 6 * sizeof ( char ) ); strcpy ( name, "BFN04" ); return name; } /******************************************************************************/ char *p14_region ( ) /******************************************************************************/ /* Purpose: p14_region() returns the name of the integration region for problem 14. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p14_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p14_title ( ) /******************************************************************************/ /* Purpose: p14_title prints a title for problem 14. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 14\n" ); printf ( " Name: BFN04\n" ); printf ( " Bratley, Fox, Niederreiter, #4\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = sum ( -1^I * product(X(1:I)) )\n" ); return; } /******************************************************************************/ void p15_default ( int dim_num ) /******************************************************************************/ /* Purpose: p15_default() sets default values for problem 15. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; int n; p15_i4 ( 'D', '*', &i4 ); n = ( 3 * dim_num ) / 2; p15_i4 ( 'S', 'N', &n ); return; } /******************************************************************************/ double p15_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p15_exact() returns the exact integral for problem 15. Discussion: Thanks to Jeffrey Sax of Extreme Optimiziation for suggesting a revision of this routine to improve its clarity, 12 August 2008. Licensing: This code is distributed under the MIT license. Modified: 12 August 2008 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P15_exact, the exact value of the integral. */ { int dim; double exact; int fraction; int n; int remainder; p15_i4 ( 'G', 'N', &n ); fraction = n / dim_num; remainder = n - fraction * dim_num; exact = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { if ( dim < remainder ) { exact = exact / ( double ) ( fraction + 2 ); } else { exact = exact / ( double ) ( fraction + 1 ); } } return exact; } /******************************************************************************/ double *p15_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p15_f evaluates the integrand for problem 15. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter values: N determines the order of the product. It defaults to 1. You can modify N by calling P15_i4. Integrand: f(x) = product ( 1 <= I <= N ) X(MOD(I-1,DIM_NUM)+1) Exact integral: product ( 1 / exponent(1:DIM_NUM) ) where, if I <= N - DIM_NUM * ( N/DIM_NUM), exponent ( I ) = ( N / dim_num ) + 2 else exponent ( I ) = ( N / dim_num ) + 1 Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P15_f[POINT_NUM], the integrand values. */ { bool any_zero; int dim; int fraction; int inc; int n; int point; int remainder; double *value; p15_i4 ( 'G', 'N', &n ); fraction = n / dim_num; remainder = n - fraction * dim_num; value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { any_zero = false; for ( dim = 0; dim < dim_num; dim++ ) { if ( x[dim+point*dim_num] == 0.0 ) { any_zero = true; break; } } if ( any_zero ) { value[point] = 0.0; } else { value[point] = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { if ( dim <= remainder ) { value[point] = value[point] * pow ( x[dim+point*dim_num], fraction + 1 ); } else if ( fraction != 0 ) { value[point] = value[point] * pow ( x[dim+point*dim_num], fraction ); } } } } inc = point_num; p15_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p15_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p15_i4 sets or gets I4 parameter values for problem 15. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. 'N' is the number of factors to multiply in the integrand. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; static int n = 1; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } if ( name == 'N' || name == '*' ) { n = 1; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else if ( name == 'N' ) { *value = n; } else { printf ( "\n" ); printf ( "p15_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else if ( name == 'N' ) { n = n + *value; } else { printf ( "\n" ); printf ( "p15_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else if ( name == 'N' ) { n = *value; } else { printf ( "\n" ); printf ( "p15_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p15_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p15_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p15_lim returns the integration limits for problem 15. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p15_name ( ) /******************************************************************************/ /* Purpose: p15_name() returns the name of problem 15. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p15_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Partial product ( X(1:N) )" ); return name; } /******************************************************************************/ char *p15_region ( ) /******************************************************************************/ /* Purpose: p15_region() returns the name of the integration region for problem 15. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p15_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p15_title ( ) /******************************************************************************/ /* Purpose: p15_title prints a title for problem 15. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 15\n" ); printf ( " Name: Partial product ( X(1:N) )\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = product ( X(1:N) )\n" ); printf ( " Parameter:\n" ); printf ( " N, defaults to 1\n" ); return; } /******************************************************************************/ void p16_default ( int dim_num ) /******************************************************************************/ /* Purpose: p16_default() sets default values for problem 16. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p16_i4 ( 'D', '*', &i4 ); p16_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p16_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p16_exact() returns the exact integral for problem 16. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P16_exact, the exact value of the integral. */ { double *a; double *b; int dim; double exact; double integral; double volume; double *z; /* Get the limits of integration. */ a = ( double * ) malloc ( dim_num * sizeof ( double ) ); b = ( double * ) malloc ( dim_num * sizeof ( double ) ); p16_lim ( dim_num, a, b ); /* Get the location of Z. */ z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p16_r8vec ( 'G', 'Z', dim_num, z ); /* The value of the DIM_NUM dimensional integral can be broken down into the weighted sum of 1 dimensional integrals. */ exact = 0.0; volume = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { volume = volume * ( b[dim] - a[dim] ); } for ( dim = 0; dim < dim_num; dim++ ) { /* Z < A < B */ if ( z[dim] < a[dim] ) { integral = 0.5 * ( b[dim] - a[dim] ) * ( b[dim] + a[dim] - 2.0 * z[dim] ); } /* A < Z < B */ else if ( z[dim] < b[dim] ) { integral = 0.5 * ( pow ( b[dim] - z[dim], 2 ) + pow ( z[dim] - a[dim], 2 ) ); } /* A < B < Z */ else { integral = 0.5 * ( b[dim] - a[dim] ) * ( 2.0 * z[dim] - a[dim] - b[dim] ); } exact = exact + volume * integral / ( b[dim] - a[dim] ); } free ( a ); free ( b ); free ( z ); return exact; } /******************************************************************************/ double *p16_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p16_f evaluates the integrand for problem 16. Discussion: The integrand can be regarded as the L1 norm of X - Z. It would be nice to allow the use to specify several base points Z, to make the function more jagged more places. The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter: The integrand can be regarded as the L1 norm of X - Z. There is a basis point Z associated with the integrand. Z(1:DIM_NUM) defaults to ( 0.5, 0.5, ..., 0.5 ). The user can set, get, or randomize this value by calling p16_r8VEC. Integrand: sum ( abs ( x(1:dim_num) - z(1:dim_num) ) ) Exact Integral: The integral is separable into Int ( A(1) <= X(1) <= B(1) ) abs ( X(1) - Z(1) ) * Product ( B(1:N)-A(1:N), skip index 1 ) + Int ( A(2) <= X(2) <= B(2) ) abs ( X(2) - Z(2) ) * Product ( B(1:N)-A(1:N), skip index 2 ) ... + Int ( A(N) <= X(N) <= B(N) ) abs ( X(N) - Z(N) ) * Product ( B(1:N)-A(1:N), skip index N ) Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P16_f[POINT_NUM], the integrand values. */ { int dim; int inc; int point; double *value; double *z; z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p16_r8vec ( 'G', 'Z', dim_num, z ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] + fabs ( x[dim+point*dim_num] - z[dim] ); } } inc = point_num; p16_i4 ( 'I', '#', &inc ); free ( z ); return value; } /******************************************************************************/ void p16_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p16_i4 sets or gets I4 parameter values for problem 16. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p16_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p16_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\".\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p16_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p16_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p16_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p16_lim returns the integration limits for problem 16. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p16_name ( ) /******************************************************************************/ /* Purpose: p16_name() returns the name of problem 16. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p16_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "L1(X-Z)" ); return name; } /******************************************************************************/ void p16_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p16_r8VEC sets or gets R8VEC parameter values for problem 16. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'Z' is the base vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { int dim; static int dim_num_save = 0; static double *z = NULL; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( z ) { free ( z ); z = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; z = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'Z' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = 0.5; } } } else if ( action == 'G' ) { if ( name == 'Z' ) { r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p16_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'Z' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p16_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'Z' ) { r8vec_copy ( dim_num, value, z ); } else { printf ( "\n" ); printf ( "p16_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p16_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p16_region ( ) /******************************************************************************/ /* Purpose: p16_region() returns the name of the integration region for problem 16. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p16_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p16_title ( ) /******************************************************************************/ /* Purpose: p16_title prints a title for problem 16. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 16\n" ); printf ( " Name: L1(X-Z)\n" ); printf ( " Lipschitz continuous.\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = sum ( | X(i) - Z(i) | )\n" ); printf ( " Parameter:\n" ); printf ( " Z(1:DIM_NUM) defaults to (0.5,0.5,...)\n" ); return; } /******************************************************************************/ void p17_default ( int dim_num ) /******************************************************************************/ /* Purpose: p17_default() sets default values for problem 17. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p17_i4 ( 'D', '*', &i4 ); p17_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p17_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p17_exact() returns the exact integral for problem 17. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P17_exact, the exact value of the integral. */ { double *a; double *b; int dim; double exact; double integral; double volume; double *z; /* Get the limits of integration. */ a = ( double * ) malloc ( dim_num * sizeof ( double ) ); b = ( double * ) malloc ( dim_num * sizeof ( double ) ); p17_lim ( dim_num, a, b ); /* Get the location of Z. */ z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p17_r8vec ( 'G', 'Z', dim_num, z ); /* The value of the DIM_NUM dimensional integral can be broken into the weighted sum of integrals over each dimension. */ exact = 0.0; volume = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { volume = volume * ( b[dim] - a[dim] ); } for ( dim = 0; dim < dim_num; dim++ ) { /* Z < A < B */ if ( z[dim] < a[dim] ) { integral = ( pow ( b[dim] - z[dim], 3 ) - pow ( a[dim] - z[dim], 3 ) ) / 3.0; } /* A < Z < B */ else if ( z[dim] < b[dim] ) { integral = ( pow ( b[dim] - z[dim], 3 ) + pow ( z[dim] - a[dim], 3 ) ) / 3.0; } /* A < B < Z */ else { integral = ( pow ( z[dim] - b[dim], 3 ) - pow ( z[dim] - a[dim], 3 ) ) / 3.0; } exact = exact + volume * integral / ( b[dim] - a[dim] ); } free ( a ); free ( b ); free ( z ); return exact; } /******************************************************************************/ double *p17_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p17_f evaluates the integrand for problem 17. Discussion: This integrand can be regarded as the square of the L2 norm of X - Z. This integrand has the advantage of symmetry under rotation about Z. Thus, it is possible to test whether a particular quadrature rule has an occasional advantage because it "lines up" with the X and Y coordinate axes and hence can integrate some separable integrals very well. The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter: There is a basis point Z associated with the integrand. Z(1:DIM_NUM) defaults to ( 0.5, 0.5, ..., 0.5 ). The user can set, get, or randomize this value by calling p17_r8VEC. Integrand: sum ( ( x(1:dim_num) - z(1:dim_num) )**2 ) Exact Integral: The integral may be broken into the sum of weighted one dimensional integrals. Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P17_f[POINT_NUM], the integrand values. */ { int dim; int inc; int point; double *value; double *z; z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p17_r8vec ( 'G', 'Z', dim_num, z ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] + pow ( x[dim+point*dim_num] - z[dim], 2 ); } } inc = point_num; p17_i4 ( 'I', '#', &inc ); free ( z ); return value; } /******************************************************************************/ void p17_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p17_i4 sets or gets I4 parameter values for problem 17. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p17_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p17_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p17_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p17_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p17_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p17_lim returns the integration limits for problem 17. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p17_name ( ) /******************************************************************************/ /* Purpose: p17_name() returns the name of problem 17. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p17_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "L2(X-Z)^2" ); return name; } /******************************************************************************/ void p17_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p17_r8VEC sets or gets R8VEC parameter values for problem 17. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'Z' is the base vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { int dim; static int dim_num_save = 0; static double *z = NULL; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( z ) { free ( z ); z = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; z = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'Z' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = 0.5; } } } else if ( action == 'G' ) { if ( name == 'Z' ) { r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p17_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'Z' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p17_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'Z' ) { r8vec_copy ( dim_num, value, z ); } else { printf ( "\n" ); printf ( "p17_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p17_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p17_region ( ) /******************************************************************************/ /* Purpose: p17_region() returns the name of the integration region for problem 17. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p17_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p17_title ( ) /******************************************************************************/ /* Purpose: p17_title prints a title for problem 17. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 17\n" ); printf ( " Name: L2(X-Z)^2\n" ); printf ( " Zero at point Z.\n" ); printf ( " Radially symmetric.\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = sum ( ( X(i) - Z(i) )^2 )\n" ); printf ( " Parameter:\n" ); printf ( " Z(1:DIM_NUM) defaults to (0.5,0.5,...)\n" ); return; } /******************************************************************************/ void p18_default ( int dim_num ) /******************************************************************************/ /* Purpose: p18_default() sets default values for problem 18. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; double r8; p18_i4 ( 'D', '*', &i4 ); p18_r8 ( 'D', '*', &r8 ); p18_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p18_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p18_exact() returns the exact integral for problem 18. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P18_exact, the exact value of the integral. */ { double exact; double r; p18_r8 ( 'G', 'R', &r ); exact = sphere_volume_nd ( dim_num, r ); return exact; } /******************************************************************************/ double *p18_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p18_f evaluates the integrand for problem 18. Discussion: This is the characteristic function of the interior of the N sphere of radius R and center Z, to be integrated within the unit hypercube [0,1]^N. If the user picks a combination of R and Z that causes the volume of the sphere to lie at least partially outside the unit hypercube, the formula for the exact integral will no longer be correct. The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter: R defaults to 0.50. You can change R by calling P18_r8. Z(1:DIM_NUM) defaults to (0.5,0.5,...0.5). You can change Z by calling P18_r8VEC. Integrand: f(x) = 1 if X(1:DIM_NUM) is less than R from Z(1:DIM_NUM), 0 otherwise. Exact Integral: The volume of the DIM_NUM sphere of radius R. Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P18_f[POINT_NUM], the integrand values. */ { double d; int dim; int inc; int point; double r; double *value; double *z; z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p18_r8vec ( 'G', 'Z', dim_num, z ); p18_r8 ( 'G', 'R', &r ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { d = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { d = d + pow ( x[dim+point*dim_num] - z[dim], 2 ); } d = sqrt ( d ); if ( d <= r ) { value[point] = 1.0; } else { value[point] = 0.0; } } inc = point_num; p18_i4 ( 'I', '#', &inc ); free ( z ); return value; } /******************************************************************************/ void p18_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p18_i4 sets or gets I4 parameter values for problem 18. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p18_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p18_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p18_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p18_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p18_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p18_lim returns the integration limits for problem 18. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p18_name ( ) /******************************************************************************/ /* Purpose: p18_name() returns the name of problem 18. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p18_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Disk" ); return name; } /******************************************************************************/ void p18_r8 ( char action, char name, double *value ) /******************************************************************************/ /* Purpose: p18_r8 sets or gets R8 parameter values for problem 18. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' sets the parameter to its default value; 'G' gets a parameter. 'R' sets the parameter to a random value. 'S' sets a parameter to VALUE, char name, the name of the variable. 'R' is the radius. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static double r = 0.50; if ( action == 'D' ) { if ( name == 'R' || name == '*' ) { r = 0.50; *value = r; } } else if ( action == 'G' ) { if ( name == 'R' ) { *value = r; } else { printf ( "\n" ); printf ( "p18_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'R' ) { r = ( double ) rand ( ) / ( double ) RAND_MAX; *value = r; } else { printf ( "\n" ); printf ( "p18_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'R' ) { r = *value; } else { printf ( "\n" ); printf ( "p18_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p18_r8(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p18_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p18_r8VEC sets or gets R8VEC parameter values for problem 18. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'Z' is the base vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { int dim; static int dim_num_save = 0; static double *z = NULL; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( z ) { free ( z ); z = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; z = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'Z' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = 0.5; } } } else if ( action == 'G' ) { if ( name == 'Z' ) { r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p18_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'Z' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p18_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'Z' ) { r8vec_copy ( dim_num, value, z ); } else { printf ( "\n" ); printf ( "p18_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p18_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p18_region ( ) /******************************************************************************/ /* Purpose: p18_region() returns the name of the integration region for problem 18. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p18_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p18_title ( ) /******************************************************************************/ /* Purpose: p18_title prints a title for problem 18. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 18\n" ); printf ( " Name: Disk\n" ); printf ( " Disk of radius R centered at Z.\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = sphere interior characteristic\n" ); printf ( " Parameter:\n" ); printf ( " R, defaults to 0.5\n" ); printf ( " Z(1:DIM_NUM) defaults to (0.5,0.5,...0.5)\n" ); return; } /******************************************************************************/ void p19_default ( int dim_num ) /******************************************************************************/ /* Purpose: p19_default() sets default values for problem 19. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p19_i4 ( 'D', '*', &i4 ); p19_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p19_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p19_exact() returns the exact integral for problem 19. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double EXACT, the exact value of the integral. */ { int dim; double exact; double *z; z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p19_r8vec ( 'G', 'Z', dim_num, z ); exact = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { if ( z[dim] <= 0.0 ) { exact = exact * ( 2.0 / 3.0 ) * ( sqrt ( pow ( 1.0 - z[dim], 3 ) ) - sqrt ( - pow ( z[dim], 3 ) ) ); } else if ( z[dim] < 1.0 ) { exact = exact * ( 2.0 / 3.0 ) * ( sqrt ( pow ( z[dim], 3 ) ) + sqrt ( pow ( 1.0 - z[dim], 3 ) ) ); } else if ( 1.0 <= z[dim] ) { exact = exact * ( 2.0 / 3.0 ) * ( sqrt ( pow ( z[dim], 3 ) ) - sqrt ( pow ( z[dim] - 1.0, 3 ) ) ); } } free ( z ); return exact; } /******************************************************************************/ double *p19_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p19_f evaluates the integrand for problem 19. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter: Z defaults to (1/3,1/3,...,1/3). You can reset Z by calling P19_r8VEC. Integrand: f(x) = product ( sqrt ( abs ( x(1:dim_num) - z(1:dim_num) ) ) ) Exact Integral: With Z as given, (2/3)**DIM_NUM * ( (2/3)**(3/2) + (1/3)**(3/2) )**DIM_NUM or approximately 0.49**DIM_NUM. Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Arnold Krommer, Christoph Ueberhuber, Numerical Integration on Advanced Systems, Springer, 1994, ISBN: 3540584102, LC: QA299.3.K76. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P19_f[POINT_NUM], the integrand values. */ { int dim; int inc; int point; double *value; double *z; z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p19_r8vec ( 'G', 'Z', dim_num, z ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] * sqrt ( fabs ( x[dim+point*dim_num] - z[dim] ) ); } } inc = point_num; p19_i4 ( 'I', '#', &inc ); free ( z ); return value; } /******************************************************************************/ void p19_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p19_i4 sets or gets I4 parameter values for problem 19. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p19_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p19_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p19_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p19_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p19_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p19_lim returns the integration limits for problem 19. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p19_name ( ) /******************************************************************************/ /* Purpose: p19_name() returns the name of problem 19. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p19_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Sqrt-Prod" ); return name; } /******************************************************************************/ void p19_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p19_r8VEC sets or gets R8VEC parameter values for problem 19. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'Z' is the base vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { int dim; static int dim_num_save = 0; static double *z = NULL; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( z ) { free ( z ); z = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; z = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'Z' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = 1.0 / 3.0; } } } else if ( action == 'G' ) { if ( name == 'Z' ) { r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p19_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'Z' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p19_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'Z' ) { r8vec_copy ( dim_num, value, z ); } else { printf ( "\n" ); printf ( "p19_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p19_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p19_region ( ) /******************************************************************************/ /* Purpose: p19_region() returns the name of the integration region for problem 19. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p19_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p19_title ( ) /******************************************************************************/ /* Purpose: p19_title prints a title for problem 19. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 19\n" ); printf ( " Name: Sqrt-Prod\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = prod ( sqrt ( | X(i) - Z(i) | ) )\n" ); printf ( " Parameter: \n" ); printf ( " Z(1:DIM_NUM) defaults to (1/3,1/3,...,1/3)\n" ); return; } /******************************************************************************/ void p20_default ( int dim_num ) /******************************************************************************/ /* Purpose: p20_default() sets default values for problem 20. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; double r8; p20_i4 ( 'D', '*', &i4 ); p20_r8 ( 'D', '*', &r8 ); return; } /******************************************************************************/ double p20_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p20_exact() returns the exact integral for problem 20. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P20_exact, the exact value of the integral. */ { double aval; double bval; double exact; double exponent; int i; double minus_one; double p; p20_r8 ( 'G', 'A', &aval ); p20_r8 ( 'G', 'B', &bval ); p20_r8 ( 'G', 'P', &p ); exact = 0.0; exponent = ( double ) ( dim_num + p ); minus_one = -1.0; for ( i = 0; i <= dim_num; i++ ) { minus_one = - minus_one; exact = exact + minus_one * r8_choose ( dim_num, i ) * pow ( ( double ) ( dim_num - i ) * bval + ( double ) ( i ) * aval, exponent ); } for ( i = 1; i <= dim_num; i++ ) { exact = exact / ( p + ( double ) ( i ) ); } return exact; } /******************************************************************************/ double *p20_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p20_f evaluates the integrand for problem 20. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: A <= X(1:DIM_NUM) <= B Integrand: f(x) = ( sum ( x(1:dim_num) ) )^p power is greater than -dim_num, and is not a negative integer. Exact Integral: sum ( 0 <= i <= dim_num ) (-1)^i * choose(dim_num,i) * ((dim_num-i)*b+i*a)^(dim_num+p) / ( (t+1) * (t+2) * ... * (t+dim_num) ) Parameter values: A defaults to 0.0. You can change A by calling P20_r8. B defaults to 1.0. You can change B by calling P20_r8. P defaults to 2.0. You can change P by calling P20_r8. Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Philip Davis, Philip Rabinowitz, Methods of Numerical Integration, Second Edition, Dover, 2007, ISBN: 0486453391, LC: QA299.3.D28. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P20_f[POINT_NUM], the integrand values. */ { int inc; double p; int point; double *value; p20_r8 ( 'G', 'P', &p ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = r8vec_sum ( dim_num, x+point*dim_num ); value[point] = pow ( value[point], p ); } inc = point_num; p20_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p20_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p20_i4 sets or gets I4 parameter values for problem 20. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p20_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p20_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p20_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p20_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p20_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p20_lim returns the integration limits for problem 20. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { double aval; double bval; int dim; p20_r8 ( 'G', 'A', &aval ); p20_r8 ( 'G', 'B', &bval ); for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = aval; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = bval; } return; } /******************************************************************************/ char *p20_name ( ) /******************************************************************************/ /* Purpose: p20_name() returns the name of problem 20. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p20_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Sum^P" ); return name; } /******************************************************************************/ void p20_r8 ( char action, char name, double *value ) /******************************************************************************/ /* Purpose: p20_r8 sets or gets R8 parameter values for problem 20. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' sets the parameter to its default value; 'G' gets a parameter. 'R' sets the parameter to a random value. 'S' sets a parameter to VALUE, char name, the name of the variable. 'R' is the radius. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static double a = 0.0; static double b = 1.0; static double p = 2.0; if ( action == 'D' ) { if ( name == 'A' || name == '*' ) { a = 0.0; } if ( name == 'B' || name == '*' ) { b = 1.0; } if ( name == 'P' || name == '*' ) { p = 2.0; } } else if ( action == 'G' ) { if ( name == 'A' ) { *value = a; } else if ( name == 'B' ) { *value = b; } else if ( name == 'P' ) { *value = p; } else { printf ( "\n" ); printf ( "p20_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'A' ) { a = ( double ) rand ( ) / ( double ) RAND_MAX; *value = a; } else if ( name == 'B' ) { b = ( double ) rand ( ) / ( double ) RAND_MAX; *value = b; } else if ( name == 'P' ) { p = ( double ) rand ( ) / ( double ) RAND_MAX; *value = p; } else { printf ( "\n" ); printf ( "p20_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'A' ) { a = *value; } else if ( name == 'B' ) { b = *value; } else if ( name == 'P' ) { p = *value; } else { printf ( "\n" ); printf ( "p20_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p20_r8(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p20_region ( ) /******************************************************************************/ /* Purpose: p20_region() returns the name of the integration region for problem 20. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p20_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p20_title ( ) /******************************************************************************/ /* Purpose: p20_title prints a title for problem 20. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 20\n" ); printf ( " Name: Sum^P\n" ); printf ( " Region: A <= X(i) <= B\n" ); printf ( " Integrand: F(X) = ( sum ( X(i) ) )^p\n" ); printf ( " Parameter:\n" ); printf ( " A, defaults to 0.0,\n" ); printf ( " B, defaults to 1.0,\n" ); printf ( " P, defaults to 2.0,\n" ); return; } /******************************************************************************/ void p21_default ( int dim_num ) /******************************************************************************/ /* Purpose: p21_default() sets default values for problem 21. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; double r8; p21_i4 ( 'D', '*', &i4 ); p21_r8 ( 'D', '*', &r8 ); p21_i4vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p21_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p21_exact() returns the exact integral for problem 21. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P21_exact, the exact value of the integral. */ { double arg; double c; int dim; int *e; double exact; p21_r8 ( 'G', 'C', &c ); e = ( int * ) malloc ( dim_num * sizeof ( int ) ); p21_i4vec ( 'G', 'E', dim_num, e ); for ( dim = 0; dim < dim_num; dim++ ) { if ( ( e[dim] % 2 ) == 1 ) { exact = 0.0; return exact; } } exact = 2.0 * c; for ( dim = 0; dim < dim_num; dim++ ) { arg = ( double ) ( e[dim] + 1 ) / 2.0; exact = exact * tgamma ( arg ); } arg = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { arg = arg + ( double ) ( e[dim] + 1 ); } arg = arg / 2.0; exact = exact / tgamma ( arg ); free ( e ); return exact; } /******************************************************************************/ double *p21_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p21_f evaluates the integrand for problem 21. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: The (surface of the) unit sphere Integral Parameter: C defaults to 1.0. Call P21_r8 to get or set this value. E(1:DIM_NUM) defaults to (/ 2, 2, ..., 2 /). Call P21_i4VEC to get or set this value. Integrand: F(X) = C * X1^E1 * X2^E2 * ... * Xn^En C is real, all exponents E are nonnegative integers. Exact Integral: 0, if any exponent is odd. 2 * C * Gamma((E1+1)/2) * Gamma((E2+1)/2) * ... * Gamma((En+1)/2) / Gamma( (E1+E2+...+En+N)/2 ), otherwise. Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Philip Davis, Philip Rabinowitz, Methods of Numerical Integration, Second Edition, Dover, 2007, ISBN: 0486453391, LC: QA299.3.D28. Gerald Folland, How to Integrate a Polynomial Over a Sphere, American Mathematical Monthly, May 2001, pages 446-448. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P21_f[POINT_NUM], the integrand values. */ { double c; int dim; int *e; int inc; int point; double *value; p21_r8 ( 'G', 'C', &c ); e = ( int * ) malloc ( dim_num * sizeof ( int ) ); p21_i4vec ( 'G', 'E', dim_num, e ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = c; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] * pow ( x[dim+point*dim_num], e[dim] ); } } inc = point_num; p21_i4 ( 'I', '#', &inc ); free ( e ); return value; } /******************************************************************************/ void p21_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p21_i4 sets or gets I4 parameter values for problem 21. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p21_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p21_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p21_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p21_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p21_i4vec ( char action, char name, int dim_num, int value[] ) /******************************************************************************/ /* Purpose: p21_i4VEC sets or gets I4VEC parameter values for problem 21. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to the default value. 'G' means the current value of the object should be returned. 'S' means the input values of the object and its dimension should be stored. char name, the name of the parameter. 'E' is the exponent vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { int dim; static int dim_num_save = 0; static int *e = NULL; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( e ) { free ( e ); e = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; e = ( int * ) malloc ( dim_num * sizeof ( int ) ); } if ( action == 'D' ) { if ( name == 'E' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { e[dim] = 2; } } } else if ( action == 'G' ) { if ( name == 'E' ) { i4vec_copy ( dim_num, e, value ); } else { printf ( "\n" ); printf ( "p21_i4VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'E' ) { i4vec_copy ( dim_num, value, e ); } else { printf ( "\n" ); printf ( "p21_i4VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p21_i4VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p21_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p21_lim returns the integration limits for problem 21. Discussion: Because the integration region is the surface of the unit sphere, the integration limits simply specify the limits of a box containing the integration region. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = -1.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p21_name ( ) /******************************************************************************/ /* Purpose: p21_name() returns the name of problem 21. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p21_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "SphereMonomial" ); return name; } /******************************************************************************/ void p21_r8 ( char action, char name, double *value ) /******************************************************************************/ /* Purpose: p21_r8 sets or gets R8 parameter values for problem 21. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' sets the parameter to its default value; 'G' gets a parameter. 'R' sets the parameter to a random value. 'S' sets a parameter to VALUE, char name, the name of the variable. 'R' is the radius. int *VALUE. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'D', 'G' or 'R', then VALUE is an output quantity, and is the current value of NAME. */ { static double c = 1.0; if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { c = 1.0; } } else if ( action == 'G' ) { if ( name == 'C' ) { *value = c; } else { printf ( "\n" ); printf ( "p21_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { c = ( double ) rand ( ) / ( double ) RAND_MAX; *value = c; } else { printf ( "\n" ); printf ( "p21_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' || name == 'c' ) { c = *value; } else { printf ( "\n" ); printf ( "p21_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p21_r8(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p21_region ( ) /******************************************************************************/ /* Purpose: p21_region() returns the name of the integration region for problem 21. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p21_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "SPHERE" ); return region; } /******************************************************************************/ void p21_title ( ) /******************************************************************************/ /* Purpose: p21_title prints a title for problem 21. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 21\n" ); printf ( " Name: SphereMonomial\n" ); printf ( " Region: Sphere surface, radius 1, center 0\n" ); printf ( " Integrand: F(X) = C * product ( X(i)^E(i) )\n" ); printf ( " Parameter:\n" ); printf ( " C, defaults to 1.0\n" ); printf ( " E(1:DIM_NUM) defaults to 2.\n" ); return; } /******************************************************************************/ void p22_default ( int dim_num ) /******************************************************************************/ /* Purpose: p22_default() sets default values for problem 22. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; double r8; p22_i4 ( 'D', '*', &i4 ); p22_r8 ( 'D', '*', &r8 ); p22_i4vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p22_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p22_exact() returns the exact integral for problem 22. Discussion: Thanks to Jeffrey Sax of Extreme Optimization for pointing out a mistake in a previous version of this routine, 28 May 2008. Licensing: This code is distributed under the MIT license. Modified: 28 May 2008 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P22_exact, the exact value of the integral. */ { double arg; double c; int dim; int *e; int e_sum; double exact; double r; p22_r8 ( 'G', 'C', &c ); p22_r8 ( 'G', 'R', &r ); e = ( int * ) malloc ( dim_num * sizeof ( int ) ); p22_i4vec ( 'G', 'E', dim_num, e ); for ( dim = 0; dim < dim_num; dim++ ) { if ( e[dim] % 2 == 1 ) { exact = 0.0; return exact; } } e_sum = i4vec_sum ( dim_num, e ) + dim_num; exact = 2.0 * c; for ( dim = 0; dim < dim_num; dim++ ) { arg = ( double ) ( e[dim] + 1 ) / 2.0; exact = exact * tgamma ( arg ); } arg = ( double ) ( e_sum ) / 2.0; exact = exact / tgamma ( arg ); exact = exact * pow ( r, e_sum ) / ( double ) ( e_sum ); free ( e ); return exact; } /******************************************************************************/ double *p22_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p22_f evaluates the integrand for problem 22. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: The interior of a sphere of radius R centered at the origin. Integral Parameter: C defaults to 1.0. Call P22_r8 to get or set this value. R defaults to 1.0. Call P22_r8 to get or set this value. E(1:DIM_NUM) defaults to (/ 2, 2, ..., 2 /). Call P22_i4VEC to get or set this value. Integrand: F(X) = C * X1^E1 * X2^E2 * ... * Xn^En C is real, all exponents E are nonnegative integers. Exact Integral: 0, if any exponent is odd. 2 * C * R^(E1+E2+...+EN+N) * Gamma((E1+1)/2) * Gamma((E2+1)/2) * ... * Gamma((En+1)/2) / ( Gamma( (E1+E2+...+En+N)/2 ) * ( E1+E2+...+EN+N) ), otherwise. Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Philip Davis, Philip Rabinowitz, Methods of Numerical Integration, Second Edition, Dover, 2007, ISBN: 0486453391, LC: QA299.3.D28. Gerald Folland, How to Integrate a Polynomial Over a Sphere, American Mathematical Monthly, May 2001, pages 446-448. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P22_f[POINT_NUM], the integrand values. */ { double c; int dim; int *e; int inc; int point; double *value; p22_r8 ( 'G', 'C', &c ); e = ( int * ) malloc ( dim_num * sizeof ( int ) ); p22_i4vec ( 'G', 'E', dim_num, e ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = c; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] * pow ( x[dim+point*dim_num], e[dim] ); } } inc = point_num; p22_i4 ( 'I', '#', &inc ); free ( e ); return value; } /******************************************************************************/ void p22_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p22_i4 sets or gets I4 parameter values for problem 22. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p22_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p22_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p22_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p22_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p22_i4vec ( char action, char name, int dim_num, int value[] ) /******************************************************************************/ /* Purpose: p22_i4VEC sets or gets I4VEC parameter values for problem 22. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to the default value. 'G' means the current value of the object should be returned. 'S' means the input values of the object and its dimension should be stored. char name, the name of the parameter. 'E' is the exponent vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { int dim; static int dim_num_save = 0; static int *e = NULL; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( e ) { free ( e ); e = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; e = ( int * ) malloc ( dim_num * sizeof ( int ) ); } if ( action == 'D' ) { if ( name == 'E' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { e[dim] = 2; } } } else if ( action == 'G' ) { if ( name == 'E' ) { i4vec_copy ( dim_num, e, value ); } else { printf ( "\n" ); printf ( "p22_i4VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'E' ) { i4vec_copy ( dim_num, value, e ); } else { printf ( "\n" ); printf ( "p22_i4VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p22_i4VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p22_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p22_lim returns the integration limits for problem 22. Discussion: Because the integration region is the interior of a sphere of radius R centered at the origin, the integration limits simply specify the limits of a box containing the integration region. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; double r; p22_r8 ( 'G', 'R', &r ); for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = -r; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = r; } return; } /******************************************************************************/ char *p22_name ( ) /******************************************************************************/ /* Purpose: p22_name() returns the name of problem 22. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p22_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "BallMonomial" ); return name; } /******************************************************************************/ void p22_r8 ( char action, char name, double *value ) /******************************************************************************/ /* Purpose: p22_r8 sets or gets R8 parameter values for problem 22. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' sets the parameter to its default value; 'G' gets a parameter. 'R' sets the parameter to a random value. 'S' sets a parameter to VALUE, char name, the name of the variable. 'R' is the radius. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'D', 'G' or 'R', then VALUE is an output quantity, and is the current value of NAME. */ { static double c = 1.0; static double r = 1.0; if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { c = 1.0; *value = c; } if ( name == 'R' || name == '*' ) { r = 1.0; *value = r; } } else if ( action == 'G' ) { if ( name == 'C' ) { *value = c; } else if ( name == 'R' ) { *value = r; } else { printf ( "\n" ); printf ( "p22_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { c = ( double ) rand ( ) / ( double ) RAND_MAX; *value = c; } else if ( name == 'R' ) { r = ( double ) rand ( ) / ( double ) RAND_MAX; *value = r; } else { printf ( "\n" ); printf ( "p22_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { c = *value; } else if ( name == 'R' ) { r = *value; } else { printf ( "\n" ); printf ( "p22_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p22_r8(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p22_region ( ) /******************************************************************************/ /* Purpose: p22_region() returns the name of the integration region for problem 22. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p22_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BALL" ); return region; } /******************************************************************************/ void p22_title ( ) /******************************************************************************/ /* Purpose: p22_title prints a title for problem 22. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { double c; double r; p22_r8 ( 'G', 'C', &c ); p22_r8 ( 'G', 'R', &r ); printf ( "\n" ); printf ( "Problem 22\n" ); printf ( " Name: BallMonomial\n" ); printf ( " Region: Sphere interior, radius R, center 0\n" ); printf ( " Integrand: F(X) = C * product ( X(i)^E(i) )\n" ); printf ( " Parameter:\n" ); printf ( " C, defaults to 1.0;\n" ); printf ( " R, defaults to 1.0;\n" ); printf ( " E(1:DIM_NUM) defaults to 2;\n" ); return; } /******************************************************************************/ void p23_default ( int dim_num ) /******************************************************************************/ /* Purpose: p23_default() sets default values for problem 23. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; double r8; p23_i4 ( 'D', '*', &i4 ); p23_r8 ( 'D', '*', &r8 ); p23_i4vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p23_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p23_exact() returns the exact integral for problem 23. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P23_exact, the exact value of the integral. */ { double c; int dim; int *e; double exact; p23_r8 ( 'G', 'C', &c ); e = ( int * ) malloc ( dim_num * sizeof ( int ) ); p23_i4vec ( 'G', 'E', dim_num, e ); exact = c; for ( dim = 0; dim < dim_num; dim++ ) { exact = exact * tgamma ( ( double ) ( e[dim] + 1 ) ); } exact = exact / tgamma ( ( double ) ( i4vec_sum ( dim_num, e ) + 1 ) ); free ( e ); return exact; } /******************************************************************************/ double *p23_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p23_f evaluates the integrand for problem 23. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: The interior of the unit simplex, for which all X's are nonnegative, and sum ( X(1:N) ) <= 1. Integral Parameter: C defaults to 1.0. Call P23_r8 to get or set this value. E(1:DIM_NUM) defaults to (/ 2, 2, ..., 2 /). Call P23_i4VEC to get or set this value. Integrand: F(X) = C * X1^E1 * X2^E2 * ... * Xn^En C is real, all exponents E are nonnegative integers. Exact Integral: C * Gamma(E1+1) * Gamma(E2+1) * ... * Gamma(En+1) / Gamma(E1+E2+...+En+1) Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Philip Davis, Philip Rabinowitz, Methods of Numerical Integration, Second Edition, Dover, 2007, ISBN: 0486453391, LC: QA299.3.D28. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P23_f[POINT_NUM], the integrand values. */ { double c; int dim; int *e; int inc; int point; double *value; p23_r8 ( 'G', 'C', &c ); e = ( int * ) malloc ( dim_num * sizeof ( int ) ); p23_i4vec ( 'G', 'E', dim_num, e ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = c; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] * pow ( x[dim+point*dim_num], e[dim] ); } } inc = point_num; p23_i4 ( 'I', '#', &inc ); free ( e ); return value; } /******************************************************************************/ void p23_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p23_i4 sets or gets I4 parameter values for problem 23. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p23_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p23_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p23_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p23_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p23_i4vec ( char action, char name, int dim_num, int value[] ) /******************************************************************************/ /* Purpose: p23_i4VEC sets or gets I4VEC parameter values for problem 23. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to the default value. 'G' means the current value of the object should be returned. 'S' means the input values of the object and its dimension should be stored. char name, the name of the parameter. 'E' is the exponent vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { int dim; static int dim_num_save = 0; static int *e = NULL; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( e ) { free ( e ); e = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; e = ( int * ) malloc ( dim_num * sizeof ( int ) ); } if ( action == 'D' ) { if ( name == 'E' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { e[dim] = 2; } } } else if ( action == 'G' ) { if ( name == 'E' ) { i4vec_copy ( dim_num, e, value ); } else { printf ( "\n" ); printf ( "p23_i4VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'E' ) { i4vec_copy ( dim_num, value, e ); } else { printf ( "\n" ); printf ( "p23_i4VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p23_i4VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p23_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p23_lim returns the integration limits for problem 23. Discussion: Because the integration region is the interior of the unit simplex, the integration limits simply specify the limits of a box containing the integration region. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p23_name ( ) /******************************************************************************/ /* Purpose: p23_name() returns the name of problem 23. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p23_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "SimplexMonomial" ); return name; } /******************************************************************************/ void p23_r8 ( char action, char name, double *value ) /******************************************************************************/ /* Purpose: p23_r8 sets or gets R8 parameter values for problem 23. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' sets the parameter to its default value; 'G' gets a parameter. 'R' sets the parameter to a random value. 'S' sets a parameter to VALUE, char name, the name of the variable. 'R' is the radius. int *VALUE. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'D', 'G' or 'R', then VALUE is an output quantity, and is the current value of NAME. */ { static double c = 1.0; if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { c = 1.0; } } else if ( action == 'G' ) { if ( name == 'C' ) { *value = c; } else { printf ( "\n" ); printf ( "p23_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { c = ( double ) rand ( ) / ( double ) RAND_MAX; *value = c; } else { printf ( "\n" ); printf ( "p23_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { c = *value; } else { printf ( "\n" ); printf ( "p23_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p23_r8(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p23_region ( ) /******************************************************************************/ /* Purpose: p23_region() returns the name of the integration region for problem 23. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p23_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "SIMPLEX" ); return region; } /******************************************************************************/ void p23_title ( ) /******************************************************************************/ /* Purpose: p23_title prints a title for problem 23. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { double c; p23_r8 ( 'G', 'C', &c ); printf ( "\n" ); printf ( "Problem 23\n" ); printf ( " Name: SimplexMonomial\n" ); printf ( " Region: Interior of unit simplex\n" ); printf ( " Integrand: F(X) = C * product ( X(i)^E(i) )\n" ); printf ( " Parameter:\n" ); printf ( " C, defaults to 1.0;\n" ); printf ( " E(1:DIM_NUM) defaults to 2;\n" ); return; } /******************************************************************************/ void p24_default ( int dim_num ) /******************************************************************************/ /* Purpose: p24_default() sets default values for problem 24. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p24_i4 ( 'D', '*', &i4 ); p24_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p24_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p24_exact() returns the exact integral for problem 24. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P24_exact, the exact value of the integral. */ { double exact; exact = 1.0; return exact; } /******************************************************************************/ double *p24_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p24_f evaluates the integrand for problem 24. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter: C(1:DIM_NUM) defaults to 0.0. A typical, more difficult problem, has C(I) = I**(1/3) Call P24_r8VEC to get or set C. Integrand: F(X) = product ( ( abs ( 4 * X(1:DIM_NUM) - 2 ) + C(1:DIM_NUM) ) / ( 1 + C(1:DIM_NUM) ) ) Exact Integral: 1 Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Stephen Joe, Frances Kuo, Remark on Algorithm 659: Implementing Sobol's Quasirandom Seqence Generator, ACM Transactions on Mathematical Software, Volume 29, Number 1, March 2003, pages 49-57. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P24_f[POINT_NUM], the integrand values. */ { double *c; int dim; int inc; int point; double *value; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p24_r8vec ( 'G', 'C', dim_num, c ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] * ( fabs ( 4.0 * x[dim+point*dim_num] - 2.0 ) + c[dim] ) / ( 1.0 + c[dim] ); } } inc = point_num; p24_i4 ( 'I', '#', &inc ); free ( c ); return value; } /******************************************************************************/ void p24_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p24_i4 sets or gets I4 parameter values for problem 24. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p24_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p24_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p24_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p24_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p24_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p24_lim returns the integration limits for problem 24. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p24_name ( ) /******************************************************************************/ /* Purpose: p24_name() returns the name of problem 24. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p24_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "(|4X-2|+c)/(1+c)" ); return name; } /******************************************************************************/ void p24_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p24_r8VEC sets or gets R8VEC parameter values for problem 24. Licensing: This code is distributed under the MIT license. Modified: 06 June 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'C' is the coefficient vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { static double *c = NULL; int dim; static int dim_num_save = 0; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( c ) { free ( c ); c = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = 0.0; } } } else if ( action == 'G' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, c, value ); } else { printf ( "\n" ); printf ( "p24_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, c, value ); } else { printf ( "\n" ); printf ( "p24_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, value, c ); } else { printf ( "\n" ); printf ( "p24_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p24_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p24_region ( ) /******************************************************************************/ /* Purpose: p24_region() returns the name of the integration region for problem 24. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p24_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p24_title ( ) /******************************************************************************/ /* Purpose: p24_title prints a title for problem 24. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 24\n" ); printf ( " Name: (|4X-2|+c)/(1+c)\n" ); printf ( " Region: 0 <= X(i) <= 1,\n" ); printf ( " Integrand: F(X) = product ( ( |4*X(i)-2| + C(i) ) / (1 + C(i) )\n" ); printf ( " Parameter:\n" ); printf ( " C(1:DIM_NUM) defaults to 0.0;\n" ); return; } /******************************************************************************/ void p25_default ( int dim_num ) /******************************************************************************/ /* Purpose: p25_default() sets default values for problem 25. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; double r8; p25_i4 ( 'D', '*', &i4 ); p25_r8 ( 'D', '*', &r8 ); return; } /******************************************************************************/ double p25_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p25_exact() returns the exact integral for problem 25. Discussion: The formula in the reference seems to yield a result that is too small by 1. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P25_exact, the exact value of the integral. */ { double c; double exact; int i; double roundoff; double term; double term2; p25_r8 ( 'G', 'C', &c ); roundoff = DBL_EPSILON; exact = 1.0; term = 1.0; i = 0; for ( ; ; ) { i = i + 1; term = term * c / ( double ) ( i ); term2 = term / ( double ) ( i4_power ( i + 1, dim_num ) ); if ( fabs ( term2 ) <= roundoff * ( 1.0 + fabs ( exact ) ) ) { break; } exact = exact + term2; } return exact; } /******************************************************************************/ double *p25_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p25_f evaluates the integrand for problem 25. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integrand: exp ( C * product ( X(1:N) ) ) Parameter values: C defaults to 0.3, and can be changed by calling P25_r8. Exact Integral: sum ( 1 <= i <= Infinity ) C**i / ( ( i + 1 )**N * i// ) Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: [Integral #3], Thomas Patterson, On the Construction of a Practical Ermakov-Zolotukhin Multiple Integrator, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D. Reidel, 1987, pages 269-290. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P25_f[POINT_NUM], the integrand values. */ { double c; int inc; int point; double *value; p25_r8 ( 'G', 'C', &c ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = exp ( c * r8vec_product ( dim_num, x+point*dim_num ) ); } inc = point_num; p25_i4 ( 'I', '#', &inc ); return value; } /******************************************************************************/ void p25_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p25_i4 sets or gets I4 parameter values for problem 25. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p25_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p25_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p25_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p25_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p25_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p25_lim returns the integration limits for problem 25. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p25_name ( ) /******************************************************************************/ /* Purpose: p25_name() returns the name of problem 25. Licensing: This code is distributed under the MIT license. Modified: 12 March 2007 Author: John Burkardt Output: char *p25_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Patterson #3, exp(c*X)" ); return name; } /******************************************************************************/ void p25_r8 ( char action, char name, double *value ) /******************************************************************************/ /* Purpose: p25_r8 sets or gets R8 parameter values for problem 25. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' sets the parameter to its default value; 'G' gets a parameter. 'R' sets the parameter to a random value. 'S' sets a parameter to VALUE, char name, the name of the variable. 'R' is the radius. int *VALUE. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'D', 'G', or 'R', then VALUE is an output quantity, and is the current value of NAME. */ { static double c = 0.3; if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { c = 0.3; } } else if ( action == 'G' ) { if ( name == 'C' ) { *value = c; } else { printf ( "\n" ); printf ( "p25_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { c = ( double ) rand ( ) / ( double ) RAND_MAX; *value = c; } else { printf ( "\n" ); printf ( "p25_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { c = *value; } else { printf ( "\n" ); printf ( "p25_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p25_r8(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p25_region ( ) /******************************************************************************/ /* Purpose: p25_region() returns the name of the integration region for problem 25. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p25_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p25_title ( ) /******************************************************************************/ /* Purpose: p25_title prints a title for problem 10. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { double c; p25_r8 ( 'G', 'C', &c ); printf ( "\n" ); printf ( "Problem 25\n" ); printf ( " Name: Patterson #3, exp(c*X))\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = exp ( C * product ( X(i) ) )\n" ); printf ( " Parameter:\n" ); printf ( " C, defaults to 0.3\n" ); return; } /******************************************************************************/ void p26_default ( int dim_num ) /******************************************************************************/ /* Purpose: p26_default() sets default values for problem 26. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p26_i4 ( 'D', '*', &i4 ); p26_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p26_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p26_exact() returns the exact integral for problem 26. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P26_exact, the exact value of the integral. */ { double *c; int dim; double exact; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p26_r8vec ( 'G', 'C', dim_num, c ); exact = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { exact = exact * ( 1.0 - exp ( -c[dim] ) ); } free ( c ); return exact; } /******************************************************************************/ double *p26_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p26_f evaluates the integrand for problem 26. Discussion: The integrand is similar to that for the Patterson integral #7, except for a normalization of the constants, and a (random) constant factor in the integrand. The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter: The integral depends on a parameter vector C(1:N). The reference suggests choosing C at random in [0,1]. C(1:N) defaults to 1/N. To get or set C, call P26_r8VEC. Integrand: product ( c(1:dim_num) * ( exp ( - c(1:dim_num) * x(1:dim_num) ) ) ) = product ( c(1:dim_num) ) * exp ( - sum ( c(1:dim_num) * x(1:dim_num) ) ) Exact Integral: product ( 1 - exp ( c(1:n) ) ) Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: [Integral #1], Thomas Patterson, On the Construction of a Practical Ermakov-Zolotukhin Multiple Integrator, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D. Reidel, 1987, pages 269-290. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P26_f[POINT_NUM], the integrand values. */ { double *c; int inc; int point; double *value; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p26_r8vec ( 'G', 'C', dim_num, c ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = r8vec_product ( dim_num, c ) * exp ( - r8vec_dot ( dim_num, c, x+point*dim_num ) ); } inc = point_num; p26_i4 ( 'I', '#', &inc ); free ( c ); return value; } /******************************************************************************/ void p26_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p26_i4 sets or gets I4 parameter values for problem 26. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p26_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p26_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p26_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p26_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p26_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p26_lim returns the integration limits for problem 26. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p26_name ( ) /******************************************************************************/ /* Purpose: p26_name() returns the name of problem 26. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p26_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Patterson #1" ); return name; } /******************************************************************************/ void p26_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p26_r8VEC sets or gets R8VEC parameter values for problem 26. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'C' is the coefficient vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { static double *c = NULL; int dim; static int dim_num_save = 0; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( c ) { free ( c ); c = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { for ( dim = 0; dim< dim_num; dim++ ) { c[dim] = 1.0 / ( double ) ( dim_num ); } } } else if ( action == 'G' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, c, value ); } else { printf ( "\n" ); printf ( "p26_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, c, value ); } else { printf ( "\n" ); printf ( "p26_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, value, c ); } else { printf ( "\n" ); printf ( "p26_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p26_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p26_region ( ) /******************************************************************************/ /* Purpose: p26_region() returns the name of the integration region for problem 26. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p26_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p26_title ( ) /******************************************************************************/ /* Purpose: p26_title prints a title for problem 26. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 26\n" ); printf ( " Name: Patterson #1\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = product ( C(i) * exp ( - C(i) * X(i) ) )\n" ); printf ( " Parameter:\n" ); printf ( " C(1:DIM_NUM) defaults to 1/DIM_NUM.\n" ); return; } /******************************************************************************/ void p27_default ( int dim_num ) /******************************************************************************/ /* Purpose: p27_default() sets default values for problem 27. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; double r8; p27_i4 ( 'D', '*', &i4 ); p27_r8 ( 'D', '*', &r8 ); p27_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p27_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p27_exact() returns the exact integral for problem 27. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P27_exact, the exact value of the integral. */ { double *c; int dim; double exact; double r; double pi = 3.141592653589793; p27_r8 ( 'G', 'R', &r ); c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p27_r8vec ( 'G', 'C', dim_num, c ); exact = pow ( 2.0, dim_num ) * cos ( 2.0 * pi * r + 0.5 * r8vec_sum ( dim_num, c ) ); for ( dim = 0; dim < dim_num; dim++ ) { exact = exact * sin ( 0.5 * c[dim] ) / c[dim]; } free ( c ); return exact; } /******************************************************************************/ double *p27_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p27_f evaluates the integrand for problem 27. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter: The integral depends on a parameter R and vector C(1:N). R defaults to 0.3. The reference suggests choosing C at random in [0,1] and then multiplying by the normalizing factor (25/N). C(1:N) defaults to 1/N. To get or set R, call P27_r8. To get or set C, call P27_r8VEC. Integrand: cos ( 2 * pi * R + sum ( c(1:n) * x(1:n) ) ) Exact Integral: 2**N * cos ( 2 * pi * R + 0.5 * sum ( c(1:n) ) ) * product ( sin ( 0.5 * c(1:n) ) / c(1:n) ) Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Alan Genz, [ Integral #1] A Package for Testing Multiple Integration Subroutines, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D Reidel, 1987, pages 337-340. [Integral #5], Thomas Patterson, On the Construction of a Practical Ermakov-Zolotukhin Multiple Integrator, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D. Reidel, 1987, pages 269-290. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P27_f[POINT_NUM], the integrand values. */ { double arg; double *c; int inc; double r; double pi = 3.141592653589793; int point; double *value; p27_r8 ( 'G', 'R', &r ); c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p27_r8vec ( 'G', 'C', dim_num, c ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { arg = 2.0 * pi * r + r8vec_dot ( dim_num, c, x+point*dim_num ); value[point] = cos ( arg ); } inc = point_num; p27_i4 ( 'I', '#', &inc ); free ( c ); return value; } /******************************************************************************/ void p27_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p27_i4 sets or gets I4 parameter values for problem 27. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p27_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p27_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p27_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p27_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p27_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p27_lim returns the integration limits for problem 27. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p27_name ( ) /******************************************************************************/ /* Purpose: p27_name() returns the name of problem 27. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p27_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Genz #1 / Patterson #5, Oscillatory" ); return name; } /******************************************************************************/ void p27_r8 ( char action, char name, double *value ) /******************************************************************************/ /* Purpose: p27_r8 sets or gets R8 parameter values for problem 27. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' sets the parameter to its default value; 'G' gets a parameter. 'R' sets the parameter to a random value. 'S' sets a parameter to VALUE, char name, the name of the variable. 'R' is the radius. int *VALUE. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'D', 'G', or 'R' then VALUE is an output quantity, and is the current value of NAME. */ { static double r = 0.3; if ( action == 'D' ) { if ( name == 'R' || name == '*' ) { r = 0.3; } } else if ( action == 'G' ) { if ( name == 'R' ) { *value = r; } else { printf ( "\n" ); printf ( "p27_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'R' ) { r = ( double ) rand ( ) / ( double ) RAND_MAX; *value = r; } else { printf ( "\n" ); printf ( "p27_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'R' ) { r = *value; } else { printf ( "\n" ); printf ( "p27_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p27_r8(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p27_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p27_r8VEC sets or gets R8VEC parameter values for problem 27. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'C' is the coefficient vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { static double *c = NULL; int dim; static int dim_num_save = 0; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( c ) { free ( c ); c = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = 1.0 / ( double ) ( dim_num ); } } } else if ( action == 'G' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, c, value ); } else { printf ( "\n" ); printf ( "p27_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, c, value ); } else { printf ( "\n" ); printf ( "p27_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, value, c ); } else { printf ( "\n" ); printf ( "p27_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p27_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p27_region ( ) /******************************************************************************/ /* Purpose: p27_region() returns the name of the integration region for problem 27. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p27_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p27_title ( ) /******************************************************************************/ /* Purpose: p27_title prints a title for problem 27. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 27\n" ); printf ( " Name: Genz #1 / Patterson #5, Oscillatory\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = cos ( 2 * pi * R + sum ( C(i) * X(i) ) )\n" ); printf ( " Parameter:\n" ); printf ( " R, defaults to 0.3\n" ); printf ( " C(1:DIM_NUM) defaults to 1/DIM_NUM\n" ); return; } /******************************************************************************/ void p28_default ( int dim_num ) /******************************************************************************/ /* Purpose: p28_default() sets default values for problem 28. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p28_i4 ( 'D', '*', &i4 ); p28_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p28_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p28_exact() returns the exact integral for problem 28. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P28_exact, the exact value of the integral. */ { double *c; int dim; double exact; double *z; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p28_r8vec ( 'G', 'C', dim_num, c ); z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p28_r8vec ( 'G', 'Z', dim_num, z ); exact = 1.0; for ( dim = 0; dim < dim_num;dim++ ) { exact = exact * ( atan ( ( 1.0 - z[dim] ) / c[dim] ) + atan ( z[dim] / c[dim] ) ) / c[dim]; } free ( c ); free ( z ); return exact; } /******************************************************************************/ double *p28_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p28_f evaluates the integrand for problem 28. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter: The integral depends on vectors C(1:N) and Z(1:N). To get or set C or Z, call P28_r8VEC. The reference suggests choosing C by initializing it to random values in [0,1], and then normalizing so that sum ( 1/C(1:N)**2 ) = 170 / N**(7/2) C(1:N) used to default to N**(9/4) / sqrt(170) but this is INSUPPORTABLE for large dimension N. So now we're setting C(1:N) to default to 1.0, but see P28_r8VEC_default to be sure. The reference suggests choosing Z at random in [0,1]. Z(1:N) defaults to 0.5. Integrand: 1 / product ( C(1:DIM_NUM)**2 + ( X(1:DIM_NUM) - Z(1:DIM_NUM) )**2 ) Exact Integral: product ( ( arctan ( ( 1 - Z(1:DIM_NUM) ) / C(1:DIM_NUM) ) + arctan ( Z(1:DIM_NUM) / C(1:DIM_NUM) ) ) / C(1:DIM_NUM) ) Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Alan Genz, [ Integral #2] A Package for Testing Multiple Integration Subroutines, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D Reidel, 1987, pages 337-340. [Integral #6], Thomas Patterson, On the Construction of a Practical Ermakov-Zolotukhin Multiple Integrator, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D. Reidel, 1987, pages 269-290. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P28_f[POINT_NUM], the integrand values. */ { double *c; int dim; int inc; int point; double *value; double *z; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p28_r8vec ( 'G', 'C', dim_num, c ); z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p28_r8vec ( 'G', 'Z', dim_num, z ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] * ( pow ( c[dim], 2 ) + pow ( x[dim+point*dim_num] - z[dim], 2 ) ); } value[point] = 1.0 / value[point]; } inc = point_num; p28_i4 ( 'I', '#', &inc ); free ( c ); free ( z ); return value; } /******************************************************************************/ void p28_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p28_i4 sets or gets I4 parameter values for problem 28. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p28_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p28_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p28_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p28_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p28_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p28_lim returns the integration limits for problem 28. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p28_name ( ) /******************************************************************************/ /* Purpose: p28_name() returns the name of problem 28. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p28_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Genz #2 / Patterson #6, Product Peak" ); return name; } /******************************************************************************/ void p28_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p28_r8VEC sets or gets R8VEC parameter values for problem 28. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'C' is the coefficient vector. 'Z' is the base vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { static double *c = NULL; int dim; static int dim_num_save = 0; double s; double t; static double *z = NULL; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( c ) { free ( c ); c = NULL; } if ( z ) { free ( z ); z = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); z = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = 1.0; } } if ( name == 'Z' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = 0.5; } } } else if ( action == 'G' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, c, value ); } else if ( name == 'Z' ) { r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p28_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { t = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; t = t + 1.0 / pow ( c[dim], 2 ); } s = sqrt ( sqrt ( ( double ) i4_power ( dim_num, 7 ) ) * t / 170.0 ); for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = s * c[dim]; } r8vec_copy ( dim_num, c, value ); } else if ( name == 'Z' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p28_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, value, c ); } else if ( name == 'Z' ) { r8vec_copy ( dim_num, value, z ); } else { printf ( "\n" ); printf ( "p28_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p28_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p28_region ( ) /******************************************************************************/ /* Purpose: p28_region() returns the name of the integration region for problem 28. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p28_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p28_title ( ) /******************************************************************************/ /* Purpose: p28_title prints a title for problem 28. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 28\n" ); printf ( " Name: Genz #2 / Patterson #6, Product Peak\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = 1 / product ( C(i)^2 + ( X(i) - Z(i) )^2 )\n" ); printf ( " Parameter:\n" ); printf ( " C(1:DIM_NUM) defaults to DIM_NUM^(9/4)/sqrt(170)\n" ); printf ( " Z(1:DIM_NUM) defaults to 0.5.\n" ); return; } /******************************************************************************/ void p29_default ( int dim_num ) /******************************************************************************/ /* Purpose: p29_default() sets default values for problem 29. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; double r8; p29_i4 ( 'D', '*', &i4 ); p29_r8 ( 'D', '*', &r8 ); p29_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p29_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p29_exact() returns the exact integral for problem 29. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double EXACT, the exact value of the integral. */ { double a; double *c; int d; int dim; double e; double exact; int *ivec; double r; int rank; double total; ivec = ( int * ) malloc ( dim_num * sizeof ( int ) ); p29_r8 ( 'G', 'R', &r ); c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p29_r8vec ( 'G', 'C', dim_num, c ); /* Here, we need to generate all possible DIM_NUM tuples with values of 0 or 1. */ total = 0.0; rank = 0; for ( ; ; ) { tuple_next ( 0, 1, dim_num, &rank, ivec ); if ( rank == 0 ) { break; } d = i4vec_sum ( dim_num, ivec ); e = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { e = e + ( double ) ivec[dim] * c[dim]; } total = total + ( double ) i4_power ( -1, d ) / pow ( 1.0 + e, r ); } a = 1.0; for ( dim = 0; dim <= dim_num-1; dim++ ) { a = a * ( r + ( double ) ( dim ) ); } exact = total / ( a * r8vec_product ( dim_num, c ) ); free ( c ); free ( ivec ); return exact; } /******************************************************************************/ double *p29_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p29_f evaluates the integrand for problem 29. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral parameter: The integral depends on a parameter R, and a vector C(1:N). The Genz reference uses R = 1. The Patterson reference suggests using R = 0.3. The Patterson reference suggests choosing C at random in [0,1] and then multiplying by the normalizing factor (80/N**2). This is what you will get if you "RANDOMIZE" C. C defaults to 1/DIM_NUM. To get or set R, call P29_r8. To get or set C, call P29_r8VEC. Integrand: 1 / ( 1 + sum ( c(1:dim_num) * x(1:dim_num) ) )**(r+dim_num) Exact Integral: (1/A) * ( 1 / product ( c(1:dim_num) ) ) * sum(0<=I(1)<=1) sum (0<=I(2)<=1) ... sum(0<=I(dim_num)<=1) (-1)**sum(I(1:dim_num)) / ( 1 + sum ( i(1:dim_num)*c(1:dim_num) ) )**r with A = r * ( r + 1 ) * ... * ( r + dim_num - 1 ) Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: [ Integral #3] Alan Genz, A Package for Testing Multiple Integration Subroutines, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D Reidel, 1987, pages 337-340. [Integral #8], Thomas Patterson, On the Construction of a Practical Ermakov-Zolotukhin Multiple Integrator, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D. Reidel, 1987, pages 269-290. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P29_f[POINT_NUM], the integrand values. */ { double *c; int inc; int point; double r; double *value; p29_r8 ( 'G', 'R', &r ); c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p29_r8vec ( 'G', 'C', dim_num, c ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 1.0 / pow ( 1.0 + r8vec_dot ( dim_num, c, x+point*dim_num ), r + dim_num ); } inc = point_num; p29_i4 ( 'I', '#', &inc ); free ( c ); return value; } /******************************************************************************/ void p29_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p29_i4 sets or gets I4 parameter values for problem 29. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p29_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p29_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p29_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p29_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p29_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p29_lim returns the integration limits for problem 29. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p29_name ( ) /******************************************************************************/ /* Purpose: p29_name() returns the name of problem 29. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p29_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Genz #3 / Patterson #8, Corner Peak" ); return name; } /******************************************************************************/ void p29_r8 ( char action, char name, double *value ) /******************************************************************************/ /* Purpose: p29_r8 sets or gets R8 parameter values for problem 29. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' sets the parameter to its default value; 'G' gets a parameter. 'R' sets the parameter to a random value. 'S' sets a parameter to VALUE, char name, the name of the variable. 'R' is the radius. int *VALUE. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'D', 'G', or 'R' then VALUE is an output quantity, and is the current value of NAME. */ { static double r = 0.3; if ( action == 'D' ) { if ( name == 'R' || name == '*' ) { r = 0.3; } } else if ( action == 'G' ) { if ( name == 'R' ) { *value = r; } else { printf ( "\n" ); printf ( "p29_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'R' ) { r = ( double ) rand ( ) / ( double ) RAND_MAX; *value = r; } else { printf ( "\n" ); printf ( "p29_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'R' ) { r = *value; } else { printf ( "\n" ); printf ( "p29_r8(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p29_r8(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p29_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p29_r8VEC sets or gets R8VEC parameter values for problem 29. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'C' is the coefficient vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { static double *c = NULL; int dim; static int dim_num_save = 0; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( c ) { free ( c ); c = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = 1.0 / ( double ) ( dim_num ); } } } else if ( action == 'G' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, c, value ); } else { printf ( "\n" ); printf ( "p29_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = 80.0 * ( double ) rand ( ) / ( double ) RAND_MAX / ( double ) ( i4_power ( dim_num, 2 ) ); } r8vec_copy ( dim_num, c, value ); } else { printf ( "\n" ); printf ( "p29_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, value, c ); } else { printf ( "\n" ); printf ( "p29_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p29_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p29_region ( ) /******************************************************************************/ /* Purpose: p29_region() returns the name of the integration region for problem 29. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p29_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p29_title ( ) /******************************************************************************/ /* Purpose: p29_title prints a title for problem 29. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 29\n" ); printf ( " Name: Genz #3 / Patterson #8, Corner Peak\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = 1 / ( 1 + sum ( C(i) * X(i) ) )^R\n" ); printf ( " Parameter:\n" ); printf ( " R, defaults to 0.3\n" ); printf ( " C(1:DIM_NUM) defaults to 1/DIM_NUM.\n" ); return; } /******************************************************************************/ void p30_default ( int dim_num ) /******************************************************************************/ /* Purpose: p30_default() sets default values for problem 30. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p30_i4 ( 'D', '*', &i4 ); p30_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p30_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p30_exact() returns the exact integral for problem 30. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P30_exact, the exact value of the integral. */ { double *c; int dim; double exact; double pi = 3.141592653589793; double *z; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p30_r8vec ( 'G', 'C', dim_num, c ); z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p30_r8vec ( 'G', 'Z', dim_num, z ); exact = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { exact = exact * sqrt ( pi ) * ( error_f ( c[dim] * ( 1.0 - z[dim] ) ) + error_f ( c[dim] * z[dim] ) ) / ( 2.0 * c[dim] ); } free ( c ); free ( z ); return exact; } /******************************************************************************/ double *p30_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p30_f evaluates the integrand for problem 30. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter: The integral depends on vectors C(1:N) and Z(1:N). The reference suggests choosing C at random in [0,1] and then multiplying by the normalizing factor sqrt(140/N**(3/2)). C(1:N) defaults to 1/N. Z(1:N) defaults to 0.5. To get or set C or Z, call P30_r8VEC. Integrand: exp ( - sum ( c(1:n)**2 * ( x(1:n) - z(1:n) )**2 ) Exact Integral: product ( sqrt ( pi ) * ( erf ( c(1:n) * ( 1 - z(1:n) ) ) + erf ( c(1:n) * z(1:n) ) ) / ( 2 * c(1:n) ) ) Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: [ Integral #4] Alan Genz, A Package for Testing Multiple Integration Subroutines, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D Reidel, 1987, pages 337-340. [Integral #9], Thomas Patterson, On the Construction of a Practical Ermakov-Zolotukhin Multiple Integrator, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D. Reidel, 1987, pages 269-290. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P30_f[POINT_NUM], the integrand values. */ { double *c; int dim; int inc; int point; double *value; double *z; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p30_r8vec ( 'G', 'C', dim_num, c ); z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p30_r8vec ( 'G', 'Z', dim_num, z ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] + pow ( c[dim] * ( x[dim+point*dim_num] - z[dim] ), 2 ); } value[point] = exp ( - value[point] ); } inc = point_num; p30_i4 ( 'I', '#', &inc ); free ( c ); free ( z ); return value; } /******************************************************************************/ void p30_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p30_i4 sets or gets I4 parameter values for problem 30. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p30_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p30_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p30_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p30_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p30_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p30_lim returns the integration limits for problem 30. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p30_name ( ) /******************************************************************************/ /* Purpose: p30_name() returns the name of problem 30. Licensing: This code is distributed under the MIT license. Modified: 11 March 2007 Author: John Burkardt Output: char *p30_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Genz #4, Patterson #9, Gaussian" ); return name; } /******************************************************************************/ void p30_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p30_r8vec() sets or gets R8VEC parameters for problem 30. Licensing: This code is distributed under the MIT license. Modified: 09 March 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'C' is the coefficient vector. 'Z' is the base vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { static double *c = NULL; int dim; static int dim_num_save = 0; static double *z = NULL; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( c ) { free ( c ); c = NULL; } if ( z ) { free ( z ); z = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); z = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = 1.0 / ( double ) ( dim_num ); } } if ( name == 'Z' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = 0.5; } } } else if ( action == 'G' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, c, value ); } else if ( name == 'Z' ) { r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p30_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = ( double ) rand ( ) / ( double ) RAND_MAX * sqrt ( 140.0 / sqrt ( ( double ) i4_power ( dim_num, 3 ) ) ) / sqrt ( 170.0 ); } r8vec_copy ( dim_num, c, value ); } else if ( name == 'Z' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p30_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, value, c ); } else if ( name == 'Z' ) { r8vec_copy ( dim_num, value, z ); } else { printf ( "\n" ); printf ( "p30_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p30_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p30_region ( ) /******************************************************************************/ /* Purpose: p30_region() returns the name of the integration region for problem 30. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt Output: char *p30_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p30_title ( ) /******************************************************************************/ /* Purpose: p30_title prints a title for problem 30. Licensing: This code is distributed under the MIT license. Modified: 07 March 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 30\n" ); printf ( " Name: Genz #4 / Patterson #9, Gaussian\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = exp ( sum ( C(i)^2 * ( X(i) - Z(i) )^2 )\n" ); printf ( " Parameter:\n" ); printf ( " C(1:DIM_NUM) defaults to 1/DIM_NUM.\n" ); printf ( " Z(1:DIM_NUM) defaults to 0.5.\n" ); return; } /******************************************************************************/ void p31_default ( int dim_num ) /******************************************************************************/ /* Purpose: p31_default() sets default values for problem 31. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p31_i4 ( 'D', '*', &i4 ); p31_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p31_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p31_exact() returns the exact integral for problem 31. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Reference: Kenneth Hanson, Quasi-Monte Carlo: halftoning in high dimensions? in Computatinal Imaging, Edited by CA Bouman and RL Stevenson, Proceedings SPIE, Volume 5016, 2003, pages 161-172. Input: int DIM_NUM, the spatial dimension. Output: double P31_exact, the exact value of the integral. */ { double *a; double *b; double *c; int dim; double exact; double *z; /* Get the limits of integration. */ a = ( double * ) malloc ( dim_num * sizeof ( double ) ); b = ( double * ) malloc ( dim_num * sizeof ( double ) ); p31_lim ( dim_num, a, b ); /* Get the coefficient vector C. */ c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p31_r8vec ( 'G', 'C', dim_num, c ); /* Get the location of Z. */ z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p31_r8vec ( 'G', 'Z', dim_num, z ); /* The value of the DIM_NUM dimensional integral is separable into the product of integrals over each dimension. Each of these 1 dimensional integrals, in turn, is easily computed, depending on where Z(I) lies with respect to the limits of integration A(I) and B(I). */ exact = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { /* Z < A < B | X - Z | = X - Z from A to B. */ if ( z[dim] < a[dim] ) { exact = exact * ( exp ( - c[dim] * ( a[dim] - z[dim] ) ) - exp ( - c[dim] * ( b[dim] - z[dim] ) ) ) / c[dim]; } /* A < Z < B | X - Z | = Z - X from B to Z, = X - Z from Z to A. */ else if ( z[dim] < b[dim] ) { exact = exact * ( 2.0 - exp ( - c[dim] * ( z[dim] - a[dim] ) ) - exp ( - c[dim] * ( b[dim] - z[dim] ) ) ) / c[dim]; } /* A < B < Z | X - Z | = Z - X from A to B. */ else { exact = exact * ( exp ( - c[dim] * ( z[dim] - b[dim] ) ) - exp ( - c[dim] * ( z[dim] - a[dim] ) ) ) / c[dim]; } } free ( a ); free ( b ); free ( c ); free ( z ); return exact; } /******************************************************************************/ double *p31_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p31_f evaluates the integrand for problem 31. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter: There is a basis point Z associated with the integrand. Z defaults to ( 0.5, 0.5, ..., 0.5 ). The user can set, get, or randomize this value by calling p31_r8VEC. The coefficient vector C (whose entries are usually positive) controls the steepness and circularity of the pseudo-Gaussian. C defaults to 2.0. The user can set, get, or randomize this value by calling p31_r8VEC. Integrand: exp ( - sum ( c(1:dim_num) * abs ( x(1:dim_num) - z(1:dim_num) ) ) ) Exact Integral: The integral is separable into Int ( A(1) <= X(1) <= B(1) ) exp ( - C(1) * abs ( X(1) - Z(1) ) ) * Int ( A(2) <= X(2) <= B(2) ) exp ( - C(2) * abs ( X(2) - Z(2) ) ) * ... Hence, the exact integral is computed as the product of one dimensional integrals. Each of these is easily computed once the location of Z(I) with respect to A(I) and B(I) is determined. Licensing: This code is distributed under the MIT license. Modified: 03 June 2007 Author: John Burkardt Reference: Alan Genz, [ Integral #5] A Package for Testing Multiple Integration Subroutines, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D. Reidel, 1987, pages 337-340. Kenneth Hanson, Quasi-Monte Carlo: halftoning in high dimensions? in Computatinal Imaging, Edited by CA Bouman and RL Stevenson, Proceedings SPIE, Volume 5016, 2003, pages 161-172. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P31_f[POINT_NUM], the integrand values. */ { double *c; int dim; int inc; int point; double *value; double *z; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p31_r8vec ( 'G', 'C', dim_num, c ); z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p31_r8vec ( 'G', 'Z', dim_num, z ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = 0.0; for ( dim = 0; dim < dim_num; dim++ ) { value[point] = value[point] - c[dim] * fabs ( x[dim+point*dim_num] - z[dim] ); } value[point] = exp ( value[point] ); } inc = point_num; p31_i4 ( 'I', '#', &inc ); free ( c ); free ( z ); return value; } /******************************************************************************/ void p31_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p31_i4 sets or gets I4 parameter values for problem 31. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p31_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p31_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p31_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p31_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p31_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p31_lim returns the integration limits for problem 31. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p31_name ( ) /******************************************************************************/ /* Purpose: p31_name() returns the name of problem 31. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Output: char *p31_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Genz #5, C0 Pseudo-Gaussian" ); return name; } /******************************************************************************/ void p31_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p31_r8vec() sets or gets R8VEC parameters for problem 31. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'C' is the coefficient vector. 'Z' is the base vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { static double *c = NULL; int dim; static int dim_num_save = 0; static double *z = NULL; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( c ) { free ( c ); c = NULL; } if ( z ) { free ( z ); z = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); z = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = 2.0; } } if ( name == 'Z' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = 0.5; } } } else if ( action == 'G' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, c, value ); } else if ( name == 'Z' ) { r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p31_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = 4.0 * ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, c, value ); } else if ( name == 'Z' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p31_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, value, c ); } else if ( name == 'Z' ) { r8vec_copy ( dim_num, value, z ); } else { printf ( "\n" ); printf ( "p31_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p31_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p31_region ( ) /******************************************************************************/ /* Purpose: p31_region() returns the name of the integration region for problem 31. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Output: char *p31_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p31_title ( ) /******************************************************************************/ /* Purpose: p31_title prints a title for problem 31. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 31\n" ); printf ( " Name: Genz #5, C0 Pseudo-Gaussian\n" ); printf ( " Nondifferentiable peak at point Z.\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = exp ( -sum ( C(i) * | X(i) - Z(i) | ) )\n" ); printf ( " Parameter:\n" ); printf ( " C(1:DIM_NUM) defaults to 2.0;\n" ); printf ( " Z(1:DIM_NUM) defaults to 0.5;\n" ); return; } /******************************************************************************/ void p32_default ( int dim_num ) /******************************************************************************/ /* Purpose: p32_default() sets default values for problem 32. Discussion: If a problem uses vector parameter values, then the spatial dimension DIM_NUM is needed as so that the vector parameter values can be properly dimensioned. Every problem keeps a count of the number of function calls. Calling this routine causes that count to be reset to 0. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the problem. */ { int i4; p32_i4 ( 'D', '*', &i4 ); p32_r8vec ( 'D', '*', dim_num, NULL ); return; } /******************************************************************************/ double p32_exact ( int dim_num ) /******************************************************************************/ /* Purpose: p32_exact() returns the exact integral for problem 32. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Input: int DIM_NUM, the spatial dimension. Output: double P32_exact, the exact value of the integral. */ { double *a; double *b; double *c; int dim; double exact; double *z; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p32_r8vec ( 'G', 'C', dim_num, c ); z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p32_r8vec ( 'G', 'Z', dim_num, z ); a = ( double * ) malloc ( dim_num * sizeof ( double ) ); b = ( double * ) malloc ( dim_num * sizeof ( double ) ); p32_lim ( dim_num, a, b ); exact = 1.0; for ( dim = 0; dim < dim_num; dim++ ) { if ( z[dim] <= a[dim] ) { exact = exact * 0.0; } else if ( z[dim] <= b[dim] ) { if ( c[dim] == 0.0 ) { exact = exact * ( z[dim] - a[dim] ); } else { exact = exact * ( exp ( c[dim] * z[dim] ) - exp ( c[dim] * a[dim] ) ) / c[dim]; } } else { if ( c[dim] == 0.0 ) { exact = exact * ( b[dim] - a[dim] ); } else { exact = exact * ( exp ( c[dim] * z[dim] ) - exp ( c[dim] * a[dim] ) ) / c[dim]; } } } free ( a ); free ( b ); free ( c ); free ( z ); return exact; } /******************************************************************************/ double *p32_f ( int dim_num, int point_num, double x[] ) /******************************************************************************/ /* Purpose: p32_f() evaluates the integrand for problem 32. Discussion: The spatial dimension DIM_NUM is arbitrary. Region: 0 <= X(1:DIM_NUM) <= 1 Integral Parameter: The integral depends on vectors C(1:N) and Z(1:N). The reference suggests choosing C at random in [0,1] and then multiplying by the normalizing factor sqrt(140/N**(3/2)). The default value of C(1:N) is (1/2)^(1/N). The default value of Z(1:N) is (1/2)^(1/N). Integrand: exp ( c(1:n)*x(1:n) ) if all x(1:n) <= z(1:n) 0 otherwise Exact Integral: product ( g(1:n)(x,z,a,b,c) ) where g(i)(x,z,a,b,c) = 0 if z(i) <= a(i) ( e^(c(i)*z(i) ) - e^(c(i)*a(i)) ) / c(i) if a(i) <= z(i) <= b(i) ( e^(c(i)*b(i) ) - e^(c(i)*a(i)) ) / c(i) if b(i) <= z(i) with obvious modifications when c(i) = 0. Licensing: This code is distributed under the MIT license. Modified: 02 July 2025 Author: John Burkardt Reference: [ Integral #6] Alan Genz, A Package for Testing Multiple Integration Subroutines, in Numerical Integration: Recent Developments, Software and Applications, edited by Patrick Keast and Graeme Fairweather, D Reidel, 1987, pages 337-340. Input: int DIM_NUM, the spatial dimension. int POINT_NUM, the number of points. double X[DIM_NUM*pOINT_NUM], the evaluation points. Output: double P32_f[POINT_NUM], the integrand values. */ { double *c; int dim; int inc; int point; double *value; double *z; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); p32_r8vec ( 'G', 'C', dim_num, c ); z = ( double * ) malloc ( dim_num * sizeof ( double ) ); p32_r8vec ( 'G', 'Z', dim_num, z ); value = ( double * ) malloc ( point_num * sizeof ( double ) ); for ( point = 0; point < point_num; point++ ) { value[point] = exp ( r8vec_dot ( dim_num, c, x+point*dim_num ) ); for ( dim = 0; dim < dim_num; dim++ ) { if ( z[dim] < x[dim+point*dim_num] ) { value[point] = 0.0; } } } inc = point_num; p32_i4 ( 'I', '#', &inc ); free ( c ); free ( z ); return value; } /******************************************************************************/ void p32_i4 ( char action, char name, int *value ) /******************************************************************************/ /* Purpose: p32_i4() sets or gets I4 parameter values for problem 32. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Input: char action, 'D' to set a parmater to its default value; 'S' to set a parameter to VALUE, 'G' to set VALUE to the parameter's value, 'I' to increment a parameter. char name, the name of the variable. '#' is the number of calls to the integrand routine. int *VALUE. * If ACTION = 'I', then VALUE is an input quantity, and is the new value to be added to NAME. * If ACTION = 'S', then VALUE is an input quantity, and is the new value to be assigned to NAME. Output: int *VALUE: * If ACTION = 'G', then VALUE is an output quantity, and is the current value of NAME. */ { static int calls = 0; if ( action == 'D' ) { if ( name == '#' || name == '*' ) { calls = 0; } } else if ( action == 'G' ) { if ( name == '#' ) { *value = calls; } else { printf ( "\n" ); printf ( "p32_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'I' ) { if ( name == '#' ) { calls = calls + *value; } else { printf ( "\n" ); printf ( "p32_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == '#' ) { calls = *value; } else { printf ( "\n" ); printf ( "p32_i4(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p32_i4(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ void p32_lim ( int dim_num, double a[], double b[] ) /******************************************************************************/ /* Purpose: p32_lim returns the integration limits for problem 32. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Input: int DIM_NUM, the dimension of the argument. Output: double A[DIM_NUM], B[DIM_NUM], the lower and upper limits of integration. Note that if A = - HUGE_VAL, the lower limit is actually negative infinity, and if B = HUGE_VAL, the upper limit is actually infinity. */ { int dim; for ( dim = 0; dim < dim_num; dim++ ) { a[dim] = 0.0; } for ( dim = 0; dim < dim_num; dim++ ) { b[dim] = 1.0; } return; } /******************************************************************************/ char *p32_name ( ) /******************************************************************************/ /* Purpose: p32_name() returns the name of problem 32. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Output: char *p32_name, the name of the problem. */ { char *name; name = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( name, "Genz #6, Discontinuous" ); return name; } /******************************************************************************/ void p32_r8vec ( char action, char name, int dim_num, double value[] ) /******************************************************************************/ /* Purpose: p32_r8vec() sets or gets R8VEC parameters for problem 32. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Input: char action, the action. 'D' sets the internal value of the object to a default value. If NAME = '*', then all variables are defaulted. 'G' means the current value of the object should be returned. 'R' means randomize the object and return its value. 'S' means the object should be set to the input VALUE. char name, the name of the parameter. 'C' is the coefficient vector. 'Z' is the base vector. int DIM_NUM, the dimension of the object. double VALUE[DIM_NUM], the value of the object. Output: double VALUE[DIM_NUM], the value of the object. */ { static double *c = NULL; int dim; static int dim_num_save = 0; static double *z = NULL; if ( dim_num_save != dim_num ) { dim_num_save = 0; if ( c ) { free ( c ); c = NULL; } if ( z ) { free ( z ); z = NULL; } } if ( dim_num_save == 0 ) { dim_num_save = dim_num; c = ( double * ) malloc ( dim_num * sizeof ( double ) ); z = ( double * ) malloc ( dim_num * sizeof ( double ) ); } if ( action == 'D' ) { if ( name == 'C' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { c[dim] = pow ( 0.5, 1.0 / ( double ) ( dim_num ) ); } } if ( name == 'Z' || name == '*' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = pow ( 0.5, 1.0 / ( double ) ( dim_num ) ); } } } else if ( action == 'G' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, c, value ); } else if ( name == 'Z' ) { r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p32_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'R' ) { if ( name == 'C' ) { for ( dim= 0; dim < dim_num; dim++ ) { c[dim] = 4.0 * ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, c, value ); } else if ( name == 'Z' ) { for ( dim = 0; dim < dim_num; dim++ ) { z[dim] = ( double ) rand ( ) / ( double ) RAND_MAX; } r8vec_copy ( dim_num, z, value ); } else { printf ( "\n" ); printf ( "p32_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else if ( action == 'S' ) { if ( name == 'C' ) { r8vec_copy ( dim_num, value, c ); } else if ( name == 'Z' ) { r8vec_copy ( dim_num, value, z ); } else { printf ( "\n" ); printf ( "p32_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized name = \"%c\"\n", name ); exit ( 1 ); } } else { printf ( "\n" ); printf ( "p32_r8VEC(): Fatal error!\n" ); printf ( " Unrecognized action = \"%c\".\n", action ); exit ( 1 ); } return; } /******************************************************************************/ char *p32_region ( ) /******************************************************************************/ /* Purpose: p32_region() returns the name of the integration region for problem 32. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Output: char *p32_region, the name of the integration region. */ { char *region; region = ( char * ) malloc ( 80 * sizeof ( char ) ); strcpy ( region, "BOX" ); return region; } /******************************************************************************/ void p32_title ( ) /******************************************************************************/ /* Purpose: p32_title prints a title for problem 32. Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt */ { printf ( "\n" ); printf ( "Problem 32\n" ); printf ( " Name: Genz #6, Discontinuous\n" ); printf ( " Region: 0 <= X(i) <= 1\n" ); printf ( " Integrand: F(X) = exp ( C(i) * X(i) ) if X <= Z, 0 otherwise.\n" ); printf ( " Parameter:\n" ); printf ( " C(1:DIM_NUM) defaults to 1/DIM_NUM.\n" ); printf ( " Z(1:DIM_NUM) defaults to 0.5.\n" ); return; } /******************************************************************************/ double r8_choose ( int n, int k ) /******************************************************************************/ /* Purpose: R8_CHOOSE computes the combinatorial coefficient C(N,K). Discussion: C(N,K) is the number of distinct combinations of K objects chosen from a set of N distinct objects. A combination is like a set, in that order does not matter. The formula is: C(N,K) = N! / ( (N-K)! * K! ) Real arithmetic is used, and C(N,K) is computed directly, via Gamma functions, rather than recursively. For example, the number of combinations of 2 things chosen from 5 is 10. Our formula is C(5,2) = ( 5 * 4 * 3 * 2 * 1 ) / ( ( 3 * 2 * 1 ) * ( 2 * 1 ) ) = 10. The actual combinations may be represented as: (1,2), (1,3), (1,4), (1,5), (2,3), (2,4), (2,5), (3,4), (3,5), (4,5). Licensing: This code is distributed under the MIT license. Modified: 02 June 2007 Author: John Burkardt Input: int N, the value of N. int K, the value of K. Output: double R8_CHOOSE, the value of C(N,K) */ { double arg; double fack; double facn; double facnmk; double value; if ( n < 0 ) { value = 0.0; } else if ( k == 0 ) { value = 1.0; } else if ( k == 1 ) { value = ( double ) ( n ); } else if ( 1 < k && k < n - 1 ) { arg = ( double ) ( n + 1 ); facn = lgamma ( arg ); arg = ( double ) ( k + 1 ); fack = lgamma ( arg ); arg = ( double ) ( n - k + 1 ); facnmk = lgamma ( arg ); value = ( double ) ( r8_nint ( exp ( facn - fack - facnmk ) ) ); } else if ( k == n - 1 ) { value = ( double ) ( n ); } else if ( k == n ) { value = 1.0; } else { value = 0.0; } return value; } /******************************************************************************/ int r8_nint ( double x ) /******************************************************************************/ /* Purpose: R8_NINT returns the integer that is nearest to a double value. Licensing: This code is distributed under the MIT license. Modified: 10 May 2003 Author: John Burkardt Input: double X, the real number. Output: int R8_NINT, the nearest integer. */ { double d; int i; i = ( int ) ( x ); d = x - i; if ( fabs ( d ) <= 0.5 ) { return i; } else if ( x < i ) { return (i-1); } else { return (i+1); } } /******************************************************************************/ double r8_sign ( double x ) /******************************************************************************/ /* Purpose: R8_SIGN returns the sign of an R8. Licensing: This code is distributed under the MIT license. Modified: 18 October 2004 Author: John Burkardt Input: double X, the number whose sign is desired. Output: double R8_SIGN, the sign of X. */ { double value; if ( x < 0.0 ) { value = -1.0; } else { value = 1.0; } return value; } /******************************************************************************/ double r8_tiny ( ) /******************************************************************************/ /* Purpose: R8_TINY returns a "tiny" R8. Licensing: This code is distributed under the MIT license. Modified: 08 March 2007 Author: John Burkardt Output: float R8_TINY, a "tiny" R8 value. */ { float value; value = 0.4450147717014E-307; return value; } /******************************************************************************/ void r8vec_copy ( int n, double a1[], double a2[] ) /******************************************************************************/ /* Purpose: R8VEC_COPY copies an R8VEC. Licensing: This code is distributed under the MIT license. Modified: 03 July 2005 Author: John Burkardt Input: int N, the number of entries in the vectors. double A1[N], the vector to be copied. double A2[N], the copy of A1. */ { int i; for ( i = 0; i < n; i++ ) { a2[i] = a1[i]; } return; } /******************************************************************************/ double r8vec_dot ( int n, double a1[], double a2[] ) /******************************************************************************/ /* Purpose: R8VEC_DOT computes the dot product of a pair of R8VEC's. Licensing: This code is distributed under the MIT license. Modified: 03 July 2005 Author: John Burkardt Input: int N, the number of entries in the vectors. double A1[N], A2[N], the two vectors to be considered. Output: double R8VEC_DOT, the dot product of the vectors. */ { int i; double value; value = 0.0; for ( i = 0; i < n; i++ ) { value = value + a1[i] * a2[i]; } return value; } /******************************************************************************/ void r8vec_print ( int n, double a[], char *title ) /******************************************************************************/ /* Purpose: R8VEC_PRINT prints an R8VEC Licensing: This code is distributed under the MIT license. Modified: 29 May 2003 Author: John Burkardt Input: int N, the number of components of the vector. double A[N], the vector to be printed. char *TITLE, a title to be printed first. TITLE may be blank. */ { int i; if ( s_len_trim ( title ) != 0 ) { printf ( "\n" ); printf ( "%s\n", title ); } printf ( "\n" ); for ( i = 0; i <= n - 1; i++ ) { printf ( " %8d %12g\n", i, a[i] ); } return; } /******************************************************************************/ double r8vec_product ( int n, double a[] ) /******************************************************************************/ /* Purpose: R8VEC_PRODUCT returns the product of the entries of an R8VEC. Licensing: This code is distributed under the MIT license. Modified: 17 September 2003 Author: John Burkardt Input: int N, the number of entries in the vector. double A[N], the vector. Output: double R8VEC_PRODUCT, the product of the vector. */ { int i; double product; product = 1.0; for ( i = 0; i < n; i++ ) { product = product * a[i]; } return product; } /******************************************************************************/ double r8vec_sum ( int n, double a[] ) /******************************************************************************/ /* Purpose: R8VEC_SUM returns the sum of an R8VEC. Licensing: This code is distributed under the MIT license. Modified: 15 October 2004 Author: John Burkardt Input: int N, the number of entries in the vector. double A[N], the vector. Output: double R8VEC_SUM, the sum of the vector. */ { int i; double sum; sum = 0.0; for ( i = 0; i < n; i++ ) { sum = sum + a[i]; } return sum; } /******************************************************************************/ double *r8vec_uniform_01 ( int n, int *seed ) /******************************************************************************/ /* Purpose: R8VEC_UNIFORM_01 returns a unit pseudorandom R8VEC. Discussion: This routine implements the recursion seed = ( 16807 * seed ) mod ( 2^31 - 1 ) u = 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: 19 August 2004 Author: John Burkardt Reference: Paul Bratley, Bennett Fox, Linus Schrage, A Guide to Simulation, Second Edition, Springer, 1987, ISBN: 0387964673, LC: QA76.9.C65.B73. Bennett Fox, Algorithm 647: Implementation and Relative Efficiency of Quasirandom Sequence Generators, ACM Transactions on Mathematical Software, Volume 12, Number 4, December 1986, pages 362-376. Pierre L'Ecuyer, Random Number Generation, in Handbook of Simulation, edited by Jerry Banks, Wiley, 1998, ISBN: 0471134031, LC: T57.62.H37. Peter Lewis, Allen Goodman, James Miller, A Pseudo-Random Number Generator for the System/360, IBM Systems Journal, Volume 8, Number 2, 1969, pages 136-143. Input: int N, the number of entries in the vector. int *SEED, a seed for the random number generator. Output: int *SEED, the updated seed. double R8VEC_UNIFORM_01[N], the vector of pseudorandom values. */ { int i; int i4_huge = 2147483647; int k; double *r; if ( *seed == 0 ) { printf ( "\n" ); printf ( "R8VEC_UNIFORM_01(): Fatal error!\n" ); printf ( " Input value of SEED = 0.\n" ); exit ( 1 ); } r = ( double * ) malloc ( n * sizeof ( double ) ); for ( i = 0; i < n; i++ ) { k = *seed / 127773; *seed = 16807 * ( *seed - k * 127773 ) - k * 2836; if ( *seed < 0 ) { *seed = *seed + i4_huge; } r[i] = ( double ) ( *seed ) * 4.656612875E-10; } return r; } /******************************************************************************/ int s_eqi ( char *s1, char *s2 ) /******************************************************************************/ /* Purpose: S_EQI reports whether two strings are equal, ignoring case. Licensing: This code is distributed under the MIT license. Modified: 03 June 2008 Author: John Burkardt Input: char *S1, char *S2, pointers to two strings. Output: int S_EQI, is true if the strings are equal. */ { int i; int nchar; int nchar1; int nchar2; nchar1 = strlen ( s1 ); nchar2 = strlen ( s2 ); if ( nchar1 < nchar2 ) { nchar = nchar1; } else { nchar = nchar2; } /* The strings are not equal if they differ over their common length. */ for ( i = 0; i < nchar; i++ ) { if ( ch_cap ( s1[i] ) != ch_cap ( s2[i] ) ) { return 0; } } /* The strings are not equal if the longer one includes nonblanks in the tail. */ if ( nchar < nchar1 ) { for ( i = nchar; i < nchar1; i++ ) { if ( s1[i] != ' ' ) { return 0; } } } else if ( nchar < nchar2 ) { for ( i = nchar; i < nchar2; i++ ) { if ( s2[i] != ' ' ) { return 0; } } } return 1; } /******************************************************************************/ int s_len_trim ( char *s ) /******************************************************************************/ /* Purpose: s_len_trim() returns the length of a string to the last nonblank. Discussion: It turns out that I also want to ignore the '\n' character! Licensing: This code is distributed under the MIT license. Modified: 05 October 2014 Author: John Burkardt Input: char *S, a pointer to a string. Output: int S_LEN_TRIM, the length of the string to the last nonblank. If S_LEN_TRIM is 0, then the string is entirely blank. */ { int n; char *t; n = strlen ( s ); t = s + strlen ( s ) - 1; while ( 0 < n ) { if ( *t != ' ' && *t != '\n' ) { return n; } t--; n--; } return n; } /******************************************************************************/ double simplex_unit_volume_nd ( int dim_num ) /******************************************************************************/ /* Purpose: SIMPLEX_UNIT_VOLUME_ND computes the volume of the unit simplex in ND. Discussion: The formula is simple: volume = 1/DIM_NUM!. Licensing: This code is distributed under the MIT license. Modified: 04 September 2003 Author: John Burkardt Input: int DIM_NUM, the dimension of the space. Output: double SIMPLEX_UNIT_VOLUME_ND, the volume of the cone. */ { int i; double volume; volume = 1.0; for ( i = 1; i <= dim_num; i++ ) { volume = volume / ( ( double ) i ); } return volume; } /******************************************************************************/ double sphere_unit_area_nd ( int dim_num ) /******************************************************************************/ /* Purpose: SPHERE_UNIT_AREA_ND computes the surface area of a unit sphere in ND. Discussion: The unit sphere in ND satisfies the equation: Sum ( 1 <= I <= DIM_NUM ) X(I) * X(I) = 1 DIM_NUM Area 2 2 * PI 3 4 * PI 4 ( 2 / 1) * PI**2 5 ( 8 / 3) * PI**2 6 ( 1 / 1) * PI**3 7 (16 / 15) * PI**3 8 ( 1 / 3) * PI**4 9 (32 / 105) * PI**4 10 ( 1 / 12) * PI**5 For the unit sphere, Area(DIM_NUM) = DIM_NUM * Volume(DIM_NUM) Sphere_Unit_Area ( DIM_NUM ) = 2 * PI**(DIM_NUM/2) / Gamma ( DIM_NUM / 2 ) Licensing: This code is distributed under the MIT license. Modified: 05 September 2003 Author: John Burkardt Input: int DIM_NUM, the dimension of the space. Output: double SPHERE_UNIT_AREA_ND, the area of the sphere. */ { double area; int i; int m; double pi = 3.141592653589793; if ( ( dim_num % 2 ) == 0 ) { m = dim_num / 2; area = 2.0 * pow ( pi, m ); for ( i = 1; i <= m-1; i++ ) { area = area / ( ( double ) i ); } } else { m = ( dim_num - 1 ) / 2; area = pow ( 2.0, dim_num ) * pow ( pi, m ); for ( i = m+1; i <= 2*m; i++ ) { area = area / ( ( double ) i ); } } return area; } /******************************************************************************/ double sphere_unit_volume_nd ( int dim_num ) /******************************************************************************/ /* Purpose: SPHERE_UNIT_VOLUME_ND computes the volume of a unit sphere in ND. Discussion: The unit sphere in ND satisfies the equation: Sum ( 1 <= I <= DIM_NUM ) X(I) * X(I) = 1 DIM_NUM Volume 1 2 2 1 * PI 3 ( 4 / 3) * PI 4 ( 1 / 2) * PI**2 5 ( 8 / 15) * PI**2 6 ( 1 / 6) * PI**3 7 (16 / 105) * PI**3 8 ( 1 / 24) * PI**4 9 (32 / 945) * PI**4 10 ( 1 / 120) * PI**5 For the unit sphere, Volume(N) = 2 * PI * Volume(N-2)/ N Licensing: This code is distributed under the MIT license. Modified: 01 September 2003 Author: John Burkardt Input: int DIM_NUM, the dimension of the space. Output: double SPHERE_UNIT_VOLUME_ND, the volume of the sphere. */ { int i; int m; double pi = 3.141592653589793; double volume; if ( dim_num % 2== 0 ) { m = dim_num / 2; volume = 1.0; for ( i = 1; i <= m; i++ ) { volume = volume * pi / ( ( double ) i ); } } else { m = ( dim_num - 1 ) / 2; volume = pow ( pi, m ) * pow ( 2.0, dim_num ); for ( i = m+1; i <= 2*m+1; i++ ) { volume = volume / ( ( double ) i ); } } return volume; } /******************************************************************************/ double sphere_volume_nd ( int dim_num, double r ) /******************************************************************************/ /* Purpose: SPHERE_VOLUME_ND computes the volume of an implicit sphere in ND. Discussion: The implicit form of a sphere in 3D is: pow ( P[0] - PC[0], 2 ) + pow ( P[1] - PC[1], 2 ) + pow ( P[2] - PC[2], 2 ) = pow ( R, 2 ) DIM_NUM Volume 2 PI * R**2 3 (4/3) * PI * R**3 4 (1/2) * PI**2 * R**4 5 (8/15) * PI**2 * R**5 6 (1/6) * PI**3 * R**6 7 (16/105) * PI**3 * R**7 Licensing: This code is distributed under the MIT license. Modified: 01 September 2003 Author: John Burkardt Input: int DIM_NUM, the dimension of the space. double R, the radius of the sphere. Output: double SPHERE_VOLUME_ND, the volume of the sphere. */ { return ( pow ( r, dim_num ) * sphere_unit_volume_nd ( dim_num ) ); } /******************************************************************************/ void tuple_next ( int m1, int m2, int n, int *rank, int x[] ) /******************************************************************************/ /* Purpose: TUPLE_NEXT computes the next element of a tuple space. Discussion: The elements are N vectors. Each entry is constrained to lie between M1 and M2. The elements are produced one at a time. The first element is (M1,M1,...,M1), the second element is (M1,M1,...,M1+1), and the last element is (M2,M2,...,M2) Intermediate elements are produced in lexicographic order. Example: N = 2, M1 = 1, M2 = 3 INPUT OUTPUT ------- ------- Rank X Rank X ---- --- ----- --- 0 * * 1 1 1 1 1 1 2 1 2 2 1 2 3 1 3 3 1 3 4 2 1 4 2 1 5 2 2 5 2 2 6 2 3 6 2 3 7 3 1 7 3 1 8 3 2 8 3 2 9 3 3 9 3 3 0 0 0 Licensing: This code is distributed under the MIT license. Modified: 29 April 2003 Author: John Burkardt Input: int M1, M2, the minimum and maximum entries. int N, the number of components. int *RANK: on first call, set RANK to 0. int X[N]: the previous tuple. Output: int *RANK: the output value of RANK will indicate the order of the element returned. When there are no more elements, RANK will be returned as 0. int X[N]: the next tuple. */ { int i; int j; if ( m2 < m1 ) { *rank = 0; return; } if ( *rank <= 0 ) { for ( i = 0; i < n; i++ ) { x[i] = m1; } *rank = 1; } else { *rank = *rank + 1; i = n - 1; for ( ; ; ) { if ( x[i] < m2 ) { x[i] = x[i] + 1; break; } x[i] = m1; if ( i == 0 ) { *rank = 0; for ( j = 0; j < n; j++ ) { x[j] = m1; } break; } i = i - 1; } } return; }