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. is in limbo Jun 19 '16 at 2:52
  • 1
    $\begingroup$ @J.M. Why not the more intuitive {Sin[#], Cos[#]} &@RandomVariate[UniformDistribution[{-\[Pi], \[Pi]}]]? $\endgroup$ – Sjoerd C. de Vries 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. is in limbo 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$ – Sjoerd C. de Vries 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$ – user6043040 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$ – user6043040 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$ – user6043040 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.