2

I have a multivariable symbolic expression say

c = x^2 +y^2 + z^2

using matlabFunction(c) returns

ans = @(x,y,z)x.^2+y.^2+z.^2

I can't input this into fminsearch (because it has multiple scalar inputs right?). How can I change the format of the output so it takes something that fminsearch actually allows, something like

@(x)x(1)^2+x(2)^2+x(3)^2

It is feasible to do this manually for 3 variables but not for hundreds.

The errors look something like if it helps:

Error using symengine?makeFhandle/@(......) Not enough input arguments.
Error in fminsearch (line 190) fv(:,1) = funfcn(x,varargin{:}):
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
Lawng
  • 33
  • 4

1 Answers1

3

A quick workaround that comes to mind is to create another anonymous function as a go-between:

fun          = @(x,y,z)x.^2+y.^2+z.^2;
funMiddleMan = @(x) fun(x(1),x(2),x(3));

For a large number of arguments, the solution becomes a little more complicated. My first instinct is to use str2func in the following manner

nVar         = 3;
funMiddleMan = str2func(['@(x)fun(',sprintf('x(%d),',1:nVar-1),'x(',num2str(nVar),'))']);

However, this will not work since str2func cannot (currently) embed the definition of fun within a local workspace attached to funMiddleMan; meaning that calling funMiddleMan in this manner will generate an "Undefined function 'fun'" error. The problem can be circumvented by using eval:

funMiddleMan = eval(['@(x)fun(',sprintf('x(%d),',1:nVar-1),'x(',num2str(nVar),'))']);

which will work since the string is actually evaluated; however, the use of eval is typically discouraged for a number of reasons and is only presented for completeness (and a quick and dirty way to get the ball rolling).


Another option is to use convert the vector x into a cell array and use comma-separated list expansion in the following manner:

splay        = @(x) fun(x{:});
funMiddleMan = @(x) splay(mat2cell(x(:),ones(1,numel(x)),1));

which is not necessarily optimal but works.

TroyHaskin
  • 8,361
  • 3
  • 22
  • 22
  • A problem that I found is that if i try: fminsearch(funMiddleMan,[0,0,0]) it doesn't work since fun is not defined yet. I tried to work around this to just copy the output of funMiddleMan in the command window and paste it in place of funMiddleMan. This worked, for a small number of variables. For the project I am working on I have an equation that is so long that the output is truncated since the text exceeds maximum line length of 25,000 characters. Any ideas? – Lawng Sep 03 '15 at 00:30
  • @Lawng Why is `fun` not defined before the creation of `funMiddleMan`? – TroyHaskin Sep 03 '15 at 00:33
  • 1
    @Lawng And as for the project problem, given the length of the equation, it sounds like something that should never touch the Symbolic Toolbox, and the solution will be a problem-specific, numerical treatment. – TroyHaskin Sep 03 '15 at 00:34
  • Sorry, fun is defined before the creation of funMiddleMan but I get an error when I use fminsearch that says: Undefined function or variable 'fun'. Don't know what to make of it. And, would you please expand on this numerical treatment suggestion? I am very new to computational methods and Matlab. – Lawng Sep 03 '15 at 01:06
  • Symbolic calculations are **very** intensive, and are only ever feasible for relatively small problems. What you are describing sounds like a big problem, and so numerical methods are more appropriate, especially since `fminsearch` will not return symbolic results anyway, so there's nothing to gain by inputting a symbolic function. How you approximate/implement your function numerically is a whole other question. – David Sep 03 '15 at 01:18
  • @David Thanks. I might have to rethink this fminsearch approach. The reason why I tried it this way is because mathematica handled this same problem pretty well finishing the minimization and outputting the minimizing parameters in about an hour using their "minimization" function. – Lawng Sep 03 '15 at 01:31
  • @Lawng It looks like the error comes from `str2func` not being able to create a local workspace within the function handle it creates. That means any function call within the string needs to be a file. I'll update the answer even though you are probably moving on to a different solution method. – TroyHaskin Sep 03 '15 at 01:38
  • @TroyHaskin It would be awesome if you update it since I don't quite understand how to implement what you just said. I would still like to try this method before moving on and delving into a numerical approach. And, thanks so much you were very helpful. – Lawng Sep 03 '15 at 01:47
  • @Lawng I've updated the answer with two methods that will work. – TroyHaskin Sep 03 '15 at 01:54
  • 1
    @TroyHaskin Just letting people know your updated method worked for me and my equation. Thanks! – Lawng Sep 03 '15 at 02:02
  • Which one @lawng? Using `eval` or the cell-array approach? – David Sep 03 '15 at 02:33
  • 1
    @David Both of them did actually. I just did a quick run and time and it turned out that the cell-array approach was a few seconds longer. Not bad when you consider the problems of the eval approach. Thanks! – Lawng Sep 03 '15 at 17:01