From: Scot T. Martin on
Has anyone ever run into the problem of trying to use Compile'd functions
within FindRoot?

The error message is:

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

[Yes, the function still evaluates but in doing so the purpose of compile
& speed gets defeated.]

The explanation for this error messages is found in ref/FindRoot:

"FindRoot first localizes the values of all variables, then evaluates f
with the variables being symbolic [1], and then repeatedly evaluates the
result numerically." [1] That's why Compile[] fails.

Here is a specific example of code that shows the problem:

*****

func = Compile[{x}, x^2];

FindRoot[func[y] == 1, {y, 0.5, 1.5}]

*****

Anyone have thoughts on how to work around this aspect so that Compile'd
functions can work within FindRoot and thus accelerate evaluation thereof?
[Or is there an inherent reason why they shouldn't?]

[My actual function is not "func"; my actual func is 3x faster as a
Compile'd, hence my motivation to get FindRoot to work.]

Thanks!


From: Mark Adler on
On 2010-07-26 03:38:23 -0700, Scot T. Martin said:
> Anyone have thoughts on how to work around this aspect so that
> Compile'd functions can work within FindRoot and thus accelerate
> evaluation thereof?

FindRoot already compiles, which may be why you're not seeing a
difference. Try FindRoot[uncompiled expression, ..., Compiled->False]
and see if it's slower than FindRoot[uncompiled expression, ...].

If you want to pre-compile, you can just turn the message off with
Off[CompiledFunction::cfsa]. The message is just a performance
warning, since when it is issued, it uses the symbolic expression to
get the correct answer anyway. It must only be calling the function
once with symbolic arguments, since otherwise you'd see that message
three times.

Mark

From: Bob Hanlon on

func = Compile[{{x, _Real}}, x^2];

FindRoot[func[y] == 1,
{y, 0.5, 1.5}] // Quiet

{y -> 0.9999999999999993}

FindRoot[func[y] == 1,
{y, #}] & /@
{-.5, .5} // Quiet

{{y -> -1.000000000000001},
{y -> 1.000000000000001}}

Solve[func[y] == 1, y] //
Quiet

{{y -> -1}, {y -> 1}}

Reduce[func[y] == 1, y] //
Quiet

y == -1 || y == 1


Bob Hanlon

---- "Scot T. Martin" <smartin(a)seas.harvard.edu> wrote:

=============
Has anyone ever run into the problem of trying to use Compile'd functions
within FindRoot?

The error message is:

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

[Yes, the function still evaluates but in doing so the purpose of compile
& speed gets defeated.]

The explanation for this error messages is found in ref/FindRoot:

"FindRoot first localizes the values of all variables, then evaluates f
with the variables being symbolic [1], and then repeatedly evaluates the
result numerically." [1] That's why Compile[] fails.

Here is a specific example of code that shows the problem:

*****

func = Compile[{x}, x^2];

FindRoot[func[y] == 1, {y, 0.5, 1.5}]

*****

Anyone have thoughts on how to work around this aspect so that Compile'd
functions can work within FindRoot and thus accelerate evaluation thereof?
[Or is there an inherent reason why they shouldn't?]

[My actual function is not "func"; my actual func is 3x faster as a
Compile'd, hence my motivation to get FindRoot to work.]

Thanks!


From: Szabolcs Horvát on
On 2010.07.26. 12:38, Scot T. Martin wrote:
> Has anyone ever run into the problem of trying to use Compile'd functions
> within FindRoot?
>
> The error message is:
>
> "CompiledFunction::cfsa: Argument y at position 1 should be a machine-size
> real number."
>
> [Yes, the function still evaluates but in doing so the purpose of compile
> & speed gets defeated.]
>
> The explanation for this error messages is found in ref/FindRoot:
>
> "FindRoot first localizes the values of all variables, then evaluates f
> with the variables being symbolic [1], and then repeatedly evaluates the
> result numerically." [1] That's why Compile[] fails.
>
> Here is a specific example of code that shows the problem:
>
> *****
>
> func = Compile[{x}, x^2];
>
> FindRoot[func[y] == 1, {y, 0.5, 1.5}]
>
> *****
>
> Anyone have thoughts on how to work around this aspect so that Compile'd
> functions can work within FindRoot and thus accelerate evaluation thereof?
> [Or is there an inherent reason why they shouldn't?]
>
> [My actual function is not "func"; my actual func is 3x faster as a
> Compile'd, hence my motivation to get FindRoot to work.]
>


Hello,

As you noticed, the problem appears because func[y] is evaluated by
FindRoot even before a number is substituted for y.

A workaround is to define a function that is evaluated for numeric
arguments only:

func2[x_?NumericQ] := func[x]

FindRoot[func2[y] == 1, {y, 0.5, 1.5}]