claesy.c
Go to the documentation of this file.
00001 /* claesy.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 complex c_b1 = {1.f,0.f};
00019 static integer c__2 = 2;
00020 
00021 /* Subroutine */ int claesy_(complex *a, complex *b, complex *c__, complex *
00022         rt1, complex *rt2, complex *evscal, complex *cs1, complex *sn1)
00023 {
00024     /* System generated locals */
00025     real r__1, r__2;
00026     complex q__1, q__2, q__3, q__4, q__5, q__6, q__7;
00027 
00028     /* Builtin functions */
00029     double c_abs(complex *);
00030     void pow_ci(complex *, complex *, integer *), c_sqrt(complex *, complex *)
00031             , c_div(complex *, complex *, complex *);
00032 
00033     /* Local variables */
00034     complex s, t;
00035     real z__;
00036     complex tmp;
00037     real babs, tabs, evnorm;
00038 
00039 
00040 /*  -- LAPACK auxiliary routine (version 3.2) -- */
00041 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00042 /*     November 2006 */
00043 
00044 /*     .. Scalar Arguments .. */
00045 /*     .. */
00046 
00047 /*  Purpose */
00048 /*  ======= */
00049 
00050 /*  CLAESY computes the eigendecomposition of a 2-by-2 symmetric matrix */
00051 /*     ( ( A, B );( B, C ) ) */
00052 /*  provided the norm of the matrix of eigenvectors is larger than */
00053 /*  some threshold value. */
00054 
00055 /*  RT1 is the eigenvalue of larger absolute value, and RT2 of */
00056 /*  smaller absolute value.  If the eigenvectors are computed, then */
00057 /*  on return ( CS1, SN1 ) is the unit eigenvector for RT1, hence */
00058 
00059 /*  [  CS1     SN1   ] . [ A  B ] . [ CS1    -SN1   ] = [ RT1  0  ] */
00060 /*  [ -SN1     CS1   ]   [ B  C ]   [ SN1     CS1   ]   [  0  RT2 ] */
00061 
00062 /*  Arguments */
00063 /*  ========= */
00064 
00065 /*  A       (input) COMPLEX */
00066 /*          The ( 1, 1 ) element of input matrix. */
00067 
00068 /*  B       (input) COMPLEX */
00069 /*          The ( 1, 2 ) element of input matrix.  The ( 2, 1 ) element */
00070 /*          is also given by B, since the 2-by-2 matrix is symmetric. */
00071 
00072 /*  C       (input) COMPLEX */
00073 /*          The ( 2, 2 ) element of input matrix. */
00074 
00075 /*  RT1     (output) COMPLEX */
00076 /*          The eigenvalue of larger modulus. */
00077 
00078 /*  RT2     (output) COMPLEX */
00079 /*          The eigenvalue of smaller modulus. */
00080 
00081 /*  EVSCAL  (output) COMPLEX */
00082 /*          The complex value by which the eigenvector matrix was scaled */
00083 /*          to make it orthonormal.  If EVSCAL is zero, the eigenvectors */
00084 /*          were not computed.  This means one of two things:  the 2-by-2 */
00085 /*          matrix could not be diagonalized, or the norm of the matrix */
00086 /*          of eigenvectors before scaling was larger than the threshold */
00087 /*          value THRESH (set below). */
00088 
00089 /*  CS1     (output) COMPLEX */
00090 /*  SN1     (output) COMPLEX */
00091 /*          If EVSCAL .NE. 0,  ( CS1, SN1 ) is the unit right eigenvector */
00092 /*          for RT1. */
00093 
00094 /* ===================================================================== */
00095 
00096 /*     .. Parameters .. */
00097 /*     .. */
00098 /*     .. Local Scalars .. */
00099 /*     .. */
00100 /*     .. Intrinsic Functions .. */
00101 /*     .. */
00102 /*     .. Executable Statements .. */
00103 
00104 
00105 /*     Special case:  The matrix is actually diagonal. */
00106 /*     To avoid divide by zero later, we treat this case separately. */
00107 
00108     if (c_abs(b) == 0.f) {
00109         rt1->r = a->r, rt1->i = a->i;
00110         rt2->r = c__->r, rt2->i = c__->i;
00111         if (c_abs(rt1) < c_abs(rt2)) {
00112             tmp.r = rt1->r, tmp.i = rt1->i;
00113             rt1->r = rt2->r, rt1->i = rt2->i;
00114             rt2->r = tmp.r, rt2->i = tmp.i;
00115             cs1->r = 0.f, cs1->i = 0.f;
00116             sn1->r = 1.f, sn1->i = 0.f;
00117         } else {
00118             cs1->r = 1.f, cs1->i = 0.f;
00119             sn1->r = 0.f, sn1->i = 0.f;
00120         }
00121     } else {
00122 
00123 /*        Compute the eigenvalues and eigenvectors. */
00124 /*        The characteristic equation is */
00125 /*           lambda **2 - (A+C) lambda + (A*C - B*B) */
00126 /*        and we solve it using the quadratic formula. */
00127 
00128         q__2.r = a->r + c__->r, q__2.i = a->i + c__->i;
00129         q__1.r = q__2.r * .5f, q__1.i = q__2.i * .5f;
00130         s.r = q__1.r, s.i = q__1.i;
00131         q__2.r = a->r - c__->r, q__2.i = a->i - c__->i;
00132         q__1.r = q__2.r * .5f, q__1.i = q__2.i * .5f;
00133         t.r = q__1.r, t.i = q__1.i;
00134 
00135 /*        Take the square root carefully to avoid over/under flow. */
00136 
00137         babs = c_abs(b);
00138         tabs = c_abs(&t);
00139         z__ = dmax(babs,tabs);
00140         if (z__ > 0.f) {
00141             q__5.r = t.r / z__, q__5.i = t.i / z__;
00142             pow_ci(&q__4, &q__5, &c__2);
00143             q__7.r = b->r / z__, q__7.i = b->i / z__;
00144             pow_ci(&q__6, &q__7, &c__2);
00145             q__3.r = q__4.r + q__6.r, q__3.i = q__4.i + q__6.i;
00146             c_sqrt(&q__2, &q__3);
00147             q__1.r = z__ * q__2.r, q__1.i = z__ * q__2.i;
00148             t.r = q__1.r, t.i = q__1.i;
00149         }
00150 
00151 /*        Compute the two eigenvalues.  RT1 and RT2 are exchanged */
00152 /*        if necessary so that RT1 will have the greater magnitude. */
00153 
00154         q__1.r = s.r + t.r, q__1.i = s.i + t.i;
00155         rt1->r = q__1.r, rt1->i = q__1.i;
00156         q__1.r = s.r - t.r, q__1.i = s.i - t.i;
00157         rt2->r = q__1.r, rt2->i = q__1.i;
00158         if (c_abs(rt1) < c_abs(rt2)) {
00159             tmp.r = rt1->r, tmp.i = rt1->i;
00160             rt1->r = rt2->r, rt1->i = rt2->i;
00161             rt2->r = tmp.r, rt2->i = tmp.i;
00162         }
00163 
00164 /*        Choose CS1 = 1 and SN1 to satisfy the first equation, then */
00165 /*        scale the components of this eigenvector so that the matrix */
00166 /*        of eigenvectors X satisfies  X * X' = I .  (No scaling is */
00167 /*        done if the norm of the eigenvalue matrix is less than THRESH.) */
00168 
00169         q__2.r = rt1->r - a->r, q__2.i = rt1->i - a->i;
00170         c_div(&q__1, &q__2, b);
00171         sn1->r = q__1.r, sn1->i = q__1.i;
00172         tabs = c_abs(sn1);
00173         if (tabs > 1.f) {
00174 /* Computing 2nd power */
00175             r__2 = 1.f / tabs;
00176             r__1 = r__2 * r__2;
00177             q__5.r = sn1->r / tabs, q__5.i = sn1->i / tabs;
00178             pow_ci(&q__4, &q__5, &c__2);
00179             q__3.r = r__1 + q__4.r, q__3.i = q__4.i;
00180             c_sqrt(&q__2, &q__3);
00181             q__1.r = tabs * q__2.r, q__1.i = tabs * q__2.i;
00182             t.r = q__1.r, t.i = q__1.i;
00183         } else {
00184             q__3.r = sn1->r * sn1->r - sn1->i * sn1->i, q__3.i = sn1->r * 
00185                     sn1->i + sn1->i * sn1->r;
00186             q__2.r = q__3.r + 1.f, q__2.i = q__3.i + 0.f;
00187             c_sqrt(&q__1, &q__2);
00188             t.r = q__1.r, t.i = q__1.i;
00189         }
00190         evnorm = c_abs(&t);
00191         if (evnorm >= .1f) {
00192             c_div(&q__1, &c_b1, &t);
00193             evscal->r = q__1.r, evscal->i = q__1.i;
00194             cs1->r = evscal->r, cs1->i = evscal->i;
00195             q__1.r = sn1->r * evscal->r - sn1->i * evscal->i, q__1.i = sn1->r 
00196                     * evscal->i + sn1->i * evscal->r;
00197             sn1->r = q__1.r, sn1->i = q__1.i;
00198         } else {
00199             evscal->r = 0.f, evscal->i = 0.f;
00200         }
00201     }
00202     return 0;
00203 
00204 /*     End of CLAESY */
00205 
00206 } /* claesy_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:30