// SPDX-License-Identifier: Apache-2.0 // // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) // Copyright 2008-2016 National ICT Australia (NICTA) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ------------------------------------------------------------------------ //! \addtogroup fn_normcdf //! @{ template inline typename enable_if2< (is_real::value), void >::result normcdf_helper(Mat& out, const Base& X_expr, const Base& M_expr, const Base& S_expr) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; if(Proxy::use_at || Proxy::use_at || Proxy::use_at) { const quasi_unwrap UX(X_expr.get_ref()); const quasi_unwrap UM(M_expr.get_ref()); const quasi_unwrap US(S_expr.get_ref()); normcdf_helper(out, UX.M, UM.M, US.M); return; } const Proxy PX(X_expr.get_ref()); const Proxy PM(M_expr.get_ref()); const Proxy PS(S_expr.get_ref()); arma_debug_check( ( (PX.get_n_rows() != PM.get_n_rows()) || (PX.get_n_cols() != PM.get_n_cols()) || (PM.get_n_rows() != PS.get_n_rows()) || (PM.get_n_cols() != PS.get_n_cols()) ), "normcdf(): size mismatch" ); out.set_size(PX.get_n_rows(), PX.get_n_cols()); eT* out_mem = out.memptr(); const uword N = PX.get_n_elem(); typename Proxy::ea_type X_ea = PX.get_ea(); typename Proxy::ea_type M_ea = PM.get_ea(); typename Proxy::ea_type S_ea = PS.get_ea(); const bool use_mp = arma_config::openmp && mp_gate::eval(N); if(use_mp) { #if defined(ARMA_USE_OPENMP) { const int n_threads = mp_thread_limit::get(); #pragma omp parallel for schedule(static) num_threads(n_threads) for(uword i=0; i::sqrt2)); out_mem[i] = eT(0.5) * std::erfc(tmp); } } #endif } else { for(uword i=0; i::sqrt2)); out_mem[i] = eT(0.5) * std::erfc(tmp); } } } template arma_warn_unused inline typename enable_if2< (is_real::value), eT >::result normcdf(const eT x) { const eT out = eT(0.5) * std::erfc( x / (-Datum::sqrt2) ); return out; } template arma_warn_unused inline typename enable_if2< (is_real::value), eT >::result normcdf(const eT x, const eT mu, const eT sigma) { const eT tmp = (x - mu) / (sigma * (-Datum::sqrt2)); const eT out = eT(0.5) * std::erfc(tmp); return out; } template arma_warn_unused inline typename enable_if2< (is_real::value), Mat >::result normcdf(const eT x, const Base& M_expr, const Base& S_expr) { arma_extra_debug_sigprint(); const quasi_unwrap UM(M_expr.get_ref()); const Mat& M = UM.M; Mat out; normcdf_helper(out, x*ones< Mat >(arma::size(M)), M, S_expr.get_ref()); return out; } template arma_warn_unused inline typename enable_if2< (is_real::value), Mat >::result normcdf(const Base& X_expr) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const quasi_unwrap UX(X_expr.get_ref()); const Mat& X = UX.M; Mat out; normcdf_helper(out, X, zeros< Mat >(arma::size(X)), ones< Mat >(arma::size(X))); return out; } template arma_warn_unused inline typename enable_if2< (is_real::value), Mat >::result normcdf(const Base& X_expr, const typename T1::elem_type mu, const typename T1::elem_type sigma) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const quasi_unwrap UX(X_expr.get_ref()); const Mat& X = UX.M; Mat out; normcdf_helper(out, X, mu*ones< Mat >(arma::size(X)), sigma*ones< Mat >(arma::size(X))); return out; } template arma_warn_unused inline typename enable_if2< (is_real::value), Mat >::result normcdf(const Base& X_expr, const Base& M_expr, const Base& S_expr) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; Mat out; normcdf_helper(out, X_expr.get_ref(), M_expr.get_ref(), S_expr.get_ref()); return out; } //! @}