# Can I compile my function?

I'm trying to do some time-consuming simulations but I have no idea how to optimize this.

sim[dist_, expectDist_, n_] :=
Block[{sample, test, freq},
sample = Table[RandomVariate[dist, #], n] & /@ {5, 10, 20, 50, 100, 200};
test =
Map[TTest[#, expectDist, VerifyTestAssumptions -> None] &, sample, {2}];
freq = Count[#, p_ /; p <= 0.05] & /@ test;
N[freq 100/n]]

sim[NormalDistribution[], 0, 10000]
• Unfortunately if you look at CompileCompilerFunctions[] // Sort TTest isn't there so you won't be able to compile that. – b3m2a1 May 23 '17 at 3:29
• Also, only uniform and normal distribution can be compiled with random variate. Besides, the argument of a compiled function can only be integer, real, complex, boolean, and tensors of them, nothing like dist would be allowed. Your code is impossible to compile, unless you implement the algorithms yourself. – vapor May 23 '17 at 4:49
• Also, your code inside Compile involves pattern pattern matching, which cannot be compiled, see here for more information. – xzczd May 23 '17 at 6:00

In response to...

I have no idea how to optimize this

Here's my shot at it. TTest seems slow, perhaps because InverseCDF/CDF on the StudentTDistribution is called for each test. Below, I do it just once for each sample size to get the critical value and omit the P-value, a big savings of time. One can then just perform the T-test by hand. There is no need or advantage to compile it. It's almost 250 times as fast as the OP's approach.

sim[dist_, expectDist_, n_] :=
Module[{sample, test, freq, cv, samplesizes},
samplesizes = {5, 10, 20, 50, 100, 200};    (* not sure if this should be a parameter *)
sample = RandomVariate[dist, {n, #}] & /@ samplesizes; (* gets n samples of each size *)
cv = InverseCDF[StudentTDistribution[# - 1], 0.975] & /@ samplesizes;  (* crit. vals. *)
test = MapThread[                                    (* calculate Abs[test stat] - CV *)
Sqrt@#3 Abs[Mean /@ # - expectDist] / StandardDeviation /@ # - #2 &,
{sample, cv, samplesizes}];
freq = Total[UnitStep[test], {2}];   (* counts nonnegative differences: total rejects *)
N[freq 100/n]]
• Thanks, now I can make n = 100000 pretty fast. – user48983 Jun 2 '17 at 1:44