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:      /// DLAS2  computes the singular values of the 2-by-2 matrix
27:      /// [  F   G  ]
28:      /// [  0   H  ].
29:      /// On return, SSMIN is the smaller singular value and SSMAX is the
30:      /// larger singular value.
31:      ///
32:      ///</summary>
33:      public class DLAS2
34:      {
35:
36:
37:          #region Fields
38:
39:          const double ZERO = 0.0E0; const double ONE = 1.0E0; const double TWO = 2.0E0; double AS = 0; double AT = 0;
40:          double AU = 0;double C = 0; double FA = 0; double FHMN = 0; double FHMX = 0; double GA = 0; double HA = 0;
41:
42:          #endregion
43:
44:          public DLAS2()
45:          {
46:
47:          }
48:
49:          /// <summary>
50:          /// Purpose
51:          /// =======
52:          ///
53:          /// DLAS2  computes the singular values of the 2-by-2 matrix
54:          /// [  F   G  ]
55:          /// [  0   H  ].
56:          /// On return, SSMIN is the smaller singular value and SSMAX is the
57:          /// larger singular value.
58:          ///
59:          ///</summary>
60:          /// <param name="F">
61:          /// (input) DOUBLE PRECISION
62:          /// The (1,1) element of the 2-by-2 matrix.
63:          ///</param>
64:          /// <param name="G">
65:          /// (input) DOUBLE PRECISION
66:          /// The (1,2) element of the 2-by-2 matrix.
67:          ///</param>
68:          /// <param name="H">
69:          /// (input) DOUBLE PRECISION
70:          /// The (2,2) element of the 2-by-2 matrix.
71:          ///</param>
72:          /// <param name="SSMIN">
73:          /// (output) DOUBLE PRECISION
74:          /// The smaller singular value.
75:          ///</param>
76:          /// <param name="SSMAX">
77:          /// (output) DOUBLE PRECISION
78:          /// The larger singular value.
79:          ///</param>
80:          public void Run(double F, double G, double H, ref double SSMIN, ref double SSMAX)
81:          {
82:
83:              #region Prolog
84:
85:              // *
86:              // *  -- LAPACK auxiliary routine (version 3.1) --
87:              // *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
88:              // *     November 2006
89:              // *
90:              // *     .. Scalar Arguments ..
91:              // *     ..
92:              // *
93:              // *  Purpose
94:              // *  =======
95:              // *
96:              // *  DLAS2  computes the singular values of the 2-by-2 matrix
97:              // *     [  F   G  ]
98:              // *     [  0   H  ].
99:              // *  On return, SSMIN is the smaller singular value and SSMAX is the
100:              // *  larger singular value.
101:              // *
102:              // *  Arguments
103:              // *  =========
104:              // *
105:              // *  F       (input) DOUBLE PRECISION
106:              // *          The (1,1) element of the 2-by-2 matrix.
107:              // *
108:              // *  G       (input) DOUBLE PRECISION
109:              // *          The (1,2) element of the 2-by-2 matrix.
110:              // *
111:              // *  H       (input) DOUBLE PRECISION
112:              // *          The (2,2) element of the 2-by-2 matrix.
113:              // *
114:              // *  SSMIN   (output) DOUBLE PRECISION
115:              // *          The smaller singular value.
116:              // *
117:              // *  SSMAX   (output) DOUBLE PRECISION
118:              // *          The larger singular value.
119:              // *
120:              // *  Further Details
121:              // *  ===============
122:              // *
123:              // *  Barring over/underflow, all output quantities are correct to within
124:              // *  a few units in the last place (ulps), even in the absence of a guard
125:              // *  digit in addition/subtraction.
126:              // *
127:              // *  In IEEE arithmetic, the code works correctly if one matrix element is
128:              // *  infinite.
129:              // *
130:              // *  Overflow will not occur unless the largest singular value itself
131:              // *  overflows, or is within a few ulps of overflow. (On machines with
132:              // *  partial overflow, like the Cray, overflow may occur if the largest
133:              // *  singular value is within a factor of 2 of overflow.)
134:              // *
135:              // *  Underflow is harmless if underflow is gradual. Otherwise, results
136:              // *  may correspond to a matrix modified by perturbations of size near
137:              // *  the underflow threshold.
138:              // *
139:              // *  ====================================================================
140:              // *
141:              // *     .. Parameters ..
142:              // *     ..
143:              // *     .. Local Scalars ..
144:              // *     ..
145:              // *     .. Intrinsic Functions ..
146:              //      INTRINSIC          ABS, MAX, MIN, SQRT;
147:              // *     ..
148:              // *     .. Executable Statements ..
149:              // *
150:
151:              #endregion
152:
153:
154:              #region Body
155:
156:              FA = Math.Abs(F);
157:              GA = Math.Abs(G);
158:              HA = Math.Abs(H);
159:              FHMN = Math.Min(FA, HA);
160:              FHMX = Math.Max(FA, HA);
161:              if (FHMN == ZERO)
162:              {
163:                  SSMIN = ZERO;
164:                  if (FHMX == ZERO)
165:                  {
166:                      SSMAX = GA;
167:                  }
168:                  else
169:                  {
170:                      SSMAX = Math.Max(FHMX, GA) * Math.Sqrt(ONE + Math.Pow(Math.Min(FHMX, GA) / Math.Max(FHMX, GA),2));
171:                  }
172:              }
173:              else
174:              {
175:                  if (GA < FHMX)
176:                  {
177:                      AS = ONE + FHMN / FHMX;
178:                      AT = (FHMX - FHMN) / FHMX;
179:                      AU = Math.Pow(GA / FHMX,2);
180:                      C = TWO / (Math.Sqrt(AS * AS + AU) + Math.Sqrt(AT * AT + AU));
181:                      SSMIN = FHMN * C;
182:                      SSMAX = FHMX / C;
183:                  }
184:                  else
185:                  {
186:                      AU = FHMX / GA;
187:                      if (AU == ZERO)
188:                      {
189:                          // *
190:                          // *              Avoid possible harmful underflow if exponent range
191:                          // *              asymmetric (true SSMIN may not underflow even if
192:                          // *              AU underflows)
193:                          // *
194:                          SSMIN = (FHMN * FHMX) / GA;
195:                          SSMAX = GA;
196:                      }
197:                      else
198:                      {
199:                          AS = ONE + FHMN / FHMX;
200:                          AT = (FHMX - FHMN) / FHMX;
201:                          C = ONE / (Math.Sqrt(ONE + Math.Pow(AS * AU,2)) + Math.Sqrt(ONE + Math.Pow(AT * AU,2)));
202:                          SSMIN = (FHMN * C) * AU;
203:                          SSMIN = SSMIN + SSMIN;
204:                          SSMAX = GA / (C + C);
205:                      }
206:                  }
207:              }
208:              return;
209:              // *
210:              // *     End of DLAS2
211:              // *
212:
213:              #endregion
214:
215:          }
216:      }
217:  }