Skip to content

Commit

Permalink
Source installed "StanHeaders", "rstan", "rstanarm" on MacOS Mojave
Browse files Browse the repository at this point in the history
  • Loading branch information
TimKDJ committed Jun 26, 2020
1 parent d517963 commit 2bf58e5
Show file tree
Hide file tree
Showing 1,880 changed files with 56,988 additions and 45,235 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ citHeader("To cite StanHeaders in publications use:")
citEntry(entry = "Misc",
title = "{StanHeaders}: Headers for the {R} interface to {Stan}",
author = person(given = "Stan Development Team"),
note = "R package version 2.19.0",
year = "2019",
note = "R package version 2.18.0",
year = "2018",
url = "http://mc-stan.org/",
textVersion =
paste("Stan Development Team (2019).",
paste("Stan Development Team (2018).",
title = "StanHeaders: Headers for the {R} interface to {Stan}.",
"http://mc-stan.org/.")
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Package: StanHeaders
Date: 2019-09-05
Date: 2020-06-09
Title: C++ Header Files for Stan
Authors@R: c(person("Ben",family="Goodrich", email="[email protected]", role=c('cre','aut')),
person("Joshua", "Pritikin", role = "ctb"),
Expand Down Expand Up @@ -29,16 +29,18 @@ Authors@R: c(person("Ben",family="Goodrich", email="[email protected]
person("The Regents of the", "University of California", role = "cph", comment = "CVODES"),
person("Southern Methodist", "University", role = "cph", comment = "CVODES"))
URL: http://mc-stan.org/
Description: The C++ header files of the Stan project are provided by this package, but it contains no R code or function documentation. There is a shared object containing part of the 'CVODES' library, but it is not accessible from R. 'StanHeaders' is only useful for developers who want to utilize the 'LinkingTo' directive of their package's DESCRIPTION file to build on the Stan library without incurring unnecessary dependencies. The Stan project develops a probabilistic programming language that implements full or approximate Bayesian statistical inference via Markov Chain Monte Carlo or 'variational' methods and implements (optionally penalized) maximum likelihood estimation via optimization. The Stan library includes an advanced automatic differentiation scheme, 'templated' statistical and linear algebra functions that can handle the automatically 'differentiable' scalar types (and doubles, 'ints', etc.), and a parser for the Stan language. The 'rstan' package provides user-facing R functions to parse, compile, test, estimate, and analyze Stan models.
Suggests: Rcpp, RcppEigen, BH, knitr (>= 1.15.1), rmarkdown, Matrix,
methods, rstan
Description: The C++ header files of the Stan project are provided by this package, but it contains little R code or documentation. The main reference is the vignette. There is a shared object containing part of the 'CVODES' library, but its functionality is not accessible from R. 'StanHeaders' is only useful for developers who want to utilize the 'LinkingTo' directive of their package's DESCRIPTION file to build on the Stan library without incurring unnecessary dependencies. The Stan project develops a probabilistic programming language that implements full or approximate Bayesian statistical inference via Markov Chain Monte Carlo or 'variational' methods and implements (optionally penalized) maximum likelihood estimation via optimization. The Stan library includes an advanced automatic differentiation scheme, 'templated' statistical and linear algebra functions that can handle the automatically 'differentiable' scalar types (and doubles, 'ints', etc.), and a parser for the Stan language. The 'rstan' package provides user-facing R functions to parse, compile, test, estimate, and analyze Stan models.
Imports: RcppParallel (>= 5.0.1)
Suggests: Rcpp, BH, knitr (>= 1.15.1), rmarkdown, Matrix, methods,
rstan
LinkingTo: RcppEigen, RcppParallel (>= 5.0.1)
VignetteBuilder: knitr
SystemRequirements: pandoc
Depends: R (>= 3.4.0)
Version: 2.19.0
Version: 2.21.0-5
License: BSD_3_clause + file LICENSE
NeedsCompilation: yes
Packaged: 2019-09-05 18:28:20 UTC; ben
Packaged: 2020-06-09 07:05:55 UTC; ben
Author: Ben Goodrich [cre, aut],
Joshua Pritikin [ctb],
Andrew Gelman [aut],
Expand Down Expand Up @@ -68,5 +70,5 @@ Author: Ben Goodrich [cre, aut],
Southern Methodist University [cph] (CVODES)
Maintainer: Ben Goodrich <[email protected]>
Repository: CRAN
Date/Publication: 2019-09-07 07:00:17 UTC
Built: R 3.6.0; x86_64-apple-darwin15.6.0; 2019-09-08 13:01:16 UTC; unix
Date/Publication: 2020-06-09 14:30:10 UTC
Built: R 3.6.1; x86_64-apple-darwin15.6.0; 2020-06-26 11:59:42 UTC; unix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CxxFlags Compilation flags for StanHeaders
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
if(.Platform$OS.type == "windows") useDynLib(StanHeaders, .registration = TRUE)

importFrom(RcppParallel, RcppParallelLibs)
#export(CxxFlags, LdFlags)
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# File share/R/nspackloader.R
# Part of the R package, http://www.R-project.org
#
# Copyright (C) 1995-2012 The R Core Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 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 General Public License for more details.
#
# A copy of the GNU General Public License is available at
# http://www.r-project.org/Licenses/

local({
info <- loadingNamespaceInfo()
pkg <- info$pkgname
ns <- .getNamespace(as.name(pkg))
if (is.null(ns))
stop("cannot find namespace environment for ", pkg, domain = NA);
dbbase <- file.path(info$libname, pkg, "R", pkg)
lazyLoad(dbbase, ns, filter = function(n) n != ".__NAMESPACE__.")
})
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,45 +1,47 @@
## ----setup, include = FALSE----------------------------------------------
## ----setup, include = FALSE---------------------------------------------------
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
Sys.setenv(USE_CXX14 = "1")
set.seed(12345)

## ------------------------------------------------------------------------
## -----------------------------------------------------------------------------
Sys.setenv(PKG_CXXFLAGS = StanHeaders:::CxxFlags(as_character = TRUE))
SH <- system.file(ifelse(.Platform$OS.type == "windows", "libs", "lib"), .Platform$r_arch,
package = "StanHeaders", mustWork = TRUE)
Sys.setenv(PKG_LIBS = paste0(StanHeaders:::LdFlags(as_character = TRUE),
" -L", shQuote(SH), " -lStanHeaders"))


## -----------------------------------------------------------------------------
x <- optim(rnorm(3), fn = f, gr = g, a = 1:3, method = "BFGS", hessian = TRUE)
x$par
x$hessian
H(x$par, a = 1:3)
J(x$par, a = 1:3)
solution(a = 1:3, guess = rnorm(3))

## ------------------------------------------------------------------------
StanHeaders_pkg_libs <- system.file(ifelse(.Platform$OS.type == "windows", "libs", "lib"),
.Platform$r_arch, package = "StanHeaders")
Sys.setenv(PKG_LIBS = paste(paste0("-L", shQuote(StanHeaders_pkg_libs)), "-lStanHeaders"))

## ------------------------------------------------------------------------
## -----------------------------------------------------------------------------
all.equal(1, Cauchy(rexp(1)), tol = 1e-15)

## ------------------------------------------------------------------------
## -----------------------------------------------------------------------------
A <- matrix(c(0, -1, 1, -runif(1)), nrow = 2, ncol = 2)
y0 <- rexp(2)
all.equal(nonstiff(A, y0), c(0, 0), tol = 1e-5)
all.equal( stiff(A, y0), c(0, 0), tol = 1e-8)

## ------------------------------------------------------------------------
Sys.setenv(PKG_CXXFLAGS = "-DSTAN_THREADS")
## -----------------------------------------------------------------------------
Sys.setenv(STAN_NUM_THREADS = 2) # specify -1 to use all available cores

## ------------------------------------------------------------------------
## -----------------------------------------------------------------------------
odd <- seq.int(from = 2^25 - 1, to = 2^26 - 1, by = 2)
tail(psapply(n = as.list(odd))) == 1 # check your process manager while this is running

## ---- echo = FALSE, comment = ""-----------------------------------------
## ---- echo = FALSE, comment = ""----------------------------------------------
cat(readLines("sparselm_stan.hpp"), sep = "\n")

## ---- message = FALSE----------------------------------------------------
## ---- message = FALSE---------------------------------------------------------
library(Rcpp)
tf <- tempfile(fileext = "Module.cpp")
exposeClass("sparselm_stan",
Expand All @@ -50,24 +52,24 @@ exposeClass("sparselm_stan",
rename = c(log_prob = "log_prob<>", gradient = "gradient<>"),
header = c("// [[Rcpp::depends(BH)]]",
"// [[Rcpp::depends(RcppEigen)]]",
"// [[Rcpp::depends(RcppParallel)]",
"// [[Rcpp::depends(StanHeaders)]]",
"// [[Rcpp::plugins(cpp14)]]",
paste0("#include <", file.path(getwd(), "sparselm_stan.hpp"), ">")),
file = tf,
Rfile = FALSE)
Sys.unsetenv("PKG_CXXFLAGS") # don't specify -DSTAN_THREADS if you are not using them
Sys.setenv(PKG_CPPFLAGS = paste0("-I",
Sys.setenv(PKG_CXXFLAGS = paste0(Sys.getenv("PKG_CXXFLAGS"), " -I",
system.file("include", "src",
package = "StanHeaders", mustWork = TRUE)))
sourceCpp(tf)
sparselm_stan

## ------------------------------------------------------------------------
## -----------------------------------------------------------------------------
dd <- data.frame(a = gl(3, 4), b = gl(4, 1, 12))
X <- Matrix::sparse.model.matrix(~ a + b, data = dd)
X

## ------------------------------------------------------------------------
## -----------------------------------------------------------------------------
sm <- new(sparselm_stan, X = X, y = rnorm(nrow(X)))
sm$log_prob(c(beta = rnorm(ncol(X)), log_sigma = log(pi)))
round(sm$gradient(c(beta = rnorm(ncol(X)), log_sigma = log(pi))), digits = 4)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,27 @@ set.seed(12345)
The **StanHeaders** package contains no R functions. To use the Stan Math Library
in other packages, it is often sufficient to specify
```
LinkingTo: StanHeaders (>= 2.19.0)
LinkingTo: StanHeaders (>= 2.21.0), RcppParallel (>= 5.0.1)
```
in the DESCRIPTION file of another package and
in the DESCRIPTION file of another package and put something like
```
CXX_STD = CXX14
PKG_CXXFLAGS = $(shell "$(R_HOME)/bin$(R_ARCH_BIN)/Rscript" -e "RcppParallel::CxxFlags()") \
$(shell "$(R_HOME)/bin$(R_ARCH_BIN)/Rscript" -e "StanHeaders:::CxxFlags()")
PKG_LIBS = $(shell "$(R_HOME)/bin$(R_ARCH_BIN)/Rscript" -e "RcppParallel::RcppParallelLibs()") \
$(shell "$(R_HOME)/bin$(R_ARCH_BIN)/Rscript" -e "StanHeaders:::LdFlags()")
```
in the src/Makevars and src/Makevars.win files. If, in addition, the other package needs to utilize
in the src/Makevars and src/Makevars.win files and put `GNU make` in the `SystemRequirements:`
field of the package's DESCRIPTION file. If, in addition, the other package needs to utilize
the MCMC, optimization, variational inference, or parsing facilities of the Stan Library, then it is
also necessary to include the `src` directory of **StanHeaders** in the other package's `PKG_CPPFLAGS`
also necessary to include the `src` directory of **StanHeaders** in the other package's `PKG_CXXFLAGS`
in the src/Makevars and src/Makevars.win files with something like
```
STANHEADERS_SRC = $(shell "$(R_HOME)/bin$(R_ARCH_BIN)/Rscript" -e "message()" \
-e "cat(system.file('include', 'src', package = 'StanHeaders', mustWork = TRUE))" \
-e "message()" | grep "StanHeaders")
PKG_CPPFLAGS = -I"$(STANHEADERS_SRC)"
PKG_CXXFLAGS += -I"$(STANHEADERS_SRC)"
```
and put `GNU make` in the `SystemRequirements:` field of the package's DESCRIPTION file. Finally,
if integrating systems of stiff Ordinary Differential Equations, then you need to link to the
shared library of StanHeaders as is shown below.

# Using Higher-Order Functions in the **StanHeaders** Package

Expand All @@ -63,17 +65,27 @@ could reconceptualize the problem as solving a homogeneous system of equations w
equal to a vector of zeros. The `stan::math::algebra_solver` function can solve such a system using
autodifferentiation to obtain the Jacobian, which we know to be the identity matrix in this case.

```{r}
Sys.setenv(PKG_CXXFLAGS = StanHeaders:::CxxFlags(as_character = TRUE))
SH <- system.file(ifelse(.Platform$OS.type == "windows", "libs", "lib"), .Platform$r_arch,
package = "StanHeaders", mustWork = TRUE)
Sys.setenv(PKG_LIBS = paste0(StanHeaders:::LdFlags(as_character = TRUE),
" -L", shQuote(SH), " -lStanHeaders"))
```

Here is C++ code that does all of the above, except for the part of finding the optimum, which is done
using the R function `optim` below.
```{Rcpp}
// [[Rcpp::depends(BH)]]
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::depends(StanHeaders)]]
#include <stan/math/fwd/mat/fun/dot_self.hpp> // stuff from fwd/ must come first
#include <stan/math/mix/mat/functor/hessian.hpp> // then stuff from mix/ must come next
#include <stan/math.hpp> // finally pull in everything from rev/ & prim/
#include <Rcpp.h>
#include <RcppEigen.h>
#include <RcppEigen.h> // do this AFTER including stan/math
// [[Rcpp::plugins(cpp14)]]
Expand Down Expand Up @@ -162,22 +174,15 @@ solution(a = 1:3, guess = rnorm(3))

The Stan Math library can do one-dimensional numerical integration and can solve stiff
and non-stiff systems of differential equations, such as the harmonic oscillator example
below. Solving stiff systems utilizes the CVODES package, which is included in **StanHeaders**,
but requires linking against its shared library with the following R code.

```{r}
StanHeaders_pkg_libs <- system.file(ifelse(.Platform$OS.type == "windows", "libs", "lib"),
.Platform$r_arch, package = "StanHeaders")
Sys.setenv(PKG_LIBS = paste(paste0("-L", shQuote(StanHeaders_pkg_libs)), "-lStanHeaders"))
```

below. Solving stiff systems utilizes the CVODES library, which is included in **StanHeaders**.
```{Rcpp}
// [[Rcpp::depends(BH)]]
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::depends(StanHeaders)]]
#include <stan/math.hpp> // pulls in everything from rev/ and prim/
#include <Rcpp.h>
#include <RcppEigen.h>
#include <RcppEigen.h> // do this AFTER including stan/math
// [[Rcpp::plugins(cpp14)]]
Expand All @@ -201,11 +206,13 @@ auto nonstiff(Eigen::MatrixXd A, Eigen::VectorXd y0) {
using stan::math::to_vector;
using stan::math::to_array_1d;
std::vector<double> theta;
std::vector<double> times = {1, 2};
auto y = integrate_ode_rk45([&A](auto t, auto y,
auto theta, auto x_r, auto x_i, std::ostream *msgs) {
return to_array_1d( (A * to_vector(y)).eval() );
}, to_array_1d(y0), 0, {1, 2}, theta, {}, {});
return (to_vector(y[0]) - stan::math::matrix_exp(A) * y0).eval();
}, to_array_1d(y0), 0, times, theta, {}, {});
Eigen::VectorXd truth = stan::math::matrix_exp(A) * y0;
return (to_vector(y[0]) - truth).eval(); // should be "zero"
}
// [[Rcpp::export]]
Expand All @@ -214,11 +221,13 @@ auto stiff(Eigen::MatrixXd A, Eigen::VectorXd y0) { // not actually stiff
using stan::math::to_vector;
using stan::math::to_array_1d;
std::vector<double> theta;
std::vector<double> times = {1, 2};
auto y = integrate_ode_bdf([&A](auto t, auto y,
auto theta, auto x_r, auto x_i, std::ostream *msgs) {
return to_array_1d( (A * to_vector(y)).eval() );
}, to_array_1d(y0), 0, {1, 2}, theta, {}, {});
return (to_vector(y[0]) - stan::math::matrix_exp(A) * y0).eval();
}, to_array_1d(y0), 0, times, theta, {}, {});
Eigen::VectorXd truth = stan::math::matrix_exp(A) * y0;
return (to_vector(y[0]) - truth).eval(); // should be "zero"
}
```

Expand Down Expand Up @@ -262,7 +271,6 @@ function. However, `map_rect` can also be executed in parallel by defining the p
directive `STAN_THREADS` and then setting the `STAN_NUM_THREADS` environmental variable to be the
number of threads to use, as in
```{r}
Sys.setenv(PKG_CXXFLAGS = "-DSTAN_THREADS")
Sys.setenv(STAN_NUM_THREADS = 2) # specify -1 to use all available cores
```

Expand All @@ -271,10 +279,11 @@ and running it in parallel via `map_rect`.
```{Rcpp}
// [[Rcpp::depends(BH)]]
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::depends(StanHeaders)]]
#include <stan/math.hpp> // pulls in everything from rev/ and prim/
#include <Rcpp.h>
#include <RcppEigen.h>
#include <RcppEigen.h> // do this AFTER including stan/math
// [[Rcpp::plugins(cpp14)]]
Expand Down Expand Up @@ -360,13 +369,13 @@ exposeClass("sparselm_stan",
rename = c(log_prob = "log_prob<>", gradient = "gradient<>"),
header = c("// [[Rcpp::depends(BH)]]",
"// [[Rcpp::depends(RcppEigen)]]",
"// [[Rcpp::depends(RcppParallel)]",
"// [[Rcpp::depends(StanHeaders)]]",
"// [[Rcpp::plugins(cpp14)]]",
paste0("#include <", file.path(getwd(), "sparselm_stan.hpp"), ">")),
file = tf,
Rfile = FALSE)
Sys.unsetenv("PKG_CXXFLAGS") # don't specify -DSTAN_THREADS if you are not using them
Sys.setenv(PKG_CPPFLAGS = paste0("-I",
Sys.setenv(PKG_CXXFLAGS = paste0(Sys.getenv("PKG_CXXFLAGS"), " -I",
system.file("include", "src",
package = "StanHeaders", mustWork = TRUE)))
sourceCpp(tf)
Expand Down
Loading

0 comments on commit 2bf58e5

Please sign in to comment.