arrayfun with multiple inputs and a different size output
15 views (last 30 days)
Show older comments
I'm trying to set arrayfun to compute Monte-Carlo simulations on a GPU. But first, I'd like to parameterize on a CPU (I don't have GPUs yet).
The thing is, arrayfun takes as inputs arrays of same size, and then returns a scalar as said here (second setup): https://fr.mathworks.com/help/matlab/ref/arrayfun.html
First issue: myfunc is not returning a scalar but a big matrix for each Monte-Carlo simulation. How must the setup be done ?
Second issue: My inputs are Px1 vectors, which are reused M times. I also need to pass an input matrix A (also reused for each simulation), which clearly won't be the same size as other inputs Px1. I'm not sure what to do. Any help would be very appreciated.
FYI: myfunc is returning a N x P matrix
The aim is to have M simulations, therefore I'd like arrayfun to run M times to have as a final result a N x P x M matrix. Final goal is to prepare the code for GPU enhancement.
0 Comments
Accepted Answer
Guillaume
on 16 Oct 2018
Edited: Guillaume
on 16 Oct 2018
Note: I'm not familiar enough with GPU computing to know if there are some restrictions that apply.
First issue: myfunc is not returning a scalar but a big matrix for each Monte-Carlo simulation. How must the setup be done
Simply tell arrayfun to put the non-scalar output in a cell array using 'UniformOutput', false:
arrayfun(@somefunc, in1, in2, in3, 'UniformOutput', false)
Second issue: I also need to pass an input matrix A
Create an aonymous function which passes A to the real function. This technique is called argument binding:
arrayfun(@(in1, in2, in3) somefunc(A, in1, in2, in3), in1, in2, in3, 'UniformOutput', false)
The anonymous function @(in1, in2, in3) somefunc(A, in1, in2, in3) binds A to the somefunc call. A must exists before the anonymous function is created and once the function is created changing the value of A (or clearing it) will not affect the A that is bound.
edit: accidently deleted my answer. Restored now
0 Comments
More Answers (2)
Adam
on 16 Oct 2018
Edited: Adam
on 16 Oct 2018
c = arrayfun( @(x,y) rand( x, y ), 1:4, 3:6, 'UniformOutput', false )
works fine to produce outputs that are matrices. If your matrix A does not change then you can just pass this as a bound argument to your function e.g.
A = rand(2,2);
c = arrayfun( @(x,y) rand( x, y ) + A(randi(4)), 1:4, 3:6, 'UniformOutput', false )
Apologies for the ridiculously contrived and meaningless example. I was just looking for the quickest way I could find to show the syntax!
If your A changes with each of the other inputs you would probably have to put all those matrices, A, into a cell array and use cellfun with 3 inputs instead.
0 Comments
cedric W
on 16 Oct 2018
Edited: cedric W
on 16 Oct 2018
8 Comments
Guillaume
on 16 Oct 2018
As for the many constants another option to the struct or vector of constants is to wrap the function in a class (a function object):
classdef myfunc
properties
const1;
const2;
const3;
end
methods
function this = myfunc(c1, c2, c3) %constructor
this.const1 = c1;
this.const2 = c2;
this.const3 = c3;
end
function out = run(this, A, in1, in2, in3)
out = A * this.const1 * in1 + this.const2 * in2 + this.const3 * in3;
end
end
Used:
func = myfunc(constant1, constant2, constant3); %set the constants of the function
arrayfun(@(A, in1, in2, in3) func.run(A, in1, in2, in3), in1, in2, in3, 'UniformOutput', false);
func.const3 = newvalue; %change value of constant3
arrayfun(@(A, in1, in2, in3) func.run(A, in1, in2, in3), in1, in2, in3, 'UniformOutput', false); %run with new value (others unchanged)
See Also
Categories
Find more on Data Type Identification in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!