View Raw SPL
/*****************************************************************************
*                                                                            *
*   YTOIDX.SPL  Copyright (C) 2010 DSP Development Corporation               *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Randy Race                                                  *
*                                                                            *
*   Synopsis:    Converts a Y value to an index                              *
*                                                                            *
*   Revisions:   10 Jan 2010  RRR  Creation                                  *
*                                                                            *
*****************************************************************************/


#if @HELP_YTOIDX

    YTOIDX

    Purpose: Converts Y values of a series to index values.

    Syntax:  YTOIDX(series, y)

             series    - input series

                  y    - A real or series of reals. The y values
                         to convert to indices

    Returns: An integer or series of integers.

    Example:
             W1: 1..0.1..10
             W2: ytoidx(W1, 1..0.1..1.5)

             W2 contains the series {1, 2, 3, 4, 5, 6}, the first 6
             index values of W1.

    Example:
             W1: 1..0.1..10
             W2: ytoidx(W1, 5..10)
             W3: W1[W2]

             W1 contains a series with values from 1 to 10 with a step size
             of 0.1.

             W2 returns the indices of W1 that correspond to the Y values
             {5, 6, 7, 8, 9, 10}.

             W3 uses the indices in W2 to return the corresponding Y values.
             The result is also equal to {5, 6, 7, 8, 9, 10}.

    Remarks:
             The indices are looked up and the closest matches are linearly
             interpolated for accuracy.

    See Also:
             Idx
             Idxtox
             Xtoidx
             Xvals

#endif


/* convert y value to index */
ytoidx(s, y, limit)
{
        local idx, gy, sy, len, start, isnum;

        if (argc < 3)
        {
                if (argc < 2)
                {
                        if (argc < 1) error(sprintf("%s - input series and Y value required", __FUNC__));

                        /* assume sole input is y value */
                        y = s;

                        /* reference current series */
                        s = refseries();
                }
                
                limit = 1;
        }

        /* check if scalar */
        isnum = isscalar(y);

        if (numcols(s) > 1)
        {
                ptype = getplottype(s);

                if (itemtype(s) == 2 && ptype >= 1 && ptype <= 5)
                {
                        /* waterfall, contour, density, Z surface, image */
                        idx = ytoidx_interval(s, y, limit);
                }
                else
                {
                        /* multi-column series */
                        idx = ytoidx_lookup_iterate(s, y, limit);
                }
        }
        else
        {
                /* interval series, XY or XYZ */
                idx = ytoidx_lookup(s, y, limit);
        }

        /* convert back to scalar if necessary */
        if (isnum)
        {
                idx = castint(idx);
        }

        return(idx);
}


/* lookup Y indices */
ytoidx_lookup(s, y, limit)
{
        local sy, len, gy, idx, start;

        sy  = yvals(s);
        len = length(s);

        if (len < length(sy))
        {
                sy = extract(sy, 1, len);
        }

        /* get indices of sorted y values */
        (sy, gy) = sort(sy, 1);

        /* lookup indices from sorted y values - constrained */
        idx = int(yvals({xylookup(sy, 1..len, y, "linear", 1)}) + 0.5);

        /* map into actual indices */
        idx = gy[idx];

        return(idx);
}


/* multi-column lookup */
ITERATE ytoidx_lookup_iterate(s, y, limit)
{
        local idx;

        idx = ytoidx_lookup(s, y, limit);

        return(idx);
}


/* use deltay */
ytoidx_interval(s, y, limit)
{
        local start, idx;

        /* start index - usually 1 */
        start = castint(getconf("SPL_START_INDEX"));

        /* interval series - use direct computation */
        idx = start + int((y - yoffset(s)) / deltay(s) + 0.5);

        if (limit)
        {
                /* clip out of range values */
                idx = clip({idx}, start, numcols(s));
        }

        return(idx);
}