From 1c005605856d6fc7f6e303f119fdc203662f2e57 Mon Sep 17 00:00:00 2001 From: Rob Carnell Date: Sun, 26 May 2024 15:55:26 -0400 Subject: [PATCH] moved from std::vector to std::array for cases where array size is static --- .github/workflows/rhub.yaml | 8 +-- src/OACommonDefines.h | 111 ++++++++++++++++---------------- src/runif.cpp | 40 ++++++------ src/runif.h | 40 ++++++------ tests/testthat/test-randomlhs.r | 2 +- 5 files changed, 98 insertions(+), 103 deletions(-) diff --git a/.github/workflows/rhub.yaml b/.github/workflows/rhub.yaml index ced5cc9..95467cb 100644 --- a/.github/workflows/rhub.yaml +++ b/.github/workflows/rhub.yaml @@ -84,13 +84,9 @@ jobs: echo "BUILD_ARGS=--no-build-vignettes" >> $GITHUB_ENV - name: Bad CXXFLAGS for atlas if: matrix.config.label == 'atlas' + # throws a warning on non-portable compilation flags run: | - echo "CXXFLAGS=-g -O2 -Wall -pedantic -mtune=native -fexceptions -fstack-protector-strong -fstack-clash-protection -fcf-protection" >> $GITHUB_ENV - echo "CXX11FLAGS=-g -O2 -Wall -pedantic -mtune=native -fexceptions -fstack-protector-strong -fstack-clash-protection -fcf-protection" >> $GITHUB_ENV - echo "CXX14FLAGS=-g -O2 -Wall -pedantic -mtune=native -fexceptions -fstack-protector-strong -fstack-clash-protection -fcf-protection" >> $GITHUB_ENV - echo "CXX17FLAGS=-g -O2 -Wall -pedantic -mtune=native -fexceptions -fstack-protector-strong -fstack-clash-protection -fcf-protection" >> $GITHUB_ENV - echo "CXX20FLAGS=-g -O2 -Wall -pedantic -mtune=native -fexceptions -fstack-protector-strong -fstack-clash-protection -fcf-protection" >> $GITHUB_ENV - echo "CXX23FLAGS=-g -O2 -Wall -pedantic -mtune=native -fexceptions -fstack-protector-strong -fstack-clash-protection -fcf-protection" >> $GITHUB_ENV + echo "_R_CHECK_COMPILATION_FLAGS_=false" >> $GITHUB_ENV - uses: r-hub/actions/run-check@v1 with: token: ${{ secrets.RHUB_TOKEN }} diff --git a/src/OACommonDefines.h b/src/OACommonDefines.h index d8dd815..4a5a0ff 100644 --- a/src/OACommonDefines.h +++ b/src/OACommonDefines.h @@ -8,15 +8,15 @@ * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . - * + * * Reference: * @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef RCOMPILE #include @@ -99,85 +100,85 @@ namespace oacpp { /** * @page oa_main_page Orthogonal Array Library - * + * * From the original documentation by Owen: - * + * *
* From: owen@stat.stanford.edu - * - * These programs construct and manipulate orthogonal + * + * These programs construct and manipulate orthogonal * arrays. They were prepared by * - Art Owen * - Department of Statistics * - Sequoia Hall * - Stanford CA 94305 - * + * * They may be freely used and shared. This code comes * with no warranty of any kind. Use it at your own * risk. - * + * * I thank the Semiconductor Research Corporation and * the National Science Foundation for supporting this * work. - * + * * I thank Randall Tobias of SAS Inc. for many helpful * electronic discussions that lead to improvements in * these programs. *
- * + * * @tableofcontents - * + * * @section orthogonal_arrays_sec Orthogonal Arrays *
- * An orthogonal array A is a matrix of n rows, k + * An orthogonal array A is a matrix of n rows, k * columns with every element being one of q symbols * 0,...,q-1. The array has strength t if, in every n by t * submatrix, the q^t possible distinct rows, all appear * the same number of times. This number is the index - * of the array, commonly denoted lambda. Clearly, - * lambda*q^t = n. Geometrically, if one were to "plot" the + * of the array, commonly denoted lambda. Clearly, + * lambda*q^t = n. Geometrically, if one were to "plot" the * submatrix with one plotting axis for each of the t columns * and one point in t dimensional space for each row, the * result would be a grid of q^t distinct points. There would * be lambda "overstrikes" at each point of the grid. - * + * * The notation for such an array is OA( n, k, q, t ). - * + * * If n <= q^(t+1), then the n rows "should" plot as * n distinct points in every n by t+1 dimensional subarray. * When this fails to hold, the array has the "coincidence * defect". - * + * * Owen (1992,199?) describes some uses for randomized * orthogonal arrays, in numerical integration, computer * experiments and visualization of functions. Those * references contain further references to the literature, - * that provide further explanations. A strength 1 randomized + * that provide further explanations. A strength 1 randomized * orthogonal array is a Latin hypercube * sample, essentially so or exactly so, depending on * the definition used for Latin hypercube sampling. * The arrays constructed here have strength 2 or more, it * being much easier to construct arrays of strength 1. - * + * * The randomization is achieved by independent * uniform permutation of the symbols in each column. - * + * * To investigate a function f of d variables, one * has to have an array with k >= d. One may also * have a maximum value of n in mind and a minimum value * for the number q of distinct levels to investigate. - * + * * It is entirely possible that no array of strength t > 1 * is compatible with these conditions. The programs * below provide some choices to pick from, hopefully * without too much of a compromise. - * + * * The constructions used are based on published * algorithms that exploit properties of Galois fields. * Because of this the number of levels q must be * a prime power. That is q = p^r where p is prime * and r >= 1 is an integer. - * + * * The Galois field arithmetic for the prime powers is * based on tables published by Knuth and Alanen (1964) * below. The resulting fields have been tested by the @@ -185,30 +186,30 @@ namespace oacpp { * they passed. This is more a test of the accuracy of * my transcription than of the original tables. *
- * + * * @section avail_prime_sec Available Prime Powers - * + * *
* The designs given here require a prime power for - * the number of levels. They presently work for the + * the number of levels. They presently work for the * following prime powers: - * + * * All Primes * All prime powers q = p^r where p < 50 and q < 10^9 - * + * * Here are some of the smaller prime powers: - * + * * - Powers of 2: 4 8 16 32 64 128 256 512 * - Powers of 3: 9 27 81 243 729 * - Powers of 5: 25 125 625 - * - Powers of 7: 49 343 + * - Powers of 7: 49 343 * - Square of 11: 121 * - Square of 13: 169 - * + * * Here are some useful primes: - * + * * - 2,3,5,7,11,13,17,19,23,29,31,37,101,251,401 - * + * * The first row are small primes, the second row are * primes that are 1 more than a "round number". The small * primes lead to small arrays. An array with 101 levels @@ -216,19 +217,19 @@ namespace oacpp { * through 1.00. Keep in mind that a strength 2 array on * 101 levels requires 101^2 = 10201 experimental runs, * so it is only useful where large experiments are possible. - * + * * Note that some of these will require more * memory than your computer has. For example, * with a large prime like 10663, the program knows * the Galois field, but can't allocate enough * memory: - * + * * bose 10663 * - Unable to allocate 1927'th row in an integer matrix. * - Unable to allocate space for Galois field on 10663 elements. * - Construction failed for GF(10663). * - Could not construct Galois field needed for Bose design. - * + * * The smallest prime power not covered is 53^2 = 2809. * The smallest strength 2 array with 2809 symbols has * 2809^2 = 7890481 rows. Therefore the missing prime powers @@ -236,16 +237,16 @@ namespace oacpp { * small ones of most practical use. In any event there * are some large primes and prime powers in the program * if an enormous array is needed. - * + * * To add GF(p^r) for some new prime power p^r, * consult Alanen and Knuth for instructions on how * to search for an appropriate indexing polynomial, * and for how to translate that polynomial into a - * replacement rule for x^r. + * replacement rule for x^r. *
- * + * * @section methods Methods - * + * *
    *
  • @ref oacpp::COrthogonalArray::bose
  • *
  • @ref oacpp::COrthogonalArray::bush
  • @@ -264,9 +265,9 @@ namespace oacpp { *
  • @ref oacpp::COrthogonalArray::oaagree
  • *
  • @ref oacpp::COrthogonalArray::oadimen
  • *
- * + * * @section tips Tips On Use - * + * *
* It is faster to generate only the columns you need. * For example @@ -275,11 +276,11 @@ namespace oacpp { * bose 101 * generates 102 columns. If you only want 4 columns the * former saves a lot of time. - * + * * Passing the q n k on the command line is more difficult * than letting the computer figure them out, but it * allows more error checking. - * + * * In practical use, I would try first to use a Bose * design. Then I would consider either an Addelman- * Kempthorne or Bose-Bush design to see whether it @@ -289,9 +290,9 @@ namespace oacpp { * large number of runs is possible a Bush design may * work well, since it can have high strength. *
- * + * * @section references References - * + * *
* Here are the references for the constructions used: *
    @@ -303,7 +304,7 @@ namespace oacpp { *
* This book provides a large list of orthogonal array constructions: *
  • Aloke Dey (1985) "Orthogonal Fractional Factorial Designs" Halstead Press
- * + * * These papers discuss randomized orthogonal arrays, the second * is being revised in parallel with development of the software * described here: @@ -320,9 +321,9 @@ namespace oacpp { *
  • M. Stein (1987) Technometrics 29, 143-151
  • * *
    - * + * * @section implement Implementation Details - * + * *
    * Galois fields are implemented through arrays that * store their addition and multiplication tables. Some @@ -333,15 +334,15 @@ namespace oacpp { * was not considered to be a burden. Subtraction and * division are implemented through vectors of additive * and multiplicative inverses, derived from the tables. - * The tables for GF(p^r) are constructed using a + * The tables for GF(p^r) are constructed using a * representation of the field elements as polynomials in x * with coefficients as integers modulo p and a special * rule (derived from minimal polynomials) for handling * products involving x^r. These rules are taken from * published references. The rules have not all - * been checked for accuracy, because some of the fields are + * been checked for accuracy, because some of the fields are * very large (e.g. 16807 elements). - * + * * The functions that manipulate orthogonal arrays * keep the arrays in integer matrices. This might be * a problem for applications that require enormous @@ -355,11 +356,11 @@ namespace oacpp { * row by row, so it is not too hard to change the program * to place the elements on an output stream as they * are computed and do away with the storage. - * + * * The functions that test the strength of the * arrays may be very far from optimally fast. *
    - * + * * @section compile_oa Compiling oalib * When compiling oalib these preprocessor directives are used: * - NDEBUG defined for a release build diff --git a/src/runif.cpp b/src/runif.cpp index dc72b08..022b98e 100644 --- a/src/runif.cpp +++ b/src/runif.cpp @@ -2,26 +2,26 @@ * @file runif.cpp * @author Robert Carnell * @copyright Copyright (c) 2013, Robert Carnell - * + * * License: This file may be freely used and shared according to the original license. - * + * * Reference: * - * + * * Original Header: *
    * These programs construct and manipulate orthogonal arrays. They were prepared by - * + * * - Art Owen * - Department of Statistics * - Sequoia Hall * - Stanford CA 94305 - * - * They may be freely used and shared. This code comes + * + * They may be freely used and shared. This code comes * with no warranty of any kind. Use it at your own * risk. - * + * * I thank the Semiconductor Research Corporation and * the National Science Foundation for supporting this * work. @@ -32,24 +32,22 @@ namespace oacpp { - RUnif::RUnif() : RUnif(1, 2, 3, 4) - { - } + RUnif::RUnif() : RUnif(1, 2, 3, 4) + { + } + + RUnif::RUnif(int is, int js, int ks, int ls) + { + m_jent = m_i = m_j = m_k = m_l = ip = jp = 0; + c = cd = cm = 0.0; + RUnif::seed(is, js, ks, ls); + } - RUnif::RUnif(int is, int js, int ks, int ls) - { - m_jent = m_i = m_j = m_k = m_l = ip = jp = 0; - c = cd = cm = 0.0; - u = std::vector(SEED_VECTOR_LENGTH); - u.assign(SEED_VECTOR_LENGTH, 0.0); - RUnif::seed(is, js, ks, ls); - } - void RUnif::seed(SeedSet & seedSet) { RUnif::seed(seedSet.is, seedSet.js, seedSet.ks, seedSet.ls); } - + int RUnif::mod(int a, int b) { int ans; @@ -98,7 +96,7 @@ namespace oacpp ostringstream_runtime_error(msg); } } - + SeedSet RUnif::getSeedSet() { SeedSet s = SeedSet(); diff --git a/src/runif.h b/src/runif.h index b73a42f..772954b 100644 --- a/src/runif.h +++ b/src/runif.h @@ -2,26 +2,26 @@ * @file runif.h * @author Robert Carnell * @copyright Copyright (c) 2013, Robert Carnell - * + * * License: This file may be freely used and shared according to the original license. - * + * * Reference: * - * + * * Original Header: *
    * These programs construct and manipulate orthogonal arrays. They were prepared by - * + * * - Art Owen * - Department of Statistics * - Sequoia Hall * - Stanford CA 94305 - * - * They may be freely used and shared. This code comes + * + * They may be freely used and shared. This code comes * with no warranty of any kind. Use it at your own * risk. - * + * * I thank the Semiconductor Research Corporation and * the National Science Foundation for supporting this * work. @@ -41,14 +41,14 @@ */ #define SEEDBAD 0 /** - * Macro to set the length of the seed vector + * Macro to set the length of the seed vector (97 + 1 since max location is 97 (ip)) */ -#define SEED_VECTOR_LENGTH (97+1) +#define SEED_VECTOR_LENGTH 98 -namespace oacpp +namespace oacpp { /** - * A set of seed variables for the random number generator + * A set of seed variables for the random number generator */ struct SeedSet { @@ -68,11 +68,11 @@ namespace oacpp /** * Marsaglia - Zaman universal random number generator. - * + * * reinitialization: call seed(is,js,ks,ls), with integer arguments - * from 1 to 168, not all 1. + * from 1 to 168, not all 1. * generate n uniform random numbers and store in x(n): call ranums(x,n). - * + * * Transliterated from FORTRAN to C by Art Owen, 4 March 1993. */ class RUnif @@ -82,9 +82,9 @@ namespace oacpp RUnif(); /** Constructor with individual seeds */ RUnif(int is, int js, int ks, int ls); - + ~RUnif() {}; - + /** * sets seed integers, rejects invalid input * @param is seed @@ -93,13 +93,13 @@ namespace oacpp * @param ls seed */ void seed(int is, int js, int ks, int ls ); - + /** * Set the seeds to equal the numbers in the seedSet * @param seedSet a set of four seeds */ void seed(SeedSet & seedSet); - + /** * Get the seed set * @return the SeedSet struct containing the seeds @@ -131,7 +131,7 @@ namespace oacpp * @return 1 if seeds ok, 0 otherwise */ static int seedok(int is, int js, int ks, int ls ); - + /** * sets z[0] through z[n-1] to the next n random uniforms between 0 and 1 * @param x double vector @@ -140,7 +140,7 @@ namespace oacpp void ranums(std::vector & x, int n); int m_jent, m_i, m_j, m_k, m_l, ip, jp; - std::vector u; + std::array u; double c, cd, cm; }; } diff --git a/tests/testthat/test-randomlhs.r b/tests/testthat/test-randomlhs.r index f1b9f73..6f7fddb 100644 --- a/tests/testthat/test-randomlhs.r +++ b/tests/testthat/test-randomlhs.r @@ -74,7 +74,7 @@ test_that("degenerate LHS problem is fixed", { }) # in version 1.0.1 and prior, this did not necessarily cause a segfault -# in all attempts. It was a relatively random occurence +# in all attempts. It was a relatively random occurrence test_that("Segfault does not occur with gctorture", { for (i in 1:20) {