00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00022 #ifndef MT_std_h
00023 #define MT_std_h
00024
00025
00026
00027 #include <iostream>
00028 #include <iomanip>
00029 #include <fstream>
00030 #include <sstream>
00031 #include <math.h>
00032 #include <vector>
00033 #include <typeinfo>
00034 #if defined MT_MSVC || defined MT_Windows || defined WIN32 || defined _WIN32 || defined _MSC_VER
00035 # undef MT_MSVC
00036 # define MT_MSVC
00037 # include<limits>
00038 # include<time.h>
00039 # include<sys/timeb.h>
00040 # ifdef MT_QT
00041 # include<windows.h>
00042 # undef min //I hate it that windows defines these macros!
00043 # undef max
00044 # undef NOUNICODE
00045 # define NOUNICODE
00046
00047
00048
00049
00050
00051 # endif
00052 # pragma warning(disable: 4305 4244 4250 4355 4786)
00053 #else
00054 # include<unistd.h>
00055 # include<sys/time.h>
00056 # include<sys/times.h>
00057 # include<sys/resource.h>
00058 #endif
00059
00060 #ifdef MT_doxy
00061 # define DOX !\brief
00062 #endif
00063
00064
00066 namespace MT{
00067 inline int debugBreakpoint(){
00068 char c; c=0;
00069
00070 return 0;
00071 }
00072 }
00073
00074
00075
00076 #ifndef HALT
00077 # define MT_MSG(msg) { std::cerr <<__FILE__ <<':' <<__LINE__ <<": " <<msg <<std::endl; }
00078 # define HALT(msg) { std::cerr <<"HALT:" <<__FILE__ <<':' <<__LINE__\
00079 <<":\n --- "<<msg<<" --- "<<std::endl; MT::debugBreakpoint(); abort();}
00080 #endif
00081
00082
00083
00084 #ifndef MT_NOCHECK
00085 # define CHECK(cond,msg) if(!(cond)) HALT("CHECK failed: "<<msg);
00086 #else
00087 # define CHECK(cond,msg)
00088 #endif
00089
00090
00091
00092 #define MT_PI 3.14159265358979323846
00093 #define MT_2PI (2.*3.14159265358979323846)
00094 #define MT_LN2 0.69314718055994528622676398299518041312694549560546875
00095 typedef unsigned char byte;
00096 typedef unsigned int uint;
00097 typedef void (*voidFct)();
00098
00099
00100
00101 #ifndef forall
00102 #define forall(i,a) for(a.First(i) ;a.CheckNext(i); a.Next(i))
00103 #define forall_rev(i,a) for(a.Last(i) ;a.CheckPrev(i); a.Prev(i))
00104 #define forall_save(i,j,a) for(a.First(i),j=i,a.Next(j);a.CheckNext(i);i=j,a.Next(j))
00105 #define forall_rev_save(i,j,a) for(a.Last(i) ,j=i,a.Prev(j);a.CheckPrev(i);i=j,a.Prev(j))
00106 #endif
00107
00108
00109
00110 #define stdInPipe(type)\
00111 inline std::istream& operator>>(std::istream& is,type& x){ x.read(is);return is; }
00112 #define stdOutPipe(type)\
00113 inline std::ostream& operator<<(std::ostream& os,const type& x){ x.write(os); return os; }
00114 #define stdPipes(type)\
00115 inline std::istream& operator>>(std::istream& is,type& x){ x.read(is);return is; }\
00116 inline std::ostream& operator<<(std::ostream& os,const type& x){ x.write(os); return os; }
00117 #define fwdStdPipes(type)\
00118 inline std::istream& operator>>(std::istream& is,type& x);\
00119 inline std::ostream& operator<<(std::ostream& os,const type& x);
00120
00121
00122
00123 #define OUTHEX(y) "0x" <<std::hex <<*((unsigned long*)&y) <<std::dec
00124 #define INHEX(y) std::hex >>*((unsigned long*)&y) >>std::dec
00125
00126
00127
00128
00129 #ifndef MT_doxy
00130
00131 template<class T>
00132 class basetype{
00133 public:
00134 T x;
00135 basetype():x(){};
00136 basetype(const T _x):x(_x){};
00137
00138 operator T() const{ return x; }
00139 void read(std::istream& is){ is >>x; }
00140 void write(std::ostream& os) const{ os <<x; }
00141 };
00142 template<class T> stdInPipe(basetype<T>);
00143 template<class T> stdOutPipe(basetype<T>);
00144
00145 namespace MT{
00146 typedef basetype<byte> Byte;
00147 typedef basetype<int> Int;
00148 typedef basetype<float> Float;
00149 typedef basetype<double> Double;
00150 }
00151 #endif
00152
00153
00154 namespace MT{
00155 inline char skip(std::istream&,char* skipchars=" \n\r\t");
00156 }
00158 inline std::istream& operator>>(std::istream& is,const char* str){
00159 uint i,n=strlen(str);
00160 char *buf=new char [n+1]; buf[n]=0;
00161 MT::skip(is," \n\r\t");
00162 is.read(buf,n);
00163 if(!is.good() || strcmp(str,buf)){
00164 for(i=n;i--;) is.putback(buf[i]);
00165 is.setstate(std::ios::failbit);
00166 std::cout <<"WARNING: scanning of constant string `" <<str
00167 <<"' failed! (read instead: `" <<buf <<"')" <<std::endl;
00168 }
00169 delete[] buf;
00170 return is;
00171 }
00173 inline std::istream& operator>>(std::istream& is,char* str){
00174 return is >>(const char*)str;
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 namespace MT{
00186 extern int argc;
00187 extern char** argv;
00188 extern std::ifstream cfgFile;
00189 extern bool cfgOpenFlag;
00190 extern std::vector<void*> parameters;
00192 extern bool IOraw;
00193
00195 std::ofstream& log(const char *name="MT.log",bool _nolog=false);
00196
00198 void open(std::ofstream& fs,const char *name,char* errmsg="");
00199
00201 void open(std::ifstream& fs,const char *name,char* errmsg="");
00202
00206 template<class T>
00207 void save(const T& x,const char *filename){
00208 std::ofstream file;
00209 MT::open(file,filename);
00210 file <<x;
00211 file.close();
00212 }
00213
00217 template<class T>
00218 void load(T& x,const char *filename){
00219 std::ifstream file;
00220 MT::open(file,filename);
00221 file >>x;
00222 file.close();
00223 }
00224
00226 inline bool contains(const char* s,char c){
00227 for(uint i=0;s[i];i++) if(s[i]==c) return true;
00228 return false;
00229 }
00230
00232 inline char skip(std::istream& is,char* skipchars){
00233 char c;
00234 do{ c=is.get(); } while(contains(skipchars,c));
00235 is.putback(c);
00236 return c;
00237 }
00238
00240 inline void skipLine(std::istream& is){
00241 char c;
00242 do{ c=is.get(); } while(c!='\n');
00243 }
00244
00246 byte bit(byte *str,uint i);
00247
00249 void flip(byte& b,uint i);
00250
00252 void flip(int& b,uint i);
00253
00256 double modMetric(double x,double y,double mod);
00257
00259 double sign(double x);
00260
00262 double linsig(double x);
00263
00264 void constrain(float& x,float a,float b);
00265
00267 float phi(float dx,float dy);
00268
00271 inline double DIV(double x,double y,bool force=false){
00272 if(x==0.) return 0.;
00273 if(force){ if(y==0.) return 0.; }else CHECK(y!=0,"Division by Zero!");
00274 return x/y;
00275 }
00276
00277 inline double sigmoid11(double x){ return x/(1.+::fabs(x)); }
00278
00279 template<class T> T MIN(T a,T b){ return a<b?a:b; }
00280 template<class T> T MAX(T a,T b){ return a>b?a:b; }
00281
00283 double approxExp(double x);
00284
00286 double Log(double x);
00287
00289 uint Log2(uint n);
00290
00292 double sqr(double x);
00293
00296 double realTime();
00297
00300 double cpuTime();
00301
00305 double sysTime();
00306
00309 double totalTime();
00310
00312 char *date();
00313
00315 void wait(double sec);
00316
00318 void wait();
00319
00321 long mem();
00322
00324 void resetTimer();
00325
00327 double getTimer(bool reset=true);
00328
00330 void init(int _argc, char *_argv[]);
00331
00333 bool checkOption(const char *tag);
00334
00336 bool getOption(const char *tag,char* &option);
00337
00341 void openConfigFile(char* name=0);
00342
00343 #ifdef MT_QT
00344
00345 void initQt();
00346 #ifndef MT_doxy
00347
00348 struct InitQt{ InitQt(){ initQt(); } };
00349 #endif
00350 #else
00351 inline void initQt(){ MT_MSG("Warning: initQt without QT configured"); }
00352 #endif
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362 namespace MT{
00367 template<class type>
00368 class Parameter{
00369 public:
00370 const char* typeName;
00371 type value,Default;
00372 char* tag;
00373 bool initialized,hasDefault;
00374
00375
00376 public:
00378
00380 Parameter(char* _tag){
00381 typeName=typeid(type).name();
00382 MT::parameters.push_back(this);
00383 initialized=false;
00384 tag=_tag;
00385 hasDefault=false;
00386 };
00387
00390 Parameter(char* _tag,const type& _default){
00391 typeName=typeid(type).name();
00392 MT::parameters.push_back(this);
00393 initialized=false;
00394 tag=_tag;
00395 hasDefault=true;
00396 Default=_default;
00397 };
00398
00399 ~Parameter(){
00400 std::vector<void*>::iterator it;
00401 for(it=MT::parameters.begin();it!=MT::parameters.end();it++)
00402 if(*it==this){ MT::parameters.erase(it); return; }
00403 }
00404
00406
00408 operator type(){ if(!initialized) initialize(); return value; }
00409
00411 type& operator()(){ if(!initialized) initialize(); return value; }
00412
00413
00415
00417 type& operator=(const type v){ initialized=true; value=v; return value; }
00418
00420 void setTag(char* _tag){ tag=_tag; }
00421
00425 void reInitialize(){ initialized=false; }
00426
00427
00429
00433 bool grabFromCmdLine(){
00434 char* opt;
00435 if(!getOption(tag,opt)) return false;
00436 std::istringstream s(opt);
00437 s >>value;
00438 if(s.fail()) HALT("error when reading parameter from command line: " <<tag);
00439 return true;
00440 }
00441
00445 bool grabFromCfgFile(){
00446 if(!cfgOpenFlag){
00447 log() <<"..." <<std::endl;
00448 openConfigFile();
00449 log() <<std::setw(40) <<"..." <<": " <<std::setw(5);
00450 }
00451 cfgFile.clear();
00452 cfgFile.seekg(std::ios::beg);
00453 if(!cfgFile.good()) return false;
00454
00455 unsigned n=strlen(tag);
00456 char *buf=new char [n+2]; memset(buf,0,n+2);
00457 while(cfgFile.good()){
00458 memmove(buf,buf+1,n);
00459 buf[n]=cfgFile.get();
00460 if(buf[n]==' ' || buf[n]==':' || buf[n]=='='){ buf[n]=0; if(!strcmp(tag,buf)) break; buf[n]=':'; }
00461 };
00462 delete[] buf;
00463
00464 if(!cfgFile.good()) return false;
00465
00466 skip(cfgFile," :=\n\r\t");
00467 cfgFile >>value;
00468
00469 if(cfgFile.fail()) HALT("error when reading parameter " <<tag);
00470 return true;
00471 }
00473
00474 private:
00475 void initialize(){
00476 if(!initialized){
00477 if(!cfgOpenFlag) openConfigFile();
00478 initialized=1;
00479 if(!tag) HALT("uninitialized parameter without tag!");
00480 log() <<std::setw(20) <<tag <<": " <<std::setw(5);
00481 log().flush();
00482
00483 if(grabFromCmdLine()){
00484 log() <<value <<" [" <<typeid(value).name() <<"] (cmd line!)" <<std::endl;
00485 return;
00486 }
00487
00488 if(grabFromCfgFile()){
00489 log() <<value <<" [" <<typeid(value).name() <<"]" <<std::endl;
00490 return;
00491 }
00492
00493 if(hasDefault){
00494 value=Default;
00495 log() <<value <<" [" <<typeid(value).name() <<"] (default!)"<<std::endl;
00496 return;
00497 }
00498
00499 HALT("could not initialize parameter `" <<tag
00500 <<"': parameter has no default;\n either use command option `-"
00501 <<tag <<" ...' or specify `"
00502 <<tag <<"= ...' in the config file `MT.cfg'");
00503 }
00504 }
00505 };
00506
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516 namespace MT{
00520 class Rnd{
00521 private:
00522 bool ready;
00523 int rpoint;
00524 long rfield[256];
00525
00526
00527 public:
00529 Rnd(){ ready=false; };
00530
00531
00532 public:
00533
00534 unsigned long seed(unsigned long n);
00535
00537 unsigned long seed();
00538
00540 unsigned long clockSeed();
00541
00542 public:
00543
00544 inline uint num(){ if(!ready) seed(); return (uint)rnd250() >> 5; }
00546 inline uint operator ()(){ return num(); }
00548 inline uint num(uint limit){
00549 CHECK(limit,"zero limit in rnd.num()"); return num() % limit; }
00550 inline uint num(int lo,int hi){ return lo+num(hi-lo+1); }
00552 inline uint operator ()(uint i){ return num(i); }
00553 inline uint operator ()(int lo,int hi){ return num(lo,hi); }
00555 inline double uni(){ return ((double)num(1<<22))/(1<<22); }
00557 inline double uni(double low,double high){ return low+uni()*(high-low); }
00559 double gauss(double stdDev);
00563 uint poisson(double mean);
00565
00566
00567 private:
00568 inline long rnd250(){
00569 rpoint = (rpoint+1) & 255;
00570 return rfield[rpoint] = rfield[(rpoint-250) & 255]
00571 ^ rfield[(rpoint-103) & 255];
00572 }
00573
00574 void seed250(long seed);
00575 };
00576
00578 extern Rnd rnd;
00579 }
00580
00581
00582
00583
00584
00585
00586
00587
00588 namespace MT{
00589 typedef std::iostream IOStream;
00590
00597 class String:public IOStream{
00598 private:
00599 class StringBuf:public std::streambuf{
00600 public:
00601 std::vector<char> arr;
00602 const char* ptr() const{ return &(arr[0]); }
00603 char* ptr(){ return &(arr[0]); }
00604 virtual int overflow(int C = EOF){
00605 arr[arr.size()-1]=C; arr.push_back(0); resetI();
00606 return C;
00607 }
00608 void resetI(){ setg(ptr(),ptr(),ptr()+arr.size()-1); }
00609 char *getIpos(){ return gptr(); }
00610 void setIpos(char* p){
00611 setg(ptr(),p,ptr()+arr.size()-1);
00612 }
00613 };
00614
00615 public:
00616 StringBuf buf;
00618 String():IOStream(&buf){ clr(); }
00620 String(const String& s):IOStream(&buf){ this->operator=(s); }
00622 String(const char* s):IOStream(&buf){ this->operator=(s); }
00624 IOStream& str(){ return (IOStream&)(*this); }
00627 operator char*(){ return buf.ptr(); }
00629 operator const char*() const{ return buf.ptr(); }
00631 char* ptr(){ return buf.ptr(); }
00633 char operator()(uint i){ return buf.arr[i]; }
00635 void operator=(const String& s){ buf.arr=s.buf.arr; buf.resetI(); }
00637 void operator=(const char *s){ buf.arr.resize(strlen(s)+1); memmove(buf.ptr(),s,strlen(s)+1); buf.resetI(); }
00639 bool operator==(const char *s){ return !strcmp(buf.ptr(),s); }
00641 bool operator==(const String& s){ return !strcmp(buf.ptr(),s.buf.ptr()); }
00643 String& clr(){ buf.arr.resize(1); buf.arr[0]=0; clear(); return *this; }
00647 String& resetI(){ buf.resetI(); clear(); return *this; }
00648 char *getIpos(){ return buf.getIpos(); }
00649 void setIpos(char* p){buf.setIpos(p); }
00650
00652 uint N() const{ return buf.arr.size()-1; }
00655 template<class T>
00656 String operator+(const T& v) const{
00657 String news(*this); news <<v; return news;
00658 }
00660 void write(std::ostream& os) const{ os <<buf.ptr(); }
00663 void read(std::istream& is,char *stopSymbols="\n\r"){
00664 buf.arr.resize(0);
00665 char c=is.get();
00666 while(is.good() && !MT::contains(stopSymbols,c)){
00667 buf.arr.push_back(c); c=is.get(); }
00668 is.putback(c);
00669 is.clear();
00670 buf.arr.push_back(0);
00671 resetI();
00672 }
00673 };
00674 }
00675 stdPipes(MT::String);
00676
00677 #define STRING(x) ((MT::String&)(MT::String().str()<<x)).ptr()
00678
00679
00680
00681
00682
00683
00684
00685
00686 #ifndef MT_doxy
00687 namespace MT{
00689 class Color{
00690 public:
00691 float
00692 r,
00693 g,
00694 b;
00695
00697 friend inline Color operator+(const Color& c1,const Color& c2){
00698 return Color(c1.r+c2.r, c1.g+c2.g, c1.b+c2.b); }
00699
00701 friend inline Color operator*(float f,const Color& c2){
00702 return Color(f*c2.r, f*c2.g, f*c2.b); }
00703
00704 public:
00706 Color(){ setGray(1.); }
00707
00709 Color(float red,float green,float blue){ setRgb(red,green,blue); }
00710
00712 Color& operator=(const Color& c){ r=c.r; g=c.g; b=c.b; return *this; }
00713
00715 bool operator!(){ if(r==0. && g==0. && b==0.) return true; return false; }
00716
00718 operator const float*() const{ return (float*)this; }
00719
00721 void setIndex(unsigned i){
00722 if(!i) setRgb(0.,0.,0.); else setHsv(((i-1)*63)%360,255,255); }
00723
00725 void setRgb(float red,float green,float blue){ r=red; g=green; b=blue; }
00726
00728 void setRgbByte(byte red,byte green,byte blue){
00729 r=(float)red/255.; g=(float)green/255.; b=(float)blue/255.; }
00730
00732 void setHsv(int hue,byte sat,byte val){
00733 float h=(double)hue/60.,s=(double)sat/255.,v=(double)val/255.;
00734 h=fmod(h,6);
00735 r=g=b=0.;
00736 if(h<=1.) { r=v; g=v*h; }
00737 if(h>1. && h<=2.){ g=v; r=v*(2.-h); }
00738 if(h>2. && h<=3.){ g=v; b=v*(h-2.); }
00739 if(h>3. && h<=4.){ b=v; g=v*(4.-h); }
00740 if(h>4. && h<=5.){ b=v; r=v*(h-4.); }
00741 if(h>5. && h<=6.){ r=v; b=v*(6.-h); }
00742 r=s*r+(1-s)*v;
00743 g=s*g+(1-s)*v;
00744 b=s*b+(1-s)*v;
00745 }
00746
00748 void setTemp(float temp){
00749 Color hot(1.,0.,0.),middle(1.,1.,0.),cold(0.,0.,1.);
00750 if(temp>1.) temp=1.;
00751 if(temp<0.) temp=0.;
00752 if(temp>.5){ temp=2.*temp-1.; *this=temp*hot + (1.-temp)*middle; }
00753 else{ temp=2.*temp; *this=temp*middle + (1.-temp)*cold; }
00754 }
00755
00757 void setTemp2(float temp){
00758 Color r(1.,0.,0.),y(1.,1.,0.),zero(.5,.5,.5),g(0.,1.,0.),b(0.,0.,1.);
00759 if(temp>1.) temp=1.;
00760 if(temp<-1.) temp=-1.;
00761 if(temp>.5){ temp=2.*temp-1.; *this=temp*r + (1.-temp)*y; return; }
00762 if(temp>.0){ temp=2.*temp; *this=temp*y + (1.-temp)*zero; return; }
00763 if(temp>-.5){ temp=-2.*temp; *this=temp*g + (1.-temp)*zero; return; }
00764 { temp=-2.*temp-1.;*this=temp*b + (1.-temp)*g; return; }
00765 }
00766
00768 void setGray(float gray){ if(gray<0) gray=0.; if(gray>1) gray=1.; r=g=b=gray; }
00769
00771 void getRgb(byte& R,byte& G,byte& B) const{
00772 R=(byte)(255.*r); G=(byte)(255.*g); B=(byte)(255.*b); }
00773
00775 float getGray() const{ return (r+g+b)/3.; }
00776
00778 void whiten(float f){
00779 if(f>1.) f=1.; else if(f<0.) f=0.;
00780 r+=f*(1.-r); g+=f*(1.-g); b+=f*(1.-b);
00781 }
00782
00784 void blacken(float f){
00785 if(f>1.) f=1.; else if(f<0.) f=0.;
00786 r-=f*r; g-=f*g; b-=f*b;
00787 }
00788
00790 void mix(Color& A,Color& B,float f=.5){
00791 if(f>1.) f=1.; else if(f<0.) f=0.;
00792 r=f*A.r+(1.-f)*B.r;
00793 g=f*A.g+(1.-f)*B.g;
00794 b=f*A.b+(1.-f)*B.b;
00795 }
00796
00798 void mixAdd(Color& A,Color& B,float f=.5){
00799 if(f>1.) f=1.; else if(f<0.) f=0.;
00800 r=1.-f*(1.-A.r)+(1.-f)*(1.-B.r);
00801 g=1.-f*(1.-A.g)+(1.-f)*(1.-B.g);
00802 b=1.-f*(1.-A.b)+(1.-f)*(1.-B.b);
00803 }
00804
00806 void mixSub(Color& A,Color& B,float f=.5){
00807 if(f>1.) f=1.; else if(f<0.) f=0.;
00808 r=1.-::pow(1.f-A.r,f)*::pow(1.f-B.r,1.f-f);
00809 g=1.-::pow(1.f-A.g,f)*::pow(1.f-B.g,1.f-f);
00810 b=1.-::pow(1.f-A.b,f)*::pow(1.f-B.b,1.f-f);
00811 }
00812
00814 void min(Color& A,Color& B){
00815 r=A.r<B.r?A.r:B.r;
00816 g=A.g<B.g?A.g:B.g;
00817 b=A.b<B.b?A.b:B.b;
00818 }
00819
00821 void write(std::ostream& os) const{ os <<"(" <<r <<":" <<g <<":" <<b <<")"; }
00822
00824 void read(std::istream& is){ is >>"(" >>r >>":" >>g >>":" >>b >>")"; }
00825 };
00826 }
00827 stdPipes(MT::Color);
00828 #endif
00829
00830
00831
00832
00833
00834
00835
00836 void gnuplot(const char* command);
00837 void gnuplotEPS(const char* file,const char* command);
00838
00839
00840
00841
00842
00843
00844
00845 #ifdef MT_IMPLEMENTATION
00846 # include"std.cpp"
00847 #endif
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 using std::ofstream;
00859 using std::ifstream;
00860 using MT::rnd;
00861 using MT::Color;
00862 using MT::Parameter;
00863 using MT::String;
00864
00865
00866 #endif