IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 1293


Ignore:
Timestamp:
Jul 23, 2004, 4:46:45 PM (22 years ago)
Author:
gusciora
Message:

...

Location:
trunk/psLib/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/astro/psCoord.c

    r1287 r1293  
    1010 *  @author George Gusciora, MHPCC
    1111 *
    12  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2004-07-23 03:13:39 $
     12 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2004-07-24 02:42:59 $
    1414 *
    1515 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2222#include "psCoord.h"
    2323#include "psMemory.h"
    24 
     24#include "psAbort.h"
     25#include <math.h>
     26#include <float.h>
    2527
    2628psPlane *psPlaneTransformApply(psPlane *out,
     
    127129}
    128130
     131// XXX: Is this the correct way to calculate this?
     132float cot(float x)
     133{
     134    return(1.0 / atan(x));
     135}
     136
     137float arg(float x, float y)
     138{
     139    if (x > 0) {
     140        return(atan(y/x));
     141    } else if ((x==0) && (y==0)) {
     142        return(0.5 * M_PI);
     143    } else if ((x==0) && (y==0)) {
     144        return(-0.5 * M_PI);
     145    } else if ((x==0) && (y==0)) {
     146        return(M_PI + atan(y/x));
     147    } else if ((x==0) && (y==0)) {
     148        return(-M_PI + atan(y/x));
     149    }
     150
     151    psAbort(__func__, "Unacceptable range for (arg(%f, %f).\n", x, y);
     152    return(0.0);
     153}
     154
     155
     156psPlane *psProject(const psSphere *coord,
     157                   const psProjection *projection)
     158{
     159    float R = 0.0;
     160    float alpha = 0.0;
     161    psPlane *tmp= (psPlane *) psAlloc(sizeof(psPlane));
     162
     163    if (projection->type == PS_PROJ_TAN) {
     164        R = cot(coord->r) * (180.0 / M_PI);
     165        tmp->x = R * sin(coord->d);
     166        tmp->y = R * cos(coord->d);
     167
     168    } else if (projection->type == PS_PROJ_SIN) {
     169        R = cos(coord->r) * (180.0 / M_PI);
     170        tmp->x = R * sin(coord->d);
     171        tmp->y = R * cos(coord->d);
     172
     173    } else if (projection->type == PS_PROJ_CAR) {
     174        tmp->x = coord->d;
     175        tmp->y = coord->r;
     176
     177    } else if (projection->type == PS_PROJ_MER) {
     178        tmp->x = coord->d;
     179        tmp->y = log(tan(45.0 + (0.5 * coord->r))) * 180.0/M_PI;
     180
     181    } else if (projection->type == PS_PROJ_AIT) {
     182        alpha = 1.0 / ((180.0 / M_PI) *
     183                       sqrt(1.0 + (cos(coord->r) * cos(0.5 * coord->d) * 0.5)));
     184
     185        tmp->x = 2.0 * alpha * cos(coord->r) * sin(0.5 * coord->d);
     186        tmp->y = alpha * sin(coord->d);
     187
     188    } else if (projection->type == PS_PROJ_PAR) {
     189        psAbort(__func__, "The projection type PS_PROJ_PAR is undefined.\n");
     190
     191    } else if (projection->type == PS_PROJ_GLS) {
     192        psAbort(__func__, "The projection type PS_PROJ_GLG is undefined.\n");
     193    }
     194
     195    return(tmp);
     196}
     197
     198psSphere *psDeproject(const psPlane *coord,
     199                      const psProjection *projection)
     200{
     201    float R = 0.0;
     202    float chu = 0.0;
     203    float chu1 = 0.0;
     204    float chu2 = 0.0;
     205    psSphere *tmp= (psSphere *) psAlloc(sizeof(psSphere));
     206
     207    if (projection->type == PS_PROJ_TAN) {
     208        R = sqrt((coord->x * coord->x) + (coord->y * coord->y));
     209        tmp->d = arg(-coord->y, coord->x);
     210        tmp->r = atan(180.0 / (R * M_PI));
     211
     212    } else if (projection->type == PS_PROJ_SIN) {
     213        R = sqrt((coord->x * coord->x) + (coord->y * coord->y));
     214        tmp->d = arg(-coord->y, coord->x);
     215        tmp->r = acos((R * M_PI) / 180.0);
     216
     217    } else if (projection->type == PS_PROJ_CAR) {
     218        tmp->d = coord->x;
     219        tmp->r = coord->y;
     220
     221    } else if (projection->type == PS_PROJ_MER) {
     222        tmp->d = coord->x;
     223        tmp->r = (2.0 * atan(exp((coord->y * M_PI/180.0)))) - 180.0;
     224
     225    } else if (projection->type == PS_PROJ_AIT) {
     226        chu1 = (coord->x * M_PI) / 720.0;
     227        chu1*= chu1;
     228        chu2 = (coord->y * M_PI) / 360.0;
     229        chu2*= chu2;
     230        chu = sqrt(1.0 - chu1 - chu2);
     231        tmp->d = 2.0 * arg((2.0 * chu * chu) - 1.0,
     232                           (coord->x * chu * M_PI)/360.0);
     233        tmp->r = asin((coord->y * chu * M_PI) / 180.0);
     234
     235    } else if (projection->type == PS_PROJ_PAR) {
     236        psAbort(__func__, "The projection type PS_PROJ_PAR is undefined.\n");
     237
     238    } else if (projection->type == PS_PROJ_GLS) {
     239        psAbort(__func__, "The projection type PS_PROJ_GLG is undefined.\n");
     240    }
     241
     242    return(tmp);
     243}
    129244
    130245psSphere *psSphereGetOffset(const psSphere *restrict position1,
     
    133248                            psSphereOffsetUnit unit)
    134249{
    135     return(NULL);
    136 }
    137 
    138 
     250    psAbort(__func__, "This function has not be dedfined.\n");
     251    return(NULL);
     252}
     253
     254
     255// XXX: I copied the algorithm from the ADD exactly.  Arguments mode and unit
     256// are ignored.
    139257psSphere *psSphereSetOffset(const psSphere *restrict position,
    140258                            const psSphere *restrict offset,
     
    142260                            psSphereOffsetUnit unit)
    143261{
    144     return(NULL);
    145 }
     262    psPlane lin;
     263    psSphere *tmp;
     264    psProjection proj;
     265
     266    if (mode == PS_LINEAR) {
     267        proj.R = position->r;
     268        proj.D = position->d;
     269        proj.Xs = 0.0;
     270        proj.Ys = 0.0;
     271        proj.type = PS_PROJ_TAN;
     272
     273        lin.x = offset->r;
     274        lin.y = offset->d;
     275
     276        tmp = psDeproject(&lin, &proj);
     277        return(tmp);
     278    } else if (mode == PS_SPHERICAL) {
     279        psAbort(__func__, "Sperical offset modes are not defined.\n");
     280    }
     281    psAbort(__func__, "Unrecognized offset mode\n");
     282    return(NULL);
     283}
  • trunk/psLib/src/astro/psCoord.h

    r1287 r1293  
    1010 *  @author George Gusciora, MHPCC
    1111 *
    12  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2004-07-23 03:13:39 $
     12 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2004-07-24 02:42:59 $
    1414 *
    1515 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2727typedef struct
    2828{
    29     double x;    ///< x position
    30     double y;    ///< y position
     29    double x;      ///< x position
     30    double y;      ///< y position
    3131    double xErr;   ///< Error in x position
    3232    double yErr;   ///< Error in y position
     
    3636typedef struct
    3737{
    38     double r;    ///< RA
    39     double d;    ///< Dec
     38    double r;      ///< RA
     39    double d;      ///< Dec
    4040    double rErr;   ///< Error in RA
    4141    double dErr;   ///< Error in Dec
     
    6363    double sinNPlat;   ///< sin of North Pole latitude
    6464    double cosNPlat;   ///< cos of North Pole latitude
    65     double sinZP;   ///< sin of Forst PT os Ares lon
    66     double cosZP;   ///< cos of Forst PT os Ares lon
     65    double sinZP;      ///< sin of Forst PT os Ares lon
     66    double cosZP;      ///< cos of Forst PT os Ares lon
    6767}
    6868psSphereTransform;
    6969
    7070typedef enum {
    71     PS_PROJ_TAN,   ///< Tangent projection
    72     PS_PROJ_SIN,   ///< Sine projection
    73     PS_PROJ_AIT,   ///< Aitoff projection
    74     PS_PROJ_PAR,   ///< Par projection
    75     PS_PROJ_GLS,   ///< GLS projection
    76     PS_PROJ_NTYPE   ///< Number of types; must be last.
     71    PS_PROJ_TAN,       ///< Tangent projection
     72    PS_PROJ_SIN,       ///< Sine projection
     73    PS_PROJ_AIT,       ///< Aitoff projection
     74    PS_PROJ_PAR,       ///< Par projection
     75    PS_PROJ_GLS,       ///< GLS projection
     76    PS_PROJ_CAR,       ///< CAR projection
     77    PS_PROJ_MER,       ///< MER projection
     78    PS_PROJ_NTYPE      ///< Number of types; must be last.
    7779} psProjectionType;
    7880
    7981typedef struct
    8082{
    81     double R;    ///< Coordinates of projection center
    82     double D;    ///< Coordinates of projection center
     83    double R;     ///< Coordinates of projection center
     84    double D;     ///< Coordinates of projection center
    8385    double Xs;    ///< plate-scale in X direction
    8486    double Ys;    ///< plate-scale in Y direction
     
    128130                   const psProjection *projection);
    129131
    130 psSphere *psProject(const psPlane *coord,
    131                     const psProjection *projection);
     132psSphere *psDeproject(const psPlane *coord,
     133                      const psProjection *projection);
    132134
    133135psSphere *psSphereGetOffset(const psSphere *restrict position1,
  • trunk/psLib/src/astronomy/psCoord.c

    r1287 r1293  
    1010 *  @author George Gusciora, MHPCC
    1111 *
    12  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2004-07-23 03:13:39 $
     12 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2004-07-24 02:42:59 $
    1414 *
    1515 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2222#include "psCoord.h"
    2323#include "psMemory.h"
    24 
     24#include "psAbort.h"
     25#include <math.h>
     26#include <float.h>
    2527
    2628psPlane *psPlaneTransformApply(psPlane *out,
     
    127129}
    128130
     131// XXX: Is this the correct way to calculate this?
     132float cot(float x)
     133{
     134    return(1.0 / atan(x));
     135}
     136
     137float arg(float x, float y)
     138{
     139    if (x > 0) {
     140        return(atan(y/x));
     141    } else if ((x==0) && (y==0)) {
     142        return(0.5 * M_PI);
     143    } else if ((x==0) && (y==0)) {
     144        return(-0.5 * M_PI);
     145    } else if ((x==0) && (y==0)) {
     146        return(M_PI + atan(y/x));
     147    } else if ((x==0) && (y==0)) {
     148        return(-M_PI + atan(y/x));
     149    }
     150
     151    psAbort(__func__, "Unacceptable range for (arg(%f, %f).\n", x, y);
     152    return(0.0);
     153}
     154
     155
     156psPlane *psProject(const psSphere *coord,
     157                   const psProjection *projection)
     158{
     159    float R = 0.0;
     160    float alpha = 0.0;
     161    psPlane *tmp= (psPlane *) psAlloc(sizeof(psPlane));
     162
     163    if (projection->type == PS_PROJ_TAN) {
     164        R = cot(coord->r) * (180.0 / M_PI);
     165        tmp->x = R * sin(coord->d);
     166        tmp->y = R * cos(coord->d);
     167
     168    } else if (projection->type == PS_PROJ_SIN) {
     169        R = cos(coord->r) * (180.0 / M_PI);
     170        tmp->x = R * sin(coord->d);
     171        tmp->y = R * cos(coord->d);
     172
     173    } else if (projection->type == PS_PROJ_CAR) {
     174        tmp->x = coord->d;
     175        tmp->y = coord->r;
     176
     177    } else if (projection->type == PS_PROJ_MER) {
     178        tmp->x = coord->d;
     179        tmp->y = log(tan(45.0 + (0.5 * coord->r))) * 180.0/M_PI;
     180
     181    } else if (projection->type == PS_PROJ_AIT) {
     182        alpha = 1.0 / ((180.0 / M_PI) *
     183                       sqrt(1.0 + (cos(coord->r) * cos(0.5 * coord->d) * 0.5)));
     184
     185        tmp->x = 2.0 * alpha * cos(coord->r) * sin(0.5 * coord->d);
     186        tmp->y = alpha * sin(coord->d);
     187
     188    } else if (projection->type == PS_PROJ_PAR) {
     189        psAbort(__func__, "The projection type PS_PROJ_PAR is undefined.\n");
     190
     191    } else if (projection->type == PS_PROJ_GLS) {
     192        psAbort(__func__, "The projection type PS_PROJ_GLG is undefined.\n");
     193    }
     194
     195    return(tmp);
     196}
     197
     198psSphere *psDeproject(const psPlane *coord,
     199                      const psProjection *projection)
     200{
     201    float R = 0.0;
     202    float chu = 0.0;
     203    float chu1 = 0.0;
     204    float chu2 = 0.0;
     205    psSphere *tmp= (psSphere *) psAlloc(sizeof(psSphere));
     206
     207    if (projection->type == PS_PROJ_TAN) {
     208        R = sqrt((coord->x * coord->x) + (coord->y * coord->y));
     209        tmp->d = arg(-coord->y, coord->x);
     210        tmp->r = atan(180.0 / (R * M_PI));
     211
     212    } else if (projection->type == PS_PROJ_SIN) {
     213        R = sqrt((coord->x * coord->x) + (coord->y * coord->y));
     214        tmp->d = arg(-coord->y, coord->x);
     215        tmp->r = acos((R * M_PI) / 180.0);
     216
     217    } else if (projection->type == PS_PROJ_CAR) {
     218        tmp->d = coord->x;
     219        tmp->r = coord->y;
     220
     221    } else if (projection->type == PS_PROJ_MER) {
     222        tmp->d = coord->x;
     223        tmp->r = (2.0 * atan(exp((coord->y * M_PI/180.0)))) - 180.0;
     224
     225    } else if (projection->type == PS_PROJ_AIT) {
     226        chu1 = (coord->x * M_PI) / 720.0;
     227        chu1*= chu1;
     228        chu2 = (coord->y * M_PI) / 360.0;
     229        chu2*= chu2;
     230        chu = sqrt(1.0 - chu1 - chu2);
     231        tmp->d = 2.0 * arg((2.0 * chu * chu) - 1.0,
     232                           (coord->x * chu * M_PI)/360.0);
     233        tmp->r = asin((coord->y * chu * M_PI) / 180.0);
     234
     235    } else if (projection->type == PS_PROJ_PAR) {
     236        psAbort(__func__, "The projection type PS_PROJ_PAR is undefined.\n");
     237
     238    } else if (projection->type == PS_PROJ_GLS) {
     239        psAbort(__func__, "The projection type PS_PROJ_GLG is undefined.\n");
     240    }
     241
     242    return(tmp);
     243}
    129244
    130245psSphere *psSphereGetOffset(const psSphere *restrict position1,
     
    133248                            psSphereOffsetUnit unit)
    134249{
    135     return(NULL);
    136 }
    137 
    138 
     250    psAbort(__func__, "This function has not be dedfined.\n");
     251    return(NULL);
     252}
     253
     254
     255// XXX: I copied the algorithm from the ADD exactly.  Arguments mode and unit
     256// are ignored.
    139257psSphere *psSphereSetOffset(const psSphere *restrict position,
    140258                            const psSphere *restrict offset,
     
    142260                            psSphereOffsetUnit unit)
    143261{
    144     return(NULL);
    145 }
     262    psPlane lin;
     263    psSphere *tmp;
     264    psProjection proj;
     265
     266    if (mode == PS_LINEAR) {
     267        proj.R = position->r;
     268        proj.D = position->d;
     269        proj.Xs = 0.0;
     270        proj.Ys = 0.0;
     271        proj.type = PS_PROJ_TAN;
     272
     273        lin.x = offset->r;
     274        lin.y = offset->d;
     275
     276        tmp = psDeproject(&lin, &proj);
     277        return(tmp);
     278    } else if (mode == PS_SPHERICAL) {
     279        psAbort(__func__, "Sperical offset modes are not defined.\n");
     280    }
     281    psAbort(__func__, "Unrecognized offset mode\n");
     282    return(NULL);
     283}
  • trunk/psLib/src/astronomy/psCoord.h

    r1287 r1293  
    1010 *  @author George Gusciora, MHPCC
    1111 *
    12  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2004-07-23 03:13:39 $
     12 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2004-07-24 02:42:59 $
    1414 *
    1515 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2727typedef struct
    2828{
    29     double x;    ///< x position
    30     double y;    ///< y position
     29    double x;      ///< x position
     30    double y;      ///< y position
    3131    double xErr;   ///< Error in x position
    3232    double yErr;   ///< Error in y position
     
    3636typedef struct
    3737{
    38     double r;    ///< RA
    39     double d;    ///< Dec
     38    double r;      ///< RA
     39    double d;      ///< Dec
    4040    double rErr;   ///< Error in RA
    4141    double dErr;   ///< Error in Dec
     
    6363    double sinNPlat;   ///< sin of North Pole latitude
    6464    double cosNPlat;   ///< cos of North Pole latitude
    65     double sinZP;   ///< sin of Forst PT os Ares lon
    66     double cosZP;   ///< cos of Forst PT os Ares lon
     65    double sinZP;      ///< sin of Forst PT os Ares lon
     66    double cosZP;      ///< cos of Forst PT os Ares lon
    6767}
    6868psSphereTransform;
    6969
    7070typedef enum {
    71     PS_PROJ_TAN,   ///< Tangent projection
    72     PS_PROJ_SIN,   ///< Sine projection
    73     PS_PROJ_AIT,   ///< Aitoff projection
    74     PS_PROJ_PAR,   ///< Par projection
    75     PS_PROJ_GLS,   ///< GLS projection
    76     PS_PROJ_NTYPE   ///< Number of types; must be last.
     71    PS_PROJ_TAN,       ///< Tangent projection
     72    PS_PROJ_SIN,       ///< Sine projection
     73    PS_PROJ_AIT,       ///< Aitoff projection
     74    PS_PROJ_PAR,       ///< Par projection
     75    PS_PROJ_GLS,       ///< GLS projection
     76    PS_PROJ_CAR,       ///< CAR projection
     77    PS_PROJ_MER,       ///< MER projection
     78    PS_PROJ_NTYPE      ///< Number of types; must be last.
    7779} psProjectionType;
    7880
    7981typedef struct
    8082{
    81     double R;    ///< Coordinates of projection center
    82     double D;    ///< Coordinates of projection center
     83    double R;     ///< Coordinates of projection center
     84    double D;     ///< Coordinates of projection center
    8385    double Xs;    ///< plate-scale in X direction
    8486    double Ys;    ///< plate-scale in Y direction
     
    128130                   const psProjection *projection);
    129131
    130 psSphere *psProject(const psPlane *coord,
    131                     const psProjection *projection);
     132psSphere *psDeproject(const psPlane *coord,
     133                      const psProjection *projection);
    132134
    133135psSphere *psSphereGetOffset(const psSphere *restrict position1,
  • trunk/psLib/src/dataManip/psStats.c

    r1292 r1293  
    131131mean of the input vector.
    132132Inputs
     133    myVector
     134    maskVector
     135    maskVal
     136    stats
    133137Returns
    134138    NULL
     
    404408    float rangeMin = 0.0;                       // Exclude data below this
    405409    float rangeMax = 0.0;                       // Exclude date above this
    406     psStats *stats2 = NULL;                     // Temporary stats structure
    407410
    408411
    409412    // Determine if the number of data points exceed a threshold which will
    410413    // cause to generate robust stats, as opposed to exact stats.
    411 
    412     if (myVector->n > stats->sampleLimit) {
    413         psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented.");
    414 
    415         // Calculate the robust quartiles.
    416         stats2 = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
    417         p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
    418 
    419         // Store the robust quartiles into the sample quartile members.
    420         stats->sampleMedian = stats2->robustMedian;
    421 
    422         // Free temporary data buffers.
    423         psFree(stats2);
    424 
    425         // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
    426         stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
    427 
    428         return;
    429     }
     414    // XXX: This code is no longer used.  We now calculate the median exactly
     415    // regardless of the vector size.
     416    /*
     417        if (myVector->n > stats->sampleLimit) {
     418            psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented.");
     419     
     420            // Calculate the robust quartiles.
     421            stats2 = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
     422            p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
     423     
     424            // Store the robust quartiles into the sample quartile members.
     425            stats->sampleMedian = stats2->robustMedian;
     426     
     427            // Free temporary data buffers.
     428            psFree(stats2);
     429     
     430            // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
     431            stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
     432     
     433            return;
     434        }
     435    */
    430436
    431437    // Determine how many data points fit inside this min/max range
     
    483489
    484490    // Calculate the median exactly.
     491    // XXX: Is this the correct action?
    485492    if (0 == (nValues % 2)) {
    486493        stats->sampleMedian = 0.5 * (sortedVector->data.F32[(nValues/2)-1] +
     
    498505    This routine smoothes the data in the input robustHistogram with a
    499506    Gaussian of width sigma.
     507 
     508    XXX: Must consult with IfA on the proper values for the Gaussian
     509    smoothing.  Currently, the Gaussian coefficients are such that only
     510    the center coefficient is non-zero.  This is because "e" is being
     511    raised to a very large negative number for all points except the
     512    center point.
     513 
     514    XXX: use a static variable for gaussianCoefs[] and compute them once.
    500515 *****************************************************************************/
    501516psVector *p_psVectorsmoothHistGaussian(psHistogram *robustHistogram,
     
    541556    }
    542557
     558    // Perform the actual smoothing.
    543559    for(i=0;i<robustHistogram->nums->n;i++) {
    544560        smooth->data.F32[i] = 0.0;
     
    576592    float rangeMin = 0.0;                       // Exclude data below this
    577593    float rangeMax = 0.0;                       // Exclude date above this
    578 
    579     // Determine if the number of data points exceed a threshold which will
    580     // cause to generate robust stats, as opposed to exact stats.
    581     if (myVector->n > stats->sampleLimit) {
    582         psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented.");
    583         psStats *stats2 = NULL;
    584         // Calculate the robust quartiles.
    585         stats2 = psStatsAlloc(PS_STAT_ROBUST_QUARTILE);
    586         p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
    587 
    588         // Store the robust quartiles into the sample quartile members.
    589         stats->sampleUQ = stats2->robustUQ;
    590         stats->sampleLQ = stats2->robustLQ;
    591 
    592         // Free temporary data buffers.
    593         psFree(stats2);
    594 
    595         // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
    596         stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
    597 
    598         return;
    599     }
    600594
    601595    // Determine how many data points fit inside this min/max range
     
    861855
    862856/*****************************************************************************
     857p_psNormalizeVector(myData): this is a private function which normalizes the
     858elements of a vector to a range between 0.0 and 1.0.
    863859 *****************************************************************************/
    864860void p_psNormalizeVector(psVector *myData)
     
    885881
    886882
     883/*****************************************************************************
     884p_psGaussian(myData, myParams): an internal function, used by robust stats,
     885intended to compute the Gaussian with a specified sigma/mean, at the
     886specified data point.
     887 *****************************************************************************/
    887888float p_psGaussian(const psVector *restrict myData,
    888889                   const psVector *restrict myParams)
     
    894895    tmp/= ((float)sqrt(2.0 * M_PI * (stdev * stdev)));
    895896
    896     printf("p_psGaussian((%.2f), %.2f, %.2f) is %.2f\n", x, mean, stdev, tmp);
     897    //    printf("p_psGaussian((%.2f), %.2f, %.2f) is %.2f\n", x, mean, stdev, tmp);
    897898    return(tmp);
    898899}
    899900
     901/*****************************************************************************
     902p_psGaussianDeriv(myData, myParams, whichParam): an internal function, which
     903calculates the specified partial derivative of the above Gaussian function.
     904 *****************************************************************************/
    900905float p_psGaussianDeriv(const psVector *restrict myData,
    901906                        const psVector *restrict myParams,
     
    922927
    923928
     929/*****************************************************************************
     930p_psQuadratic(myData, myParams): an internal function, used by robust stats,
     931intended to compute a quadratic, with the specified parameters, at the
     932specified data point.
     933 *****************************************************************************/
    924934float p_psQuadratic(const psVector *restrict myParams,
    925935                    const psVector *restrict myCoords)
     
    935945}
    936946
     947/*****************************************************************************
     948p_psQuadraticDeriv(myData, myParams, whichParam): an internal function, which
     949calculates the specified partial derivative of the above quadratic function.
     950 *****************************************************************************/
    937951float p_psQuadraticDeriv(const psVector *restrict myParams,
    938952                         const psVector *restrict myCoords,
     
    959973[rangeLow, rangeHigh].  It determines the x-value of that polynomial such
    960974that f(x) == midpoint.  This functions uses a binary-search algorithm on the
    961 range and assumes that the polnomial is monotonically increasing within that
    962 range.
     975range and assumes that the polynomial is monotonically increasing or
     976decreasing within that range.
    963977 *****************************************************************************/
    964978float p_ps1DPolyMedian(psPolynomial1D *myPoly,
     
    9981012
    9991013/******************************************************************************
    1000 p_ps1DPolyMedian(myPoly, rangeLow, rangeHigh, midpoint): This routine takes
    1001 as input a 1-D polynomial of arbitrary order (though we are using 2nd-order
    1002 polynomials here) and a range of x-values for which it is defined:
    1003 [rangeLow, rangeHigh].  It determines the x-value of that polynomial such
    1004 that f(x) == midpoint.  This functions uses a binary-search algorithm on the
    1005 range and assumes that the polnomial is monotonically increasing within that
    1006 range.
    1007  *****************************************************************************/
    1008 float p_psFitQuadratic(psHistogram *robustHistogram,
     1014p_psFitQuadratic(robustHistogram. cumulativeSums, binNum, fitFloat): given
     1015the specified histogram, with the specified pre-calculated cumulativeSums,
     1016this routine fits a quadratic f(x) to the 3 bins surrounding bin "binNum",
     1017and then finds the point x such that f(x) == fitFloat.
     1018 
     1019XXX: This function is currently not being used.
     1020 *****************************************************************************/
     1021float p_psFitQuadratic(psHistogram *histogram,
     1022                       psVector *cumulativeSums,
    10091023                       int binNum,
    10101024                       float fitFloat)
    10111025{
    1012     /*
    1013         if ((binNum > 0) &&
    1014             (binNum < (robustHistogram->nums->n+1))) {
    1015             x->data.F64[0] = (double) 0.5 *
    1016                       (robustHistogram->bounds->data.F32[binNum-1] +
    1017                        robustHistogram->bounds->data.F32[binNum]);
    1018             x->data.F64[1] = (double) 0.5 *
    1019                       (robustHistogram->bounds->data.F32[binNum] +
    1020                        robustHistogram->bounds->data.F32[binNum+1]);
    1021             x->data.F64[2] = (double) 0.5 *
    1022                       (robustHistogram->bounds->data.F32[binNum+1] +
    1023                        robustHistogram->bounds->data.F32[binNum+2]);
    1024      
    1025             y->data.F64[0] = cumulativeRobustSumsDl->data.F32[binNum-1];
    1026             y->data.F64[1] = cumulativeRobustSumsDl->data.F32[binNum];
    1027             y->data.F64[2] = cumulativeRobustSumsDl->data.F32[binNum+1];
    1028      
    1029             if (!((y->data.F64[0] <= fitFloat) &&
    1030                  (fitFloat <= y->data.F64[2]))) {
    1031                 psAbort(__func__, "p_psVectorRobustStats(0): midpoint not within y-range\n");
    1032             }
    1033      
    1034             yErr->data.F64[0] = 1.0;
    1035             yErr->data.F64[1] = 1.0;
    1036             yErr->data.F64[2] = 1.0;
    1037      
    1038             myPoly = psGetArrayPolynomial(myPoly, x, y, yErr);
    1039             return(p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2], fitFloat);
    1040          } else {
    1041             return(0.5 * (robustHistogram->bounds->data.F32[binNum+1] +
    1042                           robustHistogram->bounds->data.F32[binNum]));
    1043         }
    1044     */
     1026    psVector *x = psVectorAlloc(3, PS_TYPE_F64);
     1027    psVector *y = psVectorAlloc(3, PS_TYPE_F64);
     1028    psVector *yErr = psVectorAlloc(3, PS_TYPE_F64);
     1029    psPolynomial1D *myPoly = psPolynomial1DAlloc(2);
     1030
     1031    if ((binNum > 0) &&
     1032            (binNum < (histogram->nums->n+1))) {
     1033        x->data.F64[0] = (double) 0.5 *
     1034                         (histogram->bounds->data.F32[binNum-1] +
     1035                          histogram->bounds->data.F32[binNum]);
     1036        x->data.F64[1] = (double) 0.5 *
     1037                         (histogram->bounds->data.F32[binNum] +
     1038                          histogram->bounds->data.F32[binNum+1]);
     1039        x->data.F64[2] = (double) 0.5 *
     1040                         (histogram->bounds->data.F32[binNum+1] +
     1041                          histogram->bounds->data.F32[binNum+2]);
     1042
     1043        y->data.F64[0] = cumulativeSums->data.F32[binNum-1];
     1044        y->data.F64[1] = cumulativeSums->data.F32[binNum];
     1045        y->data.F64[2] = cumulativeSums->data.F32[binNum+1];
     1046
     1047        if (!((y->data.F64[0] <= fitFloat) &&
     1048                (fitFloat <= y->data.F64[2]))) {
     1049            psAbort(__func__, "p_psVectorRobustStats(0): midpoint not within y-range\n");
     1050        }
     1051
     1052        yErr->data.F64[0] = 1.0;
     1053        yErr->data.F64[1] = 1.0;
     1054        yErr->data.F64[2] = 1.0;
     1055
     1056        myPoly = psGetArrayPolynomial(myPoly, x, y, yErr);
     1057        return(p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2],
     1058                                fitFloat));
     1059    } else {
     1060        return(0.5 * (histogram->bounds->data.F32[binNum+1] +
     1061                      histogram->bounds->data.F32[binNum]));
     1062    }
     1063
     1064    psFree(x);
     1065    psFree(y);
     1066    psFree(yErr);
     1067    psFree(myPoly);
    10451068    return(0.0);
    10461069}
     
    10491072p_psVectorRobustStats(myVector, maskVector, maskVal, stats): this procedure
    10501073calculates a variety of robust stat measures:
    1051 PS_STAT_ROBUST_MEAN
    1052 PS_STAT_ROBUST_MEDIAN
    1053 PS_STAT_ROBUST_MODE
    1054 PS_STAT_ROBUST_STDEV
    1055 PS_STAT_ROBUST_QUARTILE
     1074    PS_STAT_ROBUST_MEAN
     1075    PS_STAT_ROBUST_MEDIAN
     1076    PS_STAT_ROBUST_MODE
     1077    PS_STAT_ROBUST_STDEV
     1078    PS_STAT_ROBUST_QUARTILE
    10561079I have included all that computation in a single function, as opposed to
    1057 breaking it across several functions for one primary reason:
    1058 they all
     1080breaking it across several functions for one primary reason:  they all
    10591081require the same basic initial processing steps (calculate the histogram,
    1060 etc.)
    1061 however there is no currently defined means, in the SDRS, to
    1062 specify this computation as a separate step.  If the above robust stat
    1063 measures were calcualted in separate functiosn, then much of the initial
    1064 processing would be duplicated.
     1082etc.)  however there is no currently defined means, in the SDRS, to specify
     1083this computation as a separate step.  If the above robust stat measures were
     1084calcualted in separate functiosn, then much of the initial processing would
     1085be duplicated.
     1086 
    10651087Inputs
    1066 myVector
    1067 maskVector
    1068 maskVal
    1069 stats
     1088    myVector
     1089    maskVector
     1090    maskVal
     1091    stats
    10701092Returns
    1071 NULL
     1093    NULL
    10721094*****************************************************************************/
    10731095void p_psVectorRobustStats(const psVector *restrict myVector,
     
    12241246        sumN50+= (float) robustHistogram->nums->data.S32[i];
    12251247    }
     1248
    12261249    // XXX: is dL defined as the value at the LQ/UQ, or the bin number?
    12271250    dL = (UQBinNum - LQBinNum) / 4;
     
    12441267                robustHistogramVector->data.F32[i];
    12451268            cumulativeMedian+= robustHistogramVector->data.F32[i];
    1246             sumNfit+= (float) robustHistogramVector->data.S32[i];
     1269            sumNfit+= (float) robustHistogram->nums->data.S32[i];
    12471270        }
    12481271    }
     
    17801803    }
    17811804
     1805    // XXX: Should we abort if (stats->min == stats->max)?
     1806    if (stats->min >= stats->max) {
     1807        psAbort(__func__, "psVectorStats() called with range: %f to %f\n",
     1808                stats->min, stats->max);
     1809    }
     1810
     1811
     1812
    17821813    PS_CHECK_VECTOR_TYPE(in, PS_TYPE_F32);
    17831814    if (mask != NULL) {
  • trunk/psLib/src/math/psStats.c

    r1292 r1293  
    131131mean of the input vector.
    132132Inputs
     133    myVector
     134    maskVector
     135    maskVal
     136    stats
    133137Returns
    134138    NULL
     
    404408    float rangeMin = 0.0;                       // Exclude data below this
    405409    float rangeMax = 0.0;                       // Exclude date above this
    406     psStats *stats2 = NULL;                     // Temporary stats structure
    407410
    408411
    409412    // Determine if the number of data points exceed a threshold which will
    410413    // cause to generate robust stats, as opposed to exact stats.
    411 
    412     if (myVector->n > stats->sampleLimit) {
    413         psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented.");
    414 
    415         // Calculate the robust quartiles.
    416         stats2 = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
    417         p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
    418 
    419         // Store the robust quartiles into the sample quartile members.
    420         stats->sampleMedian = stats2->robustMedian;
    421 
    422         // Free temporary data buffers.
    423         psFree(stats2);
    424 
    425         // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
    426         stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
    427 
    428         return;
    429     }
     414    // XXX: This code is no longer used.  We now calculate the median exactly
     415    // regardless of the vector size.
     416    /*
     417        if (myVector->n > stats->sampleLimit) {
     418            psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented.");
     419     
     420            // Calculate the robust quartiles.
     421            stats2 = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
     422            p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
     423     
     424            // Store the robust quartiles into the sample quartile members.
     425            stats->sampleMedian = stats2->robustMedian;
     426     
     427            // Free temporary data buffers.
     428            psFree(stats2);
     429     
     430            // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
     431            stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
     432     
     433            return;
     434        }
     435    */
    430436
    431437    // Determine how many data points fit inside this min/max range
     
    483489
    484490    // Calculate the median exactly.
     491    // XXX: Is this the correct action?
    485492    if (0 == (nValues % 2)) {
    486493        stats->sampleMedian = 0.5 * (sortedVector->data.F32[(nValues/2)-1] +
     
    498505    This routine smoothes the data in the input robustHistogram with a
    499506    Gaussian of width sigma.
     507 
     508    XXX: Must consult with IfA on the proper values for the Gaussian
     509    smoothing.  Currently, the Gaussian coefficients are such that only
     510    the center coefficient is non-zero.  This is because "e" is being
     511    raised to a very large negative number for all points except the
     512    center point.
     513 
     514    XXX: use a static variable for gaussianCoefs[] and compute them once.
    500515 *****************************************************************************/
    501516psVector *p_psVectorsmoothHistGaussian(psHistogram *robustHistogram,
     
    541556    }
    542557
     558    // Perform the actual smoothing.
    543559    for(i=0;i<robustHistogram->nums->n;i++) {
    544560        smooth->data.F32[i] = 0.0;
     
    576592    float rangeMin = 0.0;                       // Exclude data below this
    577593    float rangeMax = 0.0;                       // Exclude date above this
    578 
    579     // Determine if the number of data points exceed a threshold which will
    580     // cause to generate robust stats, as opposed to exact stats.
    581     if (myVector->n > stats->sampleLimit) {
    582         psAbort(__func__, "Robust Statistic Algorithms have not yet been defined or implemented.");
    583         psStats *stats2 = NULL;
    584         // Calculate the robust quartiles.
    585         stats2 = psStatsAlloc(PS_STAT_ROBUST_QUARTILE);
    586         p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
    587 
    588         // Store the robust quartiles into the sample quartile members.
    589         stats->sampleUQ = stats2->robustUQ;
    590         stats->sampleLQ = stats2->robustLQ;
    591 
    592         // Free temporary data buffers.
    593         psFree(stats2);
    594 
    595         // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure.
    596         stats->options = stats->options | PS_STAT_ROBUST_FOR_SAMPLE;
    597 
    598         return;
    599     }
    600594
    601595    // Determine how many data points fit inside this min/max range
     
    861855
    862856/*****************************************************************************
     857p_psNormalizeVector(myData): this is a private function which normalizes the
     858elements of a vector to a range between 0.0 and 1.0.
    863859 *****************************************************************************/
    864860void p_psNormalizeVector(psVector *myData)
     
    885881
    886882
     883/*****************************************************************************
     884p_psGaussian(myData, myParams): an internal function, used by robust stats,
     885intended to compute the Gaussian with a specified sigma/mean, at the
     886specified data point.
     887 *****************************************************************************/
    887888float p_psGaussian(const psVector *restrict myData,
    888889                   const psVector *restrict myParams)
     
    894895    tmp/= ((float)sqrt(2.0 * M_PI * (stdev * stdev)));
    895896
    896     printf("p_psGaussian((%.2f), %.2f, %.2f) is %.2f\n", x, mean, stdev, tmp);
     897    //    printf("p_psGaussian((%.2f), %.2f, %.2f) is %.2f\n", x, mean, stdev, tmp);
    897898    return(tmp);
    898899}
    899900
     901/*****************************************************************************
     902p_psGaussianDeriv(myData, myParams, whichParam): an internal function, which
     903calculates the specified partial derivative of the above Gaussian function.
     904 *****************************************************************************/
    900905float p_psGaussianDeriv(const psVector *restrict myData,
    901906                        const psVector *restrict myParams,
     
    922927
    923928
     929/*****************************************************************************
     930p_psQuadratic(myData, myParams): an internal function, used by robust stats,
     931intended to compute a quadratic, with the specified parameters, at the
     932specified data point.
     933 *****************************************************************************/
    924934float p_psQuadratic(const psVector *restrict myParams,
    925935                    const psVector *restrict myCoords)
     
    935945}
    936946
     947/*****************************************************************************
     948p_psQuadraticDeriv(myData, myParams, whichParam): an internal function, which
     949calculates the specified partial derivative of the above quadratic function.
     950 *****************************************************************************/
    937951float p_psQuadraticDeriv(const psVector *restrict myParams,
    938952                         const psVector *restrict myCoords,
     
    959973[rangeLow, rangeHigh].  It determines the x-value of that polynomial such
    960974that f(x) == midpoint.  This functions uses a binary-search algorithm on the
    961 range and assumes that the polnomial is monotonically increasing within that
    962 range.
     975range and assumes that the polynomial is monotonically increasing or
     976decreasing within that range.
    963977 *****************************************************************************/
    964978float p_ps1DPolyMedian(psPolynomial1D *myPoly,
     
    9981012
    9991013/******************************************************************************
    1000 p_ps1DPolyMedian(myPoly, rangeLow, rangeHigh, midpoint): This routine takes
    1001 as input a 1-D polynomial of arbitrary order (though we are using 2nd-order
    1002 polynomials here) and a range of x-values for which it is defined:
    1003 [rangeLow, rangeHigh].  It determines the x-value of that polynomial such
    1004 that f(x) == midpoint.  This functions uses a binary-search algorithm on the
    1005 range and assumes that the polnomial is monotonically increasing within that
    1006 range.
    1007  *****************************************************************************/
    1008 float p_psFitQuadratic(psHistogram *robustHistogram,
     1014p_psFitQuadratic(robustHistogram. cumulativeSums, binNum, fitFloat): given
     1015the specified histogram, with the specified pre-calculated cumulativeSums,
     1016this routine fits a quadratic f(x) to the 3 bins surrounding bin "binNum",
     1017and then finds the point x such that f(x) == fitFloat.
     1018 
     1019XXX: This function is currently not being used.
     1020 *****************************************************************************/
     1021float p_psFitQuadratic(psHistogram *histogram,
     1022                       psVector *cumulativeSums,
    10091023                       int binNum,
    10101024                       float fitFloat)
    10111025{
    1012     /*
    1013         if ((binNum > 0) &&
    1014             (binNum < (robustHistogram->nums->n+1))) {
    1015             x->data.F64[0] = (double) 0.5 *
    1016                       (robustHistogram->bounds->data.F32[binNum-1] +
    1017                        robustHistogram->bounds->data.F32[binNum]);
    1018             x->data.F64[1] = (double) 0.5 *
    1019                       (robustHistogram->bounds->data.F32[binNum] +
    1020                        robustHistogram->bounds->data.F32[binNum+1]);
    1021             x->data.F64[2] = (double) 0.5 *
    1022                       (robustHistogram->bounds->data.F32[binNum+1] +
    1023                        robustHistogram->bounds->data.F32[binNum+2]);
    1024      
    1025             y->data.F64[0] = cumulativeRobustSumsDl->data.F32[binNum-1];
    1026             y->data.F64[1] = cumulativeRobustSumsDl->data.F32[binNum];
    1027             y->data.F64[2] = cumulativeRobustSumsDl->data.F32[binNum+1];
    1028      
    1029             if (!((y->data.F64[0] <= fitFloat) &&
    1030                  (fitFloat <= y->data.F64[2]))) {
    1031                 psAbort(__func__, "p_psVectorRobustStats(0): midpoint not within y-range\n");
    1032             }
    1033      
    1034             yErr->data.F64[0] = 1.0;
    1035             yErr->data.F64[1] = 1.0;
    1036             yErr->data.F64[2] = 1.0;
    1037      
    1038             myPoly = psGetArrayPolynomial(myPoly, x, y, yErr);
    1039             return(p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2], fitFloat);
    1040          } else {
    1041             return(0.5 * (robustHistogram->bounds->data.F32[binNum+1] +
    1042                           robustHistogram->bounds->data.F32[binNum]));
    1043         }
    1044     */
     1026    psVector *x = psVectorAlloc(3, PS_TYPE_F64);
     1027    psVector *y = psVectorAlloc(3, PS_TYPE_F64);
     1028    psVector *yErr = psVectorAlloc(3, PS_TYPE_F64);
     1029    psPolynomial1D *myPoly = psPolynomial1DAlloc(2);
     1030
     1031    if ((binNum > 0) &&
     1032            (binNum < (histogram->nums->n+1))) {
     1033        x->data.F64[0] = (double) 0.5 *
     1034                         (histogram->bounds->data.F32[binNum-1] +
     1035                          histogram->bounds->data.F32[binNum]);
     1036        x->data.F64[1] = (double) 0.5 *
     1037                         (histogram->bounds->data.F32[binNum] +
     1038                          histogram->bounds->data.F32[binNum+1]);
     1039        x->data.F64[2] = (double) 0.5 *
     1040                         (histogram->bounds->data.F32[binNum+1] +
     1041                          histogram->bounds->data.F32[binNum+2]);
     1042
     1043        y->data.F64[0] = cumulativeSums->data.F32[binNum-1];
     1044        y->data.F64[1] = cumulativeSums->data.F32[binNum];
     1045        y->data.F64[2] = cumulativeSums->data.F32[binNum+1];
     1046
     1047        if (!((y->data.F64[0] <= fitFloat) &&
     1048                (fitFloat <= y->data.F64[2]))) {
     1049            psAbort(__func__, "p_psVectorRobustStats(0): midpoint not within y-range\n");
     1050        }
     1051
     1052        yErr->data.F64[0] = 1.0;
     1053        yErr->data.F64[1] = 1.0;
     1054        yErr->data.F64[2] = 1.0;
     1055
     1056        myPoly = psGetArrayPolynomial(myPoly, x, y, yErr);
     1057        return(p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2],
     1058                                fitFloat));
     1059    } else {
     1060        return(0.5 * (histogram->bounds->data.F32[binNum+1] +
     1061                      histogram->bounds->data.F32[binNum]));
     1062    }
     1063
     1064    psFree(x);
     1065    psFree(y);
     1066    psFree(yErr);
     1067    psFree(myPoly);
    10451068    return(0.0);
    10461069}
     
    10491072p_psVectorRobustStats(myVector, maskVector, maskVal, stats): this procedure
    10501073calculates a variety of robust stat measures:
    1051 PS_STAT_ROBUST_MEAN
    1052 PS_STAT_ROBUST_MEDIAN
    1053 PS_STAT_ROBUST_MODE
    1054 PS_STAT_ROBUST_STDEV
    1055 PS_STAT_ROBUST_QUARTILE
     1074    PS_STAT_ROBUST_MEAN
     1075    PS_STAT_ROBUST_MEDIAN
     1076    PS_STAT_ROBUST_MODE
     1077    PS_STAT_ROBUST_STDEV
     1078    PS_STAT_ROBUST_QUARTILE
    10561079I have included all that computation in a single function, as opposed to
    1057 breaking it across several functions for one primary reason:
    1058 they all
     1080breaking it across several functions for one primary reason:  they all
    10591081require the same basic initial processing steps (calculate the histogram,
    1060 etc.)
    1061 however there is no currently defined means, in the SDRS, to
    1062 specify this computation as a separate step.  If the above robust stat
    1063 measures were calcualted in separate functiosn, then much of the initial
    1064 processing would be duplicated.
     1082etc.)  however there is no currently defined means, in the SDRS, to specify
     1083this computation as a separate step.  If the above robust stat measures were
     1084calcualted in separate functiosn, then much of the initial processing would
     1085be duplicated.
     1086 
    10651087Inputs
    1066 myVector
    1067 maskVector
    1068 maskVal
    1069 stats
     1088    myVector
     1089    maskVector
     1090    maskVal
     1091    stats
    10701092Returns
    1071 NULL
     1093    NULL
    10721094*****************************************************************************/
    10731095void p_psVectorRobustStats(const psVector *restrict myVector,
     
    12241246        sumN50+= (float) robustHistogram->nums->data.S32[i];
    12251247    }
     1248
    12261249    // XXX: is dL defined as the value at the LQ/UQ, or the bin number?
    12271250    dL = (UQBinNum - LQBinNum) / 4;
     
    12441267                robustHistogramVector->data.F32[i];
    12451268            cumulativeMedian+= robustHistogramVector->data.F32[i];
    1246             sumNfit+= (float) robustHistogramVector->data.S32[i];
     1269            sumNfit+= (float) robustHistogram->nums->data.S32[i];
    12471270        }
    12481271    }
     
    17801803    }
    17811804
     1805    // XXX: Should we abort if (stats->min == stats->max)?
     1806    if (stats->min >= stats->max) {
     1807        psAbort(__func__, "psVectorStats() called with range: %f to %f\n",
     1808                stats->min, stats->max);
     1809    }
     1810
     1811
     1812
    17821813    PS_CHECK_VECTOR_TYPE(in, PS_TYPE_F32);
    17831814    if (mask != NULL) {
Note: See TracChangeset for help on using the changeset viewer.