cellfun with gradient [x,y]

I have a structure array q(1:50,1).p(1:50,1:50). And I was taking the gradient:
for k1=1:100
[part_x(k1).p,part_y(k1).p]= gradient(q(k1).p(:,:)); %gradient
end
I was getting part_x(1:50,1).p(1:50,1:50) and part_y(1:50,1).p(1:50,1:50)
Now I have functions (z) so I created the same structure but with cells: q{1:50,1}.p{1:50,1:50}, and I am trying to do the same but it doesn't work
for k1=1:100
[part_x{k1}.p,part_y{k1}.p]=@(z) (cellfun(@gradient,q{k1}.p{:,:}(z)));
end
Any ideas? I tried arrayfun as well but not working either.
Here is a code example to clarify things:
for k1=1:10
q1(k1).p=rand(10,10);
end
for k1=1:10
[part_x1(k1).p,part_y1(k1).p]= gradient(q1(k1).p); %gradient
end
% Now with function handle the same as above
A=rand(10^3,1);
for k2=1:10^3
a{k2}=@(z) z*A(k2);
end
%preparing the array for the gradient
l=1;
for k3=1:10
for k4=1:10
for k5=1:10
q2(k3).p{k4,k5}=@(z) a{l}(z);
l=l+1;
end
end
end
clear k1 k2 k3 k4 k5 l
% now I want to do what I have done with the matrix above but I have
% functions
%this returns 1 value so doesn't work
for k1=1:10
[part_x2{k1}.p,part_y2{k1}.p]=@(z) (cellfun(@gradient,q2(k1).p(z)));
end
%this doesn't work either
for k1=1:10^3
[part_x2{k1}.p,part_y2{k1}.p]=arrayfun(@(z) gradient(q2(k1).p(z)));
end

10 comentarios

Walter Roberson
Walter Roberson el 4 de Dic. de 2017
What is the data type of q(1:50,1).p(1:50,1:50) ? Your (z) after it in q{k1}.p{:,:}(z) implies that it is a cell array of function handles.
Your @(z) part is going to result in a single function handle, if the rest of the expression is okay, but you are attempting to extract two outputs not one ?
Are you trying to work symbolically or numerically?
Spyros Polychronopoulos
Spyros Polychronopoulos el 5 de Dic. de 2017
Hi Walter and thank you for your response. The data type of q(1:50,1).p(1:50,1:50) is just numbers, the values of temperature for example in x,y,z q(z).p(x,y) and when I am taking the gradient I get the same number of points for the gradient of the temperature for the gradient in x and y axes. Now I am trying to do the same but as I have functions I am using arrays and I don't get the same results as the matrices. You are right I get only one output from the gradient of the array but with matrices I got the same number of results as the size of q two times part_x(1:50,1).p(1:50,1:50) and part_y(1:50,1).p(1:50,1:50).
Walter Roberson
Walter Roberson el 5 de Dic. de 2017
I do not understand what you are trying to do. Try writing out the code using a for loop, without using cellfun; we can always optimize it after we get something working.
I put together some code for you in order to clarify it. Thank you
for k1=1:10
q1(k1).p=rand(10,10);
end
for k1=1:10
[part_x1(k1).p,part_y1(k1).p]= gradient(q1(k1).p(:,:)); %gradient
end
% Now with function handle the same as above
A=rand(10^3,1);
for k2=1:10^3;
a{k2}=@(z) z*A(k2);
end
%preparing the array for the gradient
l=1;
for k3=1:10;
for k4=1:10;
for k5=1:10;
q2{k3}.p{k4,k5}=@(z) a{l};
l=l+1;
end
end
end
clear k1 k2 k3 k4 k5
% now I want to do what I have done with the matrix above but I have
% functions
for k1=1:10
[part_x2{k1}.p,part_y2{k1}.p]=@(z) (cellfun(@gradient,q2{k1}.p{:,:}(z)));
end
Guillaume
Guillaume el 6 de Dic. de 2017
I think that there's something you're not explaining correctly or that you're not understanding properly. In your code, neither a or any of the p fields in q2 contain numerical values. They all contain functions to be evaluated later with an unknown input. There is therefore no gradient to be calculated yet.
Also,
p(:, :)
this is just
p
Finally, I don't see the need for q2 to be a cell array. The way you've coded it q2 is a cell array where is cell contains a scalar structure with field p itself a cell array. q2 could be a plain structure array:
q2(k3).p{k4, k4} = @(z) a{1};
Spyros Polychronopoulos
Spyros Polychronopoulos el 6 de Dic. de 2017
Hi Guillaume, Thank you for your response! your two points are noted and corrected: p(:,:)->p and q2{k3}->q2(k3).
But can't I store the gradient when I have functions in cells and later on calculate the values?
Guillaume
Guillaume el 6 de Dic. de 2017
If you are trying to calculate the gradient of a function as opposed to the gradient of a matrix, then you need to use the symbolic toolbox. I don't know much about the symbolic toolbox (don't have it) but I don't think it works with anonymous functions. Possibly, you can convert anonymous functions into symbolic functions.
Guillaume
Guillaume el 6 de Dic. de 2017
Another issue I've just noticed:
a{k} = @(z) z*A(k2);
...
x = @(z) a{l}
This is going to result in an error when you try to evaluate x since it calls a{l} without any argument (and a{l} requires one input.
x = @(z) a{l}(z);
would work but adds an unnecessary level of indirection.
x = a{l}
would be simpler.
Spyros Polychronopoulos
Spyros Polychronopoulos el 7 de Dic. de 2017
thank you Guillaume! you are right just noticed!
Spyros Polychronopoulos
Spyros Polychronopoulos el 15 de Dic. de 2017
similar problem, thank you:
https://uk.mathworks.com/matlabcentral/answers/373142-gradient-of-a-cell-array-with-optimizer

Iniciar sesión para comentar.

Respuestas (0)

Preguntada:

el 4 de Dic. de 2017

Comentada:

el 15 de Dic. de 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by