Learning Objectives

Basic Differences with R

Hello World

Declaration and Scalar Types

Assertions

Useful Math Functions for Scalars

<cmath> from std

  • double std::min(double a, double b): Minimum of two objects (usually scalars) of same type.

  • double std::max(double a, double b): Maximum of two objects (usually scalars) of same type.

  • double std::ceil(double x): Round a double up.

  • double double std::floor(double x): Round a double down.

  • double std::trunc(double x): Round a double closer to zero. So negative numbers up and positive numbers down.

  • double std::round(double x): Rounds double to nearest integer. Returns a double.

  • double std::abs(double x): Absolute value of a double or int.

  • double std::sqrt(double x): Computes \(\sqrt{x}\)

  • double std::exp(double x): Computes \(e^x\).

  • double std::exp2(double x): Computes \(2^x\)

  • double std::pow(double x, double y): Computes \(x^y\).

  • double std::log(double x), double std::log10(double x), double std::log2(double x), logs a double with base \(e\), \(10\), or \(2\) (respectively).

  • double std::lgamma(double arg): Computes natural log of the gamma function. Note that std::lgamma(x) is \(\log[(x-1)!]\) for any integer \(x\), so this can be used to calculate log-factorials.

<Rmath> from R

Math Functions

  • double R::beta(double a, double b): Compute the beta function

  • double R::lbeta(double a, double b): Compute the log of the beta function

  • double R::choose(double n, double k): Compute the combination, \(\binom{n}{k}\)

  • double R::lchoose(double n, double k): Compute the log of the combination, \(\log\left[\binom{n}{k}\right]\).

Distributions

  • There are many distributions available from <Rmath>, each is parameterized in standard ways (read about them in Wikipedia).

  • Functions that begin with d return the density (for continuous distributions) or the probability mass (for discrete distributions).

  • Functions that begin with p return the probability for being less than or equal to some value. This is called the cumulative distribution function.

  • Functions that begin with q return the quantile. That is, you tell me a probability and I will tell you the value such that the probability of being less than that value is the provided probability.

  • Functions that begin with r provide random draws from a given distribution.

  • The common arguments between functions are:

    • x an observation of that distribution.
    • p a probability.
    • lt: lt = 0 means that p is the upper tail probability while lt = 1 means that p is the lower tail probability.
    • lg: lg = 0 means that p is the probability while lg = 1 means that lg is the log-probability.
  • Below are the most common distributions.

  • Normal Distribution with mean and standard deviation (not variance).

    • In Wikipedia: mu = \(\mu\), sigma = \(\sigma\).

    C++

    double R::dnorm(double x, double mu, double sigma, int lg)              
    double R::pnorm(double x, double mu, double sigma, int lt, int lg)      
    double R::qnorm(double p, double mu, double sigma, int lt, int lg)      
    double R::rnorm(double mu, double sigma)
  • Gamma Distribution with shape and scale parameters.

    • In Wikipedia: shp = \(k\), scl = \(\theta\).

    C++

    double R::dgamma(double x, double shp, double scl, int lg)     
    double R::pgamma(double x, double alp, double scl, int lt, int lg)
    double R::qgamma(double p, double alp, double scl, int lt, int lg)
    double R::rgamma(double a, double scl)
  • Beta Distribution with left and right shape parameters.

    • In Wikipedia: a = \(\alpha\), b = \(\beta\).

    C++

    double R::dbeta(double x, double a, double b, int lg)         
    double R::pbeta(double x, double p, double q, int lt, int lg)
    double R::qbeta(double a, double p, double q, int lt, int lg)
    double R::rbeta(double a, double b)   
  • Chi-squared Distribution.

    • In Wikipedia: df = \(k\).

    C++

    double R::dchisq(double x, double df, int lg)          
    double R::pchisq(double x, double df, int lt, int lg)  
    double R::qchisq(double p, double df, int lt, int lg)  
    double R::rchisq(double df)   
  • \(F\)-distribution with numerator and denominator degrees of freedom.

    • In Wikipedia: df1 = \(d_1\), df2 = \(d_2\).

    C++

    double R::df(double x, double df1, double df2, int lg)      
    double R::pf(double x, double df1, double df2, int lt, int lg)
    double R::qf(double p, double df1, double df2, int lt, int lg)
    double R::rf(double df1, double df2)                
  • \(t\)-distribution with degrees of freedom.

    • In Wikipedia: n = \(\nu\).

    C++

    double R::dt(double x, double n, int lg)            
    double R::pt(double x, double n, int lt, int lg)        
    double R::qt(double p, double n, int lt, int lg)        
    double R::rt(double n)                      
  • Binomial Distribution with size and success probability parameters.

    • In Wikipedia: n = \(n\), p = \(p\)

    C++

    double R::dbinom(double x, double n, double p, int lg)      
    double R::pbinom(double x, double n, double p, int lt, int lg)  
    double R::qbinom(double p, double n, double m, int lt, int lg)  
    double R::rbinom(double n, double p)
  • Exponential Distribution with scale parameter.

    • In Wikipedia: sl = \(1 / \lambda\) (not \(\lambda\)).

    C++

    double R::dexp(double x, double sl, int lg)     
    double R::pexp(double x, double sl, int lt, int lg)
    double R::qexp(double p, double sl, int lt, int lg)
    double R::rexp(double sl)               

    C++

    // [[Rcpp::export]]
    double exp_demo() {
      return R::dexp(1, 2, 0);
    }

    R

    exp_demo() ## uses scale
    ## [1] 0.3033
    dexp(x = 1, rate = 1/2, log = FALSE) ## uses rate
    ## [1] 0.3033
  • Geometric Distribution with success probability \(p\). This uses the model formulation that counts the number of failures before a success.

    • In Wikipedia: p = \(p\).

    C++

    double R::dgeom(double x, double p, int lg)     
    double R::pgeom(double x, double p, int lt, int lg)
    double R::qgeom(double p, double pb, int lt, int lg)
    double R::rgeom(double p)               

    C++

    // [[Rcpp::export]]
    double g_demo() {
      return R::dgeom(0, 0.7, 0);
    }

    R

    g_demo() ## 70% prob of a success on the first trial, so 0 failures.
    ## [1] 0.7
  • Hypergeometric Distribution

    • In Wikipedia:
      • x = \(k\) = Number of white balls drawn.
      • r = \(K\) = number of white balls in urn.
      • b = \(N - K\) = number of black balls in urn.
      • n = \(n\) = number of balls drawn.

    C++

    double R::dhyper(double x, double r, double b, double n, int lg)
    double R::phyper(double x, double r, double b, double n, int lt, int lg)
    double R::qhyper(double p, double r, double b, double n, int lt, int lg)
    double R::rhyper(double r, double b, double n)   
  • Poisson Distribution with mean parameter.

    • In Wikipedia: lb = \(\lambda\).

    C++

    double R::dpois(double x, double lb, int lg)        
    double R::ppois(double x, double lb, int lt, int lg)
    double R::qpois(double p, double lb, int lt, int lg)
    double R::rpois(double mu)  

Exercises

  1. Write a function called square2() that squares a number, but does not use std::pow(). Which one is faster?

  2. Write a function called quadform() in C++ that prints the output (using Rcpp::Rcout) of the quadratic formula. That is \[ x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} \] It should print two numbers to the console if \(b^2 - 4ac > 0\), one number if \(b^2 - 4ac = 0\), and should print "No Solution" if \(b^2 - 4ac < 0\).

    R

    quadform(1, 2, 1)
    ## Solution: -1
    quadform(2, 2, 1)
    ## No Solution
    quadform(1, 4, 1)
    ## Solution 1: -3.73205
    ## Solution 2: -0.267949
  3. The beta function is defined in terms of gamma functions as follows \[ \mathrm{B}(x, y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x + y)} \]

    R has its own version

    R

    beta(1.5, 2.2)
    ## [1] 0.2341

    Use just std::lgamma() and std::exp() to write your own beta function, called beta2(). You should include an argument lg which is a flag for returning either the log-beta or the beta. lg should default to false. E.g.

    R

    beta2(1.5, 2.2)
    ## [1] 0.2341
    beta2(1.5, 2.2, TRUE)
    ## [1] -1.452
  4. Instead of shape and scale, some parameterizations of the gamma distribution use shape and rate (1 over the scale). stats::dgamma() implements both of these in R, but R::dgamma() in C++ only implements the scale parameterization. Implement a density function for the gamma that uses shape and rate parameterization. E.g.

    R

    dgamma_r(x = 1, shp = 2, rt = 3, lg = 0)
    ## [1] 0.4481
    dgamma(x = 1, shape = 2, rate = 3, log = FALSE)
    ## [1] 0.4481

National Science Foundation Logo American University Logo Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.