[PD] match the closest number

danja binary.koala at gmail.com
Mon Jun 18 23:44:39 CEST 2007


Wow Frank, the hidden patch is so elegant! I'm currently implementing it
in my layout, it does exactly what i was looking for. As i could see it
shall handle negative numbers just as fine, i hope it does! :) I will
report performance soon, I have rather big lists to go through.

Thanks for the great input,
Danja

Frank Barknecht wrote:
...
> Yes, that's the general idea: You calculate the distance using: 
> 
>  [- 45]
>  |
>  [abs]
> 
> and then you look for the smallest distance and use the number(s) of
> the original list that have this distance as your result. 
> 
> Attached patch shows several ways to achieve this result. One is using
> a bunch of abstractions from the [list]-abs collection. First it
> calculates a distance list made like: x for x in abs(x-45). 
> 
> For the list: "22 31 47 86" and the comparison value "45" this would
> be: "23 14 2 41".
> 
> Then we find the minimum using [list-minmax] which is 2. Then, using
> [list-find] we look up the position of 2 in the distance list: It's at
> index 2 (counting is starting with 0!). 
> 
> Then finally we retrieve the number at that position in the original
> list using [list-idx]. 
> 
> This will also find numbers with the same distance.
> 
> Another approach is illustrated on the right side of the patch. It
> doesn't involve any abstractions, but won't find more than one number.
> 
> The basic idea is to calculate the distance for every list element,
> and if that distance is smaller than the distance of the previous
> element, store the current item in a [f] element at the bottom. 
> 
> The first item is treated in a special way in that its distance is
> compared to itself, so that it will always be stored in the lower [f].
> 
> Finally when the whole list was consumed, the final result in the
> lower [f] is bang'd as result. Of course this will only give one result.
> 
> And finally, hidden in the subpatch [pd with-list-reduce] is a version
> that has a functional programming flavour and uses [list-reduce].
> 
> [list-reduce] calls whatever functionality  you patch and crossconnect
> to the right oulets on pairs of list items: First on the first and
> second element, then on the result of that computation and the third
> element, then on the next result and the fourth element and so on, and
> finally returns the last result to its left outlet.
> 
> In attached patch, the distances of both items in a pair are compared
> to each other. The number with the smaller distance is sent back to
> [list-reduce] where it is compared to the next element. 
> 
> So at first you get a comparison of the distances of 22 and 31 to 45.
> 31 obviously is closest so next its distance is compared to the
> distance of the next element, 47. Now 47 is closer, so 47 is sent back
> to list-reduce which pairs it up with 86. 47 still is closer, and as
> the list is fully parsed now, 47 is sent to the outlet.
> 
> This solution also only returns one result, but personally I think
> it's the most elegant of the three and looks really neat, if you put
> the comparision into a subpatch: 
> 
>  [list-reduce]x[pd compare-two]
> 
> And I'd always prefer a good looking patch. ;)




More information about the Pd-list mailing list