PageRenderTime 60ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/structural/supporting_matl_misc_and_old/support/converted/lapack/dggglm.c

https://bitbucket.org/slawton/windturbinemdo-stevebitb
C | 418 lines | 134 code | 59 blank | 225 comment | 30 complexity | 9201507b61815fa4ec88fe5a9658ff9f MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. /* dggglm.f -- translated by f2c (version 20000121).
  2. You must link the resulting object file with the libraries:
  3. -lf2c -lm (in that order)
  4. */
  5. #include "f2c.h"
  6. /* Table of constant values */
  7. static integer c__1 = 1;
  8. static integer c_n1 = -1;
  9. static doublereal c_b32 = -1.;
  10. static doublereal c_b34 = 1.;
  11. /* > \brief <b> DGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE mat
  12. rices</b> */
  13. /* =========== DOCUMENTATION =========== */
  14. /* Online html documentation available at */
  15. /* http://www.netlib.org/lapack/explore-html/ */
  16. /* > \htmlonly */
  17. /* > Download DGGGLM + dependencies */
  18. /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggglm.
  19. f"> */
  20. /* > [TGZ]</a> */
  21. /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggglm.
  22. f"> */
  23. /* > [ZIP]</a> */
  24. /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggglm.
  25. f"> */
  26. /* > [TXT]</a> */
  27. /* > \endhtmlonly */
  28. /* Definition: */
  29. /* =========== */
  30. /* SUBROUTINE DGGGLM( N, M, P, A, LDA, B, LDB, D, X, Y, WORK, LWORK, */
  31. /* INFO ) */
  32. /* .. Scalar Arguments .. */
  33. /* INTEGER INFO, LDA, LDB, LWORK, M, N, P */
  34. /* .. */
  35. /* .. Array Arguments .. */
  36. /* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), D( * ), WORK( * ), */
  37. /* $ X( * ), Y( * ) */
  38. /* .. */
  39. /* > \par Purpose: */
  40. /* ============= */
  41. /* > */
  42. /* > \verbatim */
  43. /* > */
  44. /* > DGGGLM solves a general Gauss-Markov linear model (GLM) problem: */
  45. /* > */
  46. /* > minimize || y ||_2 subject to d = A*x + B*y */
  47. /* > x */
  48. /* > */
  49. /* > where A is an N-by-M matrix, B is an N-by-P matrix, and d is a */
  50. /* > given N-vector. It is assumed that M <= N <= M+P, and */
  51. /* > */
  52. /* > rank(A) = M and rank( A B ) = N. */
  53. /* > */
  54. /* > Under these assumptions, the constrained equation is always */
  55. /* > consistent, and there is a unique solution x and a minimal 2-norm */
  56. /* > solution y, which is obtained using a generalized QR factorization */
  57. /* > of the matrices (A, B) given by */
  58. /* > */
  59. /* > A = Q*(R), B = Q*T*Z. */
  60. /* > (0) */
  61. /* > */
  62. /* > In particular, if matrix B is square nonsingular, then the problem */
  63. /* > GLM is equivalent to the following weighted linear least squares */
  64. /* > problem */
  65. /* > */
  66. /* > minimize || inv(B)*(d-A*x) ||_2 */
  67. /* > x */
  68. /* > */
  69. /* > where inv(B) denotes the inverse of B. */
  70. /* > \endverbatim */
  71. /* Arguments: */
  72. /* ========== */
  73. /* > \param[in] N */
  74. /* > \verbatim */
  75. /* > N is INTEGER */
  76. /* > The number of rows of the matrices A and B. N >= 0. */
  77. /* > \endverbatim */
  78. /* > */
  79. /* > \param[in] M */
  80. /* > \verbatim */
  81. /* > M is INTEGER */
  82. /* > The number of columns of the matrix A. 0 <= M <= N. */
  83. /* > \endverbatim */
  84. /* > */
  85. /* > \param[in] P */
  86. /* > \verbatim */
  87. /* > P is INTEGER */
  88. /* > The number of columns of the matrix B. P >= N-M. */
  89. /* > \endverbatim */
  90. /* > */
  91. /* > \param[in,out] A */
  92. /* > \verbatim */
  93. /* > A is DOUBLE PRECISION array, dimension (LDA,M) */
  94. /* > On entry, the N-by-M matrix A. */
  95. /* > On exit, the upper triangular part of the array A contains */
  96. /* > the M-by-M upper triangular matrix R. */
  97. /* > \endverbatim */
  98. /* > */
  99. /* > \param[in] LDA */
  100. /* > \verbatim */
  101. /* > LDA is INTEGER */
  102. /* > The leading dimension of the array A. LDA >= max(1,N). */
  103. /* > \endverbatim */
  104. /* > */
  105. /* > \param[in,out] B */
  106. /* > \verbatim */
  107. /* > B is DOUBLE PRECISION array, dimension (LDB,P) */
  108. /* > On entry, the N-by-P matrix B. */
  109. /* > On exit, if N <= P, the upper triangle of the subarray */
  110. /* > B(1:N,P-N+1:P) contains the N-by-N upper triangular matrix T; */
  111. /* > if N > P, the elements on and above the (N-P)th subdiagonal */
  112. /* > contain the N-by-P upper trapezoidal matrix T. */
  113. /* > \endverbatim */
  114. /* > */
  115. /* > \param[in] LDB */
  116. /* > \verbatim */
  117. /* > LDB is INTEGER */
  118. /* > The leading dimension of the array B. LDB >= max(1,N). */
  119. /* > \endverbatim */
  120. /* > */
  121. /* > \param[in,out] D */
  122. /* > \verbatim */
  123. /* > D is DOUBLE PRECISION array, dimension (N) */
  124. /* > On entry, D is the left hand side of the GLM equation. */
  125. /* > On exit, D is destroyed. */
  126. /* > \endverbatim */
  127. /* > */
  128. /* > \param[out] X */
  129. /* > \verbatim */
  130. /* > X is DOUBLE PRECISION array, dimension (M) */
  131. /* > \endverbatim */
  132. /* > */
  133. /* > \param[out] Y */
  134. /* > \verbatim */
  135. /* > Y is DOUBLE PRECISION array, dimension (P) */
  136. /* > */
  137. /* > On exit, X and Y are the solutions of the GLM problem. */
  138. /* > \endverbatim */
  139. /* > */
  140. /* > \param[out] WORK */
  141. /* > \verbatim */
  142. /* > WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
  143. /* > On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
  144. /* > \endverbatim */
  145. /* > */
  146. /* > \param[in] LWORK */
  147. /* > \verbatim */
  148. /* > LWORK is INTEGER */
  149. /* > The dimension of the array WORK. LWORK >= max(1,N+M+P). */
  150. /* > For optimum performance, LWORK >= M+min(N,P)+max(N,P)*NB, */
  151. /* > where NB is an upper bound for the optimal blocksizes for */
  152. /* > DGEQRF, SGERQF, DORMQR and SORMRQ. */
  153. /* > */
  154. /* > If LWORK = -1, then a workspace query is assumed; the routine */
  155. /* > only calculates the optimal size of the WORK array, returns */
  156. /* > this value as the first entry of the WORK array, and no error */
  157. /* > message related to LWORK is issued by XERBLA. */
  158. /* > \endverbatim */
  159. /* > */
  160. /* > \param[out] INFO */
  161. /* > \verbatim */
  162. /* > INFO is INTEGER */
  163. /* > = 0: successful exit. */
  164. /* > < 0: if INFO = -i, the i-th argument had an illegal value. */
  165. /* > = 1: the upper triangular factor R associated with A in the */
  166. /* > generalized QR factorization of the pair (A, B) is */
  167. /* > singular, so that rank(A) < M; the least squares */
  168. /* > solution could not be computed. */
  169. /* > = 2: the bottom (N-M) by (N-M) part of the upper trapezoidal */
  170. /* > factor T associated with B in the generalized QR */
  171. /* > factorization of the pair (A, B) is singular, so that */
  172. /* > rank( A B ) < N; the least squares solution could not */
  173. /* > be computed. */
  174. /* > \endverbatim */
  175. /* Authors: */
  176. /* ======== */
  177. /* > \author Univ. of Tennessee */
  178. /* > \author Univ. of California Berkeley */
  179. /* > \author Univ. of Colorado Denver */
  180. /* > \author NAG Ltd. */
  181. /* > \date November 2011 */
  182. /* > \ingroup doubleOTHEReigen */
  183. /* ===================================================================== */
  184. /* Subroutine */ int dggglm_(n, m, p, a, lda, b, ldb, d__, x, y, work, lwork,
  185. info)
  186. integer *n, *m, *p;
  187. doublereal *a;
  188. integer *lda;
  189. doublereal *b;
  190. integer *ldb;
  191. doublereal *d__, *x, *y, *work;
  192. integer *lwork, *info;
  193. {
  194. /* System generated locals */
  195. integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3, i__4;
  196. /* Local variables */
  197. static integer lopt, i__;
  198. extern /* Subroutine */ int dgemv_(), dcopy_();
  199. static integer nb, np;
  200. extern /* Subroutine */ int dggqrf_(), xerbla_();
  201. extern integer ilaenv_();
  202. static integer lwkmin, nb1, nb2, nb3, nb4;
  203. extern /* Subroutine */ int dormqr_(), dormrq_();
  204. static integer lwkopt;
  205. static logical lquery;
  206. extern /* Subroutine */ int dtrtrs_();
  207. /* -- LAPACK driver routine (version 3.4.0) -- */
  208. /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */
  209. /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
  210. /* November 2011 */
  211. /* .. Scalar Arguments .. */
  212. /* .. */
  213. /* .. Array Arguments .. */
  214. /* .. */
  215. /* =================================================================== */
  216. /* .. Parameters .. */
  217. /* .. */
  218. /* .. Local Scalars .. */
  219. /* .. */
  220. /* .. External Subroutines .. */
  221. /* .. */
  222. /* .. External Functions .. */
  223. /* .. */
  224. /* .. Intrinsic Functions .. */
  225. /* .. */
  226. /* .. Executable Statements .. */
  227. /* Test the input parameters */
  228. /* Parameter adjustments */
  229. a_dim1 = *lda;
  230. a_offset = 1 + a_dim1 * 1;
  231. a -= a_offset;
  232. b_dim1 = *ldb;
  233. b_offset = 1 + b_dim1 * 1;
  234. b -= b_offset;
  235. --d__;
  236. --x;
  237. --y;
  238. --work;
  239. /* Function Body */
  240. *info = 0;
  241. np = min(*n,*p);
  242. lquery = *lwork == -1;
  243. if (*n < 0) {
  244. *info = -1;
  245. } else if (*m < 0 || *m > *n) {
  246. *info = -2;
  247. } else if (*p < 0 || *p < *n - *m) {
  248. *info = -3;
  249. } else if (*lda < max(1,*n)) {
  250. *info = -5;
  251. } else if (*ldb < max(1,*n)) {
  252. *info = -7;
  253. }
  254. /* Calculate workspace */
  255. if (*info == 0) {
  256. if (*n == 0) {
  257. lwkmin = 1;
  258. lwkopt = 1;
  259. } else {
  260. nb1 = ilaenv_(&c__1, "DGEQRF", " ", n, m, &c_n1, &c_n1, (ftnlen)6,
  261. (ftnlen)1);
  262. nb2 = ilaenv_(&c__1, "DGERQF", " ", n, m, &c_n1, &c_n1, (ftnlen)6,
  263. (ftnlen)1);
  264. nb3 = ilaenv_(&c__1, "DORMQR", " ", n, m, p, &c_n1, (ftnlen)6, (
  265. ftnlen)1);
  266. nb4 = ilaenv_(&c__1, "DORMRQ", " ", n, m, p, &c_n1, (ftnlen)6, (
  267. ftnlen)1);
  268. /* Computing MAX */
  269. i__1 = max(nb1,nb2), i__1 = max(i__1,nb3);
  270. nb = max(i__1,nb4);
  271. lwkmin = *m + *n + *p;
  272. lwkopt = *m + np + max(*n,*p) * nb;
  273. }
  274. work[1] = (doublereal) lwkopt;
  275. if (*lwork < lwkmin && ! lquery) {
  276. *info = -12;
  277. }
  278. }
  279. if (*info != 0) {
  280. i__1 = -(*info);
  281. xerbla_("DGGGLM", &i__1, (ftnlen)6);
  282. return 0;
  283. } else if (lquery) {
  284. return 0;
  285. }
  286. /* Quick return if possible */
  287. if (*n == 0) {
  288. return 0;
  289. }
  290. /* Compute the GQR factorization of matrices A and B: */
  291. /* Q**T*A = ( R11 ) M, Q**T*B*Z**T = ( T11 T12 ) M */
  292. /* ( 0 ) N-M ( 0 T22 ) N-M */
  293. /* M M+P-N N-M */
  294. /* where R11 and T22 are upper triangular, and Q and Z are */
  295. /* orthogonal. */
  296. i__1 = *lwork - *m - np;
  297. dggqrf_(n, m, p, &a[a_offset], lda, &work[1], &b[b_offset], ldb, &work[*m
  298. + 1], &work[*m + np + 1], &i__1, info);
  299. lopt = (integer) work[*m + np + 1];
  300. /* Update left-hand-side vector d = Q**T*d = ( d1 ) M */
  301. /* ( d2 ) N-M */
  302. i__1 = max(1,*n);
  303. i__2 = *lwork - *m - np;
  304. dormqr_("Left", "Transpose", n, &c__1, m, &a[a_offset], lda, &work[1], &
  305. d__[1], &i__1, &work[*m + np + 1], &i__2, info, (ftnlen)4, (
  306. ftnlen)9);
  307. /* Computing MAX */
  308. i__1 = lopt, i__2 = (integer) work[*m + np + 1];
  309. lopt = max(i__1,i__2);
  310. /* Solve T22*y2 = d2 for y2 */
  311. if (*n > *m) {
  312. i__1 = *n - *m;
  313. i__2 = *n - *m;
  314. dtrtrs_("Upper", "No transpose", "Non unit", &i__1, &c__1, &b[*m + 1
  315. + (*m + *p - *n + 1) * b_dim1], ldb, &d__[*m + 1], &i__2,
  316. info, (ftnlen)5, (ftnlen)12, (ftnlen)8);
  317. if (*info > 0) {
  318. *info = 1;
  319. return 0;
  320. }
  321. i__1 = *n - *m;
  322. dcopy_(&i__1, &d__[*m + 1], &c__1, &y[*m + *p - *n + 1], &c__1);
  323. }
  324. /* Set y1 = 0 */
  325. i__1 = *m + *p - *n;
  326. for (i__ = 1; i__ <= i__1; ++i__) {
  327. y[i__] = 0.;
  328. /* L10: */
  329. }
  330. /* Update d1 = d1 - T12*y2 */
  331. i__1 = *n - *m;
  332. dgemv_("No transpose", m, &i__1, &c_b32, &b[(*m + *p - *n + 1) * b_dim1 +
  333. 1], ldb, &y[*m + *p - *n + 1], &c__1, &c_b34, &d__[1], &c__1, (
  334. ftnlen)12);
  335. /* Solve triangular system: R11*x = d1 */
  336. if (*m > 0) {
  337. dtrtrs_("Upper", "No Transpose", "Non unit", m, &c__1, &a[a_offset],
  338. lda, &d__[1], m, info, (ftnlen)5, (ftnlen)12, (ftnlen)8);
  339. if (*info > 0) {
  340. *info = 2;
  341. return 0;
  342. }
  343. /* Copy D to X */
  344. dcopy_(m, &d__[1], &c__1, &x[1], &c__1);
  345. }
  346. /* Backward transformation y = Z**T *y */
  347. /* Computing MAX */
  348. i__1 = 1, i__2 = *n - *p + 1;
  349. i__3 = max(1,*p);
  350. i__4 = *lwork - *m - np;
  351. dormrq_("Left", "Transpose", p, &c__1, &np, &b[max(i__1,i__2) + b_dim1],
  352. ldb, &work[*m + 1], &y[1], &i__3, &work[*m + np + 1], &i__4, info,
  353. (ftnlen)4, (ftnlen)9);
  354. /* Computing MAX */
  355. i__1 = lopt, i__2 = (integer) work[*m + np + 1];
  356. work[1] = (doublereal) (*m + np + max(i__1,i__2));
  357. return 0;
  358. /* End of DGGGLM */
  359. } /* dggglm_ */