dy_vector.h
Go to the documentation of this file.
1 /*
2  This file is a part of the Dylp LP distribution.
3 
4  Copyright (C) 2005 -- 2007 Lou Hafer
5 
6  School of Computing Science
7  Simon Fraser University
8  Burnaby, B.C., V5A 1S6, Canada
9  lou@cs.sfu.ca
10 
11  This code is licensed under the terms of the Common Public License (CPL).
12 */
13 
14 #ifndef _DYLP_VECTOR_H
15 #define _DYLP_VECTOR_H
16 
17 /*
18  @(#)dy_vector.h 4.5 11/06/04
19  svn/cvs: $Id: dy_vector.h 198 2008-01-03 00:43:36Z lou $
20 */
21 
22 #include <DylpConfig.h>
23 
24 /*
25  Why, you might ask, are we including ctype.h? Well, it's required by the
26  ANSI C specification, so it's pretty well guaranteed to exist. And, at least
27  in Solaris and Linux environments that I'm familiar with, it'll pull in the
28  compile-time symbols that specify big- or little-endian, which we really
29  want.
30 */
31 #include <ctype.h>
32 
33 /*
34  A bunch of standard definitions.
35 */
36 #include "dylib_std.h"
37 
38 /*
39  In a few rare instances, the declarations here will be unused, but for dylp
40  this is a good bet.
41 */
42 #include <math.h>
43 
44 /*
45  Some subset of these will work on any system. Check config_dylp.h to see
46  which ones are actually in use.
47 */
48 #ifdef HAVE_FLOAT_H
49 # include <float.h>
50 #endif
51 #ifdef HAVE_IEEEFP_H
52 # include <ieeefp.h>
53 #endif
54 #ifdef HAVE_SUNMATH_H
55 # include <sunmath.h>
56 #endif
57 
58 
59 /*
60  The Theory: quiet_nan is used to indicate failure (by returning NaN)
61  without triggering a signal the client may not be prepared to catch. The
62  idea is that any reasonable checks in the client will detect NaN fairly
63  quickly. signalling_nan is used when there's no advantage in delaying a
64  signal.
65 
66  The Reality: Neither seems to trigger a signal, and many computing
67  environments can't tell the difference. But it's coded into dylp, and it'd
68  be much ado to change. Hence the compile-time ugliness that follows.
69 
70  In the Sun Workshop environment, quiet_nan and signalling_nan are declared
71  in sunmath.h and found in libsunmath. With release 5.0, sunmath.h includes
72  some declarations of type `long long', which isn't supported under the -Xc
73  (strict ANSI compatibility) option for cc. So, we extract only the
74  definitions we need. Unfortunately, sunmath.h is present only in the Sun
75  Workshop programming environment. Sun without Workshop has only the
76  require file nan.h, which is inadequate.
77 
78  For a long while, GNU C didn't distinguish QNaN and SNaN. More recently,
79  its support for IEEE 754 seems to have improved, but it's not clear that we
80  can count on everyone having a recent GCC environment just yet. Here, too,
81  nan.h is inadequate. The easy way out is to simply #define them as macros
82  that return the proper bit pattern. Arguably this would make more sense in
83  general than Sun's implementation as functions.
84 
85  According to IEEE 754, the proper bit patterns are:
86 
87  0x7ff00000 00000000 for Inf
88  0x7fffffff ffffffff for QNaN
89  0x7ff00000 00000001 for SNaN
90 
91  It works this way: The IEEE definition of NaN is
92  Bits Value
93  63 sign --- don't care for a NaN, but nice to be positive (0)
94  62:52 exponent --- must be maximum value, 0x7ff
95  51:0 fraction --- must not be zero (a fraction of zero is the
96  representation of infinity). Sun documentation defines QNaN
97  as having bit 51 of the fraction set to 1, SNaN as having
98  bit 51 set to 0.
99 
100  Creating the proper constants qualifies as a serious gross hack. And if you
101  have a little-endian machine (the 80x86 family being far and away the most
102  common example), you need to flip the byte order.
103 */
104  typedef union { unsigned char fpchr[8] ; double fpdbl ; } fpunion_t ;
105 /*
106  Yes, all this really is needed to get all the various compilers to quit
107  complaining. We need the `(unsigned char)' to prevent some compilers from
108  complaining about the initialiser being out of range. Goes to the ANSI C
109  rule that `Character constants not preceded by the letter L have type int.'
110 */
111 #ifdef WORDS_BIGENDIAN
112  static fpunion_t QNaNbits UNUSED = { { (unsigned char) '\177',
113  (unsigned char) '\377',
114  (unsigned char) '\377',
115  (unsigned char) '\377',
116  (unsigned char) '\377',
117  (unsigned char) '\377',
118  (unsigned char) '\377',
119  (unsigned char) '\376' } } ;
120  static fpunion_t SNaNbits UNUSED = { { (unsigned char) '\177',
121  (unsigned char) '\360',
122  (unsigned char) '\0',
123  (unsigned char) '\0',
124  (unsigned char) '\0',
125  (unsigned char) '\0',
126  (unsigned char) '\0',
127  (unsigned char) '\001' } } ;
128  static fpunion_t Infbits UNUSED = { { (unsigned char) '\177',
129  (unsigned char) '\360',
130  (unsigned char) '\0',
131  (unsigned char) '\0',
132  (unsigned char) '\0',
133  (unsigned char) '\0',
134  (unsigned char) '\0',
135  (unsigned char) '\0' } } ;
136 #else
137  static fpunion_t QNaNbits UNUSED = { { (unsigned char) '\376',
138  (unsigned char) '\377',
139  (unsigned char) '\377',
140  (unsigned char) '\377',
141  (unsigned char) '\377',
142  (unsigned char) '\377',
143  (unsigned char) '\377',
144  (unsigned char) '\177' } } ;
145  static fpunion_t SNaNbits UNUSED = { { (unsigned char) '\001',
146  (unsigned char) '\0',
147  (unsigned char) '\0',
148  (unsigned char) '\0',
149  (unsigned char) '\0',
150  (unsigned char) '\0',
151  (unsigned char) '\360',
152  (unsigned char) '\177' } } ;
153  static fpunion_t Infbits UNUSED = { { (unsigned char) '\0',
154  (unsigned char) '\0',
155  (unsigned char) '\0',
156  (unsigned char) '\0',
157  (unsigned char) '\0',
158  (unsigned char) '\0',
159  (unsigned char) '\360',
160  (unsigned char) '\177' } } ;
161 #endif /* WORDS_BIGENDIAN */
162 
163 /*
164  If we didn't find a quiet_nan function, fake it with a macro.
165 */
166 
167 #ifndef DYLP_HAS_QUIET_NAN
168 # define quiet_nan(zz_dummy_zz) (QNaNbits.fpdbl)
169 #endif
170 
171 /*
172  On some machines, HUGE_VAL isn't actually IEEE infinity. Make sure that
173  it really is IEEE infinity.
174 */
175 
176 #undef HUGE_VAL
177 #define HUGE_VAL (Infbits.fpdbl)
178 
179 /*
180  In a Sun/Solaris environment, the definitions and functions that support
181  IEEE floating point are in ieeefp.h. This seems to be true even if GNU
182  compilers are being used instead of Sun Workshop compilers. In a GNU/Linux
183  environment, the necessary definitions seem to live in math.h. The upshot
184  is that we need to explicitly pull in ieeefp.h here for a Sun environment.
185 
186  In a Microsoft environment the correct functions look to be _finite and
187  _isnan from float.h.
188 
189  Assign the proper names to finite and isnan, based on the values deduced by
190  configure. Again, check config_dylp to see the actual names. If either name
191  is already defined, bet that it's the correct definition.
192 */
193 
194 #ifndef finite
195 # define finite DYLP_ISFINITE
196 #endif
197 #ifndef isnan
198 # define isnan DYLP_ISNAN
199 #endif
200 
201 
202 /*
203  Packed Vectors
204 
205  The packed vector type consists of a header plus an array of <index, value>
206  pairs for the non-default entries of the vector.
207 
208  pkcoeff_struct
209 
210  Field Description
211  ----- -----------
212  ndx the column/row index for the coefficient
213  val the value of the coefficient
214 
215  pkvec_struct
216 
217  Field Description
218  ----- -----------
219  ndx the common index for all coefficients when the vector is a
220  row or column from a matrix
221  nme name associated with this vector, if any
222  dim length of the vector when unpacked
223  dflt the default value of coefficients not in coeffs
224  cnt number of non-default coefficients in the coeffs array
225  sze allocated capacity (in pkcoeff_struct's) of the coeffs array
226  coeffs the array of (column/row index, coefficient) pairs
227 
228  NOTE: pkvec_struct->coeffs is indexed from 0 and sized accordingly.
229 */
230 
231 typedef struct { int ndx ;
232  double val ; } pkcoeff_struct ;
233 
234 typedef struct { int ndx ;
235  const char *nme ;
236  int dim ;
237  double dflt ;
238  int cnt ;
239  int sze ;
241 
242 pkvec_struct *pkvec_new(int sze) ;
243 bool pkvec_resize(pkvec_struct *pkvec, int sze) ;
244 void pkvec_free(pkvec_struct *pkvec) ;
245 
246 bool pkvec_check(pkvec_struct *pkvec, const char *caller) ;
247 
248 double pkvec_2norm(pkvec_struct *vec) ;
249 
250 double exvec_1norm(double *vec, int len),
251  exvec_ssq(double *vec, int len),
252  exvec_2norm(double *vec, int len),
253  exvec_infnorm(double *vec, int len, int *p_jmax) ;
254 
255 double pkvec_dotexvec(pkvec_struct *pkvec, double *exvec) ;
256 
257 #endif /* _DYLP_VECTOR_H */
pkvec_struct * pkvec_new(int sze)
pkcoeff_struct * coeffs
Definition: dy_vector.h:240
bool pkvec_resize(pkvec_struct *pkvec, int sze)
double exvec_2norm(double *vec, int len)
double exvec_infnorm(double *vec, int len, int *p_jmax)
double pkvec_2norm(pkvec_struct *vec)
double pkvec_dotexvec(pkvec_struct *pkvec, double *exvec)
static fpunion_t QNaNbits UNUSED
Definition: dy_vector.h:137
const char * nme
Definition: dy_vector.h:235
double fpdbl
Definition: dy_vector.h:104
void pkvec_free(pkvec_struct *pkvec)
bool pkvec_check(pkvec_struct *pkvec, const char *caller)
double exvec_1norm(double *vec, int len)
double dflt
Definition: dy_vector.h:237
double exvec_ssq(double *vec, int len)