Fixing copyright issues and code contributors
[alexxy/gromacs.git] / src / gmxlib / gmx_lapack / dgebrd.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013, 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 "gmx_blas.h"
37 #include "lapack_limits.h"
38
39
40 void
41 F77_FUNC(dgebrd,DGEBRD)(int *m, 
42         int *n, 
43         double *a, 
44         int *lda, 
45         double *d__, 
46         double *e,
47         double *tauq, 
48         double *taup,
49         double *work, 
50         int *lwork,
51         int *info)
52 {
53     /* System generated locals */
54     int a_dim1, a_offset, i_1, i_2, i_3, i_4;
55
56     /* Local variables */
57     int i_, j, nx,nb;
58     double ws;
59     int nbmin, iinfo, minmn;
60     int ldwrkx, ldwrky;
61     double one = 1.0;
62     double minusone = -1.0;
63
64     a_dim1 = *lda;
65     a_offset = 1 + a_dim1;
66     a -= a_offset;
67     --d__;
68     --e;
69     --tauq;
70     --taup;
71     --work;
72
73     nb = DGEBRD_BLOCKSIZE;
74     *info = 0;
75     if (*lwork==-1) {
76       work[1] = (double) ( (*m + *n) * nb);
77       return;
78     }
79     minmn = (*m < *n) ? *m : *n;
80     if (minmn == 0) {
81       work[1] = 1.;
82       return;
83     }
84
85     ws = (*m > *n) ? *m : *n;
86     ldwrkx = *m;
87     ldwrky = *n;
88
89     if (nb > 1 && nb < minmn) {
90         nx = DGEBRD_CROSSOVER;
91         if (nx < minmn) {
92             ws = (double) ((*m + *n) * nb);
93             if ((double) (*lwork) < ws) {
94               nbmin = DGEBRD_MINBLOCKSIZE;
95                 if (*lwork >= (*m + *n) * nbmin) {
96                     nb = *lwork / (*m + *n);
97                 } else {
98                     nb = 1;
99                     nx = minmn;
100                 }
101             }
102         }
103     } else {
104         nx = minmn;
105     }
106
107     i_1 = minmn - nx;
108     i_2 = nb;
109     for (i_ = 1; i_2 < 0 ? i_ >= i_1 : i_ <= i_1; i_ += i_2) {
110
111         i_3 = *m - i_ + 1;
112         i_4 = *n - i_ + 1;
113         F77_FUNC(dlabrd,DLABRD)(&i_3, &i_4, &nb, &a[i_ + i_ * a_dim1], lda, &d__[i_], 
114                 &e[i_], &tauq[i_], &taup[i_], &work[1], &ldwrkx, 
115                 &work[ldwrkx * nb + 1], &ldwrky);
116
117         i_3 = *m - i_ - nb + 1;
118         i_4 = *n - i_ - nb + 1;
119         F77_FUNC(dgemm,DGEMM)("N", "T", &i_3, &i_4, &nb, &minusone, 
120                &a[i_ + nb + i_ * a_dim1], lda, &work[ldwrkx * nb + nb + 1],
121                &ldwrky, &one, &a[i_ + nb + (i_ + nb) * a_dim1], lda);
122         i_3 = *m - i_ - nb + 1;
123         i_4 = *n - i_ - nb + 1;
124         F77_FUNC(dgemm,DGEMM)("N", "N", &i_3, &i_4, &nb, &minusone, &work[nb + 1], &ldwrkx,
125                &a[i_ + (i_ + nb) * a_dim1], lda, &one, 
126                &a[i_ + nb + (i_ + nb) * a_dim1], lda);
127
128         if (*m >= *n) {
129             i_3 = i_ + nb - 1;
130             for (j = i_; j <= i_3; ++j) {
131                 a[j + j * a_dim1] = d__[j];
132                 a[j + (j + 1) * a_dim1] = e[j];
133             }
134         } else {
135             i_3 = i_ + nb - 1;
136             for (j = i_; j <= i_3; ++j) {
137                 a[j + j * a_dim1] = d__[j];
138                 a[j + 1 + j * a_dim1] = e[j];
139             }
140         }
141     }
142
143     i_2 = *m - i_ + 1;
144     i_1 = *n - i_ + 1;
145     F77_FUNC(dgebd2,DGEBD2)(&i_2, &i_1, &a[i_ + i_ * a_dim1], lda, &d__[i_], &e[i_], &
146             tauq[i_], &taup[i_], &work[1], &iinfo);
147     work[1] = ws;
148     return;
149
150 }