Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Week 5 #8

Open
gvegayon opened this issue Jan 27, 2023 · 3 comments
Open

Week 5 #8

gvegayon opened this issue Jan 27, 2023 · 3 comments
Assignees

Comments

@gvegayon
Copy link
Member

gvegayon commented Jan 27, 2023

@UofUEpiBio/phs7045-2023, this week we will work on C++, specifically Rcpp. The requirements for the week are:

The slides will be posted soon. But if you are OK with going over an older version, you can download them from here.

If all is working OK, you should be able to run the following code block in R:

Rcpp::cppFunction('
int myfun(const NumericVector & x)
{
  int i = 0;
  for (auto & x_ : x)
    Rprintf("The value of x[%i] is: %.2f\\n", i++, x_);
  
  return 0;
}')

myfun(c(1, .12, 3))
#> The value of x[0] is: 1.00
#> The value of x[1] is: 0.12
#> The value of x[2] is: 3.00
#> [1] 0

Created on 2023-02-01 with reprex v2.0.2

@gvegayon gvegayon self-assigned this Jan 27, 2023
@gvegayon gvegayon changed the title Week 4 Week 5 Jan 27, 2023
@gvegayon
Copy link
Member Author

gvegayon commented Feb 7, 2023

Rcpp example in class

fibR <- function(n) {
  if (n <= 1)
    return(n)
  fibR(n - 1) + fibR(n - 2)
}

# Is it working?
c(
  fibR(0), fibR(1), fibR(2),
  fibR(3), fibR(4), fibR(5),
  fibR(6)
)

library(Rcpp)
cppFunction('
int fibCpp(int n) {

  if (n <= 1)
    return(n);
    
  return fibCpp(n - 1) + fibCpp(n - 2);

}')

bench::mark(fibR(20), fibCpp(20), relative = TRUE)

fibCpp(20)

@gvegayon
Copy link
Member Author

gvegayon commented Feb 7, 2023

Hey @UofUEpiBio/phs7045-2023 , this is the website I use for C++ reference https://en.cppreference.com/w/

SinghRavin added a commit to SinghRavin/phs7045-labs that referenced this issue Feb 9, 2023
hyejung0 added a commit to hyejung0/PHS7045-labs that referenced this issue Feb 9, 2023
EricAnto0 added a commit to EricAnto0/PHS7045-labs that referenced this issue Feb 9, 2023
@gvegayon
Copy link
Member Author

gvegayon commented Feb 9, 2023

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
List ps_match1(const NumericVector & x) {
  
  int n = static_cast<int>(x.size());
  
  IntegerVector indices(n);
  NumericVector values(n);
  
  for (int i = 0; i < n; ++i) {
    
    // Maximum value
    double cur_best = std::numeric_limits< double >::max();
    int cur_i = 0;
    
    for (int j = 0; j < n; ++j) {
      
        // We can't compare to oneself
        if (i == j)
          continue;
          
        // If it is lower, then update
        if (std::abs(x[i] - x[j]) < cur_best) {
          
          cur_best = std::abs(x[i] - x[j]);
          cur_i    = j;
          
        }
          
    }
    
    // In the end, we register the result
    indices[i] = cur_i;
    values[i]  = x[cur_i];
    
  }
  
  return List::create(
    _["match_id"] = indices + 1, // We add one to match R's indices
    _["match_x"]  = values 
  );
  
}

// [[Rcpp::export]]
List ps_match2(const NumericVector & x) {
  
  int n = static_cast<int>(x.size());
  
  IntegerVector indices(n);
  NumericVector values(n);
  
  for (int i = 0; i < n; ++i) {
    
    // Instead of allocating new memory, we can point by reference
    // (saves operations)
    double & cur_best = values[i]; 
    int    & cur_i    = indices[i];
    
    cur_best = std::numeric_limits< double >::max();
    
    cur_i = 0;
    
    for (int j = 0; j < n; ++j) {
      
      // We can't compare to oneself
      if (i == j)
        continue;
      
      // If it is lower, then update
      if (std::abs(x[i] - x[j]) < cur_best) {
        
        cur_best = std::abs(x[i] - x[j]);
        cur_i    = j;
        
      }
      
    }
    
  }
  
  for (int i = 0; i < n; ++i) 
    values[i] = x[indices[i]];
  
  return List::create(
    _["match_id"] = indices + 1, // We add one to match R's indices
    _["match_x"]  = values 
  );
  
}

// [[Rcpp::export]]
List ps_match3(const NumericVector & x) {
  
  int n = static_cast<int>(x.size());
  
  IntegerVector indices(n);
  NumericVector values(n);
  values.fill(std::numeric_limits< double >::max());
  
  for (int i = 0; i < n; ++i) {
    
    // Instead of allocating new memory, we can point by reference
    // (saves operations)
    double & cur_best = values[i]; 
    auto & cur_i    = indices[i];
    
    for (int j = 0; j < i; ++j) {
      
      // If it is lower, then update
      double d = std::abs(x[i] - x[j]);
      if (d < cur_best) {
        
        cur_best = d;
        cur_i    = j;
        
      }
      
      if (d < values[j]) {
        
        values[j] = d;
        indices[j] = i;
        
      }
      
    }
    
  }
  
  for (int i = 0; i < n; ++i) 
    values[i] = x[indices[i]];
  
  return List::create(
    _["match_id"] = indices + 1, // We add one to match R's indices
    _["match_x"]  = values 
  );
  
}


/***R
set.seed(1231)
x <- cbind(runif(5))

ps_matchR <- function(x) {
  
  match_expected <- dist(x) |> as.matrix()
  diag(match_expected) <- .Machine$integer.max
  indices <- apply(match_expected, 1, which.min)
  
  list(
    match_id = as.integer(unname(indices)),
    match_x  = x[indices]
  )
  
}

resR <- ps_matchR(x)
res1 <- ps_match1(x)
res2 <- ps_match2(x)
res3 <- ps_match3(x)

cbind(
  X     = x,
  R     = resR$match_id,
  Rcpp1 = res$match_id,
  Rcpp2 = res2$match_id,
  Rcpp3 = res3$match_id
) |> head()

# Benchmarking
x <- cbind(runif(10000))
bench::mark(
  resR = ps_matchR(x)$match_x,
  res1 = ps_match1(x)$match_x,
  res2 = ps_match2(x)$match_x,
  res3 = ps_match3(x)$match_x,
  relative = TRUE
)
*/

Daniel-K-Addo added a commit to Daniel-K-Addo/PHS7045-labs that referenced this issue Feb 9, 2023
Haojia-biostat added a commit to Haojia-biostat/PHS7045-Labs that referenced this issue Feb 10, 2023
Haojia-biostat added a commit to Haojia-biostat/PHS7045-Labs that referenced this issue Mar 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant