Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The following function is defined for Real input:

FFc = Compile[{{x, _Real}, {EF, _Real}},If[x > EF, 0., If[x == EF, 0.5, 1.]]]

FFc is now used in the function called foo:

EBoundary = 6.5;
foo[Ef_?NumericQ] := NIntegrate[FFc[x, Ef] , {x, -EBoundary, EBoundary}]

When I call foo like

foo[3.2]

I get an error message:

CompiledFunction::cfsa: "Argument x at position 1 should be a machine-size real number.

Since I'm using real numbers I have no idea why I get this message. What is the problem? Is it because If[] can return 0?

share|improve this question
up vote 14 down vote accepted

It's because FFc is being passed x and Ef symbolically, at first. To cure the problem, add an intermediate function between FFc and NIntegrate, such as

f[x_?NumericQ, Ef_?NumericQ] := FFc[x,Ef]

then

foo[Ef_?NumericQ] := NIntegrate[f[x, Ef] , {x, -EBoundary, EBoundary}]
share|improve this answer
3  
Do you perhaps know why adding "RuntimeOptions" -> {"EvaluateSymbolically" -> False} to FFc does not cure the problem? – Ajasja Jan 18 '13 at 9:40
1  
@Ajasja Seems related to why FFc[-x,0.] gives error while FFc[x,0.] doesn't. I wonder why NIntegrate passes -x as argument to the function. (This comment is assuming {"EvaluateSymbolically" -> False}) – ssch Jan 18 '13 at 12:20
    
@Ajasja Seems if the integration region is {x,-a,a} it doesn't work, while it is unsymmetric like {x,-a-0.00001,a} it does – ssch Jan 18 '13 at 12:26
    
@Ajasja no idea. Compile is not my strong suit. – rcollyer Jan 18 '13 at 13:14
    
Thanks. Perhaps @OleksandR will see this:) – Ajasja Jan 18 '13 at 13:47

This answer addresses Ajasja's question in rcollyer's answer:

Do you perhaps know why adding "RuntimeOptions" -> {"EvaluateSymbolically" -> False} to FFc does not cure the problem?

This is due to the fact that the methods inside NIntegrate[] (attempt to) perform a preliminary symbolic analysis, which can be helpful for integrands composed of built-in mathematical functions, but not terribly useful for compiled functions. Thus, one has to turn it off in this case, in addition to enabling the compilation options mentioned by Ajasja.

Here is a quick demonstration:

FFc = Compile[{{x, _Real}, {EF, _Real}}, 
              If[x > EF, 0., If[x == EF, 0.5, 1.]], 
              "RuntimeOptions" -> {"EvaluateSymbolically" -> False}];

With the default setting, we get this (Mathematica 10.4):

NIntegrate[FFc[x, 3.2], {x, -6.5, 6.5}]
CompiledFunction::cfsa: Argument -x at position 1 should be a machine-size real number.
CompiledFunction::cfsa: Argument -x at position 1 should be a machine-size real number.
NIntegrate::slwcon: Numerical integration converging too slowly; suspect one of the
following: singularity, value of the integration is 0, highly oscillatory integrand, or
WorkingPrecision too small.
NIntegrate::ncvb: NIntegrate failed to converge to prescribed accuracy after 9
recursive bisections in x near {x} = {3.22441}. NIntegrate obtained 9.699759342263453`
and 0.0005405922634428764` for the integral and error estimates.

before 9.69976 is returned. In contrast, if we disable symbolic processing like so:

NIntegrate[FFc[x, 3.2], {x, -6.5, 6.5}, Method -> {Automatic, "SymbolicProcessing" -> 0}]
NIntegrate::slwcon: Numerical integration converging too slowly; suspect one of the
following: singularity, value of the integration is 0, highly oscillatory integrand, or
WorkingPrecision too small.
NIntegrate::ncvb: NIntegrate failed to converge to prescribed accuracy after 9
recursive bisections in x near {x} = {3.22441}. NIntegrate obtained 9.699759342263453`
and 0.0005405922634428764` for the integral and error estimates.

we no longer get the CompiledFunction::cfsa message.

share|improve this answer
    
Nice find and explanation. – rcollyer Mar 30 at 12:43
    
@rcollyer, I think this was asked during one of my hiatuses, so I had missed it until Jason linked to it in another question. :) – J. M. Mar 30 at 13: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.