00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "ocsTools.hh"
00017 #include "ocsConst.hh"
00018
00019 extern ofstream LogFile;
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 double GetRadiusCircle(double *PointA, double *PointB, double *PointC)
00038 {
00039 double vectorAB[4];
00040 double vectorBC[4];
00041 double vectorABxBC[4];
00042 double **matrixA = dmatrix(1,3,1,3);
00043 double **matrixB = dmatrix(1,3,1,1);
00044
00045 for (int ii = 1; ii < 4; ii++) {
00046 vectorAB[ii] = PointB[ii] - PointA[ii];
00047 vectorBC[ii] = PointC[ii] - PointB[ii];
00048 vectorABxBC[ii] = vectorBC[ii];
00049 }
00050
00051 CrossProduct(vectorAB, vectorABxBC, 1);
00052
00053
00054 for (int ii = 1; ii < 4; ii++) {
00055 matrixA[1][ii] = vectorAB[ii];
00056 matrixA[2][ii] = vectorBC[ii];
00057 matrixA[3][ii] = vectorABxBC[ii];
00058 matrixB[ii][1] = 0;
00059 }
00060
00061 for (int ii = 1; ii < 4; ii++) {
00062 matrixB[1][1] += vectorAB[ii]*(PointA[ii]+PointB[ii])/2.;
00063 matrixB[2][1] += vectorBC[ii]*(PointB[ii]+PointC[ii])/2.;
00064 matrixB[3][1] += vectorABxBC[ii]*PointB[ii];
00065 }
00066
00067
00068
00069 gaussj(matrixA,3,matrixB,1);
00070
00071 double PointCenter[4];
00072 for (int ii = 1; ii < 4; ii++) {
00073 PointCenter[ii] = matrixB[ii][1];
00074 }
00075
00076
00077 cout << "DistA_Center "
00078 << GetDistance2Points(PointA,PointCenter,1) << endl;
00079 cout << "DistB_Center "
00080 << GetDistance2Points(PointB,PointCenter,1) << endl;
00081 cout << "DistC_Center "
00082 << GetDistance2Points(PointC,PointCenter,1) << endl;
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 double vectorCenterA[4];
00098 double vectorCenterB[4];
00099 double vectorCenterC[4];
00100 for (int ii = 1; ii < 4; ii++) {
00101 vectorCenterA[ii] = PointA[ii] - PointCenter[ii];
00102 vectorCenterB[ii] = PointB[ii] - PointCenter[ii];
00103 vectorCenterC[ii] = PointC[ii] - PointCenter[ii];
00104 }
00105 double Radius = GetDistance2Points(PointB,PointCenter,1);
00106 double ArcLength;
00107 ArcLength = Radius*(
00108 acos( vectorCenterA[1]*vectorCenterB[1]
00109 +vectorCenterA[2]*vectorCenterB[2]
00110 +vectorCenterA[3]*vectorCenterB[3] )
00111 +acos( vectorCenterB[1]*vectorCenterC[1]
00112 +vectorCenterB[2]*vectorCenterC[2]
00113 +vectorCenterB[3]*vectorCenterC[3] ) );
00114
00115
00116
00117 for (int ii = 1; ii < 4; ii++) {
00118 PointC[ii] = PointCenter[ii];
00119 if ( sq(vectorABxBC[1])
00120 +sq(vectorABxBC[2])
00121 +sq(vectorABxBC[3]) != 0 ) {
00122 PointA[ii] = vectorABxBC[ii]
00123 /sqrt( sq(vectorABxBC[1])
00124 +sq(vectorABxBC[2])
00125 +sq(vectorABxBC[3]) )
00126 *ArcLength/(2*pi);
00127 }
00128 else {
00129 PointA[ii] = 0;
00130 }
00131 }
00132
00133
00134
00135 return Radius;
00136 }
00137
00138
00139
00140 double GetDistance2Points(double *PointA, double *PointB, int FirstCoord)
00141 {
00142 double Distance = 0;
00143 for (int ii = 0; ii < 3; ii++) {
00144 Distance += sq(PointA[ii+FirstCoord] - PointB[ii+FirstCoord]);
00145 }
00146 return sqrt(Distance);
00147 }
00148
00149
00150
00151
00152
00153
00154 int Periodicity(int ii, int Periodicity)
00155 {
00156 int nn;
00157 if (ii < 0)
00158 nn = Periodicity + ii;
00159 else if (ii >= Periodicity)
00160 nn = ii - Periodicity;
00161 else
00162 nn = ii;
00163 return nn;
00164 }
00165
00166
00167
00168
00169
00170 void TransRzRyV3to_Xhat( double *Vector, double *thetaZthetaY)
00171
00172 {
00173 double delta,gamma;
00174
00175
00176
00177
00178 if (Vector[0] != 0)
00179 delta = atan(Vector[2]/Vector[0]);
00180 else
00181 delta = pi/2.;
00182 RotatesAboutY(delta,Vector);
00183 if (Vector[0] < 0)
00184 gamma = 1/2.*atan(Vector[1]/Vector[0]);
00185 else if (Vector[0] > 0) {
00186 if (atan(Vector[1]/Vector[0]) < 0)
00187 gamma = 1/2.*(atan(Vector[1]/Vector[0]) + pi );
00188 else
00189 gamma = 1/2.*(atan(Vector[1]/Vector[0]) - pi );
00190 }
00191 else {
00192 if (Vector[1] > 0)
00193 gamma = -pi/4;
00194 else
00195 gamma = pi/4;
00196 }
00197 RotatesAboutZ(2*gamma,Vector);
00198
00199 thetaZthetaY[0] = 2*gamma;
00200 thetaZthetaY[1] = delta;
00201
00202
00203
00204 }
00205
00206
00207
00208
00209
00210 void TransRyV3to_YZ( double *Vector, double *thetaY)
00211 {
00212 double delta;
00213
00214
00215 if (Vector[2] != 0) {
00216 delta = -atan(Vector[0]/Vector[2]);
00217 }
00218 else {
00219 delta = -sgn(Vector[0])*pi/2.;
00220 }
00221 if (Vector[2] < 0 ) {
00222 delta += -pi;
00223 }
00224
00225 RotatesAboutY(delta,Vector);
00226
00227 *thetaY = delta;
00228
00229
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 void TransRzRxV3to_Xhat( double *Vector, double *thetaZthetaX)
00239
00240 {
00241
00242 double thetaZ;
00243 double thetaX;
00244 TransRzRxV3to_Xhat( Vector, &thetaZ, &thetaX);
00245 thetaZthetaX[0] = thetaZ;
00246 thetaZthetaX[1] = thetaX;
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288 void TransRzRxV3to_Xhat( double *Vector, double *thetaZ, double *thetaX)
00289
00290 {
00291 double delta,gamma;
00292
00293
00294 if (Vector[1] != 0)
00295 delta = atan(Vector[2]/Vector[1]);
00296 else
00297 delta = pi/2.;
00298 RotatesAboutX(delta,Vector);
00299 if (Vector[0] < 0)
00300 gamma = 1/2.*atan(Vector[1]/Vector[0]);
00301 else if (Vector[0] > 0) {
00302 if (atan(Vector[1]/Vector[0]) < 0)
00303 gamma = 1/2.*(atan(Vector[1]/Vector[0]) + pi );
00304 else
00305 gamma = 1/2.*(atan(Vector[1]/Vector[0]) - pi );
00306 }
00307 else {
00308 if (Vector[1] > 0)
00309 gamma = -pi/4;
00310 else
00311 gamma = pi/4;
00312 }
00313 RotatesAboutZ(2*gamma,Vector);
00314
00315 *thetaZ = 2*gamma;
00316 *thetaX = delta;
00317
00318
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 void Multiply( double Left[][3], double Right[][3])
00332 {
00333 double RightTmp[3][3];
00334 for (int ii = 0; ii < 3; ii++) {
00335 for (int jj = 0; jj < 3; jj++) {
00336 RightTmp[ii][jj] = Right[ii][jj];
00337 }
00338 }
00339 for (int ii = 0; ii < 3; ii++) {
00340 for (int jj = 0; jj < 3; jj++) {
00341 for (int kk = 0; kk < 3; kk++) {
00342 Right[ii][jj] += Left[ii][kk]*RightTmp[kk][jj];
00343 }
00344
00345
00346
00347 }
00348 }
00349 }
00350
00351
00352
00353
00354 void Multiply(double Left[][3],double Right[3])
00355 {
00356 double RightTmp[3];
00357 for (int ii = 0; ii < 3; ii++)
00358 RightTmp[ii] = Right[ii];
00359 for (int ii = 0; ii < 3; ii++) {
00360 Right[ii] = 0;
00361 for (int jj = 0; jj < 3; jj++) {
00362 Right[ii] += Left[ii][jj]*RightTmp[jj];
00363 }
00364 }
00365 }
00366
00367
00368
00369
00370
00371 void CrossProduct(double *Left, double *Right, int FirstCoord)
00372 {
00373
00374
00375
00376 double RightTmp[4];
00377 for (int ii = 0; ii < 3; ii++) {
00378 RightTmp[ii+FirstCoord] = Right[ii+FirstCoord];
00379 }
00380 Right[0+FirstCoord] = Left[1+FirstCoord]*RightTmp[2+FirstCoord]
00381 -Left[2+FirstCoord]*RightTmp[1+FirstCoord];
00382 Right[1+FirstCoord] = Left[2+FirstCoord]*RightTmp[0+FirstCoord]
00383 -Left[0+FirstCoord]*RightTmp[2+FirstCoord];
00384 Right[2+FirstCoord] = Left[0+FirstCoord]*RightTmp[1+FirstCoord]
00385 -Left[1+FirstCoord]*RightTmp[0+FirstCoord];
00386 }
00387
00388
00389
00390
00391 void RotatesAboutZ(double angle, double *Vector)
00392 {
00393
00394 double Rz[3][3];
00395
00396
00397
00398 Rz[0][0] = cos(angle); Rz[0][1] = sin(angle);
00399 Rz[1][0] = -sin(angle); Rz[1][1] = cos(angle);
00400
00401
00402 double tmpVector[3];
00403 tmpVector[0] = Vector[0];
00404 tmpVector[1] = Vector[1];
00405 Vector[0] = Rz[0][0]*tmpVector[0] + Rz[0][1]*tmpVector[1];
00406 Vector[1] = Rz[1][0]*tmpVector[0] + Rz[1][1]*tmpVector[1];
00407 }
00408
00409
00410
00411
00412 void RotatesAboutX(double angle, double *Vector)
00413 {
00414 double Rx[3][3];
00415
00416
00417
00418
00419 Rx[1][1] = cos(angle); Rx[1][2] = sin(angle);
00420 Rx[2][1] = -sin(angle); Rx[2][2] = cos(angle);
00421
00422 double tmpVector[3];
00423 tmpVector[1] = Vector[1];
00424 tmpVector[2] = Vector[2];
00425 Vector[1] = Rx[1][1]*tmpVector[1] + Rx[1][2]*tmpVector[2];
00426 Vector[2] = Rx[2][1]*tmpVector[1] + Rx[2][2]*tmpVector[2];
00427 }
00428
00429
00430
00431
00432 void RotatesAboutY(double angle, double *Vector)
00433 {
00434 double Ry[3][3];
00435
00436
00437
00438 Ry[0][0] = cos(angle); Ry[0][2] = sin(angle);
00439
00440 Ry[2][0] = -sin(angle); Ry[2][2] = cos(angle);
00441
00442 double tmpVector[3];
00443 tmpVector[0] = Vector[0];
00444 tmpVector[2] = Vector[2];
00445 Vector[0] = Ry[0][0]*tmpVector[0] + Ry[0][2]*tmpVector[2];
00446 Vector[2] = Ry[2][0]*tmpVector[0] + Ry[2][2]*tmpVector[2];
00447 }
00448
00449
00450
00451
00452
00453 double ScalarProduct(double *VectorA, double *VectorB)
00454 {
00455 return( VectorA[0]*VectorB[0]
00456 +VectorA[1]*VectorB[1]
00457 +VectorA[2]*VectorB[2]);
00458 }
00459
00460
00461
00462 double GetVectorLength(double *Vector, int Dimension)
00463 {
00464 double VectorLength = 0;
00465 for (int ii = 0; ii < Dimension; ii++) {
00466 VectorLength += sq(Vector[ii]);
00467 }
00468 return sqrt(VectorLength);
00469 }
00470
00471
00472
00473
00474
00475 void RotatesAboutX(double angle, cplx *JonesVector)
00476 {
00477 cplx TransM[2][2];
00478 TransM[0][0] = exp(-jc*angle/2.); TransM[0][1] = 0;
00479 TransM[1][0] = 0; TransM[1][1] = exp(jc*angle/2.);
00480
00481 cplx tmpJonesVector[2];
00482 tmpJonesVector[0] = JonesVector[0];
00483 tmpJonesVector[1] = JonesVector[1];
00484 JonesVector[0] = TransM[0][0]*tmpJonesVector[0]
00485 + TransM[0][1]*tmpJonesVector[1];
00486 JonesVector[1] = TransM[1][0]*tmpJonesVector[0]
00487 + TransM[1][1]*tmpJonesVector[1];
00488 }
00489
00490
00491
00492
00493 void RotatesAboutY(double angle, cplx *JonesVector)
00494 {
00495 cplx TransM[2][2];
00496 TransM[0][0] = cos(angle/2.); TransM[0][1] = jc*sin(angle/2.);
00497 TransM[1][0] = jc*sin(angle/2.); TransM[1][1] = cos(angle/2.);
00498
00499 cplx tmpJonesVector[2];
00500 tmpJonesVector[0] = JonesVector[0];
00501 tmpJonesVector[1] = JonesVector[1];
00502 JonesVector[0] = TransM[0][0]*tmpJonesVector[0]
00503 + TransM[0][1]*tmpJonesVector[1];
00504 JonesVector[1] = TransM[1][0]*tmpJonesVector[0]
00505 + TransM[1][1]*tmpJonesVector[1];
00506 }
00507
00508
00509
00510
00511
00512
00513 void RotatesAboutZ(double angle, cplx *JonesVector)
00514 {
00515 cplx TransM[2][2];
00516 TransM[0][0] = cos(angle/2.); TransM[0][1] = sin(angle/2.);
00517 TransM[1][0] = -sin(angle/2.); TransM[1][1] = cos(angle/2.);
00518
00519 cplx tmpJonesVector[2];
00520 tmpJonesVector[0] = JonesVector[0];
00521 tmpJonesVector[1] = JonesVector[1];
00522 JonesVector[0] = TransM[0][0]*tmpJonesVector[0]
00523 + TransM[0][1]*tmpJonesVector[1];
00524 JonesVector[1] = TransM[1][0]*tmpJonesVector[0]
00525 + TransM[1][1]*tmpJonesVector[1];
00526 }
00527
00528
00529
00530
00531
00532
00533
00534
00535 double dB2Linear(double dBvalue)
00536 {
00537 return(pow(10.,dBvalue/10.) );
00538 }
00539
00540
00541
00542
00543 double dBm2Linear(double dBmPower)
00544 {
00545
00546
00547
00548
00549
00550 return(pow(10.0,dBmPower/10.0 - 3.0) );
00551
00552
00553 }
00554
00555
00556
00557 double Linear2dB(double LinearValue)
00558 {
00559
00560
00561 return 10.0*log10(LinearValue);
00562
00563
00564 }
00565
00566
00567
00568 double Linear2dBm(double LinearPower)
00569 {
00570
00571
00572
00573
00574 return 10.0*log10(LinearPower*1000.0);
00575
00576 }
00577
00578
00579
00580
00581
00582
00583
00584 double Linear2dB_Limited(double LinearValue, double MaxValue_dB)
00585 {
00586
00587 if ( LinearValue >= dB2Linear(MaxValue_dB) ) {
00588
00589 LinearValue = dB2Linear(MaxValue_dB);
00590 }
00591 return Linear2dB(LinearValue);
00592 }
00593
00594
00595
00596
00597 double GetDegreeOfPolarization(double *StokesVector)
00598 {
00599 if ( StokesVector[0]*(1 + 2*NEAR_ZERO) <
00600 sqrt(sq(StokesVector[1]) + sq(StokesVector[2])
00601 +sq(StokesVector[3])) ) {
00602 cout << "From: DegreeOfPolarization()" << endl
00603 << "Error: The Stokes Vector has DOP > 1."
00604 << endl
00605 << "Please, check simulation algorithm"
00606 << endl;
00607 for (int ii = 0; ii < 4; ii++)
00608 cout << "StokesVector[" << ii << "] = "
00609 << StokesVector[ii] << endl;
00610 exit(1);
00611 }
00612 return(sqrt( sq(StokesVector[1]) + sq(StokesVector[2])
00613 +sq(StokesVector[3]) )/StokesVector[0] );
00614 }
00615
00616
00617
00618 double GetPhase(const cplx Phasor)
00619
00620 {
00621 if (abs(Phasor) == 0)
00622 return(0.);
00623 else
00624 return( sgn(real(-jc*Phasor))*acos(real(Phasor)/abs(Phasor)) );
00625 }
00626
00627
00628
00629
00630 void Stokes2Jones(const double *Stokes, cplx *Jones)
00631
00632
00633
00634 {
00635
00636
00637
00638 double Stokes0 = sqrt(sq(Stokes[1])+sq(Stokes[2])+sq(Stokes[3]) );
00639
00640
00641
00642
00643
00644 if (Stokes0 == 0) {
00645 Jones[0] = Jones[1] = 0;
00646 }
00647 else {
00648 double StokesNorm[4];
00649 StokesNorm[1] = Stokes[1]/Stokes0;
00650 StokesNorm[2] = Stokes[2]/Stokes0;
00651 StokesNorm[3] = Stokes[3]/Stokes0;
00652 double PhaseXY;
00653
00654 if (sq(StokesNorm[1]) == 1) {
00655 PhaseXY = 0;
00656 }
00657 else {
00658 PhaseXY = acos( StokesNorm[2]/sqrt(1-sq(StokesNorm[1]) ) );
00659 }
00660 Jones[0] = sqrt((1. + StokesNorm[1])/2.);
00661 Jones[1] = sqrt((1. - StokesNorm[1])/2.)
00662 *exp(-jc*sgn(StokesNorm[3])*PhaseXY);
00663 }
00664 }
00665
00666
00667
00668 void Stokes2JonesKeepPower(const double *Stokes, cplx *Jones)
00669 {
00670 Stokes2Jones(Stokes,Jones);
00671 double TotPower = sqrt(sqrt( sq(Stokes[1])
00672 +sq(Stokes[2])+sq(Stokes[3])) );
00673 Jones[0] *= TotPower;
00674 Jones[1] *= TotPower;
00675 }
00676
00677
00678
00679
00680 void Jones2Stokes(const cplx *Jones, double *Stokes)
00681
00682
00683
00684 {
00685 Stokes[0] = sq(abs(Jones[0])) + sq(abs(Jones[1]));
00686 if (Stokes[0] != 0) {
00687 Stokes[1] = (sq(abs(Jones[0]))-sq(abs(Jones[1])) )
00688 /Stokes[0];
00689 Stokes[2] = 2*real(Jones[0]*conj(Jones[1]))
00690 /Stokes[0];
00691 Stokes[3] = 2*real(-jc*Jones[0]*conj(Jones[1]))
00692 /Stokes[0];
00693 Stokes[0] = 1;
00694 }
00695 else {
00696 Stokes[1] = Stokes[2] = Stokes[3] = 0;
00697 }
00698 }
00699
00700
00701
00702
00703 void Jones2StokesKeepPower(const cplx *Jones, double *Stokes)
00704 {
00705 Jones2Stokes(Jones,Stokes);
00706 double TotPower = sq(abs(Jones[0])) + sq(abs(Jones[1]));
00707 for (int ii = 0; ii < 4; ii++) {
00708 Stokes[ii] *= TotPower;
00709 }
00710 }
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 double Frequency2Wavelength(double Frequency)
00723 {
00724
00725
00726 return LightSpeed/Frequency;
00727 }
00728
00729
00730
00731 double Wavelength2Frequency(double Wavelength)
00732 {
00733 return LightSpeed/Wavelength;
00734 }
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746 void gaussian_pdf(int N, double stan_dev, double *vec)
00747 {
00748 double *p_vec = &(vec[0]);
00749 double *const p_vec_end = &(vec[N]);
00750 double v1, v2, SSs;
00751
00752 for( ;p_vec < p_vec_end; )
00753 {
00754 do{
00755 v1 = 2.0*drand48() - 1.0;
00756 v2 = 2.0*drand48() - 1.0;
00757 SSs = sq(v1) + sq(v2);
00758 }while(SSs > 1.0);
00759
00760 double a = stan_dev * sqrt(-2.0 * log(SSs)/SSs);
00761 *p_vec = a * v1;
00762 p_vec++;
00763 *p_vec = a * v2;
00764 p_vec++;
00765 }
00766 }
00767
00768
00769
00770
00771
00772 cplx bessel5(double omega, double omega_0, double FWHM)
00773 {
00774
00775 const double mult = 4.8548214044214655;
00776
00777 const cplx s = cplx( 0.0, (omega-omega_0)/FWHM * mult );
00778
00779
00780 return 945.0 / (945.0 + s * (945.0 + s * (420.0+s * (105.0+s * (15.0+s) ))));
00781 }
00782
00783
00784
00785
00786
00787
00788
00789
00790 void electrical_filter(cplx *my_power_time, cfftw *fft, double fwhm_norm)
00791 {
00792 fft->FFT(my_power_time, 0);
00793 cplx *power_f_p = fft->work;
00794 const int N = fft->give_N();
00795 double phase0125 = arg(bessel5(fwhm_norm/8.0, 0.0, fwhm_norm));
00796 for(int i=0; i < N; i++, power_f_p++)
00797 {
00798
00799
00800
00801 double freq = fft->freq(i);
00802 double phase = -freq/(fwhm_norm/8.0) * phase0125;
00803 *power_f_p *= cplx(cos(phase), sin(phase))
00804 * bessel5(freq, 0.0, fwhm_norm);
00805 }
00806
00807 fft->IFFT(0, my_power_time);
00808
00809
00810
00811
00812 }
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 void optical_filter(cplx *my_field_time, cplx *my_field_freq,
00823 cfftw *fft, double fwhm_norm)
00824 {
00825 cplx *field_f = my_field_freq;
00826 int i;
00827 double sigma = fwhm_norm / 2.35482 * M_SQRT2;
00828 const int N = fft->give_N();
00829 for(i=0; i < N; i++, field_f++)
00830 {
00831
00832 *field_f *= exp(-0.5*sq(fft->freq(i)/sigma));
00833 }
00834 fft->IFFT(my_field_freq, my_field_time);
00835
00836 }
00837
00838
00839
00840
00841 int lock_or_unlock_mosix(int what)
00842 {
00843 ofstream *lock_file;
00844
00845 char lock_name[50];
00846 sprintf(lock_name, "/proc/%d/lock", getpid());
00847 lock_file = new ofstream( lock_name, ios::out );
00848 if(lock_file->bad())
00849 return 1;
00850 *lock_file << ((what==MOSIX_LOCK)?"1":"0") << endl;
00851 lock_file->close();
00852 return 0;
00853 }
00854
00855
00856
00857
00858
00859 int cpujob_mosix(void)
00860 {
00861 ofstream *cpu_file;
00862
00863 cpu_file = new ofstream( "/proc/mosix/decay/cpujob", ios::out );
00864 if(cpu_file->bad())
00865 return 1;
00866 *cpu_file << 1 << endl;
00867 cpu_file->close();
00868 return 0;
00869 }
00870
00871
00872
00873
00874 int slow_mosix(void)
00875 {
00876 ofstream *slow_file;
00877
00878 slow_file = new ofstream( "/proc/mosix/decay/slow", ios::out );
00879 if(slow_file->bad())
00880 return 1;
00881 *slow_file << 1 << endl;
00882 slow_file->close();
00883 return 0;
00884 }
00885
00886
00887
00888 double peak_power(cplx *in, int N)
00889 {
00890 cplx *p = in;
00891 cplx *const p_end = in+N;
00892 double max_power = norm(*p);
00893
00894 for(p++; p < p_end; p++)
00895 {
00896 double tmp = norm(*p);
00897 if(tmp > max_power)
00898 max_power = tmp;
00899 }
00900 return max_power;
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 double pulse_energy(cplx *in, int N, double width)
00914 {
00915 if(N%2)
00916 {
00917 cout << "\a\npulse_energy(): N must be even! Returning NAN..." << endl;
00918 cout << "Error in pulse_energy()." << endl;
00919 exit(1);
00920
00921 }
00922
00923 double sum1 = 0.0;
00924 cplx *p = in+1;
00925 cplx *const p_end = in+N;
00926 for(; p < p_end; p+=2)
00927 sum1 += norm(*p);
00928
00929 double sum2 = 0.0;
00930 p = in;
00931 for(; p < p_end; p+=2)
00932 sum2 += norm(*p);
00933
00934
00935 return width/double(N)/3.0 * ( 4.0*sum1 + 2.0*sum2 );
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 #define IM1 2147483563
00948 #define IM2 2147483399
00949 #define AM (1.0/IM1)
00950 #define IMM1 (IM1-1)
00951 #define IA1 40014
00952 #define IA2 40692
00953 #define IQ1 53668
00954 #define IQ2 52774
00955 #define IR1 12211
00956 #define IR2 3791
00957 #define NTAB 32
00958 #define NDIV (1+IMM1/NTAB)
00959 #define EPS 1.2e-7
00960 #define RNMX (1.0-EPS)
00961
00962
00963 float ranG(long *idum)
00964 {
00965 int j;
00966 long k;
00967 static long idum2=123456789;
00968 static long iy=0;
00969 static long iv[NTAB];
00970 float temp;
00971
00972 if (*idum <= 0) {
00973 if (-(*idum) < 1) *idum=1;
00974 else *idum = -(*idum);
00975 idum2=(*idum);
00976 for (j=NTAB+7;j>=0;j--) {
00977 k=(*idum)/IQ1;
00978 *idum=IA1*(*idum-k*IQ1)-k*IR1;
00979 if (*idum < 0) *idum += IM1;
00980 if (j < NTAB) iv[j] = *idum;
00981 }
00982 iy=iv[0];
00983 }
00984 k=(*idum)/IQ1;
00985 *idum=IA1*(*idum-k*IQ1)-k*IR1;
00986 if (*idum < 0) *idum += IM1;
00987 k=idum2/IQ2;
00988 idum2=IA2*(idum2-k*IQ2)-k*IR2;
00989 if (idum2 < 0) idum2 += IM2;
00990 j=iy/NDIV;
00991 iy=iv[j]-idum2;
00992 iv[j] = *idum;
00993 if (iy < 1) iy += IMM1;
00994 if ((temp=AM*iy) > RNMX) return RNMX;
00995 else return temp;
00996 }
00997 #undef IM1
00998 #undef IM2
00999 #undef AM
01000 #undef IMM1
01001 #undef IA1
01002 #undef IA2
01003 #undef IQ1
01004 #undef IQ2
01005 #undef IR1
01006 #undef IR2
01007 #undef NTAB
01008 #undef NDIV
01009 #undef EPS
01010 #undef RNMX
01011
01012
01013
01014 #define IA 16807
01015 #define IM 2147483647
01016 #define AM (1.0/IM)
01017 #define IQ 127773
01018 #define IR 2836
01019 #define NTAB 32
01020 #define NDIV (1+(IM-1)/NTAB)
01021 #define EPS 1.2e-7
01022 #define RNMX (1.0-EPS)
01023
01024 float ran1(long *idum)
01025
01026 {
01027 int j;
01028 long k;
01029 static long iy=0;
01030 static long iv[NTAB];
01031 float temp;
01032
01033 if (*idum <= 0 || !iy) {
01034 if (-(*idum) < 1) *idum=1;
01035 else *idum = -(*idum);
01036 for (j=NTAB+7;j>=0;j--) {
01037 k=(*idum)/IQ;
01038 *idum=IA*(*idum-k*IQ)-IR*k;
01039 if (*idum < 0) *idum += IM;
01040 if (j < NTAB) iv[j] = *idum;
01041 }
01042 iy=iv[0];
01043 }
01044 k=(*idum)/IQ;
01045 *idum=IA*(*idum-k*IQ)-IR*k;
01046 if (*idum < 0) *idum += IM;
01047 j=iy/NDIV;
01048 iy=iv[j];
01049 iv[j] = *idum;
01050 if ((temp=AM*iy) > RNMX) return RNMX;
01051 else return temp;
01052 }
01053 #undef IA
01054 #undef IM
01055 #undef AM
01056 #undef IQ
01057 #undef IR
01058 #undef NTAB
01059 #undef NDIV
01060 #undef EPS
01061 #undef RNMX
01062
01063
01064
01065
01066
01067
01068 #include <math.h>
01069
01070 float Gaussian_pdf(long *idum)
01071
01072 {
01073
01074 float ranG(long *idum);
01075 static int iset=0;
01076 static float gset;
01077 float fac,rsq,v1,v2;
01078
01079 if (iset == 0) {
01080 do {
01081 v1=2.0*ranG(idum)-1.0;
01082 v2=2.0*ranG(idum)-1.0;
01083
01084
01085 rsq=v1*v1+v2*v2;
01086 } while (rsq >= 1.0 || rsq == 0.0);
01087 fac=sqrt(-2.0*log(rsq)/rsq);
01088 gset=v1*fac;
01089 iset=1;
01090 return v2*fac;
01091 } else {
01092 iset=0;
01093 return gset;
01094 }
01095 }
01096
01097
01098
01099
01100 #include <math.h>
01101 #define NRANSI
01102 #include "nrutil.h"
01103 #define ITMAX 200
01104
01105 void powell(float p[], float xi[][4], int n, float ftol, int *iter, float *fret,
01106 float (*func)(float []))
01107
01108
01109 {
01110 void linmin(float p[], float xi[], int n, float *fret,
01111 float (*func)(float []));
01112 int i,ibig,j;
01113 float del,fp,fptt,t,*pt,*ptt,*xit;
01114
01115 pt=nrvector(1,n);
01116 ptt=nrvector(1,n);
01117 xit=nrvector(1,n);
01118 *fret=(*func)(p);
01119 for (j=1;j<=n;j++) pt[j]=p[j];
01120 for (*iter=1;;++(*iter)) {
01121 fp=(*fret);
01122 ibig=0;
01123 del=0.0;
01124 for (i=1;i<=n;i++) {
01125 for (j=1;j<=n;j++) xit[j]=xi[j][i];
01126 fptt=(*fret);
01127 linmin(p,xit,n,fret,func);
01128 if (fabs(fptt-(*fret)) > del) {
01129 del=fabs(fptt-(*fret));
01130 ibig=i;
01131 }
01132 }
01133 if (2.0*fabs(fp-(*fret)) <= ftol*(fabs(fp)+fabs(*fret))) {
01134 free_nrvector(xit,1,n);
01135 free_nrvector(ptt,1,n);
01136 free_nrvector(pt,1,n);
01137 return;
01138 }
01139 if (*iter == ITMAX) nrerror("powell exceeding maximum iterations.");
01140 for (j=1;j<=n;j++) {
01141 ptt[j]=2.0*p[j]-pt[j];
01142 xit[j]=p[j]-pt[j];
01143 pt[j]=p[j];
01144 }
01145 fptt=(*func)(ptt);
01146 if (fptt < fp) {
01147 t=2.0*(fp-2.0*(*fret)+fptt)*SQR(fp-(*fret)-del)-del*SQR(fp-fptt);
01148 if (t < 0.0) {
01149 linmin(p,xit,n,fret,func);
01150 for (j=1;j<=n;j++) {
01151 xi[j][ibig]=xi[j][n];
01152 xi[j][n]=xit[j];
01153 }
01154 }
01155 }
01156 }
01157 }
01158 #undef ITMAX
01159 #undef NRANSI
01160
01161
01162
01163 #define NRANSI
01164 #include "nrutil.h"
01165 #define TOL 2.0e-4
01166
01167 int ncom;
01168 float *pcom,*xicom,(*nrfunc)(float []);
01169
01170 void linmin(float p[], float xi[], int n, float *fret, float (*func)(float []))
01171 {
01172 float brent(float ax, float bx, float cx,
01173 float (*f)(float), float tol, float *xmin);
01174 float f1dim(float x);
01175 void mnbrak(float *ax, float *bx, float *cx, float *fa, float *fb,
01176 float *fc, float (*func)(float));
01177 int j;
01178 float xx,xmin,fx,fb,fa,bx,ax;
01179
01180 ncom=n;
01181 pcom=nrvector(1,n);
01182 xicom=nrvector(1,n);
01183 nrfunc=func;
01184 for (j=1;j<=n;j++) {
01185 pcom[j]=p[j];
01186 xicom[j]=xi[j];
01187 }
01188 ax=0.0;
01189 xx=1.0;
01190 mnbrak(&ax,&xx,&bx,&fa,&fx,&fb,f1dim);
01191 *fret=brent(ax,xx,bx,f1dim,TOL,&xmin);
01192 for (j=1;j<=n;j++) {
01193 xi[j] *= xmin;
01194 p[j] += xi[j];
01195 }
01196 free_nrvector(xicom,1,n);
01197 free_nrvector(pcom,1,n);
01198 }
01199 #undef TOL
01200 #undef NRANSI
01201
01202
01203 #define NRANSI
01204 #include "nrutil.h"
01205
01206 extern int ncom;
01207 extern float *pcom,*xicom,(*nrfunc)(float []);
01208
01209 float f1dim(float x)
01210 {
01211 int j;
01212 float f,*xt;
01213
01214 xt=nrvector(1,ncom);
01215 for (j=1;j<=ncom;j++) xt[j]=pcom[j]+x*xicom[j];
01216 f=(*nrfunc)(xt);
01217 free_nrvector(xt,1,ncom);
01218 return f;
01219 }
01220 #undef NRANSI
01221
01222
01223 #include <math.h>
01224 #define NRANSI
01225 #include "nrutil.h"
01226 #define GOLD 1.618034
01227 #define GLIMIT 100.0
01228 #define TINY 1.0e-20
01229 #define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
01230
01231 void mnbrak(float *ax, float *bx, float *cx, float *fa, float *fb, float *fc,
01232 float (*func)(float))
01233 {
01234 float ulim,u,r,q,fu,dum;
01235
01236 *fa=(*func)(*ax);
01237 *fb=(*func)(*bx);
01238 if (*fb > *fa) {
01239 SHFT(dum,*ax,*bx,dum)
01240 SHFT(dum,*fb,*fa,dum)
01241 }
01242 *cx=(*bx)+GOLD*(*bx-*ax);
01243 *fc=(*func)(*cx);
01244 while (*fb > *fc) {
01245 r=(*bx-*ax)*(*fb-*fc);
01246 q=(*bx-*cx)*(*fb-*fa);
01247 u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/
01248 (2.0*SIGN(FMAX(fabs(q-r),TINY),q-r));
01249 ulim=(*bx)+GLIMIT*(*cx-*bx);
01250 if ((*bx-u)*(u-*cx) > 0.0) {
01251 fu=(*func)(u);
01252 if (fu < *fc) {
01253 *ax=(*bx);
01254 *bx=u;
01255 *fa=(*fb);
01256 *fb=fu;
01257 return;
01258 } else if (fu > *fb) {
01259 *cx=u;
01260 *fc=fu;
01261 return;
01262 }
01263 u=(*cx)+GOLD*(*cx-*bx);
01264 fu=(*func)(u);
01265 } else if ((*cx-u)*(u-ulim) > 0.0) {
01266 fu=(*func)(u);
01267 if (fu < *fc) {
01268 SHFT(*bx,*cx,u,*cx+GOLD*(*cx-*bx))
01269 SHFT(*fb,*fc,fu,(*func)(u))
01270 }
01271 } else if ((u-ulim)*(ulim-*cx) >= 0.0) {
01272 u=ulim;
01273 fu=(*func)(u);
01274 } else {
01275 u=(*cx)+GOLD*(*cx-*bx);
01276 fu=(*func)(u);
01277 }
01278 SHFT(*ax,*bx,*cx,u)
01279 SHFT(*fa,*fb,*fc,fu)
01280 }
01281 }
01282 #undef GOLD
01283 #undef GLIMIT
01284 #undef TINY
01285 #undef SHFT
01286 #undef NRANSI
01287
01288
01289 #include <math.h>
01290 #define NRANSI
01291 #include "nrutil.h"
01292 #define ITMAX 100
01293 #define CGOLD 0.3819660
01294 #define ZEPS 1.0e-10
01295 #define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
01296
01297 float brent(float ax, float bx, float cx, float (*f)(float), float tol,
01298 float *xmin)
01299 {
01300 int iter;
01301 float a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
01302 float e=0.0;
01303
01304 a=(ax < cx ? ax : cx);
01305 b=(ax > cx ? ax : cx);
01306 x=w=v=bx;
01307 fw=fv=fx=(*f)(x);
01308 for (iter=1;iter<=ITMAX;iter++) {
01309 xm=0.5*(a+b);
01310 tol2=2.0*(tol1=tol*fabs(x)+ZEPS);
01311 if (fabs(x-xm) <= (tol2-0.5*(b-a))) {
01312 *xmin=x;
01313 return fx;
01314 }
01315 if (fabs(e) > tol1) {
01316 r=(x-w)*(fx-fv);
01317 q=(x-v)*(fx-fw);
01318 p=(x-v)*q-(x-w)*r;
01319 q=2.0*(q-r);
01320 if (q > 0.0) p = -p;
01321 q=fabs(q);
01322 etemp=e;
01323 e=d;
01324 if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x))
01325 d=CGOLD*(e=(x >= xm ? a-x : b-x));
01326 else {
01327 d=p/q;
01328 u=x+d;
01329 if (u-a < tol2 || b-u < tol2)
01330 d=SIGN(tol1,xm-x);
01331 }
01332 } else {
01333 d=CGOLD*(e=(x >= xm ? a-x : b-x));
01334 }
01335 u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d));
01336 fu=(*f)(u);
01337 if (fu <= fx) {
01338 if (u >= x) a=x; else b=x;
01339 SHFT(v,w,x,u)
01340 SHFT(fv,fw,fx,fu)
01341 } else {
01342 if (u < x) a=u; else b=u;
01343 if (fu <= fw || w == x) {
01344 v=w;
01345 w=u;
01346 fv=fw;
01347 fw=fu;
01348 } else if (fu <= fv || v == x || v == w) {
01349 v=u;
01350 fv=fu;
01351 }
01352 }
01353 }
01354 nrerror("Too many iterations in brent");
01355 *xmin=x;
01356 return fx;
01357 }
01358 #undef ITMAX
01359 #undef CGOLD
01360 #undef ZEPS
01361 #undef SHFT
01362 #undef NRANSI
01363
01364
01365
01366
01367
01368
01369 #include <math.h>
01370 #define NRANSI
01371 #include "nrutil.h"
01372 #define ITMAX 200
01373 #define EPS 1.0e-10
01374 #define FREEALLD free_dvector(xi,1,n);free_dvector(h,1,n);free_dvector(g,1,n);
01375
01376 void frprmnd(double p[], int n, double ftol, int *iter, double *fret,
01377 double (*func)(double []), void (*dfunc)(double [], double []))
01378 {
01379 void linmind(double p[], double xi[], int n, double *fret,
01380 double (*func)(double []));
01381 int j,its;
01382 double gg,gam,fp,dgg;
01383 double *g,*h,*xi;
01384
01385 g=dvector(1,n);
01386 h=dvector(1,n);
01387 xi=dvector(1,n);
01388 fp=(*func)(p);
01389 (*dfunc)(p,xi);
01390 for (j=1;j<=n;j++) {
01391 g[j] = -xi[j];
01392 xi[j]=h[j]=g[j];
01393 }
01394 for (its=1;its<=ITMAX;its++) {
01395 *iter=its;
01396 linmind(p,xi,n,fret,func);
01397 if (2.0*fabs(*fret-fp) <= ftol*(fabs(*fret)+fabs(fp)+EPS)) {
01398 FREEALLD
01399 return;
01400 }
01401 fp=(*func)(p);
01402 (*dfunc)(p,xi);
01403 dgg=gg=0.0;
01404 for (j=1;j<=n;j++) {
01405 gg += g[j]*g[j];
01406 dgg += (xi[j]+g[j])*xi[j];
01407 }
01408 if (gg == 0.0) {
01409 FREEALLD
01410 return;
01411 }
01412 gam=dgg/gg;
01413 for (j=1;j<=n;j++) {
01414 g[j] = -xi[j];
01415 xi[j]=h[j]=g[j]+gam*h[j];
01416 }
01417 }
01418 nrerror("Too many iterations in frprmn");
01419 }
01420 #undef ITMAX
01421 #undef EPS
01422 #undef FREEALLD
01423 #undef NRANSI
01424
01425
01426
01427 #define NRANSI
01428 #include "nrutil.h"
01429 #define TOL 2.0e-4
01430
01431
01432 double *pcomd,*xicomd,(*nrfuncd)(double []);
01433
01434 void linmind(double p[], double xi[], int n, double *fret, double (*func)(double []))
01435 {
01436 double brentd(double ax, double bx, double cx,
01437 double (*f)(double), double tol, double *xmin);
01438 double f1dim(double x);
01439 void mnbrakd(double *ax, double *bx, double *cx, double *fa, double *fb,
01440 double *fc, double (*func)(double));
01441 int j;
01442 double xx,xmin,fx,fb,fa,bx,ax;
01443
01444 ncom=n;
01445 pcomd=dvector(1,n);
01446 xicomd=dvector(1,n);
01447 nrfuncd=func;
01448 for (j=1;j<=n;j++) {
01449 pcomd[j]=p[j];
01450 xicomd[j]=xi[j];
01451 }
01452 ax=0.0;
01453 xx=1.0;
01454 mnbrakd(&ax,&xx,&bx,&fa,&fx,&fb,f1dim);
01455 *fret=brentd(ax,xx,bx,f1dim,TOL,&xmin);
01456 for (j=1;j<=n;j++) {
01457 xi[j] *= xmin;
01458 p[j] += xi[j];
01459 }
01460 free_dvector(xicomd,1,n);
01461 free_dvector(pcomd,1,n);
01462 }
01463 #undef TOL
01464 #undef NRANSI
01465
01466
01467 #define NRANSI
01468 #include "nrutil.h"
01469
01470 extern int ncom;
01471 extern double *pcomd,*xicomd,(*nrfuncd)(double []);
01472
01473 double f1dim(double x)
01474 {
01475 int j;
01476 double f,*xt;
01477
01478 xt=dvector(1,ncom);
01479 for (j=1;j<=ncom;j++) xt[j]=pcomd[j]+x*xicomd[j];
01480 f=(*nrfuncd)(xt);
01481 free_dvector(xt,1,ncom);
01482 return f;
01483 }
01484 #undef NRANSI
01485
01486
01487 #include <math.h>
01488 #define NRANSI
01489 #include "nrutil.h"
01490 #define GOLD 1.618034
01491 #define GLIMIT 100.0
01492 #define TINY 1.0e-20
01493 #define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
01494
01495 void mnbrakd(double *ax, double *bx, double *cx, double *fa, double *fb, double *fc,
01496 double (*func)(double))
01497 {
01498 double ulim,u,r,q,fu,dum;
01499
01500 *fa=(*func)(*ax);
01501 *fb=(*func)(*bx);
01502 if (*fb > *fa) {
01503 SHFT(dum,*ax,*bx,dum)
01504 SHFT(dum,*fb,*fa,dum)
01505 }
01506 *cx=(*bx)+GOLD*(*bx-*ax);
01507 *fc=(*func)(*cx);
01508 while (*fb > *fc) {
01509 r=(*bx-*ax)*(*fb-*fc);
01510 q=(*bx-*cx)*(*fb-*fa);
01511 u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/
01512 (2.0*SIGN(FMAX(fabs(q-r),TINY),q-r));
01513 ulim=(*bx)+GLIMIT*(*cx-*bx);
01514 if ((*bx-u)*(u-*cx) > 0.0) {
01515 fu=(*func)(u);
01516 if (fu < *fc) {
01517 *ax=(*bx);
01518 *bx=u;
01519 *fa=(*fb);
01520 *fb=fu;
01521 return;
01522 } else if (fu > *fb) {
01523 *cx=u;
01524 *fc=fu;
01525 return;
01526 }
01527 u=(*cx)+GOLD*(*cx-*bx);
01528 fu=(*func)(u);
01529 } else if ((*cx-u)*(u-ulim) > 0.0) {
01530 fu=(*func)(u);
01531 if (fu < *fc) {
01532 SHFT(*bx,*cx,u,*cx+GOLD*(*cx-*bx))
01533 SHFT(*fb,*fc,fu,(*func)(u))
01534 }
01535 } else if ((u-ulim)*(ulim-*cx) >= 0.0) {
01536 u=ulim;
01537 fu=(*func)(u);
01538 } else {
01539 u=(*cx)+GOLD*(*cx-*bx);
01540 fu=(*func)(u);
01541 }
01542 SHFT(*ax,*bx,*cx,u)
01543 SHFT(*fa,*fb,*fc,fu)
01544 }
01545 }
01546 #undef GOLD
01547 #undef GLIMIT
01548 #undef TINY
01549 #undef SHFT
01550 #undef NRANSI
01551
01552
01553 #include <math.h>
01554 #define NRANSI
01555 #include "nrutil.h"
01556 #define ITMAX 100
01557 #define CGOLD 0.3819660
01558 #define ZEPS 1.0e-10
01559 #define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
01560
01561 double brentd(double ax, double bx, double cx, double (*f)(double), double tol,
01562 double *xmin)
01563 {
01564 int iter;
01565 double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
01566 double e=0.0;
01567
01568 a=(ax < cx ? ax : cx);
01569 b=(ax > cx ? ax : cx);
01570 x=w=v=bx;
01571 fw=fv=fx=(*f)(x);
01572 for (iter=1;iter<=ITMAX;iter++) {
01573 xm=0.5*(a+b);
01574 tol2=2.0*(tol1=tol*fabs(x)+ZEPS);
01575 if (fabs(x-xm) <= (tol2-0.5*(b-a))) {
01576 *xmin=x;
01577 return fx;
01578 }
01579 if (fabs(e) > tol1) {
01580 r=(x-w)*(fx-fv);
01581 q=(x-v)*(fx-fw);
01582 p=(x-v)*q-(x-w)*r;
01583 q=2.0*(q-r);
01584 if (q > 0.0) p = -p;
01585 q=fabs(q);
01586 etemp=e;
01587 e=d;
01588 if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x))
01589 d=CGOLD*(e=(x >= xm ? a-x : b-x));
01590 else {
01591 d=p/q;
01592 u=x+d;
01593 if (u-a < tol2 || b-u < tol2)
01594 d=SIGN(tol1,xm-x);
01595 }
01596 } else {
01597 d=CGOLD*(e=(x >= xm ? a-x : b-x));
01598 }
01599 u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d));
01600 fu=(*f)(u);
01601 if (fu <= fx) {
01602 if (u >= x) a=x; else b=x;
01603 SHFT(v,w,x,u)
01604 SHFT(fv,fw,fx,fu)
01605 } else {
01606 if (u < x) a=u; else b=u;
01607 if (fu <= fw || w == x) {
01608 v=w;
01609 w=u;
01610 fv=fw;
01611 fw=fu;
01612 } else if (fu <= fv || v == x || v == w) {
01613 v=u;
01614 fv=fu;
01615 }
01616 }
01617 }
01618 nrerror("Too many iterations in brentd");
01619 *xmin=x;
01620 return fx;
01621 }
01622 #undef ITMAX
01623 #undef CGOLD
01624 #undef ZEPS
01625 #undef SHFT
01626 #undef NRANSI
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636 #include <math.h>
01637 #define NRANSI
01638 #include "nrutil.h"
01639 #define ITMAX 200
01640 #define EPS 1.0e-10
01641 #define FREEALL free_nrvector(xi,1,n);free_nrvector(h,1,n);free_nrvector(g,1,n);
01642
01643 void frprmn(float p[], int n, float ftol, int *iter, float *fret,
01644 float (*func)(float []), void (*dfunc)(float [], float []))
01645 {
01646 void linmin(float p[], float xi[], int n, float *fret,
01647 float (*func)(float []));
01648 int j,its;
01649 float gg,gam,fp,dgg;
01650 float *g,*h,*xi;
01651
01652 g=nrvector(1,n);
01653 h=nrvector(1,n);
01654 xi=nrvector(1,n);
01655 fp=(*func)(p);
01656 (*dfunc)(p,xi);
01657 for (j=1;j<=n;j++) {
01658 g[j] = -xi[j];
01659 xi[j]=h[j]=g[j];
01660 }
01661 for (its=1;its<=ITMAX;its++) {
01662 *iter=its;
01663 linmin(p,xi,n,fret,func);
01664 if (2.0*fabs(*fret-fp) <= ftol*(fabs(*fret)+fabs(fp)+EPS)) {
01665 FREEALL
01666 return;
01667 }
01668 fp=(*func)(p);
01669 (*dfunc)(p,xi);
01670 dgg=gg=0.0;
01671 for (j=1;j<=n;j++) {
01672 gg += g[j]*g[j];
01673 dgg += (xi[j]+g[j])*xi[j];
01674 }
01675 if (gg == 0.0) {
01676 FREEALL
01677 return;
01678 }
01679 gam=dgg/gg;
01680 for (j=1;j<=n;j++) {
01681 g[j] = -xi[j];
01682 xi[j]=h[j]=g[j]+gam*h[j];
01683 }
01684 }
01685 nrerror("Too many iterations in frprmn");
01686 }
01687 #undef ITMAX
01688 #undef EPS
01689 #undef FREEALL
01690 #undef NRANSI
01691
01692
01693
01694
01695
01696
01697
01698 #include <stdio.h>
01699 #include <stddef.h>
01700 #include <stdlib.h>
01701
01702 #define NR_END 1
01703 #define FREE_ARG char*
01704
01705 void nrerror(char error_text[])
01706
01707 {
01708 fprintf(stderr,"Numerical Recipes run-time error...\n");
01709 fprintf(stderr,"%s\n",error_text);
01710 fprintf(stderr,"...now exiting to system...\n");
01711 exit(1);
01712 }
01713
01714
01715
01716 float *nrvector(long nl, long nh)
01717
01718 {
01719 float *v;
01720
01721 v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float)));
01722 if (!v) nrerror("allocation failure in nrvector()");
01723 return v-nl+NR_END;
01724 }
01725
01726 int *ivector(long nl, long nh)
01727
01728 {
01729 int *v;
01730
01731 v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int)));
01732 if (!v) nrerror("allocation failure in ivector()");
01733 return v-nl+NR_END;
01734 }
01735
01736 unsigned char *cvector(long nl, long nh)
01737
01738 {
01739 unsigned char *v;
01740
01741 v=(unsigned char *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(unsigned char)));
01742 if (!v) nrerror("allocation failure in cvector()");
01743 return v-nl+NR_END;
01744 }
01745
01746 unsigned long *lvector(long nl, long nh)
01747
01748 {
01749 unsigned long *v;
01750
01751 v=(unsigned long *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(long)));
01752 if (!v) nrerror("allocation failure in lvector()");
01753 return v-nl+NR_END;
01754 }
01755
01756 double *dvector(long nl, long nh)
01757
01758 {
01759 double *v;
01760
01761 v=(double *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(double)));
01762 if (!v) nrerror("allocation failure in dvector()");
01763 return v-nl+NR_END;
01764 }
01765
01766 float **matrix(long nrl, long nrh, long ncl, long nch)
01767
01768 {
01769 long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
01770 float **m;
01771
01772
01773 m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*)));
01774 if (!m) nrerror("allocation failure 1 in matrix()");
01775 m += NR_END;
01776 m -= nrl;
01777
01778
01779 m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float)));
01780 if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
01781 m[nrl] += NR_END;
01782 m[nrl] -= ncl;
01783
01784 for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
01785
01786
01787 return m;
01788 }
01789
01790 double **dmatrix(long nrl, long nrh, long ncl, long nch)
01791
01792 {
01793 long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
01794 double **m;
01795
01796
01797 m=(double **) malloc((size_t)((nrow+NR_END)*sizeof(double*)));
01798 if (!m) nrerror("allocation failure 1 in matrix()");
01799 m += NR_END;
01800 m -= nrl;
01801
01802
01803 m[nrl]=(double *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double)));
01804 if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
01805 m[nrl] += NR_END;
01806 m[nrl] -= ncl;
01807
01808 for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
01809
01810
01811 return m;
01812 }
01813
01814
01815 cplx **cmatrix(long nrl, long nrh, long ncl, long nch)
01816
01817 {
01818 long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
01819 cplx **m;
01820
01821
01822 m=(cplx **) malloc((size_t)((nrow+NR_END)*sizeof(cplx*)));
01823 if (!m) nrerror("allocation failure 1 in matrix()");
01824 m += NR_END;
01825 m -= nrl;
01826
01827
01828 m[nrl]=(cplx *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(cplx)));
01829 if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
01830 m[nrl] += NR_END;
01831 m[nrl] -= ncl;
01832
01833 for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
01834
01835
01836 return m;
01837 }
01838
01839 int **imatrix(long nrl, long nrh, long ncl, long nch)
01840
01841 {
01842 long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
01843 int **m;
01844
01845
01846 m=(int **) malloc((size_t)((nrow+NR_END)*sizeof(int*)));
01847 if (!m) nrerror("allocation failure 1 in matrix()");
01848 m += NR_END;
01849 m -= nrl;
01850
01851
01852
01853 m[nrl]=(int *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(int)));
01854 if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
01855 m[nrl] += NR_END;
01856 m[nrl] -= ncl;
01857
01858 for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
01859
01860
01861 return m;
01862 }
01863
01864 float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch,
01865 long newrl, long newcl)
01866
01867 {
01868 long i,j,nrow=oldrh-oldrl+1,ncol=oldcl-newcl;
01869 float **m;
01870
01871
01872 m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
01873 if (!m) nrerror("allocation failure in submatrix()");
01874 m += NR_END;
01875 m -= newrl;
01876
01877
01878 for(i=oldrl,j=newrl;i<=oldrh;i++,j++) m[j]=a[i]+ncol;
01879
01880
01881 return m;
01882 }
01883
01884 float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch)
01885
01886
01887
01888
01889 {
01890 long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1;
01891 float **m;
01892
01893
01894 m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
01895 if (!m) nrerror("allocation failure in convert_matrix()");
01896 m += NR_END;
01897 m -= nrl;
01898
01899
01900 m[nrl]=a-ncl;
01901 for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol;
01902
01903 return m;
01904 }
01905
01906 float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh)
01907
01908 {
01909 long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
01910 float ***t;
01911
01912
01913 t=(float ***) malloc((size_t)((nrow+NR_END)*sizeof(float**)));
01914 if (!t) nrerror("allocation failure 1 in f3tensor()");
01915 t += NR_END;
01916 t -= nrl;
01917
01918
01919 t[nrl]=(float **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float*)));
01920 if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
01921 t[nrl] += NR_END;
01922 t[nrl] -= ncl;
01923
01924
01925 t[nrl][ncl]=(float *) malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(float)));
01926 if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
01927 t[nrl][ncl] += NR_END;
01928 t[nrl][ncl] -= ndl;
01929
01930 for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
01931 for(i=nrl+1;i<=nrh;i++) {
01932 t[i]=t[i-1]+ncol;
01933 t[i][ncl]=t[i-1][ncl]+ncol*ndep;
01934 for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
01935 }
01936
01937
01938 return t;
01939 }
01940
01941
01942 void free_dvector(double *v, long nl, long nh)
01943
01944 {
01945 free((FREE_ARG) (v+nl-NR_END));
01946 }
01947
01948 void free_nrvector(float *v, long nl, long nh)
01949
01950 {
01951 free((FREE_ARG) (v+nl-NR_END));
01952 }
01953
01954 void free_ivector(int *v, long nl, long nh)
01955
01956 {
01957 free((FREE_ARG) (v+nl-NR_END));
01958 }
01959
01960 void free_cvector(unsigned char *v, long nl, long nh)
01961
01962 {
01963 free((FREE_ARG) (v+nl-NR_END));
01964 }
01965
01966 void free_lvector(unsigned long *v, long nl, long nh)
01967
01968 {
01969 free((FREE_ARG) (v+nl-NR_END));
01970 }
01971
01972
01973 void free_matrix(float **m, long nrl, long nrh, long ncl, long nch)
01974
01975 {
01976 free((FREE_ARG) (m[nrl]+ncl-NR_END));
01977 free((FREE_ARG) (m+nrl-NR_END));
01978 }
01979
01980 void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch)
01981
01982 {
01983 free((FREE_ARG) (m[nrl]+ncl-NR_END));
01984 free((FREE_ARG) (m+nrl-NR_END));
01985 }
01986
01987
01988 void free_cmatrix(cplx **m, long nrl, long nrh, long ncl, long nch)
01989
01990 {
01991 free((FREE_ARG) (m[nrl]+ncl-NR_END));
01992 free((FREE_ARG) (m+nrl-NR_END));
01993 }
01994
01995 void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch)
01996
01997 {
01998 free((FREE_ARG) (m[nrl]+ncl-NR_END));
01999 free((FREE_ARG) (m+nrl-NR_END));
02000 }
02001
02002 void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch)
02003
02004 {
02005 free((FREE_ARG) (b+nrl-NR_END));
02006 }
02007
02008 void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch)
02009
02010 {
02011 free((FREE_ARG) (b+nrl-NR_END));
02012 }
02013
02014 void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch,
02015 long ndl, long ndh)
02016
02017 {
02018 free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
02019 free((FREE_ARG) (t[nrl]+ncl-NR_END));
02020 free((FREE_ARG) (t+nrl-NR_END));
02021 }
02022
02023
02024
02025
02026
02027
02028 #include <math.h>
02029 #define NRANSI
02030 #include "nrutil.h"
02031 #define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;}
02032
02033
02034
02035 void gaussj(double **a, int n, double **b, int m)
02036 {
02037 int *indxc,*indxr,*ipiv;
02038 int i,icol,irow,j,k,l,ll;
02039 double big,dum,pivinv,temp;
02040
02041 indxc=ivector(1,n);
02042 indxr=ivector(1,n);
02043 ipiv=ivector(1,n);
02044 for (j=1;j<=n;j++) ipiv[j]=0;
02045 for (i=1;i<=n;i++) {
02046 big=0.0;
02047 for (j=1;j<=n;j++)
02048 if (ipiv[j] != 1)
02049 for (k=1;k<=n;k++) {
02050 if (ipiv[k] == 0) {
02051 if (abs(a[j][k]) >= big) {
02052 big=abs(a[j][k]);
02053 irow=j;
02054 icol=k;
02055 }
02056 } else if (ipiv[k] > 1) nrerror("gaussj: Singular Matrix-1");
02057 }
02058 ++(ipiv[icol]);
02059 if (irow != icol) {
02060 for (l=1;l<=n;l++) SWAP(a[irow][l],a[icol][l])
02061 for (l=1;l<=m;l++) SWAP(b[irow][l],b[icol][l])
02062 }
02063 indxr[i]=irow;
02064 indxc[i]=icol;
02065 if (a[icol][icol] == 0.0) nrerror("gaussj: Singular Matrix-2");
02066 pivinv=1.0/a[icol][icol];
02067 a[icol][icol]=1.0;
02068 for (l=1;l<=n;l++) a[icol][l] *= pivinv;
02069 for (l=1;l<=m;l++) b[icol][l] *= pivinv;
02070 for (ll=1;ll<=n;ll++)
02071 if (ll != icol) {
02072 dum=a[ll][icol];
02073 a[ll][icol]=0.0;
02074 for (l=1;l<=n;l++) a[ll][l] -= a[icol][l]*dum;
02075 for (l=1;l<=m;l++) b[ll][l] -= b[icol][l]*dum;
02076 }
02077 }
02078 for (l=n;l>=1;l--) {
02079 if (indxr[l] != indxc[l])
02080 for (k=1;k<=n;k++)
02081 SWAP(a[k][indxr[l]],a[k][indxc[l]]);
02082 }
02083 free_ivector(ipiv,1,n);
02084 free_ivector(indxr,1,n);
02085 free_ivector(indxc,1,n);
02086 }
02087 #undef SWAP
02088 #undef NRANSI
02089
02090
02091
02092
02093
02094
02095
02096 #include <math.h>
02097 #define NRANSI
02098 #include "nrutil.h"
02099 #define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;}
02100
02101
02102 void gaussj_complex(cplx **a, int n, cplx **b, int m)
02103 {
02104 int *indxc,*indxr,*ipiv;
02105 int i,icol,irow,j,k,l,ll;
02106 cplx dum,pivinv,temp;
02107 double big;
02108 indxc=ivector(1,n);
02109 indxr=ivector(1,n);
02110 ipiv=ivector(1,n);
02111 for (j=1;j<=n;j++) ipiv[j]=0;
02112 for (i=1;i<=n;i++) {
02113 big=0.0;
02114 for (j=1;j<=n;j++)
02115 if (ipiv[j] != 1)
02116 for (k=1;k<=n;k++) {
02117 if (ipiv[k] == 0) {
02118 if (abs(a[j][k]) >= big) {
02119 big=abs(a[j][k]);
02120 irow=j;
02121 icol=k;
02122 }
02123 } else if (ipiv[k] > 1) nrerror("gaussj: Singular Matrix-1");
02124 }
02125 ++(ipiv[icol]);
02126 if (irow != icol) {
02127 for (l=1;l<=n;l++) SWAP(a[irow][l],a[icol][l])
02128 for (l=1;l<=m;l++) SWAP(b[irow][l],b[icol][l])
02129 }
02130 indxr[i]=irow;
02131 indxc[i]=icol;
02132 if (a[icol][icol] == 0.0) nrerror("gaussj: Singular Matrix-2");
02133 pivinv=1.0/a[icol][icol];
02134 a[icol][icol]=1.0;
02135 for (l=1;l<=n;l++) a[icol][l] *= pivinv;
02136 for (l=1;l<=m;l++) b[icol][l] *= pivinv;
02137 for (ll=1;ll<=n;ll++)
02138 if (ll != icol) {
02139 dum=a[ll][icol];
02140 a[ll][icol]=0.0;
02141 for (l=1;l<=n;l++) a[ll][l] -= a[icol][l]*dum;
02142 for (l=1;l<=m;l++) b[ll][l] -= b[icol][l]*dum;
02143 }
02144 }
02145 for (l=n;l>=1;l--) {
02146 if (indxr[l] != indxc[l])
02147 for (k=1;k<=n;k++)
02148 SWAP(a[k][indxr[l]],a[k][indxc[l]]);
02149 }
02150 free_ivector(ipiv,1,n);
02151 free_ivector(indxr,1,n);
02152 free_ivector(indxc,1,n);
02153 }
02154 #undef SWAP
02155 #undef NRANSI
02156
02157
02158
02159 float erffc(float x)
02160 {
02161 float gammp(float a, float x);
02162 float gammq(float a, float x);
02163
02164 return x < 0.0 ? 1.0+gammp(0.5,x*x) : gammq(0.5,x*x);
02165 }
02166
02167
02168 float gammp(float a, float x)
02169 {
02170 void gcf(float *gammcf, float a, float x, float *gln);
02171 void gser(float *gamser, float a, float x, float *gln);
02172 void nrerror(char error_text[]);
02173 float gamser,gammcf,gln;
02174
02175 if (x < 0.0 || a <= 0.0) nrerror("Invalid arguments in routine gammp");
02176 if (x < (a+1.0)) {
02177 gser(&gamser,a,x,&gln);
02178 return gamser;
02179 } else {
02180 gcf(&gammcf,a,x,&gln);
02181 return 1.0-gammcf;
02182 }
02183 }
02184
02185
02186 #include <math.h>
02187 #define ITMAX 100
02188 #define EPS 3.0e-7
02189 #define FPMIN 1.0e-30
02190
02191 void gcf(float *gammcf, float a, float x, float *gln)
02192 {
02193 float gammln(float xx);
02194 void nrerror(char error_text[]);
02195 int i;
02196 float an,b,c,d,del,h;
02197
02198 *gln=gammln(a);
02199 b=x+1.0-a;
02200 c=1.0/FPMIN;
02201 d=1.0/b;
02202 h=d;
02203 for (i=1;i<=ITMAX;i++) {
02204 an = -i*(i-a);
02205 b += 2.0;
02206 d=an*d+b;
02207 if (fabs(d) < FPMIN) d=FPMIN;
02208 c=b+an/c;
02209 if (fabs(c) < FPMIN) c=FPMIN;
02210 d=1.0/d;
02211 del=d*c;
02212 h *= del;
02213 if (fabs(del-1.0) < EPS) break;
02214 }
02215 if (i > ITMAX) nrerror("a too large, ITMAX too small in gcf");
02216 *gammcf=exp(-x+a*log(x)-(*gln))*h;
02217 }
02218 #undef ITMAX
02219 #undef EPS
02220 #undef FPMIN
02221
02222
02223 #include <math.h>
02224 #define ITMAX 100
02225 #define EPS 3.0e-7
02226
02227 void gser(float *gamser, float a, float x, float *gln)
02228 {
02229 float gammln(float xx);
02230 void nrerror(char error_text[]);
02231 int n;
02232 float sum,del,ap;
02233
02234 *gln=gammln(a);
02235 if (x <= 0.0) {
02236 if (x < 0.0) nrerror("x less than 0 in routine gser");
02237 *gamser=0.0;
02238 return;
02239 } else {
02240 ap=a;
02241 del=sum=1.0/a;
02242 for (n=1;n<=ITMAX;n++) {
02243 ++ap;
02244 del *= x/ap;
02245 sum += del;
02246 if (fabs(del) < fabs(sum)*EPS) {
02247 *gamser=sum*exp(-x+a*log(x)-(*gln));
02248 return;
02249 }
02250 }
02251 nrerror("a too large, ITMAX too small in routine gser");
02252 return;
02253 }
02254 }
02255 #undef ITMAX
02256 #undef EPS
02257
02258
02259
02260 #include <math.h>
02261
02262 float gammln(float xx)
02263 {
02264 double x,y,tmp,ser;
02265 static double cof[6]={76.18009172947146,-86.50532032941677,
02266 24.01409824083091,-1.231739572450155,
02267 0.1208650973866179e-2,-0.5395239384953e-5};
02268 int j;
02269
02270 y=x=xx;
02271 tmp=x+5.5;
02272 tmp -= (x+0.5)*log(tmp);
02273 ser=1.000000000190015;
02274 for (j=0;j<=5;j++) ser += cof[j]/++y;
02275 return -tmp+log(2.5066282746310005*ser/x);
02276 }
02277
02278
02279
02280 float gammq(float a, float x)
02281 {
02282 void gcf(float *gammcf, float a, float x, float *gln);
02283 void gser(float *gamser, float a, float x, float *gln);
02284 void nrerror(char error_text[]);
02285 float gamser,gammcf,gln;
02286
02287 if (x < 0.0 || a <= 0.0) nrerror("Invalid arguments in routine gammq");
02288 if (x < (a+1.0)) {
02289 gser(&gamser,a,x,&gln);
02290 return 1.0-gamser;
02291 } else {
02292 gcf(&gammcf,a,x,&gln);
02293 return gammcf;
02294 }
02295 }
02296
02297
02298
02299
02300
02301
02302
02303