示例#1
0
//' @title Create a taper setup for an Eigen sparse matrix
//' @description Generate the storage information we'll need to create a sparse eigen matrix
//' @param d A \code{matrix} that is a symmetric distance matrix.
//' @param taprange A \code{double} that is used to specify the gamma.
//' @return A \code{list}
//' \itemize{
//' \item \code{n} - row/col of matrix
//' \item \code{good.dists} - distances that meet tapering requirements
//' \item \code{taps} - results of applying the taper function
//' \item \code{ja} - column index
//' \item \code{ia} - row index
//' }
//' @details This function is meant to be used to create SPAM matrices.
//' The function formats data so that it can be used with a compressed sparse column format.
//' Do not use output for Eigen matrices.
//' @examples
//' data(anom1962)
//' d = rdist_earth1(head(loc))
//' make_tapersetup_eigen(d, 20)
// [[Rcpp::export]]
Rcpp::List make_tapersetup_eigen(arma::mat d, double taprange){
  double n = d.n_rows;
  
  // Find elements that are less than taprange and return element ids.
  arma::uvec inrange_id = find(d < taprange);
  
  // Approximate how many zero entries exist per columnss
  int rescol = floor(double(inrange_id.n_elem) / n); 

  // Obtain the small distance elements
  arma::vec good_dists = d.elem(inrange_id);
  
  // Apply taper function
  arma::vec taps = wendland2_1(good_dists, taprange);
  
  // Create a row index matrix and extract out ranges
  arma::vec ja = row_arma(d).elem(inrange_id) - 1;
  
  // Create a col index matrix and extract the ranges
  arma::vec ia = col_arma(d).elem(inrange_id) - 1;
    
  // Export results as an R list object
  return Rcpp::List::create(
                          Rcpp::Named("n") = n,
                          Rcpp::Named("good.dists") = good_dists,
                          Rcpp::Named("taps") = taps,
                          Rcpp::Named("ja") = ja,
                          Rcpp::Named("ia") = ia,
                          Rcpp::Named("rescol") = rescol);
}
示例#2
0
//[[Rcpp::export]]
Rcpp::List changeNA(arma::mat X) {
  NumericVector x(X.begin(), X.end());
  int n = x.size();
  IntegerVector y = seq_len(n)-1;//(x.begin(), x.end());
  IntegerVector z = y[is_na(x)];
  if(z.size()==0){
    std::cout << "Nenhum valor faltante.\n";
    SEXP xNULL = R_NilValue;
    return Rcpp::List::create(xNULL);  
  } else{
    arma::uvec Xna = as<arma::uvec>(z);
    NumericVector bx(Xna.n_rows, 100.0);
    arma::vec b = as<arma::vec>(bx);
    X.elem(Xna) = b;
    return Rcpp::List::create(X);
  }  
}
示例#3
0
//' @title Create a taper setup for a SPAM matrix
//' @description Get the storage information we'll need to create a sparse matrix
//' @param d A \code{matrix} that is a symmetric distance matrix.
//' @param taprange A \code{double} that is used to specify the gamma.
//' @return A \code{list}
//' \itemize{
//' \item \code{n} - row/col of matrix
//' \item \code{good.dists} - distances that meet tapering requirements
//' \item \code{taps} - results of applying the taper function
//' \item \code{ja} - ordered column indices
//' \item \code{ia} -  pointer to the beginning of each row in the arrays entries and colindices
//' \item \code{index} - element position in matrix 
//' }
//' @details This function is meant to be used to create SPAM matrices.
//' Do not use output for Eigen matrices.
//' @examples
//' data(anom1962)
//' d = rdist_earth1(head(loc))
//' make_tapersetup_R(d, 20)
// [[Rcpp::export]]
Rcpp::List make_tapersetup_R(arma::mat d, double taprange){
  unsigned int n = d.n_rows;
  
  // Find elements that are less than (logical matrix e.g. 0/1's)
  arma::umat inrange = d < taprange;
  
  // Same idea, but return element ids.
  arma::uvec inrange_id = find(inrange);
  
  // Convert matrix to allow operations
  arma::mat temp = arma::conv_to<arma::mat>::from(inrange);

  // Obtain the small distance elements
  arma::vec good_dists = d.elem(inrange_id);
  
  // Apply taper function (this cannot be made dynamic)
  arma::vec taps = wendland2_1(good_dists, taprange);
  
  // Create ordered column indices of the nonzero values
  arma::vec ja = row_arma(d).elem(inrange_id);
  
  // Calculate pointer to the beginning of each row in the arrays' entries and colindices
  arma::vec ia(inrange.n_rows + 1);
  ia(0) = 1;
  ia.rows(1,inrange.n_rows) = 1 + arma::cumsum(arma::sum(temp,1));
  
  // Create a column index matrix and isolate ideal elements
  arma::vec index = (col_arma(d).elem(inrange_id) - 1) * n + ja;
  
  // Export results as an R list object
  return Rcpp::List::create(
                          Rcpp::Named("n") = n,
                          Rcpp::Named("good_dists") = good_dists,
                          Rcpp::Named("taps") = taps,
                          Rcpp::Named("ja") = ja,
                          Rcpp::Named("ia") = ia,
                          Rcpp::Named("index") = index);
}
示例#4
0
void getEystar_endorseIRT (const arma::mat &alpha,
                           const arma::mat &beta,
                           const arma::mat &w,
                           const arma::mat &theta,
                           const arma::mat &gamma,
                           const arma::mat &y,
                           const int N,
                           const int J,
                           arma::mat &ystars,
                           const arma::mat &theta2,
                           const arma::mat &w2
                           ) {
    // arma::mat ystars(N, J, arma::fill::zeros) ;

    // Main Calculation

#pragma omp parallel for
    for (int n = 0; n < N; n++) {

        arma::mat theseystars = arma::mat(1, J, arma::fill::zeros) ;

        for (int j = 0; j < J; j++) {
            // defaults to untruncated
            double low = y(n,j) == 1 ? 0.0 : R_NegInf ;
            double high = y(n,j) == 0 ? 0.0 : R_PosInf ;

            // mu

            double mu =
                alpha(j, 0) +
                beta(n, 0) -
                gamma(0, 0) * (
                               pow(theta(n, 0), 2) +
                               pow(w(j, 0), 2) -
                               2 * theta(n, 0) * w(j, 0)
                               ) ;

            double exp = etn1(mu, 1.0, low, high) ;

            double exp2 = exp ;

            // if (isinf(exp2) || isnan(exp2)) {
            //     if (low == 0.0) exp2 =   .0001 ;
            //     if (high == 0.0) exp2 = -.0001 ;
            // }


            // if (isnan(exp2)) {
            //     exp2 = 0 ;
            // }

            // if (isinf(exp)) {
            //     Rcout << n << " " << j << " " << low << " " << high << " " << mu << " " << exp << " " << exp2 << std::endl ;
            // }

            // if (isnan(exp)) {
            //     Rcout << n << " " << j << " " << low << " " << high << " " << mu << " " << exp << " " << exp2 << std::endl ;
            // }

            theseystars(0, j) = exp2 ;
        }
        ystars.row(n) = theseystars ;
    }

    arma::uvec check = find_nonfinite(ystars) ;

    if (check.n_elem > 0) {
        ystars.elem(check).print("ystar check") ;
    }

    // return(ystars) ;
}
示例#5
0
//' Map N(0,1) stochastic perturbations to an LNA path.
//'
//' @param pathmat matrix where the LNA path should be stored
//' @param draws matrix of N(0,1) draws to be mapped to an LNA path
//' @param lna_times vector of interval endpoint times
//' @param lna_pars numeric matrix of parameters, constants, and time-varying
//'   covariates at each of the lna_times
//' @param init_start index in the parameter vector where the initial compartment
//'   volumes start
//' @param param_update_inds logical vector indicating at which of the times the
//'   LNA parameters need to be updated.
//' @param stoich_matrix stoichiometry matrix giving the changes to compartments
//'   from each reaction
//' @param forcing_inds logical vector of indicating at which times in the
//'   time-varying covariance matrix a forcing is applied.
//' @param forcing_matrix matrix containing the forcings.
//' @param svd_d vector in which to store SVD singular values
//' @param svd_U matrix in which to store the U matrix of the SVD
//' @param svd_V matrix in which to store the V matrix of the SVD
//' @param step_size initial step size for the ODE solver (adapted internally,
//' but too large of an initial step can lead to failure in stiff systems).
//' @param lna_pointer external pointer to LNA integration function.
//' @param set_pars_pointer external pointer to the function for setting the LNA
//'   parameters.
//'
//' @return fill out pathmat with the LNA path corresponding to the stochastic
//'   perturbations.
//'
//' @export
// [[Rcpp::export]]
void map_draws_2_lna(arma::mat& pathmat,
                     const arma::mat& draws,
                     const arma::rowvec& lna_times,
                     const Rcpp::NumericMatrix& lna_pars,
                     Rcpp::NumericVector& lna_param_vec,
                     const Rcpp::IntegerVector& lna_param_inds,
                     const Rcpp::IntegerVector& lna_tcovar_inds,
                     const int init_start,
                     const Rcpp::LogicalVector& param_update_inds,
                     const arma::mat& stoich_matrix,
                     const Rcpp::LogicalVector& forcing_inds,
                     const arma::uvec& forcing_tcov_inds,
                     const arma::mat& forcings_out,
                     const arma::cube& forcing_transfers,
                     arma::vec& svd_d,
                     arma::mat& svd_U,
                     arma::mat& svd_V,
                     double step_size,
                     SEXP lna_pointer,
                     SEXP set_pars_pointer) {

        // get the dimensions of various objects
        int n_events = stoich_matrix.n_cols;         // number of transition events, e.g., S2I, I2R
        int n_comps  = stoich_matrix.n_rows;         // number of model compartments (all strata)
        int n_odes   = n_events + n_events*n_events; // number of ODEs
        int n_times  = lna_times.n_elem;             // number of times at which the LNA must be evaluated
        int n_tcovar = lna_tcovar_inds.size();       // number of time-varying covariates or parameters
        int n_forcings = forcing_tcov_inds.n_elem;   // number of forcings
        
        // for use with forcings
        double forcing_flow = 0;
        arma::vec forcing_distvec(n_comps, arma::fill::zeros);
        
        // initialize the objects used in each time interval
        double t_L = 0;
        double t_R = 0;

        // vector of parameters, initial compartment columes, constants, and time-varying covariates
        std::copy(lna_pars.row(0).begin(), lna_pars.row(0).end(), lna_param_vec.begin());

        CALL_SET_ODE_PARAMS(lna_param_vec, set_pars_pointer); // set the parameters in the odeintr namespace

        // initial state vector - copy elements from the current parameter vector
        arma::vec init_volumes(lna_param_vec.begin() + init_start, n_comps);

        // initialize the LNA objects
        bool good_svd = true;

        Rcpp::NumericVector lna_state_vec(n_odes); // the vector for storing the current state of the LNA ODEs

        arma::vec lna_drift(n_events, arma::fill::zeros);               // incidence mean vector (log scale)
        arma::mat lna_diffusion(n_events, n_events, arma::fill::zeros); // diffusion matrix

        arma::vec log_lna(n_events, arma::fill::zeros);  // LNA increment, log scale
        arma::vec nat_lna(n_events, arma::fill::zeros);  // LNA increment, natural scale

        // apply forcings if called for - applied after censusing at the first time
        if(forcing_inds[0]) {
              
              // distribute the forcings proportionally to the compartment counts in the applicable states
              for(int j=0; j < n_forcings; ++j) {
                    
                    forcing_flow       = lna_pars(0, forcing_tcov_inds[j]);
                    forcing_distvec    = forcing_flow * normalise(forcings_out.col(j) % init_volumes, 1);
                    init_volumes      += forcing_transfers.slice(j) * forcing_distvec;
              }
        }

        // iterate over the time sequence, solving the LNA over each interval
        for(int j=0; j < (n_times-1); ++j) {

                // set the times of the interval endpoints
                t_L = lna_times[j];
                t_R = lna_times[j+1];

                // Reset the LNA state vector and integrate the LNA ODEs over the next interval to 0
                std::fill(lna_state_vec.begin(), lna_state_vec.end(), 0.0);
                CALL_INTEGRATE_STEM_ODE(lna_state_vec, t_L, t_R, step_size, lna_pointer);

                // transfer the elements of the lna_state_vec to the process objects
                std::copy(lna_state_vec.begin(), lna_state_vec.begin() + n_events, lna_drift.begin());
                std::copy(lna_state_vec.begin() + n_events, lna_state_vec.end(), lna_diffusion.begin());

                // ensure symmetry of the diffusion matrix
                lna_diffusion = arma::symmatu(lna_diffusion);

                // map the stochastic perturbation to the LNA path on its natural scale
                try{
                        if(lna_drift.has_nan() || lna_diffusion.has_nan()) {
                                good_svd = false;
                                throw std::runtime_error("Integration failed.");
                        } else {
                                good_svd = arma::svd(svd_U, svd_d, svd_V, lna_diffusion); // compute the SVD
                        }

                        if(!good_svd) {
                                throw std::runtime_error("SVD failed.");

                        } else {
                                svd_d.elem(arma::find(svd_d < 0)).zeros();          // zero out negative sing. vals
                                svd_V.each_row() %= arma::sqrt(svd_d).t();          // multiply rows of V by sqrt(d)
                                svd_U *= svd_V.t();                                 // complete svd_sqrt
                                svd_U.elem(arma::find(lna_diffusion == 0)).zeros(); // zero out numerical errors

                                log_lna = lna_drift + svd_U * draws.col(j);         // map the LNA draws
                        }

                } catch(std::exception & err) {

                        // reinstatiate the SVD objects
                        arma::vec svd_d(n_events, arma::fill::zeros);
                        arma::mat svd_U(n_events, n_events, arma::fill::zeros);
                        arma::mat svd_V(n_events, n_events, arma::fill::zeros);

                        // forward the exception
                        forward_exception_to_r(err);

                } catch(...) {
                        ::Rf_error("c++ exception (unknown reason)");
                }

                // compute the LNA increment
                nat_lna = arma::vec(expm1(Rcpp::NumericVector(log_lna.begin(), log_lna.end())));

                // save the LNA increment
                pathmat(j+1, arma::span(1, n_events)) = nat_lna.t();

                // update the initial volumes
                init_volumes += stoich_matrix * nat_lna;

                // if any increments or volumes are negative, throw an error
                try{
                        if(any(nat_lna < 0)) {
                                throw std::runtime_error("Negative increment.");
                        }

                        if(any(init_volumes < 0)) {
                                throw std::runtime_error("Negative compartment volumes.");
                        }

                } catch(std::runtime_error &err) {

                        forward_exception_to_r(err);

                } catch(...) {
                        ::Rf_error("c++ exception (unknown reason)");
                }
                
                // apply forcings if called for - applied after censusing the path
                if(forcing_inds[j+1]) {
                      
                      // distribute the forcings proportionally to the compartment counts in the applicable states
                      for(int s=0; s < n_forcings; ++s) {
                            
                            forcing_flow       = lna_pars(j+1, forcing_tcov_inds[s]);
                            forcing_distvec    = forcing_flow * normalise(forcings_out.col(s) % init_volumes, 1);
                            init_volumes      += forcing_transfers.slice(s) * forcing_distvec;
                      }
                      
                      // throw errors for negative negative volumes
                      try{
                            if(any(init_volumes < 0)) {
                                  throw std::runtime_error("Negative compartment volumes.");
                            }
                            
                      } catch(std::exception &err) {
                            
                            forward_exception_to_r(err);
                            
                      } catch(...) {
                            ::Rf_error("c++ exception (unknown reason)");
                      }
                }

                // update the parameters if they need to be updated
                if(param_update_inds[j+1]) {
                      
                      // time-varying covariates and parameters
                      std::copy(lna_pars.row(j+1).end() - n_tcovar,
                                lna_pars.row(j+1).end(),
                                lna_param_vec.end() - n_tcovar);
                }

                // copy the new initial volumes into the vector of parameters
                std::copy(init_volumes.begin(), init_volumes.end(), lna_param_vec.begin() + init_start);

                // set the lna parameters and reset the LNA state vector
                CALL_SET_ODE_PARAMS(lna_param_vec, set_pars_pointer);
        }
}