How to speed up Voigt profile fits?Compiling the VoigtDistribution PDFGetting lengths of sublists that sum to more than oneHow to Output Chi-Squared Statistics when using NonLinearModelFitModule in numerical model for NonlinearModelFit is slow and leaks memoryOptimizing code containing an infinite sumP-Values are inconsistent when using DistributionFitTest repeatedlyStill more problems with Fitting, please helpNon-linear curve fit problemCurve fitting using an asymmetrical sigmoid functionFitting a Voigt distribution - never finishesFitting data to an empirical distribution, finding best fit
Existence of subset with given Hausdorff dimension
Are all passive ability checks floors for active ability checks?
Dice rolling probability game
SOQL: Populate a Literal List in WHERE IN Clause
Instead of Universal Basic Income, why not Universal Basic NEEDS?
Why doesn't using two cd commands in bash script execute the second command?
Employee lack of ownership
Life insurance that covers only simultaneous/dual deaths
Do I need life insurance if I can cover my own funeral costs?
Why do Australian milk farmers need to protest supermarkets' milk price?
Why one should not leave fingerprints on bulbs and plugs?
Co-worker team leader wants to inject his friend's awful software into our development. What should I say to our common boss?
The difference between「N分で」and「後N分で」
A sequence that has integer values for prime indexes only:
Do the common programs (for example: "ls", "cat") in Linux and BSD come from the same source code?
Have researchers managed to "reverse time"? If so, what does that mean for physics?
Is there a data structure that only stores hash codes and not the actual objects?
How to deal with taxi scam when on vacation?
Brexit - No Deal Rejection
Time travel from stationary position?
Happy pi day, everyone!
How do anti-virus programs start at Windows boot?
Why is the President allowed to veto a cancellation of emergency powers?
If I can solve Sudoku can I solve Travelling Salesman Problem(TSP)? If yes, how?
How to speed up Voigt profile fits?
Compiling the VoigtDistribution PDFGetting lengths of sublists that sum to more than oneHow to Output Chi-Squared Statistics when using NonLinearModelFitModule in numerical model for NonlinearModelFit is slow and leaks memoryOptimizing code containing an infinite sumP-Values are inconsistent when using DistributionFitTest repeatedlyStill more problems with Fitting, please helpNon-linear curve fit problemCurve fitting using an asymmetrical sigmoid functionFitting a Voigt distribution - never finishesFitting data to an empirical distribution, finding best fit
$begingroup$
Voigt profile fits in Mathematica seem terribly slow. For an example data set with 81 points a corresponding fitting procedures for Voigt fits is >1000 times slower than for Gaussian or Lorentzian profile. How can Voigt profile fits be speed up?
Here is what I do. First we define the Voigt and Gaussian profile. As Mathematica often complains about δ
and σ
being <0, I use Abs instead of constraining the model as this proved faster. In addition I use the compile command to make the function even faster.
voigtprofile = Compile[δ, _Real, 0, σ, _Real, 0, A, _Real,0, ν0,_Real, 0, ν, _Real, 0, A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]];
gaussian[σ_, A_, ν0_, ν_] := Return[A PDF[NormalDistribution[ν0, σ], ν]];
Then I create noisy example data sets with a bit of noise:
noisyDataV = #,
voigtprofile[0.15, 0.1, 1, 0, #] + RandomReal[-0.1, 0.1] & /@ Range[-2, 2, 0.05];
noisyDataG = #, gaussian[0.1, 1, 0, #] + RandomReal[-0.1, 0.1] & /@
Range[-2, 2, 0.05];
And we use NonlinearModelFit to fit the data with excellent start parameters:
tv = AbsoluteTiming[vfit = NonlinearModelFit[noisyDataV,
voigtprofile[δ, σ,
A, ν0, ν], δ, 0.15, σ, 0.1, A,
1, ν0, 0, ν];]
tg = AbsoluteTiming[gfit = NonlinearModelFit[noisyDataG,
gaussian[σ,
A, ν0, ν], σ, 0.1, A, 1, ν0,
0, ν];]
And if we compare the required time for fit:
tv[[1]]/tg[[1]]
I get values between 1000 and 6000, which is terrible. In addition, selecting a fit Method
e.g. NMinimize
or other does at best yield the same result.
As this minimal example is just a very simple example, times scale up to unbearable long times for more realistic scenarios with real data.
I'm glad for any hint on how to speed this simple example up.
performance-tuning fitting nonlinear
New contributor
$endgroup$
add a comment |
$begingroup$
Voigt profile fits in Mathematica seem terribly slow. For an example data set with 81 points a corresponding fitting procedures for Voigt fits is >1000 times slower than for Gaussian or Lorentzian profile. How can Voigt profile fits be speed up?
Here is what I do. First we define the Voigt and Gaussian profile. As Mathematica often complains about δ
and σ
being <0, I use Abs instead of constraining the model as this proved faster. In addition I use the compile command to make the function even faster.
voigtprofile = Compile[δ, _Real, 0, σ, _Real, 0, A, _Real,0, ν0,_Real, 0, ν, _Real, 0, A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]];
gaussian[σ_, A_, ν0_, ν_] := Return[A PDF[NormalDistribution[ν0, σ], ν]];
Then I create noisy example data sets with a bit of noise:
noisyDataV = #,
voigtprofile[0.15, 0.1, 1, 0, #] + RandomReal[-0.1, 0.1] & /@ Range[-2, 2, 0.05];
noisyDataG = #, gaussian[0.1, 1, 0, #] + RandomReal[-0.1, 0.1] & /@
Range[-2, 2, 0.05];
And we use NonlinearModelFit to fit the data with excellent start parameters:
tv = AbsoluteTiming[vfit = NonlinearModelFit[noisyDataV,
voigtprofile[δ, σ,
A, ν0, ν], δ, 0.15, σ, 0.1, A,
1, ν0, 0, ν];]
tg = AbsoluteTiming[gfit = NonlinearModelFit[noisyDataG,
gaussian[σ,
A, ν0, ν], σ, 0.1, A, 1, ν0,
0, ν];]
And if we compare the required time for fit:
tv[[1]]/tg[[1]]
I get values between 1000 and 6000, which is terrible. In addition, selecting a fit Method
e.g. NMinimize
or other does at best yield the same result.
As this minimal example is just a very simple example, times scale up to unbearable long times for more realistic scenarios with real data.
I'm glad for any hint on how to speed this simple example up.
performance-tuning fitting nonlinear
New contributor
$endgroup$
4
$begingroup$
Have you seen this?
$endgroup$
– J. M. is slightly pensive♦
15 hours ago
add a comment |
$begingroup$
Voigt profile fits in Mathematica seem terribly slow. For an example data set with 81 points a corresponding fitting procedures for Voigt fits is >1000 times slower than for Gaussian or Lorentzian profile. How can Voigt profile fits be speed up?
Here is what I do. First we define the Voigt and Gaussian profile. As Mathematica often complains about δ
and σ
being <0, I use Abs instead of constraining the model as this proved faster. In addition I use the compile command to make the function even faster.
voigtprofile = Compile[δ, _Real, 0, σ, _Real, 0, A, _Real,0, ν0,_Real, 0, ν, _Real, 0, A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]];
gaussian[σ_, A_, ν0_, ν_] := Return[A PDF[NormalDistribution[ν0, σ], ν]];
Then I create noisy example data sets with a bit of noise:
noisyDataV = #,
voigtprofile[0.15, 0.1, 1, 0, #] + RandomReal[-0.1, 0.1] & /@ Range[-2, 2, 0.05];
noisyDataG = #, gaussian[0.1, 1, 0, #] + RandomReal[-0.1, 0.1] & /@
Range[-2, 2, 0.05];
And we use NonlinearModelFit to fit the data with excellent start parameters:
tv = AbsoluteTiming[vfit = NonlinearModelFit[noisyDataV,
voigtprofile[δ, σ,
A, ν0, ν], δ, 0.15, σ, 0.1, A,
1, ν0, 0, ν];]
tg = AbsoluteTiming[gfit = NonlinearModelFit[noisyDataG,
gaussian[σ,
A, ν0, ν], σ, 0.1, A, 1, ν0,
0, ν];]
And if we compare the required time for fit:
tv[[1]]/tg[[1]]
I get values between 1000 and 6000, which is terrible. In addition, selecting a fit Method
e.g. NMinimize
or other does at best yield the same result.
As this minimal example is just a very simple example, times scale up to unbearable long times for more realistic scenarios with real data.
I'm glad for any hint on how to speed this simple example up.
performance-tuning fitting nonlinear
New contributor
$endgroup$
Voigt profile fits in Mathematica seem terribly slow. For an example data set with 81 points a corresponding fitting procedures for Voigt fits is >1000 times slower than for Gaussian or Lorentzian profile. How can Voigt profile fits be speed up?
Here is what I do. First we define the Voigt and Gaussian profile. As Mathematica often complains about δ
and σ
being <0, I use Abs instead of constraining the model as this proved faster. In addition I use the compile command to make the function even faster.
voigtprofile = Compile[δ, _Real, 0, σ, _Real, 0, A, _Real,0, ν0,_Real, 0, ν, _Real, 0, A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]];
gaussian[σ_, A_, ν0_, ν_] := Return[A PDF[NormalDistribution[ν0, σ], ν]];
Then I create noisy example data sets with a bit of noise:
noisyDataV = #,
voigtprofile[0.15, 0.1, 1, 0, #] + RandomReal[-0.1, 0.1] & /@ Range[-2, 2, 0.05];
noisyDataG = #, gaussian[0.1, 1, 0, #] + RandomReal[-0.1, 0.1] & /@
Range[-2, 2, 0.05];
And we use NonlinearModelFit to fit the data with excellent start parameters:
tv = AbsoluteTiming[vfit = NonlinearModelFit[noisyDataV,
voigtprofile[δ, σ,
A, ν0, ν], δ, 0.15, σ, 0.1, A,
1, ν0, 0, ν];]
tg = AbsoluteTiming[gfit = NonlinearModelFit[noisyDataG,
gaussian[σ,
A, ν0, ν], σ, 0.1, A, 1, ν0,
0, ν];]
And if we compare the required time for fit:
tv[[1]]/tg[[1]]
I get values between 1000 and 6000, which is terrible. In addition, selecting a fit Method
e.g. NMinimize
or other does at best yield the same result.
As this minimal example is just a very simple example, times scale up to unbearable long times for more realistic scenarios with real data.
I'm glad for any hint on how to speed this simple example up.
performance-tuning fitting nonlinear
performance-tuning fitting nonlinear
New contributor
New contributor
edited 15 hours ago
Johu
3,7031037
3,7031037
New contributor
asked 15 hours ago
Adrian BeckertAdrian Beckert
613
613
New contributor
New contributor
4
$begingroup$
Have you seen this?
$endgroup$
– J. M. is slightly pensive♦
15 hours ago
add a comment |
4
$begingroup$
Have you seen this?
$endgroup$
– J. M. is slightly pensive♦
15 hours ago
4
4
$begingroup$
Have you seen this?
$endgroup$
– J. M. is slightly pensive♦
15 hours ago
$begingroup$
Have you seen this?
$endgroup$
– J. M. is slightly pensive♦
15 hours ago
add a comment |
2 Answers
2
active
oldest
votes
$begingroup$
Thanks to J. M. for the suggestion. Instead of using the computationally intensive VoigtDistribution, we can use the Pseudo-Voigt numeric approximation from this post which exhibits very low errors compared to the analytical Voigt (see here or references in here) and speeds up the fitting procedure by approximately a factor of 100 or more.
pseudoVoigtProfile = With[n = 24, τ = 12, With[d = N[Range[n] π/τ],b = N[Exp[-(Range[n] π/τ)^2]], s = N[PadRight[, n, -1, 1]], sq = N[Sqrt[2]],sp = N[Sqrt[2 π]],
Compile[δ, _Real, σ, _Real, x, _Real,
Module[z = (x + I δ)/(σ sq), e,
e = Exp[I τ z];
Re[(I (1 -e)/(τ z) + (2 I z/τ)b.((e s -1)/((d + z) (d - z))))]/(σ sp)],
RuntimeAttributes -> Listable]]];
and fit it to the noisy test data
tpv = AbsoluteTiming[pvfit = NonlinearModelFit[noisyDataV,
pseudoVoigtProfile[δ, σ, ν - ν0], δ, 0.15, σ, 0.1, A, 1, ν0, 0, ν];]
which leads to a ratio tpv/tg ~ 10 on my computer.
Note: Although the Pseudo-Voigt profile is a numerical approximation it will do the job for most daily life applications where the noise on the e.g. optical spectrum is at least an order of magnitude larger than the numeric error of the approximation.
New contributor
$endgroup$
$begingroup$
As Voigt is Gaussian convolved by Lorentzian another approach regularly used in spectrometry is to work in Fourier space: see sites.math.washington.edu/~morrow/papers/GVmathThesis2010.pdf for instance (sorry I do not have all the details in mind for a complete answer here)
$endgroup$
– Picaud Vincent
12 hours ago
1
$begingroup$
The compiled implementation you got from my answer is a genuine implementation of the Voigt profile, nothing "pseudo" about it.
$endgroup$
– J. M. is slightly pensive♦
12 hours ago
add a comment |
$begingroup$
You can use CompilePrint
to check what Compile
actually did:
Needs["CompiledFunctionTools`"];
voigtprofile1 =
Compile[δ, _Real, 0, σ, _Real, 0, A, _Real,
0, ν0, _Real, 0, ν, _Real, 0,
A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]
];
CompilePrint[voigtprofile1]
Out[26]= "5 arguments
7 Real registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes ->
R0 = A1
R1 = A2
R2 = A3
R3 = A4
R4 = A5
Result = R6
1 R5 = MainEvaluate[ Function[δ, σ, A, ν0, ν,
PDF[VoigtDistribution[Abs[δ], Abs[σ]], ν - ν0]][ R0, R1, R2, R3, R4]]
2 R6 = R2 * R5
3 Return"
As you can see, all the function really does is call MainEvaluate
and then multiply two numbers together. Basically, you haven't compiled anything.
Instead, evaluate the PDF inside of the Compile
to get a symbolic expression that is compilable:
voigtprofile2 = Compile[
δ, _Real, 0, σ, _Real, 0, A, _Real, 0, ν0, _Real, 0, ν, _Real, 0,
Evaluate[
A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]
],
CompilationOptions -> "ExpressionOptimization" -> True,
RuntimeAttributes -> Listable
];
This should be significantly faster.
$endgroup$
1
$begingroup$
The problem with yourvoigtprofile2
is thatErfc[]
only works for real arguments within a compiled function, so it gets wrapped inMainEvaluate
. That was one reason why I wrote the routine in the thread I linked to in the comments.
$endgroup$
– J. M. is slightly pensive♦
11 hours ago
1
$begingroup$
Ok, that's handy to know. That's a specific problem ofVoigtDistribution
I didn't anticipate. I still wanted to point out the importance of usingCompilePrint
, though.
$endgroup$
– Sjoerd Smit
11 hours ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
);
);
, "mathjax-editing");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "387"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Adrian Beckert is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f193317%2fhow-to-speed-up-voigt-profile-fits%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Thanks to J. M. for the suggestion. Instead of using the computationally intensive VoigtDistribution, we can use the Pseudo-Voigt numeric approximation from this post which exhibits very low errors compared to the analytical Voigt (see here or references in here) and speeds up the fitting procedure by approximately a factor of 100 or more.
pseudoVoigtProfile = With[n = 24, τ = 12, With[d = N[Range[n] π/τ],b = N[Exp[-(Range[n] π/τ)^2]], s = N[PadRight[, n, -1, 1]], sq = N[Sqrt[2]],sp = N[Sqrt[2 π]],
Compile[δ, _Real, σ, _Real, x, _Real,
Module[z = (x + I δ)/(σ sq), e,
e = Exp[I τ z];
Re[(I (1 -e)/(τ z) + (2 I z/τ)b.((e s -1)/((d + z) (d - z))))]/(σ sp)],
RuntimeAttributes -> Listable]]];
and fit it to the noisy test data
tpv = AbsoluteTiming[pvfit = NonlinearModelFit[noisyDataV,
pseudoVoigtProfile[δ, σ, ν - ν0], δ, 0.15, σ, 0.1, A, 1, ν0, 0, ν];]
which leads to a ratio tpv/tg ~ 10 on my computer.
Note: Although the Pseudo-Voigt profile is a numerical approximation it will do the job for most daily life applications where the noise on the e.g. optical spectrum is at least an order of magnitude larger than the numeric error of the approximation.
New contributor
$endgroup$
$begingroup$
As Voigt is Gaussian convolved by Lorentzian another approach regularly used in spectrometry is to work in Fourier space: see sites.math.washington.edu/~morrow/papers/GVmathThesis2010.pdf for instance (sorry I do not have all the details in mind for a complete answer here)
$endgroup$
– Picaud Vincent
12 hours ago
1
$begingroup$
The compiled implementation you got from my answer is a genuine implementation of the Voigt profile, nothing "pseudo" about it.
$endgroup$
– J. M. is slightly pensive♦
12 hours ago
add a comment |
$begingroup$
Thanks to J. M. for the suggestion. Instead of using the computationally intensive VoigtDistribution, we can use the Pseudo-Voigt numeric approximation from this post which exhibits very low errors compared to the analytical Voigt (see here or references in here) and speeds up the fitting procedure by approximately a factor of 100 or more.
pseudoVoigtProfile = With[n = 24, τ = 12, With[d = N[Range[n] π/τ],b = N[Exp[-(Range[n] π/τ)^2]], s = N[PadRight[, n, -1, 1]], sq = N[Sqrt[2]],sp = N[Sqrt[2 π]],
Compile[δ, _Real, σ, _Real, x, _Real,
Module[z = (x + I δ)/(σ sq), e,
e = Exp[I τ z];
Re[(I (1 -e)/(τ z) + (2 I z/τ)b.((e s -1)/((d + z) (d - z))))]/(σ sp)],
RuntimeAttributes -> Listable]]];
and fit it to the noisy test data
tpv = AbsoluteTiming[pvfit = NonlinearModelFit[noisyDataV,
pseudoVoigtProfile[δ, σ, ν - ν0], δ, 0.15, σ, 0.1, A, 1, ν0, 0, ν];]
which leads to a ratio tpv/tg ~ 10 on my computer.
Note: Although the Pseudo-Voigt profile is a numerical approximation it will do the job for most daily life applications where the noise on the e.g. optical spectrum is at least an order of magnitude larger than the numeric error of the approximation.
New contributor
$endgroup$
$begingroup$
As Voigt is Gaussian convolved by Lorentzian another approach regularly used in spectrometry is to work in Fourier space: see sites.math.washington.edu/~morrow/papers/GVmathThesis2010.pdf for instance (sorry I do not have all the details in mind for a complete answer here)
$endgroup$
– Picaud Vincent
12 hours ago
1
$begingroup$
The compiled implementation you got from my answer is a genuine implementation of the Voigt profile, nothing "pseudo" about it.
$endgroup$
– J. M. is slightly pensive♦
12 hours ago
add a comment |
$begingroup$
Thanks to J. M. for the suggestion. Instead of using the computationally intensive VoigtDistribution, we can use the Pseudo-Voigt numeric approximation from this post which exhibits very low errors compared to the analytical Voigt (see here or references in here) and speeds up the fitting procedure by approximately a factor of 100 or more.
pseudoVoigtProfile = With[n = 24, τ = 12, With[d = N[Range[n] π/τ],b = N[Exp[-(Range[n] π/τ)^2]], s = N[PadRight[, n, -1, 1]], sq = N[Sqrt[2]],sp = N[Sqrt[2 π]],
Compile[δ, _Real, σ, _Real, x, _Real,
Module[z = (x + I δ)/(σ sq), e,
e = Exp[I τ z];
Re[(I (1 -e)/(τ z) + (2 I z/τ)b.((e s -1)/((d + z) (d - z))))]/(σ sp)],
RuntimeAttributes -> Listable]]];
and fit it to the noisy test data
tpv = AbsoluteTiming[pvfit = NonlinearModelFit[noisyDataV,
pseudoVoigtProfile[δ, σ, ν - ν0], δ, 0.15, σ, 0.1, A, 1, ν0, 0, ν];]
which leads to a ratio tpv/tg ~ 10 on my computer.
Note: Although the Pseudo-Voigt profile is a numerical approximation it will do the job for most daily life applications where the noise on the e.g. optical spectrum is at least an order of magnitude larger than the numeric error of the approximation.
New contributor
$endgroup$
Thanks to J. M. for the suggestion. Instead of using the computationally intensive VoigtDistribution, we can use the Pseudo-Voigt numeric approximation from this post which exhibits very low errors compared to the analytical Voigt (see here or references in here) and speeds up the fitting procedure by approximately a factor of 100 or more.
pseudoVoigtProfile = With[n = 24, τ = 12, With[d = N[Range[n] π/τ],b = N[Exp[-(Range[n] π/τ)^2]], s = N[PadRight[, n, -1, 1]], sq = N[Sqrt[2]],sp = N[Sqrt[2 π]],
Compile[δ, _Real, σ, _Real, x, _Real,
Module[z = (x + I δ)/(σ sq), e,
e = Exp[I τ z];
Re[(I (1 -e)/(τ z) + (2 I z/τ)b.((e s -1)/((d + z) (d - z))))]/(σ sp)],
RuntimeAttributes -> Listable]]];
and fit it to the noisy test data
tpv = AbsoluteTiming[pvfit = NonlinearModelFit[noisyDataV,
pseudoVoigtProfile[δ, σ, ν - ν0], δ, 0.15, σ, 0.1, A, 1, ν0, 0, ν];]
which leads to a ratio tpv/tg ~ 10 on my computer.
Note: Although the Pseudo-Voigt profile is a numerical approximation it will do the job for most daily life applications where the noise on the e.g. optical spectrum is at least an order of magnitude larger than the numeric error of the approximation.
New contributor
edited 9 hours ago
MarcoB
37.5k556113
37.5k556113
New contributor
answered 13 hours ago
Adrian BeckertAdrian Beckert
613
613
New contributor
New contributor
$begingroup$
As Voigt is Gaussian convolved by Lorentzian another approach regularly used in spectrometry is to work in Fourier space: see sites.math.washington.edu/~morrow/papers/GVmathThesis2010.pdf for instance (sorry I do not have all the details in mind for a complete answer here)
$endgroup$
– Picaud Vincent
12 hours ago
1
$begingroup$
The compiled implementation you got from my answer is a genuine implementation of the Voigt profile, nothing "pseudo" about it.
$endgroup$
– J. M. is slightly pensive♦
12 hours ago
add a comment |
$begingroup$
As Voigt is Gaussian convolved by Lorentzian another approach regularly used in spectrometry is to work in Fourier space: see sites.math.washington.edu/~morrow/papers/GVmathThesis2010.pdf for instance (sorry I do not have all the details in mind for a complete answer here)
$endgroup$
– Picaud Vincent
12 hours ago
1
$begingroup$
The compiled implementation you got from my answer is a genuine implementation of the Voigt profile, nothing "pseudo" about it.
$endgroup$
– J. M. is slightly pensive♦
12 hours ago
$begingroup$
As Voigt is Gaussian convolved by Lorentzian another approach regularly used in spectrometry is to work in Fourier space: see sites.math.washington.edu/~morrow/papers/GVmathThesis2010.pdf for instance (sorry I do not have all the details in mind for a complete answer here)
$endgroup$
– Picaud Vincent
12 hours ago
$begingroup$
As Voigt is Gaussian convolved by Lorentzian another approach regularly used in spectrometry is to work in Fourier space: see sites.math.washington.edu/~morrow/papers/GVmathThesis2010.pdf for instance (sorry I do not have all the details in mind for a complete answer here)
$endgroup$
– Picaud Vincent
12 hours ago
1
1
$begingroup$
The compiled implementation you got from my answer is a genuine implementation of the Voigt profile, nothing "pseudo" about it.
$endgroup$
– J. M. is slightly pensive♦
12 hours ago
$begingroup$
The compiled implementation you got from my answer is a genuine implementation of the Voigt profile, nothing "pseudo" about it.
$endgroup$
– J. M. is slightly pensive♦
12 hours ago
add a comment |
$begingroup$
You can use CompilePrint
to check what Compile
actually did:
Needs["CompiledFunctionTools`"];
voigtprofile1 =
Compile[δ, _Real, 0, σ, _Real, 0, A, _Real,
0, ν0, _Real, 0, ν, _Real, 0,
A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]
];
CompilePrint[voigtprofile1]
Out[26]= "5 arguments
7 Real registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes ->
R0 = A1
R1 = A2
R2 = A3
R3 = A4
R4 = A5
Result = R6
1 R5 = MainEvaluate[ Function[δ, σ, A, ν0, ν,
PDF[VoigtDistribution[Abs[δ], Abs[σ]], ν - ν0]][ R0, R1, R2, R3, R4]]
2 R6 = R2 * R5
3 Return"
As you can see, all the function really does is call MainEvaluate
and then multiply two numbers together. Basically, you haven't compiled anything.
Instead, evaluate the PDF inside of the Compile
to get a symbolic expression that is compilable:
voigtprofile2 = Compile[
δ, _Real, 0, σ, _Real, 0, A, _Real, 0, ν0, _Real, 0, ν, _Real, 0,
Evaluate[
A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]
],
CompilationOptions -> "ExpressionOptimization" -> True,
RuntimeAttributes -> Listable
];
This should be significantly faster.
$endgroup$
1
$begingroup$
The problem with yourvoigtprofile2
is thatErfc[]
only works for real arguments within a compiled function, so it gets wrapped inMainEvaluate
. That was one reason why I wrote the routine in the thread I linked to in the comments.
$endgroup$
– J. M. is slightly pensive♦
11 hours ago
1
$begingroup$
Ok, that's handy to know. That's a specific problem ofVoigtDistribution
I didn't anticipate. I still wanted to point out the importance of usingCompilePrint
, though.
$endgroup$
– Sjoerd Smit
11 hours ago
add a comment |
$begingroup$
You can use CompilePrint
to check what Compile
actually did:
Needs["CompiledFunctionTools`"];
voigtprofile1 =
Compile[δ, _Real, 0, σ, _Real, 0, A, _Real,
0, ν0, _Real, 0, ν, _Real, 0,
A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]
];
CompilePrint[voigtprofile1]
Out[26]= "5 arguments
7 Real registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes ->
R0 = A1
R1 = A2
R2 = A3
R3 = A4
R4 = A5
Result = R6
1 R5 = MainEvaluate[ Function[δ, σ, A, ν0, ν,
PDF[VoigtDistribution[Abs[δ], Abs[σ]], ν - ν0]][ R0, R1, R2, R3, R4]]
2 R6 = R2 * R5
3 Return"
As you can see, all the function really does is call MainEvaluate
and then multiply two numbers together. Basically, you haven't compiled anything.
Instead, evaluate the PDF inside of the Compile
to get a symbolic expression that is compilable:
voigtprofile2 = Compile[
δ, _Real, 0, σ, _Real, 0, A, _Real, 0, ν0, _Real, 0, ν, _Real, 0,
Evaluate[
A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]
],
CompilationOptions -> "ExpressionOptimization" -> True,
RuntimeAttributes -> Listable
];
This should be significantly faster.
$endgroup$
1
$begingroup$
The problem with yourvoigtprofile2
is thatErfc[]
only works for real arguments within a compiled function, so it gets wrapped inMainEvaluate
. That was one reason why I wrote the routine in the thread I linked to in the comments.
$endgroup$
– J. M. is slightly pensive♦
11 hours ago
1
$begingroup$
Ok, that's handy to know. That's a specific problem ofVoigtDistribution
I didn't anticipate. I still wanted to point out the importance of usingCompilePrint
, though.
$endgroup$
– Sjoerd Smit
11 hours ago
add a comment |
$begingroup$
You can use CompilePrint
to check what Compile
actually did:
Needs["CompiledFunctionTools`"];
voigtprofile1 =
Compile[δ, _Real, 0, σ, _Real, 0, A, _Real,
0, ν0, _Real, 0, ν, _Real, 0,
A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]
];
CompilePrint[voigtprofile1]
Out[26]= "5 arguments
7 Real registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes ->
R0 = A1
R1 = A2
R2 = A3
R3 = A4
R4 = A5
Result = R6
1 R5 = MainEvaluate[ Function[δ, σ, A, ν0, ν,
PDF[VoigtDistribution[Abs[δ], Abs[σ]], ν - ν0]][ R0, R1, R2, R3, R4]]
2 R6 = R2 * R5
3 Return"
As you can see, all the function really does is call MainEvaluate
and then multiply two numbers together. Basically, you haven't compiled anything.
Instead, evaluate the PDF inside of the Compile
to get a symbolic expression that is compilable:
voigtprofile2 = Compile[
δ, _Real, 0, σ, _Real, 0, A, _Real, 0, ν0, _Real, 0, ν, _Real, 0,
Evaluate[
A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]
],
CompilationOptions -> "ExpressionOptimization" -> True,
RuntimeAttributes -> Listable
];
This should be significantly faster.
$endgroup$
You can use CompilePrint
to check what Compile
actually did:
Needs["CompiledFunctionTools`"];
voigtprofile1 =
Compile[δ, _Real, 0, σ, _Real, 0, A, _Real,
0, ν0, _Real, 0, ν, _Real, 0,
A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]
];
CompilePrint[voigtprofile1]
Out[26]= "5 arguments
7 Real registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes ->
R0 = A1
R1 = A2
R2 = A3
R3 = A4
R4 = A5
Result = R6
1 R5 = MainEvaluate[ Function[δ, σ, A, ν0, ν,
PDF[VoigtDistribution[Abs[δ], Abs[σ]], ν - ν0]][ R0, R1, R2, R3, R4]]
2 R6 = R2 * R5
3 Return"
As you can see, all the function really does is call MainEvaluate
and then multiply two numbers together. Basically, you haven't compiled anything.
Instead, evaluate the PDF inside of the Compile
to get a symbolic expression that is compilable:
voigtprofile2 = Compile[
δ, _Real, 0, σ, _Real, 0, A, _Real, 0, ν0, _Real, 0, ν, _Real, 0,
Evaluate[
A PDF[VoigtDistribution[Abs@δ, Abs@σ], ν - ν0]
],
CompilationOptions -> "ExpressionOptimization" -> True,
RuntimeAttributes -> Listable
];
This should be significantly faster.
edited 9 hours ago
MarcoB
37.5k556113
37.5k556113
answered 11 hours ago
Sjoerd SmitSjoerd Smit
4,055815
4,055815
1
$begingroup$
The problem with yourvoigtprofile2
is thatErfc[]
only works for real arguments within a compiled function, so it gets wrapped inMainEvaluate
. That was one reason why I wrote the routine in the thread I linked to in the comments.
$endgroup$
– J. M. is slightly pensive♦
11 hours ago
1
$begingroup$
Ok, that's handy to know. That's a specific problem ofVoigtDistribution
I didn't anticipate. I still wanted to point out the importance of usingCompilePrint
, though.
$endgroup$
– Sjoerd Smit
11 hours ago
add a comment |
1
$begingroup$
The problem with yourvoigtprofile2
is thatErfc[]
only works for real arguments within a compiled function, so it gets wrapped inMainEvaluate
. That was one reason why I wrote the routine in the thread I linked to in the comments.
$endgroup$
– J. M. is slightly pensive♦
11 hours ago
1
$begingroup$
Ok, that's handy to know. That's a specific problem ofVoigtDistribution
I didn't anticipate. I still wanted to point out the importance of usingCompilePrint
, though.
$endgroup$
– Sjoerd Smit
11 hours ago
1
1
$begingroup$
The problem with your
voigtprofile2
is that Erfc[]
only works for real arguments within a compiled function, so it gets wrapped in MainEvaluate
. That was one reason why I wrote the routine in the thread I linked to in the comments.$endgroup$
– J. M. is slightly pensive♦
11 hours ago
$begingroup$
The problem with your
voigtprofile2
is that Erfc[]
only works for real arguments within a compiled function, so it gets wrapped in MainEvaluate
. That was one reason why I wrote the routine in the thread I linked to in the comments.$endgroup$
– J. M. is slightly pensive♦
11 hours ago
1
1
$begingroup$
Ok, that's handy to know. That's a specific problem of
VoigtDistribution
I didn't anticipate. I still wanted to point out the importance of using CompilePrint
, though.$endgroup$
– Sjoerd Smit
11 hours ago
$begingroup$
Ok, that's handy to know. That's a specific problem of
VoigtDistribution
I didn't anticipate. I still wanted to point out the importance of using CompilePrint
, though.$endgroup$
– Sjoerd Smit
11 hours ago
add a comment |
Adrian Beckert is a new contributor. Be nice, and check out our Code of Conduct.
Adrian Beckert is a new contributor. Be nice, and check out our Code of Conduct.
Adrian Beckert is a new contributor. Be nice, and check out our Code of Conduct.
Adrian Beckert is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Mathematica Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f193317%2fhow-to-speed-up-voigt-profile-fits%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
4
$begingroup$
Have you seen this?
$endgroup$
– J. M. is slightly pensive♦
15 hours ago