Jit.gen for list processing
Hi there, I decided after building a monster patch in max for some fairly simple list processing I would have a go at loading the data onto a jit.matrix and doing all my processing in jit.gen
I'm having a few problems getting it to behave exactly how I want it though.
The patch bellow loads a random float32 matrix with dimentions 6X1
In jit.gen I have isolated each of the 6 pixels values and used [absdiff] to work out the difference between each of these values.
You can see that each [absdiff] has it's own output.
I was wondering if it is possible to pack these values back into a list within jit.gen though so I don't have to do it in Max land.
I've tried using [vec] but I think that's for packing planes of data instead.
I'm sure I'm just missing a simple object that does this.
As I understand it, what you are trying to do is have each cell be a calculation of the absdiff with its next-door neighbor. Remember that you are coming up with a program that will run on each cell of the matrix, so you just have to come up with the logic to calculate one cell and that gets applied to all of them.
So, in order to do a calculation where you are taking the current cell and it's nearest neighbor, you just have to apply a single-pixel offset to the lookup. Since cell lookup coords are normalized, a single-cell delta can be derived by doing 1/dim. Just add that to the output of norm and you have a single cell offset. Once you have that, you can just pass that and the clean input to a single absdiff op and output the result.
I see. That simplifies things a lot as well as making the patch more powerful since now I can do this on any dimension matrix.
I'm wondering now though if you can do a similar thing across planes rather than across pixels.
So for example I could work out the difference between plane0 px1 & plane1 px1 and plane0 px2 & plane 1 px2 etc.
This is my idea so far, but again like my first patch it seems like I'm taking the long way round:
Thanks again Andrew.
In this case, you've got the right idea. It's possible that you could simplify it a little using codebox or expr, but this is probably the simplest way to unpack and repack the vectors in a gen patcher
I see. Is there any way in gen I can switch dimensions so for example if I have a matrix with 2 planes and each with a single row of 2 pixels can I switch them?
ie.
Plane 1 = 0.98 0.24
Plane 2 = 0.44 0.56
result should be
Plane 1 = 0.98 0.44
Plane 2 = 0.24 0.56
The layout of the values in a jitter matrix will look something like this:
You input matrix is:
(0.98, 0.44), (0.24, 0.56)
Your output matrix is:
(0.98, 0.24), (0.44, 0.56)
Looks like what you want is to place the first plane of the neighboring cell in the second plane of the first cell. You you get the nearest cell coordinate with norm+1/dim and sample the value with the [nearest] op, you will get this effect.
Like this?
The matrix seems to stay the same.
almost. I was thinking this:
However, I'm seeing that the boundary condition doesn't wrap the way it should for the last cell, so there's a math bug in the nearest operator that I'll need to look at. It doesn't really make a difference for video/geometry work, but for things like this it does.
A correction to my last post. There's nothing wrong with nearest and its boundmodes. The issue is how norm interacts with sampling. norm ranges from [0, 1] and is defined as cell/(dim-1). For a matrix that's 1 float32 2, the norm coordinates will be 0 and 1, so you'll have a matrix that looks like:
norm -> [0, 1]
If you shift by 1/dim, you'll get:
norm+1/dim -> [0.5, 1.5], which when sampled with nearest rounds up to [1, 2] and with wrapping [1, 1]
As a result, the output will be the second cell for both cells in the matrix. If you want to shift the sampling, you need to generate coordinates [0.25, 0.75] and shift them to [0.75, 1.25]. You can get this by doing:
(cell+0.5)/dim -> [0.25, 0.75]
(cell+1.5)/dim -> [.75, 1.25]
For you list processing, you'll want to use the latter expression. Here's an example patch: