Re: One-liners' performance
- To: mathgroup at smc.vnet.net
- Subject: [mg40753] Re: [mg40723] One-liners' performance
- From: Dr Bob <majort at cox-internet.com>
- Date: Wed, 16 Apr 2003 01:36:42 -0400 (EDT)
- References: <200304150757.DAA13833@smc.vnet.net>
- Reply-to: majort at cox-internet.com
- Sender: owner-wri-mathgroup at wolfram.com
Kyriakos, Here's just a start. (*Simulate one regime switching path*) sample[sampleSize_Integer?Positive] := Module[{p1 = 0.5, p11 = 1 - theta[[1]], p22 = 1 - theta[[2]], trueFalse, m, s}, trueFalse = NestList[If[#, Random[] < p11, Random[] > p22] &, Random[] > p1, sampleSize - 1]; m = trueFalse /. {True -> theta[[3]], False -> theta[[4]]}; s = trueFalse /. {True -> theta[[5]], False -> theta[[6]]}; m + Sqrt@s*RandomArray[NormalDistribution[], {sampleSize}] - s/2]; sample[5] (* for instance *) The "sample" module has no side-effects, as it should be in functional programming. ST wasn't used for anything. It's recommended not to start your own symbols with capital letters to keep from confusing them with built-ins. Parameterizing the function makes it easier to change the number of samples someday, and you were calculating a (known) sample-size anyway. If you'll have thousands of trials with lots of samples, this should be optimized to make only one or two passes through the samples (rather than 7 or 8). Here's a version with two passes: sample[sampleSize_Integer?Positive] := Block[{p1 = 0.5, p11 = 1 - theta[[1]], p22 = 1 - theta[[2]], f, g, one = {theta[[3]] - theta[[5]]/2, Sqrt@theta[[5]]}, two = {theta[[4]] - theta[[6]]/2, Sqrt@theta[[6]]}, }, f = If[#, Random[] < p11, Random[] > p22] &; g[True] := one.{1, Random[NormalDistribution[]]}; g[False] := two.{1, Random[NormalDistribution[]]}; g /@ NestList[f, Random[] > p1, sampleSize - 1] ]; Note that the roots and subtractions are done only once, this way. It will take more work to make that a true one-liner. Bobby On Tue, 15 Apr 2003 03:57:58 -0400 (EDT), Kyriakos Chourdakis <tuxedomoon at yahoo.com> wrote: > Dear all, > > Having read the discussion about one-liners, and the > suggestions that overall the code is typically faster if such an approach > is taken, I decided to alter some > of my existing code. The code computes the likelihood > for regime switching models. > > I run some comparisons, and found that the > ``one-liner'' code is consistenly slower than the code > that loops using Do[]. My first guess is that my > understanding of the one-liner code might be wrong, > and I would appreciate any feedback. > > The code is given below: First a sample is generated, > and likelihoods are computed. Then, 20 samples are > computed. For a sample of 3000, the Do[] version is > about 30% faster than the Fold[] one. > > I apologize for the messy Greeks. > > K. > > Quit[]; << "Statistics`NormalDistribution`" > > (* the parameter vector *) > theta = {0.05, 0.05, 0.5, -0.5, 1., 4.}; > > (* Simulate one regime switching path *) Sample := Module[ > {p11 = 1 - theta[[1]], p22 = 1 - theta[[2]]}, > StTF = NestList[If[#1, Random[] < p11, Random[] > p22] > & , Random[] > 0.5, 3000]; ST = (If[#1, 1, 0] & ) /@ StTF; > STm = (If[#1, theta[[3]], theta[[4]]] & ) /@ StTF; STs = (If[#1, > theta[[5]], theta[[6]]] & ) /@ StTF; n = Length[ST]; STm + > Sqrt[STs]*RandomArray[NormalDistribution[], {n}] > - STs/2 > ]; > > (* The original code *) > Lh = Function[ > {\[CapitalPi], \[Mu], \[Sigma], \[Xi]0, Y}, Module[ > {\[Nu], \[Zeta]1, \[Zeta]2, \[Zeta]}, \[Nu] = > Dimensions[\[CapitalPi]][[1]]; \[Xi] = Transpose[\[Xi]0]; \[Xi]1 = {}; > \[Eta] = > Transpose[Table[PDF[NormalDistribution[\[Mu][[i,1]], > Sqrt[\[Sigma][[i,1]]]], Y], {i, 1, \[Nu]}]]; > Do[ > \[Zeta]1 = Flatten[\[Xi][[-1]]]; \[Zeta]2 = \[Eta][[i]]; \[Zeta] = > \[Zeta]1*\[Zeta]2; \[Zeta]0 = \[Zeta]/Plus @@ Flatten[\[Zeta]]; \[Xi]1 = > {\[Xi]1, \[Zeta]0}; \[Xi] = {\[Xi], {\[Zeta]0} . \[CapitalPi]}, {i, > Length[Y]} > ]; \[Xi]1 = Partition[Flatten[\[Xi]1], \[Nu]]; \[Xi] = > Partition[Flatten[\[Xi]], \[Nu]]; Plus @@ Log[Apply[Plus, Delete[\[Xi], - > 1]*\[Eta], > {1}]] > ] > ]; > > (* The one-liner type code *) > Lh1L = Function[ > {\[CapitalPi], \[Mu], \[Sigma], \[Xi]0, Y}, Module[ > {\[Nu], \[Zeta]1, \[Zeta]2, \[Zeta]}, \[Nu] = > Dimensions[\[CapitalPi]][[1]]; \[Xi] = Flatten[\[Xi]0]; \[Xi]1 = {}; > \[Eta] = > Transpose[Table[PDF[NormalDistribution[\[Mu][[i,1]], > Sqrt[\[Sigma][[i,1]]]], Y], {i, 1, \[Nu]}]]; xx = Transpose[FoldList[ > Module[{Lo, \[Xi]o, \[Zeta]}, {\[Xi]o, Lo} = #1; \[Xi]o = > Flatten[{\[Xi]o} . \[CapitalPi]]; \[Zeta] = \[Xi]o*#2; \[Xi]o = Plus @@ > \[Zeta]; {\[Zeta]/\[Xi]o, Lo + Log[\[Xi]o]}] & , {\[Xi], 0.}, \[Eta]]]; > Ps = xx[[1]]; xx[[2,-1]] > ] > ]; > > (* Some wrappers *) > ToEst[x_, Y_] := Lh[ > {{1 - x[[1]], x[[1]]}, {x[[2]], 1 - x[[2]]}}, {{x[[3]]}, {x[[4]]}}, > {{x[[5]]}, {x[[6]]}}, {{x[[2]]/(x[[1]] + x[[2]])}, {x[[1]]/(x[[1]] + > x[[2]])}}, Y] > ToEst1L[x_, Y_] := Lh1L[ > {{1 - x[[1]], x[[1]]}, {x[[2]], 1 - x[[2]]}}, {{x[[3]]}, {x[[4]]}}, > {{x[[5]]}, {x[[6]]}}, {{x[[2]]/(x[[1]] + x[[2]])}, {x[[1]]/(x[[1]] + > x[[2]])}}, Y] > > (* 20 simulations *) > Do[ > Y = Sample; ET = Timing[ToEst[theta, Y]][[1]]; ET1L = > Timing[ToEst1L[theta, Y]][[1]]; Print[{ET, ET1L, ET - ET1L}], {20}] > > > > __________________________________________________ > Yahoo! Plus > For a better Internet experience > http://www.yahoo.co.uk/btoffer > > -- majort at cox-internet.com Bobby R. Treat
- References:
- One-liners' performance
- From: Kyriakos Chourdakis <tuxedomoon@yahoo.com>
- One-liners' performance