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 ->
> > http://lists.puredata.info/listinfo/pd-list
> >
> >