dir_conc = [2.0, 16.0, 128.0, 1024.0] # Do the 'simple' kernels... for kernel in [ 'uniform', 'triangular', 'epanechnikov', 'cosine', 'gaussian', 'cauchy', 'logistic' ]: for dim in dimensions: # Create a mean shift object with a single sample of the provided kernel type... ms = MeanShift() ms.set_data(numpy.array([0.0] * dim, dtype=numpy.float32), 'f') ms.set_kernel(kernel) ms.quality = 1.0 # Draw lots of samples from it... sample = ms.draws(samples) # Get the probability of each... p1 = ms.probs(sample) # Throw away samples where p1 is 0 - they are a result of the range optimisation, and break the below... keep = p1 > 1e-6 sample = sample[keep, :] p1 = p1[keep] # Do a KDE of the samples, including bandwidth estimation... kde = MeanShift() kde.set_data(sample, 'df') kde.set_kernel('uniform') # Keep is simple! kde.set_spatial('kd_tree') kde.set_scale(numpy.array([scale] * dim, dtype=numpy.float32))
kernel = 'fisher' conc = 256.0 samples = 1024 # Create the two distributions - don't need to be complicated... correct = MeanShift() correct.set_data(numpy.array([1.0] + [0.0]*(dims-1), dtype=numpy.float32), 'f') correct.set_kernel('%s(%.1fc)' % (kernel, conc)) correct.quality = 1.0 approximate = MeanShift() approximate.set_data(numpy.array([1.0] + [0.0]*(dims-1), dtype=numpy.float32), 'f') approximate.set_kernel('%s(%.1fa)' % (kernel, conc)) approximate.quality = 1.0 # Draw a bunch of samples and compare the probabilities in both to check they are basically the same... sample = correct.draws(samples) cp = correct.probs(sample) ap = approximate.probs(sample) diff = numpy.fabs(cp-ap) print 'Maximum probabilities =', cp.max(), ap.max() print 'Maximum probability difference =', diff.max(), (diff.max() / cp.max()) print 'Average probability difference =', diff.mean(), (diff.mean() / cp.max())
block[:,:,:2] *= numpy.sqrt(1.0 - numpy.square(y_to_nz)).reshape((-1,1,1)) ## Calculate the probability for each location... prob = ms.probs(block.reshape((-1,3))) prob = prob.reshape((height, width)) ## Save it out... image = array2cv(255.0 * prob / prob.max()) cv.SaveImage('fisher_mercator_kde.png', image) # Draw a new set of samples; visualise them... print 'Draw...' draw = ms.draws(8*1024) image = numpy.zeros((height, width, 3), dtype=numpy.float32) for vec in draw: x = numpy.arctan2(vec[1], vec[0]) if x<0.0: x += 2.0*numpy.pi x = x * width / (2.0 * numpy.pi) if x>=width: x -= width y = 0.5*(1.0+vec[2]) * height try: image[y,x,:] = 255.0 except: print 'Bad draw:', vec
# Do the 'simple' kernels... for kernel in ['uniform', 'triangular', 'epanechnikov', 'cosine', 'gaussian', 'cauchy', 'logistic']: for dim in dimensions: # Create a mean shift object with a single sample of the provided kernel type... ms = MeanShift() ms.set_data(numpy.array([0.0]*dim, dtype=numpy.float32), 'f') ms.set_kernel(kernel) ms.quality = 1.0 # Create a uniform sample over a suitably large region (Yes I am assuming I got the uniform kernel right!)... uniform = MeanShift() uniform.set_data(numpy.array([0.0]*dim, dtype=numpy.float32), 'f') uniform.set_kernel('uniform') uniform.set_scale(numpy.ones(dim) / ms.get_range()) sample = uniform.draws(samples) sp = uniform.prob(sample[0,:]) # Evaluate the probabilities of the uniform set... p = ms.probs(sample) # Print their average, which we are hoping is one... volume = p.mean() / sp print 'Kernel = %s; Dims = %i | Monte-Carlo volume = %.3f' % (kernel, dim, volume) print # Now for the directional kernels... for kernel in ['fisher', 'mirror_fisher']: for dim, area in zip(dir_dimensions, dir_area): for conc in dir_conc:
for i in xrange(angle_step): t = float(i) / (angle_step - 1) t_x = int(s_x - (1 - t) * o_x) t_y = int(s_y - (1 - t) * o_y) try: if img[t_y, t_x, 2] < t: img[t_y, t_x, 2] = t except: pass img = array2cv(255.0 * img) cv.SaveImage(fn, img) visualise('bandwidth_a_input.png', data) draw = ms.draws(samples) visualise('bandwidth_a_draw.png', draw) # Change the data and reoptimise - data with a very different scale... print 'b:' direction = [] radius = [] ang_a = [] ang_b = [] for i in xrange(8): count = samples // 8 direction.append(numpy.random.normal(numpy.pi * 2.0 * i / 8.0, 0.2, count)) radius.append(0.5 + numpy.random.normal(
for i in xrange(angle_step): t = float(i) / (angle_step-1) t_x = int(s_x - (1-t) * o_x) t_y = int(s_y - (1-t) * o_y) try: if img[t_y,t_x,2] < t: img[t_y,t_x,2] = t except: pass img = array2cv(255.0 * img) cv.SaveImage(fn, img) visualise('bandwidth_a_input.png', data) draw = ms.draws(samples) visualise('bandwidth_a_draw.png', draw) # Change the data and reoptimise - data with a very different scale... print 'b:' direction = [] radius = [] ang_a = [] ang_b = [] for i in xrange(8): count = samples//8
ms = MeanShift() ms.set_data(data, 'd') ms.set_kernel('discrete') ms.set_spatial('kd_tree') # Iterate and calculate the probability at a bunch of points, then plot... sam = numpy.arange(-2.5, 2.5, 0.1) prob = numpy.array(map(lambda v: ms.prob(numpy.array([v])), sam)) print 'Distribution:' for threshold in numpy.arange(prob.max(), 0.0, -prob.max() / 10.0): print ''.join(map(lambda p: '|' if p > threshold else ' ', prob)) # Draw a bunch of points, make a new ms and then plot, again... ms2 = MeanShift() ms2.set_data(ms.draws(50), 'df') ms2.set_kernel('discrete') ms2.set_spatial('kd_tree') sam = numpy.arange(-2.5, 2.5, 0.1) prob = numpy.array(map(lambda v: ms2.prob(numpy.array([v])), sam)) print 'Distribution of draw:' for threshold in numpy.arange(prob.max(), 0.0, -prob.max() / 10.0): print ''.join(map(lambda p: '|' if p > threshold else ' ', prob)) # Another distribution and its probability... data = ([-2] * 3) + ([-1] * 2) + ([0] * 2) + ([1] * 3) + ([2] * 8) data = numpy.array(data, dtype=numpy.int32) ms3 = MeanShift()
print 'Rendering probability map:' p = ProgBar() for row in xrange(dim): p.callback(row, dim) sam = numpy.append(numpy.linspace(-size, size, dim).reshape((-1,1)), ((row / (dim-1.0) - 0.5) * 2.0 * size) * numpy.ones(dim).reshape((-1,1)), axis=1) image[row, :, :] = ms.probs(sam).reshape((-1,1)) del p image *= 255.0 / image.max() image = array2cv(image) cv.SaveImage('draw_density.png', image) # Draw a new set of samples from the KDE approximation of the distribution, and visualise... draw = ms.draws(data.shape[0]) image = numpy.zeros((dim, dim, 3), dtype=numpy.float32) for r in xrange(draw.shape[0]): loc = draw[r,:] loc = (loc + size) / (2.0*size) loc *= dim try: image[int(loc[1]+0.5), int(loc[0]+0.5), :] = 255.0 except: pass # Deals with out of range values. image = array2cv(image) cv.SaveImage('draw_normal.png', image)
p = ProgBar() for row in xrange(pixels): p.callback(row, pixels) sam = numpy.append(numpy.linspace(0.0, 1.0, pixels).reshape((-1, 1)), (row / float(pixels - 1)) * numpy.ones(pixels).reshape( (-1, 1)), axis=1) image[row, :, :] = ms.probs(sam).reshape((-1, 1)) del p image *= 255.0 / image.max() image = array2cv(image) cv.SaveImage('draw_weighted_density.png', image) # Draw a bunch of points from it and plot them... samples = numpy.random.randint(16, 512) draw = ms.draws(1024) image = numpy.zeros((pixels, pixels, 3), dtype=numpy.float32) for r in xrange(draw.shape[0]): loc = draw[r, :] loc *= pixels try: image[int(loc[1] + 0.5), int(loc[0] + 0.5), :] = 255.0 except: pass # Deals with out of range values. image = array2cv(image) cv.SaveImage('draw_weighted_samples.png', image)
img = numpy.zeros((64, 64), dtype=numpy.float32) for y in xrange(img.shape[0]): for x in xrange(img.shape[1]): ang_x = 2.0 * numpy.pi * (x / float(img.shape[1]-1)) - numpy.pi ang_y = 2.0 * numpy.pi * (y / float(img.shape[0]-1)) - numpy.pi img[y,x] = ms.prob(numpy.array([ang_x, ang_y])) img *= 255.0 / img.max() cv.SaveImage('angle_pdf.png', array2cv(img)) # Try drawing... img = numpy.zeros((256, 1024), dtype=numpy.float32) for row in ms.draws(512): for y in xrange(img.shape[0]): t = float(y) / float(img.shape[0]-1) x = row[0] * t + row[1] * (1.0-t) if x<-numpy.pi: x += numpy.pi if x>numpy.pi: x -= numpy.pi x = int(img.shape[1] * (x + numpy.pi) / (numpy.pi * 2.0)) img[y, x] += 1.0 img *= 255.0 / img.max() cv.SaveImage('angle_draw.png', array2cv(img)) # New data sets to multiply together, single angles this time...
dir_dimensions = [2, 3, 4] dir_conc = [2.0, 16.0, 128.0, 1024.0] # Do the 'simple' kernels... for kernel in ['uniform', 'triangular', 'epanechnikov', 'cosine', 'gaussian', 'cauchy', 'logistic']: for dim in dimensions: # Create a mean shift object with a single sample of the provided kernel type... ms = MeanShift() ms.set_data(numpy.array([0.0]*dim, dtype=numpy.float32), 'f') ms.set_kernel(kernel) ms.quality = 1.0 # Draw lots of samples from it... sample = ms.draws(samples) # Get the probability of each... p1 = ms.probs(sample) # Throw away samples where p1 is 0 - they are a result of the range optimisation, and break the below... keep = p1>1e-6 sample = sample[keep,:] p1 = p1[keep] # Do a KDE of the samples, including bandwidth estimation... kde = MeanShift() kde.set_data(sample, 'df') kde.set_kernel('uniform') # Keep is simple! kde.set_spatial('kd_tree') kde.set_scale(numpy.array([scale]*dim, dtype=numpy.float32))
for i in xrange(angle_step): t = float(i) / (angle_step - 1) t_x = int(t * s_x + (1 - t) * e_x) t_y = int(t * s_y + (1 - t) * e_y) try: if img[t_y, t_x, 0] < t: img[t_y, t_x, :] = t except: pass img = array2cv(255.0 * img) cv.SaveImage('composite_input.png', img) # Now draw the same number of cameras again and visualise so a fleshy can check they are similar... draw = ms.draws(data.shape[0]) img = numpy.zeros((size, size, 3), dtype=numpy.float32) for sample in draw: s_x = (size - 1) * sample[1] / scale s_y = (size - 1) * sample[0] / scale e_x = (size - 1) * (sample[1] + angle_len * sample[3]) / scale e_y = (size - 1) * (sample[0] + angle_len * sample[2]) / scale for i in xrange(angle_step): t = float(i) / (angle_step - 1) t_x = int(t * s_x + (1 - t) * e_x) t_y = int(t * s_y + (1 - t) * e_y) try: if img[t_y, t_x, 0] < t:
# Test the mirrored version of the von_mises Fisher distribution, this time in 5D... # Create a dataset - just a bunch of points in one direction, so we can test the mirroring effect (Abuse MeanShift object to do this)... print 'Mirrored draws:' vec = numpy.array([1.0, 0.5, 0.0, -0.5, -1.0]) vec /= numpy.sqrt(numpy.square(vec).sum()) print 'Base dir =', vec draw = MeanShift() draw.set_data(vec, 'f') draw.set_kernel('fisher(256.0)') data = draw.draws(32) #print 'Input:' #print data # Create a mean shift object from the draws, but this time with a mirror_fisher kernel... mirror = MeanShift() mirror.set_data(data, 'df') mirror.set_kernel('mirror_fisher(64.0)') resample = mirror.draws(16) for row in resample: print '[%6.3f %6.3f %6.3f %6.3f %6.3f]' % tuple(row) print
# Iterate and calculate the probability at a bunch of points, then plot... sam = numpy.arange(-2.5, 2.5, 0.1) prob = numpy.array(map(lambda v: ms.prob(numpy.array([v])), sam)) print 'Distribution:' for threshold in numpy.arange(prob.max(), 0.0, -prob.max()/10.0): print ''.join(map(lambda p: '|' if p>threshold else ' ', prob)) # Draw a bunch of points, make a new ms and then plot, again... ms2 = MeanShift() ms2.set_data(ms.draws(50), 'df') ms2.set_kernel('discrete') ms2.set_spatial('kd_tree') sam = numpy.arange(-2.5, 2.5, 0.1) prob = numpy.array(map(lambda v: ms2.prob(numpy.array([v])), sam)) print 'Distribution of draw:' for threshold in numpy.arange(prob.max(), 0.0, -prob.max()/10.0): print ''.join(map(lambda p: '|' if p>threshold else ' ', prob)) # Another distribution and its probability... data = ([-2] * 3) + ([-1] * 2) + ([0] * 2) + ([1] * 3) + ([2] * 8) data = numpy.array(data, dtype=numpy.int32)
'uniform', 'triangular', 'epanechnikov', 'cosine', 'gaussian', 'cauchy', 'logistic' ]: for dim in dimensions: # Create a mean shift object with a single sample of the provided kernel type... ms = MeanShift() ms.set_data(numpy.array([0.0] * dim, dtype=numpy.float32), 'f') ms.set_kernel(kernel) ms.quality = 1.0 # Create a uniform sample over a suitably large region (Yes I am assuming I got the uniform kernel right!)... uniform = MeanShift() uniform.set_data(numpy.array([0.0] * dim, dtype=numpy.float32), 'f') uniform.set_kernel('uniform') uniform.set_scale(numpy.ones(dim) / ms.get_range()) sample = uniform.draws(samples) sp = uniform.prob(sample[0, :]) # Evaluate the probabilities of the uniform set... p = ms.probs(sample) # Print their average, which we are hoping is one... volume = p.mean() / sp print 'Kernel = %s; Dims = %i | Monte-Carlo volume = %.3f' % ( kernel, dim, volume) print # Now for the directional kernels... for kernel in ['fisher', 'mirror_fisher']: for dim, area in zip(dir_dimensions, dir_area): for conc in dir_conc:
print 'Rendering probability map:' p = ProgBar() for row in xrange(pixels): p.callback(row, pixels) sam = numpy.append(numpy.linspace(0.0, 1.0, pixels).reshape((-1,1)), (row / float(pixels-1)) * numpy.ones(pixels).reshape((-1,1)), axis=1) image[row, :, :] = ms.probs(sam).reshape((-1,1)) del p image *= 255.0 / image.max() image = array2cv(image) cv.SaveImage('draw_weighted_density.png', image) # Draw a bunch of points from it and plot them... samples = numpy.random.randint(16, 512) draw = ms.draws(1024) image = numpy.zeros((pixels, pixels, 3), dtype=numpy.float32) for r in xrange(draw.shape[0]): loc = draw[r,:] loc *= pixels try: image[int(loc[1]+0.5), int(loc[0]+0.5), :] = 255.0 except: pass # Deals with out of range values. image = array2cv(image) cv.SaveImage('draw_weighted_samples.png', image)