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