You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

dlavsp.f 16 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. *> \brief \b DLAVSP
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. * Definition:
  9. * ===========
  10. *
  11. * SUBROUTINE DLAVSP( UPLO, TRANS, DIAG, N, NRHS, A, IPIV, B, LDB,
  12. * INFO )
  13. *
  14. * .. Scalar Arguments ..
  15. * CHARACTER DIAG, TRANS, UPLO
  16. * INTEGER INFO, LDB, N, NRHS
  17. * ..
  18. * .. Array Arguments ..
  19. * INTEGER IPIV( * )
  20. * DOUBLE PRECISION A( * ), B( LDB, * )
  21. * ..
  22. *
  23. *
  24. *> \par Purpose:
  25. * =============
  26. *>
  27. *> \verbatim
  28. *>
  29. *> DLAVSP performs one of the matrix-vector operations
  30. *> x := A*x or x := A'*x,
  31. *> where x is an N element vector and A is one of the factors
  32. *> from the block U*D*U' or L*D*L' factorization computed by DSPTRF.
  33. *>
  34. *> If TRANS = 'N', multiplies by U or U * D (or L or L * D)
  35. *> If TRANS = 'T', multiplies by U' or D * U' (or L' or D * L' )
  36. *> If TRANS = 'C', multiplies by U' or D * U' (or L' or D * L' )
  37. *> \endverbatim
  38. *
  39. * Arguments:
  40. * ==========
  41. *
  42. *> \param[in] UPLO
  43. *> \verbatim
  44. *> UPLO is CHARACTER*1
  45. *> Specifies whether the factor stored in A is upper or lower
  46. *> triangular.
  47. *> = 'U': Upper triangular
  48. *> = 'L': Lower triangular
  49. *> \endverbatim
  50. *>
  51. *> \param[in] TRANS
  52. *> \verbatim
  53. *> TRANS is CHARACTER*1
  54. *> Specifies the operation to be performed:
  55. *> = 'N': x := A*x
  56. *> = 'T': x := A'*x
  57. *> = 'C': x := A'*x
  58. *> \endverbatim
  59. *>
  60. *> \param[in] DIAG
  61. *> \verbatim
  62. *> DIAG is CHARACTER*1
  63. *> Specifies whether or not the diagonal blocks are unit
  64. *> matrices. If the diagonal blocks are assumed to be unit,
  65. *> then A = U or A = L, otherwise A = U*D or A = L*D.
  66. *> = 'U': Diagonal blocks are assumed to be unit matrices.
  67. *> = 'N': Diagonal blocks are assumed to be non-unit matrices.
  68. *> \endverbatim
  69. *>
  70. *> \param[in] N
  71. *> \verbatim
  72. *> N is INTEGER
  73. *> The number of rows and columns of the matrix A. N >= 0.
  74. *> \endverbatim
  75. *>
  76. *> \param[in] NRHS
  77. *> \verbatim
  78. *> NRHS is INTEGER
  79. *> The number of right hand sides, i.e., the number of vectors
  80. *> x to be multiplied by A. NRHS >= 0.
  81. *> \endverbatim
  82. *>
  83. *> \param[in] A
  84. *> \verbatim
  85. *> A is DOUBLE PRECISION array, dimension (N*(N+1)/2)
  86. *> The block diagonal matrix D and the multipliers used to
  87. *> obtain the factor U or L, stored as a packed triangular
  88. *> matrix as computed by DSPTRF.
  89. *> \endverbatim
  90. *>
  91. *> \param[in] IPIV
  92. *> \verbatim
  93. *> IPIV is INTEGER array, dimension (N)
  94. *> The pivot indices from DSPTRF.
  95. *> \endverbatim
  96. *>
  97. *> \param[in,out] B
  98. *> \verbatim
  99. *> B is DOUBLE PRECISION array, dimension (LDB,NRHS)
  100. *> On entry, B contains NRHS vectors of length N.
  101. *> On exit, B is overwritten with the product A * B.
  102. *> \endverbatim
  103. *>
  104. *> \param[in] LDB
  105. *> \verbatim
  106. *> LDB is INTEGER
  107. *> The leading dimension of the array B. LDB >= max(1,N).
  108. *> \endverbatim
  109. *>
  110. *> \param[out] INFO
  111. *> \verbatim
  112. *> INFO is INTEGER
  113. *> = 0: successful exit
  114. *> < 0: if INFO = -k, the k-th argument had an illegal value
  115. *> \endverbatim
  116. *
  117. * Authors:
  118. * ========
  119. *
  120. *> \author Univ. of Tennessee
  121. *> \author Univ. of California Berkeley
  122. *> \author Univ. of Colorado Denver
  123. *> \author NAG Ltd.
  124. *
  125. *> \ingroup double_lin
  126. *
  127. * =====================================================================
  128. SUBROUTINE DLAVSP( UPLO, TRANS, DIAG, N, NRHS, A, IPIV, B, LDB,
  129. $ INFO )
  130. *
  131. * -- LAPACK test routine --
  132. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  133. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  134. *
  135. * .. Scalar Arguments ..
  136. CHARACTER DIAG, TRANS, UPLO
  137. INTEGER INFO, LDB, N, NRHS
  138. * ..
  139. * .. Array Arguments ..
  140. INTEGER IPIV( * )
  141. DOUBLE PRECISION A( * ), B( LDB, * )
  142. * ..
  143. *
  144. * =====================================================================
  145. *
  146. * .. Parameters ..
  147. DOUBLE PRECISION ONE
  148. PARAMETER ( ONE = 1.0D+0 )
  149. * ..
  150. * .. Local Scalars ..
  151. LOGICAL NOUNIT
  152. INTEGER J, K, KC, KCNEXT, KP
  153. DOUBLE PRECISION D11, D12, D21, D22, T1, T2
  154. * ..
  155. * .. External Functions ..
  156. LOGICAL LSAME
  157. EXTERNAL LSAME
  158. * ..
  159. * .. External Subroutines ..
  160. EXTERNAL DGEMV, DGER, DSCAL, DSWAP, XERBLA
  161. * ..
  162. * .. Intrinsic Functions ..
  163. INTRINSIC ABS, MAX
  164. * ..
  165. * .. Executable Statements ..
  166. *
  167. * Test the input parameters.
  168. *
  169. INFO = 0
  170. IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
  171. INFO = -1
  172. ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. .NOT.
  173. $ LSAME( TRANS, 'T' ) .AND. .NOT.LSAME( TRANS, 'C' ) ) THEN
  174. INFO = -2
  175. ELSE IF( .NOT.LSAME( DIAG, 'U' ) .AND. .NOT.LSAME( DIAG, 'N' ) )
  176. $ THEN
  177. INFO = -3
  178. ELSE IF( N.LT.0 ) THEN
  179. INFO = -4
  180. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  181. INFO = -8
  182. END IF
  183. IF( INFO.NE.0 ) THEN
  184. CALL XERBLA( 'DLAVSP ', -INFO )
  185. RETURN
  186. END IF
  187. *
  188. * Quick return if possible.
  189. *
  190. IF( N.EQ.0 )
  191. $ RETURN
  192. *
  193. NOUNIT = LSAME( DIAG, 'N' )
  194. *------------------------------------------
  195. *
  196. * Compute B := A * B (No transpose)
  197. *
  198. *------------------------------------------
  199. IF( LSAME( TRANS, 'N' ) ) THEN
  200. *
  201. * Compute B := U*B
  202. * where U = P(m)*inv(U(m))* ... *P(1)*inv(U(1))
  203. *
  204. IF( LSAME( UPLO, 'U' ) ) THEN
  205. *
  206. * Loop forward applying the transformations.
  207. *
  208. K = 1
  209. KC = 1
  210. 10 CONTINUE
  211. IF( K.GT.N )
  212. $ GO TO 30
  213. *
  214. * 1 x 1 pivot block
  215. *
  216. IF( IPIV( K ).GT.0 ) THEN
  217. *
  218. * Multiply by the diagonal element if forming U * D.
  219. *
  220. IF( NOUNIT )
  221. $ CALL DSCAL( NRHS, A( KC+K-1 ), B( K, 1 ), LDB )
  222. *
  223. * Multiply by P(K) * inv(U(K)) if K > 1.
  224. *
  225. IF( K.GT.1 ) THEN
  226. *
  227. * Apply the transformation.
  228. *
  229. CALL DGER( K-1, NRHS, ONE, A( KC ), 1, B( K, 1 ), LDB,
  230. $ B( 1, 1 ), LDB )
  231. *
  232. * Interchange if P(K) != I.
  233. *
  234. KP = IPIV( K )
  235. IF( KP.NE.K )
  236. $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
  237. END IF
  238. KC = KC + K
  239. K = K + 1
  240. ELSE
  241. *
  242. * 2 x 2 pivot block
  243. *
  244. KCNEXT = KC + K
  245. *
  246. * Multiply by the diagonal block if forming U * D.
  247. *
  248. IF( NOUNIT ) THEN
  249. D11 = A( KCNEXT-1 )
  250. D22 = A( KCNEXT+K )
  251. D12 = A( KCNEXT+K-1 )
  252. D21 = D12
  253. DO 20 J = 1, NRHS
  254. T1 = B( K, J )
  255. T2 = B( K+1, J )
  256. B( K, J ) = D11*T1 + D12*T2
  257. B( K+1, J ) = D21*T1 + D22*T2
  258. 20 CONTINUE
  259. END IF
  260. *
  261. * Multiply by P(K) * inv(U(K)) if K > 1.
  262. *
  263. IF( K.GT.1 ) THEN
  264. *
  265. * Apply the transformations.
  266. *
  267. CALL DGER( K-1, NRHS, ONE, A( KC ), 1, B( K, 1 ), LDB,
  268. $ B( 1, 1 ), LDB )
  269. CALL DGER( K-1, NRHS, ONE, A( KCNEXT ), 1,
  270. $ B( K+1, 1 ), LDB, B( 1, 1 ), LDB )
  271. *
  272. * Interchange if P(K) != I.
  273. *
  274. KP = ABS( IPIV( K ) )
  275. IF( KP.NE.K )
  276. $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
  277. END IF
  278. KC = KCNEXT + K + 1
  279. K = K + 2
  280. END IF
  281. GO TO 10
  282. 30 CONTINUE
  283. *
  284. * Compute B := L*B
  285. * where L = P(1)*inv(L(1))* ... *P(m)*inv(L(m)) .
  286. *
  287. ELSE
  288. *
  289. * Loop backward applying the transformations to B.
  290. *
  291. K = N
  292. KC = N*( N+1 ) / 2 + 1
  293. 40 CONTINUE
  294. IF( K.LT.1 )
  295. $ GO TO 60
  296. KC = KC - ( N-K+1 )
  297. *
  298. * Test the pivot index. If greater than zero, a 1 x 1
  299. * pivot was used, otherwise a 2 x 2 pivot was used.
  300. *
  301. IF( IPIV( K ).GT.0 ) THEN
  302. *
  303. * 1 x 1 pivot block:
  304. *
  305. * Multiply by the diagonal element if forming L * D.
  306. *
  307. IF( NOUNIT )
  308. $ CALL DSCAL( NRHS, A( KC ), B( K, 1 ), LDB )
  309. *
  310. * Multiply by P(K) * inv(L(K)) if K < N.
  311. *
  312. IF( K.NE.N ) THEN
  313. KP = IPIV( K )
  314. *
  315. * Apply the transformation.
  316. *
  317. CALL DGER( N-K, NRHS, ONE, A( KC+1 ), 1, B( K, 1 ),
  318. $ LDB, B( K+1, 1 ), LDB )
  319. *
  320. * Interchange if a permutation was applied at the
  321. * K-th step of the factorization.
  322. *
  323. IF( KP.NE.K )
  324. $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
  325. END IF
  326. K = K - 1
  327. *
  328. ELSE
  329. *
  330. * 2 x 2 pivot block:
  331. *
  332. KCNEXT = KC - ( N-K+2 )
  333. *
  334. * Multiply by the diagonal block if forming L * D.
  335. *
  336. IF( NOUNIT ) THEN
  337. D11 = A( KCNEXT )
  338. D22 = A( KC )
  339. D21 = A( KCNEXT+1 )
  340. D12 = D21
  341. DO 50 J = 1, NRHS
  342. T1 = B( K-1, J )
  343. T2 = B( K, J )
  344. B( K-1, J ) = D11*T1 + D12*T2
  345. B( K, J ) = D21*T1 + D22*T2
  346. 50 CONTINUE
  347. END IF
  348. *
  349. * Multiply by P(K) * inv(L(K)) if K < N.
  350. *
  351. IF( K.NE.N ) THEN
  352. *
  353. * Apply the transformation.
  354. *
  355. CALL DGER( N-K, NRHS, ONE, A( KC+1 ), 1, B( K, 1 ),
  356. $ LDB, B( K+1, 1 ), LDB )
  357. CALL DGER( N-K, NRHS, ONE, A( KCNEXT+2 ), 1,
  358. $ B( K-1, 1 ), LDB, B( K+1, 1 ), LDB )
  359. *
  360. * Interchange if a permutation was applied at the
  361. * K-th step of the factorization.
  362. *
  363. KP = ABS( IPIV( K ) )
  364. IF( KP.NE.K )
  365. $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
  366. END IF
  367. KC = KCNEXT
  368. K = K - 2
  369. END IF
  370. GO TO 40
  371. 60 CONTINUE
  372. END IF
  373. *----------------------------------------
  374. *
  375. * Compute B := A' * B (transpose)
  376. *
  377. *----------------------------------------
  378. ELSE
  379. *
  380. * Form B := U'*B
  381. * where U = P(m)*inv(U(m))* ... *P(1)*inv(U(1))
  382. * and U' = inv(U'(1))*P(1)* ... *inv(U'(m))*P(m)
  383. *
  384. IF( LSAME( UPLO, 'U' ) ) THEN
  385. *
  386. * Loop backward applying the transformations.
  387. *
  388. K = N
  389. KC = N*( N+1 ) / 2 + 1
  390. 70 CONTINUE
  391. IF( K.LT.1 )
  392. $ GO TO 90
  393. KC = KC - K
  394. *
  395. * 1 x 1 pivot block.
  396. *
  397. IF( IPIV( K ).GT.0 ) THEN
  398. IF( K.GT.1 ) THEN
  399. *
  400. * Interchange if P(K) != I.
  401. *
  402. KP = IPIV( K )
  403. IF( KP.NE.K )
  404. $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
  405. *
  406. * Apply the transformation
  407. *
  408. CALL DGEMV( 'Transpose', K-1, NRHS, ONE, B, LDB,
  409. $ A( KC ), 1, ONE, B( K, 1 ), LDB )
  410. END IF
  411. IF( NOUNIT )
  412. $ CALL DSCAL( NRHS, A( KC+K-1 ), B( K, 1 ), LDB )
  413. K = K - 1
  414. *
  415. * 2 x 2 pivot block.
  416. *
  417. ELSE
  418. KCNEXT = KC - ( K-1 )
  419. IF( K.GT.2 ) THEN
  420. *
  421. * Interchange if P(K) != I.
  422. *
  423. KP = ABS( IPIV( K ) )
  424. IF( KP.NE.K-1 )
  425. $ CALL DSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ),
  426. $ LDB )
  427. *
  428. * Apply the transformations
  429. *
  430. CALL DGEMV( 'Transpose', K-2, NRHS, ONE, B, LDB,
  431. $ A( KC ), 1, ONE, B( K, 1 ), LDB )
  432. CALL DGEMV( 'Transpose', K-2, NRHS, ONE, B, LDB,
  433. $ A( KCNEXT ), 1, ONE, B( K-1, 1 ), LDB )
  434. END IF
  435. *
  436. * Multiply by the diagonal block if non-unit.
  437. *
  438. IF( NOUNIT ) THEN
  439. D11 = A( KC-1 )
  440. D22 = A( KC+K-1 )
  441. D12 = A( KC+K-2 )
  442. D21 = D12
  443. DO 80 J = 1, NRHS
  444. T1 = B( K-1, J )
  445. T2 = B( K, J )
  446. B( K-1, J ) = D11*T1 + D12*T2
  447. B( K, J ) = D21*T1 + D22*T2
  448. 80 CONTINUE
  449. END IF
  450. KC = KCNEXT
  451. K = K - 2
  452. END IF
  453. GO TO 70
  454. 90 CONTINUE
  455. *
  456. * Form B := L'*B
  457. * where L = P(1)*inv(L(1))* ... *P(m)*inv(L(m))
  458. * and L' = inv(L(m))*P(m)* ... *inv(L(1))*P(1)
  459. *
  460. ELSE
  461. *
  462. * Loop forward applying the L-transformations.
  463. *
  464. K = 1
  465. KC = 1
  466. 100 CONTINUE
  467. IF( K.GT.N )
  468. $ GO TO 120
  469. *
  470. * 1 x 1 pivot block
  471. *
  472. IF( IPIV( K ).GT.0 ) THEN
  473. IF( K.LT.N ) THEN
  474. *
  475. * Interchange if P(K) != I.
  476. *
  477. KP = IPIV( K )
  478. IF( KP.NE.K )
  479. $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
  480. *
  481. * Apply the transformation
  482. *
  483. CALL DGEMV( 'Transpose', N-K, NRHS, ONE, B( K+1, 1 ),
  484. $ LDB, A( KC+1 ), 1, ONE, B( K, 1 ), LDB )
  485. END IF
  486. IF( NOUNIT )
  487. $ CALL DSCAL( NRHS, A( KC ), B( K, 1 ), LDB )
  488. KC = KC + N - K + 1
  489. K = K + 1
  490. *
  491. * 2 x 2 pivot block.
  492. *
  493. ELSE
  494. KCNEXT = KC + N - K + 1
  495. IF( K.LT.N-1 ) THEN
  496. *
  497. * Interchange if P(K) != I.
  498. *
  499. KP = ABS( IPIV( K ) )
  500. IF( KP.NE.K+1 )
  501. $ CALL DSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ),
  502. $ LDB )
  503. *
  504. * Apply the transformation
  505. *
  506. CALL DGEMV( 'Transpose', N-K-1, NRHS, ONE,
  507. $ B( K+2, 1 ), LDB, A( KCNEXT+1 ), 1, ONE,
  508. $ B( K+1, 1 ), LDB )
  509. CALL DGEMV( 'Transpose', N-K-1, NRHS, ONE,
  510. $ B( K+2, 1 ), LDB, A( KC+2 ), 1, ONE,
  511. $ B( K, 1 ), LDB )
  512. END IF
  513. *
  514. * Multiply by the diagonal block if non-unit.
  515. *
  516. IF( NOUNIT ) THEN
  517. D11 = A( KC )
  518. D22 = A( KCNEXT )
  519. D21 = A( KC+1 )
  520. D12 = D21
  521. DO 110 J = 1, NRHS
  522. T1 = B( K, J )
  523. T2 = B( K+1, J )
  524. B( K, J ) = D11*T1 + D12*T2
  525. B( K+1, J ) = D21*T1 + D22*T2
  526. 110 CONTINUE
  527. END IF
  528. KC = KCNEXT + ( N-K )
  529. K = K + 2
  530. END IF
  531. GO TO 100
  532. 120 CONTINUE
  533. END IF
  534. *
  535. END IF
  536. RETURN
  537. *
  538. * End of DLAVSP
  539. *
  540. END