Skip to content

Commit 9616afe

Browse files
committed
Fix volume/sample_points S3 generics and regenerate exports
1 parent 3013afa commit 9616afe

7 files changed

Lines changed: 149 additions & 32 deletions

File tree

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ export(read_sdpa_format_file)
2727
export(rotate_polytope)
2828
export(round_polytope)
2929
export(sample_points)
30+
S3method(sample_points,default)
31+
S3method(sample_points,Spectrahedron)
3032
export(uniform_sample_correlation_matrices)
3133
export(volume)
3234
S3method(volume,default)

R/RcppExports.R

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,10 @@ rounding <- function(P, method = NULL, seed = NULL) {
355355
#'
356356
#' # For sampling from logconcave densities see the examples directory
357357
#'
358-
#' @export
359-
sample_points <- function(P, n, random_walk = NULL, distribution = NULL, seed = NULL) {
360-
.Call(`_volesti_sample_points`, P, n, random_walk, distribution, seed)
358+
#' @keywords internal
359+
#' @noRd
360+
sample_points_internal <- function(P, n, random_walk = NULL, distribution = NULL, seed = NULL) {
361+
.Call(`_volesti_sample_points_internal`, P, n, random_walk, distribution, seed)
361362
}
362363

363364
#' Uniformly sample correlation matrices
@@ -412,9 +413,10 @@ uniform_sample_correlation_matrices <- function(n, num_matrices = 1000L, walk_le
412413
#' Z = gen_rand_zonotope(2, 4)
413414
#' pair_vol = volume(Z, settings = list("random_walk" = "RDHR", "walk_length" = 2))
414415
#'
415-
#' @export
416-
volume <- function(P, settings = NULL, rounding = NULL) {
417-
.Call(`_volesti_volume`, P, settings, rounding)
416+
#' @keywords internal
417+
#' @noRd
418+
volume_internal <- function(P, settings = NULL, rounding = NULL) {
419+
.Call(`_volesti_volume_internal`, P, settings, rounding)
418420
}
419421

420422
volume_spectrahedra <- function(A_list, dim, verbosity) {

R/sample_points.R

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#' Sample points from a convex polytope
2+
#'
3+
#' Sample perfect uniformly distributed points from well known convex bodies
4+
#' or run geometric random walks to approximate arbitrary distributions.
5+
#'
6+
#' The \eqn{d}-dimensional unit simplex is the set of points \eqn{\vec{x} \in \R^d},
7+
#' s.t.: \eqn{\sum_i x_i \leq 1}, \eqn{x_i \geq 0}. The \eqn{d}-dimensional canonical
8+
#' simplex is the set of points \eqn{\vec{x} \in \R^d}, s.t.: \eqn{\sum_i x_i = 1},
9+
#' \eqn{x_i \geq 0}.
10+
#'
11+
#' @param P A convex polytope object. It is an object from class (a) Hpolytope or
12+
#' (b) Vpolytope or (c) Zonotope or (d) VpolytopeIntersection.
13+
#' @param n The number of points that the function is going to sample.
14+
#' @param random_walk Optional. A list that declares the random walk method and
15+
#' related parameters as follows:
16+
#' \describe{
17+
#' \item{\code{walk}}{A string: (a) \code{'CDHR'} for coordinate direction hit-and-run,
18+
#' b) \code{'RDHR'} for random direction hit-and-run, c) \code{'BaW'} for the ball walk,
19+
#' d) \code{'BiW'} for the billiard walk, e) \code{'BiRCDHR'} for the bicriteria random walk,
20+
#' f) \code{'Dikin'} for dikin walk, g) \code{'Vaidya'} for vaidya walk,
21+
#' h) \code{'John'} for john walk, i) \code{'BRDHR'} for boundary hit-and-run,
22+
#' j) \code{'Hamiltonian'} for Hamiltonian walk, k) \code{'accelerated_billiard'} for
23+
#' accelerated billiard walk, l) \code{'BilliardRef'} for billiard walk with reflections,
24+
#' m) \code{'HRlu'} for logconcave settings with H-polytope,
25+
#' n) \code{'HRnr'} for logconcave densities with V-polytope, o) \code{'HESSIANRWR'}
26+
#' for logconcave densities with H-polytope and sparse constrained problems.}
27+
#' \item{\code{walk_length}}{The number of the steps per generated point for the random walk.
28+
#' The default value is \eqn{1}.}
29+
#' \item{\code{nburns}}{The number of points to burn before start sampling. The default
30+
#' value is \eqn{1}.}
31+
#' \item{\code{starting_point}}{A \eqn{d}-dimensional numerical vector that declares a
32+
#' starting point in the interior of the polytope for the random walk. The default choice
33+
#' is the center of the ball as computed by \code{inner_ball()}.}
34+
#' \item{\code{BaW_rad}}{The radius for the ball walk.}
35+
#' \item{\code{L}}{The maximum length of the billiard trajectory or the radius for the step
36+
#' of Dikin, Vaidya or John walk.}
37+
#' \item{\code{solver}}{Specify ODE solver for logconcave sampling. Options are i) leapfrog,
38+
#' ii) euler iii) runge-kutta iv) richardson}
39+
#' \item{\code{step_size}}{Optionally chosen step size for logconcave sampling. Defaults to
40+
#' a theoretical value if not provided.}
41+
#' }
42+
#' @param distribution Optional. A list that declares the target density and related
43+
#' parameters as follows:
44+
#' \describe{
45+
#' \item{\code{density}}{A string: (a) \code{'uniform'} for the uniform distribution,
46+
#' (b) \code{'gaussian'} for the multidimensional spherical distribution,
47+
#' (c) \code{'logconcave'} with form proportional to exp(-f(x)) where f(x) is L-smooth
48+
#' and m-strongly-convex, (d) \code{'exponential'} for the exponential distribution.
49+
#' The default target distribution is the uniform distribution.}
50+
#' \item{\code{variance}}{The variance of the multidimensional spherical Gaussian or the
51+
#' exponential distribution. The default value is 1.}
52+
#' \item{\code{mode}}{A \eqn{d}-dimensional numerical vector that declares the mode of the
53+
#' Gaussian distribution. The default choice is the center computed by \code{inner_ball()}.}
54+
#' \item{\code{bias}}{The bias vector for the exponential distribution. The default vector
55+
#' is \eqn{c_1 = 1} and \eqn{c_i = 0} for \eqn{i \neq 1}.}
56+
#' \item{\code{L_}}{Smoothness constant (for logconcave).}
57+
#' \item{\code{m}}{Strong-convexity constant (for logconcave).}
58+
#' \item{\code{negative_logprob}}{Negative log-probability (for logconcave).}
59+
#' \item{\code{negative_logprob_gradient}}{Negative log-probability gradient (for logconcave).}
60+
#' }
61+
#' @param seed Optional. A fixed seed for the number generator.
62+
#' @param ... Additional arguments passed along to methods.
63+
#'
64+
#' @references Robert L. Smith, "Efficient Monte Carlo Procedures for Generating Points
65+
#' Uniformly Distributed Over Bounded Regions," Operations Research, 1984.
66+
#' @references B.T. Polyak, E.N. Gryazina, "Billiard walk - a new sampling algorithm for control
67+
#' and optimization," IFAC Proceedings Volumes, 2014.
68+
#' @references Y. Chen, R. Dwivedi, M. J. Wainwright and B. Yu, "Fast MCMC Sampling Algorithms on
69+
#' Polytopes," Journal of Machine Learning Research, 2018.
70+
#' @references Lee, Yin Tat, Ruoqi Shen, and Kevin Tian, "Logsmooth Gradient Concentration and
71+
#' Tighter Runtimes for Metropolized Hamiltonian Monte Carlo," arXiv:2002.04121, 2020.
72+
#' @references Shen, Ruoqi, and Yin Tat Lee, "The randomized midpoint method for log-concave
73+
#' sampling," Advances in Neural Information Processing Systems, 2019.
74+
#' @references Augustin Chevallier, Sylvain Pion, Frederic Cazals, "Hamiltonian Monte Carlo with
75+
#' boundary reflections, and application to polytope volume calculations," Research Report
76+
#' preprint hal-01919855, 2018.
77+
#'
78+
#' @return A \eqn{d \times n} matrix that contains, column-wise, the sampled points from the
79+
#' convex polytope P.
80+
#' @examples
81+
#' # uniform distribution from the 3d unit cube in H-representation using ball walk
82+
#' P = gen_cube(3, 'H')
83+
#' points = sample_points(P, n = 100, random_walk = list("walk" = "BaW", "walk_length" = 5))
84+
#'
85+
#' # gaussian distribution from the 2d unit simplex in H-representation with variance = 2
86+
#' A = matrix(c(-1,0,0,-1,1,1), ncol=2, nrow=3, byrow=TRUE)
87+
#' b = c(0,0,1)
88+
#' P = Hpolytope(A=A,b=b)
89+
#' points = sample_points(P, n = 100, distribution = list("density" = "gaussian", "variance" = 2))
90+
#'
91+
#' # uniform points from the boundary of a 2-dimensional random H-polytope
92+
#' P = gen_rand_hpoly(2,20)
93+
#' points = sample_points(P, n = 100, random_walk = list("walk" = "BRDHR"))
94+
#'
95+
#' # For sampling from logconcave densities see the examples directory
96+
#'
97+
#' @export
98+
sample_points <- function(P, n, random_walk = NULL, distribution = NULL, seed = NULL, ...) {
99+
UseMethod("sample_points")
100+
}
101+
102+
#' @rdname sample_points
103+
#' @export
104+
sample_points.default <- function(P, n, random_walk = NULL, distribution = NULL, seed = NULL, ...) {
105+
sample_points_internal(P, n, random_walk, distribution, seed)
106+
}
107+
108+
#' @rdname sample_points
109+
#' @export
110+
sample_points.Spectrahedron <- function(P, n, random_walk = NULL, distribution = NULL, seed = NULL, ...) {
111+
stop("Sampling from Spectrahedron is not implemented yet in Rvolesti.")
112+
}

R/volume.R

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,33 @@
33
#' Glue that routes to the classic polytope volume code plus a Spectrahedron-specific
44
#' volume() S3 method. Keeping this tiny so the old interface still works.
55
#'
6-
#' @param body A convex body object such as a polytope or spectrahedron.
6+
#' @param P A convex body object such as a polytope or spectrahedron.
7+
#' @param settings Volume settings list for the existing C++ pipeline.
8+
#' @param rounding Optional rounding strategy string.
79
#' @param ... Extra arguments passed along to the dispatched method.
810
#'
911
#' @return A list with numeric entries named volume and log_volume.
1012
#' @export
11-
volume <- function(body, ...) UseMethod("volume")
13+
volume <- function(P, settings = NULL, rounding = NULL, ...) UseMethod("volume")
1214

1315
#' @rdname volume
14-
#' @param settings Volume settings list for the existing C++ pipeline.
15-
#' @param rounding Optional rounding strategy string.
1616
#' @export
17-
volume.default <- function(body, settings = NULL, rounding = NULL, ...) {
18-
# nothing fancy, just defer to the existing compiled entry point
19-
.Call(`_volesti_volume`, body, settings, rounding)
17+
volume.default <- function(P, settings = NULL, rounding = NULL, ...) {
18+
volume_internal(P, settings, rounding)
2019
}
2120

2221
#' @rdname volume
2322
#' @param verbosity Integer flag: 0 = silent, 1 = coarse prints, 2 = debug spam.
2423
#' @export
25-
volume.Spectrahedron <- function(body, verbosity = 0L, ...) {
24+
volume.Spectrahedron <- function(P, settings = NULL, rounding = NULL, verbosity = 0L, ...) {
2625
verb_level <- as.integer(verbosity)
2726
if (length(verb_level) != 1L || is.na(verb_level) || verb_level < 0L || verb_level > 2L) {
2827
stop("verbosity must be a single non-negative integer: 0, 1, or 2")
2928
}
30-
unk_dim <- if ("dim" %in% methods::slotNames(body)) body@dim else as.integer(length(body@matrices) - 1L)
29+
unk_dim <- if ("dim" %in% methods::slotNames(P)) P@dim else as.integer(length(P@matrices) - 1L)
3130
unk_dim <- as.integer(unk_dim)
3231
if (is.na(unk_dim) || is.null(unk_dim)) {
33-
unk_dim <- as.integer(length(body@matrices) - 1L)
32+
unk_dim <- as.integer(length(P@matrices) - 1L)
3433
}
3534
if (verb_level >= 1L) {
3635
message("Spectrahedron volume estimation is not implemented in Rvolesti yet; this call will currently error.")
@@ -39,7 +38,7 @@ volume.Spectrahedron <- function(body, verbosity = 0L, ...) {
3938
message("Spectrahedron dimension guess: ", unk_dim)
4039
}
4140
if (verb_level >= 2L) {
42-
message("Matrix count: ", length(body@matrices))
41+
message("Matrix count: ", length(P@matrices))
4342
}
44-
.Call(`_volesti_volume_spectrahedra`, body@matrices, as.integer(unk_dim), verb_level)
43+
volume_spectrahedra(P@matrices, as.integer(unk_dim), verb_level)
4544
}

src/RcppExports.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ BEGIN_RCPP
189189
return rcpp_result_gen;
190190
END_RCPP
191191
}
192-
// sample_points
193-
Rcpp::NumericMatrix sample_points(Rcpp::Reference P, Rcpp::Nullable<unsigned int> n, Rcpp::Nullable<Rcpp::List> random_walk, Rcpp::Nullable<Rcpp::List> distribution, Rcpp::Nullable<double> seed);
194-
RcppExport SEXP _volesti_sample_points(SEXP PSEXP, SEXP nSEXP, SEXP random_walkSEXP, SEXP distributionSEXP, SEXP seedSEXP) {
192+
// sample_points_internal
193+
Rcpp::NumericMatrix sample_points_internal(Rcpp::Reference P, Rcpp::Nullable<unsigned int> n, Rcpp::Nullable<Rcpp::List> random_walk, Rcpp::Nullable<Rcpp::List> distribution, Rcpp::Nullable<double> seed);
194+
RcppExport SEXP _volesti_sample_points_internal(SEXP PSEXP, SEXP nSEXP, SEXP random_walkSEXP, SEXP distributionSEXP, SEXP seedSEXP) {
195195
BEGIN_RCPP
196196
Rcpp::RObject rcpp_result_gen;
197197
Rcpp::RNGScope rcpp_rngScope_gen;
@@ -200,7 +200,7 @@ BEGIN_RCPP
200200
Rcpp::traits::input_parameter< Rcpp::Nullable<Rcpp::List> >::type random_walk(random_walkSEXP);
201201
Rcpp::traits::input_parameter< Rcpp::Nullable<Rcpp::List> >::type distribution(distributionSEXP);
202202
Rcpp::traits::input_parameter< Rcpp::Nullable<double> >::type seed(seedSEXP);
203-
rcpp_result_gen = Rcpp::wrap(sample_points(P, n, random_walk, distribution, seed));
203+
rcpp_result_gen = Rcpp::wrap(sample_points_internal(P, n, random_walk, distribution, seed));
204204
return rcpp_result_gen;
205205
END_RCPP
206206
}
@@ -219,16 +219,16 @@ BEGIN_RCPP
219219
return rcpp_result_gen;
220220
END_RCPP
221221
}
222-
// volume
223-
Rcpp::List volume(Rcpp::Reference P, Rcpp::Nullable<Rcpp::List> settings, Rcpp::Nullable<std::string> rounding);
224-
RcppExport SEXP _volesti_volume(SEXP PSEXP, SEXP settingsSEXP, SEXP roundingSEXP) {
222+
// volume_internal
223+
Rcpp::List volume_internal(Rcpp::Reference P, Rcpp::Nullable<Rcpp::List> settings, Rcpp::Nullable<std::string> rounding);
224+
RcppExport SEXP _volesti_volume_internal(SEXP PSEXP, SEXP settingsSEXP, SEXP roundingSEXP) {
225225
BEGIN_RCPP
226226
Rcpp::RObject rcpp_result_gen;
227227
Rcpp::RNGScope rcpp_rngScope_gen;
228228
Rcpp::traits::input_parameter< Rcpp::Reference >::type P(PSEXP);
229229
Rcpp::traits::input_parameter< Rcpp::Nullable<Rcpp::List> >::type settings(settingsSEXP);
230230
Rcpp::traits::input_parameter< Rcpp::Nullable<std::string> >::type rounding(roundingSEXP);
231-
rcpp_result_gen = Rcpp::wrap(volume(P, settings, rounding));
231+
rcpp_result_gen = Rcpp::wrap(volume_internal(P, settings, rounding));
232232
return rcpp_result_gen;
233233
END_RCPP
234234
}
@@ -287,9 +287,9 @@ static const R_CallMethodDef CallEntries[] = {
287287
{"_volesti_raftery", (DL_FUNC) &_volesti_raftery, 4},
288288
{"_volesti_rotating", (DL_FUNC) &_volesti_rotating, 3},
289289
{"_volesti_rounding", (DL_FUNC) &_volesti_rounding, 3},
290-
{"_volesti_sample_points", (DL_FUNC) &_volesti_sample_points, 5},
290+
{"_volesti_sample_points_internal", (DL_FUNC) &_volesti_sample_points_internal, 5},
291291
{"_volesti_uniform_sample_correlation_matrices", (DL_FUNC) &_volesti_uniform_sample_correlation_matrices, 5},
292-
{"_volesti_volume", (DL_FUNC) &_volesti_volume, 3},
292+
{"_volesti_volume_internal", (DL_FUNC) &_volesti_volume_internal, 3},
293293
{"_volesti_volume_spectrahedra", (DL_FUNC) &_volesti_volume_spectrahedra, 3},
294294
{"_volesti_write_sdpa_format_file", (DL_FUNC) &_volesti_write_sdpa_format_file, 3},
295295
{"_volesti_zono_approx", (DL_FUNC) &_volesti_zono_approx, 4},

src/sample_points.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,10 @@ bool is_walk(Rcpp::Nullable<Rcpp::List> random_walk, std::string str) {
293293
//'
294294
//' # For sampling from logconcave densities see the examples directory
295295
//'
296-
//' @export
296+
//' @keywords internal
297+
//' @noRd
297298
// [[Rcpp::export]]
298-
Rcpp::NumericMatrix sample_points(Rcpp::Reference P,
299+
Rcpp::NumericMatrix sample_points_internal(Rcpp::Reference P,
299300
Rcpp::Nullable<unsigned int> n,
300301
Rcpp::Nullable<Rcpp::List> random_walk = R_NilValue,
301302
Rcpp::Nullable<Rcpp::List> distribution = R_NilValue,

src/volume.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,10 @@ std::pair<double, double> generic_volume(Polytope& P, RNGType &rng, unsigned int
209209
//' Z = gen_rand_zonotope(2, 4)
210210
//' pair_vol = volume(Z, settings = list("random_walk" = "RDHR", "walk_length" = 2))
211211
//'
212-
//' @export
212+
//' @keywords internal
213+
//' @noRd
213214
// [[Rcpp::export]]
214-
Rcpp::List volume (Rcpp::Reference P,
215+
Rcpp::List volume_internal (Rcpp::Reference P,
215216
Rcpp::Nullable<Rcpp::List> settings = R_NilValue,
216217
Rcpp::Nullable<std::string> rounding = R_NilValue) {
217218

0 commit comments

Comments
 (0)