Update copyright statements and change license to LGPL
[alexxy/gromacs.git] / src / gmxlib / gmx_lapack / sormlq.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 "gmx_lapack.h"
36 #include "lapack_limits.h"
37
38
39 void 
40 F77_FUNC(sormlq,SORMLQ)(const char *side, 
41         const char *trans,
42         int *m, 
43         int *n, 
44         int *k,
45         float *a,
46         int *lda, 
47         float *tau, 
48         float *c__, 
49         int *ldc, 
50         float *work, 
51         int *lwork, 
52         int *info)
53 {
54     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, 
55             i__5;
56   
57
58     int i__;
59     float t[4160]       /* was [65][64] */;
60     int i1, i2, i3, ib, ic, jc, nb, mi, ni, nq, nw, iws;
61     int left;
62     int nbmin, iinfo;
63     int notran;
64     int ldwork;
65     char transt[1];
66     int lwkopt;
67     int lquery;
68     int ldt = 65;
69
70     a_dim1 = *lda;
71     a_offset = 1 + a_dim1;
72     a -= a_offset;
73     --tau;
74     c_dim1 = *ldc;
75     c_offset = 1 + c_dim1;
76     c__ -= c_offset;
77     --work;
78
79     ic = jc = 0;
80
81     *info = 0;
82     left = (*side=='L' || *side=='l');
83     notran = (*trans=='N' || *trans=='n');
84     lquery = *lwork == -1;
85
86     if (left) {
87         nq = *m;
88         nw = *n;
89     } else {
90         nq = *n;
91         nw = *m;
92     }
93
94     nb = DORMLQ_BLOCKSIZE;
95     lwkopt = nw * nb;
96     work[1] = (float) lwkopt;
97     
98     if (*info != 0) {
99         i__1 = -(*info);
100         return;
101     } else if (lquery) {
102         return;
103     }
104
105     if (*m == 0 || *n == 0 || *k == 0) {
106         work[1] = 1.;
107         return;
108     }
109
110     nbmin = 2;
111     ldwork = nw;
112     if (nb > 1 && nb < *k) {
113         iws = nw * nb;
114         if (*lwork < iws) {
115             nb = *lwork / ldwork;
116             nbmin = DORMLQ_MINBLOCKSIZE;
117         }
118     } else {
119         iws = nw;
120     }
121
122     if (nb < nbmin || nb >= *k) {
123
124
125         F77_FUNC(sorml2,SORML2)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
126                 c_offset], ldc, &work[1], &iinfo);
127     } else {
128
129         if ((left && notran) || (!left && !notran)) {
130             i1 = 1;
131             i2 = *k;
132             i3 = nb;
133         } else {
134             i1 = (*k - 1) / nb * nb + 1;
135             i2 = 1;
136             i3 = -nb;
137         }
138
139         if (left) {
140             ni = *n;
141             jc = 1;
142         } else {
143             mi = *m;
144             ic = 1;
145         }
146
147         if (notran) {
148             *(unsigned char *)transt = 'T';
149         } else {
150             *(unsigned char *)transt = 'N';
151         }
152
153         i__1 = i2;
154         i__2 = i3;
155         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
156             i__4 = nb, i__5 = *k - i__ + 1;
157             ib = (i__4<i__5) ? i__4 : i__5;
158
159             i__4 = nq - i__ + 1;
160             F77_FUNC(slarft,SLARFT)("Forward", "Rowwise", &i__4, &ib, &a[i__ + i__ * a_dim1], 
161                     lda, &tau[i__], t, &ldt);
162             if (left) {
163
164                 mi = *m - i__ + 1;
165                 ic = i__;
166             } else {
167
168                 ni = *n - i__ + 1;
169                 jc = i__;
170             }
171
172             F77_FUNC(slarfb,SLARFB)(side, transt, "Forward", "Rowwise", &mi, &ni, &ib, &a[i__ 
173                     + i__ * a_dim1], lda, t, &ldt, &c__[ic + jc * c_dim1], 
174                     ldc, &work[1], &ldwork);
175         }
176     }
177     work[1] = (float) lwkopt;
178     return;
179
180 }
181
182