1: #region Translated by Jose Antonio De Santiago-Castillo.
2:
3: //Translated by Jose Antonio De Santiago-Castillo.
4: //E-mail:JAntonioDeSantiago@gmail.com
5: //Web: www.DotNumerics.com
6: //
7: //Fortran to C# Translation.
8: //Translated by:
9: //F2CSharp Version 0.71 (November 10, 2009)
10: //Code Optimizations: None
11: //
12: #endregion
13:
14: using System;
15: using DotNumerics.FortranLibrary;
16:
17: namespace DotNumerics.CSLapack
18: {
19: /// <summary>
20: /// -- LAPACK auxiliary routine (version 3.1) --
21: /// Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
22: /// November 2006
23: /// Purpose
24: /// =======
25: ///
26: /// DLASDQ computes the singular value decomposition (SVD) of a real
27: /// (upper or lower) bidiagonal matrix with diagonal D and offdiagonal
28: /// E, accumulating the transformations if desired. Letting B denote
29: /// the input bidiagonal matrix, the algorithm computes orthogonal
30: /// matrices Q and P such that B = Q * S * P' (P' denotes the transpose
31: /// of P). The singular values S are overwritten on D.
32: ///
33: /// The input matrix U is changed to U * Q if desired.
34: /// The input matrix VT is changed to P' * VT if desired.
35: /// The input matrix C is changed to Q' * C if desired.
36: ///
37: /// See "Computing Small Singular Values of Bidiagonal Matrices With
38: /// Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
39: /// LAPACK Working Note #3, for a detailed description of the algorithm.
40: ///
41: ///</summary>
42: public class DLASDQ
43: {
44:
45:
46: #region Dependencies
47:
48: DBDSQR _dbdsqr; DLARTG _dlartg; DLASR _dlasr; DSWAP _dswap; XERBLA _xerbla; LSAME _lsame;
49:
50: #endregion
51:
52:
53: #region Fields
54:
55: const double ZERO = 0.0E+0; bool ROTATE = false; int I = 0; int ISUB = 0; int IUPLO = 0; int J = 0; int NP1 = 0;
56: int SQRE1 = 0;double CS = 0; double R = 0; double SMIN = 0; double SN = 0;
57:
58: #endregion
59:
60: public DLASDQ(DBDSQR dbdsqr, DLARTG dlartg, DLASR dlasr, DSWAP dswap, XERBLA xerbla, LSAME lsame)
61: {
62:
63:
64: #region Set Dependencies
65:
66: this._dbdsqr = dbdsqr; this._dlartg = dlartg; this._dlasr = dlasr; this._dswap = dswap; this._xerbla = xerbla;
67: this._lsame = lsame;
68:
69: #endregion
70:
71: }
72:
73: public DLASDQ()
74: {
75:
76:
77: #region Dependencies (Initialization)
78:
79: LSAME lsame = new LSAME();
80: DLAMC3 dlamc3 = new DLAMC3();
81: DLAS2 dlas2 = new DLAS2();
82: DCOPY dcopy = new DCOPY();
83: XERBLA xerbla = new XERBLA();
84: DLASQ5 dlasq5 = new DLASQ5();
85: DLAZQ4 dlazq4 = new DLAZQ4();
86: IEEECK ieeeck = new IEEECK();
87: IPARMQ iparmq = new IPARMQ();
88: DROT drot = new DROT();
89: DSCAL dscal = new DSCAL();
90: DSWAP dswap = new DSWAP();
91: DLAMC1 dlamc1 = new DLAMC1(dlamc3);
92: DLAMC4 dlamc4 = new DLAMC4(dlamc3);
93: DLAMC5 dlamc5 = new DLAMC5(dlamc3);
94: DLAMC2 dlamc2 = new DLAMC2(dlamc3, dlamc1, dlamc4, dlamc5);
95: DLAMCH dlamch = new DLAMCH(lsame, dlamc2);
96: DLARTG dlartg = new DLARTG(dlamch);
97: DLASCL dlascl = new DLASCL(lsame, dlamch, xerbla);
98: DLASQ6 dlasq6 = new DLASQ6(dlamch);
99: DLAZQ3 dlazq3 = new DLAZQ3(dlasq5, dlasq6, dlazq4, dlamch);
100: DLASRT dlasrt = new DLASRT(lsame, xerbla);
101: ILAENV ilaenv = new ILAENV(ieeeck, iparmq);
102: DLASQ2 dlasq2 = new DLASQ2(dlazq3, dlasrt, xerbla, dlamch, ilaenv);
103: DLASQ1 dlasq1 = new DLASQ1(dcopy, dlas2, dlascl, dlasq2, dlasrt, xerbla, dlamch);
104: DLASR dlasr = new DLASR(lsame, xerbla);
105: DLASV2 dlasv2 = new DLASV2(dlamch);
106: DBDSQR dbdsqr = new DBDSQR(lsame, dlamch, dlartg, dlas2, dlasq1, dlasr, dlasv2, drot, dscal, dswap
107: , xerbla);
108:
109: #endregion
110:
111:
112: #region Set Dependencies
113:
114: this._dbdsqr = dbdsqr; this._dlartg = dlartg; this._dlasr = dlasr; this._dswap = dswap; this._xerbla = xerbla;
115: this._lsame = lsame;
116:
117: #endregion
118:
119: }
120: /// <summary>
121: /// Purpose
122: /// =======
123: ///
124: /// DLASDQ computes the singular value decomposition (SVD) of a real
125: /// (upper or lower) bidiagonal matrix with diagonal D and offdiagonal
126: /// E, accumulating the transformations if desired. Letting B denote
127: /// the input bidiagonal matrix, the algorithm computes orthogonal
128: /// matrices Q and P such that B = Q * S * P' (P' denotes the transpose
129: /// of P). The singular values S are overwritten on D.
130: ///
131: /// The input matrix U is changed to U * Q if desired.
132: /// The input matrix VT is changed to P' * VT if desired.
133: /// The input matrix C is changed to Q' * C if desired.
134: ///
135: /// See "Computing Small Singular Values of Bidiagonal Matrices With
136: /// Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
137: /// LAPACK Working Note #3, for a detailed description of the algorithm.
138: ///
139: ///</summary>
140: /// <param name="UPLO">
141: /// (input) CHARACTER*1
142: /// On entry, UPLO specifies whether the input bidiagonal matrix
143: /// is upper or lower bidiagonal, and wether it is square are
144: /// not.
145: /// UPLO = 'U' or 'u' B is upper bidiagonal.
146: /// UPLO = 'L' or 'l' B is lower bidiagonal.
147: ///</param>
148: /// <param name="SQRE">
149: /// (input) INTEGER
150: /// = 0: then the input matrix is N-by-N.
151: /// = 1: then the input matrix is N-by-(N+1) if UPLU = 'U' and
152: /// (N+1)-by-N if UPLU = 'L'.
153: ///
154: /// The bidiagonal matrix has
155: /// N = NL + NR + 1 rows and
156: /// M = N + SQRE .GE. N columns.
157: ///</param>
158: /// <param name="N">
159: /// (input) INTEGER
160: /// On entry, N specifies the number of rows and columns
161: /// in the matrix. N must be at least 0.
162: ///</param>
163: /// <param name="NCVT">
164: /// (input) INTEGER
165: /// On entry, NCVT specifies the number of columns of
166: /// the matrix VT. NCVT must be at least 0.
167: ///</param>
168: /// <param name="NRU">
169: /// (input) INTEGER
170: /// On entry, NRU specifies the number of rows of
171: /// the matrix U. NRU must be at least 0.
172: ///</param>
173: /// <param name="NCC">
174: /// (input) INTEGER
175: /// On entry, NCC specifies the number of columns of
176: /// the matrix C. NCC must be at least 0.
177: ///</param>
178: /// <param name="D">
179: /// (input/output) DOUBLE PRECISION array, dimension (N)
180: /// On entry, D contains the diagonal entries of the
181: /// bidiagonal matrix whose SVD is desired. On normal exit,
182: /// D contains the singular values in ascending order.
183: ///</param>
184: /// <param name="E">
185: /// (input/output) DOUBLE PRECISION array.
186: /// dimension is (N-1) if SQRE = 0 and N if SQRE = 1.
187: /// On entry, the entries of E contain the offdiagonal entries
188: /// of the bidiagonal matrix whose SVD is desired. On normal
189: /// exit, E will contain 0. If the algorithm does not converge,
190: /// D and E will contain the diagonal and superdiagonal entries
191: /// of a bidiagonal matrix orthogonally equivalent to the one
192: /// given as input.
193: ///</param>
194: /// <param name="VT">
195: /// (input/output) DOUBLE PRECISION array, dimension (LDVT, NCVT)
196: /// On entry, contains a matrix which on exit has been
197: /// premultiplied by P', dimension N-by-NCVT if SQRE = 0
198: /// and (N+1)-by-NCVT if SQRE = 1 (not referenced if NCVT=0).
199: ///</param>
200: /// <param name="LDVT">
201: /// (input) INTEGER
202: /// On entry, LDVT specifies the leading dimension of VT as
203: /// declared in the calling (sub) program. LDVT must be at
204: /// least 1. If NCVT is nonzero LDVT must also be at least N.
205: ///</param>
206: /// <param name="U">
207: /// (input/output) DOUBLE PRECISION array, dimension (LDU, N)
208: /// On entry, contains a matrix which on exit has been
209: /// postmultiplied by Q, dimension NRU-by-N if SQRE = 0
210: /// and NRU-by-(N+1) if SQRE = 1 (not referenced if NRU=0).
211: ///</param>
212: /// <param name="LDU">
213: /// (input) INTEGER
214: /// On entry, LDU specifies the leading dimension of U as
215: /// declared in the calling (sub) program. LDU must be at
216: /// least max( 1, NRU ) .
217: ///</param>
218: /// <param name="C">
219: /// (input/output) DOUBLE PRECISION array, dimension (LDC, NCC)
220: /// On entry, contains an N-by-NCC matrix which on exit
221: /// has been premultiplied by Q' dimension N-by-NCC if SQRE = 0
222: /// and (N+1)-by-NCC if SQRE = 1 (not referenced if NCC=0).
223: ///</param>
224: /// <param name="LDC">
225: /// (input) INTEGER
226: /// On entry, LDC specifies the leading dimension of C as
227: /// declared in the calling (sub) program. LDC must be at
228: /// least 1. If NCC is nonzero, LDC must also be at least N.
229: ///</param>
230: /// <param name="WORK">
231: /// (workspace) DOUBLE PRECISION array, dimension (4*N)
232: /// Workspace. Only referenced if one of NCVT, NRU, or NCC is
233: /// nonzero, and if N is at least 2.
234: ///</param>
235: /// <param name="INFO">
236: /// (output) INTEGER
237: /// On exit, a value of 0 indicates a successful exit.
238: /// If INFO .LT. 0, argument number -INFO is illegal.
239: /// If INFO .GT. 0, the algorithm did not converge, and INFO
240: /// specifies how many superdiagonals did not converge.
241: ///</param>
242: public void Run(string UPLO, int SQRE, int N, int NCVT, int NRU, int NCC
243: , ref double[] D, int offset_d, ref double[] E, int offset_e, ref double[] VT, int offset_vt, int LDVT, ref double[] U, int offset_u, int LDU
244: , ref double[] C, int offset_c, int LDC, ref double[] WORK, int offset_work, ref int INFO)
245: {
246:
247: #region Array Index Correction
248:
249: int o_d = -1 + offset_d; int o_e = -1 + offset_e; int o_vt = -1 - LDVT + offset_vt; int o_u = -1 - LDU + offset_u;
250: int o_c = -1 - LDC + offset_c; int o_work = -1 + offset_work;
251:
252: #endregion
253:
254:
255: #region Strings
256:
257: UPLO = UPLO.Substring(0, 1);
258:
259: #endregion
260:
261:
262: #region Prolog
263:
264: // *
265: // * -- LAPACK auxiliary routine (version 3.1) --
266: // * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
267: // * November 2006
268: // *
269: // * .. Scalar Arguments ..
270: // * ..
271: // * .. Array Arguments ..
272: // * ..
273: // *
274: // * Purpose
275: // * =======
276: // *
277: // * DLASDQ computes the singular value decomposition (SVD) of a real
278: // * (upper or lower) bidiagonal matrix with diagonal D and offdiagonal
279: // * E, accumulating the transformations if desired. Letting B denote
280: // * the input bidiagonal matrix, the algorithm computes orthogonal
281: // * matrices Q and P such that B = Q * S * P' (P' denotes the transpose
282: // * of P). The singular values S are overwritten on D.
283: // *
284: // * The input matrix U is changed to U * Q if desired.
285: // * The input matrix VT is changed to P' * VT if desired.
286: // * The input matrix C is changed to Q' * C if desired.
287: // *
288: // * See "Computing Small Singular Values of Bidiagonal Matrices With
289: // * Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
290: // * LAPACK Working Note #3, for a detailed description of the algorithm.
291: // *
292: // * Arguments
293: // * =========
294: // *
295: // * UPLO (input) CHARACTER*1
296: // * On entry, UPLO specifies whether the input bidiagonal matrix
297: // * is upper or lower bidiagonal, and wether it is square are
298: // * not.
299: // * UPLO = 'U' or 'u' B is upper bidiagonal.
300: // * UPLO = 'L' or 'l' B is lower bidiagonal.
301: // *
302: // * SQRE (input) INTEGER
303: // * = 0: then the input matrix is N-by-N.
304: // * = 1: then the input matrix is N-by-(N+1) if UPLU = 'U' and
305: // * (N+1)-by-N if UPLU = 'L'.
306: // *
307: // * The bidiagonal matrix has
308: // * N = NL + NR + 1 rows and
309: // * M = N + SQRE >= N columns.
310: // *
311: // * N (input) INTEGER
312: // * On entry, N specifies the number of rows and columns
313: // * in the matrix. N must be at least 0.
314: // *
315: // * NCVT (input) INTEGER
316: // * On entry, NCVT specifies the number of columns of
317: // * the matrix VT. NCVT must be at least 0.
318: // *
319: // * NRU (input) INTEGER
320: // * On entry, NRU specifies the number of rows of
321: // * the matrix U. NRU must be at least 0.
322: // *
323: // * NCC (input) INTEGER
324: // * On entry, NCC specifies the number of columns of
325: // * the matrix C. NCC must be at least 0.
326: // *
327: // * D (input/output) DOUBLE PRECISION array, dimension (N)
328: // * On entry, D contains the diagonal entries of the
329: // * bidiagonal matrix whose SVD is desired. On normal exit,
330: // * D contains the singular values in ascending order.
331: // *
332: // * E (input/output) DOUBLE PRECISION array.
333: // * dimension is (N-1) if SQRE = 0 and N if SQRE = 1.
334: // * On entry, the entries of E contain the offdiagonal entries
335: // * of the bidiagonal matrix whose SVD is desired. On normal
336: // * exit, E will contain 0. If the algorithm does not converge,
337: // * D and E will contain the diagonal and superdiagonal entries
338: // * of a bidiagonal matrix orthogonally equivalent to the one
339: // * given as input.
340: // *
341: // * VT (input/output) DOUBLE PRECISION array, dimension (LDVT, NCVT)
342: // * On entry, contains a matrix which on exit has been
343: // * premultiplied by P', dimension N-by-NCVT if SQRE = 0
344: // * and (N+1)-by-NCVT if SQRE = 1 (not referenced if NCVT=0).
345: // *
346: // * LDVT (input) INTEGER
347: // * On entry, LDVT specifies the leading dimension of VT as
348: // * declared in the calling (sub) program. LDVT must be at
349: // * least 1. If NCVT is nonzero LDVT must also be at least N.
350: // *
351: // * U (input/output) DOUBLE PRECISION array, dimension (LDU, N)
352: // * On entry, contains a matrix which on exit has been
353: // * postmultiplied by Q, dimension NRU-by-N if SQRE = 0
354: // * and NRU-by-(N+1) if SQRE = 1 (not referenced if NRU=0).
355: // *
356: // * LDU (input) INTEGER
357: // * On entry, LDU specifies the leading dimension of U as
358: // * declared in the calling (sub) program. LDU must be at
359: // * least max( 1, NRU ) .
360: // *
361: // * C (input/output) DOUBLE PRECISION array, dimension (LDC, NCC)
362: // * On entry, contains an N-by-NCC matrix which on exit
363: // * has been premultiplied by Q' dimension N-by-NCC if SQRE = 0
364: // * and (N+1)-by-NCC if SQRE = 1 (not referenced if NCC=0).
365: // *
366: // * LDC (input) INTEGER
367: // * On entry, LDC specifies the leading dimension of C as
368: // * declared in the calling (sub) program. LDC must be at
369: // * least 1. If NCC is nonzero, LDC must also be at least N.
370: // *
371: // * WORK (workspace) DOUBLE PRECISION array, dimension (4*N)
372: // * Workspace. Only referenced if one of NCVT, NRU, or NCC is
373: // * nonzero, and if N is at least 2.
374: // *
375: // * INFO (output) INTEGER
376: // * On exit, a value of 0 indicates a successful exit.
377: // * If INFO < 0, argument number -INFO is illegal.
378: // * If INFO > 0, the algorithm did not converge, and INFO
379: // * specifies how many superdiagonals did not converge.
380: // *
381: // * Further Details
382: // * ===============
383: // *
384: // * Based on contributions by
385: // * Ming Gu and Huan Ren, Computer Science Division, University of
386: // * California at Berkeley, USA
387: // *
388: // * =====================================================================
389: // *
390: // * .. Parameters ..
391: // * ..
392: // * .. Local Scalars ..
393: // * ..
394: // * .. External Subroutines ..
395: // * ..
396: // * .. External Functions ..
397: // * ..
398: // * .. Intrinsic Functions ..
399: // INTRINSIC MAX;
400: // * ..
401: // * .. Executable Statements ..
402: // *
403: // * Test the input parameters.
404: // *
405:
406: #endregion
407:
408:
409: #region Body
410:
411: INFO = 0;
412: IUPLO = 0;
413: if (this._lsame.Run(UPLO, "U")) IUPLO = 1;
414: if (this._lsame.Run(UPLO, "L")) IUPLO = 2;
415: if (IUPLO == 0)
416: {
417: INFO = - 1;
418: }
419: else
420: {
421: if ((SQRE < 0) || (SQRE > 1))
422: {
423: INFO = - 2;
424: }
425: else
426: {
427: if (N < 0)
428: {
429: INFO = - 3;
430: }
431: else
432: {
433: if (NCVT < 0)
434: {
435: INFO = - 4;
436: }
437: else
438: {
439: if (NRU < 0)
440: {
441: INFO = - 5;
442: }
443: else
444: {
445: if (NCC < 0)
446: {
447: INFO = - 6;
448: }
449: else
450: {
451: if ((NCVT == 0 && LDVT < 1) || (NCVT > 0 && LDVT < Math.Max(1, N)))
452: {
453: INFO = - 10;
454: }
455: else
456: {
457: if (LDU < Math.Max(1, NRU))
458: {
459: INFO = - 12;
460: }
461: else
462: {
463: if ((NCC == 0 && LDC < 1) || (NCC > 0 && LDC < Math.Max(1, N)))
464: {
465: INFO = - 14;
466: }
467: }
468: }
469: }
470: }
471: }
472: }
473: }
474: }
475: if (INFO != 0)
476: {
477: this._xerbla.Run("DLASDQ", - INFO);
478: return;
479: }
480: if (N == 0) return;
481: // *
482: // * ROTATE is true if any singular vectors desired, false otherwise
483: // *
484: ROTATE = (NCVT > 0) || (NRU > 0) || (NCC > 0);
485: NP1 = N + 1;
486: SQRE1 = SQRE;
487: // *
488: // * If matrix non-square upper bidiagonal, rotate to be lower
489: // * bidiagonal. The rotations are on the right.
490: // *
491: if ((IUPLO == 1) && (SQRE1 == 1))
492: {
493: for (I = 1; I <= N - 1; I++)
494: {
495: this._dlartg.Run(D[I + o_d], E[I + o_e], ref CS, ref SN, ref R);
496: D[I + o_d] = R;
497: E[I + o_e] = SN * D[I + 1 + o_d];
498: D[I + 1 + o_d] = CS * D[I + 1 + o_d];
499: if (ROTATE)
500: {
501: WORK[I + o_work] = CS;
502: WORK[N + I + o_work] = SN;
503: }
504: }
505: this._dlartg.Run(D[N + o_d], E[N + o_e], ref CS, ref SN, ref R);
506: D[N + o_d] = R;
507: E[N + o_e] = ZERO;
508: if (ROTATE)
509: {
510: WORK[N + o_work] = CS;
511: WORK[N + N + o_work] = SN;
512: }
513: IUPLO = 2;
514: SQRE1 = 0;
515: // *
516: // * Update singular vectors if desired.
517: // *
518: if (NCVT > 0)
519: {
520: this._dlasr.Run("L", "V", "F", NP1, NCVT, WORK, 1 + o_work
521: , WORK, NP1 + o_work, ref VT, offset_vt, LDVT);
522: }
523: }
524: // *
525: // * If matrix lower bidiagonal, rotate to be upper bidiagonal
526: // * by applying Givens rotations on the left.
527: // *
528: if (IUPLO == 2)
529: {
530: for (I = 1; I <= N - 1; I++)
531: {
532: this._dlartg.Run(D[I + o_d], E[I + o_e], ref CS, ref SN, ref R);
533: D[I + o_d] = R;
534: E[I + o_e] = SN * D[I + 1 + o_d];
535: D[I + 1 + o_d] = CS * D[I + 1 + o_d];
536: if (ROTATE)
537: {
538: WORK[I + o_work] = CS;
539: WORK[N + I + o_work] = SN;
540: }
541: }
542: // *
543: // * If matrix (N+1)-by-N lower bidiagonal, one additional
544: // * rotation is needed.
545: // *
546: if (SQRE1 == 1)
547: {
548: this._dlartg.Run(D[N + o_d], E[N + o_e], ref CS, ref SN, ref R);
549: D[N + o_d] = R;
550: if (ROTATE)
551: {
552: WORK[N + o_work] = CS;
553: WORK[N + N + o_work] = SN;
554: }
555: }
556: // *
557: // * Update singular vectors if desired.
558: // *
559: if (NRU > 0)
560: {
561: if (SQRE1 == 0)
562: {
563: this._dlasr.Run("R", "V", "F", NRU, N, WORK, 1 + o_work
564: , WORK, NP1 + o_work, ref U, offset_u, LDU);
565: }
566: else
567: {
568: this._dlasr.Run("R", "V", "F", NRU, NP1, WORK, 1 + o_work
569: , WORK, NP1 + o_work, ref U, offset_u, LDU);
570: }
571: }
572: if (NCC > 0)
573: {
574: if (SQRE1 == 0)
575: {
576: this._dlasr.Run("L", "V", "F", N, NCC, WORK, 1 + o_work
577: , WORK, NP1 + o_work, ref C, offset_c, LDC);
578: }
579: else
580: {
581: this._dlasr.Run("L", "V", "F", NP1, NCC, WORK, 1 + o_work
582: , WORK, NP1 + o_work, ref C, offset_c, LDC);
583: }
584: }
585: }
586: // *
587: // * Call DBDSQR to compute the SVD of the reduced real
588: // * N-by-N upper bidiagonal matrix.
589: // *
590: this._dbdsqr.Run("U", N, NCVT, NRU, NCC, ref D, offset_d
591: , ref E, offset_e, ref VT, offset_vt, LDVT, ref U, offset_u, LDU, ref C, offset_c
592: , LDC, ref WORK, offset_work, ref INFO);
593: // *
594: // * Sort the singular values into ascending order (insertion sort on
595: // * singular values, but only one transposition per singular vector)
596: // *
597: for (I = 1; I <= N; I++)
598: {
599: // *
600: // * Scan for smallest D(I).
601: // *
602: ISUB = I;
603: SMIN = D[I + o_d];
604: for (J = I + 1; J <= N; J++)
605: {
606: if (D[J + o_d] < SMIN)
607: {
608: ISUB = J;
609: SMIN = D[J + o_d];
610: }
611: }
612: if (ISUB != I)
613: {
614: // *
615: // * Swap singular values and vectors.
616: // *
617: D[ISUB + o_d] = D[I + o_d];
618: D[I + o_d] = SMIN;
619: if (NCVT > 0) this._dswap.Run(NCVT, ref VT, ISUB+1 * LDVT + o_vt, LDVT, ref VT, I+1 * LDVT + o_vt, LDVT);
620: if (NRU > 0) this._dswap.Run(NRU, ref U, 1+ISUB * LDU + o_u, 1, ref U, 1+I * LDU + o_u, 1);
621: if (NCC > 0) this._dswap.Run(NCC, ref C, ISUB+1 * LDC + o_c, LDC, ref C, I+1 * LDC + o_c, LDC);
622: }
623: }
624: // *
625: return;
626: // *
627: // * End of DLASDQ
628: // *
629:
630: #endregion
631:
632: }
633: }
634: }