ctorture.cxx

Go to the documentation of this file.
00001 // @(#)root/test:$Id: ctorture.cxx 36320 2010-10-12 19:00:12Z brun $
00002 // Author: Federico Carminati    22/04/2004
00003 
00004 // test program for the class TComplex
00005 
00006 #include <Riostream.h>
00007 #include <TRandom.h>
00008 #include <TComplex.h>
00009 
00010 Double_t Error(TComplex a, TComplex b) 
00011 {return 2*TComplex::Abs(a-b)/(a.Rho()+b.Rho());}
00012 
00013 void Verify(const TComplex a, const TComplex b, 
00014            Double_t epsmin, Double_t epsmax, 
00015            const char* where, Int_t & ifail, Double_t &serr)
00016 {
00017   Double_t err=Error(a,b);
00018   serr+=err;
00019   if(epsmin<err) {
00020     ifail++;
00021     if(err<epsmax) {
00022       printf("Fail %s %e\n",where,err);
00023       cout << a << endl;
00024       cout << b << endl;
00025     }
00026   }
00027 }
00028            
00029 void Summary(const char* title, Int_t ifail, Double_t serr, Int_t np)
00030 {
00031   printf("Results for %s\n",title);
00032   printf("Fail= %5.2f%%, av err= %e\n",100.*ifail/np,serr/np);
00033 }
00034 
00035 
00036 int main () {
00037   //
00038   // Torture for complex numbers
00039   //
00040 
00041   const Int_t np=10000;
00042   Int_t i;
00043   Int_t ifail;
00044   Double_t serr;
00045   Double_t x;
00046   char title[20];
00047   TComplex a,b,c,d,e;
00048 
00049   // Torture Square roots
00050   serr=0;
00051   ifail=0;
00052   strcpy(title,"Sqrt");
00053   for(i=0; i<np; i++) {
00054     a=TComplex(10*(1-2*gRandom->Rndm()),10*(1-2*gRandom->Rndm()));
00055     b=a*a;
00056     c=TComplex::Sqrt(b);
00057     // Cater for the fact that there are two roots!
00058     if(a.Re()*c.Re()<0)  c*=-1;
00059     Verify(a,c,1e-14,1e10,title,ifail,serr);
00060   }
00061   Summary(title,ifail,serr,np);
00062 
00063   // Torture exp and log
00064   serr=0;
00065   ifail=0;
00066   strcpy(title,"Exp&Log");
00067   for(i=0; i<np; i++) {
00068     a=TComplex(10*(1-2*gRandom->Rndm()),10*(1-2*gRandom->Rndm()));
00069     b=TComplex::Log(a);
00070     c=TComplex::Exp(b);
00071     Verify(a,c,1e-14,1e10,title,ifail,serr);
00072   }
00073   Summary(title,ifail,serr,np);
00074 
00075   // Torture sin and asin
00076   serr=0;
00077   ifail=0;
00078   strcpy(title,"Sin&ASin");
00079   for(i=0; i<np; i++) {
00080     a=TComplex(10*(1-2*gRandom->Rndm()),10*(1-2*gRandom->Rndm()));
00081     b=TComplex::ASin(a);
00082     c=TComplex::Sin(b);
00083     Verify(a,c,1e-13,1e10,title,ifail,serr);
00084   }
00085   Summary(title,ifail,serr,np);
00086 
00087   // Torture cos and acos
00088   serr=0;
00089   ifail=0;
00090   strcpy(title,"Cos&ACos");
00091   for(i=0; i<np; i++) {
00092     a=TComplex(10*(1-2*gRandom->Rndm()),10*(1-2*gRandom->Rndm()));
00093     b=TComplex::ACos(a);
00094     c=TComplex::Cos(b);
00095     Verify(a,c,1e-13,1e10,title,ifail,serr);
00096   }
00097   Summary(title,ifail,serr,np);
00098 
00099   // Torture tan and atan
00100   serr=0;
00101   ifail=0;
00102   strcpy(title,"Tan&ATan");
00103   for(i=0; i<np; i++) {
00104     a=TComplex(10*(1-2*gRandom->Rndm()),10*(1-2*gRandom->Rndm()));
00105     b=TComplex::ATan(a);
00106     c=TComplex::Tan(b);
00107     Verify(a,c,1e-14,1e10,title,ifail,serr);
00108   }
00109   Summary(title,ifail,serr,np);
00110 
00111   // Torture SinH and ASinH
00112   serr=0;
00113   ifail=0;
00114   strcpy(title,"SinH&ASinH");
00115   for(i=0; i<np; i++) {
00116     a=TComplex(10*(1-2*gRandom->Rndm()),10*(1-2*gRandom->Rndm()));
00117     b=TComplex::ASinH(a);
00118     c=TComplex::SinH(b);
00119     Verify(a,c,1e-13,1e10,title,ifail,serr);
00120   }
00121   Summary(title,ifail,serr,np);
00122 
00123   // Torture CosH and ACosH
00124   serr=0;
00125   ifail=0;
00126   strcpy(title,"CosH&ACosH");
00127   for(i=0; i<np; i++) {
00128     a=TComplex(10*(1-2*gRandom->Rndm()),10*(1-2*gRandom->Rndm()));
00129     b=TComplex::ACosH(a);
00130     c=TComplex::CosH(b);
00131     Verify(a,c,1e-13,1e10,title,ifail,serr);
00132   }
00133   Summary(title,ifail,serr,np);
00134 
00135   // Torture TanH and ATanH
00136   serr=0;
00137   ifail=0;
00138   strcpy(title,"TanH&ATanH");
00139   for(i=0; i<np; i++) {
00140     a=TComplex(10*(1-2*gRandom->Rndm()),10*(1-2*gRandom->Rndm()));
00141     b=TComplex::ATanH(a);
00142     c=TComplex::TanH(b);
00143     Verify(a,c,1e-14,1e10,title,ifail,serr);
00144   }
00145   Summary(title,ifail,serr,np);
00146 
00147   // Torture Power complex - complex
00148   // 
00149   // Important note on the following tests. The operation of raising a complex
00150   // number to a power does not yet a single value, but rather an infinite
00151   // number of values, particularly if the number is non rational. 
00152   // For a real number a, you can define a^(b+ic) by writing a = e^(ln a):
00153   //
00154   //       b+ic    (ln a)(b+ic)    (b ln a) + i(c ln a)
00155   //      a     = e             = e
00156   //        
00157   //               (b ln a)
00158   //            = e         ( cos (c ln a) + i sin (c ln a) )
00159   //      
00160   //               b
00161   //            = a  ( cos (c ln a) + i sin (c ln a) ).
00162   //
00163   // Now, if a is a complex number instead of a real number, there is no
00164   // single value to "ln a": there are lots of different complex numbers z
00165   // for which e^z = a, and for any such complex number z, you could define
00166   // a^(b+ic) to be e^(z(b+ic)) and use the above technique to calculate it.
00167   //
00168   // In fact, the same thing is true even when a is a real number. The
00169   // expression a^(b+ic) has many possible values (infinite except when b
00170   // and c are both rational numbers), because instead of doing the calculation
00171   // writing a = e^(ln a), you could also do it by writing a = e^(ln a + 2pi i)
00172   // or by writing a = e^(ln a + 4 pi i), or a = e^(ln a + 6 pi i), and so on.
00173   // Each of these equalities is true (in fact e^(2pi n i)=1 for integer n).
00174   //
00175   // When a is real it is more "natural" to use the ordinary real-valued
00176   // logarithm ln a rather than than something like ln a + 2 pi i.
00177   // Technically, this value is called the principal value. This is what
00178   // the formula up above gives you. Unfortunately this alone does not
00179   // guarantees that the inverse operation brings you back where you 
00180   // started from. 
00181   //
00182   // When a is not real there is no one natural choice of logarithm to prefer
00183   // over any other, so in those cases we have to say that an expression like
00184   // a^(b+ic) has many different values.
00185   //
00186   // This is because in these tests we exclude from the error output the
00187   // results where we ended up very far from the initial value, and the
00188   // difference is more than 50%.
00189   //
00190   serr=0;
00191   ifail=0;
00192   strcpy(title,"Power C-C");
00193   for(i=0; i<np; i++) {
00194     a=TComplex(10*(1-2*gRandom->Rndm()),10*(1-2*gRandom->Rndm()));
00195     while (TComplex::Abs(
00196                          e=TComplex(10*(1-2*gRandom->Rndm()),
00197                                     10*(1-2*gRandom->Rndm()))
00198                          )<0.1) { }
00199     b=TComplex::Power(a,1./e);
00200     c=TComplex::Power(b,e);
00201     Verify(a,c,2e-14,1.,title,ifail,serr);
00202   }
00203   Summary(title,ifail,serr,np);
00204 
00205   // Torture Power complex - real
00206   serr=0;
00207   ifail=0;
00208   strcpy(title,"Power C-R");
00209   for(i=0; i<np; i++) {
00210     a=TComplex(10*(1-2*gRandom->Rndm()),10*(1-2*gRandom->Rndm()));
00211     while (TMath::Abs(x=10*(1-2*gRandom->Rndm()))<0.1) { }
00212     b=TComplex::Power(a,1./x);
00213     c=TComplex::Power(b,x);
00214     Verify(a,c,5e-14,.5,title,ifail,serr);
00215   }
00216   Summary(title,ifail,serr,np);
00217 
00218   // Torture Power real - complex
00219   serr=0;
00220   ifail=0;
00221   strcpy(title,"Power R-C");
00222   for(i=0; i<np; i++) {
00223     while (TComplex::Abs(
00224                          a=TComplex(10*(1-2*gRandom->Rndm()),
00225                                     10*(1-2*gRandom->Rndm()))
00226                          )<0.1) { }
00227     x=10*(1-2*gRandom->Rndm());
00228     b=TComplex::Power(x,1./a);
00229     c=TComplex::Power(b,a);
00230     Verify(c,TComplex(x,0),2e-14,1.5,title,ifail,serr);
00231   }
00232   Summary(title,ifail,serr,np);
00233 
00234   return 0;
00235 }

Generated on Tue Jul 5 15:14:48 2011 for ROOT_528-00b_version by  doxygen 1.5.1