use structure in matlab - matlab

I want to use structure in matlab but in first iteration it's run correctly and in other iteration give that message .
1x2 struct array with fields:
my code is :
for i=1:lenfd
currow=rees(i,:)
maxcn=max(currow)
if maxcn~=0
maxin=find(currow==maxcn)
ress(i).x =maxin
end
end
thank you.

That message is not a warning or error. That's just MATLAB printing the output of an operation. And it does that by default, unless you suppress it by appending a semicolon to the command:
for ii = 1:lenfd
currow = rees(ii,:); % <=== NOTE: semicolons at the end
maxcn = max(currow);
if maxcn ~= 0
ress(ii).x = find(currow==maxcn);
end
end
Note that max() may have 2 outputs, the second output being the first index into the array where the maximum occurred. If you know beforehand that any maximum will occur only once, you can skip the call to find() and use the second output of max().

Related

How to fix error: "A(I): index out of bounds; value 1 out of bound 0"

So I made this function, but I don't know why I'm getting this error. How can I fix it?
error: LOADC: A(I): index out of bounds; value 1 out of bound 0
error: called from
LOADC at line 15 column 13
function res=LOADC(url)
[nomeFicheiro,sucesso]= urlwrite(url,'Composicoes.txt');
ficheiro=fopen(nomeFicheiro,'r');
fgetl(ficheiro);
nLinhas=0;
while (fgets(ficheiro) ~= -1)
nLinhas = nLinhas+1;
end
for i=2:nLinhas
linha=fgetl(ficheiro);
pontovirgula=findstr(linha,';');
Material=linha(1:pontovirgula(1)-1);
for n=1:2:length(pontovirgula)
ElemX=linha(pontovirgula(n)+1:pontovirgula(n+1)-1);
PercentX=linha(pontovirgula(n+1)+1:pontovirgula(n+2)-1);
end
end
fclose(ficheiro);
res=Composicoes;
end
The immediate is you're trying to access a value within an empty array (which has no values in it).
The reason that this is happening is that you read your entire file inside of your first while loop which places the file pointer at the end of the file. Then (without resetting the file pointer), you try to read it line by line in the for loop. Since the file pointer is at the end of the file already, fgetl will always return an empty array ([]) so when you start trying to work with it, you get the indexing error that you've shown.
The solution is one of two options:
Call frewind(ficheiro) before the for loop to reset the file pointer to the beginning of the file so that you can successfully read each line.
Come up with a better way to parse your file rather than looping through the whole file for the sole purpose of counting the number of lines in the file.
If you post some of the file contents we can likely provide you with a better way to parse the file in one or two lines of code.
Update
Also if you look at this line, n goes all the way to the end of pontovirgula.
for n = 1:2:length(pontovirgula)
But then you try to access 1 and 2 past the end of the array
pontovirgula(n+1)
pontovirgula(n+2)
This is going to cause issues for sure. Try only looping until 2 from the end instead.
for n = 1:2:(numel(pontovirgula) - 2)
Update 2
Given that you have posted the file contents, here is an alternate way to parse the file.
fid = fopen('filename.txt', 'rt');
lines = textscan(fid, '%s', 'HeaderLines', 1);
fclose(fid);
% For each line we want to get the reference off of the front
parts = regexp(lines{1}, ';', 'split');
materials = cell(1, numel(parts));
elements = cell(1, numel(parts));
percentages = cell(1, numel(parts));
for k = 1:numel(parts)
% Remove the last empty blank
parts{k}(end) = [];
% Get the material (the first element)
materials{k} = parts{k}{1};
% Get the elements
elements{k} = parts{k}(2:2:end);
% Get the percents
percents{k} = parts{k}(3:2:end);
end
Check the length of linha, and the values of pontovirgula that you are using to index into linha.

MatLab function, variable output

function [ muln, varargout ] = my_mul( varargin )
%MY_MUL This function is used to multiply numbers.
% My_mul function multiplies array of entered numbers, and outputs single
% solution.
% For example: my_mul(12, 2, 3, 5) gives ans = 360
if nargout >=1
disp('Error, wrong number of output arguments');
varargout{1} = 0;
return
end
if nargin <= 1
disp('Error, small number of input argumnets');
return
else
muln = 1;
for i = 1:nargin
muln = muln*varargin{i};
end
end
end
Hi, everyone, I'm just doing my assignment for uni and have a qiuck question.
How can I make this function to give an error if it is called with more than one output.(It meant to give only one) Thanks!
In your function definition, you have defined your function to allow for an unlimited number of outputs. The keyword varargout is a place-holder for a variable number of outputs.
As you have stated in your question, you only want one possible output which in your case looks to be muln. So if you simply remove varargout from your function definition, MATLAB should automatically throw an error if too many outputs are requested
function muln = my_mul(varargin)
If you ever do need to use varargout but want to place constraints on how many outputs are provided for any given scenario, you can check the number of output arguments that were requested using nargout and then throw an error with the error function.
if nargout > 4
error('my_mul:TooManyOutputs', 'Too many outputs requested');
end
My opinion is that if a return value is expected the function needs to throw. Otherwise the caller (function calling this function) will expect everything to be ok. Note that disp('Error') gives information to the developer, but it does not give the program any indication on what happens. More importantly, the information does not give any indication of where the error occurs. This can force the developer to do heavy debugging just to find the error, which is completely unnecessary.
The use of variable output arguments should only be used in case a different number of output arguments should be expected. An example is some customized plot function
function varargout = myplot(varargin)
filename = '';
idx = find(strcmp(varargin,'filename'));
if (~isempty(idx) && length(varargin)<idx+1 && ~ischar(varargin{idx+1}))
error('filename property must be followed by a directory');
elseif(~isempty(idx))
filename = varargin{idx+1};
varargin([idx,idx+1]) = [];
end
h = plot(varargin{:});
varagout{1} = h;
if (~isempty(idx))
save(filename, h);
end
varagout{2} = filename;
This function works as plot except it saves the figure to file in case a filename is specified. In case the developer needs the handle it will be returned and in case the developer wants the save directory it can be returned as well. None of these arguments are necessary though. The developer may want to use this function as a standard plot function and this means that the user may want to call myplot as myplot(x,y);which does not return a value. Further note that even if 'filename' is not specified, the function can still return 2 outputs. The second output may be an empty array of char, but two outputs for the caller will never cause a crash.
Also, note that no further error handling is required. The only unchecked crashes are in plot and save. How this is handled may be different for different users and this means that it only is reasonable to let the user catch the error and handle it (as he would have done if save or plot would have thrown).
Apart from this you may also want to have a check so that the number of output variables are within the correct range (in this case 0,1 or 2 outputs).

how to compare values of an array with a single value in matlab

Can anyone tell me how to compare this for loop array value pp1 with the single value of pp. If the value of pp is present in pp1 then it must show 1 or must show 0. I'm getting 1 only the last value of pp1. The code is:
[pp,pf1]=pitchauto(x,fs);
for ix=1:2
V='.wav';
ie=num2str(ix);
Stc=strcat(ie,V);
[x1,fs1]=wavread(Stc);
figure,plot(x1);
title('Test Audio');
[pp1,pf1]=pitchauto(x1,fs1);
end
if (pp==pp1)
msgbox('Matching');
else
msgbox('Not Matching');
end
Kindly do reply with the correct answers.
You calculate a value for pp1 each time, do nothing with it, then let the next loop iteration overwrite it. To make use of it, either put the test inside the loop:
for ix=1:2
V='.wav';
ie=num2str(ix);
Stc=strcat(ie,V);
[x1,fs1]=wavread(Stc);
figure,plot(x1);
title('Test Audio');
[pp1,pf1]=pitchauto(x1,fs1);
if (pp==pp1)
msgbox('Matching', num2str(ix)); % show the index number as msgbox title
else
msgbox('Not Matching', num2str(ix));
end
end
or collect the values of pp1 in an array to test afterwards:
for ix=1:2
V='.wav';
ie=num2str(ix);
Stc=strcat(ie,V);
[x1,fs1]=wavread(Stc);
figure,plot(x1);
title('Test Audio');
[pp1(ix),pf1]=pitchauto(x1,fs1); % assuming pitchauto returns a scalar
end
matchidx = (pp == pp1);
if any(matchidx)
msgbox(strcat('Matching indices: ', num2str(find(matchidx))));
else
msgbox('Not Matching');
end
If the values aren't scalar, then this approach is a bit more difficult - you could still use a matrix to collect equal-sized vectors, or a cell array to collect anything - but it's probably easier to stick with the first approach in that case.

Removing specific elements from matrix

I want to remove a (*) asterisk from my matrix and write out that matrix to a text file and the remaining elements will be concatenated to each other without a space or any kind of delimiters. I wrote this code
for b = 1 : length(out7num_r7_nt_back)
if ~(out7num_r7_nt_back(b) == '*')
out7num_r7_back(b) = '';
end
end
disp(out7num_r7_nt_back);
dlmwrite('my_data.txt',out7num_r7_nt_back, '');
I got this error message:
??? Index of element to remove exceeds matrix dimensions.
You can use a vectorized boolean index, replacing the loop as follows:
out7num_r7_nt_back = out7num_r7_nt_back(out7num_r7_nt_back(b) ~= '*');
That should be much faster as well.
Value of upper bound of for loop (length(out7num_r7_nt_back)) gets evaluated only once!
Say you have '*ab' in a variable. Loop will count to 3 (length of variable). Inside the loop when program erases '*', you'll get 'ab' which is of length 2. Since loop is iterating to 3, program will try to access out7num_r7_nt_back(3) which is out of bounds.
You could remove characters while going backwards:
...
for b = length(out7num_r7_nt_back) : -1 : 1
...
But you should prefer vectorized approach because it's faster and cleaner to write.

How to write a function that does not throw a "wrong number of arguments" error

I am trying to write a minimal function that can be called with a variable number of arguments but that will not throw a wrong number of arguments error if miscalled.
Here is where I start from :
function varargout=fname(varargin)
% FNAME
% Usage: output=fname(input)
% Arguments check
if(nargin~=1 || nargout~=1)
disp('Function fname requires one input argument');
disp('and one output argument');
disp('Try `help fname`');
varargout(1:nargout)={0};
return;
end
input=varargin{1};
output=input;
varargout(1)={output};
end
However this does not work as I would like it to. Is there a way to write a function that :
never throw a "wrong number of arguments" error (so that the rest of the execution can continue)
accepts variable number of input and output arguments and checks them inside the function
(maybe more tricky) if the number of input / output arguments is not correct, does not replace the value of the provided output arguments (so that any misplaced call does not erase the previous value of the output argument)
I am open to any suggestions / other methods.
Thank you for your help.
UPDATE: thanks to #Amro for his answer, I guess what I miss here is either a call by address of reference for Matlab functions or a way to interrupt a function without returning anything and without stopping the rest of the execution.
Here is one way to implement your function:
function varargout = fname(input,varargin)
%# FNAME
%# Usage: output=fname(input)
%%# INPUT
if nargin<1
varargout(1:nargout) = {[]};
warning('Not enough input arguments.'), return
end
if ~isempty(varargin)
warning('Too many input arguments.')
end
%%# YOUR CODE: manipulate input, and compute output
output = input;
%%# OUTPUT
varargout{1} = output;
if nargout>1
warning('Too many output arguments.')
varargout(2:nargout) = {[]};
end
end
Obviously you can customize the warning messages to your liking...
Also, if you want your function to simply print the message instead of issuing warnings, replace all WARNING calls with simple DISP function calls.
Examples of function call:
fname()
fname(1)
fname(1,2)
x = fname()
x = fname(1)
x = fname(1,2)
[x,y] = fname()
[x,y] = fname(1)
[x,y] = fname(1,2)
The above calls execute as expected (showing warning messages when applicable). One caveat though, in the last three calls, if the variable y already existed in the workspace prior to the calls, it would be overwritten by the empty value y=[] in each...
If I understand your question correctly, then the answer is no. If a caller calls a function like this:
[a, b, c] = fname('foo');
then fname is required to return (at least) three outputs. There's no way to tell MATLAB that it should leave b and c alone if fname only returns one output.