4
$\begingroup$

I defined a security boundary for a random walk:

p = 5000;(*steps*)
tc = 15;(*cube edge length*)
tp = 0.2;

random = Accumulate[
Join[{RandomReal[{-tc, tc}/2, 3]}, 
RandomVariate[NormalDistribution[0, tp], {p, 3}]]];

periodizedWalk = Mod[random, tc, -tc/2];
splitPeriodizedWalk = 
Split[periodizedWalk, EuclideanDistance[#1, #2] < tc/2 &];

With[{cube = First[PolyhedronData["Cube"]]}, 
Graphics3D[{{Opacity[0.1], Scale[cube, tc]}, Line[random]}, 
Boxed -> False]]

and now i want to obtain a sample of the random times at which the random walk crosses the boundary for the first time. Something like this:

W = {}; For[i = 1, i <= 5000, i++,
PosFinal = {0, 0}; EME = 1;
While[True,
PosFinal = PosFinal + step[Random[]];
If[Norm[PosFinal] > 15, Break[]];

EME = EME + 1;
];
W = Append[W, EME];
]

but i want these two codes to be related. Would like some help please :)

$\endgroup$
10
$\begingroup$

Ad 1 When the walker is corssing the boundary region:

pos = Most@Accumulate[Length /@ SplitBy[tc/2 - Max /@ Abs@random, Sign]];


With[{cube = First[PolyhedronData["Cube"]]},
 Graphics3D[{{Opacity[0.1], Scale[cube, tc]}, Line[random], 
              PointSize@.03, Red, Point[random[[pos]]]}, Axes -> True]]

enter image description here

Ad 2 When the walker reaches the boundary first time. + statistics for many walks.

If you only need a moment that the boundary was reached there is no need to store the path or continue the calculation after that point. This can be a way to go:

walk[] := NestWhile[# + {RandomReal[{-1, 1}, 3], 1} &, 
                    {{0, 0, 0}, 0}, 
                    Norm[#[[1]]] < 10 &]

Here the boundary is a sphere of radius 10. The result of such walk is the last position and number of iterations:

walk[]
{{8.00459, -6.26412, 3.81035}, 43}

So we only need to store the last element for multiple (100 here) cases, like:

Reap[
  Do[Sow[walk[][[2]]],
     {100}] 
    ];
Histogram[ %[[2, 1]]]

enter image description here

$\endgroup$
  • $\begingroup$ This is the way for given data. More natural approach is to use Reap/Sow while creating data. $\endgroup$ – Kuba Mar 23 '14 at 11:43
  • $\begingroup$ i want something like this: W = {}; For[i = 1, i <= 1000, i++, PosFinal = {0, 0}; EME = 1; While[True, PosFinal = PosFinal + step[Random[]]; If[Norm[PosFinal] > 15, Break[]]; EME = EME + 1; ]; W = Append[W, EME]; ] but i want this code and the first to be related. $\endgroup$ – Mariana da Costa Mar 23 '14 at 12:11
  • 2
    $\begingroup$ @MarianadaCosta While adding new element to the list check if it is crossing border, if so use Sow[new] to Reap those posints at the end. Also, do not use Append to create lists. See point 3.2 $\endgroup$ – Kuba Mar 23 '14 at 12:38
  • 1
    $\begingroup$ @MarianadaCosta you want still to know the path or only the number of iterations to the boundary matter? If points are important, do you want to keep going after crossing the boudary? $\endgroup$ – Kuba Mar 23 '14 at 16:48
  • 1
    $\begingroup$ Do[ i = 0; NestWhile[(i++; # + RandomReal[{-1, 1}, 3]) &, {0, 0, 0}, Norm[#] < 15 &]; Sow[i], {20}] // Reap $\endgroup$ – Kuba Mar 23 '14 at 17:07

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.