~ubuntu-branches/ubuntu/lucid/igraph/lucid

« back to all changes in this revision

Viewing changes to src/lapack/dlaev2.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Malaterre
  • Date: 2009-11-16 18:12:42 UTC
  • Revision ID: james.westby@ubuntu.com-20091116181242-mzv9p5fz9uj57xd1
Tags: upstream-0.5.3
ImportĀ upstreamĀ versionĀ 0.5.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  -- translated by f2c (version 20050501).
 
2
   You must link the resulting object file with libf2c:
 
3
        on Microsoft Windows system, link with libf2c.lib;
 
4
        on Linux or Unix systems, link with .../path/to/libf2c.a -lm
 
5
        or, if you install libf2c.a in a standard place, with -lf2c -lm
 
6
        -- in that order, at the end of the command line, as in
 
7
                cc *.o -lf2c -lm
 
8
        Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
 
9
 
 
10
                http://www.netlib.org/f2c/libf2c.zip
 
11
*/
 
12
 
 
13
#include "config.h"
 
14
#include "arpack_internal.h"
 
15
#include "f2c.h"
 
16
 
 
17
/* Subroutine */ int igraphdlaev2_(doublereal *a, doublereal *b, doublereal *c__, 
 
18
        doublereal *rt1, doublereal *rt2, doublereal *cs1, doublereal *sn1)
 
19
{
 
20
    /* System generated locals */
 
21
    doublereal d__1;
 
22
 
 
23
    /* Builtin functions */
 
24
    double sqrt(doublereal);
 
25
 
 
26
    /* Local variables */
 
27
    static doublereal ab, df, cs, ct, tb, sm, tn, rt, adf, acs;
 
28
    static integer sgn1, sgn2;
 
29
    static doublereal acmn, acmx;
 
30
 
 
31
 
 
32
/*  -- LAPACK auxiliary routine (version 3.0) -- */
 
33
/*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */
 
34
/*     Courant Institute, Argonne National Lab, and Rice University */
 
35
/*     October 31, 1992 */
 
36
 
 
37
/*     .. Scalar Arguments .. */
 
38
/*     .. */
 
39
 
 
40
/*  Purpose */
 
41
/*  ======= */
 
42
 
 
43
/*  DLAEV2 computes the eigendecomposition of a 2-by-2 symmetric matrix */
 
44
/*     [  A   B  ] */
 
45
/*     [  B   C  ]. */
 
46
/*  On return, RT1 is the eigenvalue of larger absolute value, RT2 is the */
 
47
/*  eigenvalue of smaller absolute value, and (CS1,SN1) is the unit right */
 
48
/*  eigenvector for RT1, giving the decomposition */
 
49
 
 
50
/*     [ CS1  SN1 ] [  A   B  ] [ CS1 -SN1 ]  =  [ RT1  0  ] */
 
51
/*     [-SN1  CS1 ] [  B   C  ] [ SN1  CS1 ]     [  0  RT2 ]. */
 
52
 
 
53
/*  Arguments */
 
54
/*  ========= */
 
55
 
 
56
/*  A       (input) DOUBLE PRECISION */
 
57
/*          The (1,1) element of the 2-by-2 matrix. */
 
58
 
 
59
/*  B       (input) DOUBLE PRECISION */
 
60
/*          The (1,2) element and the conjugate of the (2,1) element of */
 
61
/*          the 2-by-2 matrix. */
 
62
 
 
63
/*  C       (input) DOUBLE PRECISION */
 
64
/*          The (2,2) element of the 2-by-2 matrix. */
 
65
 
 
66
/*  RT1     (output) DOUBLE PRECISION */
 
67
/*          The eigenvalue of larger absolute value. */
 
68
 
 
69
/*  RT2     (output) DOUBLE PRECISION */
 
70
/*          The eigenvalue of smaller absolute value. */
 
71
 
 
72
/*  CS1     (output) DOUBLE PRECISION */
 
73
/*  SN1     (output) DOUBLE PRECISION */
 
74
/*          The vector (CS1, SN1) is a unit right eigenvector for RT1. */
 
75
 
 
76
/*  Further Details */
 
77
/*  =============== */
 
78
 
 
79
/*  RT1 is accurate to a few ulps barring over/underflow. */
 
80
 
 
81
/*  RT2 may be inaccurate if there is massive cancellation in the */
 
82
/*  determinant A*C-B*B; higher precision or correctly rounded or */
 
83
/*  correctly truncated arithmetic would be needed to compute RT2 */
 
84
/*  accurately in all cases. */
 
85
 
 
86
/*  CS1 and SN1 are accurate to a few ulps barring over/underflow. */
 
87
 
 
88
/*  Overflow is possible only if RT1 is within a factor of 5 of overflow. */
 
89
/*  Underflow is harmless if the input data is 0 or exceeds */
 
90
/*     underflow_threshold / macheps. */
 
91
 
 
92
/* ===================================================================== */
 
93
 
 
94
/*     .. Parameters .. */
 
95
/*     .. */
 
96
/*     .. Local Scalars .. */
 
97
/*     .. */
 
98
/*     .. Intrinsic Functions .. */
 
99
/*     .. */
 
100
/*     .. Executable Statements .. */
 
101
 
 
102
/*     Compute the eigenvalues */
 
103
 
 
104
    sm = *a + *c__;
 
105
    df = *a - *c__;
 
106
    adf = abs(df);
 
107
    tb = *b + *b;
 
108
    ab = abs(tb);
 
109
    if (abs(*a) > abs(*c__)) {
 
110
        acmx = *a;
 
111
        acmn = *c__;
 
112
    } else {
 
113
        acmx = *c__;
 
114
        acmn = *a;
 
115
    }
 
116
    if (adf > ab) {
 
117
/* Computing 2nd power */
 
118
        d__1 = ab / adf;
 
119
        rt = adf * sqrt(d__1 * d__1 + 1.);
 
120
    } else if (adf < ab) {
 
121
/* Computing 2nd power */
 
122
        d__1 = adf / ab;
 
123
        rt = ab * sqrt(d__1 * d__1 + 1.);
 
124
    } else {
 
125
 
 
126
/*        Includes case AB=ADF=0 */
 
127
 
 
128
        rt = ab * sqrt(2.);
 
129
    }
 
130
    if (sm < 0.) {
 
131
        *rt1 = (sm - rt) * .5;
 
132
        sgn1 = -1;
 
133
 
 
134
/*        Order of execution important. */
 
135
/*        To get fully accurate smaller eigenvalue, */
 
136
/*        next line needs to be executed in higher precision. */
 
137
 
 
138
        *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
 
139
    } else if (sm > 0.) {
 
140
        *rt1 = (sm + rt) * .5;
 
141
        sgn1 = 1;
 
142
 
 
143
/*        Order of execution important. */
 
144
/*        To get fully accurate smaller eigenvalue, */
 
145
/*        next line needs to be executed in higher precision. */
 
146
 
 
147
        *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
 
148
    } else {
 
149
 
 
150
/*        Includes case RT1 = RT2 = 0 */
 
151
 
 
152
        *rt1 = rt * .5;
 
153
        *rt2 = rt * -.5;
 
154
        sgn1 = 1;
 
155
    }
 
156
 
 
157
/*     Compute the eigenvector */
 
158
 
 
159
    if (df >= 0.) {
 
160
        cs = df + rt;
 
161
        sgn2 = 1;
 
162
    } else {
 
163
        cs = df - rt;
 
164
        sgn2 = -1;
 
165
    }
 
166
    acs = abs(cs);
 
167
    if (acs > ab) {
 
168
        ct = -tb / cs;
 
169
        *sn1 = 1. / sqrt(ct * ct + 1.);
 
170
        *cs1 = ct * *sn1;
 
171
    } else {
 
172
        if (ab == 0.) {
 
173
            *cs1 = 1.;
 
174
            *sn1 = 0.;
 
175
        } else {
 
176
            tn = -cs / tb;
 
177
            *cs1 = 1. / sqrt(tn * tn + 1.);
 
178
            *sn1 = tn * *cs1;
 
179
        }
 
180
    }
 
181
    if (sgn1 == sgn2) {
 
182
        tn = *cs1;
 
183
        *cs1 = -(*sn1);
 
184
        *sn1 = tn;
 
185
    }
 
186
    return 0;
 
187
 
 
188
/*     End of DLAEV2 */
 
189
 
 
190
} /* igraphdlaev2_ */
 
191