Output argument "val" (and maybe others) not assigned during call to - matlab

I have the following function that aims to set a colour to a specific pixel.
function val = xyz(p)
if (p(2,2)) == 40
val=[255,0,0];
end
end
I'm not sure if the function works correct in assigning the colour since I get the following error when I call the function:
Output argument "val" (and maybe others) not assigned during call to.....
How can I solve this issue?
Thanks.

Sebastian said right, you need to add an else to be sure your output is fill.
function val = xyz(p)
if (p(2,2)) == 40
val=[255,0,0];
else
val = [];
end
end

Related

Function with different return variables

Is there a way to have one function that can return two different variables, but only one at a time AND knowing which one is returned in the function call?
example:
I have the following function in which only one of the outputs is valid (the other one would be [])
function [a,b] = AlternatingOutput (input)
if input == 1
return ONLY A
else
return ONLY B
end
end
and i call it in a script
[a,b] = AlternatingOutput (input)
i want a way to say the following (pseudocode):
if (function outputs a)
[a,~] = AlternatingOutput(input)
elseif (function outputs b)
[~,b] = AlternatingOutput(input)
end
the script is run in a loop, and later i need the newest Valid values for a and b, so i cannot overwrite one of the two with []
I do understand that I could just write a function that checks which variable will be output, but I was wondering if there is a more elegant way.
I hope I have made my question clear, and I hope someone can answer me :)
There is no way to tell if an output argument is actually used. You may check the number of output arguments using nargout and it would allow to distinguish between [a] = AlternatingOutput(input) and [~,b] = AlternatingOutput(input)
I don't know the full context of your problem, but maybe you can put all your variables into a struct? Simply pass this struct everytime you call the function and let it decide which variables to manipulate. (This might be slow in some programming languages, but not in matlab).
How about retuning a cell?
function [ ab ] = testfun( input )
if input
ab={'ax'};
else
ab={2};
end
end
No worries about what is in the cell.
thb you could return what ever you want, Matlab does not check the type anyways
If only one of the outputs from the function AlternatingOutput is valid, then you only need to return one output:
function [X] = AlternatingOutput(input)
if input == 1
X = A;
else
X = B;
end
end
To allocate the retured value to either a or b in the loop, put them into a cell:
C = {AlternatingOutput(1), AlternatingOutput(2)};
and then use input to determine which value is change. If input is either 1 or 2 you can just do
for counter = ...
input = mod(input,2)+1;
C{input}=AlternatingOutput(input);
end
If your function doesn't mind accepting more input variables, why not pass a and b as input:
function [a,b] = AlternatingOutput(a,b,input)
if input == 1
a = new_value_for_a;
% b retains its former value
else
% a retains its former value
b = new_value_for_b;
end
end
Then it can be easily called from your script in a loop:
for i= ...
[a,b] = AlternatingOutput(a,b,input);
...
...
end

nargin on matlab class method returns -1

I have the following scenario. In myClass.m I have defined
classdef myClass
...
methods
function y = foo(this, x)
...
end
end
end
Then I execute
obj = myClass();
nargin(#obj.foo)
and get as a result -1 while I would expect 1. The function nonetheless accepts only one argument.
I actually want to pass the handle to another function (in which I don't have access) which checks the number of arguments and I want the check nargin(f)==1 to succeed. Is there a way to do that?
PS
I know that if I define the method as static I will get the correct result by calling nargin(#(x)Test.foo) but the method accesses class variables.
Even though this question got answered and accepted, I think it is worth to show a working approach, which works even without creating an instance of the class. Reference to metaclass: https://ch.mathworks.com/help/matlab/ref/metaclass.html
metaClass = ?myClass
numArgIn = zeros(length(metaClass.MethodList), 1);
names = strings(length(metaClass.MethodList), 1);
for i=1:length(metaClass.MethodList)
names(i) = string(metaClass.MethodList(i).Name);
numArgIn(i) = numel(metaClass.MethodList(i).InputNames);
end
disp(numArgIn(names=="foo"))
When you create a folder with the class and some modules, you can use the following one-liner notation:
nargin('#myClass/foo.m')
In the latter example, the file ending can be removed without effect.
I can no longer verify the validity of this answer. See more recent answer(s) and comments.
Original answer
I fixed the problem by defining my own wrapper something like
function y = mywrapper(f, x)
%MYWRAPPER nargin(#(x)mywrapper(f, x)) is 1 as it should be
y = f(x);
end
I realised that nargin(#(x)#obj.foo), also does what I wanted

Matlab function switching return/no return

In Matlab, I've got a function that is called after some special points are found on an image. Depending on how the nearby pixels of that "special point" are, the function must return a structure with many parameters or return nothing.
Is it possible to have a function that by deafult will return something but, in some cases, nothing should be returned? How that "return nothing"'s code should be like? Thank you.
One common trick in matlab is to use the empty matrix [] to indicate nothing. You could write your function something like (untested code):
function result = analyze(image, special_point)
% your code here
if pixels_are_ok
result.a = 1;
result.b = 2;
else
result = [];
end
If you call this function from your other code, you can use isempty to see if you got a result or not:
result = analyze(image, special_point)
if isempty(result)
display('did not find anything')
else
display('found some interesting results')
display(result)
end

Use variable number of output while assigning to varargout

I'm making a generic subsref for my classA, which has an attribute attrA that is a classB instance.
So far, it's working, it lets me do things like
x = objA.attr1.methB(),
which was what I was trying to do to do in the first place.
function this = Class1(varargin)
this.attrA = ClassB()
this = class(this,'ClassA')
function this = ClassB()
this.AttrB1 = 'valueB1'
this.AttrB2 = 'valueB2'
function out = methB
out = this.AttrB2
The problem I stumbled upon is this:
when the call to a method is executed in my subsref, I do it like this (detecting that it's a method etc is done before):
methName = index(1).subs;
args = index(2).subs;
if iscell(args)
varargout = {feval(methName,this,args{:})};
else
varargout = {feval(methName,this,args)};
end %end if iscell
The problem is that when the methName method supports variable number of outputs, this varargout is not equivalent to [x,y,...] (the number of outputs should be assigned in the call to subsref, so methName always returns a single output, which is not always what I want (almost, but not always).
How would I let methName know how many outputs I want? (I don't want to have to pass N as a parameter).
I'm thinking something like creating a string str='[out1,out2,out3...]'
and then doing something like
eval([
str ...
'= {feval(methName,this,args{:})};'...
])
But I keep thinking there must be a more elegant way of doing it.
If the number of outputs you expect is dependent on the output arguments requested from your subsref, you can simply use nargout like this:
[varargout{1:nargout}] = feval(methName,this,args{:});
This solution worked, but I needed to add a little something for single outputs:
if iscell(args)
[argout{:}] = feval(methName,this,args{:});
else
[argout{:}]= {feval(methName,this,args)};
end %end if iscell`
if isSingleCell(argout) && iscell(argout{1})`
v = argout{1};
argout{1}=v{1};
end
I'm not sure, but it may be that the last bit was only necessary to fix something else ( I had to fix a lot of other things to make this work). I'll get back to it when I finish what I was trying to do with this class

passing a colon as argument of a function in matlab

I would like to know if it's possible to use a colon ":" as argument of a function.
Something like that:
function y=func(x)
if x is a colon
do this
else
do that
end
Also is it possible to pass the key work end as argument of a function, and also 1:end, 3:end-5, etc...
I doubt it's possible, but I would like to be sure.
Also, I get a weird error when I pass "1:end" as argument of a function, it produces no error, but inside the function, no argument is assigned (not even the other arguments). Do someone know what happens?
You can override both for your own classes:
classdef MyClass
properties(Access=public)
data
end
methods
function out = end(A,k,n)
disp(A);
disp(k);
disp(n);
out = [];
end
function B = subsref(A,S)
disp(S);
B = [];
end
end
end
As for functions, I never heard of such a functionality.
No, it's not possible to pass a colon as an argument (it doesn't make any sense).