From 34a099b5c4900cb64fec4d921b65dee1045c4dc1 Mon Sep 17 00:00:00 2001 From: James J Balamuta Date: Thu, 31 Jan 2019 10:28:00 -0600 Subject: [PATCH] Address CRAN checks related to Solaris (close #13) (#14) * Add ORCiD for Aaron... * Rebuilt package docs w/ ORCID * Address ambiguous calls to `std::pow()` per * Spacing. * Run formatting on C++ --- DESCRIPTION | 6 +- NEWS.md | 3 +- inst/CITATION | 2 +- man/simcdm-package.Rd | 2 +- src/sim_dina.cpp | 44 +++++----- src/sim_rrum.cpp | 4 +- src/utilities.cpp | 194 +++++++++++++++++++++++------------------- 7 files changed, 137 insertions(+), 118 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 9589d51..2f22f47 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -5,7 +5,8 @@ Version: 0.1.0 Authors@R: c(person("James Joseph", "Balamuta", email = "balamut2@illinois.edu", role = c("aut", "cre", "cph"), - comment = c(ORCID = "0000-0003-2826-8458")), + comment = c(ORCID = "0000-0003-2826-8458") + ), person("Steven Andrew", "Culpepper", email = "sculpepp@illinois.edu", role = c("aut", "cph"), @@ -13,7 +14,8 @@ Authors@R: c(person("James Joseph", "Balamuta", ), person("Aaron", "Hudson", email = "awhudson@uw.edu", - role = c("ctb", "cph") + role = c("ctb", "cph"), + comment = c(ORCID = "0000-0002-9731-2224") ) ) Description: Provides efficient R and 'C++' routines to simulate cognitive diagnostic diff --git a/NEWS.md b/NEWS.md index 9eee5f2..1aa170f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,10 +3,11 @@ ## Changes - Renamed `sim_attribute_classes()` to `attribute_classes()`. +- Addressed ambiguous calls to `std::pow(, )` ## Documentation -- Added a CITATION file for the package +- Added a `CITATION` file for the package - Improved Vignette Examples - Improved README contents diff --git a/inst/CITATION b/inst/CITATION index e0b51af..821fc72 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -8,7 +8,7 @@ citEntry(entry = "Manual", as.person("Aaron Hudson") ), year = 2019, - textVersion = paste("Balamuta, J.J., Culpepper, S.A., and Hudson A. (2019)", + textVersion = paste("Balamuta, J. J., Culpepper, S. A., and Hudson A. (2019)", "simcdm: Simulate Cognitive Diagnostic Model (CDM) Data.", "URL https://cran.r-project.org/package=simcdm.") ) \ No newline at end of file diff --git a/man/simcdm-package.Rd b/man/simcdm-package.Rd index 98d6871..033d90d 100644 --- a/man/simcdm-package.Rd +++ b/man/simcdm-package.Rd @@ -31,7 +31,7 @@ Authors: Other contributors: \itemize{ - \item Aaron Hudson \email{awhudson@uw.edu} [contributor, copyright holder] + \item Aaron Hudson \email{awhudson@uw.edu} (0000-0002-9731-2224) [contributor, copyright holder] } } diff --git a/src/sim_dina.cpp b/src/sim_dina.cpp index 52737ec..52d7205 100644 --- a/src/sim_dina.cpp +++ b/src/sim_dina.cpp @@ -17,15 +17,15 @@ //' the probability of an incorrect response for individuals with //' all of the required attributes //' -//' @return +//' @return //' A dichotomous item matrix with dimensions \eqn{N \times J}{N x J}. -//' -//' @author +//' +//' @author //' Steven Andrew Culpepper and James Joseph Balamuta -//' -//' @seealso +//' +//' @seealso //' [simcdm::sim_dina_attributes()] and [simcdm::sim_dina_items()] -//' +//' //' @export //' @template sim-dina-class-example // [[Rcpp::export]] @@ -50,19 +50,19 @@ arma::mat sim_dina_class(unsigned int N, unsigned int J, const arma::vec &CLASS, //' //' Generates a DINA model's \eqn{\eta} matrix based on alphas and //' the \eqn{\mathbf{Q}} matrix. -//' +//' //' @inheritParams sim_dina_items //' -//' @return +//' @return //' The \eqn{\eta} `matrix` with dimensions \eqn{N \times J}{N x J} under //' the DINA model. -//' -//' @author +//' +//' @author //' Steven Andrew Culpepper and James Joseph Balamuta -//' -//' @seealso +//' +//' @seealso //' [simcdm::sim_dina_class()] and [simcdm::sim_dina_items()] -//' +//' //' @export //' @template sim-dina-example-body // [[Rcpp::export]] @@ -94,20 +94,20 @@ arma::mat sim_dina_attributes(const arma::mat &alphas, const arma::mat &Q) //' generated under DINA model. //' //' @param alphas A \eqn{N} by \eqn{K} `matrix` of latent attributes. -//' @param Q A \eqn{J} by \eqn{K} `matrix` indicating which skills are required -//' for which items. -//' @param ss A \eqn{J} `vector` of item slipping parameters. +//' @param Q A \eqn{J} by \eqn{K} `matrix` indicating which skills are +//' required for which items. +//' @param ss A \eqn{J} `vector` of item slipping parameters. //' @param gs A \eqn{J} `vector` of item guessing parameters. //' -//' @return +//' @return //' A \eqn{N} by \eqn{J} `matrix` of responses from the DINA model. -//' -//' @author +//' +//' @author //' Steven Andrew Culpepper and James Joseph Balamuta -//' -//' @seealso +//' +//' @seealso //' [simcdm::sim_dina_class()] and [simcdm::sim_dina_attributes()] -//' +//' //' @export //' @template sim-dina-example-body // [[Rcpp::export]] diff --git a/src/sim_rrum.cpp b/src/sim_rrum.cpp index 87a279e..e7ceb5e 100644 --- a/src/sim_rrum.cpp +++ b/src/sim_rrum.cpp @@ -67,9 +67,9 @@ arma::mat sim_rrum_main(const arma::mat &Q, const arma::mat &rstar, //' @return Y A `matrix` with \eqn{N} rows and \eqn{J} columns indicating //' the indviduals' responses to each of the items, where \eqn{J} //' represents the number of items. -//' @author +//' @author //' Steven Andrew Culpepper, Aaron Hudson, and James Joseph Balamuta -//' +//' //' @export //' @template rrum-example //' @template rrum-references diff --git a/src/utilities.cpp b/src/utilities.cpp index c874c24..2e8e6cc 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -7,18 +7,18 @@ //' //' Computes the powers of 2 from \eqn{0} up to \eqn{K - 1} for //' \eqn{K}-dimensional attribute pattern. -//' +//' //' @param K Number of Attributes. -//' -//' @return +//' +//' @return //' A \code{vec} with length \eqn{K} detailing the power's of 2. -//' -//' @author +//' +//' @author //' Steven Andrew Culpepper and James Joseph Balamuta -//' -//' @seealso +//' +//' @seealso //' [simcdm::attribute_inv_bijection()] -//' +//' //' @export //' @examples //' ## Construct an attribute bijection ---- @@ -28,7 +28,7 @@ arma::vec attribute_bijection(unsigned int K) { arma::vec vv(K); for (unsigned int i = 0; i < K; ++i) { - vv(i) = pow(2, K - i - 1); + vv(i) = std::pow(2.0, static_cast(K - i) - 1.0); } return vv; } @@ -40,17 +40,17 @@ arma::vec attribute_bijection(unsigned int K) //' //' @param CL An `integer` between \eqn{0} and \eqn{2^{K-1}} //' @inheritParams attribute_bijection -//' -//' @return +//' +//' @return //' A \eqn{K}-dimensional vector with an attribute pattern corresponding //' to `CL`. -//' -//' @author +//' +//' @author //' Steven Andrew Culpepper and James Joseph Balamuta -//' -//' @seealso +//' +//' @seealso //' [simcdm::attribute_bijection()] -//' +//' //' @export //' @examples //' ## Construct an attribute inversion bijection ---- @@ -62,7 +62,7 @@ arma::vec attribute_inv_bijection(unsigned int K, double CL) arma::vec alpha(K); for (unsigned int k = 0; k < K; ++k) { - double twopow = pow(2, K - k - 1); + double twopow = std::pow(2.0, static_cast(K - k) - 1.0); alpha(k) = (twopow <= CL); CL = CL - twopow * alpha(k); } @@ -78,22 +78,22 @@ arma::vec attribute_inv_bijection(unsigned int K, double CL) //' @param J Number of Items //' @param K Number of Attributes //' -//' @return +//' @return //' A dichotomous \code{matrix} for Q. -//' -//' @author +//' +//' @author //' Steven Andrew Culpepper and James Joseph Balamuta -//' -//' @seealso +//' +//' @seealso //' [simcdm::attribute_bijection()] and [simcdm::attribute_inv_bijection()] -//' +//' //' @export //' @examples //' ## Simulate identifiable Q matrices ---- -//' +//' //' # 7 items and 2 attributes //' q_matrix_j7_k2 = sim_q_matrix(7, 2) -//' +//' //' # 10 items and 3 attributes //' q_matrix_j10_k3 = sim_q_matrix(10, 3) // [[Rcpp::export]] @@ -103,9 +103,10 @@ arma::mat sim_q_matrix(unsigned int J, unsigned int K) if (J < 3 * K - 1) { Rcpp::stop("J must be greater than 3*K."); } - + // Calculate number of classes - unsigned int nClass = pow(2, K); + unsigned int nClass = + static_cast(std::pow(2.0, static_cast(K))); // Form a Bijection arma::vec vv = attribute_bijection(K); @@ -141,21 +142,21 @@ arma::mat sim_q_matrix(unsigned int J, unsigned int K) //' @param K Number of Attribute Levels //' @param J Number of Assessment Items //' @param Q Q Matrix with dimensions \eqn{K \times J}{K x J}. -//' -//' @return +//' +//' @return //' A `mat` with dimensions \eqn{J \times 2^K}{J x 2^K}. -//' -//' @author +//' +//' @author //' Steven Andrew Culpepper and James Joseph Balamuta -//' -//' @seealso +//' +//' @seealso //' [simcdm::sim_q_matrix()], [simcdm::attribute_bijection()], and //' [simcdm::attribute_inv_bijection()] -//' +//' //' @export //' @examples //' ## Simulation Settings ---- -//' +//' //' # Fixed Number of Assessment Items for Q //' J = 18 //' @@ -163,7 +164,7 @@ arma::mat sim_q_matrix(unsigned int J, unsigned int K) //' K = 3 //' //' ## Pre-specified configuration ---- -//' +//' //' # Specify Q //' qbj = c(4, 2, 1, 4, 2, 1, 4, 2, 1, 6, 5, 3, 6, 5, 3, 7, 7, 7) //' @@ -172,21 +173,23 @@ arma::mat sim_q_matrix(unsigned int J, unsigned int K) //' for (j in seq_len(J)) { //' Q[j,] = attribute_inv_bijection(K, qbj[j]) //' } -//' +//' //' # Create an eta matrix //' ETA = sim_eta_matrix(K, J, Q) -//' +//' //' ## Random generation of Q matrix with ETA matrix ---- -//' +//' //' # Construct a random q matrix //' Q_sim = sim_q_matrix(J, K) -//' +//' //' # Generate the eta matrix //' ETA_gen = sim_eta_matrix(K, J, Q_sim) // [[Rcpp::export]] arma::mat sim_eta_matrix(unsigned int K, unsigned int J, const arma::mat &Q) { - double nClass = pow(2, K); + // Calculate number of classes + unsigned int nClass = + static_cast(std::pow(2.0, static_cast(K))); arma::mat ETA(J, nClass); @@ -204,122 +207,135 @@ arma::mat sim_eta_matrix(unsigned int K, unsigned int J, const arma::mat &Q) return ETA; } -//' Simulate all the Latent Attribute Profile \eqn{\mathbf{\alpha}_c} in Matrix form +//' Simulate all the Latent Attribute Profile \eqn{\mathbf{\alpha}_c} in Matrix +//form //' -//' Generate the \eqn{\mathbf{\alpha}_c = (\alpha_{c1}, \ldots, \alpha_{cK})'} -//' attribute profile matrix for members of class \eqn{c} such that \eqn{\alpha_{ck}} -//' is 1 if members of class \eqn{c} possess skill \eqn{k} and zero otherwise. +//' Generate the \eqn{\mathbf{\alpha}_c = (\alpha_{c1}, \ldots, \alpha_{cK})'} +//' attribute profile matrix for members of class \eqn{c} such that +//\eqn{\alpha_{ck}} ' is 1 if members of class \eqn{c} possess skill \eqn{k} and +//zero otherwise. //' //' @param K Number of Attributes //' -//' @return +//' @return //' A \eqn{2^K} by \eqn{K} `matrix` of latent classes -//' corresponding to entry \eqn{c} of \eqn{pi} based upon +//' corresponding to entry \eqn{c} of \eqn{pi} based upon //' mastery and nonmastery of the \eqn{K} skills. -//' -//' @author +//' +//' @author //' James Joseph Balamuta and Steven Andrew Culpepper -//' +//' //' @seealso //' [simcdm::sim_subject_attributes()] and [simcdm::attribute_inv_bijection()] -//' +//' //' @export //' @examples //' ## Simulate Attribute Class Matrix ---- -//' +//' //' # Define number of attributes //' K = 3 -//' +//' //' # Generate an Latent Attribute Profile (Alpha) Matrix //' alphas = attribute_classes(K) // [[Rcpp::export]] -arma::mat attribute_classes(int K) { +arma::mat attribute_classes(int K) +{ // Modified version of ETAMatrix - - double nClass = pow(2, K); + + // Calculate number of classes + unsigned int nClass = + static_cast(std::pow(2.0, static_cast(K))); + + // Create alpha matrix arma::mat alpha_matrix(nClass, K); - - for(unsigned int cc = 0; cc < nClass; cc++){ + + // Fill alpha matrix with classes under an inverse bijection + for (unsigned int cc = 0; cc < nClass; cc++) { alpha_matrix.row(cc) = attribute_inv_bijection(K, cc).t(); } - + + // Release result return alpha_matrix; } //' Simulate Subject Latent Attribute Profiles \eqn{\mathbf{\alpha}_c} //' //' Generate a sample from the -//' \eqn{\mathbf{\alpha}_c = (\alpha_{c1}, \ldots, \alpha_{cK})'} -//' attribute profile matrix for members of class \eqn{c} such that \eqn{\alpha_{ck}} -//' is 1 if members of class \eqn{c} possess skill \eqn{k} and zero otherwise. +//' \eqn{\mathbf{\alpha}_c = (\alpha_{c1}, \ldots, \alpha_{cK})'} +//' attribute profile matrix for members of class \eqn{c} such that +//\eqn{\alpha_{ck}} ' is 1 if members of class \eqn{c} possess skill \eqn{k} and +//zero otherwise. //' //' @param N Number of Observations //' @param K Number of Skills -//' @param probs A `vector` of probabilities that sum to 1. -//' -//' @return +//' @param probs A `vector` of probabilities that sum to 1. +//' +//' @return //' A \eqn{N} by \eqn{K} `matrix` of latent classes -//' corresponding to entry \eqn{c} of \eqn{pi} based upon +//' corresponding to entry \eqn{c} of \eqn{pi} based upon //' mastery and nonmastery of the \eqn{K} skills. -//' -//' @author +//' +//' @author //' James Joseph Balamuta and Steven Andrew Culpepper -//' -//' @seealso +//' +//' @seealso //' [simcdm::attribute_classes()] and [simcdm::attribute_inv_bijection()] -//' +//' //' @export //' @examples //' # Define number of subjects and attributes //' N = 100 //' K = 3 -//' +//' //' # Generate a sample from the Latent Attribute Profile (Alpha) Matrix //' # By default, we sample from a uniform distribution weighting of classes. //' alphas_builtin = sim_subject_attributes(N, K) -//' +//' //' # Generate a sample using custom probabilities from the //' # Latent Attribute Profile (Alpha) Matrix //' probs = rep(1 / (2 ^ K), 2 ^ K) //' alphas_custom = sim_subject_attributes(N, K, probs) // [[Rcpp::export]] -arma::mat sim_subject_attributes(int N, int K, - Rcpp::Nullable probs = R_NilValue) { +arma::mat +sim_subject_attributes(int N, int K, + Rcpp::Nullable probs = R_NilValue) +{ // Modified version of ETAMatrix - // Compute the number of attributes - double nClass = pow(2, K); - + // Calculate number of classes + unsigned int nClass = + static_cast(std::pow(2.0, static_cast(K))); + // Nullable trick ---- arma::vec probs_; - + // Check if probs is present if (probs.isNotNull()) { - + // Retrieve probabilities (costly) probs_ = Rcpp::as(probs); - + // Verify length is okay. if (probs_.n_elem != (int)nClass) { - Rcpp::stop("`probs` must have %s elements instead of %s.", - nClass, probs_.size()); - } + Rcpp::stop("`probs` must have %s elements instead of %s.", nClass, + probs_.size()); + } } else { probs_.set_size(nClass); - probs_.fill(1.0/nClass); + probs_.fill(1.0 / nClass); } - + // --- Profile Matrix - + // Grab the attribute matrix arma::mat attributes = attribute_classes(K); // Generate indices arma::uvec idx = arma::linspace(0, nClass - 1, nClass); - + // Update index idx = Rcpp::RcppArmadillo::sample_main(idx, N, true, probs_); - + // Retrieve and return profiles return attributes.rows(idx); } \ No newline at end of file