/*
******************************************************************************** * stat.c -- Routines for statistical series objects * * User routines * Pro_StatCovar() returns the covariance of a pair of series * samples. * Pro_StatRange() returns the range of samples correlated with a * a specified sample. * * Programmer routines * XPro_MakeStat() used to create a new statistical series object. * XPro_StatPtr() returns a pointer to the sub-object. * * Version 1.0: Original release. * Mark Showalter & Neil Heather, PDS Ring-Moon Systems Node, March 1998. * Version 1.1: QUICK compilation mode and Pro_StatRange() function added. * Mark Showalter, January 2000 *******************************************************************************/ #include <stdio.h> #include "profile.h" #include "fortran.h" /******************** * Type definitions * ********************/ typedef struct ZPRO_STAT_STRUCT { XPRO_CLASS class; RL_FLT8 (*covarfunc) RL_PROTO((RL_VOID *pointer, RL_INT4 k1, RL_INT4 k2)); void (*rangefunc) RL_PROTO((RL_VOID *pointer, RL_INT4 k, RL_INT4 *k1, RL_INT4 *k2)); RL_FLT8 (*evalfunc) RL_PROTO((RL_VOID *pointer, RL_INT4 k, RL_INT4 *flag)); void (*freefunc) RL_PROTO((RL_VOID *pointer)); void (*printfunc) RL_PROTO((RL_VOID *pointer)); } ZPRO_STAT; /******************** * Static variables * ********************/ static XPRO_CLASS stat_class = {XPRO_STAT_CLASS, "statistical", NULL}; /******************************** * Internal function prototypes * ********************************/ static RL_FLT8 ZPro_EvalStat RL_PROTO((RL_VOID *pointer, RL_INT4 k, RL_INT4 *flag)); static void ZPro_FreeStat RL_PROTO((RL_VOID *pointer)); static void ZPro_PrintStat RL_PROTO((RL_VOID *pointer)); static ZPRO_STAT *ZPro_GetStat RL_PROTO((PRO_OBJECT *object)); /********************* * Macro definitions * *********************/ #ifdef QUICK #define ZPro_GetStat(object) ((ZPRO_STAT *) XPro_SeriesPtr(object)) #endif /* ******************************************************************************** * EXPORTED USER ROUTINES ******************************************************************************** *$ Component_name: * Pro_StatCovar (stat.c) *$ Abstract: * This routine returns the covariance between two samples in a statistical * series. *$ Keywords: * PROFILE, SERIES * C, PUBLIC, SUBROUTINE *$ Declarations: * RL_FLT8 Pro_StatCovar(object, k1, k2) * PRO_OBJECT *object; * RL_INT4 k1, k2; *$ Inputs: * object pointer to a statistical series object. * k1, k2 sample indices for which to calculate covariance. *$ Outputs: * none *$ Returns: * value of the covariance between the given samples, or 0. on non-fatal * error. *$ Detailed_description: * This routine returns the covariance between two samples in a statistical * series. A statistical series extends the properties of a series by * the property that, given any pair of samples, it can evaluate the * statistical covariance between them. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose stat is a statistical series comprising uncorrelated Poisson * random numbers of mean 100. * * Then Pro_StatCovar(stat, k, k) returns 100. for k within the domain; * Pro_StatCovar(stat, j, k) returns 0. for j != k. *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a stat series. * PRO_DOMAIN_ERROR if either sample index is outside the series' * domain. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 * 1.1: October 1999 *$ Change_history: * 1.1: QUICK mode compile option added. *******************************************************************************/ RL_FLT8 Pro_StatCovar(object, k1, k2) PRO_OBJECT *object; RL_INT4 k1, k2; { ZPRO_STAT *stat; RL_INT4 klo, khi; stat = ZPro_GetStat(object); #ifndef QUICK if (stat == NULL) return 0.; #endif /* Make sure indices are inside domain */ (void) Pro_SeriesIndices(object, &klo, &khi); if (k1 < klo || k1 > khi) { XPro_IDomainError("index #1", object, klo, khi, k1); return 0.; } if (k2 < klo || k2 > khi) { XPro_IDomainError("index #2", object, klo, khi, k2); return 0.; } /* Otherwise evaluate covariance */ return (stat->covarfunc)(stat->class.pointer, k1, k2); } /* ******************************************************************************** *$ Component_name: * Pro_StatRange (stat.c) *$ Abstract: * This routine returns the range of indices in a series where samples * might have a nonzero covariance with a given sample. *$ Keywords: * PROFILE, SERIES * C, PUBLIC, SUBROUTINE *$ Declarations: * RL_INT4 Pro_StatRange(object, k, k1, k2) * PRO_OBJECT *object; * RL_INT4 k, *k1, *k2; *$ Inputs: * object pointer to a statistical series object. * k index at which to evaluate range of correlated samples. *$ Outputs: * k1, k2 range of sample indices for which the covariance might * be nonzero. *$ Returns: * size of range returned, i.e. k2-k1+1, or zero on non-fatal error. *$ Detailed_description: * This routine returns the range of indices in a series where samples * might have a nonzero covariance with a given sample. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose stat is a statistical series comprising uncorrelated samples. * * Then Pro_StatRange(stat, k, &k1, &k2) returns 1 and sets k1=k; k2=k. *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a stat series. * PRO_DOMAIN_ERROR if either sample index is outside the series' * domain. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.1: January 2000 *$ Change_history: * none *******************************************************************************/ RL_INT4 Pro_StatRange(object, k, k1, k2) PRO_OBJECT *object; RL_INT4 k, *k1, *k2; { ZPRO_STAT *stat; RL_INT4 klo, khi; stat = ZPro_GetStat(object); #ifndef QUICK if (stat == NULL) return 0; #endif /* Make sure index is inside domain */ (void) Pro_SeriesIndices(object, &klo, &khi); if (k < klo || k > khi) { XPro_IDomainError("index #1", object, klo, khi, k); return 0; } /* Otherwise evaluate covariance range */ (stat->rangefunc)(stat->class.pointer, k, k1, k2); if (*k1 < klo) *k1 = klo; if (*k2 > khi) *k2 = khi; return (*k2 - *k1 + 1); } /* ******************************************************************************* * PROGRAMMER ROUTINES ******************************************************************************** * XPro_MakeStat(k1, k2, x1, dx, evalfunc, covarfunc, rangefunc, freefunc, * printfunc, pointer) * * This routine creates and initializes a statistical series object. * * Inputs: * k1, k2 index limits. * x1 minimum X value, corresponding to first sample. * dx x-interval between consecutive samples. * evalfunc routine to evaluate series. * covarfunc routine to evaluate covariance. * rangefunc routine to evaluate nonzero covariance sample range. * freefunc routine to free data structure. * printfunc routine to print series data structure * pointer pointer to an arbitrary data structure describing the * series. * * Returns: new statistical series object. * * Errors: * RL_MEMORY_ERROR on memory allocation failure. *******************************************************************************/ PRO_OBJECT *XPro_MakeStat(k1, k2, x1, dx, evalfunc, covarfunc, rangefunc, freefunc, printfunc, pointer) RL_INT4 k1, k2; RL_FLT8 x1, dx; RL_FLT8 (*evalfunc) RL_PROTO((RL_VOID *pointer, RL_INT4 k, RL_INT4 *flag)); RL_FLT8 (*covarfunc) RL_PROTO((RL_VOID *pointer, RL_INT4 k1, RL_INT4 k2)); void (*rangefunc) RL_PROTO((RL_VOID *pointer, RL_INT4 k, RL_INT4 *k1, RL_INT4 *k2)); void (*freefunc) RL_PROTO((RL_VOID *pointer)); void (*printfunc) RL_PROTO((RL_VOID *pointer)); RL_VOID *pointer; { ZPRO_STAT *stat; PRO_OBJECT *new; /* Allocate new statistical series structure */ stat = (ZPRO_STAT *) XRL_Malloc(sizeof(ZPRO_STAT)); if (stat == NULL) return NULL; /* Initialize structure */ stat->class = stat_class; stat->class.pointer = pointer; stat->evalfunc = evalfunc; stat->covarfunc = covarfunc; stat->rangefunc = rangefunc; stat->freefunc = freefunc; stat->printfunc = printfunc; /* Create new series object */ new = XPro_MakeSeries(k1, k2, x1, dx, ZPro_EvalStat, ZPro_FreeStat, ZPro_PrintStat, (RL_VOID *) stat); return new; } /* ******************************************************************************* * XPro_StatPtr(object) * * This routine returns a pointer to the statistical series sub-object. * * Inputs: * object statistical series object. * * Return: pointer field of the object; NULL on error. * * Errors: * PRO_CLASS_ERROR if the object is NULL or not a stat series. *******************************************************************************/ #ifndef QUICK /* In QUICK mode, this is defined as a macro in profile.h */ RL_VOID *XPro_StatPtr(object) PRO_OBJECT *object; { ZPRO_STAT *stat; stat = ZPro_GetStat(object); if (stat == NULL) return NULL; if (stat->class.pointer == NULL) XPro_NullError("statistical series sub-object", object); return stat->class.pointer; } #endif /* ******************************************************************************* * INTERNAL ROUTINES ******************************************************************************** * ZPro_EvalStat(pointer, k, flag) * * This internal routine evaluates the value of a statistical series. It serves * as the standard "evalfunc" for the parent series object. * * Inputs: * pointer pointer to the ZPRO_STAT structure. * k index at which to evaluate series. * * Outputs: * *flag flag value of series. * * Returns: value of series at k. *******************************************************************************/ static RL_FLT8 ZPro_EvalStat(pointer, k, flag) RL_VOID *pointer; RL_INT4 k, *flag; { ZPRO_STAT *stat; RL_FLT8 value; stat = (ZPRO_STAT *) pointer; value = (stat->evalfunc)(stat->class.pointer, k, flag); return value; } /* ******************************************************************************* * ZPro_FreeStat(pointer) * * This internal routine deallocates the memory used by a statistical series * object. It serves as the standard "freefunc" for the parent series object. * * Input: * pointer pointer to the ZPRO_STAT structure. *******************************************************************************/ static void ZPro_FreeStat(pointer) RL_VOID *pointer; { ZPRO_STAT *stat; stat = (ZPRO_STAT *) pointer; (stat->freefunc)(stat->class.pointer); XRL_Free(stat); } /* ******************************************************************************* * ZPro_PrintStat(pointer) * * This internal routine prints information about a statistical series object. * It serves as the standard "printfunc" for the parent function object. * * Input: * pointer pointer to the ZPRO_STAT structure. *******************************************************************************/ static void ZPro_PrintStat(pointer) RL_VOID *pointer; { ZPRO_STAT *stat; RL_INT4 i; RL_CHAR *type; stat = (ZPRO_STAT *) pointer; /* Make sure object is not NULL */ if (stat == NULL) { printf("PRINT ERROR: Statistical series pointer is NULL\n"); return; } /* Make sure object is a statistical series */ if (stat->class.id != XPRO_STAT_CLASS) { printf("PRINT ERROR: Object is not a statistical series\n"); return; } /* No object info to print at this level */ /* Print more detailed info */ (stat->printfunc)(stat->class.pointer); return; } /* ******************************************************************************* * ZPro_GetStat(object) * * This internal routine confirms that the given object is a statistical series * and returns a pointer to the ZPRO_STAT data structure. * * Input: * object statistical series object. * * Errors: * PRO_CLASS_ERROR if object is NULL or is not a stat series. *******************************************************************************/ #ifndef QUICK /* In QUICK mode, this is defined as a macro above */ static ZPRO_STAT *ZPro_GetStat(object) PRO_OBJECT *object; { ZPRO_STAT *stat; /* Find statistical series object pointer */ stat = (ZPRO_STAT *) XPro_SeriesPtr(object); /* Make sure object is a statistical series */ if (stat->class.id != XPRO_STAT_CLASS) { XPro_ClassError("statistical series", object); return NULL; } return stat; } #endif /* ******************************************************************************** * FORTRAN INTERFACE ROUTINES ******************************************************************************** *$ Component_name: * FPro_StatCovar (stat.c) *$ Abstract: * This routine returns the covariance between two samples in a statistical * series. *$ Keywords: * PROFILE, SERIES * FORTRAN, PUBLIC, SUBROUTINE *$ Declarations: * real*8 function FPro_StatCovar(object, k1, k2) * integer*4 object * integer*4 k1, k2 *$ Inputs: * object FORTRAN pointer to a statistical series object. * k1, k2 sample indices for which to calculate covariance. *$ Outputs: * none *$ Returns: * value of the covariance between the given samples, or 0. on non-fatal * error. *$ Detailed_description: * This routine returns the covariance between two samples in a statistical * series. A statistical series extends the properties of a series by * the property that, given any pair of samples, it can evaluate the * statistical covariance between them. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose stat is a statistical series comprising uncorrelated Poisson * random numbers of mean 100. * * Then FPro_StatCovar(stat, k, k) returns 100.d0 for k within the domain; * FPro_StatCovar(stat, j, k) returns 0.d0 for j != k. *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a stat series. * PRO_DOMAIN_ERROR if either sample index is outside the series' * domain. * FORTRAN_POINTER_ERROR if object is not a valid FORTRAN object pointer. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 * 1.1: October 1999 *$ Change_history: * 1.1: QUICK mode compile option added. *******************************************************************************/ RL_FLT8 FORTRAN_NAME(fpro_statcovar) (object, k1, k2) RL_INT4 *object; RL_INT4 *k1, *k2; { RL_VOID *ptr; /* Look up statistical series pointer */ ptr = FORT_GetPointer(*object); #ifndef QUICK if (ptr == NULL) return 0.; #endif /* Call function */ return Pro_StatCovar((PRO_OBJECT *) ptr, *k1, *k2); } /* ******************************************************************************** *$ Component_name: * FPro_StatRange (stat.c) *$ Abstract: * This routine returns the range of indices in a series where samples * might have a nonzero covariance with a given sample. *$ Keywords: * PROFILE, SERIES * FORTRAN, PUBLIC, SUBROUTINE *$ Declarations: * real*4 function FPro_StatRange(object, k, k1, k2) * integer*4 object * integer*4 k1, k2 *$ Inputs: * object FORTRAN pointer to a statistical series object. * k index at which to evaluate range of correlated samples. *$ Outputs: * k1, k2 range of sample indices for which the covariance might * be nonzero. *$ Returns: * size of range returned, i.e. k2-k1+1, or zero on non-fatal error. *$ Detailed_description: * This routine returns the range of indices in a series where samples * might have a nonzero covariance with a given sample. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose stat is a statistical series comprising uncorrelated samples. * * Then FPro_StatRange(stat, k, k1, k2) returns 1 and sets k1=k; k2=k. *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a stat series. * PRO_DOMAIN_ERROR if either sample index is outside the series' * domain. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.1: January 2000 *$ Change_history: * none *******************************************************************************/ RL_INT4 FORTRAN_NAME(fpro_statrange) (object, k, k1, k2) RL_INT4 *object; RL_INT4 *k, *k1, *k2; { RL_VOID *ptr; /* Look up statistical series pointer */ ptr = FORT_GetPointer(*object); #ifndef QUICK if (ptr == NULL) return 0.; #endif /* Call function */ return Pro_StatRange((PRO_OBJECT *) ptr, *k, k1, k2); } /********************************************************************************/