Array addition error - matlab

I wrote the following code for convolution in Matlab, but it gives me errors at notified lines. I am a beginner in Matlab so please bear with me answering this question.
function [y] = UmerConv(x,h)
xlen=length(x);
hlen=length(h);
p=1;
for j=1:xlen
for k=1:hlen
uinput{p}=x(j)*h(k);
p=p+1;
end
end
for i=1:hlen
if(i==1 || i==hlen)
y{i}=uinput(i); // error
else
y{i}=uinput(i)+uinput(i+2); // error
end
end
Thanks

You assign values into uinput with cell array syntax {}, but then later you index them with regular array syntax with uinput(i). You have to keep it consistent. Using the curly braces {} makes the array a cell array, which is indexed differently than a regular array (which uses just parentheses).
You then also make the same assignment choice with the variable y, using the cell array syntax when it seems you'll probably want just regular array syntax.
The corrected code should probably be:
function [y] = UmerConv(x,h)
xlen=length(x);
hlen=length(h);
p=1;
for j=1:xlen
for k=1:hlen
uinput(p) = x(j)*h(k); % <-- Changed the {} syntax
p=p+1;
end
end
for i=1:hlen
if(i==1 || i==hlen)
y(i) = uinput(i); % <-- Now you access both with () instead of {}
else
y(i) = uinput(i) + uinput(i+2); % <-- Same here.
end
end
At each place where I noted a correction in a comment, you could alternately stick with solely the {} syntax, and then everything will work but the arrays will be cell arrays. Usually this is not desired for a such a numerical computation.

You should use y(i) instead that y{i} to access the i-th position of a vector.

Related

make iterative variable a cell array in matlab

In matlab, is it possible to make the iterative variable a cell array? is there a workaround? This is the code I ideally want, but throws errors:
dim={};
a=magic(5);
for dim{1}=1:5
for dim{2}=1:5
a(dim{:})=1; %aimed to be equivalent to a(dim{1},dim{2})=1;
end
end
for dim{1}=1:5
↑
Error: Invalid expression. When calling a function or indexing a variable, use
parentheses. Otherwise, check for mismatched delimiters.
I tested that you cannot have A(1), or A{1} or A.x as index variable. https://www.mathworks.com/help/matlab/ref/for.html doesn't explicitly prohibit that, but it doesn't allow it either.
After very slight changes on your code, this should achieve what you seem to want:
dim={};
a = magic(5);
for dim1=1:5
dim{1} = dim1;
for dim2=1:5
dim{2} = dim2;
a(dim{:})=1; %aimed to be equivalent to a(dim{1},dim{2})=1;
end
end
However, I believe the following is a slightly better solution keeping the spirit of "use a cell array to index in your array":
CV = combvec(1:5,1:5); % get all combinations from (1,1) to (5,5). 2x25 double array. This function is a part of deep learning toolbox. Alternatives are available.
CM = num2cell(CV); % 2x25 cell array. Each element is a single number.
for dim = CM
% dim is a 2x1 cell array, eg {2,3}.
a(dim{:}) = 1; % as above.
end
However, none of these are likely a good solution to the underlying problem.

can a matlab function detect if it has been called with semicolon [duplicate]

In a Matlab script I call a user-defined function (m-function). My function returns a value while printing the value to the command window using disp and/or fprintf calls.
When writing an expression or a statement, one puts ; at its end to suppress printing. When the expression calls my function, the ; can suppress the printing of the returned value. However, this does not effect the disp output from within the function called.
I want to eliminate the display output of the function when appropriate. Is there a way to determine whether a function call was made in an expression ending with ;?
I like the spirit of what you're trying to do, but I think that it probably goes against the common programming patterns in Matlab. As you correctly state, the purpose of the terminating semicolon is to supress printing of returned values. Trying to get it to incorporate your other feature might well require some deep hacking and ugly hard-to-maintain code. The standard way to implement what you describe is via property name-value pair arguments. For example, Matlab's optimization suite has a property called 'Display' that can be set to various values to indicate the desired level of verbosity (see optimset).
If you want to try looking for a way to check for terminating semicolons, you might look into the undocumented mint, mlintmex, and mtree functions – read more here. Unfortunately, using mlint to simply check for the "Terminate statement with semicolon to suppress output" warning (see this function on the MatlabCental File Exchange) won't work in all cases as a function call by itself doesn't produce this warning.
Update
Here's an attempt at code that could be inserted into a called function to determine if the line of the caller is terminated by a semicolon. You should be aware that this has not been thoroughly tested and is likely very fragile. I have not tested it with sub-functions or anonymous functions and I know that it fails if you wrap a line over multiple lines using ....
st = dbstack('-completenames'); % M-file of caller and line number
caller = st(2);
str = mlint('-lex',caller.file); % Struct containing parsed data
isSemicolon = false; % Assume no semicolon
for i = 1:length(str)
% Find end-of-line corresponding to function call
c = strsplit(str(i).message,'/');
if str2double(c{1}) == caller.line && strcmp(c{2}(end-5:end-1),'<EOL>')
% Check for comments
j = i-1;
if ~isempty(strfind(str(j).message,'%'))
j = j-1;
end
% Check for semicolon
if strcmp(str(j).message(end-2),';')
isSemicolon = true; % Semicolon found
break;
end
end
end
In other words, play around with this to learn, but I would not recommend actually using it.
I'm afraid that the answer to your question is no. That information is simply not passed on to the function being called.
You shouldn't think about adding the semicolon as a means to "suppress printing", but rather that the lack of a semicolon instructs MATLAB to call the display function on the output variables of the function call. In other words, MATLAB interprets this code:
y = myFunc(x)
as:
y = myFunc(x);
display(y);
I think adding a 'print' or 'verbose' parameter to your function is your best bet for achieving what you want.
I think the simplest method to achieve the results you want (i.e. whether or not disp's get displayed) is to add an extra function input or output. For example, adding an input (optional, you can set default behaviour):
function y=myFunc(a,displayResults)
if nargin==1
displayResults=true; %// set the default behaviour
end
%// if you want to print something
if displayResults
disp(a)
end
end
Or an extra output. In this case foo produces no output to the screen, but all the messages are saved into a cell array, which can be accessed if desired:
function [x,m] = foo(a)
m={}; %// initialise cell array of output messages
x=a;
m{length(m)+1}=a; %// some message
m{length(m)+1}='another message'; %// another message
end
I think the first option will be better, the second will not deal with fprintf well, and displaying elements of m could be tricky depending on what it contains. The first method is very simple, and does not even require you to change existing code, as you can make the displayResults input optional and set the default to be what you want.
You may suppress disp outputs by locally redefining it at the beginning of the function:
function [] = hideDisplay()
%[
% Override `disp` behavior
disp = #(x)doNothing;
% Next `disp` calls will no longer appear in matlab console
disp('Hello')
disp('World!')
%]
end
%% ---
function [] = doNothing()
%[
%]
end
Here's a possible workaround (to be clear - this is not a real answer to the question per-se, just a way to avoid the unwanted behaviour). Say my function is:
function y = prt_test(x)
y = x + 1;
disp('IN PRT_TEST')
end
Calling:
>> % Regular use - message and output are displayed:
>> y = prt_test(1)
IN PRT_TEST
y =
2
>> % Regular use w/ ";" - only message is displayed:
>> y = prt_test(2);
IN PRT_TEST
>> % Use "evalc()" - message and output are displayed:
>> evalc('y = prt_test(3)')
ans =
IN PRT_TEST
y =
4
>> % Use "evalc()" w/ func ";" - only message is displayed:
>> evalc('y = prt_test(4);')
ans =
IN PRT_TEST
>> % Use "evalc();" - no output:
>> evalc('y = prt_test(5)');
>> % Use "evalc();" w/ func ";" - no output:
>> evalc('y = prt_test(6);');
>>

Undefined function or variable "new_m"

I am new to Matlab. I have three functions. When I call co.m and pol_det.m they both work fine. However, when I call minor.m which in itself calls pol_det which in its turn calls co.m I get an error referring to the co.m: Undefined function or variable "new_m".
I am working with R2007b version. The three functions are below. Originally, they are written each in a separate .m document.
function [ k ] = pol_det(a)
%calculates the determinant of a general matrix (not just consisting of
%numbers)
dim=size(a); %dimensions of a matrix
if dim(1)~= dim(2)
disp('Only Square Matrices, please')
end
m=length(a);
k=0;
if(m==2)
k=sum_p(conv(a(1,1),a(2,2)),- conv(a(2,1),a(1,2))); %calc. the determinant of a 2x2 m.
else
for i=1:m
k=k+((-1)^(1+i))*conv(a(1,i),co(a,1,i)); %calc. the determinant using cofactor expansion
end
end
if (k==0)
disp('Matrix non-invertible')
end
end
function [ out ] = co( a,i,j )
%cofactor expansion,
%http://people.math.carleton.ca/~kcheung /math/notes/MATH1107/wk07/07_cofactor_expansion.html
[m,n]=size(a);
%create a new matrix by eliminating the row and column in which the %element is present
%new_m=zeros(m,n)
row=1;
col=1;
for i1=1:m
for j1=1:n
if(i1~=i && j1~=j)
new_m(row,col)=a(i1,j1);
col=col+1;
end
end
if(col~=1)
row=row+1;
end
col=1;
end
%new_m
out=pol_det(new_m);
end
function [ m ] = minor(a)
dim=size(a); %dimensions of a matrix
if dim(1)~= dim(2)
disp('Only Square Matrices, please')
end
a=a.';
for i=1:dim(1)
for j=1:dim(1)
a(i,:)=[];
a(:,j)=[];
m(i,j)= pol_det(a);
end
end
end
Your problem is that, given certain values of a, i, and j, you may never enter the conditional statement inside your loops that initializes new_m. In such a case, the variable won't exist when you then get to the following line out=pol_det(new_m);.
You should set a default value for newm before your loops and conditional statements, such as [], so that the variable will always have a value. You should also make sure pol_det can appropriately handle this default value. Best practice is to make use of preallocation, both to improve performance and avoid conditional existence of necessary variables.

How to manipulate and assign parts of a MATLAB field - Comma-separated list assignment

Consider the following MATLAB struct:
a(1).num=1; a(2).num=2; a(3).num=3;
The thing I want to do is to replace some of the elements of num with the old value minus a (scalar) number. For example, I would like to subtract 1 from a(2).num and a(3).num.
I already tried different ways:
a(2:3).num=a(2:3).num-1;
??? Error using ==> minus Too many input arguments.
Next try:
>>a(2:3).num=[a(2:3).num]-1;
??? Insufficient outputs from right hand side to satisfy comma separated list
expansion on left hand side. Missing [] are the most likely cause.
And last:
>> [a(2:3).num]=[a(2:3).num]-1;
??? Error using ==> minus
Too many output arguments.
arrayfun couldn´t help either.
Probably there is a quite easy answer to this question, but I couldn´t find any.
Easiest is a two-line solution:
C = num2cell([a(2:3).num]-1);
[a(2:3).num] = C{:}
Nicest is to have a function like deal, but with a function applied to each argument:
function varargout = fcnDeal(varargin)
%// (Copied from MATLAB's deal()
if nargin==1,
varargout = varargin(ones(1,nargout));
else
if nargout ~= nargin-1
error('fcnDeal:narginNargoutMismatch',...
'The number of outputs should match the number of inputs.')
end
%//...Except this part
varargout = cellfun(varargin{1}, varargin(2:end), 'UniformOutput', false);
end
end
Then what you want to do is just a matter of
[a(2:3).num] = fcnDeal(#(x)x-1, a(2:3).num)
You can manipulate them in the loop
index = [1,2]
for i = index
a(i).num = a(i).num - 1;
end

How do I create a vector that accepts strings?

Ok the problem is, I want to receive mathematical functions. And I won't know how many until the program runs.
When it runs i ask for an n number of functions i am going to receive and it starts saving them from the input.
So far I have this
function test()
n = input('number of equations?');
v = [1:n]
%in an ideal world, this ^ here would allow me to put a string in each position but
% they are not the same type and I understand that.. but how can I build a vector for saving my functions
%I want a vector where I can put strings in each position that is what I need
for i=1:n
x = input('what is the function?','s');
v(i)=x
end
v
%this would be my vector already changed with a function in each position.
end
When you want to store strings of different lengths, use cell arrays:
v = cell(1,n);
for i=1:n
v{i} = input('what is the function?','s'); #% note the curly braces
end
To use these as functions, use str2func:
for i=1:n
fh{i} = str2func(v{i});
end
fh is now a cell array containing handles to the functions defined by the user-input strings.