(* ::Package:: *)

(************************************************************************)
(* This file was generated automatically by the Mathematica front end.  *)
(* It contains Initialization cells from a Notebook file, which         *)
(* typically will have the same name as this file except ending in      *)
(* ".nb" instead of ".m".                                               *)
(*                                                                      *)
(* This file is intended to be loaded into the Mathematica kernel using *)
(* the package loading commands Get or Needs.  Doing so is equivalent   *)
(* to using the Evaluate Initialization Cells menu command in the front *)
(* end.                                                                 *)
(*                                                                      *)
(* DO NOT EDIT THIS FILE.  This entire file is regenerated              *)
(* automatically each time the parent Notebook file is saved in the     *)
(* Mathematica front end.  Any changes you make to this file will be    *)
(* overwritten.                                                         *)
(************************************************************************)



(* :Name: EPM`RandomWalks` *)


(* :Book: Essentials of Programming in Mathematica *)


(* :Author: Paul Wellin *)


(* :Summary: This package contains the random walk functions defined in the book. *)


(* :Context: EPM`RandomWalks` *)


(* :Package Version: 1.1 *)


(* :Copyright: Copyright 2015, Paul R. Wellin *)


(* :History: Version 1.0 by Paul Wellin, Dec 2012 
			Version 1.1 by Paul Wellin, Dec 2013 
*)


(* :Keywords:
random walks, lattice walks, off-lattice walks, mean-square distance,
 radius of gyration 
*)


(* :Source: RandomWalks.nb *)


(* :Mathematica Version: 10.3 *)


(* Tested in Mathematica 11.1 *)


Remove[AnimateWalk,Dimension,LatticeWalk,RandomWalk,ShowWalk,ShowWalkGC]


BeginPackage["EPM`RandomWalks`"];


AnimateWalk::usage="AnimateWalk[\!\(\*
StyleBox[\"walk\", \"TI\"]\), \!\(\*
StyleBox[\"opts\", \"TI\"]\)] creates an animation of a two-dimensional random walk. A red ball will be seen to move to the current position in the walk to aid in visualizing the animation.";


Dimension::usage="Dimension is an option to RandomWalk that determines whether the random walk will be a one-, two-, or three-dimensional walk. Possible values are 1, 2, or 3.";


LatticeWalk::usage="LatticeWalk is an option to RandomWalk that determines whether the random walk will be a lattice walk or an off-lattice walk. Possible values are True and False.";


RandomWalk::usage="RandomWalk[\!\(\*
StyleBox[\"t\", \"TI\"]\)] generates a \!\(\*
StyleBox[\"t\", \"TI\"]\)-step random walk. The default behavior gives a two-dimensional lattice walk with steps in one of the four compass directions. The option LatticeWalk takes values True or False. The value of the option Dimension can be any of 1, 2, or 3.";


ShowWalk::usage="ShowWalk[\!\(\*
StyleBox[\"walk\", \"TI\"]\)] displays a one, two, or three-dimensional random walk connecting each site with a line. Graphics options can be passed to ShowWalk. E.g., ShowWalk[\!\(\*
StyleBox[\"walk\", \"TI\"]\), Background\[Rule]GrayLevel[0]] to produce a black background.";


ShowWalkGC::usage="ShowWalkGC[\!\(\*
StyleBox[\"walk\", \"TI\"]\)] displays a two- or three-dimensional random walk connecting each site with a line. Graphics options can be passed to ShowWalkGC. E.g., ShowWalkGC[\!\(\*
StyleBox[\"walk\", \"TI\"]\), Background\[Rule]GrayLevel[0]] to produce a black background.";


RandomWalk::rwn="Argument `1` is not a positive integer.";


RandomWalk::baddim="The value `1` of the option Dimension is not a positive integer.";


RandomWalk::baddimlat="The value `1` of the option Dimension is not a positive integer between 1 and 3.";


Options[AnimateWalk]=Options[Animate];


Options[RandomWalk]={LatticeWalk->True,Dimension->2};


Options[ShowWalk]=Join[Options[ListLinePlot],Options[Graphics3D]];


Begin["`Private`"];


latticeWalk[steps_,dim_]:=Module[{w,mat},
mat=Join[IdentityMatrix[dim],-IdentityMatrix[dim]];w=Accumulate[RandomChoice[mat,steps]];
If[dim==1,Flatten[w],w]
]


offLatticeWalk[t_,dim_]:=Module[{f1,f2,f3},
f1:=RandomReal[{-1,1},t];
f2:=Map[{Cos[#],Sin[#]}&,RandomReal[{0,2 \[Pi]},t]];
f3:=MapThread[{Cos[#1]Sqrt[1-#2^2],Sin[#1]Sqrt[1-#2^2],#2}&,{RandomReal[{0,2Pi},t],RandomReal[{-1,1},t]}];
Which[
dim==1,Accumulate[f1],
dim==2,Accumulate[f2],
dim==3,Accumulate[f3]
]]


RandomWalk[t_,OptionsPattern[]]:=Module[{dim,latticeQ},
{latticeQ,dim}=OptionValue[{LatticeWalk,Dimension}];
Which[
!(IntegerQ[t]&&t>0),Message[RandomWalk::"rwn",t],
(latticeQ&&(!IntegerQ[dim]||NonPositive[dim])),Message[RandomWalk::baddim,dim],
(!latticeQ&&FreeQ[{1,2,3},dim]),Message[RandomWalk::baddimlat,dim],
latticeQ,latticeWalk[t,dim],
True,offLatticeWalk[t,dim]
]
]


RandomWalk[x__]/;Message[RandomWalk::rwn,x]:=Null
RandomWalk[]/;Message[General::argx,RandomWalk,0]:=Null;


ShowWalk[coords_?VectorQ,opts:OptionsPattern[]] :=
	ListLinePlot[coords, FilterRules[{opts},Options[ListLinePlot]]]


ShowWalk[coords:{{__?NumberQ}..}/;Length[First[coords]]!=3,opts:OptionsPattern[]]:=
	ListLinePlot[coords, FilterRules[{opts},Options[ListLinePlot]]]


ShowWalk[coords:{{_,_}..},opts:OptionsPattern[]] :=
	ListLinePlot[coords, Append[FilterRules[{opts},Options[ListLinePlot]], AspectRatio->Automatic]]


ShowWalk[coords:{{{_,_}..}..},opts:OptionsPattern[]] :=ListLinePlot[coords, Append[FilterRules[{opts},Options[ListLinePlot]], AspectRatio->Automatic]]


ShowWalk[coords:{{_,_,_}..},opts:OptionsPattern[]] :=
	Graphics3D[{ColorData[1][1],Thin,Line[coords]}, FilterRules[{opts},Options[Graphics3D]]]


ShowWalk[coords:{{{_,_,_}..}..},opts:OptionsPattern[]] :=Graphics3D[
MapThread[{#1,Thickness[.001],Line[#2]}&,{Map[ColorData[1][#]&,Range[Length[coords]]],coords}],
FilterRules[{opts},Options[Graphics3D]]]


ShowWalkGC[coords:{{_,_}..},opts:OptionsPattern[Graphics]]:=Graphics[
GraphicsComplex[coords,
{Thickness[Small],ColorData[1][1],Line[Range[Length[coords]]]}
],opts,
Axes->True,AspectRatio->Automatic]


ShowWalkGC[coords:{{{_,_}..}..},opts:OptionsPattern[]] :=Graphics[
MapIndexed[GraphicsComplex[#1,
{ColorData[1][First[#2]],Thin,Line[Range[Length[#1]]]}]&,coords],
FilterRules[{opts},Options[Graphics]],Axes->True,AspectRatio->Automatic]


ShowWalkGC[coords:{{_,_,_}..},opts:OptionsPattern[]] :=Graphics3D[
GraphicsComplex[coords,
{ColorData[1][1],Thin,Line[Range[Length[coords]]]}],
FilterRules[{opts},Options[Graphics3D]],Axes->True,AspectRatio->Automatic]


ShowWalkGC[coords:{{{_,_,_}..}..},opts:OptionsPattern[]] :=Graphics3D[
MapIndexed[GraphicsComplex[#1,
{ColorData[1][First[#2]],Thin,Line[Range[Length[#1]]]}]&,coords],
FilterRules[{opts},Options[Graphics3D]],Axes->True,AspectRatio->Automatic]


AnimateWalk[rw_,opts:OptionsPattern[]]:=Module[{len=Length[rw],steps,gr},
gr=If[Dimensions[rw][[2]]==2,Graphics,Graphics3D];
Animate[gr[Line[Take[rw,steps]],PlotRange->RegionBounds[ConvexHullMesh[rw]],PlotLabel->StringForm["Walk length: ``",steps]],
{{steps,2,"Steps"},2,len,1},opts]]


End[];


EndPackage[]



