View Raw SPL
/*****************************************************************************
* *
* XTOIDX.SPL Copyright (C) 2003-2010 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: Converts an x value to an index *
* *
* Revisions: 30 Jan 2003 RRR Creation *
* 19 Aug 2008 RRR optional limit argument *
* 2 Dec 2010 RRR return scalar for scalar input *
* *
*****************************************************************************/
#include
#if @HELP_XTOIDX
XTOIDX
Purpose: Converts X values of a series to index values.
Syntax: XTOIDX(series, x, limit)
series - input series
x - A real or series of reals. The x values
to convert to indices
limit - Optional integer, limit result to existing
indices range.
0: do not limit output
1: limit output to existing indices (default)
Returns: A real or series.
Example:
W1: 1..0.1..10
W2: xtoidx(W1, 1..0.1..1.5)
W2 contains the series {1, 2, 3, 4, 5}, the first 5
index values of W1.
Example:
W1: 1..0.1..10
W2: xtoidx(W1, 8..20)
W3: xtoidx(W1, 8..20, 0)
The values in W2 range from 71 to 91. Because some x values
correspond to a indices larger than the length of W1, the
result is limited to the length of W1. The resulting indices
in W3 are not limited to the indices of W1 and range
from 71 to 191.
Remarks:
For XY or XYZ series, the indices are looked up and the
closest matches are returned.
For interval series, the indices are computed as follows:
idx = 1 + int((x - xoffset(s)) / deltax(s) + 0.5);
If LIMIT is set to 0, XTOIDX can return index value outside
the range of the input series.
See Also:
Idx
Idxtox
Xvals
#endif
/* convert x value to index */
xtoidx(s, x, limit)
{
local idx, ptype, isnum;
if (argc < 3)
{
if (argc < 2)
{
if (argc < 1) error("xtoindex - input series and X value required");
/* assume sole input is x value */
x = s;
/* reference current series */
s = refseries();
}
limit = 1;
}
/* check if scalar */
isnum = isscalar(x);
if (isxy(s) || isxyz(s))
{
idx = xtoidx_lookup(s, x, limit);
}
else if (numcols(s) > 1)
{
ptype = getplottype(s);
if (itemtype(s) == 2 && ptype >= 1 && ptype <= 5)
{
/* waterfall, contour, density, Z surface, image */
idx = xtoidx_interval(s, x, limit);
}
else
{
/* multi-column series */
idx = xtoidx_interval_iterate(s, x, limit);
}
}
else
{
/* interval series */
idx = xtoidx_interval(s, x, limit);
}
/* convert back to scalar if necessary */
if (isnum)
{
idx = castint(idx);
}
return(idx);
}
/* xy or xyz series */
ITERATE xtoidx_lookup(s, x, limit)
{
local sz, leb, sx, gx, idx, start;
/* try to lookup indices */
sx = xvals(s);
len = length(s);
if (len < length(sx))
{
sx = extract(sx, 1, len);
}
/* get indices of sorted x values */
(sx, gx) = sort(sx, 1);
/* lookup indices from sorted xvalues */
idx = round(yvals({xylookup(sx, 1..len, x, "linear", 1)}));
/* start index - usually 1 */
start = castint(getconf("SPL_START_INDEX"));
/* limit to gx size */
idx = clip({idx}, start, length(gx));
/* convert to original indices */
idx = gx[idx];
if (limit)
{
/* clip out of range values */
idx = clip({idx}, start, length(s));
}
return(idx);
}
/* interval series */
xtoidx_interval(s, x, limit)
{
local start, scale, idx;
/* start index - usually 1 */
start = castint(getconf("SPL_START_INDEX"));
/* unit scale factor (mS, MHz, etc.) */
scale = gethunitsscale(s);
/* interval series - use direct computation */
idx = int(((x - xoffset(s)) * scale) / deltax(s) + 0.5) + start;
if (limit)
{
/* clip out of range values */
idx = clip({idx}, start, length(s));
}
return(idx);
}
/* multi-column interval series */
ITERATE xtoidx_interval_iterate(s, x, limit)
{
local idx;
idx = xtoidx_interval(s, x, limit);
return(idx);
}