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
1.5.1