def next_sample(self, batch_size=1):

        """ Return batch_size samples generated by choosing a centroid at
        random and randomly offsetting its attributes so that it is
        placed inside the hypersphere of that centroid.

        Parameters
        ----------
        batch_size: int
            The number of samples to return.

        Returns
        -------
        tuple or tuple list
            Return a tuple with the features matrix and the labels matrix for
            the batch_size samples that were requested.

        """
        data = np.zeros([batch_size, self.n_features + 1])

        for j in range(batch_size):
            centroid_aux = self.centroids[prp.random_index_based_on_weights(self.centroid_weights,
                                                                            self._sample_random_state)]
            att_vals = []
            magnitude = 0.0
            for i in range(self.n_features):
                att_vals.append((self._sample_random_state.rand() * 2.0) - 1.0)
                magnitude += att_vals[i] * att_vals[i]
            magnitude = np.sqrt(magnitude)
            desired_mag = self._sample_random_state.normal() * centroid_aux.std_dev
            scale = desired_mag / magnitude

            for i in range(self.n_features):
                if i < self.n_not_redund_features :
                    data[j, i] = centroid_aux.centre[i] + att_vals[i] * scale
                else :
                    # data[j, i] = math.sqrt(abs(data[j, self.index_redund[i-self.n_not_redund_features]] * self.coef_redund[i-self.n_not_redund_features])) # Add redundant feats
                    data[j, i] = data[j, self.index_redund[i-self.n_not_redund_features]] # Add redundant feats

            data[j, self.n_features] = centroid_aux.class_label

            # Add noise
            model_random_state = check_random_state(self.model_random_state)
            if 0.01 + model_random_state.rand() <= self.noise_percentage:
                new_class = model_random_state.randint(self.n_classes)
                while(new_class == data[j, self.n_features]) :
                    new_class = model_random_state.randint(self.n_classes)
                data[j, self.n_features] = new_class

        self.current_sample_x = data[:, :self.n_features]
        self.current_sample_y = data[:, self.n_features:].flatten().astype(int)
        return self.current_sample_x, self.current_sample_y
    def next_sample(self, batch_size=1):
        """ Returns next sample from the stream.

        Return batch_size samples generated by choosing a centroid at
        random and randomly offsetting its attributes so that it is 
        placed inside the hypersphere of that centroid.
        
        Parameters
        ----------
        batch_size: int (optional, default=1)
            The number of samples to return.
        
        Returns
        -------
        tuple or tuple list
            Return a tuple with the features matrix and the labels matrix for 
            the batch_size samples that were requested. 
        
        """
        data = np.zeros([batch_size, self.n_features + 1])
        for j in range(batch_size):
            centroid_aux = self.centroids[prp.random_index_based_on_weights(
                self.centroid_weights, self._sample_random_state)]
            att_vals = []
            magnitude = 0.0
            for i in range(self.n_features):
                att_vals.append((self._sample_random_state.rand() * 2.0) - 1.0)
                magnitude += att_vals[i] * att_vals[i]
            magnitude = np.sqrt(magnitude)
            desired_mag = self._sample_random_state.normal(
            ) * centroid_aux.std_dev
            scale = desired_mag / magnitude
            for i in range(self.n_features):
                data[j, i] = centroid_aux.centre[i] + att_vals[i] * scale
            data[j, self.n_features] = centroid_aux.class_label
        self.current_sample_x = data[:, :self.n_features]
        self.current_sample_y = data[:, self.n_features:].flatten().astype(int)
        return self.current_sample_x, self.current_sample_y