def ada_train(self, T, X, Y, optional=False):
       ''' adaboost training '''

       # Defines variables 
       self.weak_classifier_ens = []
       self.alpha = []
       self.X = X
       self.Y = Y
       self.T = T
       self.e = []
       N = len(self.Y)

       # Initializes with equal weigths
       Z = (1.0/N)*np.ones(N)
   
       # T iterations
       for t in range(T):
           # Methods are inside the decision stump class
           weak_learner = self.WeakClassifier()
           weak_learner.set_training_sample(X,Y)
           weak_learner.weights = Z

	   # extra plottings for the homework
           if t < 10 and optional:
                print("For t = ", t+1)
		print('Y= ', int(Y[t]))
                opt = True
           else: opt = False

	   # train the decision stump
           weak_learner.stump_train(opt)
           self.weak_classifier_ens.append(weak_learner)   
        
           # Predict so that wrong value will give more weight
           Y_p= weak_learner.stump_predict(X)
         
           # Calculates weighted training error 
           epsilon = sum(0.5*Z*abs((Y-Y_p)))/sum(Z)
           self.e = epsilon
	   
           # Calculates alpha
           inside = abs( (1-epsilon)/(epsilon*1.0)+0.00001 )
           print inside
           alpha = 0.5*math.log(inside)
           self.alpha.append(alpha)
     
           # Updates the weights
           Z *= np.exp(-alpha*Y*Y_p)
           Z /= sum(Z)
dataset/ETHPy150Open bt3gl/Advanced-Machine-Learning/adaboost/adaboost.py/AdaBoost.ada_train/original