op_randn_meat.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2009 NICTA
00002 // 
00003 // Authors:
00004 // - Conrad Sanderson (conradsand at ieee dot org)
00005 // 
00006 // This file is part of the Armadillo C++ library.
00007 // It is provided without any warranty of fitness
00008 // for any purpose. You can redistribute this file
00009 // and/or modify it under the terms of the GNU
00010 // Lesser General Public License (LGPL) as published
00011 // by the Free Software Foundation, either version 3
00012 // of the License or (at your option) any later version.
00013 // (see http://www.opensource.org/licenses for more info)
00014 
00015 
00016 //! \addtogroup op_randn
00017 //! @{
00018 
00019 
00020 // TODO:
00021 // implement a more efficient method
00022 //
00023 // possible option:
00024 // Marsaglia and Tsang Ziggurat technique to transform from a uniform to a normal distribution.
00025 // G. Marsaglia, W.W. Tsang.
00026 // "Ziggurat method for generating random variables",
00027 // J. Statistical Software, vol 5, 2000.
00028 // http://www.jstatsoft.org/v05/i08/
00029 
00030 
00031 template<typename eT>
00032 inline
00033 eT
00034 op_randn::randn()
00035   {
00036   const u32 N = 12;
00037   eT acc = eT(0);
00038   
00039   for(u32 i=0; i<N; ++i)
00040     {
00041     acc += eT(std::rand()) / eT(RAND_MAX);
00042     }
00043   
00044   return acc/eT(N) - eT(0.5);
00045   }
00046 
00047 
00048 
00049 template<typename eT>
00050 inline
00051 void
00052 op_randn::direct_randn(eT* x, const u32 n_elem)
00053   {
00054   arma_extra_debug_sigprint();
00055   
00056   for(u32 i=0; i<n_elem; ++i)
00057     {
00058     x[i] = eT(op_randn::randn<eT>());
00059     }
00060   
00061   }
00062 
00063 
00064 
00065 template<typename T>
00066 inline
00067 void
00068 op_randn::direct_randn(std::complex<T>* x, const u32 n_elem)
00069   {
00070   arma_extra_debug_sigprint();
00071   
00072   for(u32 i=0; i<n_elem; ++i)
00073     {
00074     const T a = op_randn::randn<T>();
00075     const T b = op_randn::randn<T>();
00076 
00077     x[i] = std::complex<T>(a,b);
00078     }
00079   }
00080 
00081 
00082 
00083 template<typename T1>
00084 inline
00085 void
00086 op_randn::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_randn>& in)
00087   {
00088   arma_extra_debug_sigprint();
00089   
00090   out.set_size(in.aux_u32_a, in.aux_u32_b);
00091   
00092   op_randn::direct_randn(out.memptr(), out.n_elem);
00093   }
00094 
00095 
00096 
00097 template<typename eT>
00098 inline
00099 void
00100 op_randn::apply(Cube<eT>& out, const OpCube<Cube<eT>,op_randn>& in)
00101   {
00102   arma_extra_debug_sigprint();
00103   
00104   out.set_size(in.aux_u32_a, in.aux_u32_b, in.aux_u32_c);
00105   
00106   op_randn::direct_randn(out.memptr(), out.n_elem);
00107   }
00108 
00109 
00110 
00111 //! @}