[matrixctrl] & lists

Aaron Wharton's icon

In the attached patch, I've used [funbuff] to monitor/ manage x/y pairs from [matrixctrl].
([matrixctrl] > [zl.rev] > [route 0 1] > [prepend delete/set] > [funbuff])

Past that, I'm using [thresh] to capture lists of each axis.

The issue I've run into is that [funbuff] is behaving in a "one non-zero-cell per column" manner, and I'd like for it to represent all active cells, regardless of how many there are per column.

Max Patch
Copy patch and select New From Clipboard in Max.

Perhaps, [funbuff] isn't the solution I'm looking for, but I'm out of ideas for further workarounds.

Sincerely,
Aaron

Source Audio's icon

Max Patch
Copy patch and select New From Clipboard in Max.

Aaron Wharton's icon

@source audio -- Thank you so much; this is magnificent. <3

May I ask how long have you've been at this? Just curious, as I've seen and admired quite a few of your contributions to the forum over the past year or so.

Source Audio's icon

coll is my favorite when it gets to storing lists.
Did not cost much time, because I used similar
things before, not necessary for matrixctrl
but for similar things, like sorting held midi notes for example
adapting that to your example was than not too difficult

Aaron Wharton's icon

Re: coll - I'd tried using it previously but ran into a snag when sending coordinates as a symbol through [prepend store]. I now see the "$1 -" message was the solution to that. Nice. :)

Now, I find myself wondering how to get this working when using dial mode. I like how you have coll sorting coordinates, but I doubt that would work with dial mode. Hmm.

To elaborate on my intended use case for this, I plan to:
1. send each list through a [vexpr].
2. reunite the result of each. (via [zl.lace])
3. append the 1 (or greater) for each active cell. (with [zl.stream 2] > [pack l i])
4. generate inactive cell values for the new dimension, to avoid using a clear message.
5. feed the processed list into a second [matrixctrl].

4** -- The next hurdle will be figuring out how to generate inactive cell values, rather than preceding the adjusted list with a clear message. (In previous attempts, the clear message in-between each adjustment produced a lot of extraneous data, making it hard to reliably pull data from.)

Sincerely,
Aaron

Source Audio's icon

You should have started with that dial mode if that was the goal.
Not doing so is just waste of time...
in dial mode there is no empty cell, just a value that could be
> 0 or not
Maybe you should rethink the whole concept.
Why use matrixctl at all ?

Aaron Wharton's icon

Re: Why use [matrixctrl] at all?
- It was due to how much I'd found myself using it. Both [router] and [matrix~] are built to interface with it; Gregory Taylor's Step by Step book used it a fair amount.

For sequencing, I know several to have used and advocated for [multislider], though reducing a [matrixctrl] to one row in dial-mode achieves the same result, so does it not provide more overhead than [multislider]?

I know Jean mentioned [jit.pwindow] as a potential workaround a bit ago, but after doing a bit of experimenting, I agreed that it wasn't worth it from a UI experience, standpoint.

What other alternatives are there?

Re: My reasoning for not having led with dial-mode:
- I was more so focused on the collection of the X/ Y axes, as those are the collections I want most to process. I'm sorry for not having stated a concern for the Z axis upfront; I'm not trying to waste anyone's time. =/

Sincerely,
Aaron


Source Audio's icon

Sorry, I did not mean my time wasted, but your time...
And for me it is perfectly all right whatever you want to use,
it is just that looking from outside, and not knowing the context
of the whole construct, one asks such questions.
I still don't know what you are after, but generally -
matrixctrl is allways having all rows and columns
occupied by a value, being a zero , 1 or a value from dial.
If you want to manipulate only cells that are > than zero
that is not a problem, and is fast enough.
You modify the values at same addresses.
more efficient than having to clear the matrix and then send all "populated"
values I'd think would be to allways send the full list.


Aaron Wharton's icon

Ok, so the primary objective (among others) is resampling cell states to another resolution.

The construct is:
1. the reference [matrixctrl #1]
2. the processor [what I've been building]
3. the result [matrixctrl #2]

The problem with "always send the full list" is that, when changing the resolution, the length (of the full list) expected by the second matrix will be different from the length (of the full list) issued by the first.

My first attempt was to use jit.matrix to do the resampling, but active cells would be repeated when upsampling.

My second attempt was to simply bang the first matrix (reference) to send the full list, and filter out the inactive cells, process, and clear the second matrix before issuing every new active cell state, but that creates a lot of extraneous data that makes it difficult to work with.

So my current thought process is: Surely, there's away to generate inactive cell values around the processed active values, before sending to the second, bypassing the need for a clear message.

Sincerely,
Aaron


Source Audio's icon

I don't really get that process between 2 matrixctl objects,
but there should be no difference between switch and dial mode
in the patch below in addition to cell coordinates as symbol
also x y and data of any > 0 cell is stored into coll.
You can use that to separately group, scale, repack or whatever and send
somewhere else, like matrixctl B.

I assume that both matrixctl A & B are having same number of
rows and columns.
in case of 8x4 it is only list of 96 items.
easy to deal with

Max Patch
Copy patch and select New From Clipboard in Max.

Aaron Wharton's icon

Re: ^this patch:

Oh, ok nice. :) So you could then not worry about the second output of coll > [fromsymbol] > [unpack 0 0] and just use an [unpack 0 0 0] into 3 [zl.groups] out of the first coll output, then? :) -- I like that a lot; that makes a ton of sense.

I went ahead and made ^that adjustment, while swapping [if] with [routepass 0].

Was there a purpose [capture] was serving? This is actually the first I'm seeing that object.

Max Patch
Copy patch and select New From Clipboard in Max.


"I assume that both matrixctl A & B are having same number of rows and columns."

They are not. What I meant by upsampling/ downsampling resolution was "to change the row/ column counts, while retaining the same image". So when you increase/ decrease the number of cells in [matrixctrl b], you either need to create inactive cell values to add to the list of processed active cell values (the next step), or clear [matrixctrl b] before populating with active values.

As of this moment, the only purpose [matrixctrl a] serves is to provide the list to process to send to [matrixctrl b]. If you could dump A's cell state into a list, you could potentially remove the need for A. (Though, the notion of daisy-chaining, once removing the need for a clear message, is a fun one.)

Sincerely,
Aaron

Source Audio's icon

capture was left in without need, forgot to delete it...
I sometime use it to collect raw data.
I wish you to get that working the way you want

Aaron Wharton's icon

Ah, I see. Duly noted. :)

Thank you so much.

EDIT: Ok, so after a bit of head scratching, I managed to locate this thread, and Bas's solution seems to be doing the trick. If anyone happens to pop in and know of a slicker method, please do tell. πŸ™‚

Max Patch
Copy patch and select New From Clipboard in Max.


Aaron

Aaron Wharton's icon

Ok, so I now have two lists that I'm attempting to merge:
- The format is in [matrixctrl]'s "x y z".
- The first list contains select active pairs: "x y 1".
- The second list contains all possible inactive pairs: "x y 0".

I'd like to look for the duplicate "x y" pairs in each and remove those with a 0/ keeping those with a 1. (Sorting isn't a concern, atm.)

Sincerely,
Aaron

Source Audio's icon

Max Patch
Copy patch and select New From Clipboard in Max.


Source Audio's icon

here is list merger and slicker empty list creator...

Max Patch
Copy patch and select New From Clipboard in Max.

Aaron Wharton's icon

Sorry for the delay, man. I'll give these a glance and respond, shortly. Currently wrapping up mastering work for a client. πŸ˜…

Really, though. Thanks for your time/ effort assisting. <3

Aaron Wharton's icon

My apologies, for the delay.

Alright, so regarding the creation of the empty B list, I think I've decided that it's probably simplest/ lightest to use a dummy [matrixctrl] (disabling as much GUI feedback as possible) to bang out the list on every row/ column adjustment. (Perhaps I'm wrong in thinking this though.)

As I currently understand (re: merging lists via [coll]), you send the initial list in, and then send the second to update entries of that initial list.

I believe I've got the ordering correct in this (as I don't see how the Matrix A list could be arriving at the second coll, before the Matrix B list), but there's clearly an issue, and I'm not seeing where things are going awry.

Max Patch
Copy patch and select New From Clipboard in Max.


Ideally, I'd like for the result to be as fluid/ smooth to update as possible, as the fun will come from dynamic modulation.

Sincerely,
Aaron

Source Audio's icon

I am afraid I completely lost the trace about this
I don't understand what this last patch should do.
If I remember correctly you want to input a list coming from one matrix,
expand, modify or whatever the list and populate next matrix with it.
so why don't you check number of rows and columns in new created list,
send message clear, rows $1, columns $2 to second matrix and
send the list

Aaron Wharton's icon

Re: my goal

To be able to dynamically resample a cell state to another resolution. Ie. upscale an image that began at 8x4 to either 10x4, 8x6, 10x10 (stretching), or quantize an image that began at 8x4 to either 5x4, 8x3, 5x5. (all of these dimensions being arbitrary for illustration.)

Re: the use of a clear message

This was my first approach. It turns out that sending a clear message to a [matrixctrl] doesn't quietly update the state. It causes the output of the cleared state. So for every adjustment made while using a clear message, you get two updated states. Rather than fixating on a way to filter out that cleared state, I figured it would be cleanest to bypass the need for a clear message by creating the updated/ scaled list before populating the second. Furthermore, the ability to create the list without a clear message would negate the need for the second altogether.

Sincerely,
Aaron

Source Audio's icon

It is very simple to bypass any output from matrix,
whatever message one sends to it.
Attatch a gate at output and close it when you want matrix output quiet.
For me it is totaly uncear what the values in the list control.
If a single value controls anything in the real world,
then it must get updated to reflect new state, being it simple
0 or 1 or any other value.
Only reason to bother that much about list creation etc is if
repeatedly sending same values to RECEIVER object - the one
that reacts to that value causes cpu strain or any other overload or strain.
At the end it might be that you use more cpu cycles
to work it out with complicated "from one barrel to another barrel" approach, then to insert change object in front of receiver objects.
--------
The example I sent you last is actually the second part of the
barrel.
It expects number of rows and columns and populated list
with "positive" values to fill the matrix.

Aaron Wharton's icon

I saw (and appreciated the last patch), though "mousefilter", [bondo], and [qmetro] perplexed me a little at first. In the end I concluded that as long as the empty list was received by [coll] before the active list, then things would be completely resolved. But after a fair amount of work, it doesn't seem to be working, and I don't currently see where I'm going wrong. (I attached comments in the last patch I sent).

Re: a gate to mute the outputs of [matrixctrl]:
That's a totally fair point. (I'm not sure why, but I hadn't thought of that. πŸ˜…) -- Though, the idea of not needing to use 2 matrices is exciting enough for me to continue trying to figure out a fix for compiling the list without using a clear message.

Re: the use case -- In Gregory Taylor's Step by Step book, he used [matrixctrl] to mute/ activate steps of a [live.step], using [zl.change] to a "getrow" message in conjunction with [zl.lookup].

Aaron

Source Audio's icon

Mousefilter is there to avoid sending x or y
size when one slides from for example 4 to 7
Without it matrix would be resized using x4 x5 x6 and x7
mousefilter lets only 7 out when one releases it.
bondo is there so that x y values get sent no matter which one changes.
qmetro / counter is speed controlable uzi.

You are right, coll should first get populated with
all "cells" set to zero values, than
indexes with populated matrix values get replaced.
It is only a matter to control the arrival time.
Here is example patch

Max Patch
Copy patch and select New From Clipboard in Max.


input list can be from matrix dial as well, it does not matter.
But input list must have matrixctrl form: column row value

Aaron Wharton's icon

Alright, so I just tried merging this most recent patch with the previous one, and things are still not quite working as expected (for whatever reason). I've gone ahead and included thorough commenting/ color coding, etc.

Max Patch
Copy patch and select New From Clipboard in Max.


Some additional thoughts:
1. Is sorting necessary? I'm aiming for instant updates. (which is also why I'm trying to avoid [thresh])
2. re: mousefilter - yeah, I'd like to retain the slide adjustments.
3. qmetro - I might play with using this at some point, but for the moment I'm seeking instantaneous updating.

Again, thanks so much for this assistance.

Source Audio's icon

This patch is too complicated and there are obviously some mistakes in the construct
I get errors when loadbanging to start it.

I am running Max 6 when I am traveling, maybe it is because of that.
Anyway, the answers -
sort and renumber at the end is just a cosmetic thing, maybe you don't need
the last coll at all, I included it just as example.
Sorting ? I don't know what you need that end list for,
but in case you want it sorted or output as a single list to route somewhere
you would have to sort it.
Then qmetro - it does not need to be qmetro - ordinary metro would do as well
or whateve you can use to create empty cells.
I use qmetro because it s helpful to control flow when it's result
load heavier stuff, like if one wants to preload sfplay with many
samples from populated umenu.
---
The last patch I posted works perfectly, just send it
a list that you created in first process - scaling the original list.
In your last patch you are setting end output dimensions on loadbang, why ?
It should be done only by creation of the populated modified list, not before.
-----
I see it this way:
1 you have input list
2 you modify that list working only on "populated" cells
3 you form output list using that modified list, filling the gaps with zeros

My last patch does this step 3.
It could possibly be made faster by reducing creation of empty cells time
and del 10 to merge empty list with populated one and if you don't need the last coll
remove dump message
It has nothing to do with process of inputing initial list and processing it.
You asked for a way to merge 2 lists without matrixctrl using dimensions message
and clear / dump to create empty list.
But now you do exactly that in that merge active/empty patcher .
So what out of my last patch is in use ?
----------
I would separate this 3 steps first.
1 Input list - Is it allways having same dimensions ?
In any case why do you send dimensions of input list
to output section, before modifying it ?
Maybe I am mistaking the whole process, I thought that output dimensions get created by
modifying the input list....

Aaron Wharton's icon

Re: the crashing/ errors

Oh ok, hmm. I'm on 8.1.5. That said, it seems to be loading fine for me. =/ - It really is quite close to doing what I'd like, but there are just a couple hiccups that I'm not pin-pointing.

Re: β€œI thought that output dimensions get created by modifying the input list.”

Negative, I’m afraid. The output list is created by adjusting the output dimensions/ the input list is modified by adjusting the output dimensions. (Ie. When you modify dimensions of the output dimensions, you increase/ decrease the number of output cells β€” This is why the blank list is necessary.)

Re: sorting

I believe it’ll only be necessary, if I decide to avoid using the second matrix altogether. Otherwise, as long as each cell is accounted for, the second matrixctrl will receive and represent it, etc.

Really, man. I can't tell you how much I appreciate the time/ aid,
- Aaron

Source Audio's icon

If the process of modifying the input list is initiated by
resizing the input dimensions, than you are having it even
easier, you don't need to wait till new list is created.
just find the fastest way to create the empty list.
What I did in last example is ok, but it could be done faster.

Max Patch
Copy patch and select New From Clipboard in Max.


here you can compare uzi and co vs matrixctrl.
jit.cellblock is a lame one when updating values,
ut us just here to show if coll values are set right
P.S. initial uploaded patch had a little mistake, I have replaced it

Aaron Wharton's icon

Apologies for the delay; I fell asleep for a bit.

I just went through this and modified and saved a snippet from the counter and uzi approach. There is a weird issue when updating the different axes independently. (instances of 900 or higher will pop into the list).

That said, what I had been doing was the second option: "Just update and bang a dummy matrix for the empty list." So I'm fairly certain this isn't my issue.

I suppose I'll keep hacking at it, and update if I find a fix. I just don't know where my issue is.

Aaron

Source Audio's icon

uzi - counter combo can only work if they receive settled list of
x y dimensons, at least it is so in the patch I posted.
That is why i placed a list as source, otherwise i would have used mouse filter.
Simply, you must let 2 uzi objects run till they end , before inputing new list.
---------