Yep, that sounds like the correct way to interpret it.
I've attempted a fix, now up on git repo.
Thanks again for flagging this
M
On Sat, Sep 12, 2015 at 08:18:31PM -0400, Matt Barber wrote:
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 -> http://lists.puredata.info/listinfo/pd-list
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management ->