Related
I am using the matlab to solve a simple model in economics. But I came across an error
Function 'subsindex' is not defined for values of class 'struct'
when I run the last line of code.
omega=mkt_share(Par,w,Grid);
It appears wired to me as I call this function repeatedly in the code before reaching the last line, it works fine. Could anyone inform me how to solve the problem? Thanks!
I post the full code of my program as following
clear all
Par.theta = 1.5;
Par.gamma = 6;
Par.beta = 0.1;
Par.zeta = 15;
Par.n = 100;
Grid.q = sort( gprnd(1/Par.zeta,1/Par.zeta,1,Par.n,1));
Grid.q = Grid.q./Grid.q(1);
w0=0.0001;
We0=tot_mkt_share(Par,w0,Grid);
mkt_share=mkt_share(Par,w0,Grid);
w1=0.01;
We1=tot_mkt_share(Par,w1,Grid);
while(We0*We1>0)
if We0<0
w0=w0*0.5;
We0=tot_mkt_share(Par,w0,Grid);
end
if We1>0
w1=w1*1.5;
We1=tot_mkt_share(Par,w1,Grid);
end
end
iconv2=0;
tol2=0.0000001;
maxit2=1000;
it2=1;
while(iconv2==0 && it2<=maxit2)
w=(w0+w1)/2;
We=tot_mkt_share(Par,w,Grid);
if abs(We)<tol2
iconv2=1;
disp('wage has converged in')
it2
else
if We*We1>0
w1=w;
else
w0=w;
end
it2=it2+1;
end
end
if it2>=maxit2
disp('Warning: Zero profit condition not satisfied')
end
omega=mkt_share(Par,w,Grid);
The code for function mkt_share
function omega=mkt_share(Par,w0,Grid)
omega=w0;
for i=2:Par.n
rel_q=Grid.q(i);
fcn=#(omega) (rel_q)^(-Par.gamma)*(omega/w0)^(1-Par.beta*Par.gamma)*((1-
((1-w0)/Par.gamma+w0/Par.theta))/(1-
((1omega)/Par.gamma+omega/Par.theta)))^(Par.gamma-1)-1;
omega_i=fsolve(fcn,w0);
omega=[omega',omega_i]';
end
The code for function tot_mkt_share, which calls function mkt_share
function tot_mkt_share=tot_mkt_share(Par,w0,Grid)
tot_mkt_share=sum(mkt_share(Par,w0,Grid))-1;
When you do:
mkt_share=mkt_share(Par,w0,Grid);
you create a variable with the same name as the function. From this point on, the function is no longer accessible, it is shadowed. The last line attempts to index into this variable, rather than call the function as you intend, because the function is shadowed.
I have these lines of code:
someFunction
disp('This should not be executed, if condition in someFunction is
true')
function someFunction
if condition
% what do I have to write here so the disp command is not executed?
% return does not do it. I don't want to throw an error. quit/exit
% are also not what I want..
end
What statement do I need in the if condition block so the disp statement is not executed if condition is true? error('some error') would do it. But I don't want to throw an error.
May be I do not get the question properly, by I'd recommend an approach used in device interfacing in C. Let us suggest we have a function that calls some other functions which communicate to a device and return int value: deviceOk (usually 0) or error code. If any internal function fails, we should terminate the calling function and go to resource management. The resulting function is full of checks, nested or sequential.
function isOk = mainFcn()
isOk = false;
% awaiting a bad result is better if we suppose a crash or exception somewhere inside, but wan a clean exit
[isOk , result] = someFcn(input);
if (~isOk)
disp('If everything was OK, I'd never see this message');
end
end
function [isOk, result] = someFcn(input)
isOk = false; %preallocate inputs to error and modify only if really needed
result = Nan;
if isnan(result)
return;
end
end
I'm working with someone else's code and I am unfamiliar with try/catch so I made a small, similar example. On line 11, if I write error(''), it doesn't seem to catch the error and increase the index j. However, writing error(' ') or error('bad!') does.
So does having an error with an empty string ignore the error, or am I doing something wrong?
% Just a file to understand the Matlab command try/catch
M = 3;
j = 1;
k = [Inf, 5, 4];
while M>0
try
M = M-1
u = k(j)
if (isinf(u)||isnan(u)), error(''), end;
catch
j = j+1
end
end
Yes, error('') and error([]) and error(struct([])) all do not actually display an error message and abort running code. I personally consider the use of the single string argument version of error to be bad practice in any real code. You should use always use both a 'MSGID' and a 'ERRMSG' when writing errors for your functions, e.g.
error('FunctionName:SubFunctionName:ErrorMSGID','Error message to be printed.')
Alternatively, you can use MException objects in conjuction with throw, rethrow, and throwAsCaller, which allow you to reuse error information. More here.
It is odd, but it's in the documentation for error, for the error('msgString') syntax:
All string input arguments must be enclosed in single quotation marks. If msgString is an empty string, the error command has no effect.
Similarly, if using the error(msgStruct) syntax:
If msgStruct is an empty structure, no action is taken and error returns without exiting the function.
if you have a look to the try documentation you can have an example.
Else want you want for your code it :
M = 3;
j = 1;
k = [Inf, 5, 4];
while M>0
try
M = M-1
u = k(j)
if (isinf(u)||isnan(u)), error(''), end;
catch
disp('I catch an error!');
j = j+1
end
end
Because If you never get an error in your code, it will never go in the catch. So by including error('');, it just to say, go execute the statement in the catch.
But you can just modify your code by replacing the error() by the statements into your catch like this :
while M>0
M = M-1
u = k(j)
if (isinf(u)||isnan(u)), j = j+1, end;
end
EDIT
If you take a look in the documentation, you can found this :
% ERROR(MSGSTRUCT) reports the error using fields stored in the scalar
% structure MSGSTRUCT. This structure can contain these fields:
%
% message - Error message string
% identifier - See MESSAGE IDENTIFIERS, below
% stack - Struct similar to the output of the DBSTACK function
%
% If MSGSTRUCT is an empty structure, no action is taken and ERROR
% returns without exiting the program. If you do not specify the
% stack, the ERROR function determines it from the current file and line.
So no action is taken as you can read. And nothing, so catch don't get any informations.
Not sure why you need it, but here is how it works.
error function does not throw an error with empty string or empty vector ([]) as an argument.
If you don't specify argument at all the error function itself generates the error "Not enough arguments". So it will go to catch.
Another way is to specify an empty structure as an argument.
s = struct();
error(s)
In this case, the error will be generated, but the code will not stop and in general flow you will hear no beep. In your case it should go to catch.
Here is my code:
function [im,sindx,end1]=alln(im,i,j,secret,sindx,end1)
slen=length(secret);
p=im(i,j);
neigh= [im(i-1,j) im(i+1,j) im(i,j-1) im(i,j+1) im(i-1,j-1) im(i+1,j-1) im(i-1,j+1) im(i+1,j+1)];
minpix = min (neigh)
maxpix = max (neigh)
if minpix < p < maxpix
lowlim = minpix+1;
highlim = maxpix-1;
range = highlim-lowlim+1;
nbits=floor(log2(abs(range)));
if sindx+nbits-1>slen
end1=1;
return
end
for k=1:nbits
bin(k)=secret(sindx+k-1);
end
b = bin2dec(bin);
newvalue1 = abs (minpix + b);
newvalue2 = abs (maxpix - b);
if abs(p-newvalue1)<= abs(p-newvalue2)
im(i,j) = newvalue1;
else
im(i,j) = newvalue2;
end
sindx=sindx+nbits;
end
end
My main program calls this function. When I run the program, I get the following error message:
??? Undefined function or variable "bin".
Error in ==> alln at 34
b = bin2dec(bin);
I know there are many experts for whom this is not a problem at all. I am new to MATLAB. Please guys, show me the way, which type of modification in the code can overcome this problem?
First of all, are there some lines missing from the file? Perhaps you've stripped some comments from the top? Because the error message says that
b = bin2dec(bin);
is line 34, but it's line 22 in the code you present.
OK, that aside...
The error message says that 'bin' isn't defined, but I see that it's being set on the line...
bin(k)=secret(sindx+k-1);
That suggests to me that THAT line isn't being run.
I see that that bin = ... line is inside of a 'for' loop, so I suspect that the for loop is run zero times, meaning that 'bin' never gets defined. What is nbits? Is it 1, or perhaps less than 1? THAT would prevent the loop from running at all.
Try removing the semicolon from the end of the
nbits=floor(log2(abs(range)));
line and run your code again.
Leaving off the semicolon will force the value of nbits to be printed in the Command Window. I bet you'll find that it's 1 or less. If that's the case, then start looking at HOW nbits is calculated, and I bet you'll find the problem.
At what input arguments to the function alln, are you getting the error?
Lets suppose that nbits is 0, then the following loop will not run:
for k=1:nbits
bin(k)=secret(sindx+k-1);
end
So, bin will be undefined. So, the error happens. This is one of the cases where the error can happen. There are many such possible cases.
In some of my functions I want to convert some warnings into errors. For example, if I want to throw an error when str2func yields a MATLAB:str2func:invalidFunctionName warning, I would do the following:
invalid_func_id = 'MATLAB:str2func:invalidFunctionName';
%hide warning of interest
warning('off', invalid_func_id);
%this might yield the warning of interest
predicate_func_try = str2func(predicate_func);
[~, warn_id] = lastwarn;
assert(~strcmp(warn_id, invalid_func_id)...
, 'MyFunc:InvalidFunctionName'...
, 'The predicate function %s does not have a valid name'...
, predicate_func...
);
warning on all
This works fine if I know that a particular block of code can give a small set of warnings. However it is verbose and probably doesn't scale to larger code blocks. Is there a better way of doing this? Ideally I would want a function which can turn certain warnings to errors in a whole block. It would allow me to modify my example to:
warnings2errors('MATLAB:str2func:invalidFunctionName');
predicate_func_try = str2func(predicate_func);
warnings2errors('off');
Another method would be to overload warning itself. See implementation of warning.m and warning2error.m below. The biggest side effect I see from this is that you will see an extra "warning.m" displayed on the stack for all warning messages. Not sure if there's a way around that. Also, you would need to disable the MATLAB:dispatcher:nameConflict warning since we're overloading a builtin.
EDIT: Just noticed on matlabcentral.com an undocumented use of the builtin warning that accomplishes this:
http://www.mathworks.com/matlabcentral/newsreader/view_thread/158768
http://undocumentedmatlab.com/blog/trapping-warnings-efficiently/
>> warning('error','MATLAB:str2func:invalidFunctionName')
USAGE FROM COMMAND LINE
warning2error('add','MATLAB:str2func:invalidFunctionName')
Warning.m:
% Overload of warning.m to enable conversion of certain warnings to errors
% via warning2error.m
%
% Will want to disable warning "MATLAB:dispatcher:nameConflict" via command
% warning('off','MATLAB:dispatcher:nameConflict');
%
% Jesse Hopkins
% Oct. 2 2012
function varargout = warning(varargin)
%check for component:mnemonic syntax
if nargin >= 2 && ischar(varargin{1}) && any(regexp(varargin{1},'^(\w+:\w+){1,}$','start','once'))
%we've captured <component>[:<component>]:<mnemonic>syntax
%check if this is in the list
if warning2error('query',varargin{1})
%YES, convert to error
ME = MException(varargin{1},varargin{2:end});
ME = ME.addCause(MException('Warning2Error:ConvertedWarning','Converted warning "%s" to error becuase it was registered via warning2error.m.',varargin{1}));
ME.throwAsCaller;
end
end
%pass through to built-in warning
varargout{1:nargout} = builtin('warning',varargin{:});
end
Warning2Error.m:
%warning2error.m
%USAGE:
% Add warnings to convert to errors.
% warning2error('add','<component>[:<component>]:<mnemonic>',...
%
% Remove warnings to convert to errors
% warning2error('remove','<component>[:<component>]:<mnemonic>',...
%
% Query warnings to convert to errors
% tf = warning2error('query','<component>[:<component>]:<mnemonic>')
%
% Get entire list of warnings converted to errors
% list = warning2error('get')
%
% Jesse Hopkins
% Oct 2 2012
function varargout = warning2error(op,varargin)
persistent list;
if isempty(list)
list = {};
end
varargout={};
switch lower(op)
case 'add'
list = unique([list(:);varargin(:)]);
case 'remove'
for i = 1:length(varargin)
[tf idx] = ismember(varargin{i},list);
allidx = 1:length(list);
newidx = setdiff(allidx,idx);
list = list(newidx);
end
case 'clear'
list = {};
case 'get'
varargout{1} = list;
case 'query'
out = false(1,length(varargin));
for i = 1:length(varargin)
out(i) = ismember(varargin{1},list);
end
varargout{1} = out;
end
end
I'm not aware of a clean way to do exactly what you want. Depending on your reason for wanting to turn errors into warnings, you may be able to get by with:
dbstop if warning
or
dbstop if warning MyFunc:InvalidFunctionName
You can also look at warning on stacktrace, to get more infomrat6ion on warnings as they appear.
If you need an actual error message (not just a way to break into the debugger) then I'm actually pretty impressed with the method you included in the question.
It was mentioned as an edit by jHops, but this technique is so simple, it deserves its own concise answer.
As (un)documented in https://undocumentedmatlab.com/articles/trapping-warnings-efficiently, to turn warnings to errors, simply do
s = warning('error', 'MATLAB:nearlySingularMatrix');
where the second string is the warning ID itself. It can be found by warning on verbose in cmdline, and inspecting the warning message. In my experience, it can be further debugged by turning on dbstop if error; dbstop if warning; dbstop if naninf, depending on your issue.
This is a full example for inverting a matrix and checking if it's singular. The last line turns the warning-errors back to regular warnings. s can be either a single warning state as above, or an array.
s = [warning('error', 'MATLAB:nearlySingularMatrix'), warning('error', 'MATLAB:singularMatrix')];
try
Minv = inv(Mat);
InvertFail = false;
catch
InvertFail = true;
return;
end
warning(s);
I found a way to generalise this somewhat. It works the following way (similar to tic and toc):
warn_ids = setwarnings2errors('MATLAB:str2func:invalidFunctionName');
predicate_func_try = str2func(predicate_func);
getwarnings2errors(warn_ids);
Between setwarnings2errors and getwarnings2errors, all warnings set will throw an error if they are the last warning thrown. Therefore it shouldn't be used in large blocks where many different warnings can happen. I implemented the functions the following way:
setwarnings2errors:
function warning_ids = setwarnings2errors(varargin)
warning_ids = cell(nargin, 1);
for x_ = 1:nargin
local_arg = varargin{x_};
assert(ischar(local_arg));
evalin('caller', sprintf('warning off %s', local_arg));
warning_ids{x_} = local_arg;
end
end
getwarnings2errors:
function getwarnings2errors(warning_ids)
[lastwarn_str, lastwarn_id] = evalin('caller', 'lastwarn');
num_warns = numel(warning_ids);
try
for x_ = 1:num_warns
local_warn = warning_ids{x_};
assert(~strcmp(local_warn, lastwarn_id)...
, lastwarn_id...
, lastwarn_str...
);
end
catch m_e
evalin('caller', 'warning on all');
throwAsCaller(m_e);
end
evalin('caller', 'warning on all');
end