MATLAB elementwise matrix element access with ndgrid.

75 Views Asked by At

(Apologies if this is the wrong SE)

I've got a function containing a rather ugly nested for loop structure that I'm trying to vectorize. Effectively, I've got a matrix of coefficients, C (as a function of X, Y) and I'm trying to create a new matrix, M, where M[X,Y,Z] = exp(-X^2 - Y^2 - Z^2) * C[X,Y].

Unfortunately directly doing this (see minimum not working example below) doesn't work, as it does not evaluate C(X, Y) elementwise. I've tried wrapping the matrix in an anonymous function of X,Y,Z but this has the same issue.

coefficients = [1 2 3; 2 3 1; 4 5 6];
x = linspace(1, 3, 3);
y = linspace(1, 3, 3);
z = linspace(1, 3, 3);
[X, Y, Z] = ndgrid(x, y, z);
new_matrix = exp(-X.^2 - Y.^2 - Z.^2) .* coefficients(X, Y)

What I want is to have, for example

new_matrix(1, 1, 1) = exp(-3) * coefficients(1,1)
new_matrix(2, 3, 2) = exp(-17) * coefficients(2,3)

Is there any good way to do this without duplicating coefficients? (while for this MWE this may be fine, the actual script I'm writing would need ~3000 duplicates so I don't think this would be the best way to go about it?)

Thank you.

2

There are 2 best solutions below

0
On

Use arrayfun() instead. For example;

coefficients = [1 2 3; 2 3 1; 4 5 6];
x = linspace(1, 3, 3);
y = linspace(1, 3, 3);
z = linspace(1, 3, 3);
[X, Y, Z] = ndgrid(x, y, z);
new_matrix = arrayfun(@(xk, yk, zk) exp(-xk.^2 - yk.^2 - zk.^2) .* coefficients(xk, yk), X, Y, Z)
0
On

I don't know for sure this does what you want it to do, but it works for me.

N = [4,3,2];
coeff = rand(N(1:2));
[X,Y,Z] = ndgrid(linspace(-1,1,N(1)),linspace(-1,1,N(2)),linspace(-1,1,N(3)));
new_matrix = exp(-X.^2-Y.^2-Z.^2) .*coeff;

This works in at least new versions of Matlab which have adopted "automatic broadcasting" default behaviour from Gnu Octave.