SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
pslaiect.c
Go to the documentation of this file.
1
2
3/* ---------------------------------------------------------------------
4*
5* -- ScaLAPACK routine (version 1.5) --
6* University of Tennessee, Knoxville, Oak Ridge National Laboratory,
7* and University of California, Berkeley.
8* May 1, 1997
9*
10* ---------------------------------------------------------------------
11*/
12
13/*
14 * Include Files
15 */
16#include "pxsyevx.h"
17#include "pblas.h"
18#include <stdio.h>
19#include <math.h>
20#define proto(x) ()
21
22
23void pslasnbt_( Int *ieflag )
24{
25/*
26*
27* Purpose
28* =======
29*
30* psalsnbt finds the position of the signbit of a single
31* precision floating point number. This routine assumes IEEE
32* arithmetic, and hence, tests only the 32nd bit as a possibility
33* for the sign bit.
34*
35* Note : For this release, we assume that sizeof(int) is 4 bytes.
36*
37* Note : If a compile time flag (NO_IEEE) indicates that the
38* machine does not have IEEE arithmetic, IEFLAG = 0 is returned.
39*
40* Arguments
41* =========
42*
43* IEFLAG (output) INTEGER
44* This indicates the position of the signbit of any single
45* precision floating point number.
46* IEFLAG = 0 if the compile time flag, NO_IEEE, indicates
47* that the machine does not have IEEE arithmetic, or if
48* sizeof(int) is different from 4 bytes.
49* IEFLAG = 1 indicates that the sign bit is the 32nd bit.
50*
51* =====================================================================
52*
53* .. Local Scalars ..
54*/
55 float x;
56 Int negone=-1, errornum;
57 unsigned Int *ix;
58/* ..
59* .. Executable Statements ..
60*/
61
62#ifdef NO_IEEE
63 *ieflag = 0;
64#else
65 if(sizeof(Int) != 4){
66 *ieflag = 0;
67 return;
68 }
69 x = (float) -1.0;
70 ix = (unsigned Int *) &x;
71 if( *ix == 0xbff00000 )
72 {
73 *ieflag = 1;
74 } else {
75 *ieflag = 0;
76 }
77#endif
78}
79
80void pslaiect_( float *sigma, Int *n, float *d, Int *count )
81{
82/*
83*
84* Purpose
85* =======
86*
87* pslaiect computes the number of negative eigenvalues of (A- SIGMA I).
88* This implementation of the Sturm Sequence loop exploits IEEE Arithmetic
89* and has no conditionals in the innermost loop. The signbit is assumed
90* to be bit 32.
91*
92* Note that all arguments are call-by-reference so that this routine
93* can be directly called from Fortran code.
94*
95* This is a ScaLAPACK internal subroutine and arguments are not
96* checked for unreasonable values.
97*
98* Arguments
99* =========
100*
101* SIGMA (input) REAL
102* The shift. pslaiect finds the number of eigenvalues less
103* than equal to SIGMA.
104*
105* N (input) INTEGER
106* The order of the tridiagonal matrix T. N >= 1.
107*
108* D (input) REAL array, dimension (2*N - 1)
109* Contains the diagonals and the squares of the off-diagonal
110* elements of the tridiagonal matrix T. These elements are
111* assumed to be interleaved in memory for better cache
112* performance. The diagonal entries of T are in the entries
113* D(1),D(3),...,D(2*N-1), while the squares of the off-diagonal
114* entries are D(2),D(4),...,D(2*N-2). To avoid overflow, the
115* matrix must be scaled so that its largest entry is no greater
116* than overflow**(1/2) * underflow**(1/4) in absolute value,
117* and for greatest accuracy, it should not be much smaller
118* than that.
119*
120* COUNT (output) INTEGER
121* The count of the number of eigenvalues of T less than or
122* equal to SIGMA.
123*
124* =====================================================================
125*
126* .. Local Scalars ..
127*/
128 float lsigma, tmp, *pd, *pe2;
129 Int i;
130/* ..
131* .. Executable Statements ..
132*/
133
134 lsigma = *sigma;
135 pd = d; pe2 = d+1;
136 tmp = *pd - lsigma; pd += 2;
137 *count = (*((Int *)&tmp) >> 31) & 1;
138 for(i = 1;i < *n;i++){
139 tmp = *pd - *pe2/tmp - lsigma;
140 pd += 2; pe2 += 2;
141 *count += ((*((Int *)&tmp)) >> 31) & 1;
142 }
143}
144
145void pslachkieee_( Int *isieee, float *rmax, float *rmin )
146{
147/*
148*
149* Purpose
150* =======
151*
152* pslachkieee performs a simple check to make sure that the features
153* of the IEEE standard that we rely on are implemented. In some
154* implementations, pslachkieee may not return.
155*
156* Note that all arguments are call-by-reference so that this routine
157* can be directly called from Fortran code.
158*
159* This is a ScaLAPACK internal subroutine and arguments are not
160* checked for unreasonable values.
161*
162* Arguments
163* =========
164*
165* ISIEEE (local output) INTEGER
166* On exit, ISIEEE = 1 implies that all the features of the
167* IEEE standard that we rely on are implemented.
168* On exit, ISIEEE = 0 implies that some the features of the
169* IEEE standard that we rely on are missing.
170*
171* RMAX (local input) REAL
172* The overflow threshold ( = SLAMCH('O') ).
173*
174* RMIN (local input) REAL
175* The underflow threshold ( = SLAMCH('U') ).
176*
177* =====================================================================
178*
179* .. Local Scalars ..
180*/
181 float x, pinf, pzero, ninf, nzero;
182 Int ieflag, *ix, sbit1, sbit2, negone=-1, errornum;
183/* ..
184* .. Executable Statements ..
185*/
186
187 pslasnbt_( &ieflag );
188
189 pinf = *rmax / *rmin;
190 pzero = 1.0 / pinf;
191 pinf = 1.0 / pzero;
192
193 if( pzero != 0.0 ){
194 printf("pzero = %g should be zero\n",pzero);
195 *isieee = 0;
196 return ;
197 }
198 if( ieflag == 1 ){
199 sbit1 = (*((Int *)&pzero) >> 31) & 1;
200 sbit2 = (*((Int *)&pinf) >> 31) & 1;
201 }
202 if( sbit1 == 1 ){
203 printf("Sign of positive infinity is incorrect\n");
204 *isieee = 0;
205 }
206 if( sbit2 == 1 ){
207 printf("Sign of positive zero is incorrect\n");
208 *isieee = 0;
209 }
210
211 ninf = -pinf;
212 nzero = 1.0 / ninf;
213 ninf = 1.0 / nzero;
214
215 if( nzero != 0.0 ){
216 printf("nzero = %g should be zero\n",nzero);
217 *isieee = 0;
218 }
219 if( ieflag == 1 ){
220 sbit1 = (*((Int *)&nzero) >> 31) & 1;
221 sbit2 = (*((Int *)&ninf) >> 31) & 1;
222 }
223 if( sbit1 == 0 ){
224 printf("Sign of negative infinity is incorrect\n");
225 *isieee = 0;
226 }
227 if( sbit2 == 0 ){
228 printf("Sign of negative zero is incorrect\n");
229 *isieee = 0;
230 }
231}
#define Int
Definition Bconfig.h:22
void pslaiect_(float *sigma, Int *n, float *d, Int *count)
Definition pslaiect.c:80
void pslasnbt_(Int *ieflag)
Definition pslaiect.c:23
void pslachkieee_(Int *isieee, float *rmax, float *rmin)
Definition pslaiect.c:145