DyLP 1.10.4
Loading...
Searching...
No Matches
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 isfinite
202#endif
203
204#endif
205
206/*
207 Packed Vectors
208
209 The packed vector type consists of a header plus an array of <index, value>
210 pairs for the non-default entries of the vector.
211
212 pkcoeff_struct
213
214 Field Description
215 ----- -----------
216 ndx the column/row index for the coefficient
217 val the value of the coefficient
218
219 pkvec_struct
220
221 Field Description
222 ----- -----------
223 ndx the common index for all coefficients when the vector is a
224 row or column from a matrix
225 nme name associated with this vector, if any
226 dim length of the vector when unpacked
227 dflt the default value of coefficients not in coeffs
228 cnt number of non-default coefficients in the coeffs array
229 sze allocated capacity (in pkcoeff_struct's) of the coeffs array
230 coeffs the array of (column/row index, coefficient) pairs
231
232 NOTE: pkvec_struct->coeffs is indexed from 0 and sized accordingly.
233*/
234
235typedef struct { int ndx ;
236 double val ; } pkcoeff_struct ;
237
238typedef struct { int ndx ;
239 const char *nme ;
240 int dim ;
241 double dflt ;
242 int cnt ;
243 int sze ;
245
247bool pkvec_resize(pkvec_struct *pkvec, int sze) ;
249
250bool pkvec_check(pkvec_struct *pkvec, const char *caller) ;
251
253
254double exvec_1norm(double *vec, int len),
255 exvec_ssq(double *vec, int len),
256 exvec_2norm(double *vec, int len),
257 exvec_infnorm(double *vec, int len, int *p_jmax) ;
258
259double pkvec_dotexvec(pkvec_struct *pkvec, double *exvec) ;
260
261#endif /* _DYLP_VECTOR_H */
double exvec_ssq(double *vec, int len)
void pkvec_free(pkvec_struct *pkvec)
double exvec_2norm(double *vec, int len)
double pkvec_dotexvec(pkvec_struct *pkvec, double *exvec)
pkvec_struct * pkvec_new(int sze)
bool pkvec_check(pkvec_struct *pkvec, const char *caller)
double exvec_1norm(double *vec, int len)
bool pkvec_resize(pkvec_struct *pkvec, int sze)
double exvec_infnorm(double *vec, int len, int *p_jmax)
double pkvec_2norm(pkvec_struct *vec)
#define UNUSED
Definition dylib_std.h:44
double dflt
Definition dy_vector.h:241
pkcoeff_struct * coeffs
Definition dy_vector.h:244
const char * nme
Definition dy_vector.h:239