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
Answer
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
.
Original answer
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
Comments
Post a Comment