zlaesy.c
Go to the documentation of this file.
00001 /* zlaesy.f -- translated by f2c (version 20061008).
00002    You must link the resulting object file with libf2c:
00003         on Microsoft Windows system, link with libf2c.lib;
00004         on Linux or Unix systems, link with .../path/to/libf2c.a -lm
00005         or, if you install libf2c.a in a standard place, with -lf2c -lm
00006         -- in that order, at the end of the command line, as in
00007                 cc *.o -lf2c -lm
00008         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
00009 
00010                 http://www.netlib.org/f2c/libf2c.zip
00011 */
00012 
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015 
00016 /* Table of constant values */
00017 
00018 static doublecomplex c_b1 = {1.,0.};
00019 static integer c__2 = 2;
00020 
00021 /* Subroutine */ int zlaesy_(doublecomplex *a, doublecomplex *b, 
00022         doublecomplex *c__, doublecomplex *rt1, doublecomplex *rt2, 
00023         doublecomplex *evscal, doublecomplex *cs1, doublecomplex *sn1)
00024 {
00025     /* System generated locals */
00026     doublereal d__1, d__2;
00027     doublecomplex z__1, z__2, z__3, z__4, z__5, z__6, z__7;
00028 
00029     /* Builtin functions */
00030     double z_abs(doublecomplex *);
00031     void pow_zi(doublecomplex *, doublecomplex *, integer *), z_sqrt(
00032             doublecomplex *, doublecomplex *), z_div(doublecomplex *, 
00033             doublecomplex *, doublecomplex *);
00034 
00035     /* Local variables */
00036     doublecomplex s, t;
00037     doublereal z__;
00038     doublecomplex tmp;
00039     doublereal babs, tabs, evnorm;
00040 
00041 
00042 /*  -- LAPACK auxiliary routine (version 3.2) -- */
00043 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00044 /*     November 2006 */
00045 
00046 /*     .. Scalar Arguments .. */
00047 /*     .. */
00048 
00049 /*  Purpose */
00050 /*  ======= */
00051 
00052 /*  ZLAESY computes the eigendecomposition of a 2-by-2 symmetric matrix */
00053 /*     ( ( A, B );( B, C ) ) */
00054 /*  provided the norm of the matrix of eigenvectors is larger than */
00055 /*  some threshold value. */
00056 
00057 /*  RT1 is the eigenvalue of larger absolute value, and RT2 of */
00058 /*  smaller absolute value.  If the eigenvectors are computed, then */
00059 /*  on return ( CS1, SN1 ) is the unit eigenvector for RT1, hence */
00060 
00061 /*  [  CS1     SN1   ] . [ A  B ] . [ CS1    -SN1   ] = [ RT1  0  ] */
00062 /*  [ -SN1     CS1   ]   [ B  C ]   [ SN1     CS1   ]   [  0  RT2 ] */
00063 
00064 /*  Arguments */
00065 /*  ========= */
00066 
00067 /*  A       (input) COMPLEX*16 */
00068 /*          The ( 1, 1 ) element of input matrix. */
00069 
00070 /*  B       (input) COMPLEX*16 */
00071 /*          The ( 1, 2 ) element of input matrix.  The ( 2, 1 ) element */
00072 /*          is also given by B, since the 2-by-2 matrix is symmetric. */
00073 
00074 /*  C       (input) COMPLEX*16 */
00075 /*          The ( 2, 2 ) element of input matrix. */
00076 
00077 /*  RT1     (output) COMPLEX*16 */
00078 /*          The eigenvalue of larger modulus. */
00079 
00080 /*  RT2     (output) COMPLEX*16 */
00081 /*          The eigenvalue of smaller modulus. */
00082 
00083 /*  EVSCAL  (output) COMPLEX*16 */
00084 /*          The complex value by which the eigenvector matrix was scaled */
00085 /*          to make it orthonormal.  If EVSCAL is zero, the eigenvectors */
00086 /*          were not computed.  This means one of two things:  the 2-by-2 */
00087 /*          matrix could not be diagonalized, or the norm of the matrix */
00088 /*          of eigenvectors before scaling was larger than the threshold */
00089 /*          value THRESH (set below). */
00090 
00091 /*  CS1     (output) COMPLEX*16 */
00092 /*  SN1     (output) COMPLEX*16 */
00093 /*          If EVSCAL .NE. 0,  ( CS1, SN1 ) is the unit right eigenvector */
00094 /*          for RT1. */
00095 
00096 /* ===================================================================== */
00097 
00098 /*     .. Parameters .. */
00099 /*     .. */
00100 /*     .. Local Scalars .. */
00101 /*     .. */
00102 /*     .. Intrinsic Functions .. */
00103 /*     .. */
00104 /*     .. Executable Statements .. */
00105 
00106 
00107 /*     Special case:  The matrix is actually diagonal. */
00108 /*     To avoid divide by zero later, we treat this case separately. */
00109 
00110     if (z_abs(b) == 0.) {
00111         rt1->r = a->r, rt1->i = a->i;
00112         rt2->r = c__->r, rt2->i = c__->i;
00113         if (z_abs(rt1) < z_abs(rt2)) {
00114             tmp.r = rt1->r, tmp.i = rt1->i;
00115             rt1->r = rt2->r, rt1->i = rt2->i;
00116             rt2->r = tmp.r, rt2->i = tmp.i;
00117             cs1->r = 0., cs1->i = 0.;
00118             sn1->r = 1., sn1->i = 0.;
00119         } else {
00120             cs1->r = 1., cs1->i = 0.;
00121             sn1->r = 0., sn1->i = 0.;
00122         }
00123     } else {
00124 
00125 /*        Compute the eigenvalues and eigenvectors. */
00126 /*        The characteristic equation is */
00127 /*           lambda **2 - (A+C) lambda + (A*C - B*B) */
00128 /*        and we solve it using the quadratic formula. */
00129 
00130         z__2.r = a->r + c__->r, z__2.i = a->i + c__->i;
00131         z__1.r = z__2.r * .5, z__1.i = z__2.i * .5;
00132         s.r = z__1.r, s.i = z__1.i;
00133         z__2.r = a->r - c__->r, z__2.i = a->i - c__->i;
00134         z__1.r = z__2.r * .5, z__1.i = z__2.i * .5;
00135         t.r = z__1.r, t.i = z__1.i;
00136 
00137 /*        Take the square root carefully to avoid over/under flow. */
00138 
00139         babs = z_abs(b);
00140         tabs = z_abs(&t);
00141         z__ = max(babs,tabs);
00142         if (z__ > 0.) {
00143             z__5.r = t.r / z__, z__5.i = t.i / z__;
00144             pow_zi(&z__4, &z__5, &c__2);
00145             z__7.r = b->r / z__, z__7.i = b->i / z__;
00146             pow_zi(&z__6, &z__7, &c__2);
00147             z__3.r = z__4.r + z__6.r, z__3.i = z__4.i + z__6.i;
00148             z_sqrt(&z__2, &z__3);
00149             z__1.r = z__ * z__2.r, z__1.i = z__ * z__2.i;
00150             t.r = z__1.r, t.i = z__1.i;
00151         }
00152 
00153 /*        Compute the two eigenvalues.  RT1 and RT2 are exchanged */
00154 /*        if necessary so that RT1 will have the greater magnitude. */
00155 
00156         z__1.r = s.r + t.r, z__1.i = s.i + t.i;
00157         rt1->r = z__1.r, rt1->i = z__1.i;
00158         z__1.r = s.r - t.r, z__1.i = s.i - t.i;
00159         rt2->r = z__1.r, rt2->i = z__1.i;
00160         if (z_abs(rt1) < z_abs(rt2)) {
00161             tmp.r = rt1->r, tmp.i = rt1->i;
00162             rt1->r = rt2->r, rt1->i = rt2->i;
00163             rt2->r = tmp.r, rt2->i = tmp.i;
00164         }
00165 
00166 /*        Choose CS1 = 1 and SN1 to satisfy the first equation, then */
00167 /*        scale the components of this eigenvector so that the matrix */
00168 /*        of eigenvectors X satisfies  X * X' = I .  (No scaling is */
00169 /*        done if the norm of the eigenvalue matrix is less than THRESH.) */
00170 
00171         z__2.r = rt1->r - a->r, z__2.i = rt1->i - a->i;
00172         z_div(&z__1, &z__2, b);
00173         sn1->r = z__1.r, sn1->i = z__1.i;
00174         tabs = z_abs(sn1);
00175         if (tabs > 1.) {
00176 /* Computing 2nd power */
00177             d__2 = 1. / tabs;
00178             d__1 = d__2 * d__2;
00179             z__5.r = sn1->r / tabs, z__5.i = sn1->i / tabs;
00180             pow_zi(&z__4, &z__5, &c__2);
00181             z__3.r = d__1 + z__4.r, z__3.i = z__4.i;
00182             z_sqrt(&z__2, &z__3);
00183             z__1.r = tabs * z__2.r, z__1.i = tabs * z__2.i;
00184             t.r = z__1.r, t.i = z__1.i;
00185         } else {
00186             z__3.r = sn1->r * sn1->r - sn1->i * sn1->i, z__3.i = sn1->r * 
00187                     sn1->i + sn1->i * sn1->r;
00188             z__2.r = z__3.r + 1., z__2.i = z__3.i + 0.;
00189             z_sqrt(&z__1, &z__2);
00190             t.r = z__1.r, t.i = z__1.i;
00191         }
00192         evnorm = z_abs(&t);
00193         if (evnorm >= .1) {
00194             z_div(&z__1, &c_b1, &t);
00195             evscal->r = z__1.r, evscal->i = z__1.i;
00196             cs1->r = evscal->r, cs1->i = evscal->i;
00197             z__1.r = sn1->r * evscal->r - sn1->i * evscal->i, z__1.i = sn1->r 
00198                     * evscal->i + sn1->i * evscal->r;
00199             sn1->r = z__1.r, sn1->i = z__1.i;
00200         } else {
00201             evscal->r = 0., evscal->i = 0.;
00202         }
00203     }
00204     return 0;
00205 
00206 /*     End of ZLAESY */
00207 
00208 } /* zlaesy_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:40