5
$\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$

1 Answer 1

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$
10
  • $\begingroup$ This is the way for given data. More natural approach is to use Reap/Sow while creating data. $\endgroup$
    – Kuba
    Mar 23, 2014 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$ Mar 23, 2014 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, 2014 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, 2014 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, 2014 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.