MathGroup Archive 2003

[Date Index] [Thread Index] [Author Index]

Search the Archive

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



  • Prev by Date: Re: One-liners' performance
  • Next by Date: Re: Simplification of definite integral?
  • Previous by thread: One-liners' performance
  • Next by thread: Re: One-liners' performance