IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 16, 2013, 5:49:11 PM (13 years ago)
Author:
watersc1
Message:

Partially corrected psStats code. psStats/robustMedian handles small numbers of inputs correctly. psMinimizePolyFit attempts to scale the ordinary polynomial fit data by the median and scale to make the fitting somewhat more stable. psBinomialCoeff is necessary to implement this scaling, so it is added here as a stand alone function. There is still a bias in the fitting results that I need to sort out still, but this fixes the known stats failure modes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/math/psMinimizePolyFit.c

    r31152 r36222  
    4242#include "psLogMsg.h"
    4343#include "psMathUtils.h"
     44#include "psBinomialCoeff.h"
    4445/*****************************************************************************/
    4546/* DEFINE STATEMENTS                                                         */
    4647/*****************************************************************************/
     48#define CZW 0
    4749
    4850# define USE_GAUSS_JORDAN 1
     
    603605    bool status = false;
    604606    if (USE_GAUSS_JORDAN) {
     607
     608#if (CZW)
     609        printf("CZW: about to do GJ: %d\n",status);
     610        for (psS32 k = 0; k < nTerm; k++) {
     611          printf("CZW: %d %f \t",k,B->data.F64[k]);
     612          for (psS32 kk = 0; kk < nTerm; kk++) {
     613            printf(" %f ",(A->data.F64[k][kk]));
     614          }
     615          printf("\n");
     616        }
     617#endif
    605618        status = psMatrixGJSolve(A, B);
     619#if (CZW)
     620        printf("CZW: just did GJ: %d\n",status);
     621        for (psS32 k = 0; k < nTerm; k++) {
     622          printf("CZW: %d %f \t",k,B->data.F64[k]);
     623          for (psS32 kk = 0; kk < nTerm; kk++) {
     624            printf(" %f ",(A->data.F64[k][kk]));
     625          }
     626          printf("\n");
     627        }
     628#endif
    606629    } else {
    607630        status = psMatrixLUSolve(A, B);
     
    676699    bool result = true;
    677700
     701    // Define values that may be used by PS_POLYNOMIAL_ORD form.
     702    bool scale = false;
     703    double median = 0.0;
     704    double sigma = 1.0;
     705    psVector *sorted = NULL;
     706    psVector *z64 = NULL;
     707   
    678708    switch (poly->type) {
    679709    case PS_POLYNOMIAL_ORD:
    680         result = VectorFitPolynomial1DOrd(poly, mask, maskValue, f64, fErr64, x64);
    681         if (!result) {
    682             psError(PS_ERR_UNKNOWN, false, "Could not fit polynomial.  Returning NULL.\n");
    683         }
     710      if ((f64->n < 10000)&&(poly->nX > 1)) {
     711        scale = true;
     712        sorted = psVectorSort(NULL,x64);
     713        median = sorted->data.F64[sorted->n / 2];
     714        // CZW: I'm not bothering to scale this because it doesn't really matter.
     715        sigma  = (sorted->data.F64[3 * sorted->n / 4] - sorted->data.F64[sorted->n / 4]);
     716        psFree(sorted);
     717        // I can't see a way to not clobber x if it's already F64, so make a copy.x
     718        z64 = psVectorCopy(NULL,x64,PS_TYPE_F64);
     719        psBinaryOp(z64,z64,"-",psScalarAlloc(median,PS_TYPE_F64));
     720        psBinaryOp(z64,z64,"/",psScalarAlloc(sigma,PS_TYPE_F64));
     721
     722#if (CZW)
     723        printf("poly1d: Scale parameters: %f %f\n",median,sigma);
     724#endif
     725
     726       
     727        result = VectorFitPolynomial1DOrd(poly, mask, maskValue, f64, fErr64, z64);
     728      }
     729      else {
     730        result = VectorFitPolynomial1DOrd(poly, mask, maskValue, f64, fErr64, x64);
     731      }
     732       
     733      if (!result) {
     734        psError(PS_ERR_UNKNOWN, false, "Could not fit polynomial.  Returning NULL.\n");
     735      }
     736     
     737      if (scale) {
     738        psFree(z64); // Done with this.
     739
     740        // Undo scaling in the polynomial values.
     741        psF64 *Zcoeff = psAlloc((1 + poly->nX) * sizeof(psF64 *));
     742        psF64 *ZcoeffErr = psAlloc((1 + poly->nX) * sizeof(psF64 *));
     743       
     744        for (psS32 i = 0; i <= poly->nX; i++) {
     745          Zcoeff[i] = poly->coeff[i];
     746          ZcoeffErr[i] = poly->coeffErr[i];
     747#if (CZW)
     748          printf("poly1d: fit parameters: %d %f %f\n",
     749                 i,poly->coeff[i],poly->coeffErr[i]);
     750#endif
     751        }
     752        for (psS32 i = 0; i <= poly->nX; i++) {
     753          poly->coeff[i] = 0.0;
     754          poly->coeffErr[i] = 0.0;
     755         
     756          for (psS32 j = 0; j <= poly->nX; j++) {
     757#if (CZW)
     758            printf("        %d %d %f %f %f %f => %f\n",
     759                   i,j,Zcoeff[j],pow(1.0 / sigma,j) * pow(-1,j - i),pow(median,j - i),1.0 * psBinomialCoeff(j,i),
     760                   Zcoeff[j] * pow(1.0 / sigma,j) * pow(-1,j  -i) * pow(median,j - i) * 1.0 * psBinomialCoeff(j,i)
     761                   );
     762#endif
     763            poly->coeff[i] += Zcoeff[j] * pow(1.0 / sigma,j) * pow(-1,j - i) * pow(median,j - i) * psBinomialCoeff(j,i);
     764            poly->coeffErr[i] += pow(ZcoeffErr[j] * pow(1.0 / sigma,j) * pow(-1,j - i) * pow(median,j - 1) * psBinomialCoeff(j,i),2);
     765          }
     766          poly->coeffErr[i] = sqrt(poly->coeffErr[i]);
     767#if (CZW)
     768          printf("poly1d: unscaled parameters: %d %f %f\n",
     769                 i,poly->coeff[i], poly->coeffErr[i]);
     770#endif
     771        }
     772      }
     773       
    684774        break;
    685775    case PS_POLYNOMIAL_CHEB:
Note: See TracChangeset for help on using the changeset viewer.