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