MathGroup Archive 1999

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

Search the Archive

RE: compiling problem

  • To: mathgroup at smc.vnet.net
  • Subject: [mg18956] RE: [mg18933] compiling problem
  • From: "Ersek, Ted R" <ErsekTR at navair.navy.mil>
  • Date: Fri, 30 Jul 1999 01:33:46 -0400
  • Sender: owner-wri-mathgroup at wolfram.com

Kiran Shrestha  wrote:
--------------------------------------
Can anybody teach me how to compile a function of several variables which
are values of other functions. For example, I have a function           

f[x_, y_]:= alpha[x] + alpha[y] - beta[x]/beta[y].

The alpha and beta function values are known. 

---------------------------------------

I think you need to include the calculation of alpha and beta in the
CompiledFunction.  For example suppose alpah and beta are defined as:

alpha[a_]:=x Exp[-x];
beta[b_]:=2+Sin[b];
f[x_, y_]:= alpha[x] + alpha[y] - beta[x]/beta[y]

-------------
Then I would use Compiled as below.  

Note:
It's a good idea to make sure the Compiled function is translated into
"op-code" by evaluating  f[[-2]].  If f[[-2]] returns a list of lists where
each sublist is a list of integers all is well.  Any portions represented
otherwise probably couldn't be converted to op-code, and the compiled
function will probably not run very fast.

In[1]:=
f=Compile[{x,y},x Exp[-x]+y Exp[y]-(2+Sin[x])/(2+Sin[y])];

In[6]:=
f[[-2]]

Out[6]=
{{1,3},{38,0,2},{95,34,3,0,2,3,0,3},{34,0,3,2},{95,34,3,0,1,3,0,3},{34,1,3,3
},{9,2,0},{95,1,3,0,0,3,0,4},{19,0,0,5},{30,5,4,4},{9,2,0},{95,1,3,0,1,3,0,5
},{19,0,0,6},{30,6,5,5},{41,5,5},{34,4,5,4},{38,4,5},{30,2,3,5,2},{4,2}}


Keep in mind that not all math functions in the Mathematica kernel can be
converted to op-code.  A list of functions that can is available at:
http://support.wolfram.com/Kernel/Symbols/System/Compile.html


Note:
Factorial can't be converted to opcode, so the function below doesn't run
very fast.  Instead one should replace Factorial[n] with (Times@@Range[n]).

In[20]:=
f1=Compile[{{x,_Real},{n,_Integer}},x^n/Factorial[n]];

When you evaluate the line above you don't get a message indicating
Factorial[n] couldn't be converted to op-code.  In version 4 one can use the
following line to set a system option to cause posting of such messages (as
demonstrated below).

In[21]:=
Developer`SetSystemOptions["CompileReportExternal"->True];

In[22]:=
f2=Compile[{{x,_Real},{n,_Integer}},x^n/ Factorial[n]];

Compile::extscalar: n! can not be compiled and will be evaluated externally.
The result is assumed to be of type integer.

 
-----------------------------
The Compile messages are listed in the Help Browser under
  Other Information > Warning Messages > Compile


I read over these messages, and came up with the 
following requirements for Compile to work:

- All variables must have numeric or True/False values.

- Compiled evaluation has no speed advantage if some 
  numeric values encountered are not machine numbers.

- The type of expression returned from each subexpression 
  in the compiled function must be known.

- If Apply is used the first argument must have the head 
  Plus, Times, or List.

- If Outer is used the first argument must have the head 
  Plus, Times, or List.

- (Tr) can be used with two arguments only when the second 
   argument is Plus, Times, or List.

- If an expression returns a tensor, the compiled function 
  interpreter needs to be able to determine the rank of the tensor.

- Empty tensors such as {},or {{},{},{}},or {{{}},{{}}} can't be 
  used in a compiled function.

- The second argument of Compile can't include Patterns.

- The only types compiled functions can work with are 
  (_Integer,_Real,_Complex,True|False)

- The only list structures compiled functions can work with 
  are vectors, matrices, and (other tensors with rank<101).

- A variable in a compiled function has to keep the same type.

- Local variables used in compiled evaluation must have a 
  numeric value when they are used.

- Certain functions supported by Compile don't work in situations 
  as general as they do in uncompiled evaluation.
  e.g.  In compiled evaluation Floor can't take a complex argument.


-----------------------------------------
Here is an example where Compile has trouble.  
A global variable can't be represented using op-code.  

The compiled function(f2) below isn't converted to op-code because the
global variable (w) issued in the function.  The best way around this known
to me, is to provide the global variable to the function as an argument.

f1=Compile

In[7]:=
w = 0.25;
f2 = Compile[{x}, (x^2 + Sqrt[Exp[x]]+w)];
f2[[-2]]

Out[9]=
{{1,3},{15,0,1},{34,1,1,2},{95,34,3,0,0,3,0,3},{95,54,3,0,3,3,0,4},{26,Funct
ion[{x},w],3,0,0,3,0,5},{30,2,4,5,6},{4,6}}

-----------------------------------------
Here is another example where Compile has trouble.
You can't use opcode to change the value of a function's argument.  The
CompiledFunction below doesn't convert to op-code because the function
changes the value of (x) (one of the function's arguments).

In[10]:=
f3=Compile[{x,y},
     x=Floor[y];
     x+y
];
f3[[-2]]

Out[11]=
{{1,3},{26,Function[{x,y},x=Floor[y]],3,0,0,3,0,1,6,0,17},{30,0,1,2},{4,2}}

---------------------------------
This next feature is only available in versions 3.0 and later. 
Using  Compile[{{x1,t1,n1}, ...},expr] (x1) is a rank (n1) tensor where each
element has the type (t1).  A vector is a rank 1 tensor, and a matrix is a
rank 2 tensor.

In[23]:=
magnitude = 
  Compile[{{vector, _Real, 1}}, Sqrt[Plus @@ vector^2] ];


In[24]:=
magnitude[{2.3,4.5,1.6,6.7,8.9}]

Out[24]=
12.3369

--------------------------
This next example uses the same feature as the last and 
is only available in versions 3.0 and later. 
Compile[{{x, _Real, 2}}, ...] takes an argument that is a matrix of real
numbers.  The matrix can have any dimensions.  As an example a
CompiledFunction (func) is defined below.  The function (func) takes two
matrices of real numbers named (a) and (p) and computes
(p)(a)(Inverse[p])


In[25]:=
func=Compile[{{a,_Real,2},{p,_Real,2}},(p.a.Inverse[p])];

A demonstration of (func) is given below.

In[32]:=
x={{1.2,4.3,0.1},{0.2,1.4,0.2},{0.1,0.3,0.4}};
y={{1.2,0.2,0.},{0.3,1.5,2.3},{0.2,2.2,0.7}};
result=func[x,y]

Out[34]=
{{0.948593,-0.828727,2.95153},{0.44076,-0.0110458,1.82201},{0.357749,-0.3059
64,2.06245}}

------------------------------

Regards,
Ted Ersek


  • Prev by Date: Mathematica Programmer
  • Next by Date: Incompatibility between CleanSlate and Export
  • Previous by thread: compiling problem
  • Next by thread: Re: $UserDirectory