CODE ASSISTANCE
3 views (last 30 days)
Show older comments
Hi, I have the following code ,but it gives an error. The code is :
function lambda = drive_zr17t9(p)
format short e;
load saved_data;
theta = pi/2;
zeta = cos(theta);
I = eye(n,n);
Q = zeta*I-p*p';
%T is a matrix(5,5)
Mroot = M.^(1/2); %optimization
T = Mroot*Q*Mroot;
%find the eigen values
E = eig(T);
%find the negative eigen values -- this section still needs to be fixed
ind = find(E<0);
G = E(ind);
%find the smallest negative eigen value
gamma = min(abs(G)); %this is almost certainly wrong!
%now solve for lambda
bounds = sort([0, -1/gamma]); %in case gamma is positive
Minv = inv(M); %optimization
lambda = fzero(@(lambda) zr17t9(lambda, Minv, Q, zm), bounds); %do the searching
end
function r = zr17t9(lambda, Minv, Q, zm)
Winv = inv(mInv+lambda.*Q);
r = -ctranspose(zm)*Minv*Winv*Q*Winv*Minv*zm;
end
_*The error is :
??? Error using ==> fzero
FZERO cannot continue because user supplied function_handle ==> @(lambda) zr17t9(lambda, Minv, Q, zm)
failed with the error below.
Variable 'zm' is used as a command function.
Error in ==> drive_zr17t901 at 21
lambda = fzero(@(lambda) zr17t9(lambda, Minv, Q, zm), bounds); %do the searching
_*
0 Comments
Accepted Answer
Walter Roberson
on 28 Nov 2011
Remove the final "end" statement from drive_zr17t9 and the code would likely start working.
This is a side effect of "poofing variables into existence" through a load() statement.
Matt's approach is a better one over the long term.
[Addition: code with Matt's suggested changes]
[Code modified to reflect the fact p is in the .mat file after all]
[Code modified: Minv -> M_inv]
function lambda = drive_zr17t9
format short e;
Params = load('saved_data.mat');
theta = pi/2;
zeta = cos(theta);
I = eye(Params.n,Params.n);
Q = zeta*I-Params.p*Params.p';
%T is a matrix(5,5)
Mroot = Params.M.^(1/2); %optimization
T = Mroot*Q*Mroot;
%find the eigen values
E = eig(T);
%find the negative eigen values -- this section still needs to be fixed
ind = find(E<0);
G = E(ind);
%find the smallest negative eigen value
gamma = min(abs(G)); %this is almost certainly wrong!
%now solve for lambda
bounds = sort([0, -1/gamma]); %in case gamma is positive
M_inv = inv(Params.M); %optimization
lambda = fzero(@(lambda) zr17t9(lambda, M_inv, Q, Params.zm), bounds); %do the searching
end
function r = zr17t9(lambda, M_inv, Q, zm)
Winv = inv(M_inv+lambda.*Q);
r = -zm'*M_inv*Winv*Q*Winv*M_inv*zm;
end
17 Comments
Walter Roberson
on 29 Nov 2011
You cannot "execute" M_inv . M_inv is a variable that is defined within the code, based upon previous variables defined in the code.
You can put a breakpoint in at the M_inv line and run to there, and step and examine the value of M_inv . You cannot execute the line out of context.
More Answers (1)
Matt Tearle
on 28 Nov 2011
I'm guessing it's a name conflict issue caused by your load command. Is zm loaded by the command load saved_data;? If so, do
params = load('saved_data');
...
... zr17t9(lambda, Minv, Q, params.zm) ...
instead, and similarly for any other variables loaded from saved_data. (If not, how the heck is zm defined?)
Also: %this is almost certainly wrong! is a fantastic comment :)
EDIT TO ADD An attempt at explaining what's happening here. (Note: technical details are probably not exactly correct, but close enough.) As you know, MATLAB is an interpreted language, but when code is executed, it isn't all interpreted on the fly -- there's some "pre-interpretation" where MATLAB parses, checks, optimizes, caches, and good stuff like that. When it sees x = foo, it has to resolve what x and foo mean. They could be variables, they could be function calls. The assignment x = tells MATLAB that x is going to be a variable. But if there's no foo = earlier in the code, then foo had better be a function call, otherwise you're going to get the infamous "undefined function or variable" error.
OK, so now look at your code. Nowhere is zm defined, as far as MATLAB can tell. Functions maintain their own private workspaces, so zm can't be magically inherited -- if it isn't explicitly passed in as an input, it doesn't exist. Hence, this, as far as MATLAB is concerned, is a function call. But then, you zap a variable called zm into existence with the load command. This causes a major headache for MATLAB. What does zm mean?
The solution is: don't zap variables into existence with load inside functions. If you want to load variables from a MAT-file, use the functional form: x = load('filename'). This creates a structure variable x, with fieldnames defined by the variables in the MAT-file. Hence, if filename.mat contains x, y, and foo, then you will now have a structure x with fields x, y, and foo, which you can reference with structure/dot notation: x.x, x.y, and x.foo.
(Note that the assignment x = load(...) means that MATLAB knows that x will be a variable, so the name conflict issue goes away.)
Bottom line: In your code, you appear to be relying on variables n, M, and zm being created by the load. So replace those with params.n, params.M, and params.zm, respectively.
5 Comments
See Also
Categories
Find more on File Operations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!