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 <m...@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 <m...@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 <m...@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 -> > > > > http://lists.puredata.info/listinfo/pd-list > > > > > > > > > > _______________________________________________ Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list