static inline void filter(float *x, float *y) { static float px=0, py=0; static float dx=0, dy=0; dfilter(x,&dx); dfilter(y,&dy); cfilter(x,&px); cfilter(y,&py); }
//' Generate Autoregressive Order P - Moving Average Order Q (ARMA(P,Q)) Model //' //' Generate an ARMA(P,Q) process with supplied vector of Autoregressive Coefficients (\eqn{\phi}), Moving Average Coefficients (\eqn{\theta}), and \eqn{\sigma^2}. //' @param N An \code{integer} for signal length. //' @param ar A \code{vec} that contains the AR coefficients. //' @param ma A \code{vec} that contains the MA coefficients. //' @param sigma2 A \code{double} that contains process variance. //' @param n_start An \code{unsigned int} that indicates the amount of observations to be used for the burn in period. //' @return A \code{vec} that contains the generated observations. //' @details //' The innovations are generated from a normal distribution. //' The \eqn{\sigma^2} parameter is indeed a variance parameter. //' This differs from R's use of the standard deviation, \eqn{\sigma}. //' //' For AR(1), MA(1), and ARMA(1,1) please use their functions if speed is important. //' @backref src/gen_process.cpp //' @backref src/gen_process.h //' @keywords internal //' @examples //' gen_arma(10, c(.3,.5), c(.1), 1, 0) // [[Rcpp::export]] arma::vec gen_arma(const unsigned int N, const arma::vec& ar, const arma::vec& ma, const double sigma2 = 1.5, unsigned int n_start = 0){ // P = AR1 coefs, Q = MA coefs unsigned int p = ar.n_elem, q = ma.n_elem; // Need to append 1 to vectors. arma::vec one = arma::ones<arma::vec>(1); // What is the minimum root? double min_root = 1; // SD double sd = sqrt(sigma2); // Innovation save arma::vec innov(N); // Start Innovation arma::vec start_innov; // Store data arma::vec x; // Loop counter unsigned int i; // AR terms present? if(p != 0){ // Obtain the smallest root of the AR coefs. min_root = minroot(arma::conv_to<arma::cx_vec>::from( arma::join_cols(one, -ar) ) ); // Check to see if the smallest root is not invertible (e.g. in unit circle) if(min_root <= 1){ throw std::runtime_error("Supplied model's AR component is NOT invertible!"); } } // Determine starting values if(n_start == 0){ n_start = p + q + ( p > 0 ? ceil(6/log(min_root)) : 0 ); } if(n_start < p + q){ throw std::runtime_error("burn-in 'n.start' must be as long as 'ar + ma'"); } // Generate Innovations for(i = 0; i < N; i++){ innov(i) = R::rnorm(0,sd); } // Generate Starting Innovations start_innov = arma::vec(n_start); for(i = 0; i < n_start; i++){ start_innov(i) = R::rnorm(0,sd); } // Combine x = join_cols(start_innov, innov); // Handle the MA part of ARMA if(q > 0){ // Apply a convolution filter // data, filter, sides, circular x = cfilter(x, join_cols(one,ma), 1, false); x.rows(0, q-1).fill(0); } // Handle the AR part of ARMA if(p > 0){ // Apply recursive filter // data, filter, init value // see comment in rfilter docs for init values (different than normal R) x = rfilter(x, ar, arma::zeros<arma::vec>(p)); } // Remove starting innovations if(n_start > 0){ // need -1 for C++ oob error x = x.rows(n_start, x.n_elem - 1); } return x; }
constexpr cpu_t newer(cpu_t x) { return static_cast<cpu_t>(static_cast<int>(x) + 1); } #ifdef CMT_ARCH_X86 constexpr auto cpu_list = cvals_t<cpu_t, cpu_t::avx512, cpu_t::avx2, cpu_t::avx1, cpu_t::sse41, cpu_t::ssse3, cpu_t::sse3, cpu_t::sse2>(); #else constexpr auto cpu_list = cvals<cpu_t, cpu_t::neon>; #endif } // namespace internal template <cpu_t cpu> using cpuval_t = cval_t<cpu_t, cpu>; template <cpu_t cpu> constexpr auto cpuval = cpuval_t<cpu>{}; constexpr auto cpu_all = cfilter(internal::cpu_list, internal::cpu_list >= cpuval_t<cpu_t::native>()); /// @brief Returns name of the cpu instruction set CMT_UNUSED static const char* cpu_name(cpu_t set) { #ifdef CMT_ARCH_X86 static const char* names[] = { "common", "sse2", "sse3", "ssse3", "sse41", "sse42", "avx1", "avx2", "avx512" }; #endif #ifdef CMT_ARCH_ARM static const char* names[] = { "common", "neon", "neon64" }; #endif if (set >= cpu_t::lowest && set <= cpu_t::highest) return names[static_cast<size_t>(set)]; return "-"; }