src/numafunc1.c
l_int32
numaFitMax(NUMA       *na,
           l_float32  *pmaxval,
           NUMA       *naloc,
           l_float32  *pmaxloc)
{
l_float32  val;
l_float32  smaxval;  /* start value of maximum sample, before interpolating */
l_int32    n, imaxloc;
l_float32  x1, x2, x3, y1, y2, y3, c1, c2, c3, a, b, xmax, ymax;

    PROCNAME("numaFitMax");

    *pmaxval = *pmaxloc = 0.0;  /* init */

    if (!na)
        return ERROR_INT("na not defined", procName, 1);
    if (!pmaxval)
        return ERROR_INT("&maxval not defined", procName, 1);
    if (!pmaxloc)
        return ERROR_INT("&maxloc not defined", procName, 1);

    n = numaGetCount(na);
    if (naloc) {
        if (n != numaGetCount(naloc))
            return ERROR_INT("na and naloc of unequal size", procName, 1);
    }

    numaGetMax(na, &smaxval, &imaxloc);

        /* Simple case: max is at end point */
    if (imaxloc == 0 || imaxloc == n - 1) {
        *pmaxval = smaxval;
        if (naloc) {
            numaGetFValue(naloc, imaxloc, &val);
            *pmaxloc = val;
        }
        else
            *pmaxloc = imaxloc;
        return 0;
    }

        /* Interior point; use quadratic interpolation */
    y2 = smaxval;
    numaGetFValue(na, imaxloc - 1, &val);
    y1 = val;
    numaGetFValue(na, imaxloc + 1, &val);
    y3 = val;
    if (naloc) {
        numaGetFValue(naloc, imaxloc - 1, &val);
        x1 = val;
        numaGetFValue(naloc, imaxloc, &val);
        x2 = val;
        numaGetFValue(naloc, imaxloc + 1, &val);
        x3 = val;
    }
    else {
        x1 = imaxloc - 1;
        x2 = imaxloc;
        x3 = imaxloc + 1;
    }

        /* Can't interpolate; just use the max val in na
         * and the corresponding one in naloc */
    if (x1 == x2 || x1 == x3 || x2 == x3) {
        *pmaxval = y2;
        *pmaxloc = x2;
        return 0;
    }

        /* Use lagrangian interpolation; set dy/dx = 0 */
    c1 = y1 / ((x1 - x2) * (x1 - x3));
    c2 = y2 / ((x2 - x1) * (x2 - x3));
    c3 = y3 / ((x3 - x1) * (x3 - x2));
    a = c1 + c2 + c3;
    b = c1 * (x2 + x3) + c2 * (x1 + x3) + c3 * (x1 + x2);
    xmax = b / (2 * a);
    ymax = c1 * (xmax - x2) * (xmax - x3) +
           c2 * (xmax - x1) * (xmax - x3) +
           c3 * (xmax - x1) * (xmax - x2);
    *pmaxval = ymax;
    *pmaxloc = xmax;

    return 0;
}
/*!
 *  numaFitMax()
 *
 *      Input:  na  (numa of ordinate values, to fit a max to)
 *              &maxval (<return> max value)
 *              naloc (<optional> associated numa of abscissa values)
 *              &maxloc (<return> abscissa value that gives max value in na;
 *                   if naloc == null, this is given as an interpolated
 *                   index value)
 *      Return: 0 if OK; 1 on error
 *
 *  Note: if naloc is given, there is no requirement that the
 *        data points are evenly spaced.  Lagrangian interpolation
 *        handles that.  The only requirement is that the
 *        data points are ordered so that the values in naloc
 *        are either increasing or decreasing.  We test to make
 *        sure that the sizes of na and naloc are equal, and it
 *        is assumed that the correspondences na[i] as a function
 *        of naloc[i] are properly arranged for all i.
 *
 *  The formula for Lagrangian interpolation through 3 data pts is:
 *       y(x) = y1(x-x2)(x-x3)/((x1-x2)(x1-x3)) +
 *              y2(x-x1)(x-x3)/((x2-x1)(x2-x3)) +
 *              y3(x-x1)(x-x2)/((x3-x1)(x3-x2))
 *
 *  Then the derivative, using the constants (c1,c2,c3) defined below,
 *  is set to 0:
 *       y'(x) = 2x(c1+c2+c3) - c1(x2+x3) - c2(x1+x3) - c3(x1+x2) = 0
 */
numaFitMax()
Input:  na  (numa of ordinate values, to fit a max to)
&maxval ( max value)
naloc ( associated numa of abscissa values)
&maxloc ( abscissa value that gives max value in na;
if naloc == null, this is given as an interpolated
index value)
Return: 0 if OK; 1 on error

if naloc is given, there is no requirement that the
data points are evenly spaced.  Lagrangian interpolation
handles that.  The only requirement is that the
data points are ordered so that the values in naloc
are either increasing or decreasing.  We test to make
sure that the sizes of na and naloc are equal, and it
is assumed that the correspondences na[i] as a function
of naloc[i] are properly arranged for all i.




numaFitMax () Input : na ( numa of ordinate values to fit a max to ) &maxval ( max value ) naloc ( associated numa of abscissa values ) &maxloc ( abscissa value that gives max value in na ; if naloc == null this is given as an interpolated index value ) Return : 0 if OK ; 1 on error if naloc is given there is no requirement that the data points are evenly spaced . Lagrangian interpolation handles that . The only requirement is that the data points are ordered so that the values in naloc are either increasing or decreasing . We test to make sure that the sizes of na and naloc are equal and it is assumed that the correspondences na [ i ] as a function of naloc [ i ] are properly arranged for all i .
l_int32
numaFitMax(NUMA       *na,
           l_float32  *pmaxval,
           NUMA       *naloc,
           l_float32  *pmaxloc)
{
l_float32  val;
l_float32  smaxval;  
l_int32    n, imaxloc;
l_float32  x1, x2, x3, y1, y2, y3, c1, c2, c3, a, b, xmax, ymax;
    PROCNAME("numaFitMax");
    *pmaxval = *pmaxloc = 0.0;  
    if (!na)
        return ERROR_INT("na not defined", procName, 1);
    if (!pmaxval)
        return ERROR_INT("&maxval not defined", procName, 1);
    if (!pmaxloc)
        return ERROR_INT("&maxloc not defined", procName, 1);
    n = numaGetCount(na);
    if (naloc) {
        if (n != numaGetCount(naloc))
            return ERROR_INT("na and naloc of unequal size", procName, 1);
    }
    numaGetMax(na, &smaxval, &imaxloc);
    if (imaxloc == 0 || imaxloc == n - 1) {
        *pmaxval = smaxval;
        if (naloc) {
            numaGetFValue(naloc, imaxloc, &val);
            *pmaxloc = val;
        }
        else
            *pmaxloc = imaxloc;
        return 0;
    }
    y2 = smaxval;
    numaGetFValue(na, imaxloc - 1, &val);
    y1 = val;
    numaGetFValue(na, imaxloc + 1, &val);
    y3 = val;
    if (naloc) {
        numaGetFValue(naloc, imaxloc - 1, &val);
        x1 = val;
        numaGetFValue(naloc, imaxloc, &val);
        x2 = val;
        numaGetFValue(naloc, imaxloc + 1, &val);
        x3 = val;
    }
    else {
        x1 = imaxloc - 1;
        x2 = imaxloc;
        x3 = imaxloc + 1;
    }
    if (x1 == x2 || x1 == x3 || x2 == x3) {
        *pmaxval = y2;
        *pmaxloc = x2;
        return 0;
    }
    c1 = y1 / ((x1 - x2) * (x1 - x3));
    c2 = y2 / ((x2 - x1) * (x2 - x3));
    c3 = y3 / ((x3 - x1) * (x3 - x2));
    a = c1 + c2 + c3;
    b = c1 * (x2 + x3) + c2 * (x1 + x3) + c3 * (x1 + x2);
    xmax = b / (2 * a);
    ymax = c1 * (xmax - x2) * (xmax - x3) +
           c2 * (xmax - x1) * (xmax - x3) +
           c3 * (xmax - x1) * (xmax - x2);
    *pmaxval = ymax;
    *pmaxloc = xmax;
    return 0;
}
l_int32 numaFitMax ( NUMA * na , l_float32 * pmaxval , NUMA * naloc , l_float32 * pmaxloc ) { l_float32 val ; l_float32 smaxval ; l_int32 n , imaxloc ; l_float32 x1 , x2 , x3 , y1 , y2 , y3 , c1 , c2 , c3 , a , b , xmax , ymax ; PROCNAME ( " " ) ; * pmaxval = * pmaxloc = 0.0 ; if ( ! na ) return ERROR_INT ( " " , procName , 1 ) ; if ( ! pmaxval ) return ERROR_INT ( " " , procName , 1 ) ; if ( ! pmaxloc ) return ERROR_INT ( " " , procName , 1 ) ; n = numaGetCount ( na ) ; if ( naloc ) { if ( n != numaGetCount ( naloc ) ) return ERROR_INT ( " " , procName , 1 ) ; } numaGetMax ( na , & smaxval , & imaxloc ) ; if ( imaxloc == 0 || imaxloc == n - 1 ) { * pmaxval = smaxval ; if ( naloc ) { numaGetFValue ( naloc , imaxloc , & val ) ; * pmaxloc = val ; } else * pmaxloc = imaxloc ; return 0 ; } y2 = smaxval ; numaGetFValue ( na , imaxloc - 1 , & val ) ; y1 = val ; numaGetFValue ( na , imaxloc + 1 , & val ) ; y3 = val ; if ( naloc ) { numaGetFValue ( naloc , imaxloc - 1 , & val ) ; x1 = val ; numaGetFValue ( naloc , imaxloc , & val ) ; x2 = val ; numaGetFValue ( naloc , imaxloc + 1 , & val ) ; x3 = val ; } else { x1 = imaxloc - 1 ; x2 = imaxloc ; x3 = imaxloc + 1 ; } if ( x1 == x2 || x1 == x3 || x2 == x3 ) { * pmaxval = y2 ; * pmaxloc = x2 ; return 0 ; } c1 = y1 / ( ( x1 - x2 ) * ( x1 - x3 ) ) ; c2 = y2 / ( ( x2 - x1 ) * ( x2 - x3 ) ) ; c3 = y3 / ( ( x3 - x1 ) * ( x3 - x2 ) ) ; a = c1 + c2 + c3 ; b = c1 * ( x2 + x3 ) + c2 * ( x1 + x3 ) + c3 * ( x1 + x2 ) ; xmax = b / ( 2 * a ) ; ymax = c1 * ( xmax - x2 ) * ( xmax - x3 ) + c2 * ( xmax - x1 ) * ( xmax - x3 ) + c3 * ( xmax - x1 ) * ( xmax - x2 ) ; * pmaxval = ymax ; * pmaxloc = xmax ; return 0 ; }
numaFitMax()
      Input:  na  (numa of ordinate values, to fit a max to)
              &maxval (<return> max value)
              naloc (<optional> associated numa of abscissa values)
              &maxloc (<return> abscissa value that gives max value in na;
                   if naloc == null, this is given as an interpolated
                   index value)
      Return: 0 if OK; 1 on error
numaFitMax () Input : na ( numa of ordinate values to fit a max to ) &maxval ( <return > max value ) naloc ( <optional > associated numa of abscissa values ) &maxloc ( <return > abscissa value that gives max value in na ; if naloc == null this is given as an interpolated index value ) Return : 0 if OK ; 1 on error
/* start value of maximum sample, before interpolating */ /* init */ /* Simple case: max is at end point */ /* Interior point; use quadratic interpolation */ /* Can't interpolate; just use the max val in na
         * and the corresponding one in naloc */ /* Use lagrangian interpolation; set dy/dx = 0 */