import numpy as np
from matplotlib import pyplot as plt
import pickle
import os
%pylab inline

"""
Explanation: Parallel Forest Tutorial
This notebook shows a traing process of Parallel Random Forest. For cluster training please check https://github.com/wasit7/parallel_forest
import modules
Import all necessary modules
End of explanation
"""


clmax=5
spc=5e2
theta_range=2
#samples is list of labels
samples=np.zeros(spc*clmax,dtype=np.uint32)
#I is fessture vector
I=np.zeros((spc*clmax,theta_range),dtype=np.float32)
marker=['bo','co','go','ro','mo','yo','ko',
        'bs','cs','gs','rs','ms','ys','ks']

# number of datasets being generated 
# 8 for training
# another one for evaluation
N=9 
path="train/"
if not os.path.exists(path):
    os.makedirs(path)
for n in xrange(N):
    for cl in xrange(clmax):
        xo=cl*spc
        #define label
        samples[xo:xo+spc]=cl
        phi = np.linspace(0, 2*np.pi, spc) + \
        np.random.randn(spc)*0.4*np.pi/clmax + \
        2*np.pi*cl/clmax
        r = np.linspace(0.1, 1, spc)
        I[xo:xo+spc,:]=np.transpose(np.array([r*np.cos(phi), r*np.sin(phi)]))
    with open(path+'dataset%02d.pic'%(n), 'wb') as pickleFile:
    #write label and feature vector
        theta_dim=1
        pickle.dump((clmax,theta_dim,theta_range,len(samples),samples,I,None), pickleFile, pickle.HIGHEST_PROTOCOL)

"""
Explanation: Generating datasets
End of explanation
"""


z=np.random.randint( 0,spc*clmax,1000)
for i in z:
    #ax.plot(dset.I[i,0],dset.I[i,1],marker[dset2.samples[i]])
    plt.plot(I[i,0],I[i,1],marker[samples[i]])
    plt.hold(True)

"""
Explanation: Visualization of the dataset
End of explanation
"""


from pforest.master import master
m=master()
m.reset()
m.train()

"""
Explanation: Training
End of explanation
"""


with open('out_tree.pic', 'wb') as pickleFile:
    pickle.dump(m.root, pickleFile, pickle.HIGHEST_PROTOCOL)
    
with open('out_tree.pic', 'rb') as pickleFile:
    root = pickle.load(pickleFile)

"""
Explanation: Write and read the tree
You may need to save/load the tree to/from a pickle file
End of explanation
"""


ls

"""
Explanation: Check the file size
End of explanation
"""


from pforest.dataset import dataset
from pforest.tree import tree

#init the test tree
t=tree()
t.settree(root)
t.show()

"""
Explanation: The result decision tree
Termination code (Q:min bag size, G:no information gain, D:reaching maximum depth)
End of explanation
"""


#load the last dataset that never use for training
dset=dataset(8)
correct=0;
for x in xrange(dset.size):
    L=t.getL(np.array([x]),dset)
    if dset.getL(x) == L:
        correct=correct+1
    dset.setL(x,L)
print("recall rate: {}%".format(correct/float(dset.size)*100))

"""
Explanation: Recall rate
Loading a new dataset, the last on, for computing a recall rate
End of explanation
"""


#setup the new test-set
#load dataset     
dset=dataset(8)
d=0.05
y, x = np.mgrid[slice(-1, 1+d, d), slice(-1, 1+d, d)]

#start labeling
L=np.zeros(x.shape,dtype=int)
for r in xrange(x.shape[0]):
    for c in xrange(x.shape[1]):
        u=( x[r,c],y[r,c] )
        Prob=t.classify(u)
        L[r,c]=np.argmax(Prob)

"""
Explanation: Labelling
The computer use the decision tree to classify the unknown feature vector u
End of explanation
"""


%matplotlib inline
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.axis([-1,1,-1,1])
ax.pcolor(x,y,L)
ax.hold(True)

"""
Explanation: 2D space partitioning by the decision tree
Displaying the labelled result
End of explanation
"""


z=np.random.randint(0,dset.size,1000)
for i in z:
    ax.plot(dset.I[i,0],dset.I[i,1],marker[dset.samples[i]])
fig

t.classify([0.75,0.0])

"""
Explanation: Overlay the dataset
End of explanation
"""


