source: TRACY3/trunk/tracy/tracy/src/mathlib.cc @ 3

Last change on this file since 3 was 3, checked in by zhangj, 11 years ago

Initiale import

  • Property svn:executable set to *
File size: 15.0 KB
Line 
1/* Tracy-2
2
3   J. Bengtsson, CBP, LBL      1990 - 1994   Pascal version
4                 SLS, PSI      1995 - 1997
5   M. Boege      SLS, PSI      1998          C translation
6   L. Nadolski   SOLEIL        2002          Link to NAFF, Radia field maps
7   J. Bengtsson  NSLS-II, BNL  2004 -       
8
9*/
10
11// missing in lstdc++
12//template double std::__cmath_power<double>(double, unsigned);
13
14double log(const int k) { return log((double)k); }
15
16
17/* Local variables for DetMat: */
18struct LOC_DetMat
19{
20  const Matrix  *a;
21  bool    cross[ss_dim];
22};
23
24typedef int iv1[ss_dim];
25typedef int iv2[ss_dim][2];
26typedef double v1[ss_dim];
27
28/* Local variables for InvMat: */
29struct LOC_InvMat
30{
31  long    n;
32  Matrix  *a;
33  long    row, column;
34  double  determ;
35} ;
36
37void iniranf(const long i)
38{
39  rseed0 = i; rseed = i;
40}
41
42
43#define k               19
44#define c               656329L
45#define m               100000001
46/****************************************************************************/
47/* void newseed(void)
48
49   Purpose: define a new seed
50
51   input:
52       none
53
54   output:
55       none
56
57   return:
58       none
59
60   global variables:
61       rseed0
62       rseed
63       k, c, m
64
65   specific functions:
66       none
67
68   comments
69       none
70
71****************************************************************************/
72void newseed(void)
73{
74
75  rseed0 = (k*rseed0+c) % m; rseed = (rseed0+54321) % m;
76}
77/****************************************************************************/
78/* double ranf(void)
79
80   Purpose: Generate a random number with rectangular distribution/uniform
81            distribution between the value [0, m]
82
83   input:
84       none
85
86   output:
87       none
88
89   return:
90       random number of type double
91
92   global variables:
93       rseed0
94       rseed
95       k, c, m
96
97   specific functions:
98       none
99
100   comments
101       none
102
103****************************************************************************/
104double ranf(void)
105{
106  /* Generate random number with rectangular distribution */
107  rseed = (k*rseed+c) % m; return (rseed/1e8);
108}
109
110#undef k
111#undef c
112#undef m
113
114/****************************************************************************/
115/* void setrancut(double cut)
116
117   Purpose:   Set a cut for normal distribution
118
119   input:
120       cut : number of sigma for cutting the distribution
121
122   output:
123       none
124
125   return:
126       none
127
128   global variables:
129       normcut_
130
131   specific functions:
132       none
133
134   comments
135       none
136
137****************************************************************************/
138void setrancut(const double cut)
139{
140
141  printf("\n");
142  printf("setrancut: cut set to %3.1f\n", cut);
143
144  normcut_ = cut;
145}
146
147/****************************************************************************/
148/* double normranf(void)
149
150   Purpose:
151     Generate random numbers with Gaussian/normal distribution (m=0, sigma=1)
152     and cut normcut_
153
154   input:
155       none
156
157   output:
158       none
159
160   return:
161       random number
162
163   global variables:
164       normcut_
165       maxiter
166
167   specific functions:
168       ranf
169
170   comments
171       none
172
173****************************************************************************/
174/* maximum number of iteration to generate the random number */
175#define maxiter         100
176double normranf(void)
177{ 
178  int i, j;
179  double f, w;
180
181  j = 0;
182  do {
183    j++;
184    w = 0.0;
185    for (i = 1; i <= 12; i++)
186      w += ranf();
187    f = w - 6.0;
188  }
189  while (fabs(f) > fabs(normcut_) && j <= maxiter);
190
191  if (j > maxiter)
192    fprintf(stdout,"  *** fatal error in normranf\n");
193  return f;
194}
195#undef maxiter
196
197/* convert degree to radian */
198double dtor(const double d) { return (d*M_PI/180.0); }
199
200
201double GetAngle(const double x, const double y)
202{
203  double z;
204 
205//  if (pi == 0e0)
206//    fprintf(stdout,"** pi not initialized in GetAngle\n");
207  if (x != 0e0)
208    z = atan(y/x);
209  else
210    z = sgn(y)*M_PI/2.0;
211  if (x >= 0.0)
212    return z;
213  if (y >= 0.0)
214    z += M_PI;
215  else
216    z -= M_PI;
217  return z;
218}
219
220
221void CopyVec(const int n, const Vector &a, Vector &b)
222{
223  int i;
224
225  for (i = 0; i < n; i++)
226    b[i] = a[i];
227}
228
229
230void AddVec(const int n, const Vector &a, Vector &b)
231{
232  int i;
233  for (i = 0; i < n; i++)
234    b[i] = a[i] + b[i];
235}
236
237
238void SubVec(int n, const Vector &a, Vector &b)
239{
240  int i;
241
242  for (i = 0; i < n; i++)
243    b[i] -= a[i];
244}
245
246
247double xabs(long n, Vector &x)
248{
249  long    i;
250  double  sum;
251
252  sum = 0.0;
253  for (i = 0; i < n; i++)
254    sum += sqr(x[i]);
255
256  return sqrt(sum);
257}
258
259
260/****************************************************************************/
261/* void UnitMat(const int n, Matrix &A)
262
263   Purpose:
264       generate a unit matrix A of rank n
265
266   Input:
267         n  rank of matrix A
268         A  matrix
269
270   Output:
271       none
272
273   Return:
274       matrix A
275
276   Global variables:
277       
278
279   Specific functions:
280       
281   Comments:
282       Parameter passed to variable A must be defined as type Matrix
283
284****************************************************************************/
285
286void UnitMat(const int n, Matrix &A)
287{
288  int i, j;
289
290  for (i = 1; i <= n; i++) {
291    for (j = 1; j <= n; j++) {
292      if (i == j)
293        A[i-1][j-1] = 1.0;
294      else
295        A[i-1][j-1] = 0.0;
296    }
297  }
298}
299
300/****************************************************************************/
301/* void ZeroMat(const int n, Matrix &A)
302
303   Purpose:
304       generate a zero matrix A of rank n
305
306   Input:
307       
308
309   Output:
310       none
311
312   Return:
313       matrix A
314
315   Global variables:
316       
317
318   Specific functions:
319       
320   Comments:
321        Parameter passed to variable A must be defined as type Matrix
322
323****************************************************************************/
324void ZeroMat(const int n, Matrix &A)
325{
326  int i, j;
327
328  for (i = 0; i < n; i++) {
329    for (j = 0; j < n; j++)
330      A[i][j] = 0.0;
331  }
332}
333
334/****************************************************************************/
335/* void CopyMat(const int n, const Matrix &A, Matrix &B)
336
337   Purpose:
338       copy the contents of matrix A to matrix B.
339       Matrix A and Matrix B both have rank n.
340
341   Input:
342       n:  rank of matrix A and B
343     A,B:  n*n matrices
344   Output:
345       none
346
347   Return:
348       matrix B
349
350   Global variables:
351       
352
353   Specific functions:
354       
355   Comments:
356        Parameter passed to variable A and B must be defined as type Matrix
357
358****************************************************************************/
359void CopyMat(const int n, const Matrix &A, Matrix &B)
360{
361  int i;
362
363  for (i = 0; i < n; i++)
364    CopyVec(n, A[i], B[i]);
365}
366
367/****************************************************************************/
368/* void AddMat(const int n, const Matrix &A, Matrix &B)
369
370   Purpose:
371       add matrix A and matrix B, and assign the result to matrix B
372       Matrix A and Matrix B both have rank n.
373
374   Input:
375       n:  rank of matrix A and B
376     A,B:  n*n matrices
377   Output:
378       none
379
380   Return:
381       matrix B
382
383   Global variables:
384       
385
386   Specific functions:
387       
388   Comments:
389        Parameter passed to variable A and B must be defined as type Matrix
390
391****************************************************************************/
392void AddMat(const int n, const Matrix &A, Matrix &B)
393{
394  int i;
395
396  for (i = 0; i < n; i++)
397    AddVec(n, A[i], B[i]);
398}
399
400/****************************************************************************/
401/* void SubMat(const int n, const Matrix &A, Matrix &B)
402
403   Purpose:
404       substract matrix A from matrix B, and assign the result to matrix B
405       Matrix A and Matrix B both have rank n.
406
407   Input:
408       n:  rank of matrix A and B
409     A,B:  n*n matrices
410   Output:
411       none
412
413   Return:
414       matrix B
415
416   Global variables:
417       
418
419   Specific functions:
420       
421   Comments:
422        Parameter passed to variable A and B must be defined as type Matrix
423
424****************************************************************************/
425void SubMat(const int n, const Matrix &A, Matrix &B)
426{
427  /*n : integer; VAR a, b : matrix*/
428  int i;
429
430  for (i = 0; i < n; i++)
431    SubVec(n, A[i], B[i]);
432}
433
434
435void LinTrans(const int n, const Matrix &A, Vector &x)
436{
437  int i, j;
438  Vector y;
439
440  for (i = 0; i < n; i++) {
441    y[i] = 0e0;
442    for (j = 0; j < n; j++)
443      y[i] += A[i][j]*x[j];
444  }
445  CopyVec(n, y, x);
446}
447
448
449void MulcMat(const int n, const double c, Matrix &A)
450{
451  int i,j;
452
453  for (i = 0; i < n; i++)
454    for (j = 0; j < n; j++)
455      A[i][j] = A[i][j]*c;
456}
457
458
459void MulLMat(const int n, const Matrix &A, Matrix &B)
460{
461  int i, j, k;
462  double x;
463  Matrix C;
464
465  for (i = 0; i < n; i++)
466    for (j = 0; j < n; j++) {
467      x = 0e0;
468      for (k = 0; k < n; k++)
469        x += A[i][k]*B[k][j];
470      C[i][j] = x;
471    }
472
473  CopyMat(n, C, B);
474}
475
476
477void MulRMat(const int n, Matrix &A, const Matrix &B)
478{
479  int i, j, k;
480  double x;
481  Matrix C;
482
483  for (i = 0; i < n; i++)
484    for (j = 0; j < n; j++) {
485      x = 0e0;
486      for (k = 0; k < n; k++)
487        x += A[i][k]*B[k][j];
488      C[i][j] = x;
489    }
490
491  CopyMat(n, C, A);
492}
493
494
495double TrMat(const int n, const Matrix &A)
496{
497  int i;
498  double x;
499
500  x = 0e0;
501  for (i = 0; i < n; i++)
502    x += A[i][i];
503  return x;
504}
505
506
507void TpMat(const int n, Matrix &A)
508{
509  int i, j;
510  double x;
511
512  for (i = 1; i <= n; i++) {
513    for (j = 0; j <= i-2; j++) {
514      x = A[i-1][j];
515      A[i-1][j] = A[j][i-1];
516      A[j][i-1] = x;
517    }
518  }
519}
520
521
522void SwapSigmaMat(Matrix &A)
523{
524  int i, j;
525  double x;
526
527  for (i = 0; i <= 2; i++) {
528    for (j = 0; j <= 2; j++) {
529      x = A[2*i][2*j]; A[2*i][2*j] = A[2*i+1][2*j+1]; A[2*i+1][2*j+1] = x;
530      x = A[2*i][2*j+1]; A[2*i][2*j+1] = A[2*i+1][2*j]; A[2*i+1][2*j] = x;
531    }
532  }
533}
534
535
536double GdetMat(long n, struct LOC_DetMat *LINK)
537{
538  double Result = 0.0;
539  long k, sign;
540  double det;
541
542  if (n > 1)
543  {
544    det = 0e0;
545    if ((n & 1) == 1)
546      sign = 1;
547    else
548      sign = -1;
549    for (k = 0; k < ss_dim; k++) {
550      if (!LINK->cross[k]) {
551        LINK->cross[k] = true;
552        det += sign * (*LINK->a)[n - 1][k] * GdetMat(n - 1, LINK);
553        LINK->cross[k] = false;
554        sign = -sign;
555      }
556    }
557    return det;
558  }
559  for (k = 0; k < ss_dim; k++) {
560    if (!LINK->cross[k])
561      Result = (*LINK->a)[n - 1][k];
562  }
563  return Result;
564}
565
566
567double DetMat(const int n, const Matrix &A_)
568{
569  struct LOC_DetMat V;
570  long j;
571  double d;
572
573  V.a = &A_;
574  if (n == 2)  /* simple case of a matrix of rank 2*/
575    return ((*V.a)[0][0] * (*V.a)[1][1] - (*V.a)[0][1] * (*V.a)[1][0]);
576  else if (n == 3) { /* simple case of a matrix of rank 3*/
577    d = (*V.a)[0][0]
578        * ((*V.a)[1][1] * (*V.a)[2][2] - (*V.a)[1][2] * (*V.a)[2][1]);
579    d += (*V.a)[0][1]
580         * ((*V.a)[1][2] * (*V.a)[2][0] - (*V.a)[1][0] * (*V.a)[2][2]);
581    d += (*V.a)[0][2]
582         * ((*V.a)[1][0] * (*V.a)[2][1] - (*V.a)[1][1] * (*V.a)[2][0]);
583    return d;
584  } else {
585    for (j = 1; j <= ss_dim; j++) {
586      if (j <= n)
587        V.cross[j - 1] = false;
588      else
589        V.cross[j - 1] = true;
590    }
591    return (GdetMat(n, &V));
592  }
593}
594
595
596void swap_(double *x, double *y, struct LOC_InvMat *LINK)
597{
598  double d;
599
600  d  = *x;
601  *x = *y;
602  *y = d;
603}
604
605void Interchange(struct LOC_InvMat *LINK)
606{
607  long l, FORLIM;
608
609  if (LINK->row == LINK->column)
610    return;
611  LINK->determ = -LINK->determ;
612  FORLIM = LINK->n;
613  for (l = 0; l < FORLIM; l++)
614    swap_(&(*LINK->a)[LINK->row - 1][l],
615          &(*LINK->a)[LINK->column - 1][l], LINK);
616}
617
618
619bool InvMat(const int n_, Matrix &A_)
620{
621  struct LOC_InvMat V;
622  bool Result = false;
623  long i, j, k, l, l1;
624  double amax, t, d;
625  Matrix b;
626  iv1 ipivot;
627  iv2 index;
628  v1 pivot;
629  long FORLIM, FORLIM1;
630
631  V.n = n_;
632  V.a = &A_;
633
634  /* if 2-square matrix */
635  if (V.n == 2) {
636    d = DetMat(2, *V.a);
637    if (d != 0e0) {  /* non zero determinant */
638      Result = true;
639      b[0][0] = (*V.a)[1][1] / d;
640      b[0][1] = -((*V.a)[0][1] / d);
641      b[1][0] = -((*V.a)[1][0] / d);
642      b[1][1] = (*V.a)[0][0] / d;
643      CopyMat(V.n, b, *V.a);
644    } else /* non iversible matrix */
645      Result = false;
646  } else { /* matrix with n greater than 2 */
647    V.determ = 1.0;
648    FORLIM = V.n;
649    for (j = 0; j < FORLIM; j++)
650      ipivot[j] = 0;
651    i = 1;
652    while (i <= V.n && V.determ != 0e0) {
653      amax = 0e0;
654      FORLIM = V.n;
655      for (j = 1; j <= FORLIM; j++) {
656        if (ipivot[j - 1] != 1) {
657          FORLIM1 = V.n;
658          for (k = 1; k <= FORLIM1; k++) {
659            if (ipivot[k - 1] > 1) goto _L1;
660            if (ipivot[k - 1] < 1) {
661              if (fabs(amax) < fabs((*V.a)[j - 1][k - 1])) {
662                V.row = j;
663                V.column = k;
664                amax = (*V.a)[j - 1][k - 1];
665              }
666            }
667          }
668        }
669      }
670      if (amax == 0e0) {
671        Result = false;
672        V.determ = 0e0;
673      } else {
674        Result = true;
675        ipivot[V.column - 1]++;
676        Interchange(&V);
677        index[i - 1][0] = V.row;
678        index[i - 1][1] = V.column;
679        pivot[i - 1] = (*V.a)[V.column - 1][V.column - 1];
680        V.determ *= pivot[i - 1];
681        (*V.a)[V.column - 1][V.column - 1] = 1.0;
682        FORLIM = V.n;
683        for (l = 0; l < FORLIM; l++)
684          (*V.a)[V.column - 1][l] /= pivot[i - 1];
685        FORLIM = V.n;
686        for (l1 = 0; l1 < FORLIM; l1++) {
687          if (l1 + 1 != V.column) {
688            t = (*V.a)[l1][V.column - 1];
689            (*V.a)[l1][V.column - 1] = 0e0;
690            FORLIM1 = V.n;
691            for (l = 0; l < FORLIM1; l++)
692              (*V.a)[l1][l] -= (*V.a)[V.column - 1][l] * t;
693          }
694        }
695      }  /*else */
696      i++;
697    }  /*while*/
698    if (V.determ != 0e0) {
699      FORLIM = V.n;
700      for (i = 1; i <= FORLIM; i++) {
701        l = V.n - i + 1;
702        if (index[l - 1][0] != index[l - 1][1]) {
703          V.row = index[l - 1][0];
704          V.column = index[l - 1][1];
705          FORLIM1 = V.n;
706          for (k = 0; k < FORLIM1; k++)
707            swap_(&(*V.a)[k][V.row - 1], &(*V.a)[k][V.column - 1], &V);
708        }
709      }
710    }
711  }
712_L1:
713  return Result;
714}
715
716
717#define SWAP(a,b) {float temp=(a);(a)=(b);(b)=temp;}
718
719bool InvMat2(double a[4][4])
720{
721  const int n = 4;
722
723  int     indxc[n], indxr[n], ipiv[n];
724  int     i, icol = 0, irow = 0, j, k, l, ll;
725  double  big, dum, pivinv;
726
727  for (j=0;j<n;j++)
728    ipiv[j]=0;
729  for (i=0;i<n;i++) {
730    big=0.0;
731    for (j=0;j<n;j++)
732      if (ipiv[j] != 1)
733        for (k=0;k<n;k++) {
734          if (ipiv[k] == 0) {
735            if (fabs(a[j][k]) >= big) {
736              big=fabs(a[j][k]);
737              irow=j;
738              icol=k;
739            }
740          } else if (ipiv[k] > 1) fprintf(stdout,"GAUSSJ: Singular Matrix-1");
741                                }
742    ++(ipiv[icol]);
743    if (irow != icol) {
744      for (l=0;l<=n;l++) SWAP(a[irow][l],a[icol][l])
745                           //~ for (l=0;l<=n;l++) SWAP(b[irow][l],b[icol][l])
746                           }
747    indxr[i]=irow;
748    indxc[i]=icol;
749    if (a[icol][icol] == 0.0) fprintf(stdout,"GAUSSJ: Singular Matrix-2");
750    pivinv=1.0/a[icol][icol];
751    a[icol][icol]=1.0;
752    for (l=0;l<n;l++) a[icol][l] *= pivinv;
753    //~ for (l=0;l<n;l++) b[icol][l] *= pivinv;
754    for (ll=0;ll<n;ll++)
755      if (ll != icol) {
756        dum=a[ll][icol];
757        a[ll][icol]=0.0;
758        for (l=0;l<n;l++) a[ll][l] -= a[icol][l]*dum;
759        //~ for (l=0;l<n;l++) b[ll][l] -= b[icol][l]*dum;
760      }
761  }
762  for (l=n-1;l>=0;l--) {
763    if (indxr[l] != indxc[l])
764      for (k=0;k<n;k++)
765        SWAP(a[k][indxr[l]],a[k][indxc[l]]);
766  }
767  return true;
768}
769#undef SWAP
770
771
772void prtmat(const int n, const Matrix &A)
773{
774  int i, j;
775
776  printf("matrix:\n");
777  for (i = 0; i < n; i++) {
778    for (j = 0; j < n; j++)
779      printf(" %14.6e", A[i][j]);
780//      printf(" %24.16e", A[i][j]);
781    putchar('\n');
782  }
783}
784
Note: See TracBrowser for help on using the repository browser.