MathGroup Archive 2007

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Non-numeric arguments to Compile-d functions

  • To: mathgroup at smc.vnet.net
  • Subject: [mg82131] Re: Non-numeric arguments to Compile-d functions
  • From: Szabolcs Horvát <szhorvat at gmail.com>
  • Date: Sat, 13 Oct 2007 03:44:42 -0400 (EDT)
  • References: <fen75j$5bi$1@smc.vnet.net>

Andrew Moylan wrote:
> Here's a compiled function that does some (made-up) operation on a
> real-valued function f:
> 
> Compile[{},
>  Do[If[f[i] < 0, Return[{i, f[i]}]], {i, 10}],
>  {{f[_], _Real}}
> ]
> 
> (It finds the first integer i such that f[i] is negative.)
> 
> For the usual reasons of modularity, I would like to make compiled functions
> like this not refer to global variables named f. (We can't put f as one of
> the elements of the first argument to compile, because those must all be
> numeric scalars or arrays.)
> 
> Here's one way to do this:
> 
> Module[
>  {f, compiledpart},
> 
>  compiledpart = Compile[{},
>    Do[If[f[i] < 0, Return[{i, f[i]}]], {i, 10}],
>    {{f[_], _Real}}
>    ];
> 
>  findfirstnegative[tempf_] := (compiledpart /. f -> tempf)[]
> ]
> 
> I don't really like this solution because we needed to use two names (f and
> tempf). Using two names per argument could get messy if there are several
> non-numeric arguments instead of just f.
> 
> Is this the recommended method for compiling "as much of a function as
> possible"?
> 
> Note that the following attempt (which doesn't need a tempf) doesn't work:
> 
> With[{rhs = compiledpart}, findfirstnegative[f_] := rhs]
> 
> It fails because Mathematica automatically renames the f in the
> CompiledFunction in compiledpart to *avoid* the very naming clash I am
> trying to create. The With statement effectively creates:
> 
> findfirstnegative[f$_] := CompiledFunction[{},
>   Do[If[f$851[i]<0, Return[{i,f$851[i]}]], {i,10}],
>   -CompiledCode-
> ]
> 
> What's the neatest, "right" way to make compiled functions that take
> non-numeric arguments?
> 
> 

Hi Andrew,

What's wrong with simply using the following?

fun[f_] = Compile[{}, Do[If[f[i] < 0, Return[{i, f[i]}]], {i, 10}],
      {{f[_], _Real}}]

findfirstnegative[f_Function] := fun[f][]

Of course you have to make sure that 'f' is not defined before you issue 
these definitions, but this is not a problem when you are developing a 
package.

I believe that Module and With weren't meant to be used in this way 
(i.e. to define new functions *inside* them).  When you create packages, 
use contexts to isolate those symbols which should not be exported.

But to be honest, I'm a bit tired now and it is possible that I 
misunderstood your question ...

-- 
Szabolcs


  • Prev by Date: Re: ReplaceAll behavour
  • Next by Date: Re: Evaluation question
  • Previous by thread: Non-numeric arguments to Compile-d functions
  • Next by thread: Re: JLink