psVector.h

Go to the documentation of this file.
00001 /* @file  psVector.h
00002  *
00003  * @brief basic vector definitions and operations
00004  *
00005  * This file defines the basic type for a vector struct and functions useful
00006  * in manupulating vectors.
00007  *
00008  * @author Robert DeSonia, MHPCC
00009  * @author Ross Harman, MHPCC
00010  *
00011  * @version $Revision: 1.61 $ $Name:  $
00012  * @date $Date: 2007/01/23 22:47:23 $
00013  * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
00014  */
00015 
00016 #ifndef PS_VECTOR_H
00017 #define PS_VECTOR_H
00018 
00019 /// @addtogroup MathTypes Mathematical Structures
00020 /// @{
00021 
00022 #include <stdio.h>
00023 #include "psType.h"
00024 
00025 /** An vector to support primitive types.
00026  *
00027  * Struct for maintaining an vector of frequently used primitive types.
00028  *
00029  */
00030 typedef struct
00031 {
00032     psMathType type;                   ///< Type of data.
00033     long n;                            ///< Number of elements in use.
00034     const long nalloc;                 ///< Total number of elements available.
00035     union {
00036         psS8* S8;                      ///< Signed 8-bit integer data.
00037         psS16* S16;                    ///< Signed 16-bit integer data.
00038         psS32* S32;                    ///< Signed 32-bit integer data.
00039         psS64* S64;                    ///< Signed 64-bit integer data.
00040         psU8* U8;                      ///< Unsigned 8-bit integer data.
00041         psU16* U16;                    ///< Unsigned 16-bit integer data.
00042         psU32* U32;                    ///< Unsigned 32-bit integer data.
00043         psU64* U64;                    ///< Unsigned 64-bit integer data.
00044         psF32* F32;                    ///< Single-precision float data.
00045         psF64* F64;                    ///< Double-precision float data.
00046         psC32* C32;                    ///< Single-precision complex data.
00047         psC64* C64;                    ///< Double-precision complex data.
00048     } data;
00049     void *lock;                        ///< Optional lock for thread safety.
00050 }
00051 psVector;
00052 
00053 #define P_PSVECTOR_SET_NALLOC(vec,n) *(long*)&(vec->nalloc) = n
00054 
00055         /*****************************************************************************/
00056 
00057         /* FUNCTION PROTOTYPES                                                       */
00058 
00059         /*****************************************************************************/
00060 
00061         /** Checks the type of a particular pointer.
00062          *
00063          *  Uses the appropriate deallocation function in psMemBlock to check the ptr datatype.
00064          *
00065          *  @return bool:       True if the pointer matches a psVector structure, false otherwise.
00066          */
00067         bool psMemCheckVector(
00068             psPtr ptr                          ///< the pointer whose type to check
00069         )
00070         ;
00071 
00072 /** Allocate a vector, with length set to number allocated
00073  *
00074  *  Uses psLib memory allocation functions to create a vector collection of
00075  *  data as defined by the psType type.
00076  *
00077  * @return psVector*    Pointer to psVector.
00078  */
00079 psVector* psVectorAlloc(
00080     long nalloc,                       ///< Total number of elements to make available.
00081     psElemType type                    ///< Type of data to be held by vector.
00082 );
00083 
00084 /** Allocate a vector, with length set to zero
00085  *
00086  *  Uses psLib memory allocation functions to create a vector collection of
00087  *  data as defined by the psType type.
00088  *
00089  * @return psVector*    Pointer to psVector.
00090  */
00091 psVector* psVectorAllocEmpty(
00092     long nalloc,                       ///< Total number of elements to make available.
00093     psElemType type                    ///< Type of data to be held by vector.
00094 );
00095 
00096 /** Reallocate a vector.
00097  *
00098  *  Uses psLib memory allocation functions to reallocate a vector collection
00099  *  of data. The vector is reallocated according to the psType type member
00100  *  contained within the vector.
00101  *
00102  *  @return psVector*      Pointer to psVector.
00103  *
00104  */
00105 psVector* psVectorRealloc(
00106     psVector* vector,                  ///< Vector to reallocate.
00107     long nalloc                        ///< Total number of elements to make available.
00108 );
00109 
00110 /** Extend a vector's length.
00111  *
00112  *  Increments a vector's length, n, by the specified number of elements.
00113  *  If the allocated storage is less than the current vector's length plus
00114  *  twice the number of elements to be added, it is reallocated larger by
00115  *  a given amount.
00116  *
00117  *  @return psVector*      Pointer to the adjusted psVector
00118  */
00119 psVector *psVectorExtend(
00120     psVector *vector,                  ///< Vector to extend
00121     long delta,                        ///< Amount to expand allocation, if necessary
00122     long nExtend                       ///< Number of elements to add to vector length
00123 );
00124 
00125 /** Recycle a vector.
00126  *
00127  *  Uses psLib memory allocation functions to reallocate a vector collection
00128  *  of data. The vector is reallocated according to the psElemType type
00129  *  parameter.
00130  *
00131  * @return psVector*       Pointer to psVector.
00132  *
00133  */
00134 psVector* psVectorRecycle(
00135     psVector* vector,
00136     ///< Vector to recycle.  If NULL, a new vector is created.  No effort
00137     ///< taken to preserve the values.
00138 
00139     long nalloc,                       ///< Total number of elements to make available.
00140     psElemType type                    ///< the datatype of the returned vector
00141 );
00142 
00143 /** Copy a vector, converting types.
00144  *
00145  *  Performs a deep copy of the elements of one psVector to a new psVector,
00146  *  converting numeric types to a specified type.
00147  *
00148  * @return psVector*       Pointer to resulting psVector.
00149  *
00150  */
00151 psVector* psVectorCopy(
00152     psVector* output,                  ///< if non-NULL, a psVector to recycle
00153     const psVector* input,             ///< the vector to copy.
00154     psElemType type                    ///< the data type of the resulting psVector
00155 );
00156 
00157 /** Sort an array of floats.
00158  *
00159  *  Sorts an array of floats in ascending order.  This function is valid for
00160  *  all non-complex data types.
00161  *
00162  *  @return  psVector*     Pointer to sorted psVector.
00163  */
00164 psVector* psVectorSort(
00165     psVector* outVector,               ///< the output vector to recycle, or NULL if new vector desired.
00166     const psVector* inVector           ///< the vector to sort.
00167 );
00168 
00169 /** Creates an array of indices based on sort ordered of array.
00170  *
00171  *  Sorts a vector and creates an integer array holding indices of
00172  *  sorted float values based on pre-sort index positions.
00173  *
00174  *  @return  psVector*     vector of the indices of sort.
00175  */
00176 psVector* psVectorSortIndex(
00177     psVector* outVector,               ///< vector to recycle
00178     const psVector* inVector           ///< vector to sort
00179 );
00180 
00181 /** Creates a string from a psVector's values in the form "[x0,x1,x2]".
00182  *
00183  *  @return psPtr          a newly allocated string
00184  */
00185 psString psVectorToString(
00186     const psVector* vector,             ///< vector to create a string from
00187     int maxLength                      ///< the maximum length of the resulting string
00188 );
00189 
00190 /** Returns an element in the vector as a psF64 value
00191  *
00192  *  @return psF64          the value at specified position, or NAN if position is invalid.
00193  */
00194 psF64 p_psVectorGetElementF64(
00195     const psVector* vector,                  ///< vector to retrieve element
00196     int position                       ///< the vector position to get
00197 );
00198 
00199 /** Print a vector to a stream
00200  *
00201  *  @return psBool          TRUE is successful, otherwise FALSE.
00202  */
00203 bool p_psVectorPrint (
00204     int fd,                            ///< output file descriptor
00205     const psVector *a,                       ///< vector to print
00206     char *name                         ///< name of vector (for title)
00207 );
00208 
00209 /** Initializes the vector with the given value.
00210  *
00211  *  The input data is cast to match the vector datatype, allowing for integers to be preserved.
00212  *
00213  *  @return bool:       True if successful, otherwise false.
00214  */
00215 bool psVectorInit(
00216     psVector *vector,                  ///< the vector to be initialized
00217     ...                                ///< Variable argument list for initialization
00218 );
00219 
00220 /** Creates a new vector, or reallocates the provided vector if input is not NULL.
00221  *
00222  *  The created vector consists of the data range starting at lower, running to upper,
00223  *  in steps of delta.  The upper-end value is exclusive; the sequence is equivalent to
00224  *  for (x = lower; x <= upper - 1; x += delta).
00225  *
00226  *  @return psVector*:       the newly created psVector
00227  */
00228 psVector *psVectorCreate (
00229     psVector *input,                   ///< Input vector
00230     double lower,                      ///< lower bound
00231     double upper,                      ///< upper bound
00232     double delta,                      ///< size of increment
00233     psElemType type                    ///< type of vector to create
00234 );
00235 
00236 /** Sets the value of the input vector at the specified position to value.
00237  *
00238  *  A negative position means index from the end.
00239  *
00240  *  @return bool:       True if successful, otherwise false.
00241  */
00242 bool psVectorSet(
00243     psVector *input,                   ///< Input vector to set
00244     long position,                     ///< vector position
00245     double complex value               ///< value to set
00246 );
00247 
00248 /** Returns the value of the input vector at the specified position.
00249  *
00250  *  A negative position means index from the end.
00251  *
00252  *  @return complex:        Value of the input vector at the specified position.
00253  */
00254 double complex psVectorGet(
00255     const psVector *input,             ///< Input vector from which to get value
00256     long position                      ///< vector position
00257 );
00258 
00259 /** Returns the number of pixels in the vector which satisfy any of the mask bits.
00260  *
00261  *  An error (eg, invalid vector) results in a return value of -1.  The vector must be U8.
00262  *
00263  *  @return long:       the number of pixels counted
00264  */
00265 long psVectorCountPixelMask(
00266     psVector *mask,                    ///< input vector to count
00267     psMaskType value                   ///< the mask value to satisfy
00268 );
00269 
00270 /** Get the number of elements in use from a specified psVector. (vector.n)
00271  *
00272  *  @return long:       The number of elements in use.
00273  */
00274 long psVectorLength(
00275     const psVector *vector             ///< input psVector
00276 );
00277 
00278 
00279 /*****************************************************************************
00280     PS_VECTOR macros:
00281  *****************************************************************************/
00282 
00283 #define PS_ASSERT_VECTOR_NON_NULL(NAME, RVAL) PS_ASSERT_GENERAL_VECTOR_NON_NULL(NAME, return RVAL)
00284 #define PS_ASSERT_GENERAL_VECTOR_NON_NULL(NAME, CLEANUP) \
00285 if ((NAME) == NULL || (NAME)->data.U8 == NULL) { \
00286     psError(PS_ERR_BAD_PARAMETER_NULL, true, \
00287             "Unallowable operation: psVector %s or its data is NULL.", \
00288             #NAME); \
00289     CLEANUP; \
00290 } \
00291 
00292 #define PS_ASSERT_VECTOR_NON_EMPTY(NAME, RVAL) PS_ASSERT_GENERAL_VECTOR_NON_EMPTY(NAME, return RVAL)
00293 #define PS_ASSERT_GENERAL_VECTOR_NON_EMPTY(NAME, CLEANUP) \
00294 if ((NAME)->n < 1) { \
00295     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
00296             "Unallowable operation: psVector %s has no elements.", \
00297             #NAME); \
00298     CLEANUP; \
00299 } \
00300 
00301 #define PS_ASSERT_VECTOR_TYPE_F32_OR_F64(NAME, RVAL) \
00302 if (((NAME)->type.type != PS_TYPE_F32) && ((NAME)->type.type != PS_TYPE_F64)) { \
00303     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
00304             "psVector %s: bad type(%d)", \
00305             #NAME, (NAME)->type.type); \
00306     return(RVAL); \
00307 } \
00308 
00309 #define PS_ASSERT_VECTOR_TYPE_S16_S32_F32(NAME, RVAL) \
00310 if (((NAME)->type.type != PS_TYPE_S16) && ((NAME)->type.type != PS_TYPE_S32) && ((NAME)->type.type != PS_TYPE_F32)) { \
00311     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
00312             "psVector %s: bad type(%d)", \
00313             #NAME, (NAME)->type.type); \
00314     return(RVAL); \
00315 } \
00316 
00317 #define PS_ASSERT_VECTOR_TYPE(NAME, TYPE, RVAL) \
00318 if ((NAME)->type.type != TYPE) { \
00319     psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
00320             "Unallowable operation: psVector %s has incorrect type.", \
00321             #NAME); \
00322     return(RVAL); \
00323 }
00324 
00325 #define PS_ASSERT_VECTORS_SIZE_EQUAL(VEC1, VEC2, RVAL) \
00326 if ((VEC1)->n != (VEC2)->n) { \
00327     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
00328             "psVector %s has size %ld, psVector %s has size %ld.", \
00329             #VEC1, (VEC1)->n, #VEC2, (VEC2)->n); \
00330     return(RVAL); \
00331 }
00332 
00333 #define PS_ASSERT_VECTOR_SIZE(VEC, SIZE, RVAL) \
00334 if ((VEC)->n != (SIZE)) { \
00335     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
00336             "psVector %s has size %ld, should be %ld.", \
00337             #VEC, (VEC)->n, (SIZE)); \
00338     return(RVAL); \
00339 }
00340 
00341 #define PS_ASSERT_VECTOR_TYPE_EQUAL(VEC1, VEC2, RVAL) \
00342 if ((VEC1)->type.type != (VEC2)->type.type) { \
00343     psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
00344             "psVector %s has size %d, psVector %s has size %d.", \
00345             #VEC1, (VEC1)->type.type, #VEC2, (VEC2)->type.type); \
00346     return(RVAL); \
00347 }
00348 
00349 #define PS_VECTOR_PRINT_F32(NAME) \
00350 if ((NAME) != NULL) { \
00351     for (int i = 0; i < (NAME)->n; i++) { \
00352         printf("%s->data.F32[%d] is %f\n", #NAME, i, (NAME)->data.F32[i]); \
00353     } \
00354     printf("\n"); \
00355 } else {\
00356     printf("MACRO WARNING: vector %s is NULL.\n", #NAME); \
00357 }\
00358 
00359 #define PS_VECTOR_PRINT_F64(NAME) \
00360 if ((NAME) != NULL) { \
00361     for (int i = 0; i < (NAME)->n; i++) { \
00362         printf("%s->data.F64[%d] is %f\n", #NAME, i, (NAME)->data.F64[i]); \
00363     } \
00364     printf("\n"); \
00365 } else {\
00366     printf("MACRO WARNING: vector %s is NULL.\n", #NAME); \
00367 }\
00368 
00369 /// @}
00370 #endif // #ifndef PS_VECTOR_H

Generated on Fri Feb 2 22:24:35 2007 for pslib by  doxygen 1.5.1