IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 42492


Ignore:
Timestamp:
Aug 15, 2023, 4:56:54 AM (3 years ago)
Author:
eugene
Message:

adding psPolynomial1DCopy, psPolynomial1DRecycle; working on the polynomial IRLS fitting

Location:
branches/eam_branches/ipp-20230313/psLib/src/math
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20230313/psLib/src/math/psMinimizePolyFit.c

    r42491 r42492  
    4848/* DEFINE STATEMENTS                                                         */
    4949/*****************************************************************************/
    50 #define CZW 0
     50#define CZW 1
    5151
    5252# define USE_GAUSS_JORDAN 1
     
    10301030}
    10311031
     1032// This function assumes the input vectors (f, fEval, fErr) all have the same type
     1033// This requirement is already enforced in the calling function (psVectorIRLSFitPolynomial1D)
     1034psVector *psVector_GetModifiedErrors_Caucy (
     1035    const psVector *f,
     1036    const psVector *fEval,
     1037    const psVector *fErr,
     1038    const psVector *mask,
     1039    psVectorMaskType maskValue) {
     1040
     1041  psVector *mErr = psVectorAlloc (f->n, f->type.type);
     1042
     1043  switch (f->type.type) {
     1044    case PS_TYPE_F64:
     1045      {
     1046          psF64 *fPtr     = f->data.F64;
     1047          psF64 *fErrPtr  = fErr->data.F64;
     1048          psF64 *mErrPtr  = mErr->data.F64;
     1049          psF64 *fEvalPtr = fEval->data.F64;
     1050          for (int i = 0; i < f->n; i++, fPtr++, fEvalPtr++, fErrPtr++, mErrPtr++) {
     1051              if (mask && (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValue)) continue;
     1052              double dF = (*fPtr - *fEvalPtr) / 2.385;
     1053              double dV = PS_SQR(*fErrPtr) + PS_SQR(dF);
     1054              *mErrPtr = sqrt(dV);
     1055          }
     1056      }
     1057      break;
     1058    case PS_TYPE_F32:
     1059      {
     1060          psF32 *fPtr     = f->data.F32;
     1061          psF32 *fErrPtr  = fErr->data.F32;
     1062          psF32 *mErrPtr  = mErr->data.F32;
     1063          psF32 *fEvalPtr = fEval->data.F32;
     1064          for (int i = 0; i < f->n; i++, fPtr++, fEvalPtr++, fErrPtr++, mErrPtr++) {
     1065              if (mask && (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValue)) continue;
     1066              double dF = (*fPtr - *fEvalPtr) / 2.385;
     1067              double dV = PS_SQR(*fErrPtr) + PS_SQR(dF);
     1068              *mErrPtr = sqrt(dV);
     1069          }
     1070      }
     1071      break;
     1072    default:
     1073        psError(PS_ERR_UNKNOWN, false, "invalid input data type.\n");
     1074        return NULL;
     1075  }
     1076  return mErr;
     1077}
     1078
    10321079// These should probably be tunable:
    10331080# define FIT_TOLERANCE 1e-4
     
    10361083
    10371084// This function accepts F32 and F64 input vectors.
     1085  //
    10381086bool psVectorIRLSFitPolynomial1D(
    10391087    psPolynomial1D *poly,
     1088    psStats *stats,
    10401089    const psVector *mask,
    10411090    psVectorMaskType maskValue,
     
    10781127    }
    10791128
    1080     // IRLS fitting is performed by adjusting the total weights for each point based on
    1081     // the distance of the value from the last fit.  start with weights set to 1.0 (the
    1082     // max) and adjust as needed.
    1083 
    1084     psVector *weights = psVectorAlloc(f->n, PS_TYPE_F64);
    1085     psVectorInit (weights, 1.0);
    1086 
    1087     // initial fit with weights set to 1.0
     1129    // initial fit with nominal errors
    10881130    if (!psVectorFitPolynomial1D(poly, mask, maskValue, f, fErr, x)) {
    10891131        psError(PS_ERR_UNKNOWN, false, "Could not fit polynomial.  Returning false.\n");
    10901132        if (xIn == NULL) psFree(x);
    1091         psFree (weights);
    10921133        return false;
    10931134    }
    10941135
    1095     psVector *fEval = psPolynomial1DEvalVector (poly, x);
    1096 
    1097     for (psS32 N = 0; N < stats->clipIter; N++) {
     1136    // use polyOld to save the last fit
     1137    psPolynomial1D *polyOld = NULL;
     1138
     1139    // use clipIter as max number of iterations
     1140    bool converged = false;
     1141    for (psS32 N = 0; !converged && (N < stats->clipIter); N++) {
    10981142        psTrace("psLib.math", 6, "Loop iteration %d.  Calling psVectorFitPolynomial1D()\n", N);
    1099         psS32 Nkeep = 0;
    1100         if (psTraceGetLevel("psLib.math") >= 6) {
    1101             if (mask != NULL) {
    1102                 for (psS32 i = 0 ; i < mask->n ; i++) {
    1103                     psTrace("psLib.math", 6,  "mask[%d] is %d\n", i, mask->data.PS_TYPE_VECTOR_MASK_DATA[i]);
    1104                 }
    1105             }
    1106         }
    1107         if (!psVectorFitPolynomial1D(poly, mask, maskValue, f, fErr, x)) {
     1143
     1144        // evaluate the fit at the input positions
     1145        psVector *fEval = psPolynomial1DEvalVector (poly, x);
     1146
     1147        // calculate modified errors based on the deviation from the fit
     1148        psVector *modErr = psVector_GetModifiedErrors_Caucy (f, fEval, fErr, mask, maskValue);
     1149        psFree (fEval);
     1150
     1151        // save the last fit (recycle the structure once allocated)
     1152        polyOld = psPolynomial1DCopy (polyOld, poly);
     1153
     1154        // calculate a new fit with modified errors:
     1155        if (!psVectorFitPolynomial1D(poly, mask, maskValue, f, modErr, x)) {
    11081156            psError(PS_ERR_UNKNOWN, false, "Could not fit polynomial.  Returning false.\n");
    1109             if (xIn == NULL) {
    1110                 psFree(x);
    1111             }
    1112             psFree(resid);
    1113            
     1157            if (xIn == NULL) psFree(x);
     1158            psFree(modErr);
    11141159            return false;
    11151160        }
    11161161
    1117         psVector *fit = psPolynomial1DEvalVector(poly, x);
    1118         if (fit == NULL) {
    1119             psError(PS_ERR_UNKNOWN, false, "Could not call psPolynomial3DEvalVector().  Returning false.\n");
    1120             if (xIn == NULL) {
    1121                 psFree(x);
    1122             }
    1123             psFree(resid);
    1124             return false;
    1125         }
    1126         for (psS32 i = 0 ; i < f->n ; i++) {
    1127             if (f->type.type == PS_TYPE_F64) {
    1128                 resid->data.F64[i] = f->data.F64[i] - fit->data.F64[i];
    1129             } else {
    1130                 resid->data.F64[i] = (psF64) (f->data.F32[i] - fit->data.F32[i]);
    1131             }
    1132         }
    1133         if (psTraceGetLevel("psLib.math") >= 6) {
    1134             if (mask != NULL) {
    1135                 for (psS32 i = 0 ; i < mask->n ; i++) {
    1136                     if (!((mask != NULL) && (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValue))) {
    1137                         psTrace("psLib.math", 6,  "(f, fit)[%d] is (%f, %f).  resid is (%f)\n",
    1138                                 i, f->data.F32[i], fit->data.F32[i], resid->data.F64[i]);
    1139                     }
    1140                 }
    1141             }
    1142         }
    1143 
    1144         if (!psVectorStats(stats, resid, NULL, mask, maskValue)) {
    1145             psError(PS_ERR_UNKNOWN, false, "Could not compute statistics on the resid vector.  Returning false.\n");
    1146             psFree(resid);
    1147             psFree(fit);
    1148             return false;
    1149         }
    1150 
    1151         double meanValue = psStatsGetValue (stats, meanOption);
    1152         double stdevValue = psStatsGetValue (stats, stdevOption);
    1153 
    1154         psTrace("psLib.math", 5, "Mean is %f\n", meanValue);
    1155         psTrace("psLib.math", 5, "Stdev is %f\n", stdevValue);
    1156         psF32 minClipValue = -minClipSigma*stdevValue;
    1157         psF32 maxClipValue = +maxClipSigma*stdevValue;
    1158 
    1159         // set mask if pts are not valid
    1160         // we are masking out any point which is out of range
    1161         // recovery is not allowed with this scheme
    1162         for (psS32 i = 0; i < resid->n; i++) {
    1163             if ((mask != NULL) && (mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & maskValue)) {
    1164                 continue;
    1165             }
    1166 
    1167             if ((resid->data.F64[i] - meanValue > maxClipValue) || (resid->data.F64[i] - meanValue < minClipValue)) {
    1168                 if (f->type.type == PS_TYPE_F64) {
    1169                     psTrace("psLib.math", 6, "Masking element %d (%f).  resid->data.F64[%d] is %f\n",
    1170                             i, fit->data.F64[i], i, resid->data.F64[i]);
    1171                 } else {
    1172                     psTrace("psLib.math", 6, "Masking element %d (%f).  resid->data.F64[%d] is %f\n",
    1173                             i, fit->data.F32[i], i, resid->data.F64[i]);
    1174                 }
    1175 
    1176                 if (mask != NULL) {
    1177                     mask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= 0x01;
    1178                 }
    1179                 continue;
    1180             }
    1181             Nkeep++;
    1182         }
    1183 
    1184         //
    1185         // We should probably exit this loop if no new elements were masked
    1186         // since the polynomial fit won't change.
    1187         //
    1188         psTrace("psLib.math", 6, "keeping %d of %ld pts for fit\n", Nkeep, x->n);
    1189         stats->clippedNvalues = Nkeep;
    1190         psFree(fit);
    1191     }
    1192 
    1193     // Free psVectors that were created for NULL arguments.
    1194     if (xIn == NULL) {
    1195         psFree(x);
    1196     }
    1197     // Free other local temporary variables
    1198     psFree(resid);
     1162        // has the solution converged?
     1163        converged = true;
     1164        for (int ix = 0; ix <= poly->nX; ix++) {
     1165          if ((fabs(poly->coeff[ix] - polyOld->coeff[ix]) > FIT_TOLERANCE * fabs(poly->coeff[ix])) &&
     1166              (fabs(poly->coeff[ix] - polyOld->coeff[ix]) > FLT_TOLERANCE))
     1167            converged = false;
     1168        }
     1169
     1170        psFree (modErr);
     1171    }
     1172
     1173    // Free local temporary variables
     1174    if (xIn == NULL) psFree(x);
     1175    psFree(polyOld);
    11991176
    12001177    psTrace("psLib.math", 3, "---- %s() end ----\n", __func__);
  • branches/eam_branches/ipp-20230313/psLib/src/math/psMinimizePolyFit.h

    r21183 r42492  
    134134);
    135135
     136bool psVectorIRLSFitPolynomial1D(
     137    psPolynomial1D *poly,
     138    psStats *stats,
     139    const psVector *mask,
     140    psVectorMaskType maskValue,
     141    const psVector *f,
     142    const psVector *fErr,
     143    const psVector *x
     144);
     145
    136146/// @}
    137147#endif // #ifndef PS_MINIMIZE_POLYFIT_H
  • branches/eam_branches/ipp-20230313/psLib/src/math/psPolynomial.c

    r41896 r42492  
    806806}
    807807
    808 // XXX add 1D, 3D, 4D versions
    809 bool psPolynomial2DRecycle(psPolynomial2D *poly,
    810                            psPolynomialType type,
    811                            unsigned int nX,
    812                            unsigned int nY)
    813 {
    814     PS_ASSERT_INT_NONNEGATIVE(nX, NULL);
    815     PS_ASSERT_INT_NONNEGATIVE(nY, NULL);
    816 
    817     bool match = true;
    818     match &= (poly->type == type);
    819     match &= (poly->nX == type);
    820     match &= (poly->nY == type);
    821 
    822     if (!match) {
    823         for (int i = 0; i < poly->nX + 1; i++) {
    824             psFree (poly->coeff[i]);
    825             psFree (poly->coeffErr[i]);
    826             psFree (poly->coeffMask[i]);
    827         }
    828         psFree (poly->coeff);
    829         psFree (poly->coeffErr);
    830         psFree (poly->coeffMask);
    831 
    832         poly->type = type;
    833         poly->nX = nX;
    834         poly->nY = nY;
    835 
    836         poly->coeff = psAlloc((1 + nX) * sizeof(psF64 *));
    837         poly->coeffErr = psAlloc((1 + nX) * sizeof(psF64 *));
    838         poly->coeffMask = (psMaskType **)psAlloc((1 + nX) * sizeof(psMaskType *));
    839         for (int i = 0; i < (1 + nX); i++) {
    840             poly->coeff[i] = psAlloc((1 + nY) * sizeof(psF64));
    841             poly->coeffErr[i] = psAlloc((1 + nY) * sizeof(psF64));
    842             poly->coeffMask[i] = (psMaskType *)psAlloc((1 + nY) * sizeof(psMaskType));
    843         }
    844     }
    845     for (int i = 0; i < (1 + nX); i++) {
    846         for (int j = 0; j < (1 + nY); j++) {
    847             poly->coeff[i][j] = 0.0;
    848             poly->coeffErr[i][j] = 0.0;
    849             poly->coeffMask[i][j] = PS_POLY_MASK_NONE;
    850         }
    851     }
    852     return(true);
    853 }
    854 
    855 // XXX add 1D, 3D, 4D versions
    856 psPolynomial2D *psPolynomial2DCopy(psPolynomial2D *out,
    857                                    psPolynomial2D *poly)
    858 {
    859     if (out == NULL) {
    860         out = psPolynomial2DAlloc (poly->type, poly->nX, poly->nY);
    861     } else {
    862         psPolynomial2DRecycle (out, poly->type, poly->nX, poly->nY);
    863     }
    864 
    865     for (int i = 0; i < (1 + poly->nX); i++) {
    866         for (int j = 0; j < (1 + poly->nY); j++) {
    867             out->coeff[i][j] = poly->coeff[i][j];
    868             out->coeffErr[i][j] = poly->coeffErr[i][j];
    869             out->coeffMask[i][j] = poly->coeffMask[i][j];
    870         }
    871     }
    872     return(out);
    873 }
    874 
    875808psPolynomial3D* psPolynomial3DAlloc(
    876809    psPolynomialType type,
     
    1002935}
    1003936
     937// XXX add 3D, 4D versions
     938bool psPolynomial1DRecycle(psPolynomial1D *poly,
     939                           psPolynomialType type,
     940                           unsigned int nX)
     941{
     942    PS_ASSERT_INT_NONNEGATIVE(nX, NULL);
     943
     944    bool match = true;
     945    match &= (poly->type == type);
     946    match &= (poly->nX == type);
     947
     948    if (!match) {
     949        psFree (poly->coeff);
     950        psFree (poly->coeffErr);
     951        psFree (poly->coeffMask);
     952
     953        poly->type = type;
     954        poly->nX = nX;
     955
     956        poly->coeff = psAlloc((1 + nX) * sizeof(psF64));
     957        poly->coeffErr = psAlloc((1 + nX) * sizeof(psF64));
     958        poly->coeffMask = (psMaskType *)psAlloc((1 + nX) * sizeof(psMaskType));
     959    }
     960    for (int i = 0; i < (1 + nX); i++) {
     961        poly->coeff[i] = 0.0;
     962        poly->coeffErr[i] = 0.0;
     963        poly->coeffMask[i] = PS_POLY_MASK_NONE;
     964    }
     965    return(true);
     966}
     967
     968bool psPolynomial2DRecycle(psPolynomial2D *poly,
     969                           psPolynomialType type,
     970                           unsigned int nX,
     971                           unsigned int nY)
     972{
     973    PS_ASSERT_INT_NONNEGATIVE(nX, NULL);
     974    PS_ASSERT_INT_NONNEGATIVE(nY, NULL);
     975
     976    bool match = true;
     977    match &= (poly->type == type);
     978    match &= (poly->nX == type);
     979    match &= (poly->nY == type);
     980
     981    if (!match) {
     982        for (int i = 0; i < poly->nX + 1; i++) {
     983            psFree (poly->coeff[i]);
     984            psFree (poly->coeffErr[i]);
     985            psFree (poly->coeffMask[i]);
     986        }
     987        psFree (poly->coeff);
     988        psFree (poly->coeffErr);
     989        psFree (poly->coeffMask);
     990
     991        poly->type = type;
     992        poly->nX = nX;
     993        poly->nY = nY;
     994
     995        poly->coeff = psAlloc((1 + nX) * sizeof(psF64 *));
     996        poly->coeffErr = psAlloc((1 + nX) * sizeof(psF64 *));
     997        poly->coeffMask = (psMaskType **)psAlloc((1 + nX) * sizeof(psMaskType *));
     998        for (int i = 0; i < (1 + nX); i++) {
     999            poly->coeff[i] = psAlloc((1 + nY) * sizeof(psF64));
     1000            poly->coeffErr[i] = psAlloc((1 + nY) * sizeof(psF64));
     1001            poly->coeffMask[i] = (psMaskType *)psAlloc((1 + nY) * sizeof(psMaskType));
     1002        }
     1003    }
     1004    for (int i = 0; i < (1 + nX); i++) {
     1005        for (int j = 0; j < (1 + nY); j++) {
     1006            poly->coeff[i][j] = 0.0;
     1007            poly->coeffErr[i][j] = 0.0;
     1008            poly->coeffMask[i][j] = PS_POLY_MASK_NONE;
     1009        }
     1010    }
     1011    return(true);
     1012}
     1013
     1014// XXX 3D, 4D versions
     1015psPolynomial1D *psPolynomial1DCopy(psPolynomial1D *out,
     1016                                   psPolynomial1D *poly)
     1017{
     1018    if (out == NULL) {
     1019        out = psPolynomial1DAlloc (poly->type, poly->nX);
     1020    } else {
     1021        psPolynomial1DRecycle (out, poly->type, poly->nX);
     1022    }
     1023
     1024    for (int i = 0; i < (1 + poly->nX); i++) {
     1025        out->coeff[i] = poly->coeff[i];
     1026        out->coeffErr[i] = poly->coeffErr[i];
     1027        out->coeffMask[i] = poly->coeffMask[i];
     1028    }
     1029    return(out);
     1030}
     1031psPolynomial2D *psPolynomial2DCopy(psPolynomial2D *out,
     1032                                   psPolynomial2D *poly)
     1033{
     1034    if (out == NULL) {
     1035        out = psPolynomial2DAlloc (poly->type, poly->nX, poly->nY);
     1036    } else {
     1037        psPolynomial2DRecycle (out, poly->type, poly->nX, poly->nY);
     1038    }
     1039
     1040    for (int i = 0; i < (1 + poly->nX); i++) {
     1041        for (int j = 0; j < (1 + poly->nY); j++) {
     1042            out->coeff[i][j] = poly->coeff[i][j];
     1043            out->coeffErr[i][j] = poly->coeffErr[i][j];
     1044            out->coeffMask[i][j] = poly->coeffMask[i][j];
     1045        }
     1046    }
     1047    return(out);
     1048}
     1049
    10041050/* note these functions accept unscaled values and apply the scaling saved on poly */
    10051051psF64 psPolynomial1DEval(const psPolynomial1D* poly,
  • branches/eam_branches/ipp-20230313/psLib/src/math/psPolynomial.h

    r42336 r42492  
    161161) PS_ATTR_MALLOC;
    162162
     163bool psPolynomial1DRecycle(psPolynomial1D *poly,
     164                           psPolynomialType type,
     165                           unsigned int nX);
     166
    163167bool psPolynomial2DRecycle(psPolynomial2D *poly,
    164168                           psPolynomialType type,
    165169                           unsigned int nX,
    166170                           unsigned int nY);
     171
     172psPolynomial1D *psPolynomial1DCopy(psPolynomial1D *out,
     173                                   psPolynomial1D *poly);
    167174
    168175psPolynomial2D *psPolynomial2DCopy(psPolynomial2D *out,
Note: See TracChangeset for help on using the changeset viewer.