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 Kommentare

Walter Roberson
Walter Roberson am 4 Dez. 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 am 5 Dez. 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 am 5 Dez. 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 am 6 Dez. 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 am 6 Dez. 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 am 6 Dez. 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 am 6 Dez. 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 am 7 Dez. 2017
thank you Guillaume! you are right just noticed!
Spyros Polychronopoulos
Spyros Polychronopoulos am 15 Dez. 2017
similar problem, thank you:
https://uk.mathworks.com/matlabcentral/answers/373142-gradient-of-a-cell-array-with-optimizer

Melden Sie sich an, um zu kommentieren.

Antworten (0)

Community Treasure Hunt

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

Start Hunting!

Translated by