I have defined a class like
classdef Test
properties
a
b
end
methods
function this = Test(a, b)
this.a = a;
this.b = b;
end
function disp(this)
fprintf('a=%d b=%d\n', this.a, this.b);
end
end
end
But when I want to display a vector of Test, it seems not print each elements of array using the disp function just defined.
>> out = [Test(1,2),Test(3,4)]
out =
a=1 b=3
a=2 b=4
The questions is how to display an array of objects appropriately? Is there a way to overload the disp function and print as the following:
out=
a=1 b=2
a=3 b=4
(In my considering , the output will be same as calling disp function to element of array one by one.. But the output seems like firstly print all the a's value 1 3 and then b's value 2 4.)
You are getting this result because in your statement out = [Test(1,2),Test(3,4)], the variable out becomes an array of the same class Test, but of size [1x2].
If you try out.a in your console, you'll get:
>> out.a
ans =
1
ans =
3
This is a coma separated list of all the values of a in the out array. This is also the first parameter that your custom disp function sees. It then sees another column vector of all the values of b. To understand what the function fprintf is presented with you can also try in your console:
>> [out.a,out.b]
ans =
1 3 2 4
>> [out.a;out.b]
ans =
1 3
2 4
Since fprintf works in column major order, it will consume all the values column wise first. In that case we can see that the last option we tried seems better.
Indeed, if you change your disp function to:
function disp(this)
fprintf('a=%d b=%d\n', [this.a ; this.b]);
end
You get the desired output:
>> out = [Test(1,2),Test(3,4),Test(5,6)]
out =
a=1 b=2
a=3 b=4
a=5 b=6
Whichever size of object array you define. Just keep in mind that if you input an array of Test object they will be considered column wise:
>> out = [ Test(1,2),Test(3,4) ; Test(5,6),Test(7,8) ]
out =
a=1 b=2
a=5 b=6
a=3 b=4
a=7 b=8
Last option, if you want even more granularity over the display of your object array, you can customise it the way you like inside the disp function:
function disp(this)
nElem = numel(this) ;
if nElem==1
fprintf('a=%d b=%d\n', this.a , this.b );
else
for k=1:nElem
fprintf('a=%d b=%d\n', this(k).a , this(k).b);
end
end
end
This produces the same display than before, but since the elements are treated one by one, you could customise even further without having to consider the way arrays are treated by fprintf.
With the syntax you use, you should overload the display function instead of the disp function.
See the (not that simple to read) corresponding page in the documentation.
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
Sometimes it is desired to make several calls in one command. A simple example could be strrep. Assume you want to replace all parentheses with brackets, all commas with dots and then remove all double quotations. The following pseudo code could then be desired:
strrep(myString, '()', '[]', ',', '.', '"', '')
Is there any way to accomplish this? You could of course go with:
strrep(strrep(strrep(myString, '()', '[]'), ',', '.'), '"', '')
Or save the strings in a cell array and use this in a for loop, but both solutions are incredibly ugly.
The most desired answer, is one that is generic for all functions that work in a similar way.
To directly answer your question, there is really no consistent way of doing this, no. It really depends on the function. If you search the documentation you will often find a way to do this. With strings, at least, you can usually pass cell arrays in place of strings to perform operations on multiple strings, and in this case multiple operations on the same string.
A Solution for This Particular Example
You can easily use regexprep to do this for you. You can pass a cell array of the expressions to match with a corresponding cell array of the replacement values.
regexprep('abc', {'a', 'b', 'c'}, {'1', '2', '3'});
%// '123'
For your specific example, you would do something like:
regexprep(myString, {'\(\)', ',', '"'}, {'[]', '.', ''})
And as an example:
myString = 'This, is a () "string"';
regexprep(myString, {'\(\)', ',', '"'}, {'[]', '.', ''})
%// 'This. is a [] string'
If you don't want to worry about escaping all of the expressions to be regex-compatible, you can use regexptranslate to do that for you.
expressions = regexptranslate('escape', {'()', ',', '"'});
regexprep(myString, expressions, {'[]', '.', ''});
Say you want function foo to work like this:
foo(Variable,Parameter1,Value1);
foo(Variable,Parameter1_1,Value1,Parameter2,Value2,...);
then using recursion:
function[Variable]=FooBar(Variable,varargin)
N=nargin-1; %\\ Count the input parameters
if N>=2
Parameter=varargin{1};
Value=varargin{2};
% Process the first Parameter-value pair
Variable=FooBar(Variable,varargin{3:N}); %\\ Cut first Parameter-Value pair off and pass the rest to foo again
end
This approach allows you to use chain of single parameters, pairs, triplets, quadruplets, etc.
In this perticullar example the pairs are executed as LIFO stack and last unpaired Parameter is ignored. You can also add some conditions to implement foo(IN,Parameter1,Value1,Modifier,Parameter2,Value2,...) and many other properties...
For your perticullar example:
function[MyString]=FooBar(MyString,varargin)
N=nargin-1; %\\ Count the input parameters
if N>=2
Parameter=varargin{1};
Value=varargin{2};
MyString=regexprep(MyString,Parameter,Value)
MyString=FooBar(MyString,varargin{3:N});%\\ Cut first Parameter-Value pair off and pass the rest to foo again
end
Examples:
>> myString='This, is a () "string"';
FooBar(myString,'()','[]','"','',',','.')
ans = This. is a [] string
>> myString='This, is a ("string")';
FooBar(myString,'()','[]','"','',',','.')
ans = This. is a (string)
>> myString='This, is a ("string")';
FooBar(myString,'(','[',')',']','"','',',','.')
ans = This. is a [string]
As already said by #Suever your example can be solved by regexprep and #thewaywewalk has hinted that there is no "general" soluction for all function calls.
Note I do not advocate this as a good way to code -> but its a quirky question and thus here is a suitable quirky solution....
There is lots of reason why you shouldn't do this - namely a nightmare to debug but you could in theory do this with an "intelligent" self calling function...
% Create your own function which takes the following inputs:
% fHandle - function handle to the function of choice
% property - your starting variable
% varargin - a cell array (or single var) of variables to
% pass into the fHandle on each call
% see examples below...
function output = multipleCalls ( fHandle, property, varargin )
% call your primary function using feval and your inputs
% with the 1st group of inputs from the 1st varargin
if iscell ( varargin{1} )
output = feval ( fHandle, property, varargin{1}{:} );
else
output = feval ( fHandle, property, varargin{1} );
end
% remove the varargin variable which has just been used.
varargin(1) = [];
% are they aremore multiple call?
if ~isempty ( varargin )
% if so self call to apply the subsequent calls.
output = multipleCalls ( fHandle, output, varargin{:} );
end
end
% modifying your example to use this method:
multipleCalls( #strrep, 'This, is a () "string"', { '()', '[]' }, { ',', '.' }, { '"', '' } )
% Its probably a longer command and is it any clearer -> probably not...
% Here is another example:
% Create a silly anonymous function
sillyFunction = #(a,b) a + b
% Then you can use it in the same way:
% Where 0 is what you start with and then
% each time you want to add 1, then 2, then 3 and finally 4
multipleCalls ( sillyFunction, 0, 1, 2, 3, 4 )
I am new to Matlab and I have the following problem:
A function expects an input parameter of an array of function-handles
handleArray = #( param ) [ ...
#calcSumOfParam ; ... % and so on..
#calcSumOfParam ];
solution = calculateFunc( handleArray );
However, calcSumOfParam() actually needs more/additional input parameters (not only param) and is kind of heavy-structured (only an example here)
function [ sumOfParam ] = calcSumOfParam( param , maxIter , startIter )
sumOfParam = 0;
for iter = startIter : maxIter
sumOfParam = sumOfParam + param( iter );
end
end
Is there a way to do this?
I cannot use anonymous functions as I need to use loops and conditions. Also multiple functions won't work either, as I do not know the size of the handleArray and so the amount of functions (get it through user input).
I have a matlab struct which several levels (e.g. a.b(j).c(i).d). I would like to write a function which gives me the fields I want. If the struct has only one level, it would be easy:
function x = test(struct, label1)
x = struct.(label1)
end
E.g. if I have the struct a.b I could get b via: test('b'). However, this does not work with subfields, if I have a struct a.b.c I can't use test('b.c') to access it.
Is there any way to pass a string with the full field name (with dots) to a function to retrieve this field? Or is there even a better way to get only the fields that I select through the function arguments?
The goal? Sure, it would be a useless function for one fieldname, but I wan't to pass a list of fieldnames as argument to receive exactly these fields.
You should use subsref function:
function x = test(strct, label1)
F=regexp(label1, '\.', 'split');
F(2:2:2*end)=F;
F(1:2:end)={'.'};
x=subsref(strct, substruct(F{:}));
end
To access a.b.c you can use:
subsref(a, substruct('.', 'b', '.', 'c'));
The test function first splits the input using .as a delimiter and creates a cell array F where every other element is filled with . and then its elements are passed to substruct as arguments.
Note that if there are arrays of structs involved it will get the first one. For a.b(i).c(j).d passing b.c.d will return a.b(1).c(1).d. See this question for the way it should be handled.
As a side note, I renamed your input variable struct to strct because struct is a built-in MATLAB command.
One way is to create a self calling function to do this:
a.b.c.d.e.f.g = 'abc'
value = getSubField ( a, 'b.c.d.e.f.g' )
'abc'
function output = getSubField ( myStruct, fpath )
% convert the provided path to a cell
if ~iscell(fpath); fpath = strread ( fpath, '%s', 'delimiter', '.' ); end
% extract the field (should really check if it exists)
output = myStruct.(fpath{1});
% remove the one we just found
fpath(1) = [];
% if fpath still has items in it -> self call to get the value
if isstruct ( output ) && ~isempty(fpath)
% Pass in the sub field and the remaining fpath
output = getSubField ( output, fpath );
end
end