Open PaperOpt
OpenPaperOpt/utilities.h
Go to the documentation of this file.
00001 #pragma once
00002 #ifndef UTILITIES_H
00003 #define UTILITIES_H
00004 
00005 
00006 
00007 
00008 #include <stdio.h>
00009 #include <string>
00010 #include <vector>
00011 #include <complex>
00012 #include <stdarg.h>
00013 #include <functional>
00014 #include <algorithm>
00015 #include <math.h>
00016 #include "V3.h"
00017 #include <time.h>
00018 
00019 
00024 #define MIN(a,b)   (((a)<=(b))?(a):(b))
00025 
00028 #define MAX(a,b)   (((a)>=(b))?(a):(b))
00029 
00032 #define ABS(a)     (((a) < 0) ? -(a) : (a))
00033 
00034 
00038 #define FLT_QNAN   0xffc00000
00039 
00040 #define DATA_MOVE(data,dist)    (data)=(double*)(((char*)(data))+(dist))
00041 #define DATA_ADD(data,dist)     ((double*)(((char*)(data))+(dist)))
00042 
00043 #pragma warning(disable:4996)
00044 
00045 using namespace std;
00065 //============================================================================
00075 template <class C> class AutoDelete {
00076 public:
00077 
00081         AutoDelete()           {ptr=0;}
00087         AutoDelete(C* p)       {ptr=p;}
00088         ~AutoDelete()          {delete ptr;ptr=0;}
00089 
00094         C* operator->()  const {return ptr;}
00098         C& operator*()   const {return *ptr;}
00102         C* Ptr()         const {return ptr;}
00106         operator C*()    const {return Ptr();}
00110         void clear()           {delete ptr;ptr=0;}
00115         void set(C* p)         {delete ptr;ptr=p;}
00120         void operator=(C* p)   {set(p);}
00121 
00126         C*   detatch()         {C* p=ptr;ptr=0;return p;}
00127 
00128 private:
00129         AutoDelete(const AutoDelete& p) {} //Deny copy
00130 
00131         C* ptr;
00132 };
00133 
00134 //===============================================================================
00142 template <class C> class AutoDeleteV {
00143 public:
00144         AutoDeleteV()           {ptr=0;}
00145         AutoDeleteV(C* p)       {ptr=p;}
00146         ~AutoDeleteV()          {delete [] ptr;ptr=0;}
00147 
00148         C* operator->()   const {return ptr;}
00149         C& operator*()    const {return *ptr;}
00150         C* Ptr()          const {return ptr;}
00151         operator C*()     const {return Ptr();}
00152 
00153         void clear()            {delete [] ptr;ptr=0;}
00154         void set(C* p)          {delete [] ptr;ptr=p;}
00155         void operator=(C* p)    {set(p);}
00156 
00160         C*   detatch()          {C* p=ptr;ptr=0;return p;}
00161 
00162 private:
00163         AutoDeleteV(const AutoDeleteV& p) {} //Deny copy
00164 
00165         C* ptr;
00166 };
00167 //=============================================================================
00168 
00175 class StdExcept {
00176 public:
00180         StdExcept() {}
00186         StdExcept(const char* format,...){
00187                 char buf[2048];
00188                 va_list(arglist);
00189                 va_start(arglist,format);
00190                 vsnprintf(buf,2048,format,arglist);
00191                 mMsg=buf;
00192                 printf("/n%s/n",buf);
00193         }
00197         string GetMessage() const {return mMsg;}
00198 private:
00199         string mMsg;
00200 };
00201 
00202 
00203 
00204 
00205 //==============================================================================
00206 
00214 template <int numbins>
00215 class SimpleDist {
00216 public:
00217         SimpleDist() {mMin=mBinWidth=0;memset(mF,0,sizeof(mF));}
00218         ~SimpleDist() {}
00219 
00220         int GetDataSize() {return sizeof(*this);}
00221 
00222         void InitFromSamples(double minVal,double maxVal,double* data,int numData,int dataDist);
00223 
00224         double InvF(double y); //Calc F^-1(y), y=[0..1)
00225 
00226 private:
00227         double mMin,mBinWidth;//Start of distributaion and width of bins
00228         double mF[numbins-1]; //The f-function assume 1 in last
00229 };
00230 
00231 template <int numbins>
00232 void SimpleDist<numbins>::InitFromSamples(double minVal,double maxVal,double* data,int numData,int dataDist) 
00233 {
00234         //Sanitycheck parameters
00235         if (numData<2) throw StdExcept("SimpleDist::InitFromSamples: numData<2");
00236         if (minVal>=maxVal) throw StdExcept("SimpleDist::InitFromSamples: minVal(%f)>=maxVal(%f) error",minVal,maxVal);
00237         if (numbins<2) throw StdExcept("SimpleDist::InitFromSamples: numbins<2"); //Well, will compile away...
00238         if (dataDist<4) throw StdExcept("SimpleDist::InitFromSamples: invalid dataDist (%d)",dataDist);
00239 
00240         //Uppdate locals
00241         mMin      = minVal;
00242         mBinWidth = (maxVal-minVal)/(double)(numbins);
00243 
00244         //Accumulate points
00245         int numPnts=0;
00246         int bins[numbins+1]; //+1 to capture case when data==maxVal
00247 
00248         memset(bins,0,sizeof(bins));
00249         for (int i=numData;i;i--) {
00250                 double val=*data;
00251                 data=(double*)(((char*)data)+dataDist);
00252                 if (val>=minVal && val<=maxVal) {
00253                         numPnts++;
00254                         int binNo=(int)((val-minVal)/mBinWidth);
00255                         if (binNo<0 || binNo>=numbins+1) throw StdExcept("SimpleDist<numbins>::InitFromSamples: Dodamn :)"); //TODO: Remove
00256                         bins[binNo]++;
00257                 }
00258         }
00259         //Check that we caught atleast two points
00260         if (numPnts<2) throw StdExcept("SimpleDist::InitFromSamples: Less than 2 points in intervall");
00261 
00262         //Calc f-function
00263         double nPntInv=1.0/numPnts;
00264         int    pntAcc=0;
00265 
00266         for (int i=0;i<(numbins-1);i++) {
00267                 pntAcc+=bins[i];
00268                 mF[i]=pntAcc*nPntInv;
00269         }
00270 }
00271 
00272 //----------------------------------------------------------------------------------------
00273 
00274 template <int numbins>
00275 double SimpleDist<numbins>::InvF(double y) {
00276 
00277         //Binsearch for the bin we'r in
00278         double* f=upper_bound(mF,mF+(numbins-1),y);
00279 
00280         double l=(f==mF)?0.0:*(f-1);       //Left value
00281         double r=(f==mF+(numbins-1))?1.0:*f; //Right value
00282 
00283         //If no samples in bin, return midpos
00284         if (fabs(r-l)<1e-15)
00285                 return ((f-mF)+0.5)*mBinWidth+mMin;
00286 
00287         double pos=mBinWidth*(y-l)/(r-l);  //Ofs in this bin  
00288         pos+=(f-mF)*mBinWidth+mMin;       //Add bin offset
00289         return pos;
00290 }
00291 
00292 
00293 //=================================================================================
00294 
00295 typedef SimpleDist<13> ZDist;
00296 
00297 //=================================================================================
00305 class SubdivPatch {
00306 public:
00307         SubdivPatch() {min=0;max=0;p=0;numPnt=0;}
00308         SubdivPatch(double mi,double ma,double* pp,int np) {min=mi;max=ma;p=pp,numPnt=np;}
00309 
00310         bool operator<(const SubdivPatch& p) const  {return min<p.min;}
00311         bool operator==(const SubdivPatch& p) const {return min==p.min;}
00312 
00313         double  min,max;
00314         double* p;
00315         int    numPnt;
00316 };
00317 
00318 //=================================================================================
00325 class SubdivEnv {
00326 public:
00327         double minVal,maxVal;
00328         double minDelta;
00329         int minPoints;
00330         double maxPatch;
00331         int dataDist;
00332 
00333         vector <SubdivPatch> patches;
00334 };
00335 //=================================================================================
00336 class fiberData {
00337 public:
00338         fiberData() {x=0;y=0;z=0;}
00339         fiberData(double xx,double yy,double zz) {x=xx;y=yy;z=zz;}
00340         bool operator<(const fiberData& f) const {return 1;}
00341         bool operator==(const fiberData& f) const {return 1;}
00342 
00343         double* getZPointer() {return &z;}
00344 
00345         bool compare_x(double xx) const {return x<=xx;}
00346         bool compare_y(double yy) const {return y<=yy;}
00347 
00348 
00349         double x,y,z;
00350 };
00351 //================================================================================
00352 typedef vector<fiberData>  fsamples;
00353 typedef fsamples::iterator fsamplesiter;
00354 
00355 //Predicate-templates
00356 template<class _Tx,class _Ty>
00357 struct compare_x : binary_function<_Tx, _Ty, bool> {
00358         bool operator()(const _Tx& _X, const _Ty& _Y) const
00359         {return _X.compare_x(_Y);}
00360 };
00361 template<class _Tx,class _Ty>
00362 struct compare_y : binary_function<_Tx, _Ty, bool> {
00363         bool operator()(const _Tx& _X, const _Ty& _Y) const
00364         {return _X.compare_y(_Y);}
00365 };
00366 //=================================================================================
00367 
00368 //== Creaton of local_weight(y)
00373 class TreeNode {
00374 public:
00378         TreeNode() {value=0;};
00382         ~TreeNode() {};
00383 
00387         TreeNode* Left()    const {return left;}
00391         TreeNode* Right()   const {return right;}
00395         double    Value()   const {return value;}
00396 
00400         void Left(TreeNode* n)    {left=n;}
00404         void Right(TreeNode* n)   {right=n;}
00408         void Value(double d)      {value=d;}
00409 
00413         void operator+=(double d) {value+=d;}
00414 
00415 private:
00416         AutoDelete<TreeNode> left;
00417         AutoDelete<TreeNode> right;
00418         double               value;
00419 };
00420 
00421 //======================================================================================
00422 
00431 class FiberSample {
00432 public:
00436         int   operator<(const FiberSample& f)  const {return d[0]<f.d[0];}
00440         int   operator==(const FiberSample& f) const {return d[0]==f.d[0] && d[1]==f.d[1] && d[2]==f.d[2];}
00444         double operator[](int idx)              const {return d[idx];}
00445 
00449         double* PtrToFirst()                    {return &(d[0]);}
00450 
00451         double d[3]; //Len,Wid,Curl
00452 };
00453 
00454 //=========================================================================================
00464 namespace p3d{
00465 
00466         static const double gMinBaseLen   = 1000.0/8.0;    //um, stop subdividing base here
00467         static const double gTolerance    = 0.03f;         //%,  itterate untill within this tollerance
00468         static const double gLowTolerance = 0.09f;         //%,  itterate untill within this tollerance if <65% cf
00469         static const double gEnergyMultipler = 1.0f/500.0f;//Angular scaler //TODO: Fit this parameter to samples
00470         extern int GenerateCurlVector(double len,double rad,double formfac,int numSegs,double* angles,int packetsLow=25,int packetsHig=35);
00471 }
00472 //===========================================================================================
00482 namespace p3d{
00483 #define SIMVOL_FLAG_ANGLE   0x0001 
00484 #define SIMVOL_FLAG_CURL    0x0002 
00485 #define SIMVOL_FLAG_POS     0x0004 
00486 #define SIMVOL_FLAG_POS3D   0x0008 
00487 #define SEGT_ROTZ           0x0001
00488 }
00489 
00490 
00491 
00492 #if _MSC_VER >= 1000
00493 #pragma once
00494 #endif // _MSC_VER >= 1000
00495 
00496 //#define NEW_PROP_IN_LAYER 0
00497 
00498 
00499 
00500 
00501 #define EPS 2.220446049250313e-016
00502 #define INF 1e48
00503 #define PI 3.1415926535897932384626433832795
00504 const double THICKNESS_LIMIT = 1e-4;//100*EPS;
00505 
00506 
00507 #include <stdlib.h>
00508 #include <iostream>
00509 #include <complex>
00510 using namespace std;
00511 //Complex number representation
00512 typedef std::complex<double> complex_LC;  
00513 
00514 
00515 
00516 #define R2_IM1 2147483563
00517 #define R2_IM2 2147483399
00518 #define R2_AM (1.0/R2_IM1)
00519 #define R2_IMM1 (R2_IM1-1)
00520 #define R2_IA1 40014
00521 #define R2_IA2 40692
00522 #define R2_IQ1 53668
00523 #define R2_IQ2 52774
00524 #define R2_IR1 12211
00525 #define R2_IR2 3791
00526 #define R2_NTAB 32
00527 #define R2_NDIV (1+R2_IMM1/R2_NTAB)
00528 #define R2_EPS 1.2e-7
00529 #define R2_RNMX (1.0-R2_EPS)
00530 //long rand_idnum;
00531 //=-347;
00532 
00536 inline int InitialiseGenerateRandom(void){
00537         extern long rand_idnum;
00538         srand ( time(NULL) );
00539         rand_idnum = (long)(-rand()/double(RAND_MAX)*1000);
00540         cout << "Random generator initialised: " << rand_idnum << endl;
00541         return(1);
00542 }
00543 
00547 inline double GenerateRandom(void){
00548         extern long rand_idnum;
00549         // FROM JON JENSEN
00550         //----------------------------------------------------------------------------------------
00551         // From Numerical Recipies, slightly modified code, same generator.
00552         int j;
00553         long k;
00554         static long idum2=123456789;
00555         static long iy=0;
00556         static long iv[R2_NTAB];
00557         float  temp;
00558 
00559         if (rand_idnum <= 0) {                            //Initialize.
00560                 if (-(rand_idnum) < 1)                          //Be sure to prevent rand_idnum = 0.
00561                         rand_idnum=1;
00562                 else
00563                         rand_idnum = -(rand_idnum);
00564                 idum2=(rand_idnum);
00565                 for (j=R2_NTAB+7;j>=0;j--) {                    //Load the shuffle table (after 8 warm-ups).
00566                         k=(rand_idnum)/R2_IQ1;
00567                         rand_idnum=R2_IA1*(rand_idnum-k*R2_IQ1)-k*R2_IR1;
00568                         if (rand_idnum < 0)
00569                                 rand_idnum += R2_IM1;
00570                         if (j < R2_NTAB)
00571                                 iv[j] = rand_idnum;
00572                 }
00573                 iy=iv[0];
00574         }
00575 
00576         k=(rand_idnum)/R2_IQ1;                            //Start here when not initializing.
00577         rand_idnum=R2_IA1*(rand_idnum-k*R2_IQ1)-k*R2_IR1; //Compute rand_idnum=(IA1*rand_idnum) % IM1 without
00578         if (rand_idnum < 0)                               //overflows by Schrage's method.
00579                 rand_idnum += R2_IM1;
00580         k=idum2/R2_IQ2;
00581         idum2=R2_IA2*(idum2-k*R2_IQ2)-k*R2_IR2;           //Compute idum2=(IA2*rand_idnum) % IM2 likewise.
00582         if (idum2 < 0)
00583                 idum2 += R2_IM2;
00584         j=iy/R2_NDIV;                                     //Will be in the range 0..NTAB-1.
00585         iy=iv[j]-idum2;                                   //Here rand_idnum is shufled, rand_idnum and idum2 are
00586         //combined to generate output.
00587         iv[j] = rand_idnum;
00588         if (iy < 1)
00589                 iy += R2_IMM1;
00590         if ((temp=(float)R2_AM*iy) > R2_RNMX)                    //Because users don't expect endpoint values.
00591                 return (float)R2_RNMX;
00592         else
00593                 return temp;
00594 };
00595 
00596 
00597 
00598 
00599 inline double square(complex_LC a)
00600 {
00601         double temp = a.real()*a.real() + a.imag()*a.imag();
00602         return (temp*temp);
00603 }
00604 
00605 // MIN and MAX functions
00606 inline double grMax(double n1,double n2){if (n1 > n2){return n1;} else return n2;}
00607 inline double grMin(double n1, double n2){if (n1 < n2){return n1;} else return n2;}
00608 
00609 
00610 
00611 int CalcQ(const std::complex<double> n1, const std::complex<double> n2,const V3<double> wp_lmn_local, const V3<double> wp_lmn_new,
00612                   double *Qss, double *Qsp, double *Qps, double *Qpp);
00613 
00614 int MicroScattering2(V3<double>& wp_lmn_local, V3<double>& wp_pol_local, double wp_s_local, 
00615                                          double wp_p_local, complex_LC refr_i,complex_LC refr_t,V2<float> rms,
00616                                          double lambda, double &reflfactor);
00617 
00618 // Implement complex arcsin
00619 complex<double> cmplxasin(complex<double> z);
00620 
00621 
00622 
00623 #endif