00001 /** 00002 * \file noise.h 00003 * \brief Management of IMP images for Electron Microscopy 00004 * \author Javier Velazquez-Muriel 00005 * Copyright 2007-2010 IMP Inventors. All rights reserved. 00006 */ 00007 00008 #ifndef IMPEM_NOISE_H 00009 #define IMPEM_NOISE_H 00010 00011 #include "em_config.h" 00012 #include "ImageHeader.h" 00013 #include "IMP/algebra/MultiArray.h" 00014 #include "IMP/algebra/Matrix2D.h" 00015 #include "boost/random.hpp" 00016 #include "boost/version.hpp" 00017 00018 IMPEM_BEGIN_NAMESPACE 00019 00020 //!Add noise to actual values of the image. 00021 /** 00022 * Adds random noise to the image array. Supported distributions: 00023 * - uniform distribution, giving the range (lower, upper). DEFAULT 00024 * - gaussian distribution, giving the mean and the standard deviation 00025 * \todo - t-Student distribuion giving the mean, standard deviation and 00026 * the degrees of freedom 00027 * 00028 * \code 00029 * add_noise(v1,0, 1); 00030 * // uniform distribution between 0 and 1 00031 * 00032 * v1.add_noise(0, 1, "uniform"); 00033 * // the same 00034 * 00035 * v1.add_noise(0, 1, "gaussian"); 00036 * // gaussian distribution with 0 mean and stddev=1 00037 * 00038 * \endcode 00039 * \note Tested with MultiArray, Matrix2D and Matrix3D 00040 */ 00041 //template<typename T> 00042 //void add_noise(T& data, double op1, double op2, 00043 // const String& mode = "uniform", double df = 3) 00044 //{ 00045 // if (mode == "uniform") { 00046 // // Distribution 00047 // boost::uniform_real<> unif_dist(op1, op2); 00048 // // Put generator and distribution together 00049 // typedef boost::variate_generator < RandomNumberGenerator, 00050 // boost::uniform_real<> > rnd_unif_generator; 00051 // rnd_unif_generator rnd_unif(random_number_generator, unif_dist); 00052 // 00053 // Int D = data.dimensionality; 00054 // // add noise 00055 // std::vector<Int> idx(D); // access index 00056 // while (IMP::algebra::internal::roll_inds(idx, 00057 // data.shape(), 00058 // data.index_bases())) { 00059 // data(idx) += rnd_unif(); 00060 // } 00061 // } else if (mode == "gaussian") { 00062 // // Distribution 00063 // boost::normal_distribution<> gauss_dist(op1, op2); 00064 // // Put generator and distribution together 00065 // typedef boost::variate_generator < RandomNumberGenerator, 00066 // boost::normal_distribution<> > rnd_gauss_generator; 00067 // rnd_gauss_generator rnd_gauss(random_number_generator, gauss_dist); 00068 // 00069 // Int D = data.dimensionality; 00070 // // add noise 00071 // std::vector<Int> idx(D); // access index 00072 // while (IMP::algebra::internal::roll_inds(idx, 00073 // data.shape(), 00074 // data.index_bases())) { 00075 // data(idx) += rnd_gauss(); 00076 // } 00077 // } else if (mode == "student") { 00078 // } else { 00079 // String msg = "MultiArray::add_noise: Mode " + mode + " not supported."; 00080 // throw ErrorException(msg.c_str()); 00081 // } 00082 //} 00083 00084 template<typename T> 00085 void add_noise(T& v, double op1, double op2, 00086 const String& mode = "uniform", double df = 3) 00087 { 00088 // Generator 00089 // typedef boost::rand48 base_generator_type; 00090 typedef boost::mt19937 base_generator_type; 00091 base_generator_type generator; 00092 generator.seed(static_cast<unsigned long>(std::time(NULL))); 00093 // Distribution types 00094 typedef boost::uniform_real<> unif_distribution; 00095 typedef boost::normal_distribution<> norm_distribution; 00096 // Variate generators (put generator and distributions together) 00097 typedef boost::variate_generator < base_generator_type&, 00098 unif_distribution > unif_var_generator; 00099 typedef boost::variate_generator < base_generator_type&, 00100 norm_distribution > norm_var_generator; 00101 if (mode == "uniform") { 00102 unif_distribution dist(op1, op2); 00103 unif_var_generator random_var(generator,dist); 00104 // Add the random numbers 00105 for (unsigned long i=0;i<v.num_elements();++i) {v.data()[i]+=random_var();} 00106 } else if (mode == "gaussian") { 00107 norm_distribution dist(op1, op2); 00108 norm_var_generator random_var(generator, dist); 00109 // Add the random numbers 00110 for (unsigned long i=0;i<v.num_elements();++i) {v.data()[i]+=random_var();} 00111 } else if (mode == "student") { 00112 } else { 00113 IMP_THROW("MultiArray::add_noise: Mode " + mode + " not supported.", 00114 ValueException); 00115 } 00116 00117 00118 } 00119 00120 IMPEM_END_NAMESPACE 00121 #endif /* IMPEM_NOISE_H */