def testGradientKrig(): '''Test 6. Check that the gradient of the krigged function is calculated correctly (ok, approximately), first in 1D, then in 2D ''' r = 1.72 d = 2.28 dx = 1e-8 #1D: # container setup specs = cot.Container(truth.big_poly_1D, r=r, d=d) specs.add_point(np.array([1.0])) specs.add_point(np.array([-1.0])) specs.set_matrices() # x is where derivative is calculated x = np.array([0.47]) # the derivative calculated using calculus differentiation analytic = specs.kriging(x, True, True)[2] # derivative calculated using finite differences numeric = (specs.kriging(x + dx) - specs.kriging(x - dx)) / (2 * dx) # should equal (ok, almost equal) assert abs(numeric - analytic) < 10e-6 #2D: # container setup specs = cot.Container(rose.rosenbrock_2D, r=r, d=d) specs.add_point(np.array([1.0, 2.11])) specs.add_point(np.array([5.0, -4.3])) specs.add_point(np.array([-2.0, 0.22])) specs.set_matrices() # x is where we calculate the derivative x = np.array([2.3, 1.1]) krig = specs.kriging(x) # tthe derivative using the rules of calculus analytic = specs.kriging(x, True, True)[2] # derivative using finite differences numeric = np.zeros(2) numeric[0] = (specs.kriging(x + np.array([dx, 0])) - krig) / dx numeric[1] = (specs.kriging(x + np.array([0, dx])) - krig) / dx # should equal (almost) assert np.allclose(analytic, numeric)
def testSymmetric(): ''' Test 1. Giving the kriging procedure symmetric values, we expect it to predict zero for their center of mass ''' X = [] X.append(np.array([0, 1])) X.append(np.array([1, 0])) X.append(np.array([0, -1])) X.append(np.array([-1, 0])) F = [] F.append(np.array([2])) F.append(np.array([-1])) F.append(np.array([-2])) F.append(np.array([1])) # create the container. we don'te use the true LL specs = cot.Container(truth.zero) # make sure the prior doesn't bother us specs.set_prior(lambda x: 0.0, lambda x: 0.0) for i in range(len(X)): specs.add_pair(X[i], F[i]) # the center of mass of the x1,...,x4 is (0,0) s = np.array([0, 0]) # kriging for this center ... b = specs.kriging(s, False, False) # should be zero, by symmetry assert abs(b - 0) < 10 - 8
def testGradientSigSqr(): '''Test 7. Check that the gradient of the kriged variance is calculated correctly (ok, approximately), first in 1D, then in 2D. See the comments in testGradientKrig, since these methods are practically the same (different calculations carried out under the hood, though). ''' r = 1.3 d = 2.28 dx = 1e-7 #1D: # container setup specs = cot.Container(truth.big_poly_1D, r=r, d=d) specs.add_point(np.array([1.0])) specs.add_point(np.array([-1.0])) specs.set_matrices() x = np.array([0.47]) analytic = specs.kriging(x, grads=True)[3] numeric = (specs.kriging(x + dx, var=True)[1] - specs.kriging(x - dx, var=True)[1]) / (2 * dx) assert abs(numeric - analytic) < 10e-8 #2D. Set the container specs = cot.Container(rose.rosenbrock_2D, r=r, d=d) specs.add_point(np.array([1.0, 2.11])) specs.add_point(np.array([5.0, -4.3])) specs.add_point(np.array([-2.0, 0.22])) specs.set_matrices() numeric = np.zeros(2) x = np.array([2.3, 1.1]) analytic = specs.kriging(x, grads=True)[3] # simple divided differences numeric[0] = (specs.kriging(x + np.array([dx, 0]), var=True)[1] - specs.kriging(x + np.array([-dx, 0]), var=True)[1]) / (2 * dx) numeric[1] = (specs.kriging(x + np.array([0, dx]), var=True)[1] - specs.kriging(x + np.array([0, -dx]), var=True)[1]) / (2 * dx) assert np.allclose(analytic, numeric)
def testTychonoffSimple(): '''Test 4. Test the linear solver we use - This solver uses tychonoff regularization. here we make sure the tychonoff regularization behaves reasonably for a trivial example ''' A = np.array([[1, 2], [3, 4]]) specs = cot.Container(truth.zero) specs.U, specs.S, specs.V = np.linalg.svd(A, full_matrices=True, compute_uv=True) specs.reg = 100 * np.finfo(np.float).eps b = np.array([1, 1]) svdSol = _aux.solver(specs.U, specs.S, specs.V, b, specs.reg) trueSol = np.array([-1, 1]) assert np.allclose(svdSol, trueSol)
def testSampler(): '''Here we sample from the sampler. We choose to learn from the samples. ''' # creating the container object... specs = cot.Container(rose.rosenbrock_2D) specs.add_point(np.array([-1.5, 2.0])) specs.add_point(np.array([1.5, -2.0])) sampler = smp.Sampler(specs, nwalkers=20) sampler.learn() specs = specs sampler = sampler assert len(specs.X) == 3 assert len(specs.X[0]) == len(specs.X[1]) assert len(specs.X[0]) == len(specs.X[2])
def testUniform(): ''' Test 2. Test kriging by making sure the procedure outputs a constant 0 when it is given constant 0 input ''' specs = cot.Container(truth.zero) specs.set_prior(lambda x: 0.0, lambda x: 0.0) # create locations where values of log # likelihood are known X = [] X.append(np.array([0.5])) X.append(np.array([1.0])) X.append(np.array([1.5])) X.append(np.array([1.25])) # set all these known values to be the same for x in X: specs.add_point(x) assert np.allclose(np.array([0]), specs.kriging(np.array([20.0])))
def testTychonoffRandom(): '''Test 5. Test the linear solver we use - This solver uses tychonoff regularization. here we make sure the tychonoff regularization behaves reasonably for well conditioned matrices ''' # for reproducibility purposes np.random.seed(1792) # create some random matrix A = np.random.rand(50, 50) # this is really a mocked container object. # it holds no data, only what we put in it specs = cot.Container(truth.zero) # get SVD specs.U, specs.S, specs.V = np.linalg.svd(A, full_matrices=True, compute_uv=True) # the regularization factor we ususlly use in the solver specs.reg = 100 * np.finfo(np.float).eps # create three random target vectors b = np.array(np.random.rand(50)) # solve using our solver x = _aux.solver(specs.U, specs.S, specs.V, b, specs.reg) # solve using standard package y = np.linalg.solve(A, np.ravel(b)) # compare solutions assert np.allclose(x, y)
def testGaussian(): ''' take samples from posterior (log) likelihood and plot in histogram ''' # set seed for reproducibility np.random.seed(89) # allocating memory x = np.arange(-10, 10, 0.05) n = len(x) f = np.zeros(n) # create an instance of the container specs = cot.Container(truth.gaussian_1D) specs.set_prior(lambda x: -np.linalg.norm(x)**2, lambda x: -2 * x) # use one initial point specs.add_point(np.array([0.0])) # create the sampler sampler = smp.Sampler(specs) k = 11 # ...decide how many initial points we take to resolve the log-likelihood for j in range(0, k): print("Initial samples " + str(j + 1) + " of " + str(k)) sampler.learn( ) # ... sample, incorporate into data set, repeat k times. # plot kriged LL # calculate the curves for the given input for j in range(0, n): # do kriging f[j] = specs.kriging(x[j], False, False) # do all the plotting here curve1 = plt.plot(x, f, label="kriged value") plt.plot(specs.X, specs.F, 'bo', label="sampled points ") plt.plot(x, specs.trueLL(x), label="true log-likelihood") plt.setp(curve1, 'linewidth', 3.0, 'color', 'k', 'alpha', .5) plt.legend(loc=1, prop={'size': 7}) plt.title("Kriged Log Likelihood") plt.savefig("graphics/Test_Gaussian: kriged LL") plt.close() # Done plotting kriged LL, now sample: # take some samples. We DO NOT incorporate these into the data set numSamples = 2000 # allocate memory for the data samples = np.zeros(numSamples) batchSize = sampler.nwalkers batch = np.zeros(batchSize) # sample n points from the kriged posterior log likelihood print("taking " + str(numSamples) + " samples from the posterior:") for j in range(numSamples / batchSize): # get a batch of the current walkers batch = sampler.sample_batch() # iterate over this batch for i in range(batchSize): # add every walker to the samples and print samples[j * batchSize + i] = batch[i, :] print("Sample batch from psterior: " + str(j * batchSize) + " to " + str((j + 1) * batchSize) + " of " + str(numSamples)) # do all the plotting business, copied from pylab's examples P.figure() # the histogram of the data with histtype='step' _, _, patches = P.hist(samples, 30, normed=1, histtype='stepfilled') P.setp(patches, 'facecolor', 'g', 'alpha', 0.75) P.title( str(numSamples) + " samples from the posterior likelihood interpolating a Gaussian") P.savefig("graphics/Test_Gaussian: Posterior Histogram") P.close()
def testLikelihood(): '''test and plot kriging with and show the resulting (unnormalized) likelihood function. Here we let our sampler choose points on its own. ''' # for reproducibility purposes np.random.seed(1243) # create the container object specs = cot.Container(truth.double_well_1D) # note that this prior DOES NOT decay like the # true LL. still, the plot of the likelihood looks good specs.set_prior(lambda x: -x * x, lambda x: -2 * x) # quick setup pt = 2 * np.ones(1) specs.add_point(pt) specs.add_point(-pt) # create sampler... sampler = smp.Sampler(specs) k = 11 # ...decide how many initial points we take to resolve the log-likelihood for j in range(k): print("Sample " + str(j + 1) + " of " + str(k)) sampler.learn( ) # ... sample, incorporate into data set, repeat k times. # allocating memory M = 4 x = np.arange(-M, M, 0.05) n = len(x) f = np.zeros(n) true = np.zeros(n) prior = np.ones(n) # calculate the curves for the given input for j in range(0, n): # do kriging, get avg value and std dev krig = specs.kriging(x[j]) f[j] = (krig) # set the interpolant prior[j] = specs.prior(x[j]) # set the limiting curve true[j] = specs.trueLL(x[j]) #move to normal, non-exponential, scale fExp = np.exp(f) priorExp = np.exp(prior) trueExp = np.exp(true) samplesExp = np.exp(np.asarray(specs.F)) X = np.asarray(specs.X) # first plot curve1 = plt.plot(x, f, label="kriged LL") curve2 = plt.plot(x, true, label="true LL") curve3 = plt.plot(x, prior, label="prior") plt.plot(specs.X, specs.F, 'bo', label="sampled points ") plt.setp(curve1, 'linewidth', 3.0, 'color', 'k', 'alpha', .5) plt.setp(curve2, 'linewidth', 1.5, 'color', 'r', 'alpha', .5) plt.setp(curve3, 'linewidth', 1.5, 'color', 'b', 'alpha', .5) plt.legend(loc=1, prop={'size': 7}) plt.title("Learned log likelihood") plt.savefig("graphics/testLikelihood: Learned log-likelihood") plt.close() # second plot curve4 = plt.plot(x, fExp, label="exp(kriged LL)") curve5 = plt.plot(x, trueExp, label="(unnormalized) likelihood") curve6 = plt.plot(x, priorExp, label="exp(prior)") plt.plot(X, samplesExp, 'bo', label="sampled points ") plt.setp(curve4, 'linewidth', 3.0, 'color', 'k', 'alpha', .5) plt.setp(curve5, 'linewidth', 1.5, 'color', 'r', 'alpha', .5) plt.setp(curve6, 'linewidth', 3.0, 'color', 'b', 'alpha', .5) plt.legend(loc=1, prop={'size': 7}) plt.title("Learned (unnormalized) Likelihood") plt.savefig("graphics/testLikelihood: Learned Likelihood") plt.close()
def testKriging(): '''create a plot that shows kriging ''' # locations where we know the log-likelihood value X = [] X.append(np.array([1.1])) X.append(np.array([1.0])) X.append(np.array([-1.1])) X.append(np.array([-3.0])) # create the container object and populate it... specs = cot.Container(truth.sin_1D) # set the prior so the pics look nice specs.set_prior(lambda x: -x * x / 20.0, lambda x: -x / 10.0) for v in X: specs.add_point(v) #... with (point, value) pair... # allocating memory x = np.arange(-4, 2, 0.05) n = len(x) f = np.zeros(n) upper = np.zeros(n) lower = np.zeros(n) fx = np.zeros(n) upperx = np.zeros(n) lowerx = np.zeros(n) # the default prior prior = np.ravel(specs.prior(x)) # calculate the curves for the given input for j in range(0, n): # do kriging, get avg value and std dev krig, sigSqr = specs.kriging(x[j], var=True) f[j] = krig # set the interpolant sig = math.sqrt(sigSqr) upper[j] = krig + 1.96 * sig # set the upper bound lower[j] = krig - 1.96 * sig # set lower bound specs.add_pair(np.array([-3.5]), specs.kriging(np.array([-3.5]), grads=False, var=False)) for j in range(0, n): # do kriging, get avg value and std dev krig, sigSqr = specs.kriging(x[j], var=True) fx[j] = krig # set the interpolant sig = math.sqrt(sigSqr) upperx[j] = krig + 1.96 * sig # set the upper bound lowerx[j] = krig - 1.96 * sig # set lower bound # do all the plotting here curve1 = plt.plot(x, f, label="kriged value") curve2 = plt.plot(x, upper, label="1.96 standard deviations") curve3 = plt.plot(x, lower) curve4 = plt.plot(x, prior, label="prior") curve5 = plt.plot(x, fx, label="with an extra point") curve6 = plt.plot(x, upperx, label="1.96 std with point") curve7 = plt.plot(x, lowerx) plt.plot(specs.X, specs.F, 'bo', label="sampled points ") plt.setp(curve1, 'linewidth', 3.0, 'color', 'k', 'alpha', .5) plt.setp(curve2, 'linewidth', 1.5, 'color', 'r', 'alpha', .5) plt.setp(curve3, 'linewidth', 1.5, 'color', 'r', 'alpha', .5) plt.setp(curve4, 'linewidth', 1.5, 'color', 'b', 'alpha', .5) plt.setp(curve5, 'linewidth', 1.5, 'color', 'g', 'alpha', .5) plt.setp(curve6, 'linewidth', 1.5, 'color', 'y', 'alpha', .5) plt.setp(curve7, 'linewidth', 1.5, 'color', 'y', 'alpha', .5) plt.legend(loc=1, prop={'size': 7}) plt.title("Kriging with bounds ") plt.savefig("graphics/testKriging: Kriged LL") plt.close()
def testMovie1D(): ''' if this does not work, it is likely that you don't have ffmpeg. change these to whatever movie maker you have on your system. this unit test creates a movie. run it and see for yourself!! ''' # tell the OS to prepare for the movie and the frames os.system("rm -f Data/Movie1DFrames/*.png") # for reproducibility np.random.seed(1792) # Initializations of the container object specs = cot.Container(truth.big_poly_1D) # specs.set_prior( lambda x: -np.linalg.norm(x)**6) M = 2.5 # we know the true log-likelihood in these points StartPoints = [] StartPoints.append(np.array([0])) StartPoints.append(np.array([0.5])) for point in StartPoints: specs.add_point(point) sampler = smp.Sampler(specs) # the bounds on the plot axes xMin = -M xMax = M yMax = 100 yMin = -300 # all the x values for which we plot x = np.arange(xMin, xMax, 0.05) # we create each frame many times, so the movie is slower and easier to watch delay = 3 # The number of evaluations of the true likelihood # change this if you want a longer\shorter movie nf = 33 # allocate memory for the arrays to be plotted kriged = np.zeros(x.shape) true = np.zeros(x.shape) # create frames for the ffmpeg programs for frame in range(nf + 1): # create the kriged curve and the limit curve for j in range(0, len(x)): kriged[j] = specs.kriging(x[j], False, False) true[j] = specs.trueLL(x[j]) # the real log likelihood # each frame is saved delay times, so we can watch the movie at reasonable speed # for k in range(delay): plt.figure(frame * delay) # here we create the plot. nothing too fascinating here. curve1 = plt.plot(x, kriged, label="kriged log-likelihood") curve2 = plt.plot(x, true, label="true log-likelihood") plt.plot(specs.X, specs.F, 'bo', label="sampled points ") plt.setp(curve1, 'linewidth', 3.0, 'color', 'k', 'alpha', .5) plt.setp(curve2, 'linewidth', 1.5, 'color', 'r', 'alpha', .5) plt.axis([xMin, xMax, yMin, yMax]) plt.title('Kriged Log-Likelihood Changes in Time. r = ' + str(specs.r)) textString = 'using ' + str(len(specs.X)) + ' sampled points' plt.text(1.0, 1.0, textString) plt.legend(loc=1, prop={'size': 7}) for k in range(delay): FrameFileName = "Data/Movie1DFrames/Frame" + str(frame * delay + k) + ".png" plt.savefig(FrameFileName) if (frame * delay + k) % 10 == 0: print("saved file " + FrameFileName + ". " + str(frame * delay + k) + " / " + str(nf * delay)) plt.close(frame * delay) # IMPORTANT - we sample from the kriged log-likelihood. this is crucial!!!! sampler.learn()
def testMovie2D(helpers): '''create a 2D movie, based on the data we put in the container object in the setUp method sthis method does all the graphics involved since this is a 2D running for lots of points might take a while ''' make_movie_frame, getLevels = helpers # for reproducibility np.random.seed(1792) # tell the OS to prepare for the movie and the frames os.system("rm -f Data/Movie2DContourFrames/*.png") # parameters to play with nSamples = 5000 # number of samples we use for KL maxiter = 3000 # max number of optimization steps nPoints = 60 # The number of evaluations of the true likelihood delay = 3 # number of copies of each frame M = 7 # bound on the plot axes nopt = 15 nwalk = 50 burn = 500 LLlevels = getLevels(350, -1e6, 1e4) # levels of log likelihood contours intLevels = np.concatenate( [np.arange(0, 4, 0.8), np.arange(5, 50, 15), np.arange(50, 550, 250)]) # levels of integrand contours delta = 0.1 # grid for the contour plots parameters = [nSamples, maxiter, nwalk, nopt, nPoints, M, delay, delta] # initialize container and sampler specs = cot.Container(rose.rosenbrock_2D) n = 1 for i in range(-n, n + 1): for j in range(-n, n + 1): specs.add_point(np.array([2 * i, 2 * j])) sampler = smp.Sampler(specs, target=targets.exp_krig_sigSqr, maxiter=maxiter, nwalkers=nwalk, noptimizers=nopt, burn=burn) # memory allocations. constants etc KL = [] # create list for KL div and its error bars a = np.arange(-M, M, delta) X, Y = np.meshgrid(a, a) # create two meshgrid form = X.shape points = np.asarray([np.ravel(X), np.ravel(Y)]) frame = 0 desc = sampler.target.desc locRos = rose.rosenbrock_2D locKrig = specs.kriging # some calculations we'll use again and again rosen = np.reshape(locRos(points, True), form) xpRosen = np.exp(rosen) xpRosenTimesRosen = xpRosen * rosen Zphi = np.sum(xpRosen) # no delta**2!! see below # create frames for the movie for sample in range(nPoints + 1): # get the KL divergence estimate and error bars samples = rose.sample_rosenbrock(nSamples) tmpKL = kl.get_KL(locRos, locKrig, samples) # tmpKL = rose.rosenbrock_KL(specs, nSamples) # the kriged surface kriged = np.reshape(np.asarray([locKrig(x) for x in points.T]), form) # the integrand (contour plot on left) integrand = np.reshape(xpRosenTimesRosen - xpRosen * kriged, form) # Z(rosenbrock) = 1!! # estimate of log(Z) by using a riemann sum on the grid Zpsi = np.sum(np.exp(kriged)) # no delta**2 ... logZpsiOverZphi = math.log(Zpsi / Zphi) # ...it would've cancelled out!! # estimate of the KL divergence, from the grid we used for plotting uniKL = delta * delta * np.sum(integrand) + logZpsiOverZphi tmpKL.append(uniKL) # add this to the other estimates # the value of KL integrand at every point on the grid integrand = integrand + logZpsiOverZphi tmpKL.append(uniKL) tmpKL.append(logZpsiOverZphi) KL.append(tmpKL) # print("Here's one problem - the log of the normalization constants don't agree.") # print(tmpKL[6]) # # print(logZpsiOverZphi) # make the frames frame = make_movie_frame(sample, frame, LLlevels, intLevels, kriged, integrand, specs.X, X, Y, KL, desc, parameters) # learn a new point and incorporate it and save sampler.learn()