- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# /home/coin/SVN-release/Cgl-0.52.0/DyLP/src/Dylp/dy_vector.h

Go to the documentation of this file.

    00001 /*
    00002   This file is a part of the Dylp LP distribution.
    00003
    00004         Copyright (C) 2005 -- 2007 Lou Hafer
    00005
    00006         School of Computing Science
    00007         Simon Fraser University
    00008         Burnaby, B.C., V5A 1S6, Canada
    00009         lou@cs.sfu.ca
    00010
    00011   This code is licensed under the terms of the Common Public License (CPL).
    00012 */
    00013
    00014 #ifndef _DYLP_VECTOR_H
    00015 #define _DYLP_VECTOR_H
    00016
    00017 /*
    00018   @(#)dy_vector.h         4.5         11/06/04
    00019   svn/cvs: $Id: dy_vector.h 198 2008-01-03 00:43:36Z lou $
    00020 */
    00021
    00022 #include <DylpConfig.h>
    00023
    00024 /*
    00025   Why, you might ask, are we including ctype.h? Well, it's required by the
    00026   ANSI C specification, so it's pretty well guaranteed to exist. And, at least
    00027   in Solaris and Linux environments that I'm familiar with, it'll pull in the
    00028   compile-time symbols that specify big- or little-endian, which we really
    00029   want.
    00030 */
    00031 #include <ctype.h>
    00032
    00033 /*
    00034   A bunch of standard definitions.
    00035 */
    00036 #include "dylib_std.h"
    00037
    00038 /*
    00039   In a few rare instances, the declarations here will be unused, but for dylp
    00040   this is a good bet.
    00041 */
    00042 #include <math.h>
    00043
    00044 /*
    00045   Some subset of these will work on any system. Check config_dylp.h to see
    00046   which ones are actually in use.
    00047 */
    00048 #ifdef HAVE_FLOAT_H
    00049 # include <float.h>
    00050 #endif
    00051 #ifdef HAVE_IEEEFP_H
    00052 # include <ieeefp.h>
    00053 #endif
    00054 #ifdef HAVE_SUNMATH_H
    00055 # include <sunmath.h>
    00056 #endif
    00057
    00058
    00059 /*
    00060   The Theory: quiet_nan is used to indicate failure (by returning NaN)
    00061   without triggering a signal the client may not be prepared to catch. The
    00062   idea is that any reasonable checks in the client will detect NaN fairly
    00063   quickly.  signalling_nan is used when there's no advantage in delaying a
    00064   signal.
    00065
    00066   The Reality: Neither seems to trigger a signal, and many computing
    00067   environments can't tell the difference. But it's coded into dylp, and it'd
    00068   be much ado to change. Hence the compile-time ugliness that follows.
    00069
    00070   In the Sun Workshop environment, quiet_nan and signalling_nan are declared
    00071   in sunmath.h and found in libsunmath. With release 5.0, sunmath.h includes
    00072   some declarations of type `long long', which isn't supported under the -Xc
    00073   (strict ANSI compatibility) option for cc. So, we extract only the
    00074   definitions we need.  Unfortunately, sunmath.h is present only in the Sun
    00075   Workshop programming environment. Sun without Workshop has only the
    00076   require file nan.h, which is inadequate.
    00077
    00078   For a long while, GNU C didn't distinguish QNaN and SNaN. More recently,
    00079   its support for IEEE 754 seems to have improved, but it's not clear that we
    00080   can count on everyone having a recent GCC environment just yet. Here, too,
    00081   nan.h is inadequate.  The easy way out is to simply #define them as macros
    00082   that return the proper bit pattern. Arguably this would make more sense in
    00083   general than Sun's implementation as functions.
    00084
    00085   According to IEEE 754, the proper bit patterns are:
    00086
    00087     0x7ff00000 00000000                  for Inf
    00088     0x7fffffff ffffffff                  for QNaN
    00089     0x7ff00000 00000001                  for SNaN
    00090
    00091   It works this way: The IEEE definition of NaN is
    00092     Bits         Value
    00093     63                  sign --- don't care for a NaN, but nice to be positive (0)
    00094     62:52         exponent --- must be maximum value, 0x7ff
    00095     51:0         fraction --- must not be zero (a fraction of zero is the
    00096                   representation of infinity). Sun documentation defines QNaN
    00097                   as having bit 51 of the fraction set to 1, SNaN as having
    00098                   bit 51 set to 0.
    00099
    00100   Creating the proper constants qualifies as a serious gross hack. And if you
    00101   have a little-endian machine (the 80x86 family being far and away the most
    00102   common example), you need to flip the byte order.
    00103 */
    00104   typedef union { unsigned char fpchr[8] ; double fpdbl ; } fpunion_t ;
    00105 /*
    00106   Yes, all this really is needed to get all the various compilers to quit
    00107   complaining. We need the `(unsigned char)' to prevent some compilers from
    00108   complaining about the initialiser being out of range. Goes to the ANSI C
    00109   rule that `Character constants not preceded by the letter L have type int.'
    00110 */
    00111 #ifdef WORDS_BIGENDIAN
    00112     static fpunion_t QNaNbits UNUSED = { { (unsigned char) '\177',
    00113                                         (unsigned char) '\377',
    00114                                         (unsigned char) '\377',
    00115                                         (unsigned char) '\377',
    00116                                         (unsigned char) '\377',
    00117                                         (unsigned char) '\377',
    00118                                         (unsigned char) '\377',
    00119                                         (unsigned char) '\376' } } ;
    00120     static fpunion_t SNaNbits UNUSED = { { (unsigned char) '\177',
    00121                                         (unsigned char) '\360',
    00122                                         (unsigned char) '\0',
    00123                                         (unsigned char) '\0',
    00124                                         (unsigned char) '\0',
    00125                                         (unsigned char) '\0',
    00126                                         (unsigned char) '\0',
    00127                                         (unsigned char) '\001' } } ;
    00128     static fpunion_t Infbits UNUSED = { { (unsigned char) '\177',
    00129                                        (unsigned char) '\360',
    00130                                        (unsigned char) '\0',
    00131                                        (unsigned char) '\0',
    00132                                        (unsigned char) '\0',
    00133                                        (unsigned char) '\0',
    00134                                        (unsigned char) '\0',
    00135                                        (unsigned char) '\0' } } ;
    00136 #else
    00137     static fpunion_t QNaNbits UNUSED = { { (unsigned char) '\376',
    00138                                         (unsigned char) '\377',
    00139                                         (unsigned char) '\377',
    00140                                         (unsigned char) '\377',
    00141                                        (unsigned char) '\377',
    00142                                         (unsigned char) '\377',
    00143                                         (unsigned char) '\377',
    00144                                         (unsigned char) '\177' } } ;
    00145     static fpunion_t SNaNbits UNUSED = { { (unsigned char) '\001',
    00146                                         (unsigned char) '\0',
    00147                                         (unsigned char) '\0',
    00148                                         (unsigned char) '\0',
    00149                                         (unsigned char) '\0',
    00150                                         (unsigned char) '\0',
    00151                                         (unsigned char) '\360',
    00152                                         (unsigned char) '\177' } } ;
    00153     static fpunion_t Infbits UNUSED = { { (unsigned char) '\0',
    00154                                        (unsigned char) '\0',
    00155                                        (unsigned char) '\0',
    00156                                        (unsigned char) '\0',
    00157                                        (unsigned char) '\0',
    00158                                        (unsigned char) '\0',
    00159                                        (unsigned char) '\360',
    00160                                        (unsigned char) '\177' } } ;
    00161 #endif /* WORDS_BIGENDIAN */
    00162
    00163 /*
    00164   If we didn't find a quiet_nan function, fake it with a macro.
    00165 */
    00166
    00167 #ifndef DYLP_HAS_QUIET_NAN
    00168 # define quiet_nan(zz_dummy_zz) (QNaNbits.fpdbl)
    00169 #endif
    00170
    00171 /*
    00172   On some machines, HUGE_VAL isn't actually IEEE infinity. Make sure that
    00173   it really is IEEE infinity.
    00174 */
    00175
    00176 #undef HUGE_VAL
    00177 #define HUGE_VAL (Infbits.fpdbl)
    00178
    00179 /*
    00180   In a Sun/Solaris environment, the definitions and functions that support
    00181   IEEE floating point are in ieeefp.h. This seems to be true even if GNU
    00182   compilers are being used instead of Sun Workshop compilers. In a GNU/Linux
    00183   environment, the necessary definitions seem to live in math.h. The upshot
    00184   is that we need to explicitly pull in ieeefp.h here for a Sun environment.
    00185
    00186   In a Microsoft environment the correct functions look to be _finite and
    00187   _isnan from float.h.
    00188
    00189   Assign the proper names to finite and isnan, based on the values deduced by
    00190   configure. Again, check config_dylp to see the actual names. If either name
    00191   is already defined, bet that it's the correct definition.
    00192 */
    00193
    00194 #ifndef finite
    00195 # define finite DYLP_ISFINITE
    00196 #endif
    00197 #ifndef isnan
    00198 # define isnan  DYLP_ISNAN
    00199 #endif
    00200
    00201
    00202 /*
    00203   Packed Vectors
    00204
    00205   The packed vector type consists of a header plus an array of <index, value>
    00206   pairs for the non-default entries of the vector.
    00207
    00208   pkcoeff_struct
    00209
    00210   Field         Description
    00211   -----         -----------
    00212   ndx           the column/row index for the coefficient
    00213   val           the value of the coefficient
    00214
    00215   pkvec_struct
    00216
    00217   Field         Description
    00218   -----         -----------
    00219   ndx           the common index for all coefficients when the vector is a
    00220                 row or column from a matrix
    00221   nme           name associated with this vector, if any
    00222   dim           length of the vector when unpacked
    00223   dflt          the default value of coefficients not in coeffs
    00224   cnt           number of non-default coefficients in the coeffs array
    00225   sze           allocated capacity (in pkcoeff_struct's) of the coeffs array
    00226   coeffs        the array of (column/row index, coefficient) pairs
    00227
    00228   NOTE: pkvec_struct->coeffs is indexed from 0 and sized accordingly.
    00229 */
    00230
    00231 typedef struct { int ndx ;
    00232                    double val ; } pkcoeff_struct ;
    00233
    00234 typedef struct { int ndx ;
    00235                    const char *nme ;
    00236                    int dim ;
    00237                    double dflt ;
    00238                    int cnt ;
    00239                    int sze ;
    00240                    pkcoeff_struct *coeffs ; } pkvec_struct ;
    00241
    00242 pkvec_struct *pkvec_new(int sze) ;
    00243 bool pkvec_resize(pkvec_struct *pkvec, int sze) ;
    00244 void pkvec_free(pkvec_struct *pkvec) ;
    00245
    00246 bool pkvec_check(pkvec_struct *pkvec, const char *caller) ;
    00247
    00248 double pkvec_2norm(pkvec_struct *vec) ;
    00249
    00250 double exvec_1norm(double *vec, int len),
    00251        exvec_ssq(double *vec, int len),
    00252        exvec_2norm(double *vec, int len),
    00253        exvec_infnorm(double *vec, int len, int *p_jmax) ;
    00254
    00255 double pkvec_dotexvec(pkvec_struct *pkvec, double *exvec) ;
    00256
    00257 #endif /* _DYLP_VECTOR_H */