0
$\begingroup$

I hope to compile a complicated function with the process that create an complex list and sum over it. However, system always tell me the output should be a real number and I cannot change them. How can I set type of return or is there other methods to solve this?

In[1]:= Needs["CCompilerDriver`GenericCCompiler`"]

In[2]:= ot = Subdivide @@ N[{-3, 3, 3600*4}];

In[3]:= st = RandomReal[1, 10000];

In[4]:= ucgf = Function[{om}, Total[1/(om + I*0.001 - st), 1]]

Out[4]= Function[{om}, Total[1/(om + I 0.001 - st), 1]]

In[5]:= gf1 = 
 Compile[{{omega, _Real}}, ucgf[omega], RuntimeOptions -> "Speed", 
  RuntimeAttributes -> Listable, Parallelization -> True, 
  CompilationOptions -> {"InlineExternalDefinitions" -> True}, 
  CompilationTarget -> "C"]

In[6]:= gf1[1]

During evaluation of In[6]:= CompiledFunction::cfse: Compiled expression 70281.2 -15548.9 I should be a machine-size real number.

During evaluation of In[6]:= CompiledFunction::cfexe: Could not complete external evaluation; proceeding with uncompiled evaluation.

Out[6]= 70281.2 - 15548.9 I

In[7]:= ucgf2[om_] := Total[1/(om + I*0.001 - st), 1]

In[8]:= gf2 = 
 Compile[{{omega, _Real}}, ucgf2[omega], {{ucgf2[_], _Complex, 0}}, 
  RuntimeOptions -> "Speed", RuntimeAttributes -> Listable, 
  Parallelization -> True, 
  CompilationOptions -> {"InlineExternalDefinitions" -> True}, 
  CompilationTarget -> "C"]

In[9]:= ucgf2[2]// AbsoluteTiming

Out[9]= {0.0002784, 70016.2 - 16548.8 I}

In[10]:= gf[2]// AbsoluteTiming

Out[10]= {0.0002784, 70016.2 - 16548.8 I}

We can see in gf1, Mathematica compile the return should be a real number and directly run in interpreter. And in gf2, I define an external function ucgf2 then add into compilation, and declear it is a complex number. Now the kernel does not throw an error, but not compile at all. The time elapse of compiled function and original ucgf2 are the same, no acceleration. Therefore, is there a method to compile successfully without error and improve its efficiency?

$\endgroup$
2

1 Answer 1

2
$\begingroup$

I see that your compiled code is 2x faster than the uncompiled code

SeedRandom[1];
st = RandomReal[1, 10000];


fc =
  Compile[
   {{omega, _Real}},
   Block[
    {list},
    list = 1/(omega + I*0.001 - st);
    Total[list]
    ],
   RuntimeOptions -> "Speed",
   RuntimeAttributes -> Listable,
   Parallelization -> True,
   CompilationOptions -> {"InlineExternalDefinitions" -> True},
   CompilationTarget -> "C"
   ];
{fcTime, fcResult} = RepeatedTiming[fc@Range[1000]];


f[omega_] := Total[1/(omega + I*0.001 - st)];
{fTime, fResult} = RepeatedTiming[f /@ Range[1000]];

fcTime (* 0.0448778 *)
fTime (* 0.0905876 *)

fcResult == fResult (* True *)
$\endgroup$
1
  • 1
    $\begingroup$ Thank you so much for your reply. I understand. You use CompilationOptions -> {"InlineExternalDefinitions" -> True}. This makes great contribution. $\endgroup$
    – swish47
    Oct 26, 2022 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.