/src/igraph/vendor/lapack/dlaln2.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* -- translated by f2c (version 20191129). |
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 | | |
10 | | http://www.netlib.org/f2c/libf2c.zip |
11 | | */ |
12 | | |
13 | | #include "f2c.h" |
14 | | |
15 | | /* > \brief \b DLALN2 solves a 1-by-1 or 2-by-2 linear system of equations of the specified form. |
16 | | |
17 | | =========== DOCUMENTATION =========== |
18 | | |
19 | | Online html documentation available at |
20 | | http://www.netlib.org/lapack/explore-html/ |
21 | | |
22 | | > \htmlonly |
23 | | > Download DLALN2 + dependencies |
24 | | > <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaln2. |
25 | | f"> |
26 | | > [TGZ]</a> |
27 | | > <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaln2. |
28 | | f"> |
29 | | > [ZIP]</a> |
30 | | > <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaln2. |
31 | | f"> |
32 | | > [TXT]</a> |
33 | | > \endhtmlonly |
34 | | |
35 | | Definition: |
36 | | =========== |
37 | | |
38 | | SUBROUTINE DLALN2( LTRANS, NA, NW, SMIN, CA, A, LDA, D1, D2, B, |
39 | | LDB, WR, WI, X, LDX, SCALE, XNORM, INFO ) |
40 | | |
41 | | LOGICAL LTRANS |
42 | | INTEGER INFO, LDA, LDB, LDX, NA, NW |
43 | | DOUBLE PRECISION CA, D1, D2, SCALE, SMIN, WI, WR, XNORM |
44 | | DOUBLE PRECISION A( LDA, * ), B( LDB, * ), X( LDX, * ) |
45 | | |
46 | | |
47 | | > \par Purpose: |
48 | | ============= |
49 | | > |
50 | | > \verbatim |
51 | | > |
52 | | > DLALN2 solves a system of the form (ca A - w D ) X = s B |
53 | | > or (ca A**T - w D) X = s B with possible scaling ("s") and |
54 | | > perturbation of A. (A**T means A-transpose.) |
55 | | > |
56 | | > A is an NA x NA real matrix, ca is a real scalar, D is an NA x NA |
57 | | > real diagonal matrix, w is a real or complex value, and X and B are |
58 | | > NA x 1 matrices -- real if w is real, complex if w is complex. NA |
59 | | > may be 1 or 2. |
60 | | > |
61 | | > If w is complex, X and B are represented as NA x 2 matrices, |
62 | | > the first column of each being the real part and the second |
63 | | > being the imaginary part. |
64 | | > |
65 | | > "s" is a scaling factor (.LE. 1), computed by DLALN2, which is |
66 | | > so chosen that X can be computed without overflow. X is further |
67 | | > scaled if necessary to assure that norm(ca A - w D)*norm(X) is less |
68 | | > than overflow. |
69 | | > |
70 | | > If both singular values of (ca A - w D) are less than SMIN, |
71 | | > SMIN*identity will be used instead of (ca A - w D). If only one |
72 | | > singular value is less than SMIN, one element of (ca A - w D) will be |
73 | | > perturbed enough to make the smallest singular value roughly SMIN. |
74 | | > If both singular values are at least SMIN, (ca A - w D) will not be |
75 | | > perturbed. In any case, the perturbation will be at most some small |
76 | | > multiple of max( SMIN, ulp*norm(ca A - w D) ). The singular values |
77 | | > are computed by infinity-norm approximations, and thus will only be |
78 | | > correct to a factor of 2 or so. |
79 | | > |
80 | | > Note: all input quantities are assumed to be smaller than overflow |
81 | | > by a reasonable factor. (See BIGNUM.) |
82 | | > \endverbatim |
83 | | |
84 | | Arguments: |
85 | | ========== |
86 | | |
87 | | > \param[in] LTRANS |
88 | | > \verbatim |
89 | | > LTRANS is LOGICAL |
90 | | > =.TRUE.: A-transpose will be used. |
91 | | > =.FALSE.: A will be used (not transposed.) |
92 | | > \endverbatim |
93 | | > |
94 | | > \param[in] NA |
95 | | > \verbatim |
96 | | > NA is INTEGER |
97 | | > The size of the matrix A. It may (only) be 1 or 2. |
98 | | > \endverbatim |
99 | | > |
100 | | > \param[in] NW |
101 | | > \verbatim |
102 | | > NW is INTEGER |
103 | | > 1 if "w" is real, 2 if "w" is complex. It may only be 1 |
104 | | > or 2. |
105 | | > \endverbatim |
106 | | > |
107 | | > \param[in] SMIN |
108 | | > \verbatim |
109 | | > SMIN is DOUBLE PRECISION |
110 | | > The desired lower bound on the singular values of A. This |
111 | | > should be a safe distance away from underflow or overflow, |
112 | | > say, between (underflow/machine precision) and (machine |
113 | | > precision * overflow ). (See BIGNUM and ULP.) |
114 | | > \endverbatim |
115 | | > |
116 | | > \param[in] CA |
117 | | > \verbatim |
118 | | > CA is DOUBLE PRECISION |
119 | | > The coefficient c, which A is multiplied by. |
120 | | > \endverbatim |
121 | | > |
122 | | > \param[in] A |
123 | | > \verbatim |
124 | | > A is DOUBLE PRECISION array, dimension (LDA,NA) |
125 | | > The NA x NA matrix A. |
126 | | > \endverbatim |
127 | | > |
128 | | > \param[in] LDA |
129 | | > \verbatim |
130 | | > LDA is INTEGER |
131 | | > The leading dimension of A. It must be at least NA. |
132 | | > \endverbatim |
133 | | > |
134 | | > \param[in] D1 |
135 | | > \verbatim |
136 | | > D1 is DOUBLE PRECISION |
137 | | > The 1,1 element in the diagonal matrix D. |
138 | | > \endverbatim |
139 | | > |
140 | | > \param[in] D2 |
141 | | > \verbatim |
142 | | > D2 is DOUBLE PRECISION |
143 | | > The 2,2 element in the diagonal matrix D. Not used if NW=1. |
144 | | > \endverbatim |
145 | | > |
146 | | > \param[in] B |
147 | | > \verbatim |
148 | | > B is DOUBLE PRECISION array, dimension (LDB,NW) |
149 | | > The NA x NW matrix B (right-hand side). If NW=2 ("w" is |
150 | | > complex), column 1 contains the real part of B and column 2 |
151 | | > contains the imaginary part. |
152 | | > \endverbatim |
153 | | > |
154 | | > \param[in] LDB |
155 | | > \verbatim |
156 | | > LDB is INTEGER |
157 | | > The leading dimension of B. It must be at least NA. |
158 | | > \endverbatim |
159 | | > |
160 | | > \param[in] WR |
161 | | > \verbatim |
162 | | > WR is DOUBLE PRECISION |
163 | | > The real part of the scalar "w". |
164 | | > \endverbatim |
165 | | > |
166 | | > \param[in] WI |
167 | | > \verbatim |
168 | | > WI is DOUBLE PRECISION |
169 | | > The imaginary part of the scalar "w". Not used if NW=1. |
170 | | > \endverbatim |
171 | | > |
172 | | > \param[out] X |
173 | | > \verbatim |
174 | | > X is DOUBLE PRECISION array, dimension (LDX,NW) |
175 | | > The NA x NW matrix X (unknowns), as computed by DLALN2. |
176 | | > If NW=2 ("w" is complex), on exit, column 1 will contain |
177 | | > the real part of X and column 2 will contain the imaginary |
178 | | > part. |
179 | | > \endverbatim |
180 | | > |
181 | | > \param[in] LDX |
182 | | > \verbatim |
183 | | > LDX is INTEGER |
184 | | > The leading dimension of X. It must be at least NA. |
185 | | > \endverbatim |
186 | | > |
187 | | > \param[out] SCALE |
188 | | > \verbatim |
189 | | > SCALE is DOUBLE PRECISION |
190 | | > The scale factor that B must be multiplied by to insure |
191 | | > that overflow does not occur when computing X. Thus, |
192 | | > (ca A - w D) X will be SCALE*B, not B (ignoring |
193 | | > perturbations of A.) It will be at most 1. |
194 | | > \endverbatim |
195 | | > |
196 | | > \param[out] XNORM |
197 | | > \verbatim |
198 | | > XNORM is DOUBLE PRECISION |
199 | | > The infinity-norm of X, when X is regarded as an NA x NW |
200 | | > real matrix. |
201 | | > \endverbatim |
202 | | > |
203 | | > \param[out] INFO |
204 | | > \verbatim |
205 | | > INFO is INTEGER |
206 | | > An error flag. It will be set to zero if no error occurs, |
207 | | > a negative number if an argument is in error, or a positive |
208 | | > number if ca A - w D had to be perturbed. |
209 | | > The possible values are: |
210 | | > = 0: No error occurred, and (ca A - w D) did not have to be |
211 | | > perturbed. |
212 | | > = 1: (ca A - w D) had to be perturbed to make its smallest |
213 | | > (or only) singular value greater than SMIN. |
214 | | > NOTE: In the interests of speed, this routine does not |
215 | | > check the inputs for errors. |
216 | | > \endverbatim |
217 | | |
218 | | Authors: |
219 | | ======== |
220 | | |
221 | | > \author Univ. of Tennessee |
222 | | > \author Univ. of California Berkeley |
223 | | > \author Univ. of Colorado Denver |
224 | | > \author NAG Ltd. |
225 | | |
226 | | > \date September 2012 |
227 | | |
228 | | > \ingroup doubleOTHERauxiliary |
229 | | |
230 | | ===================================================================== |
231 | | Subroutine */ int igraphdlaln2_(logical *ltrans, integer *na, integer *nw, |
232 | | doublereal *smin, doublereal *ca, doublereal *a, integer *lda, |
233 | | doublereal *d1, doublereal *d2, doublereal *b, integer *ldb, |
234 | | doublereal *wr, doublereal *wi, doublereal *x, integer *ldx, |
235 | | doublereal *scale, doublereal *xnorm, integer *info) |
236 | 0 | { |
237 | | /* Initialized data */ |
238 | |
|
239 | 0 | static logical zswap[4] = { FALSE_,FALSE_,TRUE_,TRUE_ }; |
240 | 0 | static logical rswap[4] = { FALSE_,TRUE_,FALSE_,TRUE_ }; |
241 | 0 | static integer ipivot[16] /* was [4][4] */ = { 1,2,3,4,2,1,4,3,3,4,1,2, |
242 | 0 | 4,3,2,1 }; |
243 | | |
244 | | /* System generated locals */ |
245 | 0 | integer a_dim1, a_offset, b_dim1, b_offset, x_dim1, x_offset; |
246 | 0 | doublereal d__1, d__2, d__3, d__4, d__5, d__6; |
247 | 0 | IGRAPH_F77_SAVE doublereal equiv_0[4], equiv_1[4]; |
248 | | |
249 | | /* Local variables */ |
250 | 0 | integer j; |
251 | 0 | #define ci (equiv_0) |
252 | 0 | #define cr (equiv_1) |
253 | 0 | doublereal bi1, bi2, br1, br2, xi1, xi2, xr1, xr2, ci21, ci22, cr21, cr22, |
254 | 0 | li21, csi, ui11, lr21, ui12, ui22; |
255 | 0 | #define civ (equiv_0) |
256 | 0 | doublereal csr, ur11, ur12, ur22; |
257 | 0 | #define crv (equiv_1) |
258 | 0 | doublereal bbnd, cmax, ui11r, ui12s, temp, ur11r, ur12s, u22abs; |
259 | 0 | integer icmax; |
260 | 0 | doublereal bnorm, cnorm, smini; |
261 | 0 | extern doublereal igraphdlamch_(char *); |
262 | 0 | extern /* Subroutine */ int igraphdladiv_(doublereal *, doublereal *, |
263 | 0 | doublereal *, doublereal *, doublereal *, doublereal *); |
264 | 0 | doublereal bignum, smlnum; |
265 | | |
266 | | |
267 | | /* -- LAPACK auxiliary routine (version 3.4.2) -- |
268 | | -- LAPACK is a software package provided by Univ. of Tennessee, -- |
269 | | -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- |
270 | | September 2012 |
271 | | |
272 | | |
273 | | ===================================================================== |
274 | | |
275 | | Parameter adjustments */ |
276 | 0 | a_dim1 = *lda; |
277 | 0 | a_offset = 1 + a_dim1; |
278 | 0 | a -= a_offset; |
279 | 0 | b_dim1 = *ldb; |
280 | 0 | b_offset = 1 + b_dim1; |
281 | 0 | b -= b_offset; |
282 | 0 | x_dim1 = *ldx; |
283 | 0 | x_offset = 1 + x_dim1; |
284 | 0 | x -= x_offset; |
285 | | |
286 | | /* Function Body |
287 | | |
288 | | Compute BIGNUM */ |
289 | |
|
290 | 0 | smlnum = 2. * igraphdlamch_("Safe minimum"); |
291 | 0 | bignum = 1. / smlnum; |
292 | 0 | smini = max(*smin,smlnum); |
293 | | |
294 | | /* Don't check for input errors */ |
295 | |
|
296 | 0 | *info = 0; |
297 | | |
298 | | /* Standard Initializations */ |
299 | |
|
300 | 0 | *scale = 1.; |
301 | |
|
302 | 0 | if (*na == 1) { |
303 | | |
304 | | /* 1 x 1 (i.e., scalar) system C X = B */ |
305 | |
|
306 | 0 | if (*nw == 1) { |
307 | | |
308 | | /* Real 1x1 system. |
309 | | |
310 | | C = ca A - w D */ |
311 | |
|
312 | 0 | csr = *ca * a[a_dim1 + 1] - *wr * *d1; |
313 | 0 | cnorm = abs(csr); |
314 | | |
315 | | /* If | C | < SMINI, use C = SMINI */ |
316 | |
|
317 | 0 | if (cnorm < smini) { |
318 | 0 | csr = smini; |
319 | 0 | cnorm = smini; |
320 | 0 | *info = 1; |
321 | 0 | } |
322 | | |
323 | | /* Check scaling for X = B / C */ |
324 | |
|
325 | 0 | bnorm = (d__1 = b[b_dim1 + 1], abs(d__1)); |
326 | 0 | if (cnorm < 1. && bnorm > 1.) { |
327 | 0 | if (bnorm > bignum * cnorm) { |
328 | 0 | *scale = 1. / bnorm; |
329 | 0 | } |
330 | 0 | } |
331 | | |
332 | | /* Compute X */ |
333 | |
|
334 | 0 | x[x_dim1 + 1] = b[b_dim1 + 1] * *scale / csr; |
335 | 0 | *xnorm = (d__1 = x[x_dim1 + 1], abs(d__1)); |
336 | 0 | } else { |
337 | | |
338 | | /* Complex 1x1 system (w is complex) |
339 | | |
340 | | C = ca A - w D */ |
341 | |
|
342 | 0 | csr = *ca * a[a_dim1 + 1] - *wr * *d1; |
343 | 0 | csi = -(*wi) * *d1; |
344 | 0 | cnorm = abs(csr) + abs(csi); |
345 | | |
346 | | /* If | C | < SMINI, use C = SMINI */ |
347 | |
|
348 | 0 | if (cnorm < smini) { |
349 | 0 | csr = smini; |
350 | 0 | csi = 0.; |
351 | 0 | cnorm = smini; |
352 | 0 | *info = 1; |
353 | 0 | } |
354 | | |
355 | | /* Check scaling for X = B / C */ |
356 | |
|
357 | 0 | bnorm = (d__1 = b[b_dim1 + 1], abs(d__1)) + (d__2 = b[(b_dim1 << |
358 | 0 | 1) + 1], abs(d__2)); |
359 | 0 | if (cnorm < 1. && bnorm > 1.) { |
360 | 0 | if (bnorm > bignum * cnorm) { |
361 | 0 | *scale = 1. / bnorm; |
362 | 0 | } |
363 | 0 | } |
364 | | |
365 | | /* Compute X */ |
366 | |
|
367 | 0 | d__1 = *scale * b[b_dim1 + 1]; |
368 | 0 | d__2 = *scale * b[(b_dim1 << 1) + 1]; |
369 | 0 | igraphdladiv_(&d__1, &d__2, &csr, &csi, &x[x_dim1 + 1], &x[(x_dim1 << 1) |
370 | 0 | + 1]); |
371 | 0 | *xnorm = (d__1 = x[x_dim1 + 1], abs(d__1)) + (d__2 = x[(x_dim1 << |
372 | 0 | 1) + 1], abs(d__2)); |
373 | 0 | } |
374 | |
|
375 | 0 | } else { |
376 | | |
377 | | /* 2x2 System |
378 | | |
379 | | Compute the real part of C = ca A - w D (or ca A**T - w D ) */ |
380 | |
|
381 | 0 | cr[0] = *ca * a[a_dim1 + 1] - *wr * *d1; |
382 | 0 | cr[3] = *ca * a[(a_dim1 << 1) + 2] - *wr * *d2; |
383 | 0 | if (*ltrans) { |
384 | 0 | cr[2] = *ca * a[a_dim1 + 2]; |
385 | 0 | cr[1] = *ca * a[(a_dim1 << 1) + 1]; |
386 | 0 | } else { |
387 | 0 | cr[1] = *ca * a[a_dim1 + 2]; |
388 | 0 | cr[2] = *ca * a[(a_dim1 << 1) + 1]; |
389 | 0 | } |
390 | |
|
391 | 0 | if (*nw == 1) { |
392 | | |
393 | | /* Real 2x2 system (w is real) |
394 | | |
395 | | Find the largest element in C */ |
396 | |
|
397 | 0 | cmax = 0.; |
398 | 0 | icmax = 0; |
399 | |
|
400 | 0 | for (j = 1; j <= 4; ++j) { |
401 | 0 | if ((d__1 = crv[j - 1], abs(d__1)) > cmax) { |
402 | 0 | cmax = (d__1 = crv[j - 1], abs(d__1)); |
403 | 0 | icmax = j; |
404 | 0 | } |
405 | | /* L10: */ |
406 | 0 | } |
407 | | |
408 | | /* If norm(C) < SMINI, use SMINI*identity. */ |
409 | |
|
410 | 0 | if (cmax < smini) { |
411 | | /* Computing MAX */ |
412 | 0 | d__3 = (d__1 = b[b_dim1 + 1], abs(d__1)), d__4 = (d__2 = b[ |
413 | 0 | b_dim1 + 2], abs(d__2)); |
414 | 0 | bnorm = max(d__3,d__4); |
415 | 0 | if (smini < 1. && bnorm > 1.) { |
416 | 0 | if (bnorm > bignum * smini) { |
417 | 0 | *scale = 1. / bnorm; |
418 | 0 | } |
419 | 0 | } |
420 | 0 | temp = *scale / smini; |
421 | 0 | x[x_dim1 + 1] = temp * b[b_dim1 + 1]; |
422 | 0 | x[x_dim1 + 2] = temp * b[b_dim1 + 2]; |
423 | 0 | *xnorm = temp * bnorm; |
424 | 0 | *info = 1; |
425 | 0 | return 0; |
426 | 0 | } |
427 | | |
428 | | /* Gaussian elimination with complete pivoting. */ |
429 | | |
430 | 0 | ur11 = crv[icmax - 1]; |
431 | 0 | cr21 = crv[ipivot[(icmax << 2) - 3] - 1]; |
432 | 0 | ur12 = crv[ipivot[(icmax << 2) - 2] - 1]; |
433 | 0 | cr22 = crv[ipivot[(icmax << 2) - 1] - 1]; |
434 | 0 | ur11r = 1. / ur11; |
435 | 0 | lr21 = ur11r * cr21; |
436 | 0 | ur22 = cr22 - ur12 * lr21; |
437 | | |
438 | | /* If smaller pivot < SMINI, use SMINI */ |
439 | |
|
440 | 0 | if (abs(ur22) < smini) { |
441 | 0 | ur22 = smini; |
442 | 0 | *info = 1; |
443 | 0 | } |
444 | 0 | if (rswap[icmax - 1]) { |
445 | 0 | br1 = b[b_dim1 + 2]; |
446 | 0 | br2 = b[b_dim1 + 1]; |
447 | 0 | } else { |
448 | 0 | br1 = b[b_dim1 + 1]; |
449 | 0 | br2 = b[b_dim1 + 2]; |
450 | 0 | } |
451 | 0 | br2 -= lr21 * br1; |
452 | | /* Computing MAX */ |
453 | 0 | d__2 = (d__1 = br1 * (ur22 * ur11r), abs(d__1)), d__3 = abs(br2); |
454 | 0 | bbnd = max(d__2,d__3); |
455 | 0 | if (bbnd > 1. && abs(ur22) < 1.) { |
456 | 0 | if (bbnd >= bignum * abs(ur22)) { |
457 | 0 | *scale = 1. / bbnd; |
458 | 0 | } |
459 | 0 | } |
460 | |
|
461 | 0 | xr2 = br2 * *scale / ur22; |
462 | 0 | xr1 = *scale * br1 * ur11r - xr2 * (ur11r * ur12); |
463 | 0 | if (zswap[icmax - 1]) { |
464 | 0 | x[x_dim1 + 1] = xr2; |
465 | 0 | x[x_dim1 + 2] = xr1; |
466 | 0 | } else { |
467 | 0 | x[x_dim1 + 1] = xr1; |
468 | 0 | x[x_dim1 + 2] = xr2; |
469 | 0 | } |
470 | | /* Computing MAX */ |
471 | 0 | d__1 = abs(xr1), d__2 = abs(xr2); |
472 | 0 | *xnorm = max(d__1,d__2); |
473 | | |
474 | | /* Further scaling if norm(A) norm(X) > overflow */ |
475 | |
|
476 | 0 | if (*xnorm > 1. && cmax > 1.) { |
477 | 0 | if (*xnorm > bignum / cmax) { |
478 | 0 | temp = cmax / bignum; |
479 | 0 | x[x_dim1 + 1] = temp * x[x_dim1 + 1]; |
480 | 0 | x[x_dim1 + 2] = temp * x[x_dim1 + 2]; |
481 | 0 | *xnorm = temp * *xnorm; |
482 | 0 | *scale = temp * *scale; |
483 | 0 | } |
484 | 0 | } |
485 | 0 | } else { |
486 | | |
487 | | /* Complex 2x2 system (w is complex) |
488 | | |
489 | | Find the largest element in C */ |
490 | |
|
491 | 0 | ci[0] = -(*wi) * *d1; |
492 | 0 | ci[1] = 0.; |
493 | 0 | ci[2] = 0.; |
494 | 0 | ci[3] = -(*wi) * *d2; |
495 | 0 | cmax = 0.; |
496 | 0 | icmax = 0; |
497 | |
|
498 | 0 | for (j = 1; j <= 4; ++j) { |
499 | 0 | if ((d__1 = crv[j - 1], abs(d__1)) + (d__2 = civ[j - 1], abs( |
500 | 0 | d__2)) > cmax) { |
501 | 0 | cmax = (d__1 = crv[j - 1], abs(d__1)) + (d__2 = civ[j - 1] |
502 | 0 | , abs(d__2)); |
503 | 0 | icmax = j; |
504 | 0 | } |
505 | | /* L20: */ |
506 | 0 | } |
507 | | |
508 | | /* If norm(C) < SMINI, use SMINI*identity. */ |
509 | |
|
510 | 0 | if (cmax < smini) { |
511 | | /* Computing MAX */ |
512 | 0 | d__5 = (d__1 = b[b_dim1 + 1], abs(d__1)) + (d__2 = b[(b_dim1 |
513 | 0 | << 1) + 1], abs(d__2)), d__6 = (d__3 = b[b_dim1 + 2], |
514 | 0 | abs(d__3)) + (d__4 = b[(b_dim1 << 1) + 2], abs(d__4)); |
515 | 0 | bnorm = max(d__5,d__6); |
516 | 0 | if (smini < 1. && bnorm > 1.) { |
517 | 0 | if (bnorm > bignum * smini) { |
518 | 0 | *scale = 1. / bnorm; |
519 | 0 | } |
520 | 0 | } |
521 | 0 | temp = *scale / smini; |
522 | 0 | x[x_dim1 + 1] = temp * b[b_dim1 + 1]; |
523 | 0 | x[x_dim1 + 2] = temp * b[b_dim1 + 2]; |
524 | 0 | x[(x_dim1 << 1) + 1] = temp * b[(b_dim1 << 1) + 1]; |
525 | 0 | x[(x_dim1 << 1) + 2] = temp * b[(b_dim1 << 1) + 2]; |
526 | 0 | *xnorm = temp * bnorm; |
527 | 0 | *info = 1; |
528 | 0 | return 0; |
529 | 0 | } |
530 | | |
531 | | /* Gaussian elimination with complete pivoting. */ |
532 | | |
533 | 0 | ur11 = crv[icmax - 1]; |
534 | 0 | ui11 = civ[icmax - 1]; |
535 | 0 | cr21 = crv[ipivot[(icmax << 2) - 3] - 1]; |
536 | 0 | ci21 = civ[ipivot[(icmax << 2) - 3] - 1]; |
537 | 0 | ur12 = crv[ipivot[(icmax << 2) - 2] - 1]; |
538 | 0 | ui12 = civ[ipivot[(icmax << 2) - 2] - 1]; |
539 | 0 | cr22 = crv[ipivot[(icmax << 2) - 1] - 1]; |
540 | 0 | ci22 = civ[ipivot[(icmax << 2) - 1] - 1]; |
541 | 0 | if (icmax == 1 || icmax == 4) { |
542 | | |
543 | | /* Code when off-diagonals of pivoted C are real */ |
544 | |
|
545 | 0 | if (abs(ur11) > abs(ui11)) { |
546 | 0 | temp = ui11 / ur11; |
547 | | /* Computing 2nd power */ |
548 | 0 | d__1 = temp; |
549 | 0 | ur11r = 1. / (ur11 * (d__1 * d__1 + 1.)); |
550 | 0 | ui11r = -temp * ur11r; |
551 | 0 | } else { |
552 | 0 | temp = ur11 / ui11; |
553 | | /* Computing 2nd power */ |
554 | 0 | d__1 = temp; |
555 | 0 | ui11r = -1. / (ui11 * (d__1 * d__1 + 1.)); |
556 | 0 | ur11r = -temp * ui11r; |
557 | 0 | } |
558 | 0 | lr21 = cr21 * ur11r; |
559 | 0 | li21 = cr21 * ui11r; |
560 | 0 | ur12s = ur12 * ur11r; |
561 | 0 | ui12s = ur12 * ui11r; |
562 | 0 | ur22 = cr22 - ur12 * lr21; |
563 | 0 | ui22 = ci22 - ur12 * li21; |
564 | 0 | } else { |
565 | | |
566 | | /* Code when diagonals of pivoted C are real */ |
567 | |
|
568 | 0 | ur11r = 1. / ur11; |
569 | 0 | ui11r = 0.; |
570 | 0 | lr21 = cr21 * ur11r; |
571 | 0 | li21 = ci21 * ur11r; |
572 | 0 | ur12s = ur12 * ur11r; |
573 | 0 | ui12s = ui12 * ur11r; |
574 | 0 | ur22 = cr22 - ur12 * lr21 + ui12 * li21; |
575 | 0 | ui22 = -ur12 * li21 - ui12 * lr21; |
576 | 0 | } |
577 | 0 | u22abs = abs(ur22) + abs(ui22); |
578 | | |
579 | | /* If smaller pivot < SMINI, use SMINI */ |
580 | |
|
581 | 0 | if (u22abs < smini) { |
582 | 0 | ur22 = smini; |
583 | 0 | ui22 = 0.; |
584 | 0 | *info = 1; |
585 | 0 | } |
586 | 0 | if (rswap[icmax - 1]) { |
587 | 0 | br2 = b[b_dim1 + 1]; |
588 | 0 | br1 = b[b_dim1 + 2]; |
589 | 0 | bi2 = b[(b_dim1 << 1) + 1]; |
590 | 0 | bi1 = b[(b_dim1 << 1) + 2]; |
591 | 0 | } else { |
592 | 0 | br1 = b[b_dim1 + 1]; |
593 | 0 | br2 = b[b_dim1 + 2]; |
594 | 0 | bi1 = b[(b_dim1 << 1) + 1]; |
595 | 0 | bi2 = b[(b_dim1 << 1) + 2]; |
596 | 0 | } |
597 | 0 | br2 = br2 - lr21 * br1 + li21 * bi1; |
598 | 0 | bi2 = bi2 - li21 * br1 - lr21 * bi1; |
599 | | /* Computing MAX */ |
600 | 0 | d__1 = (abs(br1) + abs(bi1)) * (u22abs * (abs(ur11r) + abs(ui11r)) |
601 | 0 | ), d__2 = abs(br2) + abs(bi2); |
602 | 0 | bbnd = max(d__1,d__2); |
603 | 0 | if (bbnd > 1. && u22abs < 1.) { |
604 | 0 | if (bbnd >= bignum * u22abs) { |
605 | 0 | *scale = 1. / bbnd; |
606 | 0 | br1 = *scale * br1; |
607 | 0 | bi1 = *scale * bi1; |
608 | 0 | br2 = *scale * br2; |
609 | 0 | bi2 = *scale * bi2; |
610 | 0 | } |
611 | 0 | } |
612 | |
|
613 | 0 | igraphdladiv_(&br2, &bi2, &ur22, &ui22, &xr2, &xi2); |
614 | 0 | xr1 = ur11r * br1 - ui11r * bi1 - ur12s * xr2 + ui12s * xi2; |
615 | 0 | xi1 = ui11r * br1 + ur11r * bi1 - ui12s * xr2 - ur12s * xi2; |
616 | 0 | if (zswap[icmax - 1]) { |
617 | 0 | x[x_dim1 + 1] = xr2; |
618 | 0 | x[x_dim1 + 2] = xr1; |
619 | 0 | x[(x_dim1 << 1) + 1] = xi2; |
620 | 0 | x[(x_dim1 << 1) + 2] = xi1; |
621 | 0 | } else { |
622 | 0 | x[x_dim1 + 1] = xr1; |
623 | 0 | x[x_dim1 + 2] = xr2; |
624 | 0 | x[(x_dim1 << 1) + 1] = xi1; |
625 | 0 | x[(x_dim1 << 1) + 2] = xi2; |
626 | 0 | } |
627 | | /* Computing MAX */ |
628 | 0 | d__1 = abs(xr1) + abs(xi1), d__2 = abs(xr2) + abs(xi2); |
629 | 0 | *xnorm = max(d__1,d__2); |
630 | | |
631 | | /* Further scaling if norm(A) norm(X) > overflow */ |
632 | |
|
633 | 0 | if (*xnorm > 1. && cmax > 1.) { |
634 | 0 | if (*xnorm > bignum / cmax) { |
635 | 0 | temp = cmax / bignum; |
636 | 0 | x[x_dim1 + 1] = temp * x[x_dim1 + 1]; |
637 | 0 | x[x_dim1 + 2] = temp * x[x_dim1 + 2]; |
638 | 0 | x[(x_dim1 << 1) + 1] = temp * x[(x_dim1 << 1) + 1]; |
639 | 0 | x[(x_dim1 << 1) + 2] = temp * x[(x_dim1 << 1) + 2]; |
640 | 0 | *xnorm = temp * *xnorm; |
641 | 0 | *scale = temp * *scale; |
642 | 0 | } |
643 | 0 | } |
644 | 0 | } |
645 | 0 | } |
646 | | |
647 | 0 | return 0; |
648 | | |
649 | | /* End of DLALN2 */ |
650 | |
|
651 | 0 | } /* igraphdlaln2_ */ |
652 | | |
653 | | #undef crv |
654 | | #undef civ |
655 | | #undef cr |
656 | | #undef ci |
657 | | |
658 | | |