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.

dlaqtr.f 24 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. *> \brief \b DLAQTR solves a real quasi-triangular system of equations, or a complex quasi-triangular system of special form, in real arithmetic.
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. *> \htmlonly
  9. *> Download DLAQTR + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqtr.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqtr.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqtr.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE DLAQTR( LTRAN, LREAL, N, T, LDT, B, W, SCALE, X, WORK,
  22. * INFO )
  23. *
  24. * .. Scalar Arguments ..
  25. * LOGICAL LREAL, LTRAN
  26. * INTEGER INFO, LDT, N
  27. * DOUBLE PRECISION SCALE, W
  28. * ..
  29. * .. Array Arguments ..
  30. * DOUBLE PRECISION B( * ), T( LDT, * ), WORK( * ), X( * )
  31. * ..
  32. *
  33. *
  34. *> \par Purpose:
  35. * =============
  36. *>
  37. *> \verbatim
  38. *>
  39. *> DLAQTR solves the real quasi-triangular system
  40. *>
  41. *> op(T)*p = scale*c, if LREAL = .TRUE.
  42. *>
  43. *> or the complex quasi-triangular systems
  44. *>
  45. *> op(T + iB)*(p+iq) = scale*(c+id), if LREAL = .FALSE.
  46. *>
  47. *> in real arithmetic, where T is upper quasi-triangular.
  48. *> If LREAL = .FALSE., then the first diagonal block of T must be
  49. *> 1 by 1, B is the specially structured matrix
  50. *>
  51. *> B = [ b(1) b(2) ... b(n) ]
  52. *> [ w ]
  53. *> [ w ]
  54. *> [ . ]
  55. *> [ w ]
  56. *>
  57. *> op(A) = A or A**T, A**T denotes the transpose of
  58. *> matrix A.
  59. *>
  60. *> On input, X = [ c ]. On output, X = [ p ].
  61. *> [ d ] [ q ]
  62. *>
  63. *> This subroutine is designed for the condition number estimation
  64. *> in routine DTRSNA.
  65. *> \endverbatim
  66. *
  67. * Arguments:
  68. * ==========
  69. *
  70. *> \param[in] LTRAN
  71. *> \verbatim
  72. *> LTRAN is LOGICAL
  73. *> On entry, LTRAN specifies the option of conjugate transpose:
  74. *> = .FALSE., op(T+i*B) = T+i*B,
  75. *> = .TRUE., op(T+i*B) = (T+i*B)**T.
  76. *> \endverbatim
  77. *>
  78. *> \param[in] LREAL
  79. *> \verbatim
  80. *> LREAL is LOGICAL
  81. *> On entry, LREAL specifies the input matrix structure:
  82. *> = .FALSE., the input is complex
  83. *> = .TRUE., the input is real
  84. *> \endverbatim
  85. *>
  86. *> \param[in] N
  87. *> \verbatim
  88. *> N is INTEGER
  89. *> On entry, N specifies the order of T+i*B. N >= 0.
  90. *> \endverbatim
  91. *>
  92. *> \param[in] T
  93. *> \verbatim
  94. *> T is DOUBLE PRECISION array, dimension (LDT,N)
  95. *> On entry, T contains a matrix in Schur canonical form.
  96. *> If LREAL = .FALSE., then the first diagonal block of T mu
  97. *> be 1 by 1.
  98. *> \endverbatim
  99. *>
  100. *> \param[in] LDT
  101. *> \verbatim
  102. *> LDT is INTEGER
  103. *> The leading dimension of the matrix T. LDT >= max(1,N).
  104. *> \endverbatim
  105. *>
  106. *> \param[in] B
  107. *> \verbatim
  108. *> B is DOUBLE PRECISION array, dimension (N)
  109. *> On entry, B contains the elements to form the matrix
  110. *> B as described above.
  111. *> If LREAL = .TRUE., B is not referenced.
  112. *> \endverbatim
  113. *>
  114. *> \param[in] W
  115. *> \verbatim
  116. *> W is DOUBLE PRECISION
  117. *> On entry, W is the diagonal element of the matrix B.
  118. *> If LREAL = .TRUE., W is not referenced.
  119. *> \endverbatim
  120. *>
  121. *> \param[out] SCALE
  122. *> \verbatim
  123. *> SCALE is DOUBLE PRECISION
  124. *> On exit, SCALE is the scale factor.
  125. *> \endverbatim
  126. *>
  127. *> \param[in,out] X
  128. *> \verbatim
  129. *> X is DOUBLE PRECISION array, dimension (2*N)
  130. *> On entry, X contains the right hand side of the system.
  131. *> On exit, X is overwritten by the solution.
  132. *> \endverbatim
  133. *>
  134. *> \param[out] WORK
  135. *> \verbatim
  136. *> WORK is DOUBLE PRECISION array, dimension (N)
  137. *> \endverbatim
  138. *>
  139. *> \param[out] INFO
  140. *> \verbatim
  141. *> INFO is INTEGER
  142. *> On exit, INFO is set to
  143. *> 0: successful exit.
  144. *> 1: the some diagonal 1 by 1 block has been perturbed by
  145. *> a small number SMIN to keep nonsingularity.
  146. *> 2: the some diagonal 2 by 2 block has been perturbed by
  147. *> a small number in DLALN2 to keep nonsingularity.
  148. *> NOTE: In the interests of speed, this routine does not
  149. *> check the inputs for errors.
  150. *> \endverbatim
  151. *
  152. * Authors:
  153. * ========
  154. *
  155. *> \author Univ. of Tennessee
  156. *> \author Univ. of California Berkeley
  157. *> \author Univ. of Colorado Denver
  158. *> \author NAG Ltd.
  159. *
  160. *> \date December 2016
  161. *
  162. *> \ingroup doubleOTHERauxiliary
  163. *
  164. * =====================================================================
  165. SUBROUTINE DLAQTR( LTRAN, LREAL, N, T, LDT, B, W, SCALE, X, WORK,
  166. $ INFO )
  167. *
  168. * -- LAPACK auxiliary routine (version 3.7.0) --
  169. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  170. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  171. * December 2016
  172. *
  173. * .. Scalar Arguments ..
  174. LOGICAL LREAL, LTRAN
  175. INTEGER INFO, LDT, N
  176. DOUBLE PRECISION SCALE, W
  177. * ..
  178. * .. Array Arguments ..
  179. DOUBLE PRECISION B( * ), T( LDT, * ), WORK( * ), X( * )
  180. * ..
  181. *
  182. * =====================================================================
  183. *
  184. * .. Parameters ..
  185. DOUBLE PRECISION ZERO, ONE
  186. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  187. * ..
  188. * .. Local Scalars ..
  189. LOGICAL NOTRAN
  190. INTEGER I, IERR, J, J1, J2, JNEXT, K, N1, N2
  191. DOUBLE PRECISION BIGNUM, EPS, REC, SCALOC, SI, SMIN, SMINW,
  192. $ SMLNUM, SR, TJJ, TMP, XJ, XMAX, XNORM, Z
  193. * ..
  194. * .. Local Arrays ..
  195. DOUBLE PRECISION D( 2, 2 ), V( 2, 2 )
  196. * ..
  197. * .. External Functions ..
  198. INTEGER IDAMAX
  199. DOUBLE PRECISION DASUM, DDOT, DLAMCH, DLANGE
  200. EXTERNAL IDAMAX, DASUM, DDOT, DLAMCH, DLANGE
  201. * ..
  202. * .. External Subroutines ..
  203. EXTERNAL DAXPY, DLADIV, DLALN2, DSCAL
  204. * ..
  205. * .. Intrinsic Functions ..
  206. INTRINSIC ABS, MAX
  207. * ..
  208. * .. Executable Statements ..
  209. *
  210. * Do not test the input parameters for errors
  211. *
  212. NOTRAN = .NOT.LTRAN
  213. INFO = 0
  214. *
  215. * Quick return if possible
  216. *
  217. IF( N.EQ.0 )
  218. $ RETURN
  219. *
  220. * Set constants to control overflow
  221. *
  222. EPS = DLAMCH( 'P' )
  223. SMLNUM = DLAMCH( 'S' ) / EPS
  224. BIGNUM = ONE / SMLNUM
  225. *
  226. XNORM = DLANGE( 'M', N, N, T, LDT, D )
  227. IF( .NOT.LREAL )
  228. $ XNORM = MAX( XNORM, ABS( W ), DLANGE( 'M', N, 1, B, N, D ) )
  229. SMIN = MAX( SMLNUM, EPS*XNORM )
  230. *
  231. * Compute 1-norm of each column of strictly upper triangular
  232. * part of T to control overflow in triangular solver.
  233. *
  234. WORK( 1 ) = ZERO
  235. DO 10 J = 2, N
  236. WORK( J ) = DASUM( J-1, T( 1, J ), 1 )
  237. 10 CONTINUE
  238. *
  239. IF( .NOT.LREAL ) THEN
  240. DO 20 I = 2, N
  241. WORK( I ) = WORK( I ) + ABS( B( I ) )
  242. 20 CONTINUE
  243. END IF
  244. *
  245. N2 = 2*N
  246. N1 = N
  247. IF( .NOT.LREAL )
  248. $ N1 = N2
  249. K = IDAMAX( N1, X, 1 )
  250. XMAX = ABS( X( K ) )
  251. SCALE = ONE
  252. *
  253. IF( XMAX.GT.BIGNUM ) THEN
  254. SCALE = BIGNUM / XMAX
  255. CALL DSCAL( N1, SCALE, X, 1 )
  256. XMAX = BIGNUM
  257. END IF
  258. *
  259. IF( LREAL ) THEN
  260. *
  261. IF( NOTRAN ) THEN
  262. *
  263. * Solve T*p = scale*c
  264. *
  265. JNEXT = N
  266. DO 30 J = N, 1, -1
  267. IF( J.GT.JNEXT )
  268. $ GO TO 30
  269. J1 = J
  270. J2 = J
  271. JNEXT = J - 1
  272. IF( J.GT.1 ) THEN
  273. IF( T( J, J-1 ).NE.ZERO ) THEN
  274. J1 = J - 1
  275. JNEXT = J - 2
  276. END IF
  277. END IF
  278. *
  279. IF( J1.EQ.J2 ) THEN
  280. *
  281. * Meet 1 by 1 diagonal block
  282. *
  283. * Scale to avoid overflow when computing
  284. * x(j) = b(j)/T(j,j)
  285. *
  286. XJ = ABS( X( J1 ) )
  287. TJJ = ABS( T( J1, J1 ) )
  288. TMP = T( J1, J1 )
  289. IF( TJJ.LT.SMIN ) THEN
  290. TMP = SMIN
  291. TJJ = SMIN
  292. INFO = 1
  293. END IF
  294. *
  295. IF( XJ.EQ.ZERO )
  296. $ GO TO 30
  297. *
  298. IF( TJJ.LT.ONE ) THEN
  299. IF( XJ.GT.BIGNUM*TJJ ) THEN
  300. REC = ONE / XJ
  301. CALL DSCAL( N, REC, X, 1 )
  302. SCALE = SCALE*REC
  303. XMAX = XMAX*REC
  304. END IF
  305. END IF
  306. X( J1 ) = X( J1 ) / TMP
  307. XJ = ABS( X( J1 ) )
  308. *
  309. * Scale x if necessary to avoid overflow when adding a
  310. * multiple of column j1 of T.
  311. *
  312. IF( XJ.GT.ONE ) THEN
  313. REC = ONE / XJ
  314. IF( WORK( J1 ).GT.( BIGNUM-XMAX )*REC ) THEN
  315. CALL DSCAL( N, REC, X, 1 )
  316. SCALE = SCALE*REC
  317. END IF
  318. END IF
  319. IF( J1.GT.1 ) THEN
  320. CALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
  321. K = IDAMAX( J1-1, X, 1 )
  322. XMAX = ABS( X( K ) )
  323. END IF
  324. *
  325. ELSE
  326. *
  327. * Meet 2 by 2 diagonal block
  328. *
  329. * Call 2 by 2 linear system solve, to take
  330. * care of possible overflow by scaling factor.
  331. *
  332. D( 1, 1 ) = X( J1 )
  333. D( 2, 1 ) = X( J2 )
  334. CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, T( J1, J1 ),
  335. $ LDT, ONE, ONE, D, 2, ZERO, ZERO, V, 2,
  336. $ SCALOC, XNORM, IERR )
  337. IF( IERR.NE.0 )
  338. $ INFO = 2
  339. *
  340. IF( SCALOC.NE.ONE ) THEN
  341. CALL DSCAL( N, SCALOC, X, 1 )
  342. SCALE = SCALE*SCALOC
  343. END IF
  344. X( J1 ) = V( 1, 1 )
  345. X( J2 ) = V( 2, 1 )
  346. *
  347. * Scale V(1,1) (= X(J1)) and/or V(2,1) (=X(J2))
  348. * to avoid overflow in updating right-hand side.
  349. *
  350. XJ = MAX( ABS( V( 1, 1 ) ), ABS( V( 2, 1 ) ) )
  351. IF( XJ.GT.ONE ) THEN
  352. REC = ONE / XJ
  353. IF( MAX( WORK( J1 ), WORK( J2 ) ).GT.
  354. $ ( BIGNUM-XMAX )*REC ) THEN
  355. CALL DSCAL( N, REC, X, 1 )
  356. SCALE = SCALE*REC
  357. END IF
  358. END IF
  359. *
  360. * Update right-hand side
  361. *
  362. IF( J1.GT.1 ) THEN
  363. CALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
  364. CALL DAXPY( J1-1, -X( J2 ), T( 1, J2 ), 1, X, 1 )
  365. K = IDAMAX( J1-1, X, 1 )
  366. XMAX = ABS( X( K ) )
  367. END IF
  368. *
  369. END IF
  370. *
  371. 30 CONTINUE
  372. *
  373. ELSE
  374. *
  375. * Solve T**T*p = scale*c
  376. *
  377. JNEXT = 1
  378. DO 40 J = 1, N
  379. IF( J.LT.JNEXT )
  380. $ GO TO 40
  381. J1 = J
  382. J2 = J
  383. JNEXT = J + 1
  384. IF( J.LT.N ) THEN
  385. IF( T( J+1, J ).NE.ZERO ) THEN
  386. J2 = J + 1
  387. JNEXT = J + 2
  388. END IF
  389. END IF
  390. *
  391. IF( J1.EQ.J2 ) THEN
  392. *
  393. * 1 by 1 diagonal block
  394. *
  395. * Scale if necessary to avoid overflow in forming the
  396. * right-hand side element by inner product.
  397. *
  398. XJ = ABS( X( J1 ) )
  399. IF( XMAX.GT.ONE ) THEN
  400. REC = ONE / XMAX
  401. IF( WORK( J1 ).GT.( BIGNUM-XJ )*REC ) THEN
  402. CALL DSCAL( N, REC, X, 1 )
  403. SCALE = SCALE*REC
  404. XMAX = XMAX*REC
  405. END IF
  406. END IF
  407. *
  408. X( J1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X, 1 )
  409. *
  410. XJ = ABS( X( J1 ) )
  411. TJJ = ABS( T( J1, J1 ) )
  412. TMP = T( J1, J1 )
  413. IF( TJJ.LT.SMIN ) THEN
  414. TMP = SMIN
  415. TJJ = SMIN
  416. INFO = 1
  417. END IF
  418. *
  419. IF( TJJ.LT.ONE ) THEN
  420. IF( XJ.GT.BIGNUM*TJJ ) THEN
  421. REC = ONE / XJ
  422. CALL DSCAL( N, REC, X, 1 )
  423. SCALE = SCALE*REC
  424. XMAX = XMAX*REC
  425. END IF
  426. END IF
  427. X( J1 ) = X( J1 ) / TMP
  428. XMAX = MAX( XMAX, ABS( X( J1 ) ) )
  429. *
  430. ELSE
  431. *
  432. * 2 by 2 diagonal block
  433. *
  434. * Scale if necessary to avoid overflow in forming the
  435. * right-hand side elements by inner product.
  436. *
  437. XJ = MAX( ABS( X( J1 ) ), ABS( X( J2 ) ) )
  438. IF( XMAX.GT.ONE ) THEN
  439. REC = ONE / XMAX
  440. IF( MAX( WORK( J2 ), WORK( J1 ) ).GT.( BIGNUM-XJ )*
  441. $ REC ) THEN
  442. CALL DSCAL( N, REC, X, 1 )
  443. SCALE = SCALE*REC
  444. XMAX = XMAX*REC
  445. END IF
  446. END IF
  447. *
  448. D( 1, 1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X,
  449. $ 1 )
  450. D( 2, 1 ) = X( J2 ) - DDOT( J1-1, T( 1, J2 ), 1, X,
  451. $ 1 )
  452. *
  453. CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, T( J1, J1 ),
  454. $ LDT, ONE, ONE, D, 2, ZERO, ZERO, V, 2,
  455. $ SCALOC, XNORM, IERR )
  456. IF( IERR.NE.0 )
  457. $ INFO = 2
  458. *
  459. IF( SCALOC.NE.ONE ) THEN
  460. CALL DSCAL( N, SCALOC, X, 1 )
  461. SCALE = SCALE*SCALOC
  462. END IF
  463. X( J1 ) = V( 1, 1 )
  464. X( J2 ) = V( 2, 1 )
  465. XMAX = MAX( ABS( X( J1 ) ), ABS( X( J2 ) ), XMAX )
  466. *
  467. END IF
  468. 40 CONTINUE
  469. END IF
  470. *
  471. ELSE
  472. *
  473. SMINW = MAX( EPS*ABS( W ), SMIN )
  474. IF( NOTRAN ) THEN
  475. *
  476. * Solve (T + iB)*(p+iq) = c+id
  477. *
  478. JNEXT = N
  479. DO 70 J = N, 1, -1
  480. IF( J.GT.JNEXT )
  481. $ GO TO 70
  482. J1 = J
  483. J2 = J
  484. JNEXT = J - 1
  485. IF( J.GT.1 ) THEN
  486. IF( T( J, J-1 ).NE.ZERO ) THEN
  487. J1 = J - 1
  488. JNEXT = J - 2
  489. END IF
  490. END IF
  491. *
  492. IF( J1.EQ.J2 ) THEN
  493. *
  494. * 1 by 1 diagonal block
  495. *
  496. * Scale if necessary to avoid overflow in division
  497. *
  498. Z = W
  499. IF( J1.EQ.1 )
  500. $ Z = B( 1 )
  501. XJ = ABS( X( J1 ) ) + ABS( X( N+J1 ) )
  502. TJJ = ABS( T( J1, J1 ) ) + ABS( Z )
  503. TMP = T( J1, J1 )
  504. IF( TJJ.LT.SMINW ) THEN
  505. TMP = SMINW
  506. TJJ = SMINW
  507. INFO = 1
  508. END IF
  509. *
  510. IF( XJ.EQ.ZERO )
  511. $ GO TO 70
  512. *
  513. IF( TJJ.LT.ONE ) THEN
  514. IF( XJ.GT.BIGNUM*TJJ ) THEN
  515. REC = ONE / XJ
  516. CALL DSCAL( N2, REC, X, 1 )
  517. SCALE = SCALE*REC
  518. XMAX = XMAX*REC
  519. END IF
  520. END IF
  521. CALL DLADIV( X( J1 ), X( N+J1 ), TMP, Z, SR, SI )
  522. X( J1 ) = SR
  523. X( N+J1 ) = SI
  524. XJ = ABS( X( J1 ) ) + ABS( X( N+J1 ) )
  525. *
  526. * Scale x if necessary to avoid overflow when adding a
  527. * multiple of column j1 of T.
  528. *
  529. IF( XJ.GT.ONE ) THEN
  530. REC = ONE / XJ
  531. IF( WORK( J1 ).GT.( BIGNUM-XMAX )*REC ) THEN
  532. CALL DSCAL( N2, REC, X, 1 )
  533. SCALE = SCALE*REC
  534. END IF
  535. END IF
  536. *
  537. IF( J1.GT.1 ) THEN
  538. CALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
  539. CALL DAXPY( J1-1, -X( N+J1 ), T( 1, J1 ), 1,
  540. $ X( N+1 ), 1 )
  541. *
  542. X( 1 ) = X( 1 ) + B( J1 )*X( N+J1 )
  543. X( N+1 ) = X( N+1 ) - B( J1 )*X( J1 )
  544. *
  545. XMAX = ZERO
  546. DO 50 K = 1, J1 - 1
  547. XMAX = MAX( XMAX, ABS( X( K ) )+
  548. $ ABS( X( K+N ) ) )
  549. 50 CONTINUE
  550. END IF
  551. *
  552. ELSE
  553. *
  554. * Meet 2 by 2 diagonal block
  555. *
  556. D( 1, 1 ) = X( J1 )
  557. D( 2, 1 ) = X( J2 )
  558. D( 1, 2 ) = X( N+J1 )
  559. D( 2, 2 ) = X( N+J2 )
  560. CALL DLALN2( .FALSE., 2, 2, SMINW, ONE, T( J1, J1 ),
  561. $ LDT, ONE, ONE, D, 2, ZERO, -W, V, 2,
  562. $ SCALOC, XNORM, IERR )
  563. IF( IERR.NE.0 )
  564. $ INFO = 2
  565. *
  566. IF( SCALOC.NE.ONE ) THEN
  567. CALL DSCAL( 2*N, SCALOC, X, 1 )
  568. SCALE = SCALOC*SCALE
  569. END IF
  570. X( J1 ) = V( 1, 1 )
  571. X( J2 ) = V( 2, 1 )
  572. X( N+J1 ) = V( 1, 2 )
  573. X( N+J2 ) = V( 2, 2 )
  574. *
  575. * Scale X(J1), .... to avoid overflow in
  576. * updating right hand side.
  577. *
  578. XJ = MAX( ABS( V( 1, 1 ) )+ABS( V( 1, 2 ) ),
  579. $ ABS( V( 2, 1 ) )+ABS( V( 2, 2 ) ) )
  580. IF( XJ.GT.ONE ) THEN
  581. REC = ONE / XJ
  582. IF( MAX( WORK( J1 ), WORK( J2 ) ).GT.
  583. $ ( BIGNUM-XMAX )*REC ) THEN
  584. CALL DSCAL( N2, REC, X, 1 )
  585. SCALE = SCALE*REC
  586. END IF
  587. END IF
  588. *
  589. * Update the right-hand side.
  590. *
  591. IF( J1.GT.1 ) THEN
  592. CALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
  593. CALL DAXPY( J1-1, -X( J2 ), T( 1, J2 ), 1, X, 1 )
  594. *
  595. CALL DAXPY( J1-1, -X( N+J1 ), T( 1, J1 ), 1,
  596. $ X( N+1 ), 1 )
  597. CALL DAXPY( J1-1, -X( N+J2 ), T( 1, J2 ), 1,
  598. $ X( N+1 ), 1 )
  599. *
  600. X( 1 ) = X( 1 ) + B( J1 )*X( N+J1 ) +
  601. $ B( J2 )*X( N+J2 )
  602. X( N+1 ) = X( N+1 ) - B( J1 )*X( J1 ) -
  603. $ B( J2 )*X( J2 )
  604. *
  605. XMAX = ZERO
  606. DO 60 K = 1, J1 - 1
  607. XMAX = MAX( ABS( X( K ) )+ABS( X( K+N ) ),
  608. $ XMAX )
  609. 60 CONTINUE
  610. END IF
  611. *
  612. END IF
  613. 70 CONTINUE
  614. *
  615. ELSE
  616. *
  617. * Solve (T + iB)**T*(p+iq) = c+id
  618. *
  619. JNEXT = 1
  620. DO 80 J = 1, N
  621. IF( J.LT.JNEXT )
  622. $ GO TO 80
  623. J1 = J
  624. J2 = J
  625. JNEXT = J + 1
  626. IF( J.LT.N ) THEN
  627. IF( T( J+1, J ).NE.ZERO ) THEN
  628. J2 = J + 1
  629. JNEXT = J + 2
  630. END IF
  631. END IF
  632. *
  633. IF( J1.EQ.J2 ) THEN
  634. *
  635. * 1 by 1 diagonal block
  636. *
  637. * Scale if necessary to avoid overflow in forming the
  638. * right-hand side element by inner product.
  639. *
  640. XJ = ABS( X( J1 ) ) + ABS( X( J1+N ) )
  641. IF( XMAX.GT.ONE ) THEN
  642. REC = ONE / XMAX
  643. IF( WORK( J1 ).GT.( BIGNUM-XJ )*REC ) THEN
  644. CALL DSCAL( N2, REC, X, 1 )
  645. SCALE = SCALE*REC
  646. XMAX = XMAX*REC
  647. END IF
  648. END IF
  649. *
  650. X( J1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X, 1 )
  651. X( N+J1 ) = X( N+J1 ) - DDOT( J1-1, T( 1, J1 ), 1,
  652. $ X( N+1 ), 1 )
  653. IF( J1.GT.1 ) THEN
  654. X( J1 ) = X( J1 ) - B( J1 )*X( N+1 )
  655. X( N+J1 ) = X( N+J1 ) + B( J1 )*X( 1 )
  656. END IF
  657. XJ = ABS( X( J1 ) ) + ABS( X( J1+N ) )
  658. *
  659. Z = W
  660. IF( J1.EQ.1 )
  661. $ Z = B( 1 )
  662. *
  663. * Scale if necessary to avoid overflow in
  664. * complex division
  665. *
  666. TJJ = ABS( T( J1, J1 ) ) + ABS( Z )
  667. TMP = T( J1, J1 )
  668. IF( TJJ.LT.SMINW ) THEN
  669. TMP = SMINW
  670. TJJ = SMINW
  671. INFO = 1
  672. END IF
  673. *
  674. IF( TJJ.LT.ONE ) THEN
  675. IF( XJ.GT.BIGNUM*TJJ ) THEN
  676. REC = ONE / XJ
  677. CALL DSCAL( N2, REC, X, 1 )
  678. SCALE = SCALE*REC
  679. XMAX = XMAX*REC
  680. END IF
  681. END IF
  682. CALL DLADIV( X( J1 ), X( N+J1 ), TMP, -Z, SR, SI )
  683. X( J1 ) = SR
  684. X( J1+N ) = SI
  685. XMAX = MAX( ABS( X( J1 ) )+ABS( X( J1+N ) ), XMAX )
  686. *
  687. ELSE
  688. *
  689. * 2 by 2 diagonal block
  690. *
  691. * Scale if necessary to avoid overflow in forming the
  692. * right-hand side element by inner product.
  693. *
  694. XJ = MAX( ABS( X( J1 ) )+ABS( X( N+J1 ) ),
  695. $ ABS( X( J2 ) )+ABS( X( N+J2 ) ) )
  696. IF( XMAX.GT.ONE ) THEN
  697. REC = ONE / XMAX
  698. IF( MAX( WORK( J1 ), WORK( J2 ) ).GT.
  699. $ ( BIGNUM-XJ ) / XMAX ) THEN
  700. CALL DSCAL( N2, REC, X, 1 )
  701. SCALE = SCALE*REC
  702. XMAX = XMAX*REC
  703. END IF
  704. END IF
  705. *
  706. D( 1, 1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X,
  707. $ 1 )
  708. D( 2, 1 ) = X( J2 ) - DDOT( J1-1, T( 1, J2 ), 1, X,
  709. $ 1 )
  710. D( 1, 2 ) = X( N+J1 ) - DDOT( J1-1, T( 1, J1 ), 1,
  711. $ X( N+1 ), 1 )
  712. D( 2, 2 ) = X( N+J2 ) - DDOT( J1-1, T( 1, J2 ), 1,
  713. $ X( N+1 ), 1 )
  714. D( 1, 1 ) = D( 1, 1 ) - B( J1 )*X( N+1 )
  715. D( 2, 1 ) = D( 2, 1 ) - B( J2 )*X( N+1 )
  716. D( 1, 2 ) = D( 1, 2 ) + B( J1 )*X( 1 )
  717. D( 2, 2 ) = D( 2, 2 ) + B( J2 )*X( 1 )
  718. *
  719. CALL DLALN2( .TRUE., 2, 2, SMINW, ONE, T( J1, J1 ),
  720. $ LDT, ONE, ONE, D, 2, ZERO, W, V, 2,
  721. $ SCALOC, XNORM, IERR )
  722. IF( IERR.NE.0 )
  723. $ INFO = 2
  724. *
  725. IF( SCALOC.NE.ONE ) THEN
  726. CALL DSCAL( N2, SCALOC, X, 1 )
  727. SCALE = SCALOC*SCALE
  728. END IF
  729. X( J1 ) = V( 1, 1 )
  730. X( J2 ) = V( 2, 1 )
  731. X( N+J1 ) = V( 1, 2 )
  732. X( N+J2 ) = V( 2, 2 )
  733. XMAX = MAX( ABS( X( J1 ) )+ABS( X( N+J1 ) ),
  734. $ ABS( X( J2 ) )+ABS( X( N+J2 ) ), XMAX )
  735. *
  736. END IF
  737. *
  738. 80 CONTINUE
  739. *
  740. END IF
  741. *
  742. END IF
  743. *
  744. RETURN
  745. *
  746. * End of DLAQTR
  747. *
  748. END