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.

stfsm.f 35 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. *> \brief \b STFSM solves a matrix equation (one operand is a triangular matrix in RFP format).
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. *> \htmlonly
  9. *> Download STFSM + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/stfsm.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/stfsm.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/stfsm.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE STFSM( TRANSR, SIDE, UPLO, TRANS, DIAG, M, N, ALPHA, A,
  22. * B, LDB )
  23. *
  24. * .. Scalar Arguments ..
  25. * CHARACTER TRANSR, DIAG, SIDE, TRANS, UPLO
  26. * INTEGER LDB, M, N
  27. * REAL ALPHA
  28. * ..
  29. * .. Array Arguments ..
  30. * REAL A( 0: * ), B( 0: LDB-1, 0: * )
  31. * ..
  32. *
  33. *
  34. *> \par Purpose:
  35. * =============
  36. *>
  37. *> \verbatim
  38. *>
  39. *> Level 3 BLAS like routine for A in RFP Format.
  40. *>
  41. *> STFSM solves the matrix equation
  42. *>
  43. *> op( A )*X = alpha*B or X*op( A ) = alpha*B
  44. *>
  45. *> where alpha is a scalar, X and B are m by n matrices, A is a unit, or
  46. *> non-unit, upper or lower triangular matrix and op( A ) is one of
  47. *>
  48. *> op( A ) = A or op( A ) = A**T.
  49. *>
  50. *> A is in Rectangular Full Packed (RFP) Format.
  51. *>
  52. *> The matrix X is overwritten on B.
  53. *> \endverbatim
  54. *
  55. * Arguments:
  56. * ==========
  57. *
  58. *> \param[in] TRANSR
  59. *> \verbatim
  60. *> TRANSR is CHARACTER*1
  61. *> = 'N': The Normal Form of RFP A is stored;
  62. *> = 'T': The Transpose Form of RFP A is stored.
  63. *> \endverbatim
  64. *>
  65. *> \param[in] SIDE
  66. *> \verbatim
  67. *> SIDE is CHARACTER*1
  68. *> On entry, SIDE specifies whether op( A ) appears on the left
  69. *> or right of X as follows:
  70. *>
  71. *> SIDE = 'L' or 'l' op( A )*X = alpha*B.
  72. *>
  73. *> SIDE = 'R' or 'r' X*op( A ) = alpha*B.
  74. *>
  75. *> Unchanged on exit.
  76. *> \endverbatim
  77. *>
  78. *> \param[in] UPLO
  79. *> \verbatim
  80. *> UPLO is CHARACTER*1
  81. *> On entry, UPLO specifies whether the RFP matrix A came from
  82. *> an upper or lower triangular matrix as follows:
  83. *> UPLO = 'U' or 'u' RFP A came from an upper triangular matrix
  84. *> UPLO = 'L' or 'l' RFP A came from a lower triangular matrix
  85. *>
  86. *> Unchanged on exit.
  87. *> \endverbatim
  88. *>
  89. *> \param[in] TRANS
  90. *> \verbatim
  91. *> TRANS is CHARACTER*1
  92. *> On entry, TRANS specifies the form of op( A ) to be used
  93. *> in the matrix multiplication as follows:
  94. *>
  95. *> TRANS = 'N' or 'n' op( A ) = A.
  96. *>
  97. *> TRANS = 'T' or 't' op( A ) = A'.
  98. *>
  99. *> Unchanged on exit.
  100. *> \endverbatim
  101. *>
  102. *> \param[in] DIAG
  103. *> \verbatim
  104. *> DIAG is CHARACTER*1
  105. *> On entry, DIAG specifies whether or not RFP A is unit
  106. *> triangular as follows:
  107. *>
  108. *> DIAG = 'U' or 'u' A is assumed to be unit triangular.
  109. *>
  110. *> DIAG = 'N' or 'n' A is not assumed to be unit
  111. *> triangular.
  112. *>
  113. *> Unchanged on exit.
  114. *> \endverbatim
  115. *>
  116. *> \param[in] M
  117. *> \verbatim
  118. *> M is INTEGER
  119. *> On entry, M specifies the number of rows of B. M must be at
  120. *> least zero.
  121. *> Unchanged on exit.
  122. *> \endverbatim
  123. *>
  124. *> \param[in] N
  125. *> \verbatim
  126. *> N is INTEGER
  127. *> On entry, N specifies the number of columns of B. N must be
  128. *> at least zero.
  129. *> Unchanged on exit.
  130. *> \endverbatim
  131. *>
  132. *> \param[in] ALPHA
  133. *> \verbatim
  134. *> ALPHA is REAL
  135. *> On entry, ALPHA specifies the scalar alpha. When alpha is
  136. *> zero then A is not referenced and B need not be set before
  137. *> entry.
  138. *> Unchanged on exit.
  139. *> \endverbatim
  140. *>
  141. *> \param[in] A
  142. *> \verbatim
  143. *> A is REAL array, dimension (NT)
  144. *> NT = N*(N+1)/2. On entry, the matrix A in RFP Format.
  145. *> RFP Format is described by TRANSR, UPLO and N as follows:
  146. *> If TRANSR='N' then RFP A is (0:N,0:K-1) when N is even;
  147. *> K=N/2. RFP A is (0:N-1,0:K) when N is odd; K=N/2. If
  148. *> TRANSR = 'T' then RFP is the transpose of RFP A as
  149. *> defined when TRANSR = 'N'. The contents of RFP A are defined
  150. *> by UPLO as follows: If UPLO = 'U' the RFP A contains the NT
  151. *> elements of upper packed A either in normal or
  152. *> transpose Format. If UPLO = 'L' the RFP A contains
  153. *> the NT elements of lower packed A either in normal or
  154. *> transpose Format. The LDA of RFP A is (N+1)/2 when
  155. *> TRANSR = 'T'. When TRANSR is 'N' the LDA is N+1 when N is
  156. *> even and is N when is odd.
  157. *> See the Note below for more details. Unchanged on exit.
  158. *> \endverbatim
  159. *>
  160. *> \param[in,out] B
  161. *> \verbatim
  162. *> B is REAL array, DIMENSION (LDB,N)
  163. *> Before entry, the leading m by n part of the array B must
  164. *> contain the right-hand side matrix B, and on exit is
  165. *> overwritten by the solution matrix X.
  166. *> \endverbatim
  167. *>
  168. *> \param[in] LDB
  169. *> \verbatim
  170. *> LDB is INTEGER
  171. *> On entry, LDB specifies the first dimension of B as declared
  172. *> in the calling (sub) program. LDB must be at least
  173. *> max( 1, m ).
  174. *> Unchanged on exit.
  175. *> \endverbatim
  176. *
  177. * Authors:
  178. * ========
  179. *
  180. *> \author Univ. of Tennessee
  181. *> \author Univ. of California Berkeley
  182. *> \author Univ. of Colorado Denver
  183. *> \author NAG Ltd.
  184. *
  185. *> \date September 2012
  186. *
  187. *> \ingroup realOTHERcomputational
  188. *
  189. *> \par Further Details:
  190. * =====================
  191. *>
  192. *> \verbatim
  193. *>
  194. *> We first consider Rectangular Full Packed (RFP) Format when N is
  195. *> even. We give an example where N = 6.
  196. *>
  197. *> AP is Upper AP is Lower
  198. *>
  199. *> 00 01 02 03 04 05 00
  200. *> 11 12 13 14 15 10 11
  201. *> 22 23 24 25 20 21 22
  202. *> 33 34 35 30 31 32 33
  203. *> 44 45 40 41 42 43 44
  204. *> 55 50 51 52 53 54 55
  205. *>
  206. *>
  207. *> Let TRANSR = 'N'. RFP holds AP as follows:
  208. *> For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last
  209. *> three columns of AP upper. The lower triangle A(4:6,0:2) consists of
  210. *> the transpose of the first three columns of AP upper.
  211. *> For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first
  212. *> three columns of AP lower. The upper triangle A(0:2,0:2) consists of
  213. *> the transpose of the last three columns of AP lower.
  214. *> This covers the case N even and TRANSR = 'N'.
  215. *>
  216. *> RFP A RFP A
  217. *>
  218. *> 03 04 05 33 43 53
  219. *> 13 14 15 00 44 54
  220. *> 23 24 25 10 11 55
  221. *> 33 34 35 20 21 22
  222. *> 00 44 45 30 31 32
  223. *> 01 11 55 40 41 42
  224. *> 02 12 22 50 51 52
  225. *>
  226. *> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the
  227. *> transpose of RFP A above. One therefore gets:
  228. *>
  229. *>
  230. *> RFP A RFP A
  231. *>
  232. *> 03 13 23 33 00 01 02 33 00 10 20 30 40 50
  233. *> 04 14 24 34 44 11 12 43 44 11 21 31 41 51
  234. *> 05 15 25 35 45 55 22 53 54 55 22 32 42 52
  235. *>
  236. *>
  237. *> We then consider Rectangular Full Packed (RFP) Format when N is
  238. *> odd. We give an example where N = 5.
  239. *>
  240. *> AP is Upper AP is Lower
  241. *>
  242. *> 00 01 02 03 04 00
  243. *> 11 12 13 14 10 11
  244. *> 22 23 24 20 21 22
  245. *> 33 34 30 31 32 33
  246. *> 44 40 41 42 43 44
  247. *>
  248. *>
  249. *> Let TRANSR = 'N'. RFP holds AP as follows:
  250. *> For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last
  251. *> three columns of AP upper. The lower triangle A(3:4,0:1) consists of
  252. *> the transpose of the first two columns of AP upper.
  253. *> For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first
  254. *> three columns of AP lower. The upper triangle A(0:1,1:2) consists of
  255. *> the transpose of the last two columns of AP lower.
  256. *> This covers the case N odd and TRANSR = 'N'.
  257. *>
  258. *> RFP A RFP A
  259. *>
  260. *> 02 03 04 00 33 43
  261. *> 12 13 14 10 11 44
  262. *> 22 23 24 20 21 22
  263. *> 00 33 34 30 31 32
  264. *> 01 11 44 40 41 42
  265. *>
  266. *> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the
  267. *> transpose of RFP A above. One therefore gets:
  268. *>
  269. *> RFP A RFP A
  270. *>
  271. *> 02 12 22 00 01 00 10 20 30 40 50
  272. *> 03 13 23 33 11 33 11 21 31 41 51
  273. *> 04 14 24 34 44 43 44 22 32 42 52
  274. *> \endverbatim
  275. *
  276. * =====================================================================
  277. SUBROUTINE STFSM( TRANSR, SIDE, UPLO, TRANS, DIAG, M, N, ALPHA, A,
  278. $ B, LDB )
  279. *
  280. * -- LAPACK computational routine (version 3.4.2) --
  281. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  282. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  283. * September 2012
  284. *
  285. * .. Scalar Arguments ..
  286. CHARACTER TRANSR, DIAG, SIDE, TRANS, UPLO
  287. INTEGER LDB, M, N
  288. REAL ALPHA
  289. * ..
  290. * .. Array Arguments ..
  291. REAL A( 0: * ), B( 0: LDB-1, 0: * )
  292. * ..
  293. *
  294. * =====================================================================
  295. *
  296. * ..
  297. * .. Parameters ..
  298. REAL ONE, ZERO
  299. PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )
  300. * ..
  301. * .. Local Scalars ..
  302. LOGICAL LOWER, LSIDE, MISODD, NISODD, NORMALTRANSR,
  303. $ NOTRANS
  304. INTEGER M1, M2, N1, N2, K, INFO, I, J
  305. * ..
  306. * .. External Functions ..
  307. LOGICAL LSAME
  308. EXTERNAL LSAME
  309. * ..
  310. * .. External Subroutines ..
  311. EXTERNAL SGEMM, STRSM, XERBLA
  312. * ..
  313. * .. Intrinsic Functions ..
  314. INTRINSIC MAX, MOD
  315. * ..
  316. * .. Executable Statements ..
  317. *
  318. * Test the input parameters.
  319. *
  320. INFO = 0
  321. NORMALTRANSR = LSAME( TRANSR, 'N' )
  322. LSIDE = LSAME( SIDE, 'L' )
  323. LOWER = LSAME( UPLO, 'L' )
  324. NOTRANS = LSAME( TRANS, 'N' )
  325. IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THEN
  326. INFO = -1
  327. ELSE IF( .NOT.LSIDE .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
  328. INFO = -2
  329. ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THEN
  330. INFO = -3
  331. ELSE IF( .NOT.NOTRANS .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
  332. INFO = -4
  333. ELSE IF( .NOT.LSAME( DIAG, 'N' ) .AND. .NOT.LSAME( DIAG, 'U' ) )
  334. $ THEN
  335. INFO = -5
  336. ELSE IF( M.LT.0 ) THEN
  337. INFO = -6
  338. ELSE IF( N.LT.0 ) THEN
  339. INFO = -7
  340. ELSE IF( LDB.LT.MAX( 1, M ) ) THEN
  341. INFO = -11
  342. END IF
  343. IF( INFO.NE.0 ) THEN
  344. CALL XERBLA( 'STFSM ', -INFO )
  345. RETURN
  346. END IF
  347. *
  348. * Quick return when ( (N.EQ.0).OR.(M.EQ.0) )
  349. *
  350. IF( ( M.EQ.0 ) .OR. ( N.EQ.0 ) )
  351. $ RETURN
  352. *
  353. * Quick return when ALPHA.EQ.(0D+0)
  354. *
  355. IF( ALPHA.EQ.ZERO ) THEN
  356. DO 20 J = 0, N - 1
  357. DO 10 I = 0, M - 1
  358. B( I, J ) = ZERO
  359. 10 CONTINUE
  360. 20 CONTINUE
  361. RETURN
  362. END IF
  363. *
  364. IF( LSIDE ) THEN
  365. *
  366. * SIDE = 'L'
  367. *
  368. * A is M-by-M.
  369. * If M is odd, set NISODD = .TRUE., and M1 and M2.
  370. * If M is even, NISODD = .FALSE., and M.
  371. *
  372. IF( MOD( M, 2 ).EQ.0 ) THEN
  373. MISODD = .FALSE.
  374. K = M / 2
  375. ELSE
  376. MISODD = .TRUE.
  377. IF( LOWER ) THEN
  378. M2 = M / 2
  379. M1 = M - M2
  380. ELSE
  381. M1 = M / 2
  382. M2 = M - M1
  383. END IF
  384. END IF
  385. *
  386. IF( MISODD ) THEN
  387. *
  388. * SIDE = 'L' and N is odd
  389. *
  390. IF( NORMALTRANSR ) THEN
  391. *
  392. * SIDE = 'L', N is odd, and TRANSR = 'N'
  393. *
  394. IF( LOWER ) THEN
  395. *
  396. * SIDE ='L', N is odd, TRANSR = 'N', and UPLO = 'L'
  397. *
  398. IF( NOTRANS ) THEN
  399. *
  400. * SIDE ='L', N is odd, TRANSR = 'N', UPLO = 'L', and
  401. * TRANS = 'N'
  402. *
  403. IF( M.EQ.1 ) THEN
  404. CALL STRSM( 'L', 'L', 'N', DIAG, M1, N, ALPHA,
  405. $ A, M, B, LDB )
  406. ELSE
  407. CALL STRSM( 'L', 'L', 'N', DIAG, M1, N, ALPHA,
  408. $ A( 0 ), M, B, LDB )
  409. CALL SGEMM( 'N', 'N', M2, N, M1, -ONE, A( M1 ),
  410. $ M, B, LDB, ALPHA, B( M1, 0 ), LDB )
  411. CALL STRSM( 'L', 'U', 'T', DIAG, M2, N, ONE,
  412. $ A( M ), M, B( M1, 0 ), LDB )
  413. END IF
  414. *
  415. ELSE
  416. *
  417. * SIDE ='L', N is odd, TRANSR = 'N', UPLO = 'L', and
  418. * TRANS = 'T'
  419. *
  420. IF( M.EQ.1 ) THEN
  421. CALL STRSM( 'L', 'L', 'T', DIAG, M1, N, ALPHA,
  422. $ A( 0 ), M, B, LDB )
  423. ELSE
  424. CALL STRSM( 'L', 'U', 'N', DIAG, M2, N, ALPHA,
  425. $ A( M ), M, B( M1, 0 ), LDB )
  426. CALL SGEMM( 'T', 'N', M1, N, M2, -ONE, A( M1 ),
  427. $ M, B( M1, 0 ), LDB, ALPHA, B, LDB )
  428. CALL STRSM( 'L', 'L', 'T', DIAG, M1, N, ONE,
  429. $ A( 0 ), M, B, LDB )
  430. END IF
  431. *
  432. END IF
  433. *
  434. ELSE
  435. *
  436. * SIDE ='L', N is odd, TRANSR = 'N', and UPLO = 'U'
  437. *
  438. IF( .NOT.NOTRANS ) THEN
  439. *
  440. * SIDE ='L', N is odd, TRANSR = 'N', UPLO = 'U', and
  441. * TRANS = 'N'
  442. *
  443. CALL STRSM( 'L', 'L', 'N', DIAG, M1, N, ALPHA,
  444. $ A( M2 ), M, B, LDB )
  445. CALL SGEMM( 'T', 'N', M2, N, M1, -ONE, A( 0 ), M,
  446. $ B, LDB, ALPHA, B( M1, 0 ), LDB )
  447. CALL STRSM( 'L', 'U', 'T', DIAG, M2, N, ONE,
  448. $ A( M1 ), M, B( M1, 0 ), LDB )
  449. *
  450. ELSE
  451. *
  452. * SIDE ='L', N is odd, TRANSR = 'N', UPLO = 'U', and
  453. * TRANS = 'T'
  454. *
  455. CALL STRSM( 'L', 'U', 'N', DIAG, M2, N, ALPHA,
  456. $ A( M1 ), M, B( M1, 0 ), LDB )
  457. CALL SGEMM( 'N', 'N', M1, N, M2, -ONE, A( 0 ), M,
  458. $ B( M1, 0 ), LDB, ALPHA, B, LDB )
  459. CALL STRSM( 'L', 'L', 'T', DIAG, M1, N, ONE,
  460. $ A( M2 ), M, B, LDB )
  461. *
  462. END IF
  463. *
  464. END IF
  465. *
  466. ELSE
  467. *
  468. * SIDE = 'L', N is odd, and TRANSR = 'T'
  469. *
  470. IF( LOWER ) THEN
  471. *
  472. * SIDE ='L', N is odd, TRANSR = 'T', and UPLO = 'L'
  473. *
  474. IF( NOTRANS ) THEN
  475. *
  476. * SIDE ='L', N is odd, TRANSR = 'T', UPLO = 'L', and
  477. * TRANS = 'N'
  478. *
  479. IF( M.EQ.1 ) THEN
  480. CALL STRSM( 'L', 'U', 'T', DIAG, M1, N, ALPHA,
  481. $ A( 0 ), M1, B, LDB )
  482. ELSE
  483. CALL STRSM( 'L', 'U', 'T', DIAG, M1, N, ALPHA,
  484. $ A( 0 ), M1, B, LDB )
  485. CALL SGEMM( 'T', 'N', M2, N, M1, -ONE,
  486. $ A( M1*M1 ), M1, B, LDB, ALPHA,
  487. $ B( M1, 0 ), LDB )
  488. CALL STRSM( 'L', 'L', 'N', DIAG, M2, N, ONE,
  489. $ A( 1 ), M1, B( M1, 0 ), LDB )
  490. END IF
  491. *
  492. ELSE
  493. *
  494. * SIDE ='L', N is odd, TRANSR = 'T', UPLO = 'L', and
  495. * TRANS = 'T'
  496. *
  497. IF( M.EQ.1 ) THEN
  498. CALL STRSM( 'L', 'U', 'N', DIAG, M1, N, ALPHA,
  499. $ A( 0 ), M1, B, LDB )
  500. ELSE
  501. CALL STRSM( 'L', 'L', 'T', DIAG, M2, N, ALPHA,
  502. $ A( 1 ), M1, B( M1, 0 ), LDB )
  503. CALL SGEMM( 'N', 'N', M1, N, M2, -ONE,
  504. $ A( M1*M1 ), M1, B( M1, 0 ), LDB,
  505. $ ALPHA, B, LDB )
  506. CALL STRSM( 'L', 'U', 'N', DIAG, M1, N, ONE,
  507. $ A( 0 ), M1, B, LDB )
  508. END IF
  509. *
  510. END IF
  511. *
  512. ELSE
  513. *
  514. * SIDE ='L', N is odd, TRANSR = 'T', and UPLO = 'U'
  515. *
  516. IF( .NOT.NOTRANS ) THEN
  517. *
  518. * SIDE ='L', N is odd, TRANSR = 'T', UPLO = 'U', and
  519. * TRANS = 'N'
  520. *
  521. CALL STRSM( 'L', 'U', 'T', DIAG, M1, N, ALPHA,
  522. $ A( M2*M2 ), M2, B, LDB )
  523. CALL SGEMM( 'N', 'N', M2, N, M1, -ONE, A( 0 ), M2,
  524. $ B, LDB, ALPHA, B( M1, 0 ), LDB )
  525. CALL STRSM( 'L', 'L', 'N', DIAG, M2, N, ONE,
  526. $ A( M1*M2 ), M2, B( M1, 0 ), LDB )
  527. *
  528. ELSE
  529. *
  530. * SIDE ='L', N is odd, TRANSR = 'T', UPLO = 'U', and
  531. * TRANS = 'T'
  532. *
  533. CALL STRSM( 'L', 'L', 'T', DIAG, M2, N, ALPHA,
  534. $ A( M1*M2 ), M2, B( M1, 0 ), LDB )
  535. CALL SGEMM( 'T', 'N', M1, N, M2, -ONE, A( 0 ), M2,
  536. $ B( M1, 0 ), LDB, ALPHA, B, LDB )
  537. CALL STRSM( 'L', 'U', 'N', DIAG, M1, N, ONE,
  538. $ A( M2*M2 ), M2, B, LDB )
  539. *
  540. END IF
  541. *
  542. END IF
  543. *
  544. END IF
  545. *
  546. ELSE
  547. *
  548. * SIDE = 'L' and N is even
  549. *
  550. IF( NORMALTRANSR ) THEN
  551. *
  552. * SIDE = 'L', N is even, and TRANSR = 'N'
  553. *
  554. IF( LOWER ) THEN
  555. *
  556. * SIDE ='L', N is even, TRANSR = 'N', and UPLO = 'L'
  557. *
  558. IF( NOTRANS ) THEN
  559. *
  560. * SIDE ='L', N is even, TRANSR = 'N', UPLO = 'L',
  561. * and TRANS = 'N'
  562. *
  563. CALL STRSM( 'L', 'L', 'N', DIAG, K, N, ALPHA,
  564. $ A( 1 ), M+1, B, LDB )
  565. CALL SGEMM( 'N', 'N', K, N, K, -ONE, A( K+1 ),
  566. $ M+1, B, LDB, ALPHA, B( K, 0 ), LDB )
  567. CALL STRSM( 'L', 'U', 'T', DIAG, K, N, ONE,
  568. $ A( 0 ), M+1, B( K, 0 ), LDB )
  569. *
  570. ELSE
  571. *
  572. * SIDE ='L', N is even, TRANSR = 'N', UPLO = 'L',
  573. * and TRANS = 'T'
  574. *
  575. CALL STRSM( 'L', 'U', 'N', DIAG, K, N, ALPHA,
  576. $ A( 0 ), M+1, B( K, 0 ), LDB )
  577. CALL SGEMM( 'T', 'N', K, N, K, -ONE, A( K+1 ),
  578. $ M+1, B( K, 0 ), LDB, ALPHA, B, LDB )
  579. CALL STRSM( 'L', 'L', 'T', DIAG, K, N, ONE,
  580. $ A( 1 ), M+1, B, LDB )
  581. *
  582. END IF
  583. *
  584. ELSE
  585. *
  586. * SIDE ='L', N is even, TRANSR = 'N', and UPLO = 'U'
  587. *
  588. IF( .NOT.NOTRANS ) THEN
  589. *
  590. * SIDE ='L', N is even, TRANSR = 'N', UPLO = 'U',
  591. * and TRANS = 'N'
  592. *
  593. CALL STRSM( 'L', 'L', 'N', DIAG, K, N, ALPHA,
  594. $ A( K+1 ), M+1, B, LDB )
  595. CALL SGEMM( 'T', 'N', K, N, K, -ONE, A( 0 ), M+1,
  596. $ B, LDB, ALPHA, B( K, 0 ), LDB )
  597. CALL STRSM( 'L', 'U', 'T', DIAG, K, N, ONE,
  598. $ A( K ), M+1, B( K, 0 ), LDB )
  599. *
  600. ELSE
  601. *
  602. * SIDE ='L', N is even, TRANSR = 'N', UPLO = 'U',
  603. * and TRANS = 'T'
  604. CALL STRSM( 'L', 'U', 'N', DIAG, K, N, ALPHA,
  605. $ A( K ), M+1, B( K, 0 ), LDB )
  606. CALL SGEMM( 'N', 'N', K, N, K, -ONE, A( 0 ), M+1,
  607. $ B( K, 0 ), LDB, ALPHA, B, LDB )
  608. CALL STRSM( 'L', 'L', 'T', DIAG, K, N, ONE,
  609. $ A( K+1 ), M+1, B, LDB )
  610. *
  611. END IF
  612. *
  613. END IF
  614. *
  615. ELSE
  616. *
  617. * SIDE = 'L', N is even, and TRANSR = 'T'
  618. *
  619. IF( LOWER ) THEN
  620. *
  621. * SIDE ='L', N is even, TRANSR = 'T', and UPLO = 'L'
  622. *
  623. IF( NOTRANS ) THEN
  624. *
  625. * SIDE ='L', N is even, TRANSR = 'T', UPLO = 'L',
  626. * and TRANS = 'N'
  627. *
  628. CALL STRSM( 'L', 'U', 'T', DIAG, K, N, ALPHA,
  629. $ A( K ), K, B, LDB )
  630. CALL SGEMM( 'T', 'N', K, N, K, -ONE,
  631. $ A( K*( K+1 ) ), K, B, LDB, ALPHA,
  632. $ B( K, 0 ), LDB )
  633. CALL STRSM( 'L', 'L', 'N', DIAG, K, N, ONE,
  634. $ A( 0 ), K, B( K, 0 ), LDB )
  635. *
  636. ELSE
  637. *
  638. * SIDE ='L', N is even, TRANSR = 'T', UPLO = 'L',
  639. * and TRANS = 'T'
  640. *
  641. CALL STRSM( 'L', 'L', 'T', DIAG, K, N, ALPHA,
  642. $ A( 0 ), K, B( K, 0 ), LDB )
  643. CALL SGEMM( 'N', 'N', K, N, K, -ONE,
  644. $ A( K*( K+1 ) ), K, B( K, 0 ), LDB,
  645. $ ALPHA, B, LDB )
  646. CALL STRSM( 'L', 'U', 'N', DIAG, K, N, ONE,
  647. $ A( K ), K, B, LDB )
  648. *
  649. END IF
  650. *
  651. ELSE
  652. *
  653. * SIDE ='L', N is even, TRANSR = 'T', and UPLO = 'U'
  654. *
  655. IF( .NOT.NOTRANS ) THEN
  656. *
  657. * SIDE ='L', N is even, TRANSR = 'T', UPLO = 'U',
  658. * and TRANS = 'N'
  659. *
  660. CALL STRSM( 'L', 'U', 'T', DIAG, K, N, ALPHA,
  661. $ A( K*( K+1 ) ), K, B, LDB )
  662. CALL SGEMM( 'N', 'N', K, N, K, -ONE, A( 0 ), K, B,
  663. $ LDB, ALPHA, B( K, 0 ), LDB )
  664. CALL STRSM( 'L', 'L', 'N', DIAG, K, N, ONE,
  665. $ A( K*K ), K, B( K, 0 ), LDB )
  666. *
  667. ELSE
  668. *
  669. * SIDE ='L', N is even, TRANSR = 'T', UPLO = 'U',
  670. * and TRANS = 'T'
  671. *
  672. CALL STRSM( 'L', 'L', 'T', DIAG, K, N, ALPHA,
  673. $ A( K*K ), K, B( K, 0 ), LDB )
  674. CALL SGEMM( 'T', 'N', K, N, K, -ONE, A( 0 ), K,
  675. $ B( K, 0 ), LDB, ALPHA, B, LDB )
  676. CALL STRSM( 'L', 'U', 'N', DIAG, K, N, ONE,
  677. $ A( K*( K+1 ) ), K, B, LDB )
  678. *
  679. END IF
  680. *
  681. END IF
  682. *
  683. END IF
  684. *
  685. END IF
  686. *
  687. ELSE
  688. *
  689. * SIDE = 'R'
  690. *
  691. * A is N-by-N.
  692. * If N is odd, set NISODD = .TRUE., and N1 and N2.
  693. * If N is even, NISODD = .FALSE., and K.
  694. *
  695. IF( MOD( N, 2 ).EQ.0 ) THEN
  696. NISODD = .FALSE.
  697. K = N / 2
  698. ELSE
  699. NISODD = .TRUE.
  700. IF( LOWER ) THEN
  701. N2 = N / 2
  702. N1 = N - N2
  703. ELSE
  704. N1 = N / 2
  705. N2 = N - N1
  706. END IF
  707. END IF
  708. *
  709. IF( NISODD ) THEN
  710. *
  711. * SIDE = 'R' and N is odd
  712. *
  713. IF( NORMALTRANSR ) THEN
  714. *
  715. * SIDE = 'R', N is odd, and TRANSR = 'N'
  716. *
  717. IF( LOWER ) THEN
  718. *
  719. * SIDE ='R', N is odd, TRANSR = 'N', and UPLO = 'L'
  720. *
  721. IF( NOTRANS ) THEN
  722. *
  723. * SIDE ='R', N is odd, TRANSR = 'N', UPLO = 'L', and
  724. * TRANS = 'N'
  725. *
  726. CALL STRSM( 'R', 'U', 'T', DIAG, M, N2, ALPHA,
  727. $ A( N ), N, B( 0, N1 ), LDB )
  728. CALL SGEMM( 'N', 'N', M, N1, N2, -ONE, B( 0, N1 ),
  729. $ LDB, A( N1 ), N, ALPHA, B( 0, 0 ),
  730. $ LDB )
  731. CALL STRSM( 'R', 'L', 'N', DIAG, M, N1, ONE,
  732. $ A( 0 ), N, B( 0, 0 ), LDB )
  733. *
  734. ELSE
  735. *
  736. * SIDE ='R', N is odd, TRANSR = 'N', UPLO = 'L', and
  737. * TRANS = 'T'
  738. *
  739. CALL STRSM( 'R', 'L', 'T', DIAG, M, N1, ALPHA,
  740. $ A( 0 ), N, B( 0, 0 ), LDB )
  741. CALL SGEMM( 'N', 'T', M, N2, N1, -ONE, B( 0, 0 ),
  742. $ LDB, A( N1 ), N, ALPHA, B( 0, N1 ),
  743. $ LDB )
  744. CALL STRSM( 'R', 'U', 'N', DIAG, M, N2, ONE,
  745. $ A( N ), N, B( 0, N1 ), LDB )
  746. *
  747. END IF
  748. *
  749. ELSE
  750. *
  751. * SIDE ='R', N is odd, TRANSR = 'N', and UPLO = 'U'
  752. *
  753. IF( NOTRANS ) THEN
  754. *
  755. * SIDE ='R', N is odd, TRANSR = 'N', UPLO = 'U', and
  756. * TRANS = 'N'
  757. *
  758. CALL STRSM( 'R', 'L', 'T', DIAG, M, N1, ALPHA,
  759. $ A( N2 ), N, B( 0, 0 ), LDB )
  760. CALL SGEMM( 'N', 'N', M, N2, N1, -ONE, B( 0, 0 ),
  761. $ LDB, A( 0 ), N, ALPHA, B( 0, N1 ),
  762. $ LDB )
  763. CALL STRSM( 'R', 'U', 'N', DIAG, M, N2, ONE,
  764. $ A( N1 ), N, B( 0, N1 ), LDB )
  765. *
  766. ELSE
  767. *
  768. * SIDE ='R', N is odd, TRANSR = 'N', UPLO = 'U', and
  769. * TRANS = 'T'
  770. *
  771. CALL STRSM( 'R', 'U', 'T', DIAG, M, N2, ALPHA,
  772. $ A( N1 ), N, B( 0, N1 ), LDB )
  773. CALL SGEMM( 'N', 'T', M, N1, N2, -ONE, B( 0, N1 ),
  774. $ LDB, A( 0 ), N, ALPHA, B( 0, 0 ), LDB )
  775. CALL STRSM( 'R', 'L', 'N', DIAG, M, N1, ONE,
  776. $ A( N2 ), N, B( 0, 0 ), LDB )
  777. *
  778. END IF
  779. *
  780. END IF
  781. *
  782. ELSE
  783. *
  784. * SIDE = 'R', N is odd, and TRANSR = 'T'
  785. *
  786. IF( LOWER ) THEN
  787. *
  788. * SIDE ='R', N is odd, TRANSR = 'T', and UPLO = 'L'
  789. *
  790. IF( NOTRANS ) THEN
  791. *
  792. * SIDE ='R', N is odd, TRANSR = 'T', UPLO = 'L', and
  793. * TRANS = 'N'
  794. *
  795. CALL STRSM( 'R', 'L', 'N', DIAG, M, N2, ALPHA,
  796. $ A( 1 ), N1, B( 0, N1 ), LDB )
  797. CALL SGEMM( 'N', 'T', M, N1, N2, -ONE, B( 0, N1 ),
  798. $ LDB, A( N1*N1 ), N1, ALPHA, B( 0, 0 ),
  799. $ LDB )
  800. CALL STRSM( 'R', 'U', 'T', DIAG, M, N1, ONE,
  801. $ A( 0 ), N1, B( 0, 0 ), LDB )
  802. *
  803. ELSE
  804. *
  805. * SIDE ='R', N is odd, TRANSR = 'T', UPLO = 'L', and
  806. * TRANS = 'T'
  807. *
  808. CALL STRSM( 'R', 'U', 'N', DIAG, M, N1, ALPHA,
  809. $ A( 0 ), N1, B( 0, 0 ), LDB )
  810. CALL SGEMM( 'N', 'N', M, N2, N1, -ONE, B( 0, 0 ),
  811. $ LDB, A( N1*N1 ), N1, ALPHA, B( 0, N1 ),
  812. $ LDB )
  813. CALL STRSM( 'R', 'L', 'T', DIAG, M, N2, ONE,
  814. $ A( 1 ), N1, B( 0, N1 ), LDB )
  815. *
  816. END IF
  817. *
  818. ELSE
  819. *
  820. * SIDE ='R', N is odd, TRANSR = 'T', and UPLO = 'U'
  821. *
  822. IF( NOTRANS ) THEN
  823. *
  824. * SIDE ='R', N is odd, TRANSR = 'T', UPLO = 'U', and
  825. * TRANS = 'N'
  826. *
  827. CALL STRSM( 'R', 'U', 'N', DIAG, M, N1, ALPHA,
  828. $ A( N2*N2 ), N2, B( 0, 0 ), LDB )
  829. CALL SGEMM( 'N', 'T', M, N2, N1, -ONE, B( 0, 0 ),
  830. $ LDB, A( 0 ), N2, ALPHA, B( 0, N1 ),
  831. $ LDB )
  832. CALL STRSM( 'R', 'L', 'T', DIAG, M, N2, ONE,
  833. $ A( N1*N2 ), N2, B( 0, N1 ), LDB )
  834. *
  835. ELSE
  836. *
  837. * SIDE ='R', N is odd, TRANSR = 'T', UPLO = 'U', and
  838. * TRANS = 'T'
  839. *
  840. CALL STRSM( 'R', 'L', 'N', DIAG, M, N2, ALPHA,
  841. $ A( N1*N2 ), N2, B( 0, N1 ), LDB )
  842. CALL SGEMM( 'N', 'N', M, N1, N2, -ONE, B( 0, N1 ),
  843. $ LDB, A( 0 ), N2, ALPHA, B( 0, 0 ),
  844. $ LDB )
  845. CALL STRSM( 'R', 'U', 'T', DIAG, M, N1, ONE,
  846. $ A( N2*N2 ), N2, B( 0, 0 ), LDB )
  847. *
  848. END IF
  849. *
  850. END IF
  851. *
  852. END IF
  853. *
  854. ELSE
  855. *
  856. * SIDE = 'R' and N is even
  857. *
  858. IF( NORMALTRANSR ) THEN
  859. *
  860. * SIDE = 'R', N is even, and TRANSR = 'N'
  861. *
  862. IF( LOWER ) THEN
  863. *
  864. * SIDE ='R', N is even, TRANSR = 'N', and UPLO = 'L'
  865. *
  866. IF( NOTRANS ) THEN
  867. *
  868. * SIDE ='R', N is even, TRANSR = 'N', UPLO = 'L',
  869. * and TRANS = 'N'
  870. *
  871. CALL STRSM( 'R', 'U', 'T', DIAG, M, K, ALPHA,
  872. $ A( 0 ), N+1, B( 0, K ), LDB )
  873. CALL SGEMM( 'N', 'N', M, K, K, -ONE, B( 0, K ),
  874. $ LDB, A( K+1 ), N+1, ALPHA, B( 0, 0 ),
  875. $ LDB )
  876. CALL STRSM( 'R', 'L', 'N', DIAG, M, K, ONE,
  877. $ A( 1 ), N+1, B( 0, 0 ), LDB )
  878. *
  879. ELSE
  880. *
  881. * SIDE ='R', N is even, TRANSR = 'N', UPLO = 'L',
  882. * and TRANS = 'T'
  883. *
  884. CALL STRSM( 'R', 'L', 'T', DIAG, M, K, ALPHA,
  885. $ A( 1 ), N+1, B( 0, 0 ), LDB )
  886. CALL SGEMM( 'N', 'T', M, K, K, -ONE, B( 0, 0 ),
  887. $ LDB, A( K+1 ), N+1, ALPHA, B( 0, K ),
  888. $ LDB )
  889. CALL STRSM( 'R', 'U', 'N', DIAG, M, K, ONE,
  890. $ A( 0 ), N+1, B( 0, K ), LDB )
  891. *
  892. END IF
  893. *
  894. ELSE
  895. *
  896. * SIDE ='R', N is even, TRANSR = 'N', and UPLO = 'U'
  897. *
  898. IF( NOTRANS ) THEN
  899. *
  900. * SIDE ='R', N is even, TRANSR = 'N', UPLO = 'U',
  901. * and TRANS = 'N'
  902. *
  903. CALL STRSM( 'R', 'L', 'T', DIAG, M, K, ALPHA,
  904. $ A( K+1 ), N+1, B( 0, 0 ), LDB )
  905. CALL SGEMM( 'N', 'N', M, K, K, -ONE, B( 0, 0 ),
  906. $ LDB, A( 0 ), N+1, ALPHA, B( 0, K ),
  907. $ LDB )
  908. CALL STRSM( 'R', 'U', 'N', DIAG, M, K, ONE,
  909. $ A( K ), N+1, B( 0, K ), LDB )
  910. *
  911. ELSE
  912. *
  913. * SIDE ='R', N is even, TRANSR = 'N', UPLO = 'U',
  914. * and TRANS = 'T'
  915. *
  916. CALL STRSM( 'R', 'U', 'T', DIAG, M, K, ALPHA,
  917. $ A( K ), N+1, B( 0, K ), LDB )
  918. CALL SGEMM( 'N', 'T', M, K, K, -ONE, B( 0, K ),
  919. $ LDB, A( 0 ), N+1, ALPHA, B( 0, 0 ),
  920. $ LDB )
  921. CALL STRSM( 'R', 'L', 'N', DIAG, M, K, ONE,
  922. $ A( K+1 ), N+1, B( 0, 0 ), LDB )
  923. *
  924. END IF
  925. *
  926. END IF
  927. *
  928. ELSE
  929. *
  930. * SIDE = 'R', N is even, and TRANSR = 'T'
  931. *
  932. IF( LOWER ) THEN
  933. *
  934. * SIDE ='R', N is even, TRANSR = 'T', and UPLO = 'L'
  935. *
  936. IF( NOTRANS ) THEN
  937. *
  938. * SIDE ='R', N is even, TRANSR = 'T', UPLO = 'L',
  939. * and TRANS = 'N'
  940. *
  941. CALL STRSM( 'R', 'L', 'N', DIAG, M, K, ALPHA,
  942. $ A( 0 ), K, B( 0, K ), LDB )
  943. CALL SGEMM( 'N', 'T', M, K, K, -ONE, B( 0, K ),
  944. $ LDB, A( ( K+1 )*K ), K, ALPHA,
  945. $ B( 0, 0 ), LDB )
  946. CALL STRSM( 'R', 'U', 'T', DIAG, M, K, ONE,
  947. $ A( K ), K, B( 0, 0 ), LDB )
  948. *
  949. ELSE
  950. *
  951. * SIDE ='R', N is even, TRANSR = 'T', UPLO = 'L',
  952. * and TRANS = 'T'
  953. *
  954. CALL STRSM( 'R', 'U', 'N', DIAG, M, K, ALPHA,
  955. $ A( K ), K, B( 0, 0 ), LDB )
  956. CALL SGEMM( 'N', 'N', M, K, K, -ONE, B( 0, 0 ),
  957. $ LDB, A( ( K+1 )*K ), K, ALPHA,
  958. $ B( 0, K ), LDB )
  959. CALL STRSM( 'R', 'L', 'T', DIAG, M, K, ONE,
  960. $ A( 0 ), K, B( 0, K ), LDB )
  961. *
  962. END IF
  963. *
  964. ELSE
  965. *
  966. * SIDE ='R', N is even, TRANSR = 'T', and UPLO = 'U'
  967. *
  968. IF( NOTRANS ) THEN
  969. *
  970. * SIDE ='R', N is even, TRANSR = 'T', UPLO = 'U',
  971. * and TRANS = 'N'
  972. *
  973. CALL STRSM( 'R', 'U', 'N', DIAG, M, K, ALPHA,
  974. $ A( ( K+1 )*K ), K, B( 0, 0 ), LDB )
  975. CALL SGEMM( 'N', 'T', M, K, K, -ONE, B( 0, 0 ),
  976. $ LDB, A( 0 ), K, ALPHA, B( 0, K ), LDB )
  977. CALL STRSM( 'R', 'L', 'T', DIAG, M, K, ONE,
  978. $ A( K*K ), K, B( 0, K ), LDB )
  979. *
  980. ELSE
  981. *
  982. * SIDE ='R', N is even, TRANSR = 'T', UPLO = 'U',
  983. * and TRANS = 'T'
  984. *
  985. CALL STRSM( 'R', 'L', 'N', DIAG, M, K, ALPHA,
  986. $ A( K*K ), K, B( 0, K ), LDB )
  987. CALL SGEMM( 'N', 'N', M, K, K, -ONE, B( 0, K ),
  988. $ LDB, A( 0 ), K, ALPHA, B( 0, 0 ), LDB )
  989. CALL STRSM( 'R', 'U', 'T', DIAG, M, K, ONE,
  990. $ A( ( K+1 )*K ), K, B( 0, 0 ), LDB )
  991. *
  992. END IF
  993. *
  994. END IF
  995. *
  996. END IF
  997. *
  998. END IF
  999. END IF
  1000. *
  1001. RETURN
  1002. *
  1003. * End of STFSM
  1004. *
  1005. END