According to List of compilable functions, Erf
and Erfc
are compilable functions.
However, I want to make a compiled version of the PDF
of a VoigtDistribution
to use in a NonlinearModelFit
, and it doesn't seem that the Erfc
of a complex value will compile:
funcReal =
Compile[{{x, _Real}}, Erfc[x I], CompilationTarget -> "C",
RuntimeOptions -> "Speed"]
funcComplex =
Compile[{{x, _Complex}}, Erfc[x I], CompilationTarget -> "C",
RuntimeOptions -> "Speed"]
Needs["CompiledFunctionTools`"];
CompilePrint[funcReal] (*same as funcComplex*)
1 argument
2 Real registers
4 Complex registers
Underflow checking off
Overflow checking off
Integer overflow checking off
RuntimeAttributes -> {}
R0 = A1
C0 = 0. + 1. I
R1 = 0.
Result = C3
1 C1 = R0 + R1 I
2 C1 = C1 * C0
3 C2 = R0 + R1 I
4 C2 = C2 * C0
5 C3 = MainEvaluate[ Hold[Erfc][ C2]]
6 Return
Note the call to MainEvaluate
:
Erfc[I] // N
funcReal[1]
funcComplex[1]
1. - 1.65043 I
1. - 1.65043 I
1. - 1.65043 I
All the functions work, but because of the MainEvaluate
, they offer no performance benefit. How can I compile this function? Is this possible? Is there an alternative formula I could use?
Removing the CompilationTarget
doesn't solve the problem either.
Answer
From the documentation, we have a pseudo-Voigt Distribution that might be used as an approximation. This might be useful as a basis for making a compilable function.
PseudoVoigtDistribution[δ_, σ_] :=
Block[{g = (δ^5 + σ^5 + 2.69296 σ^4 δ + 2.42843 σ^3 δ^2 +
4.47163 σ^2 δ^3 + 0.07842 σ δ^4)^(1/5), η},
η = δ/g;
η = η*(1.36603 - 0.47719 η + 0.11116 η^2);
MixtureDistribution[{1 - η, η}, {NormalDistribution[0, g],
CauchyDistribution[0, g]}]
]
Comments
Post a Comment