def _bfit_get_prior(distribution, em=0): from csb.statistics import scalemixture as sm if distribution == 'student': prior = sm.GammaPrior() if em: prior.estimator = sm.GammaPosteriorMAP() elif distribution == 'k': prior = sm.InvGammaPrior() if em: prior.estimator = sm.InvGammaPosteriorMAP() else: raise AttributeError('distribution') return prior
def bfit(X, Y, n_iter=10, distribution='student', em=False, full_output=False): """ Robust superposition of two coordinate arrays. Models non-rigid displacements with outlier-tolerant probability distributions. @param X: (n, 3) input vector @type X: numpy.array @param Y: (n, 3) input vector @type Y: numpy.array @param n_iter: number of iterations @type n_iter: int @param distribution: student or k @type distribution: str @param em: use maximum a posteriori probability (MAP) estimator @type em: bool @param full_output: if true, return ((R, t), scales) @type full_output: bool @rtype: tuple """ from csb.statistics import scalemixture as sm if distribution == 'student': prior = sm.GammaPrior() if em: prior.estimator = sm.GammaPosteriorMAP() elif distribution == 'k': prior = sm.InvGammaPrior() if em: prior.estimator = sm.InvGammaPosteriorMAP() else: raise AttributeError('distribution') mixture = sm.ScaleMixture(scales=X.shape[0], prior=prior, d=3) R, t = fit(X, Y) for _ in range(n_iter): data = distance(X, transform(Y, R, t)) mixture.estimate(data) R, t = probabilistic_fit(X, Y, mixture.scales) if full_output: return (R, t), mixture.scales else: return (R, t)