Here are my six pence.
This function takes a function crit that reflects the stopping criterion (this function is assumed to be Listable!), an initial point initpt and a timestepsize and calculates a random walk until crit evaluates to True. I use chunks such that we can exploit the Listable property of crit and the fact that RandomFunction is primarily good at creating long lists of results.
abortedRandomWalk::maxiter =
"Maximal number of iterations `1` reached. Try to increase the \
value of the option MaxIterations.";
ClearAll[abortedRandomWalk];
abortedRandomWalk[crit_, initpt_, timestepsize_,
OptionsPattern[{
MaxIterations -> 10^9, "ChunkSize" -> 1000
}]
] := Module[{maxiter, pt, data, memberQ, couter, X, chunkpath, i0,
chunksize, chunkmaxtime, path},
maxiter = OptionValue[MaxIterations];
chunksize = OptionValue["ChunkSize"];
chunkmaxtime = chunksize timestepsize;
pt = initpt;
data = {{pt}};
couter = 0;
While[couter < maxiter,
couter += chunksize;
X = RandomFunction[
WienerProcess[], {0, chunkmaxtime, timestepsize}, 2];
chunkpath =
Rest[Transpose@X["States"]] + ConstantArray[pt, chunksize];
i0 = FirstPosition[crit[chunkpath], False];
If[MissingQ[i0],
data = {data, chunkpath}; pt = chunkpath[[-1]];
,
data = {data, chunkpath[[1 ;; i0[[1]]]]}; Break[];
]
];
path = Partition[Flatten[data], 2];
Print["Chunks needed: ", Quotient[couter, chunksize]];
Print["Path length: ", Length[path]];
If[couter > maxiter,
Message[abortedRandomWalk::maxiter, maxiter];
];
path
]
We are not bound to use a rectangle. For example, we can use any other Region with an efficient way of determining if a point is inside. In particular, we may use BoundaryMeshRegions and MeshRegions:
c = t \[Function] (2 + Cos[5 t])/3 {Cos[t], Sin[t]};
R = Module[{pts, edges, B},
pts = Most@Table[c[t], {t, 0., 2. Pi, 2. Pi/2000}];
edges =
Append[Transpose[{Range[1, Length[pts] - 1],
Range[2, Length[pts]]}], {Length[pts], 1}];
BoundaryMeshRegion[pts, Line[edges]]
];
initpt = {.03, .02};
memberQ = RegionMember[R];
SeedRandom[12345];
path = abortedRandomWalk[memberQ, initpt, 0.00001,
"ChunkSize" -> 10000
]; // AbsoluteTiming
Show[R, Graphics[{EdgeForm[Thin], Line[path]}]]
Chunks needed: 2
Path length: 11313
{0.026381, Null}

x={x1,x2,x3...},y={y1,y2,y3,...}, so long asLength[x]==Length[y],Transpose[{x,y}]=={{x1,y1},{x2,y2},{x3,y3},...}. – eyorble Feb 24 '18 at 01:15