Authored by Pavel Govyadinov
1 parent 9bfae4d0

### Fixed the pdf implementation in spharmonics classes, added the random.h class in…

`… stim/math for access to randomized variables and to sample a solid sphere (or angle), the functions are static but an instance can be initialized if a specific seed is needed`
Showing 2 changed files with 152 additions and 2 deletions
stim/math/random.h 0 → 100644

 1 +#ifndef STIM_RANDOM 2 +#define STIM_RANDOM 3 + 4 +#include 5 +#include 6 +#include 7 +#include 8 +#include 9 + 10 +namespace stim{ 11 + 12 +template 13 +class Random{ 14 +protected: 15 + void init(int seed = 0) 16 + { 17 + if(seed <= 0) 18 + srand(time(NULL)); 19 + else if(seed > 0) 20 + srand(time(seed)); 21 + else 22 + std::cout << "Error: Unknown value: in STIM::RANDOM" << std::endl; 23 + } 24 + 25 +public: 26 + /// Default Constructor 27 + Random(){ 28 + init(-1); 29 + } 30 + 31 + /// Constructor from a seed. 32 + /// A positive seed sets, 0 or negative yeilds the 33 + Random(int seed){ 34 + init(seed); 35 + } 36 + 37 + ///Returns a random number uniformly sampled between 0 and 1 38 + static 39 + T uniformRandom() 40 + { 41 + return ( (T)(rand()))/( (T)(RAND_MAX)); ///generates a random number between 0 and 1 using the uniform distribution. 42 + } 43 + 44 + ///Returns a random number from a normal distribution between 0 to 1. 45 + static 46 + T normalRandom() 47 + { 48 + T u1 = uniformRandom(); 49 + T u2 = uniformRandom(); 50 + return cos(2.0*atan(1.0)*u2)*sqrt(-1.0*log(u1)); ///generate a random number using the normal distribution between 0 and 1. 51 + } 52 + ///Return a random vec3 each value between 0 and 1 from a uniform distribution. 53 + static 54 + stim::vec3 uniformRandVector() 55 + { 56 + stim::vec3 r(uniformRandom(), uniformRandom(), 1.0); ///generate a random vector using the uniform distribution between 0 and 1. 57 + return r; 58 + } 59 + ///Return a random vec3, each value between 0 and 1 from a normal distribution. 60 + static 61 + stim::vec3 normalRandVector() 62 + { 63 + stim::vec3 r(normalRandom(), normalRandom(), 1.0); ///generate a random vector using the normal distribution between 0 and 1. 64 + return r; 65 + } 66 + 67 + ///place num_samples of samples on the surface of a sphere of radius r. 68 + ///returns an std::vector of vec3's in cartisian coordinates. 69 + static std::vector > 70 + sample_sphere(unsigned int num_samples, T radius = 1, T solidAngle = stim::TAU) 71 + { 72 + std::cout << "did this" << std::endl; 73 + T PHI[2], Z[2], range; ///Range of angles in cylinderical coordinates 74 + PHI[0] = solidAngle/2; ///project the solid angle into spherical coords 75 + PHI[1] = asin(0); /// 76 + Z[0] = cos(PHI[0]); ///project the z into spherical coordinates 77 + Z[1] = cos(PHI[1]); /// 78 + range = Z[0] - Z[1]; ///the range of all possible z values. 79 + 80 + T z, theta, phi; /// temporary individual 81 + 82 + std::vector > samples; 83 + 84 + //srand(100); ///set random seed 85 + 86 + for(int i = 0; i < num_samples; i++) ///for each sample 87 + { 88 + z = uniformRandom()*range + Z[1]; ///find a random z based on the solid angle 89 + theta = uniformRandom() * stim::TAU; ///find theta 90 + phi = acos(z); ///project into spherical coord phi 91 + stim::vec3 sph(radius, theta, phi); ///assume spherical 92 + stim::vec3 cart = sph.sph2cart(); ///conver to cartesisn 93 + samples.push_back(cart); ///push into list 94 + } 95 + 96 +///THIS IS DEBUGGING CODE, UNCOMMENT TO CHECK WHETHER THE SURFACE IS WELL SAMPLED! 97 +/* 98 + std::stringstream name; 99 + for(int i = 0; i < num_samples; i++) 100 + name << samples[i].str() << std::endl; 101 + 102 + 103 + std::ofstream outFile; 104 + outFile.open("Sampled Surface.txt"); 105 + outFile << name.str().c_str(); 106 +*/ 107 + 108 + return samples; ///return full list. 109 + } 110 +}; 111 + 112 +} 113 + 114 +#endif ... ...
stim/math/spharmonics.h

 ... ... @@ -5,6 +5,7 @@ 5 5 #include 6 6 #include 7 7 #include 8 +#include 8 9 #include 9 10 10 11 #define WIRE_SCALE 1.001 ... ... @@ -26,7 +27,6 @@ protected: 26 27 double SH(int l, int m, double theta, double phi){ 27 28 std::complex result = boost::math::spherical_harmonic(l, m, phi, theta); 28 29 return result.imag() + result.real(); 29 -// return boost::math::spherical_harmonic_i(l, m, phi, theta); 30 30 } 31 31 32 32 unsigned int coeff_1d(unsigned int l, int m){ ... ... @@ -117,10 +117,10 @@ public: 117 117 } 118 118 119 119 /// Generates a PDF describing the probability distribution of points on a spherical surface 120 - 121 120 /// @param sph_pts is a list of points in spherical coordinates (theta, phi) where theta = [0, 2pi] and phi = [0, pi] 122 121 /// @param l is the maximum degree of the spherical harmonic function 123 122 /// @param m is the maximum order 123 + 124 124 void pdf(std::vector > sph_pts, unsigned int l, int m){ 125 125 126 126 mcBegin( l, m ); //begin spherical harmonic sampling ... ... @@ -134,6 +134,42 @@ public: 134 134 mcEnd(); 135 135 } 136 136 137 + /// Generates a PDF describing the probability distribution of points on a spherical surface 138 + /// @param sph_pts is a list of points in cartesian coordinates 139 + /// @param l is the maximum degree of the spherical harmonic function 140 + /// @param m is the maximum order 141 + /// @param c is the centroid of the points in sph_pts. DEFAULT 0,0,0 142 + /// @param n is the number of points of the surface of the sphere used to create the PDF. DEFAULT 1000 143 + void pdf(std::vector > sph_pts, unsigned int l, int m, stim::vec3 c = stim::vec3(0,0,0), unsigned int n = 1000) 144 + { 145 + std::vector weights; ///the weight at each point on the surface of the sphere. 146 +// weights.resize(n); 147 + unsigned int nP = sph_pts.size(); 148 + std::vector > sphere = stim::Random::sample_sphere(n, 1.0, stim::TAU); 149 + for(int i = 0; i < n; i++) 150 + { 151 + double val = 0; 152 + for(int j = 0; j < nP; j++) 153 + { 154 + stim::vec3 temp = sph_pts[j] - c; 155 + if(temp.dot(sphere[i]) > 0) 156 + val += pow(temp.dot(sphere[i]),4); 157 + } 158 + weights.push_back(val); 159 + } 160 + 161 + 162 + mcBegin(l, m); //begin spherical harmonic sampling 163 + 164 + for(unsigned int i = 0; i < n; i++) 165 + { 166 + stim::vec3 sph = sphere[i].cart2sph(); 167 + mcSample(sph[1], sph[2], weights[i]); 168 + } 169 + 170 + mcEnd(); 171 + } 172 + 137 173 std::string str(){ 138 174 139 175 std::stringstream ss; ... ...