(* ::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: PwM`RandomWalks` *)


(* :Book: Programming with Mathematica: An Introduction *)


(* :Author: Paul Wellin *)


(* :Summary: This package contains the random walk functions defined throughout the book but particularly in Chapter 13, Applications and packages. *)


(* :Context: PwM`RandomWalks` *)


(* :Package Version: 1.0 *)


(* :Copyright: Copyright 2012, Cambridge University Press *)


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


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


(* :Source: RandomWalks.nb *)


(* :Mathematica Version: 8.0.4 *)


Remove[RandomWalk,ShowWalk,RadiusOfGyrationTensor]


BeginPackage["PwM`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.";


MeanSquareDistance::usage="MeanSquareDistance[\!\(\*
StyleBox[\"t\", \"TI\"]\), \!\(\*
StyleBox[\"m\", \"TI\"]\)] computes the mean square end-to-end distance of \!\(\*
StyleBox[\"m\", \"TI\"]\) \!\(\*
StyleBox[\"t\", \"TI\"]\)-step lattice walks.";


MeanSquareRadiusGyration::usage="MeanSquareRadiusGyration[\!\(\*
StyleBox[\"t\", \"TI\"]\), \!\(\*
StyleBox[\"m\", \"TI\"]\)] computes the mean square radius of gyration of a random walk. This is the sum of the squares of the distances of the step locations from the center of mass, divided by the number of step locations, where the center of mass is the sum of the step locations divided by the number of step locations.";


RadiusOfGyrationTensor::usage="RadiusOfGyrationTensor[\!\(\*
StyleBox[\"walk\", \"TI\"]\)] computes the radius of gyration tensor for the random walk \!\(\*
StyleBox[\"walk\", \"TI\"]\).";


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.";


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


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


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


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


Options[AnimateWalk]=Options[Animate];


Begin["`Private`"]


latticeWalk[steps_,dim_]:= Module[{w},
w=Accumulate[RandomChoice[Join[IdentityMatrix[dim],-IdentityMatrix[dim]],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=Table[Function[{\[Theta],u},{Cos[\[Theta]]Sqrt[1-u^2],Sin[\[Theta]]Sqrt[1-u^2],u}]@@{RandomReal[{0,2Pi}],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],
!(IntegerQ[dim]&&1<=dim<=3),Message[RandomWalk::baddim,dim],
True,If[latticeQ,latticeWalk[t,dim],offLatticeWalk[t,dim]]
]
]


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


MeanSquareDistance[t_Integer,trials_Integer]:=
Mean[Table[SquaredEuclideanDistance[First[#],Last[#]]& [ RandomWalk[t]],{trials}]]


squareRadiusGyration[t_Integer]:=Module[{locs=RandomWalk[t]},
Total[Map[SquaredEuclideanDistance[#,N[Mean[locs]]]&,locs]]/(t+1)]


MeanSquareRadiusGyration[t_Integer,trials_Integer]:=Mean[Table[squareRadiusGyration[t],{trials}]]


RadiusOfGyrationTensor[lis_]:=Module[{cmx,cmy,xcoords,ycoords,xy},
{cmx,cmy}=Mean[lis];
{xcoords,ycoords}=Transpose[lis];
xy=(xcoords-cmx).(ycoords-cmy)/Length[lis];
{{Mean[(xcoords-cmx)^2],xy},{xy,Mean[(ycoords-cmy)^2]}}
]


ShowWalk[coords_?VectorQ,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[]] :=
	Graphics3D[Line[coords], FilterRules[{opts},Options[Graphics3D]]]


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


End[]


EndPackage[]



