Very simple question, which for some reason I am unable to find a proper solution with Nest or NestWhile. My issue is speed.

The idea is simple.

1) Construct a list of length T according to a linear rule and a limitation (bottom loop) 2) Substitute into a linear rule, store numerical results into vectors. Repeat G times creating 4 lists of length G 3) Average and subtract the 4 lists, repeat D times

The sets I want to create are SampleJU, SampleNJU, SampleJW, SampleNJW who will be averaged and compared D times. Also please note that at the end of the middle loop I reset Y and V, so that the next repetition will collect new sets, without the old values.

The key issue is that during the construction of the first list (Y) some parameters need to be sampled and a quantity needs to be positive. This has been giving me issues. I am looking for a way, either via pure functions or Nest / NestWhile structures, to optimise this structure. The only result of interest is the final Count result at the end.

A very crude code that consists of 3 consecutive loops follows, to illustrate a working variation. It is horrible but it works. Suffice to say that any help and advice you may offer will be deeply appreciated.

If you require any clarifications, please go ahead and ask.


a := 0.0210543
m := 0.034035
r := -0.67
SampleJU := {}
SampleNJU := {}
SampleJW := {}
SampleNJW := {}
HR := {}
UDif := {}
Y := {}
V := {0.8427865991162602`}
Gama := 5
f[x_] := a + x*Sqrt[V[[-1]]]

And the body of the code

       m = RandomVariate[UniformDistribution[{-1, 1}]],
   EE = RandomVariate[BinormalDistribution[{0, 0}, {1, 1}, r]],

   eV = EE[[2]],
   Vnew = f[eV]; 
   While[Vnew < 0, 
    EE = RandomVariate[
      BinormalDistribution[{0, 0}, {1, 1}, r]]; eV = EE[[2]];
     Vnew = f[eV]],
   eY = EE[[1]],
   Ynew = m + eY*Sqrt[V[[-1]]]},
  Y = Append[Y, Ynew],
  V = Append[V, Vnew]}, {T}],

SumY = Total[Y],
JW = Exp[5 + SumY],
NJW = Exp[10 + SumY],
SampleJW = Append[SampleJW, JW],
SampleNJW = Append[SampleNJW, NJW],
JU = JW^(1 - Gama)/(1 - Gama),
NJU = NJW^(1 - Gama)/(1 - Gama),
SampleJU = Append[SampleJU, JU],
SampleNJU = Append[SampleNJU, NJU],
Y = {},
V = {0.8427865991162602`}}, {G}],

  UDif = Mean[SampleNJU] - Mean[SampleJU],
  HR = Append[HR, UDif],
}, {A}]
Count[HR, _?Positive]
  • 2
    $\begingroup$ Could you perhaps reduce this to a Minimum Working Example of your problem? It will make it easier and more likely for others to help you. $\endgroup$ – Quantum_Oli Sep 13 '16 at 11:03
  • $\begingroup$ Thank you for the comment, I mis-clicked while writing. The question is now complete along with a working example. $\endgroup$ – Titus Sep 13 '16 at 11:36
  • 1
    $\begingroup$ This example isn't quite minimal ... a few comments on making it clearer: use a; b; c for writing three statements. Do not use {a, b, c} if you don't want to create a list. It makes the code unreadable. Are you aware of the distinction between = and :=? You have unusual and unnecessary (albeit not incorrect) uses of :=. There's a lot of hard to read code here so I cannot immediately tell, but: are you sure you can't use Table? Repeated Append is slow and should not be used. Use Table whenever possible, use Sow/Reap otherwise. $\endgroup$ – Szabolcs Sep 13 '16 at 12:17
  • 1
    $\begingroup$ Every single x = Append[x,y] reallocates the whole list x, leading to quadratic complexity in a loop. $\endgroup$ – Szabolcs Sep 13 '16 at 12:17
  • $\begingroup$ Nesting of Do is unnecessary. Do, like Table, accepts multiple iterator statements, from outer to inner, e.g. Do[Do[Print[{i, j}], {j, 4}], {i, 4}] becomes Do[Print[{i, j}], {i, 4}, {j, 4}]. $\endgroup$ – rcollyer Sep 13 '16 at 14:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.