📄 rand.c
字号:
sum += value; sumOfSqu += value*value; if (value > sampleMax) sampleMax = value; if (value < sampleMin) sampleMin = value; };void FloatRandomStream::CollectStat(float value) { count++; sum += value; sumOfSqu += value*value; if (value > sampleMax) sampleMax = value; if (value < sampleMin) sampleMin = value; };DiscreteUniform::DiscreteUniform(int n, int stream) { this->stream = stream; this->n = n; statFlag = 2; mean = (n+1)*0.5; if (n == 1){ std = 0; } else { std = sqrt((n*n-1)/(12.0)); }; };int DiscreteUniform::Draw() { int result; float sample = rint(n)*Uniform(this->stream); #if defined(linux ) || (defined(i386) && defined(sun)) result = int(rint(floor(sample))) + 1; // I hope that was the right idea#else result = irint(floor(sample)) + 1;#endif if (statFlag == 2) CollectStat(result); return result; };void DiscreteUniform::PrintProfile() { printf("\n DiscreteUniform [1-%d] generator (%f, %f)",n,mean,std); };Choose::Choose(float prob, int stream) { this->stream = stream; this->prob = prob; statFlag = 2; mean = prob; std = sqrt(prob*(1-prob)); };int Choose::Draw() { int sample; sample = (Uniform(this->stream) <= prob) ? 1 : 0; if (statFlag & 2) CollectStat(sample); return sample; };void Choose::PrintProfile() { printf("\n Choose[%f] generator (%f, %f)",prob,mean,std); }Uniform::Uniform(float low, float high, int stream) { this->stream = stream; this->low = low; this->high = high; statFlag = 2; mean = (low+high)*0.5; std = (high-low)/sqrt(12.0); };float Uniform::Draw() { double sample = low+(high-low)*Uniform(this->stream); if (statFlag == 2) CollectStat(sample); return sample; };void Uniform::PrintProfile() { printf("\n Uniform [%f,%f] generator (%f, %f)",low,high,mean,std); };Uniform01::Uniform01(int stream) { this->stream = stream; statFlag = 2; mean = 0.5; std = sqrt(1.0/12.0); };float Uniform01::Draw() { double sample = Uniform(this->stream); if (statFlag == 2) CollectStat(sample); return sample; };void Uniform01::PrintProfile() { printf("\n Uniform [0,1] generator (%f, %f)",mean,std); };Exponential::Exponential(float mean, int stream) { this->stream = stream; this->mean = mean; this->std = mean; statFlag = 2;}float Exponential::Draw(){ float sample = -mean * ( log ( Uniform(this->stream))); if (statFlag == 2) CollectStat(sample); return sample; };void Exponential::PrintProfile() { printf("\n Exponential(%f) generator (%f, %f)",mean,mean,std); };HyperExp::HyperExp(float mean, float variance, int stream) { float cx2; this->stream = stream; this->mean = mean; this->std = sqrt(variance); cx2 = variance/ (mean * mean); alpha = 1/(1 + cx2); mu1 = mean * (1/( 1 + sqrt( 1/(alpha - 1.0)*(cx2 -1)/2))); mu2 = mean * (1/( 1 - sqrt((1/(1 - alpha) - 1) * (cx2 -1)/2)));}HyperExp::HyperExp(float alpha, float mu1, float mu2, int stream) { this->stream = stream; this->alpha = alpha; this->mu1 = mu1; this->mu2 = mu2; mean = alpha*mu1 + (1 - alpha)*mu2; std = sqrt(alpha*mu1*mu1 + (1 - alpha)*mu2*mu2); std = sqrt(2*(alpha*mu1*mu1 + (1 - alpha)*mu2*mu2) - (alpha*mu1+(1-alpha)*mu2)*(alpha*mu1+(1-alpha)*mu2));}float HyperExp::Draw(){ float sample; if (Uniform(stream) <= alpha) sample = -log(Uniform(stream))*mu1; else sample = -log(Uniform(stream))*mu2; CollectStat(sample); return sample;}void HyperExp::PrintProfile() { printf("\nHyperexponential[%f, %f,%f] generator (%f, %f)", alpha,mu1,mu2,mean,std);}Normal::Normal(float mean, float sigma, int stream) { this->stream = stream; this->mean = mean; this->std = sigma; statFlag = 2; };float Normal::Draw() { float v1, v2; float sample; do { v1 = - log(Uniform(this->stream)); v2 = - log(Uniform(this->stream)); } while( (2.0* v1) < ((v2 - 1.0)*(v2 - 1.0))); if (Uniform(this->stream) < 0.5) v2 *= -1; sample = std * v2 + mean; if (statFlag == 2) CollectStat(sample); return sample; };void Normal::PrintProfile() { printf("\n Normal[%f,%f] generator (%f, %f)",mean,std,mean,std); };LogNormal::LogNormal(float mean, float sigma, int stream) { this->stream = stream; this->mean = mean; this->std = sigma; statFlag = 2; };float LogNormal::Draw() { float v1, v2; float sample; do { v1 = - log(Uniform(this->stream)); v2 = - log(Uniform(this->stream)); } while( (2.0* v1) < ((v2 - 1.0)*(v2 - 1.0))); if (Uniform(this->stream) < 0.5) v2 *= -1; sample = exp(std * v2 + mean); if (statFlag == 2) CollectStat(sample); return sample; };void LogNormal::PrintProfile() { printf("\n LogNormal[%f,%f] generator (%f, %f)",mean,std,mean,std); };Gamma::Gamma(float alpha, float beta, int stream) { this->alpha = alpha; this->beta = beta; mean = alpha/beta; std = sqrt(alpha)/beta; statFlag = 2;}float GammaDist(int stream, float alpha, float beta) { float a, v1, v2; a = alpha - 1.0; do { v1 = -log( Uniform(stream)); v2 = -log( Uniform(stream)); } while ( v2 < a* (v1 - log(v1) - 1.0)); return alpha/beta*v1; };float Gamma::Draw() { float sample = GammaDist(this->stream,alpha,beta); if (statFlag == 2) CollectStat(sample); return sample; };void Gamma::PrintProfile(){ printf("\n Gamma [%f, %f] generator (%f, %f)",alpha,beta,mean,std);}Beta::Beta(float alpha, float beta, int stream) { this->alpha = alpha; this->beta = beta; statFlag = 2; mean = alpha/(alpha + beta); std = sqrt((alpha*beta / (alpha + beta + 1))/((alpha + beta)*(alpha + beta)));}float Beta::Draw(){ float y1, y2, sample; y1 = GammaDist(stream,alpha,beta); y2 = GammaDist(stream,alpha,beta); sample = y1/(y1+y2); if (statFlag == 2) CollectStat(sample); return sample;}void Beta::PrintProfile() { printf("\n Beta[%f, %f] generator (%f, %f)",alpha,beta,mean,std); };GeneralCDF::GeneralCDF(int n, float* v, float* p , int stream) { int i; this->n = n; this->v = new float[n]; this->p = new float[n]; q = new float[n]; this->v[0] = v[0]; this->p[0] = p[0]; this->q[0] = p[0]; for(i=1; i < n; i++){ this->v[i] = v[i]; this->p[i] = p[i]; this->q[i] = p[i] + p[i-1]; } }float GeneralCDF::Draw() { float sample, result; sample = Uniform(stream); result = v[binary_search(0, n-1, q, sample)]; CollectStat(result); return result;}GeneralCDF::~GeneralCDF(){ delete this->v; delete this->p; delete this->q;}void GeneralCDF::PrintProfile(){ printf("\nGeneral CDF generator (%f, %f)",mean,std);}int binary_search(int low, int high, float* q, float val){ int mid; while (low <= high) { mid = (low + high)/2; if (q[mid] == val) return mid; else if (q[mid] < val) { low = mid + 1; return binary_search(low, high, q, val); } else { high = mid - 1; return binary_search(low, high, q, val); } } return low;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -