I am new to programming inMathematica, and I am trying to pick up a few things by myself. As an exercise, I wanted to generate a two-dimensional random walk starting at the origin, and then moving a unit length randomly in each subsequent step. After that the goal of the exercise is to a) find the distance between the origin and the terminal point and b) if possible, to plot the random walk.

Here's what I thought of doing. Assign a vector a = {0,0} and then add a normalized vector b = Normalize[{RandomReal[], RandomReal[]}], and perform this procedure iteratively.

What I'm having trouble doing is performing the iterations. For instance, in the first step a + b generates c1, in the second I wish to generate c2 = c1 + b, and so on.

Moreover, I want b to be different each time, something I have failed at accomplishing. I'm kinda lost, and don't know where to start, any help would be appreciated.

  • 1
    $\begingroup$ Try Accumulate, and you may also use {Sin@t,Cos@t} to create each step. $\endgroup$
    – Wjx
    Jun 19 '16 at 1:37
  • 1
    $\begingroup$ Note that Normalize[{RandomReal[], RandomReal[]}] will not yield a uniformly distributed direction, which is maybe what you want. The right way to generate a uniformly distributed direction would be the method in Wjx's answer, or the cheaper Normalize[RandomVariate[NormalDistribution[], 2]] (see this paper for more details). $\endgroup$
    – J. M.'s torpor
    Jun 19 '16 at 2:52
  • 1
    $\begingroup$ @J.M. Why not the more intuitive {Sin[#], Cos[#]} &@RandomVariate[UniformDistribution[{-\[Pi], \[Pi]}]]? $\endgroup$ Jun 19 '16 at 19:22
  • 1
    $\begingroup$ @Sjoerd, because generating two normal variates (via e.g. the ziggurat method) and normalizing is cheaper than evaluating a trigonometric function, so it might make a performance difference if you're looking to generate a grand pile of random unit vectors. $\endgroup$
    – J. M.'s torpor
    Jun 19 '16 at 19:31
  • 1
    $\begingroup$ @J.M. Not really. Generating a million vectors using {Sin[#], Cos[#]} & /@ RandomVariate[ UniformDistribution[{-\[Pi], \[Pi]}], {1000000}]; // AbsoluteTiming is about 8 times faster than using Normalize /@ RandomVariate[NormalDistribution[], {1000000, 2}]; // AbsoluteTiming $\endgroup$ Jun 19 '16 at 19:40

Try the following code:

pt=Accumulate[{Sin@#,Cos@#}&/@RandomReal[{0,2 Pi},1000]];
(*Distance is here*)

The result will be:


Also,I suspect you may need to run it multiple times and track it's end points distribution, so try this:

pt = Table[Total[{Sin@#, Cos@#} & /@RandomReal[{0, 2 Pi}, 1000]], {1000}];
Histogram[Norm /@ pt,ColorFunction->"TemperatureMap"]

And the result will be:


randomWalk[t_] := Accumulate[
  Prepend[RandomPoint[DiscretizeRegion[Circle[]], t], {0, 0}]]//ListLinePlot


enter image description here

EDIT (3D Case)

Borrowing @eldo's idea here:

randomWalk[t_] := (Accumulate[Prepend[RandomPoint[DiscretizeRegion[Sphere[]], t], {0, 0, 0}]] //
         ListPointPlot3D) /. Point -> Line

enter image description here

  • $\begingroup$ Interesting! Can this be extended to 3D random walking? $\endgroup$ Jun 19 '16 at 5:29
  • 1
    $\begingroup$ I will edit the answer when I get back home, but changing {0, 0} to {0, 0, 0} and Circle[] to Sphere[] should work. (There is also a 3D ListLinePlot function out there) $\endgroup$
    – thedude
    Jun 19 '16 at 5:34
  • $\begingroup$ The @acl answer here looks efficient but not so good since the step length varies. $\endgroup$ Jun 19 '16 at 5:51
  • $\begingroup$ I tried this code: random3Walk[t_]:=Accumulate[Prepend[RandomPoint[DiscretizeRegion[Sphere[]],t],{0,0,0}]]//(ListPointPlot3D[#,ImageSize->Full,PlotTheme->"Marketing",AspectRatio->1]/.Point[pts_,rest___]:>Tube[pts,0.1,rest])&, but it still looks weird $\endgroup$ Jun 19 '16 at 8:09

Use AnglePath.

ListLinePlot[AnglePath[RandomReal[{-Pi, Pi}, 100]], Axes -> None, Frame -> True]

enter image description here

randomWalk[steps_] := 
   {pts = FoldList[Plus, {0, 0}, 
                   Normalize /@ RandomReal[{0, 1}, {steps, 2}]]}, 
   Graphics[{Line[pts], Red, Point[pts]}]


enter image description here


Propagate for a unit step.

step[position_] :=
 With[{t = 2 Pi RandomReal[]},
  position + {Cos[t], Sin[t]}]

Make n steps from origin. If the second argument is omitted, it defaults to {0, 0}.

walk[n_, origin_: {0, 0}] :=
 NestList[step, origin, n]

Calculate distance of a walk instance, and visualize it.

distance[aWalk_] :=
 EuclideanDistance @@ aWalk[[{1, -1}]]

draw[aWalk_] :=
   Gray, Line[aWalk],
   Dashed, Arrowheads[Large], Arrow[aWalk[[{1, -1}]]],
   Black, PointSize[Medium], Point[aWalk]},
  ImageSize -> Small]

Method invoking examples:

step[{10, 0}]


w = walk[4, {1, 3}]



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