def draw_MAP_residuals(objectsA, objectsB, P, scaled='no'): from pyBA.distortion import compute_displacements, compute_residual from numpy import array # Compute displacements between frames for tie objects xobs, yobs, vxobs, vyobs, sxobs, syobs = compute_displacements(objectsA, objectsB) # Compute residual dx, dy = compute_residual(objectsA, objectsB, P) # Draw residuals fig = figure(figsize=(16,16)) ax = fig.add_subplot(111, aspect='equal') if scaled is 'yes': # Allow relative scaling of arrows quiver(xobs,yobs,dx,dy) else: # Show residuals in absolute size (often very tiny), with uncertainties # Also plot error ellipses ellipses = array([ Bivarg( mu = array([xobs[i] + dx[i], yobs[i] + dy[i]]), sigma = objectsA[i].sigma + objectsB[i].sigma ) for i in range(len(objectsA)) ]) draw_objects(ellipses, replot='yes') # Residuals quiver(xobs,yobs,dx,dy,color='r', angles='xy', scale_units='xy', scale=1) ax.autoscale(enable=None, axis='both', tight=True) show()
def regression(self, xy): """Performs regression on a mapping object at some locations, which can be points or distributions.""" from scipy.linalg import cho_solve from pyBA.distortion import d2, astrometry_cov, compute_residual # Convert list of inputs to array if needed if type(xy) == list: xy = np.array(xy) # Parse input if type(xy)==np.ndarray: # Single point if xy.size == 2 and type(xy)==np.ndarray: XY = np.array([ Bivarg(mu=xy,sigma=0) ]) # Array of points elif xy.ndim == 2 and type(xy[0])==np.ndarray: XY = np.array([ Bivarg(mu=xy[i],sigma=0) for i in range(len(xy)) ]) # Array of query distributions elif type(xy[0].__class__.__name__=='Bivarg'): XY = xy else: raise TypeError('Regression input should be an nx2 array of coordinates, or an array of Bivarg distributions') # Single query distribution elif xy.__class__.__name__ == 'Bivarg': XY = np.array([ xy ]) else: raise TypeError('Regression input should be an nx2 array of coordinates, or an array of Bivarg distributions') ## Gaussian process regression # Old grid coordinates xyobs = np.array([o.mu for o in self.A]) # New grid coordinates xynew = np.array([o.mu for o in XY]) # Get regression data (resdiual to background) dx, dy = compute_residual(self.A, self.B, self.P) dxy = np.array([dx, dy]).T.flatten() # Build cross covariance between old and new locations d2_grid = d2(xynew,xyobs) Cs = astrometry_cov(d2_grid, self.scale, self.amp) # Build covariance for new locations d2_grid = d2(xynew, xynew) Vnew = np.array([o.sigma for o in XY]) # Don't need to add variances for input points here, they will be propagated # through the background transformation. #Css = astrometry_cov(d2_grid, self.scale, self.amp, var=Vnew) Css = astrometry_cov(d2_grid, self.scale, self.amp) # Regression: mean function evaluated at new locations vxy = Cs.dot(cho_solve(self.chol, dxy)).reshape( (len(XY),2) ) # Regression: uncertainties at new locations S = Css - Cs.dot(cho_solve(self.chol, Cs.T)) ## Package output # Background (mean function) mapping R = np.array([o.transform(self.P) for o in XY]) # Add regression residuals to mean function munew = np.array([o.mu for o in R]) + vxy # Get regression uncertainty from background mapping S_P = self.P.uncertainty(XY) # Get regression uncertainty from gaussian process S_gp = np.array([S[i:i+2,i:i+2] for i in range(0,len(S),2)]) # Combine uncertainties into single covariance matrix sigmanew = np.array([o.sigma for o in R]) + S_gp + S_P # Construct output array of Bivargs O = np.array([ Bivarg(mu=munew[i], sigma=sigmanew[i]) for i in range(len(R)) ]) return O, S_gp, S_P
def regression(self, xy): """Performs regression on a mapping object at some locations, which can be points or distributions.""" from scipy.linalg import cho_solve from pyBA.distortion import d2, astrometry_cov, compute_residual # Convert list of inputs to array if needed if type(xy) == list: xy = np.array(xy) # Parse input if type(xy) == np.ndarray: # Single point if xy.size == 2 and type(xy) == np.ndarray: XY = np.array([Bivarg(mu=xy, sigma=0)]) # Array of points elif xy.ndim == 2 and type(xy[0]) == np.ndarray: XY = np.array( [Bivarg(mu=xy[i], sigma=0) for i in range(len(xy))]) # Array of query distributions elif type(xy[0].__class__.__name__ == 'Bivarg'): XY = xy else: raise TypeError( 'Regression input should be an nx2 array of coordinates, or an array of Bivarg distributions' ) # Single query distribution elif xy.__class__.__name__ == 'Bivarg': XY = np.array([xy]) else: raise TypeError( 'Regression input should be an nx2 array of coordinates, or an array of Bivarg distributions' ) ## Gaussian process regression # Old grid coordinates xyobs = np.array([o.mu for o in self.A]) # New grid coordinates xynew = np.array([o.mu for o in XY]) # Get regression data (resdiual to background) dx, dy = compute_residual(self.A, self.B, self.P) dxy = np.array([dx, dy]).T.flatten() # Build cross covariance between old and new locations d2_grid = d2(xynew, xyobs) Cs = astrometry_cov(d2_grid, self.scale, self.amp) # Build covariance for new locations d2_grid = d2(xynew, xynew) Vnew = np.array([o.sigma for o in XY]) # Don't need to add variances for input points here, they will be propagated # through the background transformation. #Css = astrometry_cov(d2_grid, self.scale, self.amp, var=Vnew) Css = astrometry_cov(d2_grid, self.scale, self.amp) # Regression: mean function evaluated at new locations vxy = Cs.dot(cho_solve(self.chol, dxy)).reshape((len(XY), 2)) # Regression: uncertainties at new locations S = Css - Cs.dot(cho_solve(self.chol, Cs.T)) ## Package output # Background (mean function) mapping R = np.array([o.transform(self.P) for o in XY]) # Add regression residuals to mean function munew = np.array([o.mu for o in R]) + vxy # Get regression uncertainty from background mapping S_P = self.P.uncertainty(XY) # Get regression uncertainty from gaussian process S_gp = np.array([S[i:i + 2, i:i + 2] for i in range(0, len(S), 2)]) # Combine uncertainties into single covariance matrix sigmanew = np.array([o.sigma for o in R]) + S_gp + S_P # Construct output array of Bivargs O = np.array( [Bivarg(mu=munew[i], sigma=sigmanew[i]) for i in range(len(R))]) return O, S_gp, S_P