* Compute pi using the Leibniz formula * (a very inefficient approach). * @param[in] n Number of summands * @param[in] frequency Check for interrupts after * every @p frequency loop cycles. */
| 73 | * every @p frequency loop cycles. |
| 74 | */ |
| 75 | RcppExport SEXP PiLeibniz(SEXP n, SEXP frequency) |
| 76 | { |
| 77 | BEGIN_RCPP |
| 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 |
nothing calls this directly
no test coverage detected