This answer gives explicitly a (parallel) MCMC implementation in mathematica following closely this Wolfram Demonstrations Project. This basically involves only a few lines:
mcmcfunComp = Compile[{{s, _Real, 1}}, Module[{xm, ym, proposal, xp, yp, p2, p1, proposalSigma = 0.2}, {xm, ym} = s; xp = RandomReal[NormalDistribution[xm, proposalSigma]]; yp = RandomReal[NormalDistribution[ym, proposalSigma]]; p2 = pdf[xp, yp]; p1 = pdf[xm, ym]; proposal = p2/p1; If[RandomReal[] <= proposal, {xp, yp}, {xm, ym}]], (* THIS IS THE MCMC STEP *) CompilationOptions -> {"InlineExternalDefinitions" -> True}, Parallelization -> True, CompilationTarget -> "C"]; sim = NestList[mcmcfunComp[#] &, {-4, 9}, 1000000];
and is quite fast!
Illustration
As an illustration (so as to actually contribute something other than a link) let us implement it on a 4D PDF
Let us first define the 4D PDF as a simple sum of Gaussians
Clear[pdf0, pdf1, pdf2, pdf, pdfN]; pdf0 = MultinormalDistribution[{1, 0, -1, 1}, 1/8 {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}]; pdf1 = MultinormalDistribution[{1, 1, 0, 1}, 1/8 {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}]; pdf2 = MultinormalDistribution[{0, -1, 1, 0}, 1/8 {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}]; pdf[x_, y_, z_, t_] = PDF[pdf0, {x, y, z, t}] + 1/2. PDF[pdf1, {x, y, z, t}] + 1/4. PDF[pdf2, {x, y, z, t}];
Then Compile the function
pdfN = Compile[{{x, _Real}, {y, _Real}, {z, _Real}, {t, _Real}}, pdf[x, y, z, t] // Evaluate, Parallelization -> True, CompilationTarget -> "C"];
Now the mcmc function itself obeys
mcmcfun = Compile[{{s, _Real, 1}}, Module[{xm, ym, zm, tm, proposal, xp, yp, zp, tp, p2, p1, proposalSigma = 1}, {xm, ym, zm, tm} = s; xp = RandomReal[NormalDistribution[xm, proposalSigma]]; yp = RandomReal[NormalDistribution[ym, proposalSigma]]; zp = RandomReal[NormalDistribution[zm, proposalSigma]]; tp = RandomReal[NormalDistribution[tm, proposalSigma]]; p2 = pdfN[xp, yp, zp, tp]; p1 = pdfN[xm, ym, zm, tm]; proposal = p2/p1; If[RandomReal[] <= proposal, {xp, yp, zp, tp}, {xm, ym, zm, tm}]], CompilationOptions -> {"InlineExternalDefinitions" -> True}, Parallelization -> True, CompilationTarget -> "C"];
and is indeed fast and straightforward to iterate.
sim = Drop[NestList[mcmcfun[#] &, {0, 0, 0, 0}, 1000000], {1, 1000}];
We can see by looking at different projections that it has indeed sampled the PDF
{{{First[#], Last[#]} & /@ sim // DensityHistogram // Image, {First[#], #[[2]]} & /@ sim // DensityHistogram // Image, {First[#], #[[3]]} & /@ sim // DensityHistogram // Image}, {{#[[2]], #[[3]]} & /@ sim // DensityHistogram // Image, {#[[4]], #[[2]]} & /@ sim // DensityHistogram // Image, {#[[3]], #[[4]]} & /@ sim // DensityHistogram // Image}} // GraphicsGrid
