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

Last change on this file since 32 was 32, checked in by zhangj, 10 years ago

active the transport of the twiss functions and orbits of the transfer line.

  • Property svn:executable set to *
File size: 15.9 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/***********************************************************
221 * void CopyVec(const int n, const Vector &a, Vector &b)
222 *
223 *  Copy 6D vector a to b: b = a.
224 *
225 ***********************************************************/
226void CopyVec(const int n, const Vector &a, Vector &b)
227{
228  int i=0;
229
230  for (i = 0; i < n; i++)
231    b[i] = a[i];
232}
233
234
235void AddVec(const int n, const Vector &a, Vector &b)
236{
237  int i;
238  for (i = 0; i < n; i++)
239    b[i] = a[i] + b[i];
240}
241
242
243void SubVec(int n, const Vector &a, Vector &b)
244{
245  int i;
246
247  for (i = 0; i < n; i++)
248    b[i] -= a[i];
249}
250
251
252double xabs(long n, Vector &x)
253{
254  long    i;
255  double  sum;
256
257  sum = 0.0;
258  for (i = 0; i < n; i++)
259    sum += sqr(x[i]);
260
261  return sqrt(sum);
262}
263
264
265/****************************************************************************/
266/* void UnitMat(const int n, Matrix &A)
267
268   Purpose:
269       generate a unit matrix A of rank n
270
271   Input:
272         n  rank of matrix A
273         A  matrix
274
275   Output:
276       none
277
278   Return:
279       matrix A
280
281   Global variables:
282       
283
284   Specific functions:
285       
286   Comments:
287       Parameter passed to variable A must be defined as type Matrix
288
289****************************************************************************/
290
291void UnitMat(const int n, Matrix &A)
292{
293  int i, j;
294
295  for (i = 1; i <= n; i++) {
296    for (j = 1; j <= n; j++) {
297      if (i == j)
298        A[i-1][j-1] = 1.0;
299      else
300        A[i-1][j-1] = 0.0;
301    }
302  }
303}
304
305/****************************************************************************/
306/* void ZeroMat(const int n, Matrix &A)
307
308   Purpose:
309       generate a zero matrix A of rank n
310
311   Input:
312       
313
314   Output:
315       none
316
317   Return:
318       matrix A
319
320   Global variables:
321       
322
323   Specific functions:
324       
325   Comments:
326        Parameter passed to variable A must be defined as type Matrix
327
328****************************************************************************/
329void ZeroMat(const int n, Matrix &A)
330{
331  int i, j;
332
333  for (i = 0; i < n; i++) {
334    for (j = 0; j < n; j++)
335      A[i][j] = 0.0;
336  }
337}
338
339/****************************************************************************/
340/* void CopyMat(const int n, const Matrix &A, Matrix &B)
341
342   Purpose:
343       copy the contents of matrix A to matrix B.
344       Matrix A and Matrix B both have rank n.
345
346   Input:
347       n:  rank of matrix A and B
348     A,B:  n*n matrices
349   Output:
350       none
351
352   Return:
353       matrix B
354
355   Global variables:
356       
357
358   Specific functions:
359       
360   Comments:
361        Parameter passed to variable A and B must be defined as type Matrix
362
363****************************************************************************/
364void CopyMat(const int n, const Matrix &A, Matrix &B)
365{
366  int i;
367
368  for (i = 0; i < n; i++)
369    CopyVec(n, A[i], B[i]);
370}
371
372/****************************************************************************/
373/* void AddMat(const int n, const Matrix &A, Matrix &B)
374
375   Purpose:
376       add matrix A and matrix B, and assign the result to matrix B
377       Matrix A and Matrix B both have rank n.
378
379   Input:
380       n:  rank of matrix A and B
381     A,B:  n*n matrices
382   Output:
383       none
384
385   Return:
386       matrix B
387
388   Global variables:
389       
390
391   Specific functions:
392       
393   Comments:
394        Parameter passed to variable A and B must be defined as type Matrix
395
396****************************************************************************/
397void AddMat(const int n, const Matrix &A, Matrix &B)
398{
399  int i;
400
401  for (i = 0; i < n; i++)
402    AddVec(n, A[i], B[i]);
403}
404
405/****************************************************************************/
406/* void SubMat(const int n, const Matrix &A, Matrix &B)
407
408   Purpose:
409       substract matrix A from matrix B, and assign the result to matrix B
410       Matrix A and Matrix B both have rank n.
411
412   Input:
413       n:  rank of matrix A and B
414     A,B:  n*n matrices
415   Output:
416       none
417
418   Return:
419       matrix B
420
421   Global variables:
422       
423
424   Specific functions:
425       
426   Comments:
427        Parameter passed to variable A and B must be defined as type Matrix
428
429****************************************************************************/
430void SubMat(const int n, const Matrix &A, Matrix &B)
431{
432  /*n : integer; VAR a, b : matrix*/
433  int i;
434
435  for (i = 0; i < n; i++)
436    SubVec(n, A[i], B[i]);
437}
438
439
440void LinTrans(const int n, const Matrix &A, Vector &x)
441{
442  int i, j;
443  Vector y;
444
445  for (i = 0; i < n; i++) {
446    y[i] = 0e0;
447    for (j = 0; j < n; j++)
448      y[i] += A[i][j]*x[j];
449  }
450  CopyVec(n, y, x);
451}
452
453
454void MulcMat(const int n, const double c, Matrix &A)
455{
456  int i,j;
457
458  for (i = 0; i < n; i++)
459    for (j = 0; j < n; j++)
460      A[i][j] = A[i][j]*c;
461}
462
463
464/*********************************************************
465 * void MulLMat(const int n, const Matrix &A, Matrix &B)
466 *
467 * Matrix multiplication.  B = A * B
468 *
469 *
470 **********************************************************/
471void MulLMat(const int n, const Matrix &A, Matrix &B)
472{
473  int i=0, j=0, k=0;
474  double x=0.0;
475  Matrix C;
476
477  for (i = 0; i < n; i++)
478    for (j = 0; j < n; j++) {
479      x = 0e0;
480      for (k = 0; k < n; k++)
481        x += A[i][k]*B[k][j];
482      C[i][j] = x;
483    }
484
485  CopyMat(n, C, B);
486}
487
488/*********************************************************
489 * void MulRMat(const int n, const Matrix &A, Matrix &B)
490 *
491 * Matrix multiplication.  A = A * B
492 *
493 *
494 **********************************************************/
495void MulRMat(const int n, Matrix &A, const Matrix &B)
496{
497  int i=0, j=0, k=0;
498  double x=0.0;
499  Matrix C;
500
501  for (i = 0; i < n; i++)
502    for (j = 0; j < n; j++) {
503      x = 0e0;
504      for (k = 0; k < n; k++)
505        x += A[i][k]*B[k][j];
506      C[i][j] = x;
507    }
508
509  CopyMat(n, C, A);
510}
511
512/*********************************************************
513 * double TrMat(const int n, const Matrix &A)
514 *
515 * Calculate the trance of the matrix A.
516 *
517 *  return:
518 *          x.
519 *
520 **********************************************************/
521double TrMat(const int n, const Matrix &A)
522{
523  int i;
524  double x;
525
526  x = 0e0;
527  for (i = 0; i < n; i++)
528    x += A[i][i];
529  return x;
530}
531
532
533void TpMat(const int n, Matrix &A)
534{
535  int i, j;
536  double x;
537
538  for (i = 1; i <= n; i++) {
539    for (j = 0; j <= i-2; j++) {
540      x = A[i-1][j];
541      A[i-1][j] = A[j][i-1];
542      A[j][i-1] = x;
543    }
544  }
545}
546
547
548void SwapSigmaMat(Matrix &A)
549{
550  int i, j;
551  double x;
552
553  for (i = 0; i <= 2; i++) {
554    for (j = 0; j <= 2; j++) {
555      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;
556      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;
557    }
558  }
559}
560
561
562double GdetMat(long n, struct LOC_DetMat *LINK)
563{
564  double Result = 0.0;
565  long k, sign;
566  double det;
567
568  if (n > 1)
569  {
570    det = 0e0;
571    if ((n & 1) == 1)
572      sign = 1;
573    else
574      sign = -1;
575    for (k = 0; k < ss_dim; k++) {
576      if (!LINK->cross[k]) {
577        LINK->cross[k] = true;
578        det += sign * (*LINK->a)[n - 1][k] * GdetMat(n - 1, LINK);
579        LINK->cross[k] = false;
580        sign = -sign;
581      }
582    }
583    return det;
584  }
585  for (k = 0; k < ss_dim; k++) {
586    if (!LINK->cross[k])
587      Result = (*LINK->a)[n - 1][k];
588  }
589  return Result;
590}
591
592
593double DetMat(const int n, const Matrix &A_)
594{
595  struct LOC_DetMat V;
596  long j;
597  double d;
598
599  V.a = &A_;
600  if (n == 2)  /* simple case of a matrix of rank 2*/
601    return ((*V.a)[0][0] * (*V.a)[1][1] - (*V.a)[0][1] * (*V.a)[1][0]);
602  else if (n == 3) { /* simple case of a matrix of rank 3*/
603    d = (*V.a)[0][0]
604        * ((*V.a)[1][1] * (*V.a)[2][2] - (*V.a)[1][2] * (*V.a)[2][1]);
605    d += (*V.a)[0][1]
606         * ((*V.a)[1][2] * (*V.a)[2][0] - (*V.a)[1][0] * (*V.a)[2][2]);
607    d += (*V.a)[0][2]
608         * ((*V.a)[1][0] * (*V.a)[2][1] - (*V.a)[1][1] * (*V.a)[2][0]);
609    return d;
610  } else {
611    for (j = 1; j <= ss_dim; j++) {
612      if (j <= n)
613        V.cross[j - 1] = false;
614      else
615        V.cross[j - 1] = true;
616    }
617    return (GdetMat(n, &V));
618  }
619}
620
621
622void swap_(double *x, double *y, struct LOC_InvMat *LINK)
623{
624  double d;
625
626  d  = *x;
627  *x = *y;
628  *y = d;
629}
630
631void Interchange(struct LOC_InvMat *LINK)
632{
633  long l, FORLIM;
634
635  if (LINK->row == LINK->column)
636    return;
637  LINK->determ = -LINK->determ;
638  FORLIM = LINK->n;
639  for (l = 0; l < FORLIM; l++)
640    swap_(&(*LINK->a)[LINK->row - 1][l],
641          &(*LINK->a)[LINK->column - 1][l], LINK);
642}
643
644
645bool InvMat(const int n_, Matrix &A_)
646{
647  struct LOC_InvMat V;
648  bool Result = false;
649  long i, j, k, l, l1;
650  double amax, t, d;
651  Matrix b;
652  iv1 ipivot;
653  iv2 index;
654  v1 pivot;
655  long FORLIM, FORLIM1;
656
657  V.n = n_;
658  V.a = &A_;
659
660  /* if 2-square matrix */
661  if (V.n == 2) {
662    d = DetMat(2, *V.a);
663    if (d != 0e0) {  /* non zero determinant */
664      Result = true;
665      b[0][0] = (*V.a)[1][1] / d;
666      b[0][1] = -((*V.a)[0][1] / d);
667      b[1][0] = -((*V.a)[1][0] / d);
668      b[1][1] = (*V.a)[0][0] / d;
669      CopyMat(V.n, b, *V.a);
670    } else /* non iversible matrix */
671      Result = false;
672  } else { /* matrix with n greater than 2 */
673    V.determ = 1.0;
674    FORLIM = V.n;
675    for (j = 0; j < FORLIM; j++)
676      ipivot[j] = 0;
677    i = 1;
678    while (i <= V.n && V.determ != 0e0) {
679      amax = 0e0;
680      FORLIM = V.n;
681      for (j = 1; j <= FORLIM; j++) {
682        if (ipivot[j - 1] != 1) {
683          FORLIM1 = V.n;
684          for (k = 1; k <= FORLIM1; k++) {
685            if (ipivot[k - 1] > 1) goto _L1;
686            if (ipivot[k - 1] < 1) {
687              if (fabs(amax) < fabs((*V.a)[j - 1][k - 1])) {
688                V.row = j;
689                V.column = k;
690                amax = (*V.a)[j - 1][k - 1];
691              }
692            }
693          }
694        }
695      }
696      if (amax == 0e0) {
697        Result = false;
698        V.determ = 0e0;
699      } else {
700        Result = true;
701        ipivot[V.column - 1]++;
702        Interchange(&V);
703        index[i - 1][0] = V.row;
704        index[i - 1][1] = V.column;
705        pivot[i - 1] = (*V.a)[V.column - 1][V.column - 1];
706        V.determ *= pivot[i - 1];
707        (*V.a)[V.column - 1][V.column - 1] = 1.0;
708        FORLIM = V.n;
709        for (l = 0; l < FORLIM; l++)
710          (*V.a)[V.column - 1][l] /= pivot[i - 1];
711        FORLIM = V.n;
712        for (l1 = 0; l1 < FORLIM; l1++) {
713          if (l1 + 1 != V.column) {
714            t = (*V.a)[l1][V.column - 1];
715            (*V.a)[l1][V.column - 1] = 0e0;
716            FORLIM1 = V.n;
717            for (l = 0; l < FORLIM1; l++)
718              (*V.a)[l1][l] -= (*V.a)[V.column - 1][l] * t;
719          }
720        }
721      }  /*else */
722      i++;
723    }  /*while*/
724    if (V.determ != 0e0) {
725      FORLIM = V.n;
726      for (i = 1; i <= FORLIM; i++) {
727        l = V.n - i + 1;
728        if (index[l - 1][0] != index[l - 1][1]) {
729          V.row = index[l - 1][0];
730          V.column = index[l - 1][1];
731          FORLIM1 = V.n;
732          for (k = 0; k < FORLIM1; k++)
733            swap_(&(*V.a)[k][V.row - 1], &(*V.a)[k][V.column - 1], &V);
734        }
735      }
736    }
737  }
738_L1:
739  return Result;
740}
741
742
743#define SWAP(a,b) {float temp=(a);(a)=(b);(b)=temp;}
744
745bool InvMat2(double a[4][4])
746{
747  const int n = 4;
748
749  int     indxc[n], indxr[n], ipiv[n];
750  int     i, icol = 0, irow = 0, j, k, l, ll;
751  double  big, dum, pivinv;
752
753  for (j=0;j<n;j++)
754    ipiv[j]=0;
755  for (i=0;i<n;i++) {
756    big=0.0;
757    for (j=0;j<n;j++)
758      if (ipiv[j] != 1)
759        for (k=0;k<n;k++) {
760          if (ipiv[k] == 0) {
761            if (fabs(a[j][k]) >= big) {
762              big=fabs(a[j][k]);
763              irow=j;
764              icol=k;
765            }
766          } else if (ipiv[k] > 1) fprintf(stdout,"GAUSSJ: Singular Matrix-1");
767                                }
768    ++(ipiv[icol]);
769    if (irow != icol) {
770      for (l=0;l<=n;l++) SWAP(a[irow][l],a[icol][l])
771                           //~ for (l=0;l<=n;l++) SWAP(b[irow][l],b[icol][l])
772                           }
773    indxr[i]=irow;
774    indxc[i]=icol;
775    if (a[icol][icol] == 0.0) fprintf(stdout,"GAUSSJ: Singular Matrix-2");
776    pivinv=1.0/a[icol][icol];
777    a[icol][icol]=1.0;
778    for (l=0;l<n;l++) a[icol][l] *= pivinv;
779    //~ for (l=0;l<n;l++) b[icol][l] *= pivinv;
780    for (ll=0;ll<n;ll++)
781      if (ll != icol) {
782        dum=a[ll][icol];
783        a[ll][icol]=0.0;
784        for (l=0;l<n;l++) a[ll][l] -= a[icol][l]*dum;
785        //~ for (l=0;l<n;l++) b[ll][l] -= b[icol][l]*dum;
786      }
787  }
788  for (l=n-1;l>=0;l--) {
789    if (indxr[l] != indxc[l])
790      for (k=0;k<n;k++)
791        SWAP(a[k][indxr[l]],a[k][indxc[l]]);
792  }
793  return true;
794}
795#undef SWAP
796
797
798void prtmat(const int n, const Matrix &A)
799{
800  int i, j;
801
802  printf("matrix:\n");
803  for (i = 0; i < n; i++) {
804    for (j = 0; j < n; j++)
805      printf(" %14.6e", A[i][j]);
806//      printf(" %24.16e", A[i][j]);
807    putchar('\n');
808  }
809}
810
Note: See TracBrowser for help on using the repository browser.