Matlab work with each vector from a 4D array - arrays

I have a 4D matrix of size, let's say, 100x200x3x10 where 100x200 is the size of one image, 3 is the number of channels (RGB images) and 10 is the number of images.
I want to compute the inner product of each RGB vector in each image with itself. The resulting image should be of size 100x200x10. How can I efficiently compute these products, possibly without the use of loops?
Thanks.

If you call your matrix M, this should work:
squeeze(dot(M,M,3))
The squeeze is because matlab gives a 100x200x1x10 matrix as the result, and squeeze knocks out the redundant dimension.

Related

Efficiently store an N-dimensional array of mostly zeros in Matlab

I implemented a finite differences algorithm to solve a PDE.
The grid is a structured 2D domain of size [Nx, Nz], solved Nt times.
I pre-allocate the object containing all solutions:
sol = zeros(Nx, Nz, Nt, 'single') ;
This becomes very easily too large and I get a 'out of memory' error.
Unfortunately sparse doesn't work for N-dimensional arrays.
For the sake of the question it's not important to know the values, it goes without saying that the RAM usage grows exponentially with decreasing the grid spacing and increasing the simulation time.
I am aware that I do not need to store each time instant for the purpose of the advancement of the solution. It would be sufficient to just store the previous two time steps. However, for post-processing reasons I need to access the solution at all time-steps (or at least at a submultiple of the total number).It might help to specify that, even after the solution, the grid remains predominantly populated by zeros.
Am I fighting a lost battle or is there a more efficient way to proceed (other type of objects, vectorization...)?
Thank you.
You could store the array in sparse, linear form; that is, a column vector with length equal to the product of dimensions:
sol = sparse([], [], [], Nx*Nz*Nt, 1); % sparse column vector containing zeros
Then, instead of indexing normally,
sol(x, z, t),
you need to translate the indices x, z, t into the corresponding linear index:
For scalar indices you use
sol(x + Nx*(z-1) + Nx*Nz*(t-1))
You can define a helper function for convenience:
ind = #(sol, x, y, t) sol(x + Nx*(z-1) + Nx*Nz*(t-1))
so the indexing becomes more readable:
ind(sol, x, z, t)
For general (array) indices you need to reshape the indices along different dimensions so that implicit expansion produces the appropriate linear index:
sol(reshape(x,[],1,1) + Nx*(reshape(z,1,[],1)-1) + Nx*Nz*(reshape(t,1,1,[])-1))
which of course could also be encapsulated into a function.
Check that the conversion to linear indexing works (general case, using non-sparse array to compare with normal indexing):
Nx = 15; Nz = 18; Nt = 11;
sol = randi(9, Nx, Nz, Nt);
x = [5 6; 7 8]; z = 7; t = [4 9 1];
isequal(sol(x, z, t), ...
sol(reshape(x,[],1,1) + Nx*(reshape(z,1,[],1)-1) + Nx*Nz*(reshape(t,1,1,[])-1)))
gives
ans =
logical
1
You can create a a cell array of sparse matrices to store the results. However computations can be performed on full matrices if working with a full matrix is faster than sparse matrix and convert the full matrix to sparse matrix and place it in the cell.

Fill Grid With Random Pixels

I have a grid of pixels 64x8. The aim is to to activate the pixels on this grid in a random manner till the whole grid is activated.
Logically I can generate random numbers in 0-63 and 0-7 range and then activate this pixel. Assuming I run this for long enough, the grid should be completely activated.
However, I am wondering if there is any algorithm that can minimize / avoid altogether collision (returning already activated pixel coordinate) and guarantee complete grid activation in a finite amount of time?
Fill an array of length 512 with numbers increasing from from 0 to 511 (64x8 = 512), so the array will contain {0,1,2,3,..., 511}).
Then shuffle that array, for example like explained here: Shuffle array in C.
Then define a function that maps a number to a coordinate, that would be:
y = n / 8
x = n % 8
n being one of the numbers of the array.
If the array is well shuffled this guarantees that all pixels will be activatged in a random order.
You could implement a pseudo random generator (PRG # Wikipedia) with a period of 64 * 8. Use 3 bits for the axis with 8, and the remaining 6 bits for the axis with 64.

How to perform arithmetics on element in 2D Numpy array involving elements indices?

Context
I am implementing 2D Discrete Fourier Transform algorithm using Python with Numpy.
According to image processing theory in order to center image's transform, before performing the transform, each intensity f(x, y) of the image needs to be multiplied by (-1)^(x + y) where x and y are intensity's indices in 2D array representing the image.
What was tried
The obvious approach is to iterate over each intensity and its indices using two for loops.
Question
Is there a more elegant/faster solution using Python/Numpy matrix operations or should I stick with two for loops?
The idiomatic way would be:
y,x = np.ogrid[:m,:n]
prefactor = (-1)**(y+x)
Here m,n are, of course, the dimensions of your operand array.

Summing elements from a vector, bounded by certain indices

I have a row vector x in Matlab which contains 164372 components. I now want to group these elements in another vector y, which has to contain 52 components. The first element of the vector y must be the average of the first 164372 / 52 = 3161 elements of the vector x, the second element of y must be the average of the next 3161 elements of x, etc. This continues until I have taken all of the 52 averages of the elements in the vector x and placed them in y.
How can I implement this in Matlab? Is there some built-in function that lets me sum elements from a certain index to another index?
Thank you kindly for any help!
With reshape and mean:
x = rand(1,164372); % example data
N = 52; % block size. Assumed to divide numel(x)
result = mean(reshape(x, numel(x)/N, []), 1)
What this does is: reshape the vector into a 52-row matrix in the usual column-major order, and then compute the mean of each column.

How to use the given FFT function in C?

Sorry this is the first time for me to ask question here, I've given a FFT function
void fft_1d(int n, float xr[256], float xi[256], int ntype)
{
/* compute the FFT of a complex signal
xr and xi are the real and imaginary parts respectively
xr and xi contain the signal as input and the FT as output
n is the number of points, it should be a power of 2
ntype is set to 1 for forward transform and -1 for inverse transform
*/
And I have been told to extend this function to do the 2D (DFT) of the given image.
My problem is:
I can get every itensity value of the given image but how can I deal with the complex components (real part /imaginary part) of the fft_1d? In other words, what should I put in the parameters float xr[256] and float xi[256] in order to do the 2D (DFT) of the image?
Thanks for your attention!
An image is, generally, a real-only function. Therefore, you can set the real inputs to be the image values, and the imaginary inputs to zero when calling the FFT function.
However, in order to perform a 2D FFT, you must first call the 1D FFT on each row, and then call the 1D FFT on each column of the results. These intermediate results will be complex, and must be passed as such to the second set of FFTs.

Resources