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