def make_knots(size=30, num_knots=4, order=7): knots = np.round(-1 + np.logspace(np.log10(1), np.log10(size - 1), num_knots)) knots = np.round(np.sqrt(knots) * (size - 1) / max(np.sqrt(knots))) knots = np.unique(knots) knots = splinelab.augknt(knots, order) return knots
def create_bspline_basis(xmin, xmax, p=3, nknots=5): """ compute a Bspline basis set where: :param p: order of spline (3 = cubic) :param nknots: number of knots (endpoints only counted once) """ knots = np.linspace(xmin, xmax, nknots) k = splinelab.augknt(knots, p) # pad the knot vector B = bspline.Bspline(k, p) return B
def bspline_fit(X, order, nknots): X = X.squeeze() if len(X.shape) > 1: raise ValueError('Bspline method only works for a single covariate.') knots = np.linspace(X.min(), X.max(), nknots) k = splinelab.augknt(knots, order) bsp_basis = bspline.Bspline(k, order) return bsp_basis
def test(): ######################## # config ######################## p = 3 # order of spline basis (as-is! 3 = cubic) nknots = 5 # for testing: number of knots to generate (here endpoints count only once) tau = [0.1, 0.33] # collocation sites (i.e. where to evaluate) ######################## # usage example ######################## knots = np.linspace( 0, 1, nknots) # create a knot vector without endpoint repeats k = splinelab.augknt( knots, p) # add endpoint repeats as appropriate for spline order p B = bspline.Bspline(k, p) # create spline basis of order p on knots k # build some collocation matrices: # A0 = B.collmat(tau) # function value at sites tau A2 = B.collmat(tau, deriv_order=2) # second derivative at sites tau print(A0) print(A2) ######################## # tests ######################## # number of basis functions n_interior_knots = len(knots) - 2 n_basis_functions_expected = n_interior_knots + (p + 1) n_basis_functions_actual = len( B(0.)) # perform dummy evaluation to get number of basis functions assert n_basis_functions_actual == n_basis_functions_expected, "something went wrong, number of basis functions is incorrect" # partition-of-unity property of the spline basis assert np.allclose( np.sum(A0, axis=1), 1.0 ), "something went wrong, the basis functions do not form a partition of unity"
Phips = np.zeros((Xs.shape[0], dimpoly)) colid = np.arange(0, 1) for d in range(1, dimpoly + 1): Phips[:, colid] = np.vstack(Xs**d) colid += 1 # generative model b = [0.5, -0.1, 0.005] # true regression coefficients s2 = 0.05 # noise variance y = Phip.dot(b) + np.random.normal(0, s2, N) # cubic B-spline basis (used for regression) p = 3 # order of spline (3 = cubic) nknots = 5 # number of knots (endpoints only counted once) knots = np.linspace(0, 10, nknots) k = splinelab.augknt(knots, p) # pad the knot vector B = bspline.Bspline(k, p) Phi = np.array([B(i) for i in X]) Phis = np.array([B(i) for i in Xs]) hyp0 = np.zeros(2) #hyp0 = np.zeros(4) # use ARD B = BLR(hyp0, Phi, y) hyp = B.estimate(hyp0, Phi, y, optimizer='powell') yhat, s2 = B.predict(hyp, Phi, y, Phis) plt.fill_between(Xs, yhat - 1.96 * np.sqrt(s2), yhat + 1.96 * np.sqrt(s2), alpha=0.2) plt.scatter(X, y)
start_n = 1000 # sample size at first analysis typ_list = [2, 3] # phi function type list nk_list = [(200, 5), (20, 50)] # delta_list = [0.0, 0.10, 0.15, 0.20, 0.25, 0.30] # effect size typ three alpha = 0.05 e = 0.5 # error variance ms = [1, 2, 3] # alpha spending functions lm = len(ms) lb, ub = -2, 2 order = 3 # order of spline (as-is; 3 = cubic) nknots = 4 # number of knots to generate knots = np.linspace(lb, ub, nknots) # create a knot vector without endpoint repeats knots = splinelab.augknt( knots, order) # add endpoint repeats as appropriate for spline order bases = bspline.Bspline(knots, order) # create spline basis of order p on knots k nfeatures = 3 p = nfeatures * (order + nknots - 1) + 1 rho = 0.5 cov_mat = (1 - rho) * np.eye(nfeatures) + rho * np.ones((nfeatures, nfeatures)) L = np.linalg.cholesky(cov_mat).T for (typ, (n, k), delta) in product(typ_list, nk_list, delta_list): name = 'result/HTE/' + 'typ' + str(typ) + 'n' + str(n) + 'k' + str( k) + 'delta' + str(delta) + '_nonlinear_adaptive_HTE.npz' # if os.path.exists(name):
def main(): """Demonstration: plot a B-spline basis and its first three derivatives.""" ######################################################################################### # config ######################################################################################### # Order of spline basis. # p = 3 # Knot vector, including the endpoints. # # For convenience, endpoints are specified only once, regardless of the value of p. # # Duplicate knots *in the interior* are allowed, with the standard meaning for B-splines. # knots = [0., 0.25, 0.5, 0.75, 1.] # How many plotting points to use on each subinterval [knots[i], knots[i+1]). # # Only intervals with length > 0 are actually plotted. # nt_per_interval = 101 ######################################################################################### # the demo itself ######################################################################################### # The evaluation algorithm used in bspline.py uses half-open intervals t_i <= x < t_{i+1}. # # This causes the right endpoint of each interval to actually be the start point of the next interval. # # Especially, the right endpoint of the last interval is the start point of the next (nonexistent) interval, # so the basis will return a value of zero there. # # We work around this by using a small epsilon to avoid evaluation exactly at t_{i+1} (for each interval). # epsrel = 1e-10 epsabs = epsrel * (knots[-1] - knots[0]) original_knots = knots knots = splinelab.augknt( knots, p) # add repeated endpoint knots for splines of order p # treat each interval separately to preserve discontinuities # # (useful especially when plotting the highest-order nonzero derivative) # B = bspline.Bspline(knots, p) xxs = [] for I in zip(knots[:-1], knots[1:]): t_i = I[0] t_ip1 = I[1] - epsabs if t_ip1 - t_i > 0.: # accept only intervals of length > 0 (to skip higher-multiplicity knots in the interior) xxs.append(np.linspace(t_i, t_ip1, nt_per_interval)) # common settings for all plotted lines settings = {"linestyle": 'solid', "linewidth": 1.0} # create a list of unique colors for plotting # # http://stackoverflow.com/questions/8389636/creating-over-20-unique-legend-colors-using-matplotlib # NUM_COLORS = nbasis = len( B(0.)) # perform dummy evaluation to get number of basis functions cm = plt.get_cmap('gist_rainbow') cNorm = matplotlib.colors.Normalize(vmin=0, vmax=NUM_COLORS - 1) scalarMap = matplotlib.cm.ScalarMappable(norm=cNorm, cmap=cm) colors = [scalarMap.to_rgba(i) for i in range(NUM_COLORS)] labels = [ r"$B$", r"$\mathrm{d}B\,/\,\mathrm{d}x$", r"$\mathrm{d}^2B\,/\,\mathrm{d}x^2$", r"$\mathrm{d}^3B\,/\,\mathrm{d}x^3$" ] # for plotting the knot positions: unique_knots_xx = np.unique(original_knots) unique_knots_yy = np.zeros_like(unique_knots_xx) # plot the basis functions B(x) and their first three derivatives plt.figure(1) plt.clf() for k in range(4): ax = plt.subplot(2, 2, k + 1) # place the axis label where it fits if k % 2 == 0: ax.yaxis.set_label_position("left") else: ax.yaxis.set_label_position("right") # plot the kth derivative; each basis function gets a unique color f = B.diff(order=k) # order=0 is a passthrough for xx in xxs: yy = np.array([ f(x) for x in xx ]) # f(scalar) -> rank-1 array, one element per basis function for i in range(nbasis): settings["color"] = colors[i] plt.plot(xx, yy[:, i], **settings) plt.ylabel(labels[k]) # show knot positions plt.plot(unique_knots_xx, unique_knots_yy, "kx") plt.suptitle(r"$B$-spline basis functions, $p=%d$" % (p))