def train(self, input_data, min_em_iters=1, max_em_iters=10):
        N = input_data.shape[0] 
        if input_data.shape[1] != self.D:
            print "Error: Data has %d features, model expects %d features." % (input_data.shape[1], self.D)
        self.internal_alloc_event_data(input_data)
        self.internal_alloc_eval_data(input_data)
        self.internal_alloc_component_data()
        
        if not self.components_seeded:
            self.internal_seed_data(input_data, input_data.shape[1], input_data.shape[0])

        self.eval_data.likelihood = getattr(self.get_asp_mod(),'train_'+self.cvtype)(self.M, self.D, N, min_em_iters, max_em_iters)[0]

        self.components.means = self.components.means.reshape(self.M, self.D)
        self.components.covars = self.components.covars.reshape(self.M, self.D, self.D)
        
        return self.eval_data.likelihood

        #TODO: expose only one function to the domain programmer
        #handle selection of gather mechanisms internally

        #train on subset
        #collect indices in python
        #gather in CUDA
Set the factory to construct a remote instance of a type::
dataset/ETHPy150Open hcook/gmm/gmm_specializer/gmm.py/GMM.train--crossover with--dataset/ETHPy150Open nlloyd/SubliminalCollaborator/libs/twisted/spread/jelly.py/setUnjellyableFactoryForClass