# Using compiled function inside NMinimize

Consider this code:

variable = Sin[x];
fun = Compile[{{x, _Real}}, variable, CompilationOptions -> {"InlineExternalDefinitions" -> True}];
NMinimize[fun[x], {x}]


This code returns:

 CompiledFunction::cfsa: Argument x at position 1 should be a machine-size real number. >>
{-1., {x -> -1.5707963267948966}}


Why do I get the error? How can I resolve this issue?

Edit

What if we use instead of Sin an expression like a+b? Because in reality I have an expression with 63 variable which must be find by NMinimize I cannot define a function of that expression and use it instead of Sin

• I cannot reproduce this pb on mma 9 macos. try x=. first? Aug 14, 2014 at 16:14
• minimizing a function of 63 variable can be a bit challenging :-) Aug 14, 2014 at 20:32
• @chris I already did it but it takes two hours to get the results. I thought if I compile the function which I want to minimize I may get some speed up. In another case, I realized that the compiled function is fast at least 3 times than when I use pure functions.
– MOON
Aug 14, 2014 at 20:38

## Update

What if we use instead of Sin an expression like a+b?

I'll try a simple example, namely minimizing $(a + 3)^2 + (b - 3)^2$. Making use of CompilationOptions, I'll define a function with two variables, then nest that inside another compiled function prior to minimization.

Needs["CompiledFunctionTools"]

myfunction = Compile[{{a}, {b}}, (a + 3)^2 + (b - 3)^2]

With[{variable = myfunction},
fun = Compile[{{a, _Real}, {b, _Real}},
variable[a, b],
"RuntimeOptions" -> {"EvaluateSymbolically" -> False},
CompilationOptions -> {"InlineCompiledFunctions" -> True},
CompilationTarget -> "C"]
];

NMinimize[fun[x, y], {x, y}]

(* {1.97215*10^-30, {x -> -3., y -> 3.}} *)


You can add // Trace to the NMinimize to check for errors. For example, if you remove the line "RuntimeOptions" -> {"EvaluateSymbolically" -> False}, adding // Trace throws up the cfsa error from before.

And again, let's check all is well with the compilation.

CompilePrint[fun]

(*
2 arguments
5 Real registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}

R0 = A1
R1 = A2
Result = R4

1   R2 = R0
2   R3 = R1
3   R4 = R2 + R3
4   Return
*)


No calls to MainEvaluate.

This works for me.

With[{variable = Sin},
fun = Compile[{{a, _Real}}, variable[a],
"RuntimeOptions" -> {"EvaluateSymbolically" -> False}]
];
NMinimize[fun[x], x]


And let's check all is well:

Needs["CompiledFunctionTools"]
With[{variable = Sin},
fun = Compile[{{a, _Real}}, variable[a],
"RuntimeOptions" -> {"EvaluateSymbolically" -> False},
CompilationTarget -> "C"]
];
CompilePrint[fun]

(*
1 argument
2 Real registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}

R0 = A1
Result = R1

1   R1 = Sin[ R0]
2   Return
*)


As to why you get this problem, this question should answer it for you: Using a compiled function inside NIntegrate gives "CompiledFunction::cfsa" message

• What if we use instead of Sin an expression like a+b? Because in reality I have an expression with 63 variable which must be find by NMinimize I cannot define a function of that expression and use it instead of Sin.
– MOON
Aug 14, 2014 at 19:55
• Does my edit answer your question? Aug 15, 2014 at 8:57
• Yes it works. Thank you. Although I have to install C compiler to use the CompilationTarget.
– MOON
Aug 15, 2014 at 9:41
• Sorry yes, though the Windows SDK should be straightforward enough to download. Aug 15, 2014 at 9:45
• I am in need of the similar thing (hopefully) to speed up my optimization. I might be wrong. But did you compile the function twice? (very top example of your post) First compile the function myfunction, then fun again. Dec 16, 2014 at 1:17

In principle 63 variable is not a problem.

Lets define them

var = Table[ToExpression["x" <> ToString[i]], {i, 64}];


Q = var.var;


This defines the function

fun =
Compile[Sequence@Map[{{#, _Real}} &, var] // Evaluate, Q,
CompilationOptions -> {"InlineExternalDefinitions" -> True}];


and the minimization proceeds as it should

NMinimize[fun @@ var, var]

(*
==> {0., {x1 -> 0., x2 -> 0., x3 -> 0., x4 -> 0., x5 -> 0.,
x6 -> 0., x7 -> 0., x8 -> 0., x9 -> 0., x10 -> 0., x11 -> 0.,
x12 -> 0., x13 -> 0., x14 -> 0., x15 -> 0., x16 -> 0., x17 -> 0.,
x18 -> 0., x19 -> 0., x20 -> 0., x21 -> 0., x22 -> 0., x23 -> 0.,
x24 -> 0., x25 -> 0., x26 -> 0., x27 -> 0., x28 -> 0., x29 -> 0.,
x30 -> 0., x31 -> 0., x32 -> 0., x33 -> 0., x34 -> 0., x35 -> 0.,
x36 -> 0., x37 -> 0., x38 -> 0., x39 -> 0., x40 -> 0., x41 -> 0.,
x42 -> 0., x43 -> 0., x44 -> 0., x45 -> 0., x46 -> 0., x47 -> 0.,
x48 -> 0., x49 -> 0., x50 -> 0., x51 -> 0., x52 -> 0., x53 -> 0.,
x54 -> 0., x55 -> 0., x56 -> 0., x57 -> 0., x58 -> 0., x59 -> 0.,
x60 -> 0., x61 -> 0., x62 -> 0., x63 -> 0., x64 -> 0.}}
*)


It works more generally for another objective function

 Q = (var - Table[i, {i, 64}]) //(#.# + (#.#)^2) &;
fun = Compile[Sequence@Map[{{#, _Real}} &, var] // Evaluate, Q,
CompilationOptions -> {"InlineExternalDefinitions" -> True}];
NMinimize[fun @@ var, var];//Timing


(* ===> 0.78 sec. *)

• I got this error, although it returns the answer: CompiledFunction::cfsa: Argument x1 at position 1 should be a machine-size real number. >>
– MOON
Aug 14, 2014 at 21:00
• There's not much point in compiling this though, because when you check CompilePrint[fun] it has lots of calls to MainEvaluate? Indeed, if I just run NMinimize[Q, var] // AbsoluteTiming it takes 0.35 seconds and returns the correct answer with no errors. Aug 15, 2014 at 9:05
• sure but the OP wanted to demonstrate that the pb came from compilation over 63 variables. Aug 15, 2014 at 9:08
• Yep fair point! Aug 15, 2014 at 9:10