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