Merge release-5-0 into master
[alexxy/gromacs.git] / src / gromacs / linearalgebra / gmx_blas / dsyr2.c
1 #include <ctype.h>
2 #include <math.h>
3
4 #include "gromacs/utility/real.h"
5
6 #include "../gmx_blas.h"
7
8 void
9 F77_FUNC(dsyr2,DSYR2)(const char *    uplo,
10                       int *     n__,
11                       double *  alpha__,
12                       double *  x,
13                       int *     incx__,
14                       double *  y,
15                       int *     incy__,
16                       double *  a,
17                       int *     lda__)
18 {
19     int kx,ky,ix,iy,jx,jy,j,i;
20     double temp1,temp2;
21     const char ch=toupper(*uplo);
22     
23     int n = *n__;
24     int lda = *lda__;
25     int incx = *incx__;
26     int incy = *incy__;
27     float alpha = *alpha__;
28     
29     
30     if(n<=0 || fabs(alpha)<GMX_DOUBLE_MIN || incx==0 || incy==0 ||
31        (ch != 'U' && ch != 'L'))
32         return;
33     
34     jx = jy = kx = ky = 0;
35     
36     /* init start points for non-unit increments */
37     if(incx!=1 || incy!=1) {
38         if(incx>0)
39             kx = 1;
40         else
41             kx = 1 - (n - 1)*(incx);
42         if(incy>0)
43             ky = 1;
44         else
45             ky = 1 - (n - 1)*(incy);
46         
47         jx = kx;
48         jy = ky;
49     }
50     
51     if(ch == 'U') {
52         /* Data in upper part of A */
53         if(incx==1 && incy==1) {
54             /* Unit increments for both x and y */
55             for(j=1;j<=n;j++) {
56                 if( fabs(x[j-1])>GMX_DOUBLE_MIN  || fabs(y[j-1])>GMX_DOUBLE_MIN ) {
57                     temp1 = alpha * y[j-1];
58                     temp2 = alpha * x[j-1];
59                     for(i=1;i<=j;i++)
60                         a[(j-1)*(lda)+(i-1)] += x[i-1]*temp1 + y[i-1]*temp2;
61                 }
62             }
63         } else {
64             
65             /* non-unit increments */
66             for(j=1;j<=n;j++) {
67                 
68                 if( fabs(x[jx-1])>GMX_DOUBLE_MIN || fabs(y[jy-1])>GMX_DOUBLE_MIN ) {
69                     temp1 = alpha * y[jy-1];
70                     temp2 = alpha * x[jx-1];
71                     ix = kx;
72                     iy = ky;
73                     for(i=1;i<=j;i++) {
74                         a[(j-1)*(lda)+(i-1)] += x[ix-1]*temp1 + y[iy-1]*temp2;
75                         ix += incx;
76                         iy += incy;
77                     }
78                 }
79                 jx += incx;
80                 jy += incy;
81             }
82         }
83     } else {
84         /* Data in lower part of A */
85         if(incx==1 && incy==1) {
86             /* Unit increments for both x and y */
87             for(j=1;j<=n;j++) {
88                 if( fabs(x[j-1])>GMX_DOUBLE_MIN  || fabs(y[j-1])>GMX_DOUBLE_MIN ) {
89                     temp1 = alpha * y[j-1];
90                     temp2 = alpha * x[j-1];
91                     for(i=j;i<=n;i++)
92                         a[(j-1)*(lda)+(i-1)] += x[i-1]*temp1 + y[i-1]*temp2;
93                 }
94             }
95         } else {
96             
97             /* non-unit increments */
98             for(j=1;j<=n;j++) {
99                 
100                 if( fabs(x[jx-1])>GMX_DOUBLE_MIN || fabs(y[jy-1])>GMX_DOUBLE_MIN ) {
101                     temp1 = alpha * y[jy-1];
102                     temp2 = alpha * x[jx-1];
103                     ix = jx;
104                     iy = jy;
105                     for(i=j;i<=n;i++) {
106                         a[(j-1)*(lda)+(i-1)] += x[ix-1]*temp1 + y[iy-1]*temp2;
107                         ix += incx;
108                         iy += incy;
109                     }
110                 }
111                 jx += incx;
112                 jy += incy;
113             }
114         }
115     }
116     
117     return;
118 }