LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Shift 2D Array circularly in labview

Solved!
Go to solution

Hi everyone, 

 

I am trying to create a VI that can shift rows up/down and columns right/left in a 2D array. This would be easily implemented with "Rotate Array" function, however, it only takes 1D array. I was able use the MATLAB Script to implement the 2D shift using the shift array circularly "circshift" function, but is there anyway to do it with the use of LabVIEW functions only? 

 

The VI that uses MATLAB script is attached to show exactly what I want to implement while only using LabVIEW-based functions. I used two output arrays to facilitate visualisation of the shift in row and column but essentially it would be one output array with separate row and column control.

 

Thanks,

S

Download All
0 Kudos
Message 1 of 9
(254 Views)

It'll probably look a lot cruder and more brute force in LabVIEW.

 

1D array rotations are done efficiently behind the scenes in LabVIEW, without actually copying and moving data around.  Like you, I don't know of any way to get similar efficient 2D rotation.

 

Fortunately, the 2 rotation operations are orthogonal, thus independent, and can be done in either order.  That's gonna help.

 

...I had a few minutes while needing a break from writing help docs.  Here's a screenshot and a vi version.   I only tested briefly, but it seems to replicate your Matlab example (I don't have it installed to test other shift amounts).

 

 

-Kevin P

 

image.png

Message 2 of 9
(223 Views)

Something like this maybe:

Rotate2DArray.png

Message 3 of 9
(218 Views)

Take how many rows (or columns) you will be shifting and use that value in an Array Subset Function.  Do that to take your initial array and break it into 2 subsets.  Then use Concatenate Array to but those two subsets back together in reverse order.  Without having tested this out, I think this might work easier for one direction (my guess is shifting rows, than the other, shifting columns.)

 

So if the next idea, and probably better idea, is initialize an array of the same size, and use Replace Array Subset to put in the two parts back together in the new order in your array.

Message 4 of 9
(217 Views)
Solution
Accepted by topic author Sandro07

Came back to clean things up a bit after a 9:00 virtual mtg.  The solution was quite a bit less crude and ugly than I was prepared for.

 

Now all functions have their labels visible, and I added a little redundancy to show alternatives in the code.  One of those is to illustrate the idea from RavensFan to use "Replace Array Subset" when accumulating the shifted output array.

 

If it matters, this method handles both positive and negative shifts.  The other posted code won't.  You didn't say you needed that, but you also didn't say you didn't.  I kinda like having that ability, making it more like "Rotate 1D Array".

 

Attached as LV 2010 snippet, same version as OP's posted code.

 

 

-Kevin P

 

shift 2d array.png

Message 5 of 9
(205 Views)

Brilliant! Thank you all for the help, it works perfectly now. Really appreciate it! 

0 Kudos
Message 6 of 9
(188 Views)

Sorting the entire array to rotate is just a waste of CPU...

 

The negate values is a minor problem:

Rotate2DArray.png

 

Suit yourself. I hope your arrays stay small.

Message 7 of 9
(176 Views)

That's a good point about the sorting, though in just thinking about it, I'm kinda doubtful that the array data itself needs to get manipulated at all in the sort.  The comparison operation for the sort only uses the first field (a unique integer) and never has to touch the array contents.

 

I'd also tend to guess that somewhere deep inside, LabVIEW arrays of clusters are carried as something more like arrays of pointers to cluster.  If so, the sort operation only needs to rearrange the order of those pointers.  Still inefficient for sufficiently "big" arrays of clusters.  But "big" may not come into play until you get dimensions of 1000 or more.

 

You've got me curious though.  When I can get to a LV 2020 system, I might try to do a little benchmarking with different array dimensions.   This 2D shift is starting to "feel like" a potentially useful function for image data, where dimensions can indeed exceed 1000 or more.

 

 

-Kevin P

0 Kudos
Message 8 of 9
(163 Views)

@Kevin_Price wrote:

That's a good point about the sorting, though in just thinking about it, I'm kinda doubtful that the array data itself needs to get manipulated at all in the sort.  The comparison operation for the sort only uses the first field (a unique integer) and never has to touch the array contents.


It won't be terrible.

 


@Kevin_Price wrote:

I'd also tend to guess that somewhere deep inside, LabVIEW arrays of clusters are carried as something more like arrays of pointers to cluster.  If so, the sort operation only needs to rearrange the order of those pointers.  Still inefficient for sufficiently "big" arrays of clusters.  But "big" may not come into play until you get dimensions of 1000 or more.


They do use pointers. There won't be much penalty in the sort itself. The sort itself will be Log(O), so the time it takes to sort the array will grow exponential. A map will improve that.

 


@Kevin_Price wrote:

You've got me curious though.  When I can get to a LV 2020 system, I might try to do a little benchmarking with different array dimensions.   This 2D shift is starting to "feel like" a potentially useful function for image data, where dimensions can indeed exceed 1000 or more.


I don't think my solution is optimal. Especially the transpose (that doesn't take time, it's simply a flag) and then the 2nd get subset that could be expensive.

 

I think getting the subset in one dimension and then a for loop with a rotate might be faster, because the rotate is fast.

 

If a 2D array not required, an array of clusters with arrays might be faster.

 

I did some rudimentary benchmarking. My version seemed faster, especially for large arrays, but yours wasn't terrible.   

0 Kudos
Message 9 of 9
(157 Views)