Thanks again. Can you confirm that a range with onset greater than n-1 should be empty, and not a range with just the (n-1) item? I'm building some abstractions with these, and I want range behavior to be consistent with those in the [array] objects.
Thanks!
M
On Fri, Sep 11, 2015 at 7:50 PM, Miller Puckette msp@ucsd.edu wrote:
I think it's correct to output negative infinity as the maximum value of the empty set, since if A is a subset of B, max(A) <= max(B), so the max of the empty set should be less than any number. Hovever, using "1e30" for infinity is stupid and arbitrary - I do that sort of thing only because it's so poisonous in a real-time context when actual "inf" values start getting around the objects...
The second thing you brought up is a mistake. OTOH on revisiting this, I think the empty set should result in an output of (the impossible) -1 so that it can be easily checked for using select. Also using "firstitem" would give a bad result if used on an array of structs with more than one member - so a but more surgery is needed here...
more soon, off to a party to welcome the excellent Natacha Diels to our department :)
M
On Fri, Sep 11, 2015 at 04:14:47PM -0400, Matt Barber wrote:
Thanks for the fix in 0.46.7. There are a couple more subtle problems having to do with bounds checking (one of which may be there by design). Bounds checking occurs in the function array_rangeop_getrange() starting line 536:
firstitem = x->x_onset; if (firstitem < 0) firstitem = 0; else if (firstitem > a->a_n) firstitem = a->a_n; if (x->x_n < 0) nitem = a->a_n - firstitem; else { nitem = x->x_n; if (nitem + firstitem > a->a_n) nitem = a->a_n - firstitem; }
So unlike tabread which clips indices from 0 to n-1, this clips the onset from 0 to n, which means an onset greater than (n-1) gets a range with 0 items. I think this might be by design, but I wanted to check because a range with 0 items does something funny in the min/max array objects.
So first off, in these lines (starting line 746):
for (i = 0, besti = 0, bestf= -1e30, itemp = firstitem; i < nitem; i++, itemp += stride) if (*(t_float *)itemp > bestf) bestf = *(t_float *)itemp, besti = i;
If the input range has 0 items (i.e. if nitems is set to zero manually,
or
if the onset is greater than n-1), the for-loop condition i < nitem is never true, so the value output is going to be the bestf init value -1e30 (likewise with +1e30 in the min function). Since this a value that
doesn't
point to anything in the array, I wonder if it would be better not to output anything (or maybe a bang) in those cases.
Second, the value x->x_rangeop.x_onset is not bounds checked, so when you do this (line 750):
outlet_float(x->x_out2, besti + x->x_rangeop.x_onset);
if x_rangeop.x_onset iss out of range, you're going to output an
erroneous
index value, which could be negative or greater than n. firstitem is bounds-checked from the onset by array_rangeop_getrange() -- would it be possible to use that instead?
This suite is really a wonderful addition to Pd, and adds so much new functionality to vanilla. Many cheers!
Matt
On Fri, Sep 4, 2015 at 8:11 PM, Miller Puckette msp@ucsd.edu wrote:
Yep :)
M
On Fri, Sep 04, 2015 at 07:46:30PM -0400, Matt Barber wrote:
Thanks.
I meant to say that there was the same problem in [array min], but
you
probably caught it in your fix.
Best,
Matt
On Fri, Sep 4, 2015 at 7:19 PM, Miller Puckette msp@ucsd.edu
wrote:
Yep... thanks. Fixed in git - may take some time for me to get
out a
new
compiled version (other stuff to fix too :)
M
On Fri, Sep 04, 2015 at 05:51:15PM -0400, Matt Barber wrote:
Hi list,
I've been playing around with the new(ish) [array] object suite
in
vanilla
0.46.6. Forgive me if this is already a known issue, but it looks
like
the
min and max arguments aren't working properly.
The second inlet (setting the number of points to search) works
as
expected. The first inlet doesn't update: it seems to be set to
0 no
matter
what (although the index outlet is updated, but not as expected).
I think I see the problem in x_array.c
The max object is defined line 723:
typedef struct _array_max { t_array_rangeop x_rangeop; t_outlet *x_out1; /* value */ t_outlet *x_out2; /* index */ int x_onset; /* search onset */ } t_array_max;
And the bang and float methods starting 740:
static void array_max_bang(t_array_max *x) { char *itemp, *firstitem; int stride, nitem, i, besti; t_float bestf; if (!array_rangeop_getrange(&x->x_rangeop, &firstitem,
&nitem,
&stride))
return; for (i = 0, besti = 0, bestf= -1e30, itemp = firstitem; i < nitem; i++, itemp += stride) if (*(t_float *)itemp > bestf) bestf = *(t_float *)itemp, besti = i; outlet_float(x->x_out2, besti+x->x_onset); outlet_float(x->x_out1, bestf);
}
static void array_max_float(t_array_max *x, t_floatarg f) { x->x_onset = f; array_max_bang(x); }
In the float method it looks like the onset is never actually
assigned in
the x_rangeop member of the t_array_max struct, so
array_rangeop_getrange
can't set the firstitem pointer to anything but its init value.
Thanks,
Matt
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management ->
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management ->