I have a function with the form:
function t = fun(str1, str2, str3)
I'm trying to figure out a way to have the arguments passed to it as one cell containing the 3 arguments. Is there a way to do this? i.e.:
args = {str1, str2, str3};
x = fun(args);
I'm trying to find something that sets up this type of functionality. I know I could theoretically do fun(args{1}, args{2}, args{3}) but this isn't quite what I had in mind. I know varargs would work, but only if I were to change the function inputs, which I hope not to have to do. Anyway, thanks for the help.
How about
args = {str1, str2, str3};
x = fun(args{:});
Related
I've been stuck with this for a while and I couldn't find something similar asked previously (or I have failed in doing so)
My situation is fairly simple: I have a cell array of objects. They are all the same object and I have a get function for this kind of object which is: get (obj, attr), where obj is the object in question and attr is a integer from 1-6. Depending on the number the get function returns the corresponding attribute.
I would like to obtain all of my "position" attributes from all my objects which are in the corresponding cell array (this would be attr = 2). I know that cellfun performs a function on all cells, but the question is, how do I use my get function here for all my objects, taking into account that the function is get (obj, attr) ?
Thanks in advance
Firstly, by using get as a custom function you are shadowing the built-in get function - this is bad practise!
With this in mind, and to avoid confusion with the built-in get function which has similar syntax, I'm going to use getattr as a stand-in for your custom function which accpets an object and an integer 1 to 6.
pos = cellfun( #(obj) getattr( obj, 2 ), myCellOfObjects, 'uni', 0 );
By specifying 'uni', 0, the output doesn't have to be scalar and will be put into a cell array. This is useful when, for example, you have a multi-element array for your position.
This is equivalent to the following loop:
pos = cell( numel(myCellOfObjects), 1 );
for ii = 1:numel(pos)
pos{ii} = getattr( myCellOfObjects{ii}, 2 );
end
If ever in doubt about cellfun or arrayfun, just write a loop first - they are essentially the same but more concise.
There is a trick to this some are unaware of: you can pass multiple arguments to cellfun like this:
cellfun(#(obj,attr) get(obj,attr), {obj1,obj2},{attr1,attr2},'uni',0)
if you want to get one attribute of the cellarray (instead of providing an attribute for every object in the cellarray), then you can simply use this
cellfun(#(x) getattr(x,attr),obj,'uni',0)
put into anonymous function for convenience:
get_attr = #(obj,attr) cellfun(#(x) getattr(x,attr),obj,'uni',0)
%use:
get_attr(obj_in_cellarray,'myattribute')
%returns cell array of object attributes
I haven't run any of these functions since you didn't provide any example data / code. Please test and feedback.
I am trying to understand the usage of positional arguments in MATLAB and I was referring to this page.
Let's say I have a MATLAB function defined as follows:
function printPhoto(filename,varargin)
p = inputParser;
defaultFinish = 'glossy';
validFinishes = {'glossy','matte', 'colorful'};
checkFinish = #(x) any(validatestring(x,validFinishes));
defaultColor = 'RGB';
validColors = {'RGB','CMYK','colorful'};
checkColor = #(x) any(validatestring(x,validColors));
defaultWidth = 6;
defaultHeight = 4;
addRequired(p,'filename',#ischar);
addOptional(p,'finish',defaultFinish,checkFinish);
addOptional(p,'color',defaultColor,checkColor);
addParameter(p,'width',defaultWidth,#isnumeric);
addParameter(p,'height',defaultHeight,#isnumeric);
parse(p,filename,varargin{:});
end
When I call the above function as follows: printphoto('myFile.img', 'colorful'), is it possible to make this second argument to correspond to the second optional positional argument in the function definition i.e. color='colorful' and not finish='colorful'?
This is what you get when mixing optional-positional arguments and parameters. IMHO, you should use one or the other, but not both.
When you define an argument as positional, you're telling MATLAB that this input will always appear in that specific place, if it does appear. If you want to play around with the order of the inputs, that's exactly what a parameter-type argument is for.
Just think about it, the following syntaxes aren't that different:
printphoto('myFile.img','color','colorful')
printphoto('myFile.img', color='colorful' )
So I would suggest sticking with parameter-type arguments, but if you insist on having them positional, make sure that you assign a default value to the input if the user wants to "skip" it (by supplying some agreed-upon "null" value such as "" or []).
I am aware many of you will think this should be easily solvable. However, I have no clue about MATLAB.
Here goes my problem: when trying to execute the following example in the Command Window through the command
getLogReturnExcel('ALL.xls', {'ALL'}, 37000, 38000)
the cell-type error appears for this function. From what I understand however, when using {} the function should be grabbing the type inside {} (String in this case?) instead of the cell itself, which would be being grabbed if we were to use (), so there should be no error? Or is there something much more elementary that I might be overseeing? Thanks in advance for every bit of help; as you can tell I very much need it.
Cheers,
Ben
Here goes the function getLogReturnExcel:
function [logreturn, datearray] = getLogReturnExcel( datafilename, ticker, begindate, enddate )
[aanumber, aatext] = xlsread(datafilename);
aaticker = aatext(:,1);
aadate = aanumber(:,2);
aaret = zeros(length(aaticker),1);
aaret(1,1) = 0;
for i = 2:length(aaret)
aaret(i,1) = ln(aanumber(i,3))-ln(aanumber(i-1,3));
end
aadate = aadate(strcmp(aaticker,ticker));
aaret = aaret(strcmp(aaticker,ticker));
logreturn = aaret(aadate>=begindate & aadate<=enddate);
datearray = aadate(aadate>=begindate & aadate<=enddate);
return
The file 'ALL.xls' contains 3 columns, one with strings (the acronym for stocks) and two with numbers (I'm assuming double), one for the date in Excel-format and one with each day's stock standing.
The string can be obtained by using:
ticker{:}
or else the comparison in the lines
aadate = aadate(strcmp(aaticker,ticker));
aaret = aaret(strcmp(aaticker,ticker));
will be between strings and cell array.
Here is some documentation to access elements of a cell array.
I have this couple of lines which is difficult to understand..
oframes1 = do_localmax( difofg.octave{o}, 0.8*thresh, difofg.smin ) ;
oframes = [oframes1 , do_localmax( - difofg.octave{o}, 0.8*thresh, difofg.smin)] ;
here,
do_localmax is a function
thresh is a variable
difofg is also a function
I understand that the 1st line calls the function and passes the parameters but it is difficult understanding the second line and also what kind of syntax is difofg.octave{o}
Syntactically:
difofg is not a function; it's a variable, probably a struct or a class object. difofg.octave and difofg.smin get the element named octave or smin from that struct/object.
difofg.octave is apparently a cell array, and difofg.octave{o} gets the oth element of that cell array.
The second line creates an array with two elements: the first is oframes1, and the second is the result of the second call to do_localmax. Maybe this equivalent code will make it clearer what's happening:
oframes1 = do_localmax( difofg.octave{o}, 0.8*thresh, difofg.smin);
oframes2 = do_localmax( -difofg.octave{o}, 0.8*thresh, difofg.smin);
oframes = [oframes1, oframes2];
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