Suppose we have an 3-D array (tensor) and we want to apply in each slice a function, e.g., myFun = #(x)mean(x). Is there any way to do this without for loop using build-in functions (possibly withbsxfun, or arrayfun, or accumarray)?
For loop example:
inputA = rand(10,5,20);
for sl = 1:size(A,3)
inputB = myFun(inputA(:,:,sl));
end
Thank you.
EDIT:
inputB = arrayfun(#(iterSlice) myFun(inputA(:,:,iterSlice), 1:size(inputA,3))
PS: I would like to mention, that the handler function applied is more complicated in each slice, mean was an example included in the handler function.
A for loop is already the best possibility to iterate. The only way to further improve the performance is to get rid of the iteration and have a single function call of myFun which processes all data in a vectorized way. For your example function that very simple:
myFun=#(x)permute(mean(x,1),[3,2,1])
Now it accepts 3d inputs and in the rows you find the results of the previous iterative code. You have to modify your function, there is no generic wrapper on top which can do this for you.
Regarding your edit: arrayfun is known to be slow
Related
I am going to try and explain myself simply in the hopes of getting a simple answer.
Let's say I have a function 'calculate' that takes the inputs [t,k,r,x] and outputs [A,B,C,D] as follows:
function [A,B,C,D] = calculate(t,k,r,x)
Now lets say I have another function that takes these outputs as the inputs, and spits out more, different outputs, eg.
function [M,N] = again(A,B,C,D)
How do I link [M,N] to say k and t? The overall aim is to minimise both M and N by optimising k and t, and I can guess that it has something to do with nested functions and passing parameters but I'm not sure how to start, and the start is all I want. Thanks
Take a look at the Matlab optimization toolbox. It provides functions for a multitude of optimization problems. Although I believe these functions only take one function as a parameter. Therefore for your case it would probably be best, if you do it like this if you can:
Write function calculate.m with parameters (t,k,r,x) and save it.
Write function again.m with parameters(t,k,r,x) and save it.
Function again calls function calculate with parameters (t,k,r,x) and then continues to determine (M,N) from the output of calculate.
in the Matlab toolbox optimization function, e.g.: fmincon(fun,x0,A,b), you then have to use again.m as the function you want to optimize (fun).
Hope that's good enough for a start.
To process data in MATLAB I have to execute a certain function, let's call it function(). Since there is much data to be processed, like large array Time or Voltage (but many more) I execute those one by one like this:
TimeNew = function(Time);
VoltageNew = function(Voltage);
... etc
So this is done around 10 times. Moreover, I have to do such a thing multiple times, resulting in around 30 lines of code which all do the same thing but to a different variable.
Is there a way to optimize this? I am using the most recent version of MATLAB (2015b) and have all toolboxes installed.
A possible solution could be to store the input array into a struct, them use that struct as input of the function.
In the function you can identify the number and content of each field by using fieldnames and getfiled built-in function.
The function could return a structure as output whose names can be made the same as the ones of the input struct.
In the example below, three arrays are generated and the function siply compute their square.
var_1=1:10;
var_2=11:20;
var_3=21:30;
str_in=struct('var_1',var_1,'var_2',var_2,'var_3',var_3)
str_out=my_function(str_in)
The function
function [str_out]=my_function(str_in)
f_names=fieldnames(str_in)
n_fields=length(f_names);
for i=1:n_fields
x=getfield(str_in,f_names{i})
str_out.(f_names{i})=x.^2;
end
Hope this helps.
Qapla'
You could try cellfun
allResultsAsACell = cellfun(#function, {Time,Voltage,...,varN});
This is equivalent to
allResultsAsACell{1} = function(Time);
allResultsAsACell{2} = function(Voltage);
...
allResultsAsACell{N} = function{VarN};
The issue is just matching up the indices with the values. I'm sure you could code those in as well if you needed (e.g. timeInd = 1; voltageInd =2; ...)
To see more on the cellfun method, type
help cellfun
into your MATLAB terminal.
I am trying to use parallel computing with GPU in Matlab, and I would like to apply a function to a large array (to avoid the use of a for loop, which is quite slow). I have read Matlab's documentation, and I can use arrayfun, but only if I want to do elementwise operations. Maybe I am confused, but I would appreciate if someone can help me to use it. As an example of what I want to do, imagine that I would like to perform the following operation,
$X_t = B Z_t + Q\varepsilon_t$
where $X_t$ is 2x1, $B$ is 2x5, and $Z_t$ is 5x1, with $Q$ 2x2. I define a function,
function X = propose(Z,B,Q)
X=Z*B+Q*rand(2,1);
end
Now, suppose that I have an array $Z_p$ which is 5x1000. To each of the 1000 columns I would like to apply the previous function, for given matrices $B$ and $Q$, to get an array $X_p$ which is 2x1000.
Given the documentation for arrayfun I can not do this,
X=arrayfun(#propose,Zp,B,Q)
So, is there any possibility to do it?
Thanks!
PS: Yes, I know that in this simple example I can just do the multiplication without a for loop, but the application I have in mind is more complicated and I cannot do it. I just put this example as an illustration.
I am trying to understand the following commands of a MATLAB script :
global operatorObj
calcEVR_handles = operatorObj.calcEVR_handles;
m = operatorObj.nInputs
E = zeros(m,1);
V = zeros(m,1);
R = zeros(m,m);
for i=1:m
[E(i), V(i), R(i,i)] = calcEVR_handles{i}(t,x);
end
What can calcEVR_handles be, if t is a float and x is a vector?
calcEVR_handles (to me) looks like a cell array where each element is a handle to a function. Each element in calcEVR_handles is an anonymous function that takes in a single value t and a single vector x. As such, by doing calcEVR_handles{i}, you would access the corresponding function stored at the ith element in the cell array. Once you have access, you then pass your parameters to this function and it gives you those three outputs.
To show you an example of this working, consider the following cell array that works similarly to calcEVR_handles.
calcCellFunc = {#sin, #cos, #tan};
This is a three element cell array, where each element is a handle to a function. The # is a special character in MATLAB that denotes that you are creating a handle to a function. It's also used to create anonymous functions, but let's shelve that for this answer. You can read more about it here if you want to delve into more detail regarding this.
Back to our cell array of handles, we will make handles for sin, cos and tan. You can then iterate over your cell array by accessing the function you want by calcCellFunc{idx} where idx is the element you want in the cell array. This will ultimately give you the function stored at index idx. Once you do that, you can then call the function and specify whatever inputs you want (or none if it doesn't take any inputs). Here's a quick example for you. Let's create a random 5 x 5 matrix, and run through each function with this matrix serving as the input. We then take each of these outputs and store them into a corresponding slot in an output cell array. As such:
rng(123); %// Set seed for reproducibility
M = rand(5);
calcCellFunc = {#sin, #cos, #tan};
out = cell(1, numel(calcCellFunc)); %// To store the results for each function
for idx = 1 : numel(calcCellFunc)
out{idx} = calcCellFunc{idx}(M); %// Get the function, then pass
%// the matrix M to it
end
If you want to make things clear, you could split up the out statement to this instead:
func = calcCellFunc{idx}; %// Get access to the function
out{idx} = func(M); %// Pass M to this function
If you're new to handles / anonymous functions, you should probably use the above code first to make it explicitly clear on what MATLAB is doing. You are first getting access to the function you want that is stored in the cell array, and then you pass your arguments to this function.
If we display the output, we get:
>> celldisp(out)
out{1} =
0.6415 0.4106 0.3365 0.6728 0.5927
0.2823 0.8309 0.6662 0.1815 0.7509
0.2249 0.6325 0.4246 0.1746 0.6627
0.5238 0.4626 0.0596 0.5069 0.5737
0.6590 0.3821 0.3876 0.5071 0.6612
out{2} =
0.7671 0.9118 0.9417 0.7398 0.8054
0.9593 0.5564 0.7458 0.9834 0.6604
0.9744 0.7745 0.9054 0.9846 0.7489
0.8518 0.8866 0.9982 0.8620 0.8191
0.7522 0.9241 0.9218 0.8619 0.7502
out{3} =
0.8363 0.4503 0.3573 0.9094 0.7359
0.2942 1.4934 0.8932 0.1845 1.1370
0.2308 0.8167 0.4690 0.1773 0.8850
0.6149 0.5218 0.0597 0.5880 0.7004
0.8761 0.4135 0.4205 0.5884 0.8814
The first element of the output cell array has the output when you pass M to sin, the second when you pass M to cos, and the third when you pass M to tan.
So the next question you're asking... why is this useful?
Point #1 - Nix the copying and pasting
This kind of code writing is very useful because if you want to use the same inputs and supply them to many different functions, we would naturally be inclined to do some copying and pasting. Take each of your function names, and create a single line for each. Each line would call the corresponding function you want, followed by the input arguments. This can become quite tedious, and so one smart way to do it would be to place your function name as a handle into a cell array, and to write one for loop that goes over all of the functions dynamically. You could even explore cellfun and escape using the for loop to iterate over all of the function handles too, but I'll leave that for you to read up on.
In this way, you have very maintainable code and if you want to remove functions that don't need to be run, just remove the handles from the cell array rather than scrolling down to where the line that invokes this function is located and removing that.
This is actually a very common technique in computer science / software engineering in general. In fact, this is actually quite close to what are known as function pointers. This is MATLAB's cheap way of doing it, but the logic behind this is essentially the same.
Point #2 - Higher Order Functions
Another way this is useful is if you have a function where one (or more than one!) of the inputs is a function, and you also specify inputs into this function as additional parameters to this function. This is what is known as a higher order function. The outputs would be based on using this input function, and the additional inputs you specify to it and the outputs are based on using this input function and the inputs you specify for this function.
One very good example is the fzero function in MATLAB. The goal is to find the root of a non-linear function, and the first parameter is a handle to a function that you specify. The base behaviour behind how fzero works is the same no matter what the function is. All you have to do is specify the function you want to solve and the initial guess of where you think this root is.
All in all, anonymous functions are very useful.
Given a multiple-input MATLAB function
out=f(in1, in2)
I would like to write a second function g which generates the inputs for f, e.g.
[in1, in2]=g(in)
so that I can call something like:
out=f(g(in))
I have tried writing g as a single output function that stores in1 and in2 in a cell array so that I can feed the output of g to f using the colon operator:
in_c=g(in);
out=f(in_c{:})
but I was looking for a one-line solution, which seems not possible to achieve this way as I read in this Stack Overflow question
Is there any other way to do this?
As discussed recently, this is not possible in Matlab.
However, if you do not want to re-write your function g(x,y) to return a cell array, you can still do everything in two lines:
[in4f{1}, in4f{2}] = g(in);
out = f(in4f{:});
As an aside: Unless you're really hurting for memory, it doesn't make a lot of sense to try and force one-line statements everywhere by avoiding temporary variables. Sure, you can make your code look like CrazyPerl, but in the long run, you'll be glad for the added readability.