Update copyright statements and change license to LGPL
[alexxy/gromacs.git] / src / gmxlib / gmx_blas / sgemv.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(sgemv,SGEMV)(const char *trans, 
43                       int *m__,
44                       int *n__,
45                       float *alpha__,
46                       float *a,
47                       int *lda__,
48                       float *x,
49                       int *incx__,
50                       float *beta__,
51                       float *y,
52                       int *incy__)
53 {
54   const char ch=toupper(*trans);
55   int lenx,leny,kx,ky;
56   int i,j,jx,jy,ix,iy;
57   float temp;
58
59   int m = *m__;
60   int n = *n__;
61   float alpha = *alpha__;
62   float beta = *beta__;
63   int incx = *incx__;
64   int incy = *incy__;
65   int lda = *lda__;
66   
67   if(n<=0 || m<=0 || (fabs(alpha)<GMX_FLOAT_MIN && fabs(beta-1.0)<GMX_FLOAT_EPS))
68     return;
69
70   if(ch=='N') {
71     lenx = n;
72     leny = m;
73   } else {
74     lenx = m;
75     leny = n;
76   }
77   
78    if(incx>0)
79     kx = 1;
80   else
81     kx = 1 - (lenx -1)*(incx);
82
83   if(incy>0)
84     ky = 1;
85   else
86     ky = 1 - (leny -1)*(incy);
87  
88   if(fabs(beta-1.0)>GMX_FLOAT_EPS) {
89     if(incy==1) {
90       if(fabs(beta)<GMX_FLOAT_MIN)
91         for(i=0;i<leny;i++)
92           y[i] = 0.0;
93       else
94         for(i=0;i<leny;i++)
95           y[i] *= beta;
96     } else {
97       /* non-unit incr. */
98       iy = ky;
99       if(fabs(beta)<GMX_FLOAT_MIN) 
100         for(i=0;i<leny;i++,iy+=incy)
101           y[iy] = 0.0;
102       else
103         for(i=0;i<leny;i++,iy+=incy)
104           y[iy] *= beta;
105     }
106   }
107   
108   if(fabs(alpha)<GMX_FLOAT_MIN)
109     return;
110   
111   if(ch=='N') {
112     jx = kx;
113     if(incy==1) {
114       for(j=1;j<=n;j++,jx+=incx) 
115         if( fabs(x[jx-1])>GMX_FLOAT_MIN) {
116           temp = alpha * x[jx-1];
117           for(i=1;i<=m;i++)
118             y[i-1] += temp * a[(j-1)*(lda)+(i-1)];
119         }
120     } else {
121       /* non-unit y incr. */
122       for(j=1;j<=n;j++,jx+=incx) 
123         if( fabs(x[jx-1])>GMX_FLOAT_MIN) {
124           temp = alpha * x[jx-1];
125           iy = ky;
126           for(i=1;i<=m;i++,iy+=incy)
127             y[iy-1] += temp * a[(j-1)*(lda)+(i-1)];
128         }
129     }
130   } else {
131     /* transpose */
132     jy = ky;
133     if(incx==1) {
134       for(j=1;j<=n;j++,jy+=incy) {
135         temp = 0.0;
136         for(i=1;i<=m;i++)
137           temp += a[(j-1)*(lda)+(i-1)] * x[i-1];
138         y[jy-1] += alpha * temp;
139       }
140     } else {
141       /* non-unit y incr. */
142       for(j=1;j<=n;j++,jy+=incy) {
143         temp = 0.0;
144         ix = kx;
145         for(i=1;i<=m;i++,ix+=incx)
146           temp += a[(j-1)*(lda)+(i-1)] * x[ix-1];
147         y[jy-1] += alpha * temp;
148       }
149     }
150   }
151
152