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: /// DLARTG generate a plane rotation so that
27: ///
28: /// [ CS SN ] . [ F ] = [ R ] where CS**2 + SN**2 = 1.
29: /// [ -SN CS ] [ G ] [ 0 ]
30: ///
31: /// This is a slower, more accurate version of the BLAS1 routine DROTG,
32: /// with the following other differences:
33: /// F and G are unchanged on return.
34: /// If G=0, then CS=1 and SN=0.
35: /// If F=0 and (G .ne. 0), then CS=0 and SN=1 without doing any
36: /// floating point operations (saves work in DBDSQR when
37: /// there are zeros on the diagonal).
38: ///
39: /// If F exceeds G in magnitude, CS will be positive.
40: ///
41: ///</summary>
42: public class DLARTG
43: {
44:
45:
46: #region Dependencies
47:
48: DLAMCH _dlamch;
49:
50: #endregion
51:
52:
53: #region Fields
54:
55: const double ZERO = 0.0E0; const double ONE = 1.0E0; const double TWO = 2.0E0; int COUNT = 0; int I = 0; double EPS = 0;
56: double F1 = 0;double G1 = 0; double SAFMIN = 0; double SAFMN2 = 0; double SAFMX2 = 0; double SCALE = 0;
57:
58: #endregion
59:
60: public DLARTG(DLAMCH dlamch)
61: {
62:
63:
64: #region Set Dependencies
65:
66: this._dlamch = dlamch;
67:
68: #endregion
69:
70: }
71:
72: public DLARTG()
73: {
74:
75:
76: #region Dependencies (Initialization)
77:
78: LSAME lsame = new LSAME();
79: DLAMC3 dlamc3 = new DLAMC3();
80: DLAMC1 dlamc1 = new DLAMC1(dlamc3);
81: DLAMC4 dlamc4 = new DLAMC4(dlamc3);
82: DLAMC5 dlamc5 = new DLAMC5(dlamc3);
83: DLAMC2 dlamc2 = new DLAMC2(dlamc3, dlamc1, dlamc4, dlamc5);
84: DLAMCH dlamch = new DLAMCH(lsame, dlamc2);
85:
86: #endregion
87:
88:
89: #region Set Dependencies
90:
91: this._dlamch = dlamch;
92:
93: #endregion
94:
95: }
96: /// <summary>
97: /// Purpose
98: /// =======
99: ///
100: /// DLARTG generate a plane rotation so that
101: ///
102: /// [ CS SN ] . [ F ] = [ R ] where CS**2 + SN**2 = 1.
103: /// [ -SN CS ] [ G ] [ 0 ]
104: ///
105: /// This is a slower, more accurate version of the BLAS1 routine DROTG,
106: /// with the following other differences:
107: /// F and G are unchanged on return.
108: /// If G=0, then CS=1 and SN=0.
109: /// If F=0 and (G .ne. 0), then CS=0 and SN=1 without doing any
110: /// floating point operations (saves work in DBDSQR when
111: /// there are zeros on the diagonal).
112: ///
113: /// If F exceeds G in magnitude, CS will be positive.
114: ///
115: ///</summary>
116: /// <param name="F">
117: /// (input) DOUBLE PRECISION
118: /// The first component of vector to be rotated.
119: ///</param>
120: /// <param name="G">
121: /// (input) DOUBLE PRECISION
122: /// The second component of vector to be rotated.
123: ///</param>
124: /// <param name="CS">
125: /// (output) DOUBLE PRECISION
126: /// The cosine of the rotation.
127: ///</param>
128: /// <param name="SN">
129: /// (output) DOUBLE PRECISION
130: /// The sine of the rotation.
131: ///</param>
132: /// <param name="R">
133: /// (output) DOUBLE PRECISION
134: /// The nonzero component of the rotated vector.
135: ///</param>
136: public void Run(double F, double G, ref double CS, ref double SN, ref double R)
137: {
138:
139: #region Prolog
140:
141: // *
142: // * -- LAPACK auxiliary routine (version 3.1) --
143: // * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
144: // * November 2006
145: // *
146: // * .. Scalar Arguments ..
147: // * ..
148: // *
149: // * Purpose
150: // * =======
151: // *
152: // * DLARTG generate a plane rotation so that
153: // *
154: // * [ CS SN ] . [ F ] = [ R ] where CS**2 + SN**2 = 1.
155: // * [ -SN CS ] [ G ] [ 0 ]
156: // *
157: // * This is a slower, more accurate version of the BLAS1 routine DROTG,
158: // * with the following other differences:
159: // * F and G are unchanged on return.
160: // * If G=0, then CS=1 and SN=0.
161: // * If F=0 and (G .ne. 0), then CS=0 and SN=1 without doing any
162: // * floating point operations (saves work in DBDSQR when
163: // * there are zeros on the diagonal).
164: // *
165: // * If F exceeds G in magnitude, CS will be positive.
166: // *
167: // * Arguments
168: // * =========
169: // *
170: // * F (input) DOUBLE PRECISION
171: // * The first component of vector to be rotated.
172: // *
173: // * G (input) DOUBLE PRECISION
174: // * The second component of vector to be rotated.
175: // *
176: // * CS (output) DOUBLE PRECISION
177: // * The cosine of the rotation.
178: // *
179: // * SN (output) DOUBLE PRECISION
180: // * The sine of the rotation.
181: // *
182: // * R (output) DOUBLE PRECISION
183: // * The nonzero component of the rotated vector.
184: // *
185: // * This version has a few statements commented out for thread safety
186: // * (machine parameters are computed on each entry). 10 feb 03, SJH.
187: // *
188: // * =====================================================================
189: // *
190: // * .. Parameters ..
191: // * ..
192: // * .. Local Scalars ..
193: // * LOGICAL FIRST
194: // * ..
195: // * .. External Functions ..
196: // * ..
197: // * .. Intrinsic Functions ..
198: // INTRINSIC ABS, INT, LOG, MAX, SQRT;
199: // * ..
200: // * .. Save statement ..
201: // * SAVE FIRST, SAFMX2, SAFMIN, SAFMN2
202: // * ..
203: // * .. Data statements ..
204: // * DATA FIRST / .TRUE. /
205: // * ..
206: // * .. Executable Statements ..
207: // *
208: // * IF( FIRST ) THEN
209:
210: #endregion
211:
212:
213: #region Body
214:
215: SAFMIN = this._dlamch.Run("S");
216: EPS = this._dlamch.Run("E");
217: SAFMN2 = Math.Pow(this._dlamch.Run("B"),Convert.ToInt32(Math.Truncate(Math.Log(SAFMIN / EPS) / Math.Log(this._dlamch.Run("B")) / TWO)));
218: SAFMX2 = ONE / SAFMN2;
219: // * FIRST = .FALSE.
220: // * END IF
221: if (G == ZERO)
222: {
223: CS = ONE;
224: SN = ZERO;
225: R = F;
226: }
227: else
228: {
229: if (F == ZERO)
230: {
231: CS = ZERO;
232: SN = ONE;
233: R = G;
234: }
235: else
236: {
237: F1 = F;
238: G1 = G;
239: SCALE = Math.Max(Math.Abs(F1), Math.Abs(G1));
240: if (SCALE >= SAFMX2)
241: {
242: COUNT = 0;
243: LABEL10:;
244: COUNT = COUNT + 1;
245: F1 = F1 * SAFMN2;
246: G1 = G1 * SAFMN2;
247: SCALE = Math.Max(Math.Abs(F1), Math.Abs(G1));
248: if (SCALE >= SAFMX2) goto LABEL10;
249: R = Math.Sqrt(Math.Pow(F1,2) + Math.Pow(G1,2));
250: CS = F1 / R;
251: SN = G1 / R;
252: for (I = 1; I <= COUNT; I++)
253: {
254: R = R * SAFMX2;
255: }
256: }
257: else
258: {
259: if (SCALE <= SAFMN2)
260: {
261: COUNT = 0;
262: LABEL30:;
263: COUNT = COUNT + 1;
264: F1 = F1 * SAFMX2;
265: G1 = G1 * SAFMX2;
266: SCALE = Math.Max(Math.Abs(F1), Math.Abs(G1));
267: if (SCALE <= SAFMN2) goto LABEL30;
268: R = Math.Sqrt(Math.Pow(F1,2) + Math.Pow(G1,2));
269: CS = F1 / R;
270: SN = G1 / R;
271: for (I = 1; I <= COUNT; I++)
272: {
273: R = R * SAFMN2;
274: }
275: }
276: else
277: {
278: R = Math.Sqrt(Math.Pow(F1,2) + Math.Pow(G1,2));
279: CS = F1 / R;
280: SN = G1 / R;
281: }
282: }
283: if (Math.Abs(F) > Math.Abs(G) && CS < ZERO)
284: {
285: CS = - CS;
286: SN = - SN;
287: R = - R;
288: }
289: }
290: }
291: return;
292: // *
293: // * End of DLARTG
294: // *
295:
296: #endregion
297:
298: }
299: }
300: }