|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4 -*- 00002 // 00003 // rnorm.h: Rcpp R/C++ interface class library -- 00004 // 00005 // Copyright (C) 2010 - 2011 Douglas Bates, Dirk Eddelbuettel and Romain Francois 00006 // 00007 // This file is part of Rcpp. 00008 // 00009 // Rcpp is free software: you can redistribute it and/or modify it 00010 // under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation, either version 2 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // Rcpp is distributed in the hope that it will be useful, but 00015 // WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 00021 00022 #ifndef Rcpp__stats__random_rnorm_h 00023 #define Rcpp__stats__random_rnorm_h 00024 00025 namespace Rcpp { 00026 namespace stats { 00027 00028 class NormGenerator : public Generator<false,double> { 00029 public: 00030 00031 NormGenerator( double mean_ = 0.0 , double sd_ = 1.0 ) : 00032 mean(mean_), sd(sd_) {} 00033 00034 inline double operator()() const { 00035 return mean + sd * ::norm_rand() ; 00036 } 00037 00038 private: 00039 double mean ; 00040 double sd ; 00041 } ; 00042 00043 00044 class NormGenerator__sd1 : public Generator<false,double> { 00045 public: 00046 00047 NormGenerator__sd1( double mean_ = 0.0 ) : mean(mean_) {} 00048 00049 inline double operator()() const { 00050 return mean + ::norm_rand() ; 00051 } 00052 00053 private: 00054 double mean ; 00055 } ; 00056 00057 00058 class NormGenerator__mean0 : public Generator<false,double> { 00059 public: 00060 00061 NormGenerator__mean0( double sd_ = 1.0 ) : sd(sd_) {} 00062 00063 inline double operator()() const { 00064 return sd * ::norm_rand() ; 00065 } 00066 00067 private: 00068 double sd ; 00069 } ; 00070 00071 00072 } // stats 00073 00074 // Please make sure you to read Section 6.3 of "Writing R Extensions" 00075 // about the need to call GetRNGstate() and PutRNGstate() when using 00076 // the random number generators provided by R. 00077 inline NumericVector rnorm( int n, double mean, double sd){ 00078 if (ISNAN(mean) || !R_FINITE(sd) || sd < 0.){ 00079 // TODO: R also throws a warning in that case, should we ? 00080 return NumericVector( n, R_NaN ) ; 00081 } else if (sd == 0. || !R_FINITE(mean)){ 00082 return NumericVector( n, mean ) ; 00083 } else { 00084 bool sd1 = sd == 1.0 ; 00085 bool mean0 = mean == 0.0 ; 00086 if( sd1 && mean0 ){ 00087 return NumericVector( n, norm_rand ) ; 00088 } else if( sd1 ){ 00089 return NumericVector( n, stats::NormGenerator__sd1( mean ) ); 00090 } else if( mean0 ){ 00091 return NumericVector( n, stats::NormGenerator__mean0( sd ) ); 00092 } else { 00093 // general case 00094 return NumericVector( n, stats::NormGenerator( mean, sd ) ); 00095 } 00096 } 00097 } 00098 00099 // Please make sure you to read Section 6.3 of "Writing R Extensions" 00100 // about the need to call GetRNGstate() and PutRNGstate() when using 00101 // the random number generators provided by R. 00102 inline NumericVector rnorm( int n, double mean /*, double sd [=1.0] */ ){ 00103 if (ISNAN(mean) ){ 00104 // TODO: R also throws a warning in that case, should we ? 00105 return NumericVector( n, R_NaN ) ; 00106 } else if ( !R_FINITE(mean)){ 00107 return NumericVector( n, mean ) ; 00108 } else { 00109 bool mean0 = mean == 0.0 ; 00110 if( mean0 ){ 00111 return NumericVector( n, norm_rand ) ; 00112 } else { 00113 return NumericVector( n, stats::NormGenerator__sd1( mean ) ); 00114 } 00115 } 00116 } 00117 00118 // Please make sure you to read Section 6.3 of "Writing R Extensions" 00119 // about the need to call GetRNGstate() and PutRNGstate() when using 00120 // the random number generators provided by R. 00121 inline NumericVector rnorm( int n /*, double mean [=0.0], double sd [=1.0] */ ){ 00122 return NumericVector( n, norm_rand ) ; 00123 } 00124 00125 } // Rcpp 00126 00127 #endif