3

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.

Sjoerd C. de Vries
  • 65,815
  • 14
  • 188
  • 323
getafix
  • 133
  • 1
  • 6
  • 1
    Try Accumulate, and you may also use {Sin@t,Cos@t} to create each step. – Wjx Jun 19 '16 at 01:37
  • Welcome to Mathematica.SE! I suggest the following: 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Take the tour! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! – Michael E2 Jun 19 '16 at 01:55
  • You can format inline code and code blocks by selecting the code and clicking the {} button above the edit window. The edit window help button ? is also useful for learning how to format your questions and answers. You may also find this meta Q&A helpful – Michael E2 Jun 19 '16 at 01:56
  • 1
    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). – J. M.'s missing motivation Jun 19 '16 at 02:52
  • If you enter "random walk" into the search field of the Mathematica Documentation Center and search, you find a lot on random walks, including this article – m_goldberg Jun 19 '16 at 13:29
  • 1
    @J.M. Why not the more intuitive {Sin[#], Cos[#]} &@RandomVariate[UniformDistribution[{-\[Pi], \[Pi]}]]? – Sjoerd C. de Vries Jun 19 '16 at 19:22
  • 1
    @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. – J. M.'s missing motivation Jun 19 '16 at 19:31
  • 1
    @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 – Sjoerd C. de Vries Jun 19 '16 at 19:40
  • 1
    That's interesting, @Sjoerd; the last time I did such a test had the trig stuff being twice as slow. Maybe I should check things again… – J. M.'s missing motivation Jun 19 '16 at 19:42

5 Answers5

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

randomWalk[100]

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

Baran Cimen
  • 1,184
  • 1
  • 8
  • 18
  • Interesting! Can this be extended to 3D random walking? – user6043040 Jun 19 '16 at 05:29
  • 1
    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) – Baran Cimen Jun 19 '16 at 05:34
  • The @acl answer here looks efficient but not so good since the step length varies. – user6043040 Jun 19 '16 at 05:51
  • 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 – user6043040 Jun 19 '16 at 08:09
6

Use AnglePath.

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

enter image description here

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
ibragimov
  • 61
  • 1
3

Try the following code:

pt=Accumulate[{Sin@#,Cos@#}&/@RandomReal[{0,2 Pi},1000]];
boundary={Min@pt,Max@pt};
(*Distance is here*)
Norm@Last@pt
ListLinePlot[pt,PlotRange->{boundary,boundary},AspectRatio->1]

The result will be:

result1

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}];
Histogram3D[pt,ColorFunction->"TemperatureMap"]
Histogram[Norm /@ pt,ColorFunction->"TemperatureMap"]

And the result will be:

result2

Wjx
  • 9,558
  • 1
  • 34
  • 70
2
randomWalk[steps_] := 
 With[
   {pts = FoldList[Plus, {0, 0}, 
                   Normalize /@ RandomReal[{0, 1}, {steps, 2}]]}, 
   Graphics[{Line[pts], Red, Point[pts]}]
 ]

randomWalk[5]

enter image description here

xyz
  • 605
  • 4
  • 38
  • 117
0

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_] :=
 Graphics[{
   Gray, Line[aWalk],
   Dashed, Arrowheads[Large], Arrow[aWalk[[{1, -1}]]],
   Black, PointSize[Medium], Point[aWalk]},
  ImageSize -> Small]

Method invoking examples:

step[{10, 0}]

walk[5]

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

distance[w]

draw[w]
BoLe
  • 5,819
  • 15
  • 33