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

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))

Related

Is it possible to use fsolve if an existing script return a class structure?

I have a script Function.m such that for example, when I write TEST=Function(1,2), I have TEST.x1=4 and TEST.x2=[5,6,7]. I want to use fsolve to help me find input. To be precise, I want to define a function, say a=#(y)Function(1,y)-4 so that when I use [z,vector]=fsolve(#(y)a(y),5), matlab can help me to obtain z=2 and vector=[5,6,7].
I would like to solve it by defining the same structure New_Function.m as Function.m such that it returns x1 values, i.e., TEST=New_Function(1,2) gives TEST=4 only. Then I write new_a=#(y)New_Function(1,y)-4 and solve z=fsolve(#(y)new_a(y),5) and define new_vector=Function(1,z) so that I can access new_vector.x2.
I want to know if it is possible to do my task without defining a new script or amending the content in the existing script. How to write code?
Since Matlab does not allow further referencing the result of a function call, you may need to help yourself with getfield. In your example (provided I got it right), it would be something like New_Func = #(y) getfield(Function(1,y),'x1'). This would take one scalar and return one scalar, i.e., New_Func(y) gives the field value of the struct returned by Function(1,y) associated to the field x1.

Passing names of functions to another function with parameters as input in MATLAB

Problem Statement: I am trying to write MATLAB code for a main caller function (like run_experiment below) to specify which computations I want to execute where computations are made sequentially using other MATLAB functions. Those other functions are to be evaluated based on parameters passed with the main caller function. The said functions used in computations are to be specified with name of the scripts they are written in.
Example Desired Code Behavior: For example, a command like the following should run the preprocess_data, initialise_model and train_model scripts.
>> run_experiment('dataset_1_options', '|preprocess_data|initialise_model|train_model|');
And this command should run only the train_model script but also evaluates its performance:
>> run_experiment('dataset_1_options', '|train_model|evaluate_model|');
In the above examples "|" is used as a delimiter to specify separate function names to be evaluated. Those functions use the options specified with dataset_1_options. Please do not focus on how to separate that part of the input into meaningful function names; I know how to do it with strsplit.
Constraints and Specifications: The function names to be passed as input to the main caller function are NOT anonymous functions. The purpose is to be able to pass such multiple function names as input AND to evaluate them with the options like the above example. They return output to be evaluated in other parts of the research code (i.e. passing data matrices to other functions within the research code as results of the computations carried out within them.)
Question: Given the desired behavior and constraints mentioned above, can anybody help in how to pass the separate function names from another caller function along with options/parameter to those functions? How should the main caller function evaluate the function names passed in as input with the options specified during the call?
Thank you in advance.
You can pass functions to functions in matlab. You just need to use the # sign when you pass it. In your case it would be run_experiment('dataset_1_options', #train_model) inside a script. You could keep your options in a cell array or something. The run_experiment function would just be a regular function,
function [output] = run_experiment(options, train_model, ...);
train_model(options{1}, ...)
.
.
.
end
What you need to do this is create a cell array with your function names and another array with the corresponding options as below
% Function name array
fn_array = {#fn_1, #fn_2, ...};
% Option array
option_array = {{fn1_opt1, fn2opt2, ...}; {fn2_opt1, fn2_opt2, ...};, ...};
These two need to be passed to your run_experiment function which will evaluate them as below
function run_experiment(fn_array, option_array)
num_fn = length(fn_array); %Finds number of functions to evaluate
for ii = 1:num_fn %Evaluates each function
fn_array{ii}(option_array{ii}{:});
end

Does matlab treat colon mark differently during variable assignment and indexing without assignment?

For example I have a 1*30 structure a.field, when I type a(:).field in command window it just iteratively display a(1).field, a(2).field,... However, when I was trying to assign a(:).field to another variable b, what b get is just a(1).field.
BTW, if I attampt to pass a(:).field to a function, Matlab just throws an error "too many input arguments".
What is the mechanism behind? My guess is that matlab threat colon equivlant to the first element during assignment, is that true?
You need to add brackets, otherwise matlab don't understand that your trying to store an array:
b = [a(:).field]
Another option that provide similar result:
b = horzcat(a(:).field)

Passing multiple inputs into a MATLAB function via loop?

I have multiple variables var_1, var_2, var_3....var_9 (they are named like that) that I want to pass in a function. All of the variables are saved in the workspace. The function takes 2 variables, and spits out an output. I want to compare var_1 with all the variables, including itself, so I prefer to automate it in a loop.
So I want to execute
function(var_1,var_1)--> display answer, function(var_1,var_2)--> display answer...function(var_1,var_9)-->display answer all at once in a loop. I've tried the following, with no luck:
for i=1:7
functionname(var_1,var_'num2str(i)')
end
Where did I go wrong?
You cannot make a dynamic variable name directly. But you can use the eval-function to evaluate an expression as a string. The string can be generated with sprintf and replaces %d with your value.
for i=1:7
eval(sprintf('functionname(var_1,var_%d)', i));
end
But: Whenever you can, you should avoid using the eval function. A much better solution is to use a cell array for this purpose. In the documentation of Matlab there is a whole article about the why and possible alternatives. To make it short, here is the code that uses a cell array:
arr = {val_1, val_2, val_3, val_4, val_5, val_6, val_7, val_8, val_9};
for i = 1:length(arr)
functionname(arr{1},arr{i})
end

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.