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