hey list,
here's [d-median], a 'running median' abstraction i put together today. it's pure-Pd, for your PDa/Palmpilot/iPhoning pleasure. it outlets a running median of the last n values sent to its inlet.
internally, it maintains two arrays - one a sorted list of values, the other a table of the timetags associated with each value. when you pass it a new value it increments the current timetag, finds the 'oldest' value in the list (the value with the current timetag) and removes it, and inserts the new value in-order, attaching the current timetag. this is implemented as a single pass through the array, doing the smallest number of copies possible, so it's fairly efficient.
also included is [d-for], a C-like for loop based on [until]. you can say [d-for 0 20], bang it, and it will outlet sequentially 0,1,2,...,19. you can also say [d-for 0 20 2] to increment by 2 instead of 1, or even [d-for 0 1 0.1427] (negative increments are not supported unfortunately). and just like in C, if you say [d-for 1 0], nothing at all will be output. there's a debug mode as well, which allows you to step one iteration at a time - great for debugging code that is based around the [d-for]. have a look at the help for examples.
working on additional documentation for the dlib - everything in here is documented... comments appreciated.
damian stewart | skype: damiansnz | damian@frey.co.nz frey | live art with machines | http://www.frey.co.nz
hello,
i did not try it yet, but it look good. since it's pure pd, unlike the median_n from the mapping stuff, do you mind if i use your version for the mapping lib?
Cyrille
Damian Stewart a écrit :
hey list,
here's [d-median], a 'running median' abstraction i put together today. it's pure-Pd, for your PDa/Palmpilot/iPhoning pleasure. it outlets a running median of the last n values sent to its inlet.
internally, it maintains two arrays - one a sorted list of values, the other a table of the timetags associated with each value. when you pass it a new value it increments the current timetag, finds the 'oldest' value in the list (the value with the current timetag) and removes it, and inserts the new value in-order, attaching the current timetag. this is implemented as a single pass through the array, doing the smallest number of copies possible, so it's fairly efficient.
also included is [d-for], a C-like for loop based on [until]. you can say [d-for 0 20], bang it, and it will outlet sequentially 0,1,2,...,19. you can also say [d-for 0 20 2] to increment by 2 instead of 1, or even [d-for 0 1 0.1427] (negative increments are not supported unfortunately). and just like in C, if you say [d-for 1 0], nothing at all will be output. there's a debug mode as well, which allows you to step one iteration at a time - great for debugging code that is based around the [d-for]. have a look at the help for examples.
working on additional documentation for the dlib - everything in here is documented... comments appreciated.
d
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
cyrille henry wrote:
hello,
i did not try it yet, but it look good. since it's pure pd, unlike the median_n from the mapping stuff, do you mind if i use your version for the mapping lib? Cyrille
sure, go for it
Hallo, Damian Stewart hat gesagt: // Damian Stewart wrote:
here's [d-median], a 'running median' abstraction i put together today. it's pure-Pd, for your PDa/Palmpilot/iPhoning pleasure. it outlets a running median of the last n values sent to its inlet.
internally, it maintains two arrays - one a sorted list of values, the other a table of the timetags associated with each value. when you pass it a new value it increments the current timetag, finds the 'oldest' value in the list (the value with the current timetag) and removes it, and inserts the new value in-order, attaching the current timetag. this is implemented as a single pass through the array, doing the smallest number of copies possible, so it's fairly efficient.
That's really useful!
But I had a *really* hard time to read your patch. Attached is a slightly cleaned up version with some added local sends and many cord crossings removed. Still not perfect, but now I can see more of all these objects. ;)
Frank Barknecht Do You RjDj.me? _ ______footils.org__
Frank Barknecht wrote:
But I had a *really* hard time to read your patch. Attached is a slightly cleaned up version with some added local sends and many cord crossings removed. Still not perfect, but now I can see more of all these objects. ;)
heh :-)
... actually looking at that cleaned up version, now *i* can't figure out what's going on :-/ although to be honest, i could only barely figure out what was going on when i was writing it in the first place, so that's not surprising. doing logic with dataflow languages is so heinously complicated...
personally i find sends and receives to be a mixed blessing. on the one hand they get rid of unnecessary patch cords, but on the other hand they make it much less clear to see what's going on with the execution order. (what happens to the execution order when you do a message send/receive, anyway? do the send/receive pairs act exactly like patchcords, or is a send considered a leaf in the depth-first traversal tree?
d
Hallo, Damian Stewart hat gesagt: // Damian Stewart wrote:
personally i find sends and receives to be a mixed blessing. on the one hand they get rid of unnecessary patch cords, but on the other hand they make it much less clear to see what's going on with the execution order. (what happens to the execution order when you do a message send/receive, anyway?
Nothing. The execution order is not affected by sends and receives.
I didn't change that much actually: I only introduced three or four sends like for current position and for the new value, also I changed the backwards stop connections into a send "$0-stop". But of course it's confusing for you now as you've been into the old version a lot deeper that I was. I also replaced many fanning connections because they make me nervous. ;) I also left-aligned almost everything for clarity.
Normally I like it if there are lots of verbosely named subpatches when dealing with a complicated algorithm, i.e.:
[pd initialize] | [pd increment-timetag] | [pd send-new-x-value] | [pd loop-backwards-through-arrays] | [pd check-for-old-value] | [pd insert-sorted] | [pd output-median]
I wanted to make the patch clearer by separating stuff into more subpatches like this, but then I broke it. :(
Frank
Frank Barknecht wrote:
Normally I like it if there are lots of verbosely named subpatches when dealing with a complicated algorithm, i.e.:
[pd initialize] | [pd increment-timetag] | [pd send-new-x-value] | [pd loop-backwards-through-arrays] | [pd check-for-old-value] | [pd insert-sorted] | [pd output-median]
yeah this is a smart move. i'd probably do it that way if i was re-implementing things. while developing this i had a clearish understanding of more-or-less how to make it work; but there was also a considerable amount of making-it-up-as-i-went-along in there too.
then again, this approach brings you head to head with the problem of what to do when each subpatch has to communicate multiple things to subpatches further down the line... do you pack and unpack at the inlets/outlets? do you have multiple inlets and outlets?
and debugging execution order problems when things are sub-patched, for example: no thanks. if you calculate something in step 3 and don't need it again until step 6, but it needs to be delivered to the step 6 objects _before_ the thing you calculated in step 4 but _after_ the thing you calculated in step 5 - what happens then? i find it's clearer to have those scary fanning connections coming out of trigger objects, in this case.. sometimes i really wish i could use DesireData's stepping functionality, because reverse engineering using print objects is awkward at best; but as it is there is no DesireData for OSX, and no-one seems interested in helping me make it work at the moment.
... and then, of course, it's always a bit hairy trying to separate stuff after the fact, because:
I wanted to make the patch clearer by separating stuff into more subpatches like this, but then I broke it. :(
: exactly.
:-)
On Fri, 2008-10-17 at 17:59 +0200, Damian Stewart wrote:
Frank Barknecht wrote:
Normally I like it if there are lots of verbosely named subpatches when dealing with a complicated algorithm, i.e.:
[pd initialize] | [pd increment-timetag] | [pd send-new-x-value] | [pd loop-backwards-through-arrays] | [pd check-for-old-value] | [pd insert-sorted] | [pd output-median]
yeah this is a smart move. i'd probably do it that way if i was re-implementing things. while developing this i had a clearish understanding of more-or-less how to make it work; but there was also a considerable amount of making-it-up-as-i-went-along in there too.
then again, this approach brings you head to head with the problem of what to do when each subpatch has to communicate multiple things to subpatches further down the line... do you pack and unpack at the inlets/outlets? do you have multiple inlets and outlets?
and debugging execution order problems when things are sub-patched, for example: no thanks. if you calculate something in step 3 and don't need it again until step 6, but it needs to be delivered to the step 6 objects _before_ the thing you calculated in step 4 but _after_ the thing you calculated in step 5 - what happens then? i find it's clearer to have those scary fanning connections coming out of trigger objects, in this case.. sometimes i really wish i could use DesireData's stepping functionality, because reverse engineering using print objects is awkward at best; but as it is there is no DesireData for OSX, and no-one seems interested in helping me make it work at the moment.
... and then, of course, it's always a bit hairy trying to separate stuff after the fact, because:
and it becomes a lot easier when grouping stuff together from the beginning. this is at least what i believe and have experienced. debugging execution order doesn't need to be hard, if you apply certain paradigmes when patching. personally, i almost always use only one send symbol MYPATCH. then i give all parameters in use meaningful labels:
[freq $1( | [s MYPATCH]
as i said in the previous post, the receiving side should only go into cold inlets, if possible:
[r MYPATCH] | [route freq] | [X ]
when debugging execution order, you only need one single print to monitor your patch:
[r MYPATCH] | [print DEBUG]
yo, after all, i still think, that everyone has and should have their own personal patching style. however, i find it interesting to confront different styles with each other.
roman
Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de
Hallo, Damian Stewart hat gesagt: // Damian Stewart wrote:
Frank Barknecht wrote:
Normally I like it if there are lots of verbosely named subpatches when dealing with a complicated algorithm, i.e.:
[pd initialize] | [pd increment-timetag] | [pd send-new-x-value] | [pd loop-backwards-through-arrays] | [pd check-for-old-value] | [pd insert-sorted] | [pd output-median]
and debugging execution order problems when things are sub-patched, for example: no thanks.
The important trick is to build your execution order into the order of your subpatches (i.e. to model the subpatches after the execution order).
For example [pd increment-timetag] from above is a separate step in the logic, that has to be activated before all the steps that come after it. So it's put on top of most of the other actions and the graphical layout mimicks the logic flow.
Inside of these subpatches I generally have a construct like this:
[inlet | [t a a] | | | ... do subpatch task | [outlet]
Actually I even have a template subpatch for this, which gets copied and renamed first, then filled later.
This way the subpatch finishes all its work, after that the incoming data gets sent along through the first trigger outlet to activate the next subpatch. It could send along a simple bang, but in d-median.pd I think, passing along the new float value would be appropriate, too.
That's divide and conquer - and order.
This approach may not be needed all the time, but I found it immensly helpful when dealing with complicated algorithms with lots of steps. For example I used it for the Turing machine simulator: http://footils.org/cms/show/58 (see the [pd logic] subpatch there).
if you calculate something in step 3 and don't need it again until step 6, but it needs to be delivered to the step 6 objects _before_ the thing you calculated in step 4 but _after_ the thing you calculated in step 5 - what happens then?
Then I probably didn't use the right number and order of subpatches yet. ;)
Frank
On Fri, 2008-10-17 at 17:04 +0200, Damian Stewart wrote:
Frank Barknecht wrote:
But I had a *really* hard time to read your patch. Attached is a slightly cleaned up version with some added local sends and many cord crossings removed. Still not perfect, but now I can see more of all these objects. ;)
heh :-)
... actually looking at that cleaned up version, now *i* can't figure out what's going on :-/ although to be honest, i could only barely figure out what was going on when i was writing it in the first place, so that's not surprising. doing logic with dataflow languages is so heinously complicated...
personally i find sends and receives to be a mixed blessing. on the one hand they get rid of unnecessary patch cords, but on the other hand they make it much less clear to see what's going on with the execution order. (what happens to the execution order when you do a message send/receive, anyway? do the send/receive pairs act exactly like patchcords, or is a send considered a leaf in the depth-first traversal tree?
when having a look at your patch, i thought to myself: wow, this guy must be smart, that he still manages to see the overall picture of it. i agree on what you say about send/receive pairs. however, i still think, that they could be helpful. the main trouble i have when looking at d-median, is that there are so many chords going up and down at the same time. i think, send/receive can help a lot, as long as the receives only go to an non-triggering inlet. this way you can have very few (optimally one) patch chords going top->down, while the other stuff is a) labelled and b) doesn't interfere with the 'main triggering line'. personally i try to make - especially complex - patches going visually only one direction (top -> down, usually) and pack as many subparts into subpatches with meaningful labels. when reading the patch, one can forget about the details of certain part, while still seeing what the part does and how it is integrated in the main patch.
roman
Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de
Hallo, Frank Barknecht hat gesagt: // Frank Barknecht wrote:
But I had a *really* hard time to read your patch. Attached is a slightly cleaned up version with some added local sends and many cord crossings removed. Still not perfect, but now I can see more of all these objects. ;)
I made two other changes that I hade coded in my version before it broke: I replaced the tables with larger tables of size 500 that only get resized if 500 wasn't enough. This trades a bit of memory waste for less resizing. Resizing tables a lot can be bad for performance in Pd.
Then I changed the calculation of the median in the case of an even table size to take the arithmetic mean of both center values i.e. it calculates "(t[n/2] + t[n/2+1]) / 2" if n is even, otherwise it uses "t[n/2]"
Frank Barknecht Do You RjDj.me? _ ______footils.org__
Hi Damian,
On Thu, 2008-10-16 at 01:43 +0200, Damian Stewart wrote:
hey list,
here's [d-median], a 'running median' abstraction i put together today. it's pure-Pd, for your PDa/Palmpilot/iPhoning pleasure. it outlets a running median of the last n values sent to its inlet.
That's really useful. Where can I get the rest of dlib, I searched your website, but I couldn't find anything?
I like your music BTW.
www.postlude.co.uk http://www.linkedin.com/in/jamiebullock
Jamie Bullock wrote:
That's really useful. Where can I get the rest of dlib, I searched your website, but I couldn't find anything?
it's not officially released yet. i'm going through at the moment and gradually documenting and adding help patches for everything. when that's done i'll post it here.
I like your music BTW.
thanks! :-)