%* 			Short Introduction
%* 				to
%* 			    Random Walks
%* 		Stocks, Volatility, and Diversification (SandP)
%* 	Biggest of Bunch: Gumbel and Extreme Value Statistics (Gumbel)


% Random numbers are amazingly useful in computation. 

import scipy
scipy.random.random()
scipy.random.random()

% Random number generators traditionally create a uniform probability
% distribution between zero and one

nums = []
for i in range(10000):
   nums.append(scipy.random.random())

% or, more efficiently,

nums = scipy.random.random(10000)

import pylab
pylab.hist(nums, bins=100)
pylab.show()

% Computers generate so-called random numbers through purely 
% deterministic algorithms, starting from a "seed"

scipy.random.seed(3)
scipy.random.random()
scipy.random.seed(3)
scipy.random.random()

% The computer will set the seed (maybe using the time of day) if you don't.
% It is a good programming practice to always set the seed yourself, so 
%     (a) you guarantee that you're not duplicating a previous run 
%     (change the seed!), and 
%     (b) you can duplicate the run exactly if needed (for debugging or 
%     re-running crashed programs).


% These three exercises explore emergent properties from large collections
% of random numbers. 

% * 	Emergent properties
%*
%* 	RandomWalks: 	Fractals
%* 			Diffusion
%* 			Central Limit Theorem

% RandomWalks explores the properties that emerge when
% many random numbers are summed, or averaged. The average of the sum of N 
% terms is of course given by the sum of the average, so let's remove
% the mean (0.5) from our random numbers

nums = scipy.random.random(10000) - 0.5

walk = []
walkEnd = 0.
for r in nums:
    walkEnd += r
    walk.append(walkEnd)

% or, more efficiently

walk = scipy.cumsum(nums)

pylab.plot(walk)

% It is much faster to generate or sum entire arrays of random numbers than
% to fill an array one element at a time. 
% "Functional programming" is a technique which makes use of functions or
% operations that act on the whole data set in one command, rather than 
% on each piece of data individually. 
% Higher-level interpreted languages like Python, Mathematica, Matlab, 
% and Octave will be much faster using functional programming. 
% Even C++, C, and Fortran will be faster using large-scale operations:
% modern CPUs and compilers can be much faster when given simple repetitive
% tasks.

% 2D random walk: functional programming, slicing

walk = scipy.cumsum(scipy.random.random((10000,2))-0.5)
pylab.plot(walk[:,0],walk[:,1])
pylab.axis('equal')
pylab.show()
 
% The disadvantage of functional programming is that one must learn the
% names of many different functions 
% Python: 		sum, cumsum, random, max, ...
% Mathematica:  	Plus, CumulativeSums, RandomArray, Max ...
% 
% Another advantage, though, is that you are spared many routine 
% programming tasks.

% SandP explores the real-world random behavior exhibited by the stock market
% (in particular, the Standard & Poors 500 index).
% One learns that much of the behavior of the stock market (apart from the
% overall growth with time) is well described  by uncorrelated random walks,
% seemingly unaffected by information from the real world.
% Using this as an insight, one can understand both the vocabulary of finance
% and the rationale for diversified investment strategies.

%* 	Emergent properties
% ...
%* 	SandP: 		Volatility
%* 			Diversification
%*			Power laws
%*			Heavy tails

% Finally, Gumbel explores not the sum or the average of many random numbers,
% but the largest or smallest values in a distribution (like the distribution
% of high-water marks each year). This is important for engineers and
% insurance companies that need to plan for floods.

%* 	Emergent properties
% ...
%* 	Gumbel: 	Extreme value distribution
%* 			Universality
%*