Rcpp Version 1.0.14
Loading...
Searching...
No Matches
piWithInterrupts.cpp
Go to the documentation of this file.
1// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
2
3#include <Rcpp.h>
4
5#ifdef _OPENMP
6#include <omp.h>
7#endif
8
9#include <R_ext/Utils.h>
10
15class interrupt_exception : public std::exception {
16public:
22 interrupt_exception(std::string message)
23 : detailed_message(message)
24 {};
25
29 virtual ~interrupt_exception() throw() {};
30
35 virtual const char* what() const throw() {
36 return detailed_message.c_str();
37 }
38
42 std::string detailed_message;
43};
44
50static inline void check_interrupt_impl(void* /*dummy*/) {
51 R_CheckUserInterrupt();
52}
53
64inline bool check_interrupt() {
65 return (R_ToplevelExec(check_interrupt_impl, NULL) == FALSE);
66}
67
75RcppExport SEXP PiLeibniz(SEXP n, SEXP frequency)
76{
78
79 // cast parameters
80 int n_cycles = Rcpp::as<int>(n);
81 int interrupt_check_frequency = Rcpp::as<int>(frequency);
82
83 // user interrupt flag
84 bool interrupt = false;
85
86 double pi = 0;
87#ifdef _OPENMP
88#pragma omp parallel for \
89 shared(interrupt_check_frequency, n_cycles, interrupt) \
90 reduction(+:pi)
91#endif
92 for (int i=0; i<n_cycles; i+=interrupt_check_frequency) {
93 // check for user interrupt
94 if (interrupt) {
95 continue;
96 }
97
98#ifdef _OPENMP
99 if (omp_get_thread_num() == 0) // only in master thread!
100#endif
101 if (check_interrupt()) {
102 interrupt = true;
103 }
104
105 // do actual computations
106 int j_end = std::min(i+interrupt_check_frequency, n_cycles);
107 for (int j=i; j<j_end; ++j) {
108 double summand = 1.0 / (double)(2*j + 1);
109 if (j % 2 == 0) {
110 pi += summand;
111 }
112 else {
113 pi -= summand;
114 }
115 }
116 }
117
118 // additional check, in case frequency was too large
119 if (check_interrupt()) {
120 interrupt = true;
121 }
122
123 // throw exception if interrupt occurred
124 if (interrupt) {
125 throw interrupt_exception("The computation of pi was interrupted.");
126 }
127
128 pi *= 4.0;
129
130 // result list
131 return Rcpp::wrap(pi);
132
134}
#define RcppExport
Definition RcppCommon.h:141
virtual const char * what() const
interrupt_exception(std::string message)
#define END_RCPP
Definition macros.h:99
#define BEGIN_RCPP
Definition macros.h:49
T as(SEXP x)
Definition as.h:151
SEXP wrap(const Date &date)
Definition Date.h:38
bool check_interrupt()
RcppExport SEXP PiLeibniz(SEXP n, SEXP frequency)
static void check_interrupt_impl(void *)