IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 4958


Ignore:
Timestamp:
Sep 7, 2005, 11:35:50 AM (21 years ago)
Author:
gusciora
Message:

Split of psFunctions.c into psSpline.c and psPolynomial.c.

Location:
trunk/psLib/src/math
Files:
4 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/math/Makefile.am

    r4540 r4958  
    99        psMinimize.c \
    1010        psRandom.c \
    11         psFunctions.c \
     11        psPolynomial.c \
     12        psSpline.c \
    1213        psStats.c \
    1314        psUnaryOp.c
     
    2324        psMinimize.h \
    2425        psRandom.h \
    25         psFunctions.h \
     26        psPolynomial.h \
     27        psSpline.h \
    2628        psStats.h \
    2729        psUnaryOp.h
  • trunk/psLib/src/math/psFunctions.c

    r4937 r4958  
    77*  polynomials.  It also contains a Gaussian functions.
    88*
    9 *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
    10 *  @date $Date: 2005-08-31 22:28:35 $
     9*  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
     10*  @date $Date: 2005-09-07 21:35:50 $
    1111*
    1212*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    13071307/*****************************************************************************
    13081308p_psVectorBinDisect(): A wrapper to the above p_psVectorBinDisect().
     1309 
     1310XXX: Assert that the psVector and psScalar have the same type.
    13091311 *****************************************************************************/
    13101312psS32 p_psVectorBinDisect(psVector *bins,
  • trunk/psLib/src/math/psMinimize.c

    r4944 r4958  
    99 *  @author GLG, MHPCC
    1010 *
    11  *  @version $Revision: 1.133 $ $Name: not supported by cvs2svn $
    12  *  @date $Date: 2005-09-02 21:32:06 $
     11 *  @version $Revision: 1.134 $ $Name: not supported by cvs2svn $
     12 *  @date $Date: 2005-09-07 21:35:50 $
    1313 *
    1414 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    2929#include "psImageStructManip.h"
    3030#include "psBinaryOp.h"
     31#include "psLogMsg.h"
    3132/*****************************************************************************/
    3233/* DEFINE STATEMENTS                                                         */
     
    112113
    113114/******************************************************************************
    114 p_psBuildSums1D(x, polyOrder, sums): this routine calculates the powers of
    115 input parameter "x" between 0 and input parameter polyOrder.  The result is
    116 returned as a psVector sums.
     115buildSums1D(x, polyOrder, sums): this routine calculates the powers of input
     116parameter "x" between 0 and input parameter polyOrder.  The result is returned
     117as a psVector sums.
    117118 
    118119XXX: Use a static vector.
     120 
     121XXX: should the argument be polyOrder or numTerms?
    119122 *****************************************************************************/
    120123static void buildSums1D(psF64 x,
     
    124127    psS32 i = 0;
    125128    psF64 xSum = 0.0;
     129    psS32 numTerms = polyOrder + 1;
    126130
    127131    if (sums == NULL) {
    128         sums = psVectorAlloc(polyOrder, PS_TYPE_F64);
    129     }
    130     if (polyOrder > sums->n) {
    131         sums = psVectorRealloc(sums, polyOrder);
     132        sums = psVectorAlloc(numTerms, PS_TYPE_F64);
     133    } else if (numTerms > sums->n) {
     134        sums = psVectorRealloc(sums, numTerms);
    132135    }
    133136
    134137    xSum = 1.0;
    135     for (i = 0; i <= polyOrder; i++) {
     138    for (i = 0; i < numTerms; i++) {
    136139        sums->data.F64[i] = xSum;
    137140        xSum *= x;
     
    708711those coords.
    709712 
    710 // XXX EAM this is my re-implementation of MinLM
     713XXX EAM this is my re-implementation of MinLM
    711714 
    712715XXX: This must work for both F32 and F64.  F32 is currently implemented.
     
    13061309 
    13071310XXX: type F32 is done via vector conversion only.
     1311 
     1312XXX: Get rid of this.  Use new argument list.
    13081313 *****************************************************************************/
    13091314psPolynomial1D* psVectorFitPolynomial1D(psPolynomial1D* poly,
     
    21432148
    21442149/******************************************************************************
     2150 ******************************************************************************
     2151 ******************************************************************************
     2152 ******************************************************************************
    21452153EAM Code:
     2154 ******************************************************************************
     2155 ******************************************************************************
     2156 ******************************************************************************
    21462157 *****************************************************************************/
    21472158
    2148 // XXX EAM : my alternate EAMBuildSums1D
    21492159static psVector *EAMBuildSums1D(
    21502160    psVector* sums,
     
    21552165    psF64 xSum = 0.0;
    21562166
     2167    //
     2168    // XXX: Why do we multiply by 2 here?  Better to do it outside and have the
     2169    // definition of this function remain sensible.
     2170    //
    21572171    nSum = 2*nTerm;
    21582172    if (sums == NULL) {
    21592173        sums = psVectorAlloc(nSum, PS_TYPE_F64);
    2160     }
    2161     if (nSum > sums->n) {
     2174    } else if (nSum > sums->n) {
    21622175        sums = psVectorRealloc(sums, nSum);
    21632176    }
     
    21772190    const psVector *x,
    21782191    const psVector *y,
    2179     const psVector *yErr
    2180 )
     2192    const psVector *yErr)
    21812193{
    21822194    // I think this is 1 dimension down
     
    22772289    const psPolynomial2D *myPoly,
    22782290    const psVector *x,
    2279     const psVector *y
    2280 )
     2291    const psVector *y)
    22812292{
    22822293    PS_ASSERT_POLY_NON_NULL(myPoly, NULL);
     
    23122323    psF64 y,
    23132324    psS32 nXterm,
    2314     psS32 nYterm
    2315 )
     2325    psS32 nYterm)
    23162326{
    23172327    psS32 nXsum = 0;
     
    23492359    const psVector* y,
    23502360    const psVector* z,
    2351     const psVector* zErr
    2352 )
     2361    const psVector* zErr)
    23532362{
    23542363    // I think this is 1 dimension down
     
    24392448    const psVector* y,
    24402449    const psVector* z,
    2441     const psVector* dz
    2442 )
     2450    const psVector* dz)
    24432451{
    24442452    psVector *X;
     
    24872495
    24882496// XXX EAM : be careful here with F32 vs F64 vectors
     2497/*
     2498 Basically, you repetitively fit a polynomial to a set of data points,
     2499 reject the points that did not fit well, then refit the polynomial.
     2500 
     2501 Basically, simply fit the polynomial to the data.  They compare the
     2502 fit (by evaluating the x data with that polynomial and subtracting
     2503 from the original f data).  That's the residual.  Loop through all
     2504 data and if the ((residual - mean) > 3*stDev), mask that data point,
     2505 and fit the polynomial again.  Do this 3 times.
     2506*/
     2507
    24892508psPolynomial2D* RobustFit2D(psPolynomial2D* poly,
    24902509                            psVector* mask,
     
    25312550}
    25322551
    2533 
     2552/******************************************************************************
     2553 ******************************************************************************
     2554 ******************************************************************************
     2555 ******************************************************************************
     2556NEW Code:
     2557 ******************************************************************************
     2558 ******************************************************************************
     2559 ******************************************************************************
     2560 *****************************************************************************/
     2561
     2562#define PS_VECTOR_GEN_INDEX_F32(VEC, SIZE) \
     2563VEC = psVectorAlloc(SIZE, PS_TYPE_F32); \
     2564for (psS32 i = 0 ; i < SIZE ; i++) { \
     2565    VEC->data.F32[i] = (psF32) i; \
     2566} \
     2567
     2568psPolynomial1D *psVectorFitPolynomial1D_NEW(
     2569    psPolynomial1D *poly,
     2570    const psVector *mask,
     2571    psMaskType maskValue,
     2572    const psVector *f,
     2573    const psVector *fErr,
     2574    const psVector *x)
     2575{
     2576    // Internal pointers for possibly NULL vectors.
     2577    psVector *x32 = NULL;
     2578    psVector *fErr32 = NULL;
     2579
     2580    PS_ASSERT_POLY_NON_NULL(poly, NULL);
     2581    PS_ASSERT_VECTOR_NON_NULL(f, NULL);
     2582    PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F32, NULL);
     2583    if (mask != NULL) {
     2584        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
     2585        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL);
     2586    }
     2587    if (x != NULL) {
     2588        PS_ASSERT_VECTORS_SIZE_EQUAL(f, x, NULL);
     2589        PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, NULL);
     2590    } else {
     2591        PS_VECTOR_GEN_INDEX_F32(x32, f->n);
     2592    }
     2593
     2594    if (fErr != NULL) {
     2595        PS_ASSERT_VECTORS_SIZE_EQUAL(f, fErr, NULL);
     2596        PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL);
     2597    } else {
     2598        fErr = psVectorAlloc(f->n, PS_TYPE_F32);
     2599        PS_VECTOR_SET_F32(fErr, 1.0);
     2600    }
     2601
     2602    psLogMsg(__func__, PS_LOG_WARN, "WARNING: This function has not been implemented.  Returning NULL.\n");
     2603    if (poly->type == PS_POLYNOMIAL_ORD) {
     2604        // XXX: Call EAM code
     2605    } else if (poly->type == PS_POLYNOMIAL_CHEB) {
     2606        // XXX: Call my code
     2607    } else {
     2608        printf("XXX: ERROR: incorrect polynomial type.\n");
     2609    }
     2610
     2611    // Free psVectors that were created for NULL arguments.
     2612    if (x == NULL) {
     2613        psFree(x32);
     2614    }
     2615    if (fErr == NULL) {
     2616        psFree(fErr32);
     2617    }
     2618
     2619    return(NULL);
     2620}
     2621
     2622
     2623psPolynomial2D *psVectorFitPolynomial2D_NEW(
     2624    psPolynomial1D *poly,
     2625    const psVector *mask,
     2626    psMaskType maskValue,
     2627    const psVector *f,
     2628    const psVector *fErr,
     2629    const psVector *x,
     2630    const psVector *y)
     2631{
     2632    // Internal pointers for possibly NULL vectors.
     2633    psVector *fErr32 = NULL;
     2634
     2635    PS_ASSERT_POLY_NON_NULL(poly, NULL);
     2636    PS_ASSERT_POLY_TYPE(poly, PS_POLYNOMIAL_ORD, NULL);
     2637    PS_ASSERT_VECTOR_NON_NULL(f, NULL);
     2638    PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F32, NULL);
     2639    if (mask != NULL) {
     2640        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
     2641        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL);
     2642    }
     2643    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
     2644    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2645    PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, NULL);
     2646    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
     2647    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2648    PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F32, NULL);
     2649    if (fErr != NULL) {
     2650        PS_ASSERT_VECTORS_SIZE_EQUAL(fErr, mask, NULL);
     2651        PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL);
     2652    } else {
     2653        fErr32 = psVectorAlloc(f->n, PS_TYPE_F32);
     2654        PS_VECTOR_SET_F32(fErr32, 1.0);
     2655    }
     2656
     2657    psLogMsg(__func__, PS_LOG_WARN, "WARNING: This function has not been implemented.  Returning NULL.\n");
     2658    if (poly->type == PS_POLYNOMIAL_ORD) {
     2659        psLogMsg(__func__, PS_LOG_WARN, "WARNING: 2-D polynomial vector fitting has not been implemented.  Returning NULL.\n");
     2660    } else if (poly->type == PS_POLYNOMIAL_CHEB) {
     2661        psLogMsg(__func__, PS_LOG_WARN, "WARNING: 2-D Chebyshev polynomial vector fitting has not been implemented.  Returning NULL.\n");
     2662    } else {
     2663        printf("XXX: ERROR: incorrect polynomial type.\n");
     2664    }
     2665    if (fErr == NULL) {
     2666        psFree(fErr32);
     2667    }
     2668    return(NULL);
     2669}
     2670
     2671psPolynomial3D *psVectorFitPolynomial3D_NEW(
     2672    psPolynomial1D *poly,
     2673    const psVector *mask,
     2674    psMaskType maskValue,
     2675    const psVector *f,
     2676    const psVector *fErr,
     2677    const psVector *x,
     2678    const psVector *y,
     2679    const psVector *z)
     2680{
     2681    // Internal pointers for possibly NULL vectors.
     2682    psVector *fErr32 = NULL;
     2683
     2684    PS_ASSERT_POLY_NON_NULL(poly, NULL);
     2685    PS_ASSERT_POLY_TYPE(poly, PS_POLYNOMIAL_ORD, NULL);
     2686    PS_ASSERT_VECTOR_NON_NULL(f, NULL);
     2687    PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F32, NULL);
     2688    if (mask != NULL) {
     2689        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
     2690        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL);
     2691    }
     2692    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
     2693    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2694    PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, NULL);
     2695    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
     2696    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2697    PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F32, NULL);
     2698    PS_ASSERT_VECTOR_NON_NULL(z, NULL);
     2699    PS_ASSERT_VECTORS_SIZE_EQUAL(f, z, NULL);
     2700    PS_ASSERT_VECTOR_TYPE(z, PS_TYPE_F32, NULL);
     2701    if (fErr != NULL) {
     2702        PS_ASSERT_VECTORS_SIZE_EQUAL(fErr, mask, NULL);
     2703        PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL);
     2704    } else {
     2705        fErr32 = psVectorAlloc(f->n, PS_TYPE_F32);
     2706        PS_VECTOR_SET_F32(fErr32, 1.0);
     2707    }
     2708
     2709    psLogMsg(__func__, PS_LOG_WARN, "WARNING: This function has not been implemented.  Returning NULL.\n");
     2710    if (poly->type == PS_POLYNOMIAL_ORD) {
     2711        psLogMsg(__func__, PS_LOG_WARN, "WARNING: 3-D polynomial vector fitting has not been implemented.  Returning NULL.\n");
     2712    } else if (poly->type == PS_POLYNOMIAL_CHEB) {
     2713        psLogMsg(__func__, PS_LOG_WARN, "WARNING: 3-D Chebyshev polynomial vector fitting has not been implemented.  Returning NULL.\n");
     2714    } else {
     2715        printf("XXX: ERROR: incorrect polynomial type.\n");
     2716    }
     2717    if (fErr == NULL) {
     2718        psFree(fErr32);
     2719    }
     2720    return(NULL);
     2721}
     2722
     2723psPolynomial4D *psVectorFitPolynomial4D_NEW(
     2724    psPolynomial1D *poly,
     2725    const psVector *mask,
     2726    psMaskType maskValue,
     2727    const psVector *f,
     2728    const psVector *fErr,
     2729    const psVector *x,
     2730    const psVector *y,
     2731    const psVector *z,
     2732    const psVector *t)
     2733{
     2734    // Internal pointers for possibly NULL vectors.
     2735    psVector *fErr32 = NULL;
     2736
     2737    PS_ASSERT_POLY_NON_NULL(poly, NULL);
     2738    PS_ASSERT_POLY_TYPE(poly, PS_POLYNOMIAL_ORD, NULL);
     2739    PS_ASSERT_VECTOR_NON_NULL(f, NULL);
     2740    PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F32, NULL);
     2741    if (mask != NULL) {
     2742        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
     2743        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL);
     2744    }
     2745    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
     2746    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2747    PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, NULL);
     2748    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
     2749    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2750    PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F32, NULL);
     2751    PS_ASSERT_VECTOR_NON_NULL(z, NULL);
     2752    PS_ASSERT_VECTORS_SIZE_EQUAL(f, z, NULL);
     2753    PS_ASSERT_VECTOR_TYPE(z, PS_TYPE_F32, NULL);
     2754    PS_ASSERT_VECTOR_NON_NULL(t, NULL);
     2755    PS_ASSERT_VECTORS_SIZE_EQUAL(f, t, NULL);
     2756    PS_ASSERT_VECTOR_TYPE(t, PS_TYPE_F32, NULL);
     2757    if (fErr != NULL) {
     2758        PS_ASSERT_VECTORS_SIZE_EQUAL(fErr, mask, NULL);
     2759        PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL);
     2760    } else {
     2761        fErr32 = psVectorAlloc(f->n, PS_TYPE_F32);
     2762        PS_VECTOR_SET_F32(fErr32, 1.0);
     2763    }
     2764
     2765    if (poly->type == PS_POLYNOMIAL_ORD) {
     2766        psLogMsg(__func__, PS_LOG_WARN, "WARNING: 4-D polynomial vector fitting has not been implemented.  Returning NULL.\n");
     2767    } else if (poly->type == PS_POLYNOMIAL_CHEB) {
     2768        psLogMsg(__func__, PS_LOG_WARN, "WARNING: 4-D Chebyshev polynomial vector fitting has not been implemented.  Returning NULL.\n");
     2769    } else {
     2770        printf("XXX: ERROR: incorrect polynomial type.\n");
     2771    }
     2772    if (fErr == NULL) {
     2773        psFree(fErr32);
     2774    }
     2775    return(NULL);
     2776}
     2777
     2778
     2779psPolynomial1D *psVectorClipFitPolynomial1D_NEW(
     2780    psPolynomial1D *poly,
     2781    psStats *stats,
     2782    const psVector *mask,
     2783    psMaskType maskValue,
     2784    const psVector *f,
     2785    const psVector *fErr,
     2786    const psVector *x)
     2787{
     2788    // Internal pointers for possibly NULL vectors.
     2789    psVector *x32 = NULL;
     2790    psVector *fErr32 = NULL;
     2791
     2792    PS_ASSERT_POLY_NON_NULL(poly, NULL);
     2793    PS_ASSERT_POLY_TYPE(poly, PS_POLYNOMIAL_ORD, NULL);
     2794    PS_ASSERT_VECTOR_NON_NULL(f, NULL);
     2795    PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F32, NULL);
     2796    if (mask != NULL) {
     2797        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
     2798        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL);
     2799    }
     2800    if (x != NULL) {
     2801        PS_ASSERT_VECTORS_SIZE_EQUAL(f, x, NULL);
     2802        PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, NULL);
     2803    }
     2804    if (fErr != NULL) {
     2805        PS_ASSERT_VECTORS_SIZE_EQUAL(f, fErr, NULL);
     2806        PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL);
     2807    } else {
     2808        fErr32 = psVectorAlloc(f->n, PS_TYPE_F32);
     2809        PS_VECTOR_SET_F32(fErr32, 1.0);
     2810    }
     2811
     2812    psLogMsg(__func__, PS_LOG_WARN, "WARNING: This function has not been implemented.  Returning NULL.\n");
     2813    // Free psVectors that were created for NULL arguments.
     2814    if (x == NULL) {
     2815        psFree(x32);
     2816    }
     2817    if (fErr == NULL) {
     2818        psFree(fErr32);
     2819    }
     2820    return(NULL);
     2821}
     2822
     2823psPolynomial2D *psVectorClipFitPolynomial2D_NEW(
     2824    psPolynomial1D *poly,
     2825    psStats *stats,
     2826    const psVector *mask,
     2827    psMaskType maskValue,
     2828    const psVector *f,
     2829    const psVector *fErr,
     2830    const psVector *x,
     2831    const psVector *y)
     2832{
     2833    // Internal pointers for possibly NULL vectors.
     2834    psVector *fErr32 = NULL;
     2835
     2836    PS_ASSERT_POLY_NON_NULL(poly, NULL);
     2837    PS_ASSERT_POLY_TYPE(poly, PS_POLYNOMIAL_ORD, NULL);
     2838    PS_ASSERT_VECTOR_NON_NULL(f, NULL);
     2839    PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F32, NULL);
     2840    if (mask != NULL) {
     2841        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
     2842        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL);
     2843    }
     2844    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
     2845    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2846    PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, NULL);
     2847    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
     2848    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2849    PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F32, NULL);
     2850    if (fErr != NULL) {
     2851        PS_ASSERT_VECTORS_SIZE_EQUAL(fErr, mask, NULL);
     2852        PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL);
     2853    } else {
     2854        fErr32 = psVectorAlloc(f->n, PS_TYPE_F32);
     2855        PS_VECTOR_SET_F32(fErr32, 1.0);
     2856    }
     2857
     2858    psLogMsg(__func__, PS_LOG_WARN, "WARNING: This function has not been implemented.  Returning NULL.\n");
     2859    if (fErr == NULL) {
     2860        psFree(fErr32);
     2861    }
     2862    return(NULL);
     2863}
     2864
     2865psPolynomial3D *psVectorClipFitPolynomial3D_NEW(
     2866    psPolynomial1D *poly,
     2867    psStats *stats,
     2868    const psVector *mask,
     2869    psMaskType maskValue,
     2870    const psVector *f,
     2871    const psVector *fErr,
     2872    const psVector *x,
     2873    const psVector *y,
     2874    const psVector *z)
     2875{
     2876    // Internal pointers for possibly NULL vectors.
     2877    psVector *fErr32 = NULL;
     2878
     2879    PS_ASSERT_POLY_NON_NULL(poly, NULL);
     2880    PS_ASSERT_POLY_TYPE(poly, PS_POLYNOMIAL_ORD, NULL);
     2881    PS_ASSERT_VECTOR_NON_NULL(f, NULL);
     2882    PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F32, NULL);
     2883    if (mask != NULL) {
     2884        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
     2885        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL);
     2886    }
     2887    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
     2888    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2889    PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, NULL);
     2890    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
     2891    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2892    PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F32, NULL);
     2893    PS_ASSERT_VECTOR_NON_NULL(z, NULL);
     2894    PS_ASSERT_VECTORS_SIZE_EQUAL(f, z, NULL);
     2895    PS_ASSERT_VECTOR_TYPE(z, PS_TYPE_F32, NULL);
     2896    if (fErr != NULL) {
     2897        PS_ASSERT_VECTORS_SIZE_EQUAL(fErr, mask, NULL);
     2898        PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL);
     2899    } else {
     2900        fErr32 = psVectorAlloc(f->n, PS_TYPE_F32);
     2901        PS_VECTOR_SET_F32(fErr32, 1.0);
     2902    }
     2903
     2904    psLogMsg(__func__, PS_LOG_WARN, "WARNING: This function has not been implemented.  Returning NULL.\n");
     2905    if (fErr == NULL) {
     2906        psFree(fErr32);
     2907    }
     2908    return(NULL);
     2909}
     2910
     2911psPolynomial4D *psVectorClipFitPolynomial4D_NEW(
     2912    psPolynomial1D *poly,
     2913    psStats *stats,
     2914    const psVector *mask,
     2915    psMaskType maskValue,
     2916    const psVector *f,
     2917    const psVector *fErr,
     2918    const psVector *x,
     2919    const psVector *y,
     2920    const psVector *z,
     2921    const psVector *t)
     2922{
     2923    // Internal pointers for possibly NULL vectors.
     2924    psVector *fErr32 = NULL;
     2925
     2926    PS_ASSERT_POLY_NON_NULL(poly, NULL);
     2927    PS_ASSERT_POLY_TYPE(poly, PS_POLYNOMIAL_ORD, NULL);
     2928    PS_ASSERT_VECTOR_NON_NULL(f, NULL);
     2929    PS_ASSERT_VECTOR_TYPE(f, PS_TYPE_F32, NULL);
     2930    if (mask != NULL) {
     2931        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
     2932        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL);
     2933    }
     2934    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
     2935    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2936    PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, NULL);
     2937    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
     2938    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     2939    PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F32, NULL);
     2940    PS_ASSERT_VECTOR_NON_NULL(z, NULL);
     2941    PS_ASSERT_VECTORS_SIZE_EQUAL(f, z, NULL);
     2942    PS_ASSERT_VECTOR_TYPE(z, PS_TYPE_F32, NULL);
     2943    PS_ASSERT_VECTOR_NON_NULL(t, NULL);
     2944    PS_ASSERT_VECTORS_SIZE_EQUAL(f, t, NULL);
     2945    PS_ASSERT_VECTOR_TYPE(t, PS_TYPE_F32, NULL);
     2946    if (fErr != NULL) {
     2947        PS_ASSERT_VECTORS_SIZE_EQUAL(fErr, mask, NULL);
     2948        PS_ASSERT_VECTOR_TYPE(fErr, PS_TYPE_F32, NULL);
     2949    } else {
     2950        fErr32 = psVectorAlloc(f->n, PS_TYPE_F32);
     2951        PS_VECTOR_SET_F32(fErr32, 1.0);
     2952    }
     2953
     2954    psLogMsg(__func__, PS_LOG_WARN, "WARNING: This function has not been implemented.  Returning NULL.\n");
     2955    if (fErr == NULL) {
     2956        psFree(fErr32);
     2957    }
     2958    return(NULL);
     2959}
     2960
     2961
  • trunk/psLib/src/math/psMinimize.h

    r4898 r4958  
    88 *  @author GLG, MHPCC
    99 *
    10  *  @version $Revision: 1.53 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2005-08-30 01:14:13 $
     10 *  @version $Revision: 1.54 $ $Name: not supported by cvs2svn $
     11 *  @date $Date: 2005-09-07 21:35:50 $
    1212 *
    1313 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    9191);
    9292
     93
     94
     95
     96
     97psPolynomial1D *psVectorFitPolynomial1D_NEW(
     98    psPolynomial1D *poly,
     99    const psVector *mask,
     100    psMaskType maskValue,
     101    const psVector *f,
     102    const psVector *fErr,
     103    const psVector *x
     104);
     105
     106psPolynomial2D *psVectorFitPolynomial2D_NEW(
     107    psPolynomial1D *poly,
     108    const psVector *mask,
     109    psMaskType maskValue,
     110    const psVector *f,
     111    const psVector *fErr,
     112    const psVector *x,
     113    const psVector *y
     114);
     115
     116psPolynomial3D *psVectorFitPolynomial3D_NEW(
     117    psPolynomial1D *poly,
     118    const psVector *mask,
     119    psMaskType maskValue,
     120    const psVector *f,
     121    const psVector *fErr,
     122    const psVector *x,
     123    const psVector *y,
     124    const psVector *z
     125);
     126
     127psPolynomial4D *psVectorFitPolynomial4D_NEW(
     128    psPolynomial1D *poly,
     129    const psVector *mask,
     130    psMaskType maskValue,
     131    const psVector *f,
     132    const psVector *fErr,
     133    const psVector *x,
     134    const psVector *y,
     135    const psVector *z,
     136    const psVector *t
     137);
     138
     139
     140psPolynomial1D *psVectorClipFitPolynomial1D_NEW(
     141    psPolynomial1D *poly,
     142    psStats *stats,
     143    const psVector *mask,
     144    psMaskType maskValue,
     145    const psVector *f,
     146    const psVector *fErr,
     147    const psVector *x
     148);
     149
     150psPolynomial2D *psVectorClipFitPolynomial2D_NEW(
     151    psPolynomial1D *poly,
     152    psStats *stats,
     153    const psVector *mask,
     154    psMaskType maskValue,
     155    const psVector *f,
     156    const psVector *fErr,
     157    const psVector *x,
     158    const psVector *y
     159);
     160
     161psPolynomial3D *psVectorClipFitPolynomial3D_NEW(
     162    psPolynomial1D *poly,
     163    psStats *stats,
     164    const psVector *mask,
     165    psMaskType maskValue,
     166    const psVector *f,
     167    const psVector *fErr,
     168    const psVector *x,
     169    const psVector *y,
     170    const psVector *z
     171);
     172
     173psPolynomial4D *psVectorClipFitPolynomial4D_NEW(
     174    psPolynomial1D *poly,
     175    psStats *stats,
     176    const psVector *mask,
     177    psMaskType maskValue,
     178    const psVector *f,
     179    const psVector *fErr,
     180    const psVector *x,
     181    const psVector *y,
     182    const psVector *z,
     183    const psVector *t
     184);
     185
     186
     187
     188
    93189/** Derive a one-dimensional spline fit.
    94190 *
     
    230326/* \} */// End of MathGroup Functions
    231327
     328
     329
     330
    232331#endif // #ifndef PS_MINIMIZE_H
    233332
  • trunk/psLib/src/math/psStats.c

    r4898 r4958  
    1414 *      stats->binsize
    1515 *
    16  *  @version $Revision: 1.139 $ $Name: not supported by cvs2svn $
    17  *  @date $Date: 2005-08-30 01:14:13 $
     16 *  @version $Revision: 1.140 $ $Name: not supported by cvs2svn $
     17 *  @date $Date: 2005-09-07 21:35:50 $
    1818 *
    1919 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    4646/* DEFINE STATEMENTS                                                         */
    4747/*****************************************************************************/
    48 #define PS_GAUSS_WIDTH 5       // The width of the Gaussian or boxcar smoothing.
     48#define PS_GAUSS_WIDTH 5                // The width of the Gaussian smoothing.
     49// This corresponds to N in the ADD.
    4950#define PS_CLIPPED_NUM_ITER_LB 1
    5051#define PS_CLIPPED_NUM_ITER_UB 10
     
    292293max of the input vector.  If there was a problem with the max calculation,
    293294this routine sets stats->max to NAN.
     295 
     296XXX: Do we need to factor errors into it?
    294297 *****************************************************************************/
    295298psS32 p_psVectorMax(const psVector* myVector,
     
    614617/******************************************************************************
    615618p_psVectorSmoothHistGaussian(): This routine smoothes the data in the input
    616 robustHistogram with a Gaussian of width sigma.
     619robustHistogram with a Gaussian of width sigma.  It returns a psVector of the
     620smoothed data.
    617621 
    618622XXX: Only PS_TYPE_F32 is supported.
     
    621625call that.  Is that possible?
    622626 *****************************************************************************/
    623 psVector* p_psVectorSmoothHistGaussian(psHistogram* robustHistogram,
     627psVector *p_psVectorSmoothHistGaussian(psHistogram *histogram,
    624628                                       psF32 sigma)
    625629{
    626     PS_ASSERT_PTR_NON_NULL(robustHistogram, NULL);
    627     PS_ASSERT_PTR_NON_NULL(robustHistogram->bounds, NULL);
    628 
    629     psS32 i = 0;                  // Loop index variable
    630     psS32 j = 0;                  // Loop index variable
    631     psF32 iMid;
    632     psF32 jMid;
    633     psS32 numBins = robustHistogram->nums->n;
    634     psS32 numBounds = robustHistogram->bounds->n;
    635     psVector* smooth = psVectorAlloc(numBins, PS_TYPE_F32);
     630    PS_ASSERT_PTR_NON_NULL(histogram, NULL);
     631    PS_ASSERT_PTR_NON_NULL(histogram->bounds, NULL);
     632    PS_ASSERT_PTR_NON_NULL(histogram->nums, NULL);
     633
     634    psS32 numBins = histogram->nums->n;
     635    psS32 numBounds = histogram->bounds->n;
     636    psVector *smooth = psVectorAlloc(numBins, PS_TYPE_F32);
     637    psF32 firstBound = histogram->bounds->data.F32[0];
     638    psF32 lastBound = histogram->bounds->data.F32[numBounds-1];
     639    psScalar x;
     640    x.type.type = PS_TYPE_F32;
    636641    psS32 jMin = 0;
    637642    psS32 jMax = 0;
    638     psF32 firstBound = robustHistogram->bounds->data.F32[0];
    639     psF32 lastBound = robustHistogram->bounds->data.F32[numBounds-1];
     643
     644    if (histogram->uniform == false) {
     645        //
     646        // We get here if the histogram is non-uniform.
     647        //
     648
     649        for (psS32 i = 0; i < numBins; i++) {
     650            // Determine the midpoint of bin i.
     651            psS32 iMid = PS_BIN_MIDPOINT(histogram, i);
     652
     653            //
     654            // We determine the bin numbers (jMin:jMax) corresponding to a
     655            // range of data values surrounding iMid.  The range is of size:
     656            // 2*PS_GAUSS_WIDTH*sigma
     657            //
     658            x.data.F32 = iMid - (PS_GAUSS_WIDTH * sigma);
     659            if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
     660                jMin = p_psVectorBinDisect( *(psVector* *)&histogram->bounds, &x);
     661                if (jMin < 0) {
     662                    psError(PS_ERR_UNEXPECTED_NULL,
     663                            false,
     664                            PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
     665                    return(NULL);
     666                }
     667            } else if (x.data.F32 <= firstBound) {
     668                jMin = 0;
     669            } else if (x.data.F32 >= lastBound) {
     670                jMin = histogram->bounds->n - 1;
     671            }
     672
     673            x.data.F32 = iMid + (PS_GAUSS_WIDTH * sigma);
     674            if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
     675                jMax = p_psVectorBinDisect( *(psVector* *)&histogram->bounds, &x);
     676                if (jMax < 0) {
     677                    psError(PS_ERR_UNEXPECTED_NULL,
     678                            false,
     679                            PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
     680                    return(NULL);
     681                }
     682            } else if (x.data.F32 <= firstBound) {
     683                jMax = 0;
     684            } else if (x.data.F32 >= lastBound) {
     685                jMax = histogram->bounds->n - 1;
     686            }
     687
     688            //
     689            // Loop from jMin to jMax, computing the gaussian of data i.
     690            //
     691            smooth->data.F32[i] = 0.0;
     692            for (psS32 j = jMin ; j <= jMax ; j++) {
     693                psS32 jMid = PS_BIN_MIDPOINT(histogram, j);
     694                smooth->data.F32[i] +=
     695                    histogram->nums->data.F32[j] * psGaussian(jMid, iMid, sigma, true);
     696            }
     697        }
     698    } else {
     699        //
     700        // We get here if the histogram is uniform.
     701        //
     702
     703        for (psS32 i = 0; i < numBins; i++) {
     704            psF32 binSize = histogram->bounds->data.F32[1] - histogram->bounds->data.F32[0];
     705            psS32 gaussWidth = (psS32) ((PS_GAUSS_WIDTH * sigma) / binSize);
     706
     707            //
     708            // We determine the bin numbers (jMin:jMax) corresponding to a
     709            // range of data values surrounding iMid.  The range is of size:
     710            // 2*PS_GAUSS_WIDTH*sigma
     711            //
     712            psS32 jMin = i - gaussWidth;
     713            if (jMin < 0 ) {
     714                jMin = 0;
     715            }
     716            psS32 jMax = i + gaussWidth;
     717            if (jMax > (histogram->bounds->n - 1)) {
     718                jMax = (histogram->bounds->n - 1);
     719            }
     720
     721            //
     722            // Loop from jMin to jMax, computing the gaussian of data i.
     723            //
     724            smooth->data.F32[i] = 0.0;
     725            psS32 iMid = PS_BIN_MIDPOINT(histogram, i);
     726            for (psS32 j = jMin ; j <= jMax ; j++) {
     727                psS32 jMid = PS_BIN_MIDPOINT(histogram, j);
     728                smooth->data.F32[i] +=
     729                    histogram->nums->data.F32[j] * psGaussian(jMid, iMid, sigma, true);
     730            }
     731        }
     732    }
     733
     734    return(smooth);
     735}
     736/******************************************************************************
     737p_psVectorSmoothHistGaussianNEW(): This routine smoothes the data in the input
     738robustHistogram with a Gaussian of width sigma.  It returns a psVector of the
     739smoothed data.
     740 
     741XXX: Only PS_TYPE_F32 is supported.
     742 
     743XXX: Write a general routine which smoothes a psVector.  This routine should
     744call that.  Is that possible?
     745 *****************************************************************************/
     746psVector *p_psVectorSmoothHistGaussianNEW(psHistogram *histogram,
     747        psF32 sigma)
     748{
     749    PS_ASSERT_PTR_NON_NULL(histogram, NULL);
     750    PS_ASSERT_PTR_NON_NULL(histogram->bounds, NULL);
     751    PS_ASSERT_PTR_NON_NULL(histogram->nums, NULL);
     752
     753    psS32 numBins = histogram->nums->n;
     754    psS32 numBounds = histogram->bounds->n;
     755    psVector *smooth = psVectorAlloc(numBins, PS_TYPE_F32);
     756    psF32 firstBound = histogram->bounds->data.F32[0];
     757    psF32 lastBound = histogram->bounds->data.F32[numBounds-1];
    640758    psScalar x;
    641 
    642759    x.type.type = PS_TYPE_F32;
    643     for (i = 0; i < numBins; i++) {
    644         // Determine the midpoint of bin i.
    645         iMid = (robustHistogram->bounds->data.F32[i] +
    646                 robustHistogram->bounds->data.F32[i+1]) / 2.0;
    647 
    648 
    649         // We determine the bin numbers corresponding to a range of data
    650         // values surrounding iMid.  The ranges is of size
    651         // s*PS_GAUSS_WIDTH*sigma
    652 
    653         // YYY: The p_psVectorBinDisect() routine does much of the work of
    654         // the following conditionals, however, it also reports a warning
    655         // message.  I don't want the warning message so I reproduce the
    656         // conditionals here.  Maybe p_psVectorBinDisect() should not produce
    657         // warnings?
    658 
    659         x.data.F32 = iMid - (PS_GAUSS_WIDTH * sigma);
    660         if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
    661             jMin = p_psVectorBinDisect( *(psVector* *)&robustHistogram->bounds, &x);
    662             if (jMin < 0) {
    663                 psError(PS_ERR_UNEXPECTED_NULL,
    664                         false,
    665                         PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
    666                 return(NULL);
    667             }
    668         } else if (x.data.F32 <= firstBound) {
    669             jMin = 0;
    670         } else if (x.data.F32 >= lastBound) {
    671             jMin = robustHistogram->bounds->n - 1;
    672         }
    673 
    674         x.data.F32 = iMid + (PS_GAUSS_WIDTH * sigma);
    675         if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
    676             jMax = p_psVectorBinDisect( *(psVector* *)&robustHistogram->bounds, &x);
    677             if (jMax < 0) {
    678                 psError(PS_ERR_UNEXPECTED_NULL,
    679                         false,
    680                         PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
    681                 return(NULL);
    682             }
    683         } else if (x.data.F32 <= firstBound) {
    684             jMax = 0;
    685         } else if (x.data.F32 >= lastBound) {
    686             jMax = robustHistogram->bounds->n - 1;
    687         }
    688 
    689         smooth->data.F32[i] = 0.0;
    690         for (j = jMin ; j <= jMax ; j++) {
    691             jMid = (robustHistogram->bounds->data.F32[j] +
    692                     robustHistogram->bounds->data.F32[j+1]) / 2.0;
    693             smooth->data.F32[i] +=
    694                 robustHistogram->nums->data.F32[j] *
    695                 psGaussian(jMid, iMid, sigma, true);
     760    psS32 jMin = 0;
     761    psS32 jMax = 0;
     762
     763    if (histogram->uniform == false) {
     764        //
     765        // We get here if the histogram is non-uniform.
     766        //
     767
     768        for (psS32 i = 0; i < numBins; i++) {
     769            // Determine the midpoint of bin i.
     770            psS32 iMid = PS_BIN_MIDPOINT(histogram, i);
     771
     772            //
     773            // We determine the bin numbers (jMin:jMax) corresponding to a
     774            // range of data values surrounding iMid.  The range is of size:
     775            // 2*PS_GAUSS_WIDTH*sigma
     776            //
     777            x.data.F32 = iMid - (PS_GAUSS_WIDTH * sigma);
     778            if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
     779                jMin = p_psVectorBinDisect( *(psVector* *)&histogram->bounds, &x);
     780                if (jMin < 0) {
     781                    psError(PS_ERR_UNEXPECTED_NULL,
     782                            false,
     783                            PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
     784                    return(NULL);
     785                }
     786            } else if (x.data.F32 <= firstBound) {
     787                jMin = 0;
     788            } else if (x.data.F32 >= lastBound) {
     789                jMin = histogram->bounds->n - 1;
     790            }
     791
     792            x.data.F32 = iMid + (PS_GAUSS_WIDTH * sigma);
     793            if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
     794                jMax = p_psVectorBinDisect( *(psVector* *)&histogram->bounds, &x);
     795                if (jMax < 0) {
     796                    psError(PS_ERR_UNEXPECTED_NULL,
     797                            false,
     798                            PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
     799                    return(NULL);
     800                }
     801            } else if (x.data.F32 <= firstBound) {
     802                jMax = 0;
     803            } else if (x.data.F32 >= lastBound) {
     804                jMax = histogram->bounds->n - 1;
     805            }
     806
     807            //
     808            // Loop from jMin to jMax, computing the gaussian of data i.
     809            //
     810            smooth->data.F32[i] = 0.0;
     811            for (psS32 j = jMin ; j <= jMax ; j++) {
     812                psS32 jMid = PS_BIN_MIDPOINT(histogram, j);
     813                smooth->data.F32[i] +=
     814                    histogram->nums->data.F32[j] * psGaussian(jMid, iMid, sigma, true);
     815            }
     816        }
     817    } else {
     818        //
     819        // We get here if the histogram is uniform.
     820        //
     821
     822        for (psS32 i = 0; i < numBins; i++) {
     823            psF32 binSize = histogram->bounds->data.F32[1] - histogram->bounds->data.F32[0];
     824            psS32 gaussWidth = (psS32) ((PS_GAUSS_WIDTH * sigma) / binSize);
     825
     826            //
     827            // We determine the bin numbers (jMin:jMax) corresponding to a
     828            // range of data values surrounding iMid.  The range is of size:
     829            // 2*PS_GAUSS_WIDTH*sigma
     830            //
     831            psS32 jMin = i - gaussWidth;
     832            if (jMin < 0 ) {
     833                jMin = 0;
     834            }
     835            psS32 jMax = i + gaussWidth;
     836            if (jMax > (histogram->bounds->n - 1)) {
     837                jMax = (histogram->bounds->n - 1);
     838            }
     839
     840            //
     841            // Loop from jMin to jMax, computing the gaussian of data i.
     842            //
     843            smooth->data.F32[i] = 0.0;
     844            psS32 iMid = PS_BIN_MIDPOINT(histogram, i);
     845            for (psS32 j = jMin ; j <= jMax ; j++) {
     846                psS32 jMid = PS_BIN_MIDPOINT(histogram, j);
     847                smooth->data.F32[i] +=
     848                    histogram->nums->data.F32[j] * psGaussian(jMid, iMid, sigma, true);
     849            }
    696850        }
    697851    }
     
    11421296These macros and functions define the following functions:
    11431297 
    1144 <    p_psNormalizeVectorRange(myData, low, high)
     1298    p_psNormalizeVectorRange(myData, low, high)
    11451299 
    11461300That assumes that the low/high arguments are PS_TYPE_F64; the vector myData
     
    12511405
    12521406/******************************************************************************
    1253 p_ps1DPolyMedian(myPoly, rangeLow, rangeHigh, midpoint): This routine takes
    1254 as input a 1-D polynomial of arbitrary order (though we are using 2nd-order
    1255 polynomials here) and a range of x-values for which it is defined:
    1256 [rangeLow, rangeHigh].  It determines the x-value of that polynomial such
    1257 that f(x) == midpoint.  This functions uses a binary-search algorithm on the
    1258 range and assumes that the polynomial is monotonically increasing or
    1259 decreasing within that range.
     1407p_ps1DPolyMedian(myPoly, rangeLow, rangeHigh, getThisValue): This routine
     1408takes as input a 1-D polynomial of arbitrary order and a range of x-values for
     1409which it is defined:  [rangeLow, rangeHigh].  It determines the x-value of
     1410that polynomial such that f(x) == getThisValue.  This function uses a
     1411binary-search algorithm on the range and assumes that the polynomial is
     1412monotonically increasing or decreasing within that range.
    12601413 
    12611414XXX: Terminate when f(x)-getThisValue is within some error tolerance.
     
    12691422{
    12701423    PS_ASSERT_POLY_NON_NULL(myPoly, NAN);
    1271     PS_FLOAT_COMPARE(rangeLow, rangeHigh, NAN);
     1424    PS_ASSERT_FLOAT_LARGER_THAN(rangeHigh, rangeLow, NAN);
    12721425    // We ensure that the requested f(y) value, which is getThisValue, is
    12731426    // falls within the range of y-values of the polynomial "myPoly" in the
    12741427    // specified x-range (rangeLow:rangeHigh).
    1275     psF32 fLo = psPolynomial1DEval(
    1276                     myPoly,
    1277                     rangeLow
    1278                 );
    1279     psF32 fHi = psPolynomial1DEval(
    1280                     myPoly,
    1281                     rangeHigh
    1282                 );
     1428    psF32 fLo = psPolynomial1DEval(myPoly, rangeLow);
     1429    psF32 fHi = psPolynomial1DEval(myPoly, rangeHigh);
    12831430    if (!((fLo <= getThisValue) && (fHi >= getThisValue))) {
    12841431        psError(PS_ERR_UNKNOWN,
     
    13001447        oldMidpoint = midpoint;
    13011448
    1302         f = psPolynomial1DEval(
    1303                 myPoly,
    1304                 midpoint
    1305             );
     1449        f = psPolynomial1DEval(myPoly, midpoint);
    13061450        if (fabs(f - getThisValue) <= FLT_EPSILON) {
    13071451            return (midpoint);
     
    13311475XXX: the vectors do not have to be the same length.  Must insert the proper
    13321476tests to ensure that binNum is within acceptable ranges for both vectors.
     1477 
     1478XXX: This currently assumes that the three points are monotonically increasing
     1479or decreasing: so, it works for the cumulative histogram vectors, but not for
     1480arbitrary vectors.  We should probably test that condition.
    13331481*****************************************************************************/
    13341482psF32 fitQuadraticSearchForYThenReturnX(psVector *xVec,
     
    13451493    PS_ASSERT_INT_WITHIN_RANGE(binNum, 0, (yVec->n - 1), NAN);
    13461494
    1347     //    PS_VECTOR_DECLARE_ALLOC_STATIC(x, 3, PS_TYPE_F64);
    1348     //    PS_VECTOR_DECLARE_ALLOC_STATIC(y, 3, PS_TYPE_F64);
    1349     //    PS_VECTOR_DECLARE_ALLOC_STATIC(yErr, 3, PS_TYPE_F64);
    1350     //    PS_POLY_1D_DECLARE_ALLOC_STATIC(myPoly, 2, PS_POLYNOMIAL_ORD);
    13511495    psVector *x = psVectorAlloc(3, PS_TYPE_F64);
    13521496    psVector *y = psVectorAlloc(3, PS_TYPE_F64);
     
    13641508        y->data.F64[1] = yVec->data.F32[binNum];
    13651509        y->data.F64[2] = yVec->data.F32[binNum + 1];
     1510
     1511        //
     1512        // Ensure that the y values are monotonic.
     1513        //
     1514        // XXX: This routine should probably be rewritten in a more general fashion
     1515        // so that the folloiwng checks are not necessary.
     1516        //
     1517        if (y->data.F64[0] < y->data.F64[1]) {
     1518            if (!(y->data.F64[1] <= y->data.F64[2])) {
     1519                psError(PS_ERR_UNKNOWN, true, "This routine must be called with montically increasing or decreasing data points.\n");
     1520                psFree(myPoly);
     1521                psFree(x);
     1522                psFree(y);
     1523                psFree(yErr);
     1524                return(NAN);
     1525            }
     1526        } else {
     1527            if (!(y->data.F64[1] >= y->data.F64[2])) {
     1528                psError(PS_ERR_UNKNOWN, true, "This routine must be called with montically increasing or decreasing data points.\n");
     1529                psFree(myPoly);
     1530                psFree(x);
     1531                psFree(y);
     1532                psFree(yErr);
     1533                return(NAN);
     1534            }
     1535        }
    13661536
    13671537        // Ensure that yVal is within the range of the bins we are using.
     
    16371807        // code no longer produces sensible results.
    16381808        // XXX: Since we are no longer fitting a 1-D Gaussian, we can probably
    1639         // remove some of theabove code that calculated the initial estimate
     1809        // remove some of the above code that calculated the initial estimate
    16401810        // for the mean and sigma.
    16411811
     
    16451815            int index = i - modeBinNum + dL;
    16461816            // XXX: Should this be the natural log?
    1647             y->data.F32[index] = robustHistogramVector->data.F32[i];
    1648             //            y->data.F32[index] = logf(robustHistogramVector->data.F32[i]);
     1817            //            y->data.F32[index] = robustHistogramVector->data.F32[i];
     1818            y->data.F32[index] = logf(robustHistogramVector->data.F32[i]);
    16491819            x->data.F32[index] = (psF32) index;
    16501820        }
     
    17421912    psFree(robustHistogramVector);
    17431913    psFree(cumulativeRobustSums);
     1914
    17441915    return(0);
    17451916}
     1917
     1918
     1919/*****************************************************************************
     1920XXX: Is there a psLib function for this?
     1921 *****************************************************************************/
     1922psVector *PsVectorDup(psVector *in)
     1923{
     1924    psVector *out = psVectorAlloc(in->n, in->type.type);
     1925
     1926    if (in->type.type == PS_TYPE_F32) {
     1927        for (psS32 i = 0 ; i < in->n ; i++) {
     1928            out->data.F32[i] = in->data.F32[i];
     1929        }
     1930    } else if (in->type.type == PS_TYPE_F64) {
     1931        for (psS32 i = 0 ; i < in->n ; i++) {
     1932            out->data.F64[i] = in->data.F64[i];
     1933        }
     1934    } else {
     1935        printf("XXX: Generate an error here.\n");
     1936        return(NULL);
     1937    }
     1938    return(out);
     1939}
     1940
     1941/******************************************************************************
     1942XXX: This function need to be written.  Actually, it simply needs to be
     1943retrieved from the CVS repository, since it was written earlier, then
     1944discarded.  At present, it was deleted from the CVS repository, so we might
     1945have to retrieve it from tape.
     1946*****************************************************************************/
     1947psVector *Fit1DGaussian(psVector *x, psVector*y)
     1948{
     1949    printf("XXX: Generate an error here.\n");
     1950    printf("XXX: Error: This function was previously part of psStats.c, was removed, was purged from CVS, and now needs to be retrieved from tape.\n");
     1951    return(NULL);
     1952}
     1953
     1954/******************************************************************************
     1955 
     1956p_psVectorRobustStatsNew(myVector, maskVector, maskVal, stats): This is the new
     1957version of the robust stats routine.
     1958 
     1959XXX: MUST DO: If the errors in the input values are known, then the same
     1960approach is used, except that the histograms become probability density
     1961functions (PDFs). In this case, the input values are spread out, so that they
     1962do not simply contribute a single unit to the histogram, but rather contribute
     1963a fraction of a value, equivalent to the weight. In the interests of speed, a
     1964boxcar PDF may be used to represent each input value (as opposed to a
     1965Gaussian), where the boxcar width is equal to 2p2 ln 2 times the error and
     1966each input value contributes constant area. Then the robust median and
     1967standard deviation are estimated in the same manner as above.
     1968 
     1969XXX: Check for errors in psLib routines that we call.
     1970*****************************************************************************/
     1971psS32 p_psVectorRobustStatsNew(const psVector* myVector,
     1972                               const psVector* errors,
     1973                               const psVector* maskVector,
     1974                               psU32 maskVal,
     1975                               psStats* stats)
     1976{
     1977    psHistogram *robustHistogram = NULL;
     1978    psHistogram *cumulativeRobustHistogram = NULL;
     1979    psS32 numBins = 0;
     1980    psScalar *tmpScalar = psScalarAlloc(0.0, PS_TYPE_F32);
     1981    tmpScalar->type.type = PS_TYPE_F32;
     1982    psS32 totalDataPoints = 0;
     1983    psS32 rc = 0;
     1984    psVector *tmpMaskVec = PsVectorDup((psVector *) maskVector);
     1985
     1986    while (1) {
     1987        //
     1988        // Determine the bin size of the robust histogram.  This is done
     1989        // by computing the total range of data values and dividing by 1000.0.
     1990        //
     1991        psStats* tmpStatsMinMax = psStatsAlloc(PS_STAT_MIN | PS_STAT_MAX);
     1992        rc = p_psVectorMin(myVector, tmpMaskVec, maskVal, tmpStatsMinMax);
     1993        rc|= p_psVectorMax(myVector, tmpMaskVec, maskVal, tmpStatsMinMax);
     1994        if ((rc != 0) || isnan(tmpStatsMinMax->min) || isnan(tmpStatsMinMax->max)) {
     1995            psError(PS_ERR_UNKNOWN, false, "Failed to calculate the min/max of the input vector.\n");
     1996            psFree(tmpStatsMinMax);
     1997            psFree(tmpMaskVec);
     1998            psFree(tmpScalar);
     1999            return(1);
     2000        }
     2001        psF32 binSize = (tmpStatsMinMax->max - tmpStatsMinMax->min) / 1000.0f;
     2002
     2003        //
     2004        // If all data points have the same value, then we set the appropiate
     2005        // members of stats and return.
     2006        //
     2007        if (fabs(tmpStatsMinMax->max - tmpStatsMinMax->min) <= FLT_EPSILON) {
     2008            if (stats->options & PS_STAT_ROBUST_MEDIAN) {
     2009                stats->robustMedian = tmpStatsMinMax->min;
     2010            }
     2011            if (stats->options & PS_STAT_ROBUST_QUARTILE) {
     2012                stats->robustUQ = tmpStatsMinMax->min;
     2013                stats->robustLQ = tmpStatsMinMax->min;
     2014            }
     2015            // XXX: Set these to the number of unmasked data points?
     2016            stats->robustNfit = 0.0;
     2017            stats->robustN50 = 0.0;
     2018            psFree(tmpStatsMinMax);
     2019            psFree(tmpMaskVec);
     2020            psFree(tmpScalar);
     2021
     2022            return(0);
     2023        }
     2024
     2025        //
     2026        // ADD: Step 0.
     2027        // Construct the histogram with the specified bin size.
     2028        //
     2029        // NOTE: we can not specify the bin size precisely since the argument
     2030        // to psHistogramAlloc() is the number of bins, not the binSize.
     2031        // If we get here, we know that binSize != 0.0.
     2032        //
     2033        numBins = (psS32)((tmpStatsMinMax->max - tmpStatsMinMax->min) / binSize);
     2034        robustHistogram = psHistogramAlloc(tmpStatsMinMax->min, tmpStatsMinMax->max, numBins);
     2035        cumulativeRobustHistogram = psHistogramAlloc(tmpStatsMinMax->min, tmpStatsMinMax->max, numBins);
     2036
     2037        // Populate the histogram array.
     2038        psVectorHistogram(robustHistogram, myVector, errors, tmpMaskVec, maskVal);
     2039
     2040        //
     2041        // ADD: Step 1.
     2042        // Construct the cumulative histogram from the specific histogram
     2043        //
     2044        cumulativeRobustHistogram->nums->data.F32[0] = robustHistogram->nums->data.F32[0];
     2045        for (psS32 i = 1 ; i < robustHistogram->nums->n ; i++) {
     2046            cumulativeRobustHistogram->nums->data.F32[i] = cumulativeRobustHistogram->nums->data.F32[i-1] +
     2047                    robustHistogram->nums->data.F32[i];
     2048        }
     2049
     2050        //
     2051        // ADD: Step 2.
     2052        // Find the bin which contains the 50% data point.
     2053        //
     2054        totalDataPoints = cumulativeRobustHistogram->nums->data.F32[numBins - 1];
     2055        tmpScalar->data.F32 = totalDataPoints/2.0;
     2056        psS32 binMedian = p_psVectorBinDisect(cumulativeRobustHistogram->nums, tmpScalar);
     2057        if (binMedian != 0) {
     2058            psError(PS_ERR_UNKNOWN, false, "Failed to calculate the 50% data point.\n");
     2059            psFree(tmpStatsMinMax);
     2060            psFree(robustHistogram);
     2061            psFree(cumulativeRobustHistogram);
     2062            psFree(tmpScalar);
     2063            return(1);
     2064        }
     2065
     2066        //
     2067        // ADD: Step 3.
     2068        // Interpolate to the exact 50% position: this is the robust histogram median.
     2069        // XXX: Check for errors here!
     2070        //
     2071        stats->robustMedian = fitQuadraticSearchForYThenReturnX(
     2072                                  *(psVector* *)&robustHistogram->bounds,
     2073                                  *(psVector* *)&robustHistogram->nums,
     2074                                  binMedian,
     2075                                  totalDataPoints/2.0);
     2076
     2077        //
     2078        // ADD: Step 4.
     2079        // Find the bins which contains the 15.8655% and 84.1345% data points.
     2080        //
     2081        tmpScalar->data.F32 = totalDataPoints * 0.158655f;
     2082        psS32 binLo = p_psVectorBinDisect(cumulativeRobustHistogram->nums, tmpScalar);
     2083        tmpScalar->data.F32 = totalDataPoints * 0.841345f;
     2084        psS32 binHi = p_psVectorBinDisect(cumulativeRobustHistogram->nums, tmpScalar);
     2085        if ((binLo != 0) || (binHi != 0)) {
     2086            psError(PS_ERR_UNKNOWN, false, "Failed to calculate the15.8655% and 84.1345% data point\n");
     2087            psFree(tmpStatsMinMax);
     2088            psFree(robustHistogram);
     2089            psFree(cumulativeRobustHistogram);
     2090            psFree(tmpScalar);
     2091            return(1);
     2092        }
     2093
     2094        //
     2095        // ADD: Step 4b.
     2096        // Interpolate Sigma to find these two positions exactly: these are the 1sigma positions.
     2097        //
     2098        psF32 binLoF32 = fitQuadraticSearchForYThenReturnX(
     2099                             *(psVector* *)&robustHistogram->bounds,
     2100                             *(psVector* *)&robustHistogram->nums,
     2101                             binLo,
     2102                             totalDataPoints * 0.158655f);
     2103        psF32 binHiF32 = fitQuadraticSearchForYThenReturnX(
     2104                             *(psVector* *)&robustHistogram->bounds,
     2105                             *(psVector* *)&robustHistogram->nums,
     2106                             binHi,
     2107                             totalDataPoints * 0.841345f);
     2108
     2109        //
     2110        // ADD: Step 5.
     2111        // Determine SIGMA as 1/2 of the distance between these positions.
     2112        //
     2113        psF32 sigma = (binHiF32 - binLoF32) / 2.0;
     2114
     2115        //
     2116        // ADD: Step 6.
     2117        // If the measured SIGMA is less than 2 times the bin size, exclude
     2118        // points which are more than 25 bins from the median,
     2119        // recalculate the bin size, and perform the algorithm again.
     2120        //
     2121        if (sigma < (2 * binSize)) {
     2122            psF32 medianLo = robustHistogram->bounds->data.F32[binMedian - 25];
     2123            psF32 medianHi = robustHistogram->bounds->data.F32[binMedian + 25];
     2124            for (psS32 i = 0 ; i < myVector->n ; i++) {
     2125                if ((myVector->data.F32[i] < medianLo) ||
     2126                        (myVector->data.F32[i] > medianHi)) {
     2127                    tmpMaskVec->data.U8[i] = 1;
     2128                }
     2129            }
     2130        } else {
     2131            //
     2132            // ADD: Step 7.
     2133            // Find the bins which contains the 25% and 75% data points.
     2134            //
     2135            tmpScalar->data.F32 = totalDataPoints * 0.25f;
     2136            psS32 binLo25 = p_psVectorBinDisect(cumulativeRobustHistogram->nums, tmpScalar);
     2137            tmpScalar->data.F32 = totalDataPoints * 0.75f;
     2138            psS32 binHi25 = p_psVectorBinDisect(cumulativeRobustHistogram->nums, tmpScalar);
     2139            if ((binLo25 != 0) || (binHi25 != 0)) {
     2140                psError(PS_ERR_UNKNOWN, false, "Failed to calculate the 25% and 75% data points\n");
     2141                psFree(tmpStatsMinMax);
     2142                psFree(robustHistogram);
     2143                psFree(cumulativeRobustHistogram);
     2144                psFree(tmpScalar);
     2145                return(1);
     2146            }
     2147
     2148            //
     2149            // ADD: Step 8.
     2150            // Interpolate to find these two positions exactly: these are the upper
     2151            // and lower quartile positions.
     2152            // XXX: Check for errors.
     2153            //
     2154            psF32 binLo25F32 = fitQuadraticSearchForYThenReturnX(
     2155                                   *(psVector* *)&robustHistogram->bounds,
     2156                                   *(psVector* *)&robustHistogram->nums,
     2157                                   binLo25,
     2158                                   totalDataPoints * 0.25f);
     2159            psF32 binHi25F32 = fitQuadraticSearchForYThenReturnX(
     2160                                   *(psVector* *)&robustHistogram->bounds,
     2161                                   *(psVector* *)&robustHistogram->nums,
     2162                                   binHi25,
     2163                                   totalDataPoints * 0.75f);
     2164
     2165            stats->robustLQ = binLo25F32;
     2166            stats->robustUQ = binHi25F32;
     2167            // XXX: No idea how to calculate stats->stdev
     2168
     2169            // PS_BIN_MIDPOINT(robustHistogram, modeBinNum);
     2170
     2171            // XXX: I think sumNfit == sumN50 here.
     2172            stats->robustNfit = -1;
     2173            stats->robustN50 = -1;
     2174
     2175            //
     2176            // Perform the Robust Histogram Statistics algorithm above
     2177            //
     2178
     2179            //
     2180            // Smooth the resulting histogram with a Gaussian with SIGMA_s = 1
     2181            // bin.
     2182            //
     2183            // XXX: SIGMA_s is defined nowhere in the ADD.
     2184            //
     2185            psF32 SIGMA_S = 1.0;
     2186            p_psVectorSmoothHistGaussian(robustHistogram, SIGMA_S);
     2187
     2188            //
     2189            // Find the bin with the peak value in the range 2 SIGMA of the
     2190            // robust histogram median.
     2191            //
     2192            // XXX: SIGMA is defined nowhere in the ADD.
     2193            //
     2194            psF32 SIGMA = 2.0;
     2195            psS32 binMin = binMedian - (SIGMA * PS_GAUSS_WIDTH);
     2196            if (binMin < 0) {
     2197                binMin = 0;
     2198            }
     2199            psS32 binMax = binMedian + (2 * PS_GAUSS_WIDTH);
     2200            if (binMin > (robustHistogram->nums->n - 1)) {
     2201                binMin = (robustHistogram->nums->n - 1);
     2202            }
     2203            psS32 binNum = binNum;
     2204            psF32 binMaxNums = robustHistogram->nums->data.F32[binNum];
     2205            for (psS32 i = binNum+1 ; i <= binMax ; i++) {
     2206                if (robustHistogram->nums->data.F32[i] > binMaxNums) {
     2207                    binNum = i;
     2208                    binMaxNums = robustHistogram->nums->data.F32[i];
     2209                }
     2210            }
     2211
     2212            //
     2213            // Fit a Gaussian to the bins in the range 2 SIGMA of the robust
     2214            // histogram median.
     2215            //
     2216            // XXX: SIGMA is defined nowhere in the ADD.
     2217            //
     2218            psVector *y = psVectorAlloc((1 + (binMax - binMin)), PS_TYPE_F32);
     2219            psVector *x = psVectorAlloc((1 + (binMax - binMin)), PS_TYPE_F32);
     2220            psS32 j = 0;
     2221            for (psS32 i = binNum ; i <= binMax ; i++) {
     2222                y->data.F32[j] = robustHistogram->nums->data.F32[i];
     2223                x->data.F32[j] = PS_BIN_MIDPOINT(robustHistogram, i);
     2224            }
     2225            //
     2226            // XXX: This function need to be written.  Actually, it simply
     2227            // needs to be retrieved from the CVS repository, since it was
     2228            // written earlier, then discarded.  At present, it was deleted
     2229            // from the CVS repository, so we might have to retrieve it from
     2230            // tape.
     2231            //
     2232            psVector *params = Fit1DGaussian(x, y);
     2233
     2234            //
     2235            // The robust mean mean_r is derived directly from the fitted
     2236            // Gaussian mean.
     2237            //
     2238            stats->robustMean = params->data.F32[0];
     2239
     2240            //
     2241            // The robust standard deviation, SIGMA_r is determined by
     2242            // subtracting the smoothing scale in quadrature: SIGMA_r^2 = SIGMA^2
     2243            // - SIGMA_s^2
     2244            //
     2245            // XXX: SIGMA and SIGMA_s are defined nowhere in the ADD.  We must figure
     2246            // out what they are.
     2247            //
     2248            stats->robustStdev = sqrt(PS_SQR(SIGMA) - PS_SQR(SIGMA_S));
     2249
     2250            psFree(tmpStatsMinMax);
     2251            psFree(robustHistogram);
     2252            psFree(cumulativeRobustHistogram);
     2253            psFree(tmpScalar);
     2254            psFree(params);
     2255
     2256            return(0);
     2257        }
     2258
     2259        psFree(tmpStatsMinMax);
     2260        psFree(robustHistogram);
     2261        psFree(cumulativeRobustHistogram);
     2262    }
     2263    return(1);
     2264}
     2265
     2266
     2267
     2268
     2269
     2270
     2271
     2272
    17462273
    17472274/*****************************************************************************/
Note: See TracChangeset for help on using the changeset viewer.