5af43274b9cb6e6fe05ed667b4a800d3af9a52c3
[alexxy/gromacs.git] / src / gmxlib / gmx_blas / ssyr2.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012, by the GROMACS development team, led by
5  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
6  * others, as listed in the AUTHORS file in the top-level source
7  * directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 #include <ctype.h>
36 #include <math.h>
37
38 #include <types/simple.h>
39 #include "gmx_blas.h"
40
41 void
42 F77_FUNC(ssyr2,SSYR2)(const char *    uplo,
43                       int *     n__,
44                       float *  alpha__,
45                       float *  x,
46                       int *     incx__,
47                       float *  y,
48                       int *     incy__,
49                       float *  a,
50                       int *     lda__)
51 {
52     int kx,ky,ix,iy,jx,jy,j,i;
53     float temp1,temp2;
54     const char ch=toupper(*uplo);
55     
56     int n = *n__;
57     int lda = *lda__;
58     int incx = *incx__;
59     int incy = *incy__;
60     float alpha = *alpha__;
61     
62     if(n<=0 || fabs(alpha)<GMX_FLOAT_MIN || incx==0 || incy==0 ||
63        (ch != 'U' && ch != 'L'))
64         return;
65     
66     jx = jy = kx = ky = 0;
67     
68     /* init start points for non-unit increments */
69     if(incx!=1 || incy!=1) {
70         if(incx>0)
71             kx = 1;
72         else
73             kx = 1 - (n - 1)*(incx);
74         if(incy>0)
75             ky = 1;
76         else
77             ky = 1 - (n - 1)*(incy);
78         
79         jx = kx;
80         jy = ky;
81     }
82     
83     if(ch == 'U') {
84         /* Data in upper 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_FLOAT_MIN  || fabs(y[j-1])>GMX_FLOAT_MIN ) {
89                     temp1 = alpha * y[j-1];
90                     temp2 = alpha * x[j-1];
91                     for(i=1;i<=j;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_FLOAT_MIN || fabs(y[jy-1])>GMX_FLOAT_MIN ) {
101                     temp1 = alpha * y[jy-1];
102                     temp2 = alpha * x[jx-1];
103                     ix = kx;
104                     iy = ky;
105                     for(i=1;i<=j;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     } else {
116         /* Data in lower part of A */
117         if(incx==1 && incy==1) {
118             /* Unit increments for both x and y */
119             for(j=1;j<=n;j++) {
120                 if( fabs(x[j-1])>GMX_FLOAT_MIN  || fabs(y[j-1])>GMX_FLOAT_MIN ) {
121                     temp1 = alpha * y[j-1];
122                     temp2 = alpha * x[j-1];
123                     for(i=j;i<=n;i++)
124                         a[(j-1)*(lda)+(i-1)] += x[i-1]*temp1 + y[i-1]*temp2;
125                 }
126             }
127         } else {
128             
129             /* non-unit increments */
130             for(j=1;j<=n;j++) {
131                 
132                 if( fabs(x[jx-1])>GMX_FLOAT_MIN || fabs(y[jy-1])>GMX_FLOAT_MIN ) {
133                     temp1 = alpha * y[jy-1];
134                     temp2 = alpha * x[jx-1];
135                     ix = jx;
136                     iy = jy;
137                     for(i=j;i<=n;i++) {
138                         a[(j-1)*(lda)+(i-1)] += x[ix-1]*temp1 + y[iy-1]*temp2;
139                         ix += incx;
140                         iy += incy;
141                     }
142                 }
143                 jx += incx;
144                 jy += incy;
145             }
146         }
147     }
148     
149     return;
150 }