Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

share|improve this question
    
I cannot reproduce this pb on mma 9 macos. try x=. first? –  chris Aug 14 at 16:14
    
minimizing a function of 63 variable can be a bit challenging :-) –  chris Aug 14 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. –  yashar Aug 14 at 20:38

2 Answers 2

up vote 4 down vote accepted

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

share|improve this answer
    
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. –  yashar Aug 14 at 19:55
    
Does my edit answer your question? –  blochwave Aug 15 at 8:57
    
Yes it works. Thank you. Although I have to install C compiler to use the CompilationTarget. –  yashar Aug 15 at 9:41
    
Sorry yes, though the Windows SDK should be straightforward enough to download. –  blochwave Aug 15 at 9:45

In principle 63 variable is not a problem.

Lets define them

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

and a Quadratic function

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. *)

share|improve this answer
    
I got this error, although it returns the answer: CompiledFunction::cfsa: Argument x1 at position 1 should be a machine-size real number. >> –  yashar Aug 14 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. –  blochwave Aug 15 at 9:05
    
sure but the OP wanted to demonstrate that the pb came from compilation over 63 variables. –  chris Aug 15 at 9:08
    
Yep fair point! –  blochwave Aug 15 at 9:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.