Arrayfun syntax and usage with class method - matlab

Here's a line of code that's giving me trouble.
arrayfun(#(x)container.nodelist(x).config(#a_func_handle,0),2:6);
Container is a class with one of its properties being an object array of nodes, and that array is called nodelist.
Each node has a function called config that is used to initialize it. Config expects one input, one of which is a handle to a function. The function handle I'm passing needs a constant passed along with it, which is represented by the 0.
In this case, I want to configure the nodes at positions 2 through 6 in nodelist with a specific function, so I thought to use arrayfun instead of a for loop.
Unfortunately, Matlab barfs with "too many inputs" for function config. What am I writing wrong? Is this example clear?

I figured it out. What I ended up doing was using nested anonymous functions, like so:
arrayfun(#(y)y.config(#(x)(configSlave(x,0))),exp.pico_list(2:6));

If I've understood correctly, config is a method of the objects contained within your nodelist array. In which case, in the usual MATLAB manner, the object on which you're invoking the method gets passed as the first argument. For example, you might need to write the config method like this:
function config(obj, fcnHandle, value)
obj.FunctionHandle = fcnHandle;
obj.Value = value;
end

Related

Use workspace variables in a Matlab function

I'd like to use the data that are loaded to my workspace in a Matlab function. This is the beginning of my function.
function [totalProfit] = compute(p,exit)
%% Declaration of variables
entry=0;
T = length(data);
.
.
.
end
I'm getting an error:
Undefined function or variable 'data'.
Where is the error?
The variable data was probably defined outside of the function, so it is out of scope.
Pass data as a parameter to compute and then it will be available inside the function.
You can use evalin to work with variables from another workspace. In your example this could be
T = evalin('caller','length(data)')
But please note that in most cases you get cleaner code if you define the variable as input argument for the function. So for your case this would be
function [totalProfit] = compute(p,exit,data)
T = length(data) ;
end
Ran is correct, but I wanted to mention something else. In general, only variables that are passed as arguments to a function are able to be used inside that function, so if you want to use your existing variables inside the function, pass them as input arguments.
It is possible to create global variables which allow you to use them inside functions without passing them as arguments, but it's usually not the best way of writing code. The times where I have used global variables are where I am calling multiple functions from a single script, and I have some constants that will be used by all the functions (for example gravity is a common one). An alternative to global variables is to use a struct, with the variables you want to pass to the function in it, so you only need one extra input argument, but you still have to be a bit careful.

about matlab's Adaptfilt.<algorithm> function

Matlab's DSP toolbox has a function called adaptfilt., where calling adaptfilt is not enough, but you must add the .< algorithm> where the algorithm can be one of the many things, which we can view using help adaptfilt. What kind of Matlab structure has been used here (or what is the . operator and how can I make my own function that has to be called using a dot).
Also, the result of doing, say, adaptfilt.fdaf, gives a result that seems like a structure. How can I view all the elements of this structure (that is, if there are any more members besides the values that are returned on the screen by the function itself)?
adaptfilt is a class definition, of which fdaf is a member. Then, you use the dot operator to access the static member of the class. See Static Methods in the MATLAB documentation. In summary, to define a similar function yourself use
classdef MyClass
...
methods(Static)
function y = yourFunc(x)
...
end
end
end
The result you're getting from adaptfilt.fdaf is in fact an object. The adaptfilt.fdaf documentation page outlines the members of the object.

How can I make the value of an expression equal to a second return value of another expression

Is there an idiomatic way in Matlab to bind the value of an expression to the nth return value of another expression?
For example, say I want an array of indices corresponding to the maximum value of a number of vectors stored in a cell array. I can do that by
function I = max_index(varargin)
[~,I]=max(varargin{:});
cellfun(#max_index, my_data);
But this requires one to define a function (max_index) specific for each case one wants to select a particular return value in an expression. I can of course define a generic function that does what I want:
function y = nth_return(n,fun,varargin)
[vals{1:n}] = fun(varargin{:});
y = vals{n};
And call it like:
cellfun(#(x) nth_return(2,#max,x), my_data)
Adding such functions, however, makes code snippets less portable and harder to understand. Is there an idiomatic to achieve the same result without having to rely on the custom nth_return function?
This is as far as I know not possible in another way as with the solutions you mention. So just use the syntax:
[~,I]=max(var);
Or indeed create an extra function. But I would also suggest against this. Just write the extra line of code, in case you want to use the output in another function. I found two earlier questions on stackoverflow, which adress the same topic, and seem to confirm that this is not possible.
Skipping outputs with anonymous function in MATLAB
How to elegantly ignore some return values of a MATLAB function?
The reason why the ~ operator was added to MATLAB some versions ago was to prevent you from saving variables you do not need. If there would be a syntax like the one you are searching for, this would not have been necessary.

Picking out the fourth value of a function using an anonymous function [duplicate]

I have a function that returns two values, like so:
[a b] = myfunc(x)
Is there a way to get the second return value without using a temporary variable, and without altering the function?
What I'm looking for is something like this:
abs(secondreturnvalue(myfunc(x)))
not that i know of. subsref doesn't seem to work in this case, possibly because the second variable isn't even returned from the function.
since matlab 2009b it is possible to use the notation
[~, b] = function(x)
if you don't need the first argument, but this still uses a temporary variable for b.
Unless there is some pressing need to do this, I would probably advise against it. The clarity of your code will suffer. Storing the outputs in temporary variables and then passing these variables to another function will make your code cleaner, and the different ways you could do this are outlined here: How to elegantly ignore some return values of a MATLAB function?.
However, if you really want or need to do this, the only feasible way I can think of would be to create your own function secondreturnvalue. Here's a more general example called nth_output:
function value = nth_output(N,fcn,varargin)
[value{1:N}] = fcn(varargin{:});
value = value{N};
end
And you would call it by passing as inputs 1) the output argument number you want, 2) a function handle to myfunc, and 3) whatever input arguments you need to pass to myfunc:
abs(nth_output(2,#myfunc,x))

Using varargin when passing argument into a function in Matlab?

I have a function called viewcsi(varargin) and I want to pass in three variables at most.
The first is a MBSspectrum class I made and then a string and also a number.
viewcsi is a call back, it gets called like this:
...'ButtonDownFcn','viewcsi(''pickvox_cb'', sp_viewcsi)');
sp_viewcsi is the MBSspectrum class I made and is in the workspace. I want to be able to add another argument called counter which is integer of type double.
I want to do something like this:
...'ButtonDownFcn','viewcsi(''pickvox_cb'', sp_viewcsi, counter)');
or
...'ButtonDownFcn', {#viewcsi, 'pickvox_cb', 'sp_viewcsi', counter)');
But when I do the last two thing these do not work since they do not preserve 'sp_viewcsi' as a class but treats it like a string. What can I do to fix this? I have a feeling its something easy but I havent been able to figure it out.
The ButtonDownFcn will only ever pass it two arguments. You can cheat it by saying
...'ButtonDownFcn',#(a,b)viewcsi(a,b, counter));
so that the callback will pass it a and b, while Matlab will hand it the current value of counter.
See also the doc on passing extra parameters.