00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef _ABKRAND_TEMPL_CXX_INCLUDED
00043 #define _ABKRAND_TEMPL_CXX_INCLUDED
00044
00045 #ifdef _MSC_VER
00046 #pragma warning(disable:4786)
00047 #endif
00048
00049 #include "abkrand.h"
00050 #include <float.h>
00051 #include <stdio.h>
00052
00053 template <class RK>
00054 inline
00055 unsigned RandomNumberGeneratorT<RK>::_getUnsignedRand()
00056 {
00057 return _lowerB + RK::_getRawUnsigned() % _delta;
00058 }
00059
00060 template <class RK>
00061 inline
00062 double RandomNumberGeneratorT<RK>::_getDoubleRand()
00063 {
00064 return RK::_getRawDouble()*_dDelta +_dLowerB;
00065 }
00066
00067
00068 template<class RK>
00069 RandomNormalT<RK>::operator double()
00070 {
00071 if (_cacheFull)
00072 {
00073 _cacheFull = false;
00074 return _cachedValue;
00075 }
00076 else
00077 {
00078 while(true)
00079 {
00080 double V1,V2,S;
00081 V1 = 2*RK::_getRawDouble()-1;
00082 V2 = 2*RK::_getRawDouble()-1;
00083 S = V1*V1 + V2*V2;
00084 if (S < 1.0)
00085 {
00086 double multiplier = sqrt(-2*log(S)/S);
00087 _cachedValue = _sigma*V1*multiplier + _mu;
00088 _cacheFull = true;
00089 return _sigma*V2*multiplier + _mu;
00090 }
00091
00092 }
00093 }
00094 }
00095
00096 template<class RK>
00097 std::pair<double,double> RandomNormCorrPairsT<RK>::getPair()
00098 {
00099 double x1=_norm;
00100 double x2=_norm;
00101 double z1=_a1*x1+_b1*x2+_mu1;
00102 double z2=_a2*x1-_b2*x2+_mu2;
00103 return std::pair<double,double>(z1,z2);
00104 }
00105 template<class RK>
00106 bool RandomNormCorrTuplesT<RK>::
00107 _findBasis(const vector<vector<double> > &_rho_ij,
00108 vector<vector<double> > &_v_ij)
00109 {
00110 _v_ij.clear();
00111 const unsigned n=_rho_ij.size()+1;
00112 vector<double> zeros(n,0);
00113 _v_ij.insert(_v_ij.end(),n,zeros);
00114 _v_ij[0][0]=1;
00115 unsigned i,j,k;
00116 for (i=1;i<n;i++)
00117 {
00118 double sumsq=0;
00119 for (j=0;j<i;j++)
00120 {
00121
00122
00123 double val=_rho_ij[j][i-j-1];
00124 for (k=0;k<j;k++)
00125 {
00126 val -= _v_ij[i][k]*_v_ij[j][k];
00127 }
00128 val /= _v_ij[j][j];
00129
00130 _v_ij[i][j]=val;
00131 sumsq += val*val;
00132 }
00133
00134 if (sumsq >= 1) return false;
00135
00136
00137
00138
00139 _v_ij[i][i] = sqrt(1-sumsq);
00140
00141 }
00142
00143 return true;
00144 }
00145
00146 template<class RK>
00147 RandomNormCorrTuplesT<RK>::~RandomNormCorrTuplesT()
00148 {
00149 unsigned j;
00150 for (j=0;j<_norm_j.size();j++)
00151 delete _norm_j[j];
00152 }
00153
00154 template<class RK>
00155 RandomNormCorrTuplesT<RK>::
00156 RandomNormCorrTuplesT<RK>(const vector<double> &means,
00157 const vector<double> &stdDevs,
00158
00159
00160
00161
00162
00163 const vector<vector<double> > &corrs,
00164 const char *locIdent,
00165 unsigned counterOverride,
00166 Verbosity verb):_n(means.size()),
00167 _norm_j(_n,NULL),
00168 _y_j(_n,DBL_MAX),
00169 _mu_i(means),
00170 _sigma_i(stdDevs),
00171 _bad(false)
00172 {
00173 char txt[127];
00174 char ourIdent[]="RandomNormCorrTuplesT<RK>";
00175 abkfatal(stdDevs.size()==_n,"Mismatch between size of means and stdDevs");
00176 abkfatal(corrs.size()==_n-1,"Mismatch between size of means and corrs");
00177 unsigned j;
00178 for (j=0;j<_n;j++)
00179 {
00180 sprintf(txt,"%d",j);
00181 char *newIdent =
00182 new char[strlen(txt)+strlen(ourIdent)
00183 +strlen(locIdent)+1];
00184 strcpy(newIdent,locIdent);
00185 strcat(newIdent,ourIdent);
00186 strcat(newIdent,txt);
00187 _norm_j[j] = new RandomNormalT<RK>(0,1,newIdent,counterOverride,verb);
00188 delete [] newIdent;
00189 }
00190
00191 bool success=_findBasis(corrs,_v_ij);
00192 _bad=!success;
00193 }
00194 template<class RK>
00195 void RandomNormCorrTuplesT<RK>::getTuple(vector<double> &tuple)
00196 {
00197 abkfatal(tuple.size()==_n,"Bad tuple size");
00198 abkfatal(!_bad,"Attempt to get tuple from bad RNG");
00199 unsigned i,j;
00200 for (j=0;j<_n;j++)
00201 _y_j[j]=_norm_j[j]->operator double();
00202
00203 for (i=0;i<_n;i++)
00204 {
00205 double val=0;
00206 const vector<double> &v_i=_v_ij[i];
00207 for (j=0;j<=i;j++)
00208 val += v_i[j]*_y_j[j];
00209 val *= _sigma_i[i];
00210 val += _mu_i[i];
00211 tuple[i]=val;
00212 }
00213 }
00214
00215
00216 #endif // !defined (_ABKRAND_TEMPL_CXX_INCLUDED)
00217