dggrqf.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /* dggrqf.f -- translated by f2c (version 20061008).
  2. You must link the resulting object file with libf2c:
  3. on Microsoft Windows system, link with libf2c.lib;
  4. on Linux or Unix systems, link with .../path/to/libf2c.a -lm
  5. or, if you install libf2c.a in a standard place, with -lf2c -lm
  6. -- in that order, at the end of the command line, as in
  7. cc *.o -lf2c -lm
  8. Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
  9. http://www.netlib.org/f2c/libf2c.zip
  10. */
  11. #include "f2c.h"
  12. #include "blaswrap.h"
  13. /* Table of constant values */
  14. static integer c__1 = 1;
  15. static integer c_n1 = -1;
  16. /* Subroutine */ int _starpu_dggrqf_(integer *m, integer *p, integer *n, doublereal *
  17. a, integer *lda, doublereal *taua, doublereal *b, integer *ldb,
  18. doublereal *taub, doublereal *work, integer *lwork, integer *info)
  19. {
  20. /* System generated locals */
  21. integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3;
  22. /* Local variables */
  23. integer nb, nb1, nb2, nb3, lopt;
  24. extern /* Subroutine */ int _starpu_dgeqrf_(integer *, integer *, doublereal *,
  25. integer *, doublereal *, doublereal *, integer *, integer *),
  26. _starpu_dgerqf_(integer *, integer *, doublereal *, integer *, doublereal
  27. *, doublereal *, integer *, integer *), _starpu_xerbla_(char *, integer *);
  28. extern integer _starpu_ilaenv_(integer *, char *, char *, integer *, integer *,
  29. integer *, integer *);
  30. extern /* Subroutine */ int _starpu_dormrq_(char *, char *, integer *, integer *,
  31. integer *, doublereal *, integer *, doublereal *, doublereal *,
  32. integer *, doublereal *, integer *, integer *);
  33. integer lwkopt;
  34. logical lquery;
  35. /* -- LAPACK routine (version 3.2) -- */
  36. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  37. /* November 2006 */
  38. /* .. Scalar Arguments .. */
  39. /* .. */
  40. /* .. Array Arguments .. */
  41. /* .. */
  42. /* Purpose */
  43. /* ======= */
  44. /* DGGRQF computes a generalized RQ factorization of an M-by-N matrix A */
  45. /* and a P-by-N matrix B: */
  46. /* A = R*Q, B = Z*T*Q, */
  47. /* where Q is an N-by-N orthogonal matrix, Z is a P-by-P orthogonal */
  48. /* matrix, and R and T assume one of the forms: */
  49. /* if M <= N, R = ( 0 R12 ) M, or if M > N, R = ( R11 ) M-N, */
  50. /* N-M M ( R21 ) N */
  51. /* N */
  52. /* where R12 or R21 is upper triangular, and */
  53. /* if P >= N, T = ( T11 ) N , or if P < N, T = ( T11 T12 ) P, */
  54. /* ( 0 ) P-N P N-P */
  55. /* N */
  56. /* where T11 is upper triangular. */
  57. /* In particular, if B is square and nonsingular, the GRQ factorization */
  58. /* of A and B implicitly gives the RQ factorization of A*inv(B): */
  59. /* A*inv(B) = (R*inv(T))*Z' */
  60. /* where inv(B) denotes the inverse of the matrix B, and Z' denotes the */
  61. /* transpose of the matrix Z. */
  62. /* Arguments */
  63. /* ========= */
  64. /* M (input) INTEGER */
  65. /* The number of rows of the matrix A. M >= 0. */
  66. /* P (input) INTEGER */
  67. /* The number of rows of the matrix B. P >= 0. */
  68. /* N (input) INTEGER */
  69. /* The number of columns of the matrices A and B. N >= 0. */
  70. /* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
  71. /* On entry, the M-by-N matrix A. */
  72. /* On exit, if M <= N, the upper triangle of the subarray */
  73. /* A(1:M,N-M+1:N) contains the M-by-M upper triangular matrix R; */
  74. /* if M > N, the elements on and above the (M-N)-th subdiagonal */
  75. /* contain the M-by-N upper trapezoidal matrix R; the remaining */
  76. /* elements, with the array TAUA, represent the orthogonal */
  77. /* matrix Q as a product of elementary reflectors (see Further */
  78. /* Details). */
  79. /* LDA (input) INTEGER */
  80. /* The leading dimension of the array A. LDA >= max(1,M). */
  81. /* TAUA (output) DOUBLE PRECISION array, dimension (min(M,N)) */
  82. /* The scalar factors of the elementary reflectors which */
  83. /* represent the orthogonal matrix Q (see Further Details). */
  84. /* B (input/output) DOUBLE PRECISION array, dimension (LDB,N) */
  85. /* On entry, the P-by-N matrix B. */
  86. /* On exit, the elements on and above the diagonal of the array */
  87. /* contain the min(P,N)-by-N upper trapezoidal matrix T (T is */
  88. /* upper triangular if P >= N); the elements below the diagonal, */
  89. /* with the array TAUB, represent the orthogonal matrix Z as a */
  90. /* product of elementary reflectors (see Further Details). */
  91. /* LDB (input) INTEGER */
  92. /* The leading dimension of the array B. LDB >= max(1,P). */
  93. /* TAUB (output) DOUBLE PRECISION array, dimension (min(P,N)) */
  94. /* The scalar factors of the elementary reflectors which */
  95. /* represent the orthogonal matrix Z (see Further Details). */
  96. /* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
  97. /* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
  98. /* LWORK (input) INTEGER */
  99. /* The dimension of the array WORK. LWORK >= max(1,N,M,P). */
  100. /* For optimum performance LWORK >= max(N,M,P)*max(NB1,NB2,NB3), */
  101. /* where NB1 is the optimal blocksize for the RQ factorization */
  102. /* of an M-by-N matrix, NB2 is the optimal blocksize for the */
  103. /* QR factorization of a P-by-N matrix, and NB3 is the optimal */
  104. /* blocksize for a call of DORMRQ. */
  105. /* If LWORK = -1, then a workspace query is assumed; the routine */
  106. /* only calculates the optimal size of the WORK array, returns */
  107. /* this value as the first entry of the WORK array, and no error */
  108. /* message related to LWORK is issued by XERBLA. */
  109. /* INFO (output) INTEGER */
  110. /* = 0: successful exit */
  111. /* < 0: if INF0= -i, the i-th argument had an illegal value. */
  112. /* Further Details */
  113. /* =============== */
  114. /* The matrix Q is represented as a product of elementary reflectors */
  115. /* Q = H(1) H(2) . . . H(k), where k = min(m,n). */
  116. /* Each H(i) has the form */
  117. /* H(i) = I - taua * v * v' */
  118. /* where taua is a real scalar, and v is a real vector with */
  119. /* v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit in */
  120. /* A(m-k+i,1:n-k+i-1), and taua in TAUA(i). */
  121. /* To form Q explicitly, use LAPACK subroutine DORGRQ. */
  122. /* To use Q to update another matrix, use LAPACK subroutine DORMRQ. */
  123. /* The matrix Z is represented as a product of elementary reflectors */
  124. /* Z = H(1) H(2) . . . H(k), where k = min(p,n). */
  125. /* Each H(i) has the form */
  126. /* H(i) = I - taub * v * v' */
  127. /* where taub is a real scalar, and v is a real vector with */
  128. /* v(1:i-1) = 0 and v(i) = 1; v(i+1:p) is stored on exit in B(i+1:p,i), */
  129. /* and taub in TAUB(i). */
  130. /* To form Z explicitly, use LAPACK subroutine DORGQR. */
  131. /* To use Z to update another matrix, use LAPACK subroutine DORMQR. */
  132. /* ===================================================================== */
  133. /* .. Local Scalars .. */
  134. /* .. */
  135. /* .. External Subroutines .. */
  136. /* .. */
  137. /* .. External Functions .. */
  138. /* .. */
  139. /* .. Intrinsic Functions .. */
  140. /* .. */
  141. /* .. Executable Statements .. */
  142. /* Test the input parameters */
  143. /* Parameter adjustments */
  144. a_dim1 = *lda;
  145. a_offset = 1 + a_dim1;
  146. a -= a_offset;
  147. --taua;
  148. b_dim1 = *ldb;
  149. b_offset = 1 + b_dim1;
  150. b -= b_offset;
  151. --taub;
  152. --work;
  153. /* Function Body */
  154. *info = 0;
  155. nb1 = _starpu_ilaenv_(&c__1, "DGERQF", " ", m, n, &c_n1, &c_n1);
  156. nb2 = _starpu_ilaenv_(&c__1, "DGEQRF", " ", p, n, &c_n1, &c_n1);
  157. nb3 = _starpu_ilaenv_(&c__1, "DORMRQ", " ", m, n, p, &c_n1);
  158. /* Computing MAX */
  159. i__1 = max(nb1,nb2);
  160. nb = max(i__1,nb3);
  161. /* Computing MAX */
  162. i__1 = max(*n,*m);
  163. lwkopt = max(i__1,*p) * nb;
  164. work[1] = (doublereal) lwkopt;
  165. lquery = *lwork == -1;
  166. if (*m < 0) {
  167. *info = -1;
  168. } else if (*p < 0) {
  169. *info = -2;
  170. } else if (*n < 0) {
  171. *info = -3;
  172. } else if (*lda < max(1,*m)) {
  173. *info = -5;
  174. } else if (*ldb < max(1,*p)) {
  175. *info = -8;
  176. } else /* if(complicated condition) */ {
  177. /* Computing MAX */
  178. i__1 = max(1,*m), i__1 = max(i__1,*p);
  179. if (*lwork < max(i__1,*n) && ! lquery) {
  180. *info = -11;
  181. }
  182. }
  183. if (*info != 0) {
  184. i__1 = -(*info);
  185. _starpu_xerbla_("DGGRQF", &i__1);
  186. return 0;
  187. } else if (lquery) {
  188. return 0;
  189. }
  190. /* RQ factorization of M-by-N matrix A: A = R*Q */
  191. _starpu_dgerqf_(m, n, &a[a_offset], lda, &taua[1], &work[1], lwork, info);
  192. lopt = (integer) work[1];
  193. /* Update B := B*Q' */
  194. i__1 = min(*m,*n);
  195. /* Computing MAX */
  196. i__2 = 1, i__3 = *m - *n + 1;
  197. _starpu_dormrq_("Right", "Transpose", p, n, &i__1, &a[max(i__2, i__3)+ a_dim1],
  198. lda, &taua[1], &b[b_offset], ldb, &work[1], lwork, info);
  199. /* Computing MAX */
  200. i__1 = lopt, i__2 = (integer) work[1];
  201. lopt = max(i__1,i__2);
  202. /* QR factorization of P-by-N matrix B: B = Z*T */
  203. _starpu_dgeqrf_(p, n, &b[b_offset], ldb, &taub[1], &work[1], lwork, info);
  204. /* Computing MAX */
  205. i__1 = lopt, i__2 = (integer) work[1];
  206. work[1] = (doublereal) max(i__1,i__2);
  207. return 0;
  208. /* End of DGGRQF */
  209. } /* _starpu_dggrqf_ */