0

Good evening everyone,

I want to create a function

f(x) = [f1(x), f2(x), ... , fn(x)]

in MatLab, with an arbitrary form and number for the fi. In my current case they are meant to be basis elements for a finite-dimensional function space, so for example a number of multi variable polynomials. I want to able to be able to set form (e.g. hermite/lagrange polynomials, ...) and number via arguments in some sort of "function creating" function, so I would like to solve this for arbitrary functions fi.
Assume for now that the fi are fi:R^d -> R, so vector input to scalar output. This means the result from f should be a n-dim vector containing the output of all n functions. The number of functions n could be fairly large, as there is permutation involved. I also need to evaluate the resulting function very often, so I hope to do it as efficiently as possible.


Currently I see two ways to do this:

  1. Create a cell with each fi using a loop, using something like
    funcell{i}=matlabFunction(createpoly(degree, x),'vars',{x})
    and one of the functions from the symbolic toolbox and a symbolic x (vector). It is then possible to create the desired function with cellfun, e.g.
    f=@(x) cellfun(@(v) v(x), funcell)
    This is relatively short, easy and what can be found when doing searches. It even allows extension to vector output using 'UniformOutput',false and cell2mat. On the downside it is very inefficient, first during creation because of matlabFunction and then during evaluation because of cellfun.

  2. The other idea I had is to create a string and use eval. One way to do this would be
    stringcell{i}=[char(createpoly(degree, x)),';']
    and then use strjoin. In theory this should yield an efficient function. There are two problems however. The first is the use of eval (mostly on principle), the second is inserting the correct arguments. The symbolic toolbox does not allow symbols of the form x(i), so the resulting string will not contain them either. The only remedy I have so far is some sort of string replacement on the xi that are allowed, but this is also far from elegant.


So I do have ways to do what I need right now, but I would appreciate any ideas for a better solution.

crown42
  • 305
  • 1
  • 7
  • Is this a correct interpretation of what you're trying to do? You have `n` polynomials of degree `k` in a single variable. For some scalar double `d`, you would like a function `my_f(d)` which returns a vector of double equal to `[f1(d); ...; fn(d)]` where `fi(d)` denotes the `ith` polynomial evaluated at the double `d`? – Matthew Gunn Dec 05 '15 at 19:35
  • Or is it: You have `n` matlab functions `f1(x)` through `fn(x)`, each of which take in a vector `x` of doubles and returns a single double. You would like a function returning a vector of doubles whose value = `[f1(x); f2(x); ...; fn(x)]`? – Matthew Gunn Dec 05 '15 at 19:42
  • Or is it: You have `n` symbolic functions of class `symfun` in variables `f1` through `fn`. You would like to create a symbolic function `fvec` equal to `[f1; ...; fn]` for any positive integer n? Or possibly a vector of doubles equal to `[f1(x); ...; fn(x)]`, that is, the symbolic functions evaluated at a double vector `x`? Basically I'm confused what you're exactly asking for. – Matthew Gunn Dec 05 '15 at 19:53
  • It is the second interpretation. As stated I have a number (lets say n) of functions fi, that go from a d-dim vector to a scalar value and want a vector containing the output of all n functions. Also n is fairly large, there is permutation involved. – crown42 Dec 05 '15 at 21:07
  • I completely agree with your not wanting to use `eval`. But anyway, you *can* tell `matlabFunction` to assume vector input. Or is that not what you referred to with your last two sentences in point 2? – Andras Deak -- Слава Україні Dec 05 '15 at 22:12
  • For point 2 (creating a string) the problem is, that when creating symbolic functions they can not have the form _x(1)^2+x(2)^2_. This means directly creating something like 'eval(strjoin({{@(x)} {x(1)^2+x(2)^2'}})) for use in `eval` is not possible. (Also this kind of code gives me slight shivers) Or were you talking about point 1, since you mentioned matlabFunction. – crown42 Dec 05 '15 at 23:02
  • It [*is* possible](http://stackoverflow.com/a/32803436/5067311) with `matlabFunction` to use input as `x(1)`, `x(2)` etc, but I'd also avoid it. – Andras Deak -- Слава Україні Dec 05 '15 at 23:04
  • I think I am already doing what you mention. In option 1 I get functions containing symbolic x1,x2,... (from vector symbol x) which `matlabFunction` correctly translates to in(1), in(2),... for input vector _in_. – crown42 Dec 05 '15 at 23:10
  • Ah, OK then. I just wanted to make sure you know about that option. – Andras Deak -- Слава Україні Dec 05 '15 at 23:14

1 Answers1

0

From my understanding of the problem, you could do the straightforward:

Initialization step:

my_fns = cell(n, 1);  %where n is number of functions
my_fns{1} = @f1;   % Assuming f1 is defined in f1.m etc...
my_fns{2} = @f2;

Evaluation at x:

z = zeros(n, 1);
for i=1:n,
   z(i) = my_fns{i}(x)
end

For example if you put it in my_evaluate.m:

function z = my_evaluate(my_fns, x)
  z = zeros(n, 1);
  for i=1:n,
    z(i) = my_fns{i}(x)
  end      

How might this possibly be sped up?

Depends on if you have special structure than can be exploited.

  • Are there calculations common to some subset of f1 through fn that need not be repeated with each function call? Eg. if the common calculation step is costly, you could do y = f_helper(x) and z(i) = fi(x, y).
  • Can the functions f1...fn be vector / matrix friendly, allowing evaluation of multiple points with each function call?

The big issue is how fast your function calls f1 through fn are, not how you collect the results from those calls in a vector.

Matthew Gunn
  • 4,451
  • 1
  • 12
  • 30
  • I disagree with your last comment: from what I understand, I think OP essentially wants a very general way of constructing functions from R^n to R^m. Using a single array-valued anonymous function vs an array of scalar anonymous functions would indeed show as a massive impact in runtime. – Andras Deak -- Слава Україні Dec 05 '15 at 22:41
  • I think you propose to replace the `cellfun` with a loop, which I should have thought about sooner, as it is usually an improvement ( I remember [this post](https://stackoverflow.com/questions/18284027/cellfun-versus-simple-matlab-loop-performance . But I as Andras mentioned, I believe further speed up could be possible. If I type a number of functions into a single array by hand, I think it should be faster than putting them into a cell and running a loop. – crown42 Dec 05 '15 at 22:52
  • @AndrasDeak Agreed that a single, vectorized function from R^n to R^m would almost certainly be faster than array of scalar functions. This brings up what I find so bizarre about the question: to optimize for speed, you need specifics. With the problem phrased in such a highly general way, there's really not much useful to say. The question in a sense is: "how do I write a fast function from R^m to R^n?" Well, it depends on what the function is! – Matthew Gunn Dec 06 '15 at 09:37
  • I believe it's intentionally general: consider a GUI where you load some data and compute coefficients for a basis. And the basis can be constructed in many ways, from various special function/polynomial sets. I think OP is after something lke this, at least the question specification seems to tell me that. – Andras Deak -- Слава Україні Dec 06 '15 at 11:15