- Define the variable at the start of the parent function, which can then be accessed by the nested function.
- Use output arguments, exactly as Geoff Hayes advised you to do.
Matlab: Nested PDEG functions
1 visualizzazione (ultimi 30 giorni)
Mostra commenti meno recenti
Soheil Esmaeilzadeh
il 26 Mag 2016
Modificato: Soheil Esmaeilzadeh
il 1 Ago 2016
I have originally two functions as below: The first one:
function [ X ] = faces( d,hc )
[p,e,t] = initmesh(@cardioid1,'init','off');
load('func_contents.mat');
zval_u=-hc;
zval_d=-hc-d;
t(4,:)=t(1,:);
val(:,:)=p(:,t(:,:));
valu(:,:)=val(:,:);
valu(3,:)=zval_u;
vald(:,:)=val(:,:);
vald(3,:)=zval_d;
%%%%%%%%Upper face %%%%%%%%%%%%
for i=1:size(t,2)
% for i=1:3
X(1,i,:,:)=[valu(:,4*i-3)';valu(:,4*i-2)';valu(:,4*i-1)';valu(:,4*i)'];
end
bord1(1,:)=xt(1,:);
bord1(2,:)=yt(1,:);
end
And the second one as below:
function [x,y,xt,yt,th] = cardioid1(bs,s)
%CARDIOID1 Geometry File defining the geometry of a cardioid.
global r0 a1;
r0=1;
a1=1;
if nargin == 0
x = 12; % four segments in boundary
return
end
if nargin == 1
dl = [0 pi/6 2*pi/6 3*pi/6 4*pi/6 5*pi/6 6*pi/6 7*pi/6 8*pi/6 9*pi/6 10*pi/6 11*pi/6
pi/6 2*pi/6 3*pi/6 4*pi/6 5*pi/6 6*pi/6 7*pi/6 8*pi/6 9*pi/6 10*pi/6 11*pi/6 12*pi/6
1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0];
x = dl(:,bs);
return
end
x = zeros(size(s));
y = zeros(size(s));
if numel(bs) == 1 % bs might need scalar expansion
bs = bs*ones(size(s)); % expand bs
end
nth =190; % fine polygon, 100 segments per quadrant
r0=1;
th = linspace(0,2*pi,nth); % parametrization
r=r0+a1*cos(th);
xt = r.*cos(th); % Points for interpolation of arc lengths
yt = r.*sin(th)+1000;
% Compute parameters corresponding to the arc length values in s
th = pdearcl(th,[xt;yt],s,0,2*pi); % th contains the parameters
% Now compute x and y for the parameters th
r=r0+a1*cos(th);
x(:) = r.*cos(th);
y(:) = r.*sin(th)+1000;
save('func_contents.mat','-v6')
end
Inside the "faces" function I access the second function by @cardioid1 and when cardioid1 runs I pass its parameters to "faces" by saving of the workspace and loading it inside "faces" again.
Since I want to change this format to parallel, they mix up the names, since all will save under a single name.mat in a single directory.
Now I thought to make it nested function, so that each parallel process locally and directly have access to parameters of cardioid1.
So I changed it to below code:
function [ X ] = faces2( d,hc )
cardioid1;
function [x,y,xt,yt,th] = cardioid1(bs,s)
%CARDIOID1 Geometry File defining the geometry of a cardioid.
global r0 a1;
a1=0.1;
a2=0.1;
a3=0.5;
if nargin == 0
x = 12; % four segments in boundary
return
end
if nargin == 1
dl = [0 pi/6 2*pi/6 3*pi/6 4*pi/6 5*pi/6 6*pi/6 7*pi/6 8*pi/6 9*pi/6 10*pi/6 11*pi/6
pi/6 2*pi/6 3*pi/6 4*pi/6 5*pi/6 6*pi/6 7*pi/6 8*pi/6 9*pi/6 10*pi/6 11*pi/6 12*pi/6
1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0];
x = dl(:,bs);
return
end
x = zeros(size(s));
y = zeros(size(s));
if numel(bs) == 1 % bs might need scalar expansion
bs = bs*ones(size(s)); % expand bs
end
nth =190; % fine polygon, 100 segments per quadrant
r0=1;
th = linspace(0,2*pi,nth); % parametrization
r=r0+a1*cos(th);
xt = r.*cos(th); % Points for interpolation of arc lengths
yt = r.*sin(th)+1000;
% Compute parameters corresponding to the arc length values in s
th = pdearcl(th,[xt;yt],s,0,2*pi); % th contains the parameters
% Now compute x and y for the parameters th
r=r0+a1*cos(th);
x(:) = r.*cos(th);
y(:) = r.*sin(th)+1000;
% save('func_contents.mat','xt','yt')
end
[p,e,t] = initmesh(@cardioid1,'init','off');
pdemesh(p,e,t)
% load('func_contents.mat');
zval_u=-hc;
zval_d=-hc-d;
t(4,:)=t(1,:);
val(:,:)=p(:,t(:,:));
valu(:,:)=val(:,:);
valu(3,:)=zval_u;
vald(:,:)=val(:,:);
vald(3,:)=zval_d;
%%%%%%%%Upper face %%%%%%%%%%%%
for i=1:size(t,2)
% for i=1:3
X(1,i,:,:)=[valu(:,4*i-3)';valu(:,4*i-2)';valu(:,4*i-1)';valu(:,4*i)'];
end
bord1(1,:)=xt(1,:);
bord1(2,:)=yt(1,:);
end
But I get the error: Undefined function or variable 'xt'. Error in faces (line 71) bord1(1,:)=xt(1,:);
0 Commenti
Risposta accettata
Stephen23
il 2 Giu 2016
Modificato: Stephen23
il 2 Giu 2016
@Soheil Smz: what do you expect to happen? You have two possible solutions:
Geoff Hayes told you to use output augments, but I can't see any in your code:
function main2
nestfun2
function nestfun2
x = 5;
end
x = x + 1
end
When I fix your code following Geoff Hayes' advice exactly, it works perfectly:
function y = main2
y = nestfun2;
function x = nestfun2
x = 5;
end
y = y + 1
end
And tested:
>> main2
ans = 6
Or alternatively without output argument, but defining the variables at the start of the parent function:
function y = main3
y = 0;
nestfun2
function nestfun2
y = 5;
end
y = y + 1;
end
And tested:
>> main3
ans = 6
Both of these are explained very well in the documentation, here is the salient info "All of the variables in nested functions or the functions that contain them must be explicitly defined. That is, you cannot call a function or script that assigns values to variables unless those variables already exist in the function workspace."
There is more to read and learn:
0 Commenti
Più risposte (1)
Geoff Hayes
il 27 Mag 2016
Modificato: Stephen23
il 27 Mag 2016
Soheil - you have posted more code than you should have to your question. As such, that is likely to discourage people from attempting to answer it. I think even those on StackOverflow (given the link above) have indicated the same. In the future, post only relevant code and only enough that is necessary to reproduce the problem.
That being said, look at how you call cardiod1 from your main function:
function [ X ] = faces( d,hc )
cardioid1;
function [x,y,xt,yt,th] = cardioid1(bs,s)
% cardioid1 body
end
% other stuff
end
You are calling cardiod1 but not saving/storing any of the output parameters, one of which is your xt. So when the code in the other stuff section tries to access xt you get the expected error of undefined function or variable 'xt'. Since you are trying to make use of this output parameter, then you should change the above to
function [ X ] = faces( d,hc )
[x,y,xt,yt,th] = cardioid1;
function [x,y,xt,yt,th] = cardioid1(bs,s)
% body of caridioid1
end
% other stuff
end
so that you can get to all output parameters of the function.
I think that you have misunderstood the idea of nested functions. If function B is nested within function A, then B has access to the local variables of A. This doesn't work in the other direction which is what you are attempting (to have the local variables of the nested cardioid1 function be accessible to the "parent" faces function).
4 Commenti
Geoff Hayes
il 2 Giu 2016
For your last comment, you need to clarify what you mean by but for me does not work as well. What is happening? What are you expecting to happen?
As for the error message that indicates
"Output argument "y" (and maybe others) not assigned during call to "cardioid1""
look at your function signature
function [x,y,xt,yt,th] = cardioid1(bs,s)
If you exit this function before the x, y, xt, yt, and th have been defined, then you will observe this error message. (This may be due to the return that you have.) What you can do is just assign each a default value - whether this is zero or an empty matrix is entirely up to you. For example,
function [x,y,xt,yt,th] = cardioid1(bs,s)
x = [];
y = [];
xt = [];
yt = [];
theta = [];
% now follow with your code for this function
Vedere anche
Categorie
Scopri di più su Geometry and Mesh in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!