Main Page | Data Structures | File List | Data Fields | Globals

doubleArray.c

Go to the documentation of this file.
00001 /* just some information about this file */
00002 #define DOUBLEARRAY_VERSION     "1.1.0"
00003 #define DOUBLEARRAY_DATE        "23-Jun-2003"
00004 
00005 /* structures and typedefs */
00006 
00007 /** @file
00008 * @anchor DoubleArray
00009 * Fault-tolerant structure to store one or more double values.
00010 *
00011 * This structure provides a fault-tolerant way to store several double values. The individual values
00012 * are accessed via their index @b starting @b from @b zero. Therefore, the index of the element with
00013 * the highest index number is one less than @c numberOfElements. The memory allocation of the structure
00014 * is managed via the @ref DoubleArray_create and @ref DoubleArray_destroy functions.
00015 *
00016 * The structure is created with @ref DoubleArray_create, destroyed with @ref DoubleArray_destroy and
00017 * displayed with @ref DoubleArray_display. The structure could also be displayed with function
00018 * @ref DoubleArray_displayIntegers; the individual values of the elements are than treated as integers.
00019 * It could be copied with the function @ref DoubleArray_copy. The number of elements of a structure
00020 * could be found out via @ref DoubleArray_getNumberOfElements. Elements could be assigned values with
00021 * @ref DoubleArray_setValue and the value of an element could be obtained with @ref DoubleArray_getValue.
00022 *
00023 * If an element is accessed via @ref DoubleArray_setValue or @ref DoubleArray_getValue and the index
00024 * is higher than @c numberOfElements - 1 (maximum index of this structure) the define @ref
00025 * IndexOutOfBoundsError is called and the program aborts.
00026 *
00027 * <B>Description of the members:</B><BR><BR>
00028 * @c value - the double values of the structure<BR>
00029 * @c numberOfElements - number of elements in the structure
00030 * @author Uli Fechner
00031 * @version 01/24/2003 - Uli Fechner - initial release
00032 * @version 05/20/2003 - Uli Fechner - added function @ref DoubleArray_calculateMeanAndSd
00033 * @version 05/22/2003 - Uli Fechner - added the member @c identifier und the functions @ref
00034 * DoubleArray_createWithIdentifier and DoubleArray_getIdentifier; adjusted the function @ref
00035 * DoubleArray_copy accordingly
00036 * @version 05/23/2003 - Uli Fechner - SPECIAL MODIFICATION for the RankIt program: added function
00037 * @ref DoubleArray_lessThan
00038 * @version 06/16/2003 - v1.0.1 - Uli Fechner - SPECIAL MODIFICATION for the RankIt program: several
00039 * adjustments in function @ref DoubleArray_calculateMeanAndSd
00040 * @version 06/23/2003 - v1.1.0 - Uli Fechner - bugfix in function @ref DoubleArray_calculateMeanAndSd
00041 * @@code
00042 */
00043 typedef struct
00044 {
00045         double* value;
00046         int numberOfElements;
00047         int identifier;
00048 } DoubleArray;
00049 /** @endcode */
00050 
00051 
00052 /** A pointer to structure @ref DoubleArray is assigned the name @c DoubleArrayPtr. */
00053 typedef DoubleArray* DoubleArrayPtr;
00054 
00055 
00056 /* function prototypes */
00057 
00058 DoubleArrayPtr DoubleArray_create( const int numberOfElements );
00059 
00060 DoubleArrayPtr DoubleArray_createWithIdentifier( const int numberOfElements, const int identifier );
00061 
00062 void DoubleArray_destroy( DoubleArrayPtr dAPtr );
00063 
00064 void DoubleArray_display( void* dAPtr, FILE* outputStream );
00065 
00066 void DoubleArray_displayIntegers( const DoubleArrayPtr dAPtr, FILE* outputStream );
00067 
00068 DoubleArrayPtr DoubleArray_copy( const DoubleArrayPtr dAPtr );
00069 
00070 int DoubleArray_getIdentifier( const DoubleArrayPtr dAPtr );
00071 
00072 int DoubleArray_getNumberOfElements( const DoubleArrayPtr dAPtr );
00073 
00074 void DoubleArray_setValue( const DoubleArrayPtr dAPtr, const int index, const double value );
00075 
00076 double DoubleArray_getValue( const DoubleArrayPtr dAPtr, const int index );
00077 
00078 DoubleArrayPtr DoubleArray_calculateMeanAndSd( const DoubleArrayPtr dAPtr );
00079 
00080 int DoubleArray_lessThan( void* dAPtr1, void* dAPtr2 );
00081 
00082 
00083 /* functions */
00084 
00085 /** Creates a @ref DoubleArray structure.
00086 *
00087 * A @ref DoubleArray structure is created. The number of elements of the structure is given as an
00088 * argument and is not dynamic during the lifetime of a structure @ref DoubleArray.
00089 *
00090 * @param numberOfElements the number of elements of the newly created structure
00091 * @retval DoubleArrayPtr pointer on the newly created structure @ref DoubleArray
00092 * @author Uli Fechner
00093 * @version 01/24/2003 - Uli Fechner - initial release
00094 */
00095 DoubleArrayPtr DoubleArray_create( const int numberOfElements )
00096 {
00097         DoubleArrayPtr dAPtr;
00098         
00099         if( !( dAPtr = calloc( 1, sizeof( DoubleArray ) ) ) )
00100                 MemoryError( "dAPtr", "DoubleArray_create" );
00101         
00102         dAPtr->numberOfElements = numberOfElements;
00103         
00104         if( numberOfElements == 0 )
00105                 dAPtr->value = NULL;
00106         
00107         else
00108         {
00109                 if( !( dAPtr->value = calloc( numberOfElements, sizeof( double ) ) ) )
00110                         MemoryError( "dAPtr->value", "DoubleArray_create" );
00111         }
00112 
00113         return dAPtr;
00114 }
00115 
00116 
00117 /** Creates a @ref DoubleArray structure with an identifier.
00118 *
00119 * A @ref DoubleArray structure is created. The number of elements of the structure is given as an
00120 * argument and is not dynamic during the lifetime of a structure @ref DoubleArray. The second
00121 * argument is an integer that serves as a unique identifier of this @ref DoubleArray. This function
00122 * for the creation of a @ref DoubleArray is useful, if the @ref DoubleArray is part of an array of
00123 * DoubleArrays.
00124 *
00125 * @param numberOfElements the number of elements of the newly created structure
00126 * @param identifier integer that serves as a unique identifier
00127 * @retval DoubleArrayPtr pointer on the newly created structure @ref DoubleArray
00128 * @author Uli Fechner
00129 * @version 05/22/2003 - Uli Fechner - initial release
00130 */
00131 DoubleArrayPtr DoubleArray_createWithIdentifier( const int numberOfElements, const int identifier )
00132 {
00133         DoubleArrayPtr dAPtr;
00134         
00135         if( !( dAPtr = calloc( 1, sizeof( DoubleArray ) ) ) )
00136                 MemoryError( "dAPtr", "DoubleArray_create" );
00137         
00138         dAPtr->numberOfElements = numberOfElements;
00139         dAPtr->identifier = identifier;
00140         
00141         if( numberOfElements == 0 )
00142                 dAPtr->value = NULL;
00143         
00144         else
00145         {
00146                 if( !( dAPtr->value = calloc( numberOfElements, sizeof( double ) ) ) )
00147                         MemoryError( "dAPtr->value", "DoubleArray_create" );
00148         }
00149 
00150         return dAPtr;
00151 }
00152 
00153 
00154 /** Destroys a structure @ref DoubleArray.
00155 *
00156 * The structure @ref DoubleArray the pointer @c dAPtr refers to is destroyed. All allocated memory of
00157 * the structure is automatically freed.
00158 *
00159 * @param dAPtr pointer on the structure @ref DoubleArray that should be destroyed
00160 * @author Uli Fechner
00161 * @version 01/24/2003 - Uli Fechner - initial release
00162 */
00163 void DoubleArray_destroy( DoubleArrayPtr dAPtr )
00164 {
00165         if( dAPtr != NULL )
00166         {
00167                 if( dAPtr->value != NULL )
00168                         free( dAPtr->value );
00169                 free( dAPtr );
00170         }
00171         else
00172         {
00173                 fprintf( stderr, "\n\nERROR: Function 'DoubleArray_destroy' could not destroy a structure\n" );
00174                 fprintf( stderr, "'DoubleArray' that has not been created before!\n" );
00175                 AbortProgram;
00176         }
00177 }
00178 
00179 
00180 /** Copies a structure @ref DoubleArray.
00181 *
00182 * A copy of the structure @ref DoubleArray referred to by @c dAPtr is made. The copy lives in its own
00183 * memory and contains all elements the template contains (sometimes called @c deepcopy).
00184 *
00185 * @param dAPtr pointer on the structure @ref DoubleArray that should be copied
00186 * @retval DoubleArrayPtr pointer on structure @ref DoubleArray containing the copy
00187 * @author Uli Fechner
00188 * @version 01/24/2003 - Uli Fechner - initial release
00189 * @version 05/22/2003 - Uli Fechner - added the copying of the identifier
00190 */
00191 DoubleArrayPtr DoubleArray_copy( const DoubleArrayPtr dAPtr )
00192 {
00193         int counter;
00194         DoubleArrayPtr copyOfDAPtr;
00195         
00196         if( dAPtr == NULL )
00197         {
00198                 fprintf( stderr, "\n\nERROR: Function 'DoubleArray_copy' could not copy a structure\n" );
00199                 fprintf( stderr, "'DoubleArray' that is empty!\n" );
00200                 AbortProgram;
00201         }
00202         
00203         if( !( copyOfDAPtr = calloc( 1, sizeof( DoubleArray ) ) ) )
00204                 MemoryError( "copyOfDAPtr", "DoubleArray_copy" );
00205         
00206         copyOfDAPtr->numberOfElements = DoubleArray_getNumberOfElements( dAPtr );
00207         copyOfDAPtr->identifier = DoubleArray_getIdentifier( dAPtr );
00208         
00209         if( DoubleArray_getNumberOfElements( dAPtr ) == 0 )
00210                 copyOfDAPtr->value = NULL;
00211         
00212         else
00213         {
00214                 if( !( copyOfDAPtr->value = calloc( DoubleArray_getNumberOfElements( dAPtr ), sizeof( double ) ) ) )
00215                         MemoryError( "copyOfDAPtr->value", "DoubleArray_copy" );
00216         }
00217 
00218         for( counter = 0; counter < DoubleArray_getNumberOfElements( dAPtr ); counter++ )
00219                 DoubleArray_setValue( copyOfDAPtr, counter, DoubleArray_getValue( dAPtr, counter ) );
00220         
00221         return copyOfDAPtr;
00222 }
00223 
00224 /** Displays a structure @ref DoubleArray.
00225 *
00226 * The structure @ref DoubleArray the pointer @c dAPtr refers to is displayed on the FILE* @c
00227 * outputStream.
00228 *
00229 * @param dAPtr pointer on the structure @ref DoubleArray that should be displayed
00230 * @param outputStream FILE* on the stream the output should be sent to
00231 * @author Uli Fechner
00232 * @version 01/24/2003 - Uli Fechner - initial release
00233 */
00234 void DoubleArray_display( void* dAPtr, FILE* outputStream )
00235 {
00236         int counter; /* simple counter variable in for loop */
00237         
00238         if( dAPtr == NULL )
00239         {
00240                 fprintf( stderr, "\n\nERROR: Function 'DoubleArray_display' could not display a structure\n" );
00241                 fprintf( stderr, "'DoubleArray' that is empty!\n" );
00242                 AbortProgram;
00243         }
00244 
00245         for( counter = 0; counter < DoubleArray_getNumberOfElements( dAPtr ); counter++ )
00246                 fprintf( outputStream, "%.6f  ", DoubleArray_getValue( dAPtr, counter ) );
00247         fprintf( outputStream, "\n" ); 
00248 }
00249 
00250 /** Displays a structure @ref DoubleArray.
00251 *
00252 * The structure @ref DoubleArray the pointer @c dAPtr refers to is displayed on the FILE* @c
00253 * outputStream. The values of each element contained in @ref DoubleArray are treated as integers.
00254 *
00255 * @param dAPtr pointer on the structure @ref DoubleArray that should be displayed
00256 * @param outputStream FILE* on the stream the output should be sent to
00257 * @author Uli Fechner
00258 * @version 01/24/2003 - Uli Fechner - initial release
00259 */
00260 void DoubleArray_displayIntegers( const DoubleArrayPtr dAPtr, FILE* outputStream )
00261 {
00262         int counter; /* simple counter variable in for loop */
00263         
00264         if( dAPtr == NULL )
00265         {
00266                 fprintf( stderr, "\n\nERROR: Function 'DoubleArray_display' could not display a structure\n" );
00267                 fprintf( stderr, "'DoubleArray' that is empty!\n" );
00268                 AbortProgram;
00269         }
00270 
00271         for( counter = 0; counter < DoubleArray_getNumberOfElements( dAPtr ); counter++ )
00272                 fprintf( outputStream, "%d  ", (int) DoubleArray_getValue( dAPtr, counter ) );
00273         fprintf( outputStream, "\n" ); 
00274 }
00275 
00276 
00277 /** Returns the identifier of a structure @ref DoubleArray.
00278 *
00279 * @param dAPtr pointer on the structure @ref DoubleArray of which the number of elements should be returned
00280 * @retval int unique identifier of the structure @ref DoubleArray
00281 * @author Uli Fechner
00282 * @version 05/22/2003 - Uli Fechner - initial release
00283 */
00284 int DoubleArray_getIdentifier( const DoubleArrayPtr dAPtr )
00285 {
00286         return dAPtr->identifier;
00287 }
00288 
00289 /** Returns the number of elements of a structure @ref DoubleArray.
00290 *
00291 * The number of elements of the structure @ref DoubleArray the pointer @c dAPtr refers to is returned.
00292 *
00293 * @param dAPtr pointer on the structure @ref DoubleArray of which the number of elements should be returned
00294 * @retval int number of elements of the structure @ref DoubleArray
00295 * @author Uli Fechner
00296 * @version 01/24/2003 - Uli Fechner - initial release
00297 */
00298 int DoubleArray_getNumberOfElements( const DoubleArrayPtr dAPtr )
00299 {
00300         return dAPtr->numberOfElements;
00301 }
00302 
00303 
00304 /** The element with index @c index of structure @ref DoubleArray is assigned the value @c value.
00305 *
00306 * The value @c value is assigned to the element with index @c index of the structure @ref DoubleArray
00307 * @c dAPtr points on. If the index @c index is greater than (@c numberOfElements - 1 ), the program
00308 * aborts with the call of the define @ref IndexOutOfBoundsError.
00309 *
00310 * @param dAPtr pointer on the structure @ref DoubleArray that contains the element
00311 * @param index index of the element the value @c value should be assigned to
00312 * @param value value that should be assigned to the element with index @c index
00313 * @author Uli Fechner
00314 * @version 01/24/2003 - Uli Fechner - initial release
00315 */
00316 void DoubleArray_setValue( const DoubleArrayPtr dAPtr, const int index, const double value )
00317 {
00318         if( index >= DoubleArray_getNumberOfElements( dAPtr ) )
00319                 IndexOutOfBoundsError( "DoubleArray", DoubleArray_getNumberOfElements( dAPtr ), index );
00320 
00321         (dAPtr->value)[ index ] = value;
00322 }
00323 
00324 /** The value of the element with index @c index of structure @ref DoubleArray is returned.
00325 *
00326 * The value of the element with index @c index of the structure @ref DoubleArray @c dAPtr points on is
00327 * returned. If the index @c index is greater than (@c numberOfElements - 1 ), the program aborts with
00328 * the call of the define @ref IndexOutOfBoundsError.
00329 *
00330 * @param dAPtr pointer on the structure @ref DoubleArray that contains the element
00331 * @param index index of the element the value should be returned
00332 * @retval double the value of the element with index @c index
00333 * @author Uli Fechner
00334 * @version 01/24/2003 - Uli Fechner - initial release
00335 */
00336 double DoubleArray_getValue( const DoubleArrayPtr dAPtr, const int index )
00337 {
00338         if( index < DoubleArray_getNumberOfElements( dAPtr ) )
00339                 return (dAPtr->value)[ index ];
00340         else
00341                 IndexOutOfBoundsError( "DoubleArray", DoubleArray_getNumberOfElements( dAPtr ), index );
00342 }
00343 
00344 
00345 /** The mean and standard deviation of the values contained in one @ref DoubleArray is calculated.
00346 *
00347 * The return value of this function is a DoubleArrayPtr. The corresponding @ref DoubleArray contains
00348 * two values:
00349 * @li 1st value - arithmetic mean
00350 * @li 2nd value - standard deviation
00351 *
00352 * @param dAPtr pointer on the structure @ref DoubleArray that contains the elements
00353 * @retval DoubleArrayPtr DoubleArray with two values: mean and standard deviation
00354 * @author Uli Fechner
00355 * @version 05/20/2003 - Uli Fechner - initial release
00356 * @version 05/23/2003 - Uli Fechner - SPECIAL MODIFICATION for the RankIt program (see remarks)
00357 * @version 06/16/2003 - Uli Fechner - SPECIAL MODIFICATION for the RankIt program (see remarks)
00358 * @version 06/23/2003 - Uli Fechner - IMPORTANT bugifx: the standard deviation for the active compounds
00359 * was not calculated correctly
00360 */
00361 DoubleArrayPtr DoubleArray_calculateMeanAndSd( const DoubleArrayPtr dAPtr )
00362 {
00363         int counter; /* simpler counter variable in for loop */
00364         int numberOfElements; /* number of elements of the DoubleArray */
00365         double mean = 0.0f; /* used to store the calculated mean value */
00366         double standardDeviation = 0.0f; /* used to store the calculated standard deviation */
00367         /* DoubleArray that contains two values: first the mean and second the standard deviation of dAPtr */
00368         DoubleArrayPtr dAMeanAndSd;
00369         /* if one value of the DoubleArray is zero the mean is divided by numberOfElements - 1 */
00370         int zeroContained = BOOLEAN_FALSE;
00371         
00372         for( counter = 0; counter < DoubleArray_getNumberOfElements( dAPtr ); counter++ )
00373                 if( ( (int) DoubleArray_getValue( dAPtr, counter ) ) == 0 )
00374                         zeroContained = BOOLEAN_TRUE;
00375         
00376         dAMeanAndSd = DoubleArray_create( 2 );
00377         numberOfElements = DoubleArray_getNumberOfElements( dAPtr );
00378                 
00379         /* calculating the mean */
00380         for( counter = 0; counter < numberOfElements; counter++ )
00381                 mean += DoubleArray_getValue( dAPtr, counter );
00382         /* if one element of the DoubleArray is zero the mean is divided by numberOfElements - 1.
00383         This is a special modification for the rankIt program. The element that is zero indicates that
00384         the corresponding Compound is an active compound. Every active compound is one time the query
00385         structure. Hence, it has no real rank for this similarity search and the mean has to be calculated
00386         with one element less than the other, non-active compounds. */
00387         mean /= numberOfElements - zeroContained;
00388         DoubleArray_setValue( dAMeanAndSd, 0, mean );
00389         
00390         /* if there is only one element in daPtr and this element is zero the mean is set to zero */
00391         if( numberOfElements - zeroContained == 0 )
00392                 DoubleArray_setValue( dAMeanAndSd, 0, 0.0f );
00393         
00394         /* calculating the standard deviation */
00395         for( counter = 0; counter < numberOfElements; counter++ )
00396         {
00397                 if( DoubleArray_getValue( dAPtr, counter ) != 0 )
00398                         standardDeviation += pow( mean - DoubleArray_getValue( dAPtr, counter ), 2 );
00399         }
00400         standardDeviation /= ( numberOfElements - 1 - zeroContained );
00401         standardDeviation = sqrt( standardDeviation );
00402         DoubleArray_setValue( dAMeanAndSd, 1, standardDeviation );
00403         
00404         /* it does not make any sense to calculate a standard deviation if there are only 2 values and one
00405         of these two is zero, i.e. the compound is an active compound OR if there is only one value at all */
00406         if( ( numberOfElements == 2 && zeroContained == BOOLEAN_TRUE ) || ( numberOfElements ==1 ) )
00407                 DoubleArray_setValue( dAMeanAndSd, 1, 0.0f );
00408         
00409         return dAMeanAndSd;
00410 }
00411 
00412 /** Evaluates if the @c first value of @c dAPtr1 is less than that of @c dAPtr2.
00413 *
00414 * The function returns @ref BOOLEAN_TRUE if the @c first value of @c dAPtr 1 is less than the
00415 * @c first value of @c dAPtr2 and @ref BOOLEAN_FALSE if this condition is not matched.
00416 *
00417 * @param dAPtr1 pointer on the first structure @ref DoubleArray
00418 * @param dAPtr2 pointer on the second structure @ref DoubleArray
00419 * @author Uli Fechner
00420 * @version 05/23/2003 - Uli Fechner - initial release
00421 */
00422 int DoubleArray_lessThan( void* dAPtr1, void* dAPtr2 )
00423 {
00424         if( DoubleArray_getValue( dAPtr1, 0 ) < DoubleArray_getValue( dAPtr2, 0 ) )
00425                 return BOOLEAN_TRUE;
00426         else
00427                 return BOOLEAN_FALSE;
00428 }

Generated on Tue Nov 9 16:27:11 2004 for retroflux by doxygen 1.3.6