def h_constraint_der_zero(grid_points): """ Boundary condition h'(0) = 0. """ h_coef = grid_points[N_COEF_U:] h = Chebyshev(h_coef, domain=[0, radius]) return h.deriv(m=1)(0.0)
def __init__(self, n): self.x0 = (1 + np.arange(n)) / (n + 1) specs = [] super(ChebyshevQuadrature, self).__init__(n, n, specs) cp = Chebyshev(1) self.T_all = [cp.basis(i + 1, domain=[0.0, 1.0]) for i in range(n)]
def background(self, two_theta, intensities): n_deg = 5 spline = Chebyshev(coef=np.ones((5,))) red_two_theta, red_intensities = self.remove_peaks( two_theta, self.smooth_data(intensities)) # Fit the background using the reduced dataset spline = spline.fit(red_two_theta, red_intensities, n_deg) # Return the predicted background background = np.array(spline(two_theta)) return background
def PolyDiff(self, u, x): """Differentiate data with polynomial interpolation. This method takes a collection of points of size (2*self.cheb_width), fits a Chebychev polynomial to the collection of points, and computes the derivative at the central point. The derivatives are collated and returned to the calling functions as a NumPy array. Keyword arguments: u -- values of some function x -- corresponding x-coordinates where u is evaluated Note: This throws out the data close to the edges since the polynomial derivative only works well when we're looking at the middle of the points fit. """ u = u.flatten() x = x.flatten() n = len(x) # Initialize a numpy array for storing the derivative values du = np.zeros((n - 2 * self.cheb_width, self.diff_order)) # Loop for fitting Cheb polynomials to each point for j in range(self.cheb_width, n - self.cheb_width): # Select the points on which to fit polynomial points = np.arange(j - self.cheb_width, j + self.cheb_width) # Fit the polynomial poly = Cheb.fit(x[points], u[points], self.cheb_degree) # Take derivatives for d in range(1, self.diff_order + 1): du[j - self.cheb_width, d - 1] = poly.deriv(m=d)(x[j]) return du
def polynomials(self) -> List[List[float]]: """The polynomials for the piecewise approximation. Returns: The polynomials for the piecewise approximation. """ if self.num_state_qubits is None: return [[]] # note this must be the private attribute since we handle missing breakpoints at # 0 and 2 ^ num_qubits here (e.g. if the function we approximate is not defined at 0 # and the user takes that into account we just add an identity) num_intervals = len(self._breakpoints) # Calculate the polynomials polynomials = [] for i in range(0, num_intervals - 1): # Calculate the polynomial approximating the function on the current interval poly = Chebyshev.interpolate(self._f_x, self._degree, domain=[self._breakpoints[i], self._breakpoints[i + 1]]) # Convert polynomial to the standard basis and rescale it for the rotation gates poly = 2 * poly.convert(kind=np.polynomial.Polynomial).coef # Convert to list and append polynomials.append(poly.tolist()) # If the last breakpoint is < 2 ** num_qubits, add the identity polynomial if self._breakpoints[-1] < 2 ** self.num_state_qubits: polynomials = polynomials + [[2 * np.arcsin(1)]] # If the first breakpoint is > 0, add the identity polynomial if self._breakpoints[0] > 0: polynomials = [[2 * np.arcsin(1)]] + polynomials return polynomials
def u_constraint_zero(grid_points): """ Boundary condition u(0) = 0. """ u_coef = grid_points[:N_COEF_U] u = Chebyshev(u_coef, domain=[0, radius]) return u(0.0)
def interpolate_cheb_from_col(cheb_column, bands, wave): bluest = np.min(bands) #effective wavelength of bluest filter reddest = np.max(bands) #effective wavelength of reddest filter if len(cheb_column) != len(wave): warnings.warn( "wave must be an array with the same number of elements as cheb_column" ) else: funcs = { n: Chebyshev(cheb_column[n], domain=[bluest, reddest]) for n in range(len(cheb_column)) } polynom = np.zeros(len(cheb_column)) for i in range(len(cheb_column)): if cheb_column[i][0] != -99: polynom[i] = funcs[i](wave[i]) if wave[i] >= reddest or wave[i] <= bluest: warnings.warn( "The wavelength at which you're interpolating the Chebyshev polynomial for index:" + str(i) + " is outside the wavelength range of the used bands") else: polynom[i] = -99 return polynom
def h_constraint(grid_points): """ Boundary condition h(r) = 0. """ h_coef = grid_points[N_COEF_U:] h = Chebyshev(h_coef, domain=[0, radius]) return h(radius)
def _setup_approximants(self): return [ Chebyshev.interpolate(self.function, self.degree, domain=window, *self.args) for window in self._windows ]
def cheb_series(x): sum = 0 alpha = np.sqrt(2) - 1 coef = np.zeros(11 * 2 + 1) for i in range(11): coef[2 * i + 1] = 1 sum += (-1)**i / (2 * i + 1) * alpha**(2 * i + 1) * Chebyshev(coef)(x) coef[2 * i + 1] = 0 return 2 * sum
def get_mode_cheb_coeffs(self, mode_index, cheb_order): """ Cheb coeffs of a mode. The projection process is performed on [0,1]^dim. """ import scipy.special as sps cheby_nodes, _, cheby_weights = \ sps.chebyt(cheb_order).weights.T # pylint: disable=E1136,E0633 window = [0, 1] cheby_nodes = cheby_nodes * (window[1] - window[0]) / 2 + np.mean(window) cheby_weights = cheby_weights * (window[1] - window[0]) / 2 mode = self.get_template_mode(mode_index) grid = np.meshgrid(*[cheby_nodes for d in range(self.dim)], indexing='ij') mvals = mode(*grid) from numpy.polynomial.chebyshev import Chebyshev coef_scale = 2 * np.ones(cheb_order) / cheb_order coef_scale[0] /= 2 basis_1d = np.array([ Chebyshev(coef=_orthonormal(cheb_order, i), domain=window)(cheby_nodes) for i in range(cheb_order) ]) from itertools import product if self.dim == 1: basis_set = basis_1d elif self.dim == 2: basis_set = np.array([ b1.reshape([cheb_order, 1]) * b2.reshape([1, cheb_order]) for b1, b2 in product(*[basis_1d for d in range(self.dim)]) ]) elif self.dim == 3: basis_set = np.array([ b1.reshape([cheb_order, 1, 1]) * b2.reshape([1, cheb_order, 1]) * b3.reshape([1, 1, cheb_order]) for b1, b2, b3 in product(*[basis_1d for d in range(self.dim)]) ]) mode_cheb_coeffs = np.array([ np.sum(mvals * basis) for basis in basis_set ]) * _self_tp(coef_scale, self.dim).reshape(-1) # purge small coeffs whose magnitude are less than 8 times machine epsilon mode_cheb_coeffs[np.abs(mode_cheb_coeffs) < 8 * np.finfo(mode_cheb_coeffs.dtype).eps] = 0 return mode_cheb_coeffs
def polynomials(self) -> List[List[float]]: """The polynomials for the piecewise approximation. Returns: The polynomials for the piecewise approximation. Raises: TypeError: If the input function is not in the correct format. """ if self.num_state_qubits is None: return [[]] # note this must be the private attribute since we handle missing breakpoints at # 0 and 2 ^ num_qubits here (e.g. if the function we approximate is not defined at 0 # and the user takes that into account we just add an identity) breakpoints = self._breakpoints # Need to take into account the case in which no breakpoints were provided in first place if breakpoints == [0]: breakpoints = [0, 2**self.num_state_qubits] num_intervals = len(breakpoints) # Calculate the polynomials polynomials = [] for i in range(0, num_intervals - 1): # Calculate the polynomial approximating the function on the current interval try: # If the function is constant don't call Chebyshev (not necessary and gives errors) if isinstance(self.f_x, (float, int)): # Append directly to list of polynomials polynomials.append([self.f_x]) else: poly = Chebyshev.interpolate( self.f_x, self.degree, domain=[breakpoints[i], breakpoints[i + 1]] ) # Convert polynomial to the standard basis and rescale it for the rotation gates poly = 2 * poly.convert(kind=np.polynomial.Polynomial).coef # Convert to list and append polynomials.append(poly.tolist()) except ValueError as err: raise TypeError( " <lambda>() missing 1 required positional argument: '" + self.f_x.__code__.co_varnames[0] + "'." + " Constant functions should be specified as 'f_x = constant'." ) from err # If the last breakpoint is < 2 ** num_qubits, add the identity polynomial if breakpoints[-1] < 2**self.num_state_qubits: polynomials = polynomials + [[2 * np.arcsin(1)]] # If the first breakpoint is > 0, add the identity polynomial if breakpoints[0] > 0: polynomials = [[2 * np.arcsin(1)]] + polynomials return polynomials
def get_volume_from_h_coefs(h, radius): """ Returns volum of the bubble. h is Chebyshev polynomial coefficients for shape. radius is radius in A. """ r = Chebyshev([radius/2, radius/2], domain=[0, radius]) pol_to_integrate = h * r return 2.0 * np.pi * (pol_to_integrate.integ()(radius) \ - pol_to_integrate.integ()(0.0))
def chebyshev(coefs, time, domain): """Evaluate a Chebyshev Polynomial. Args: coefs (list, np.array): Coefficients defining the polynomial time (int, float): Time where to evaluate the polynomial domain (list, tuple): Domain (or time interval) for which the polynomial is defined: [left, right] Reference: Appendix A in the MSG Level 1.5 Image Data Format Description. """ return Chebyshev(coefs, domain=domain)(time) - 0.5 * coefs[0]
def refine_background(self, scattering_lengths, intensities, s=None, k=4): """Fit a univariate spline to the background data. Arguments --------- - scattering_lengths : Array of scattering vector lengths, q. - intensities : Array of intensity values at each q position - s : Smoothing factor passed to the spline. Default is the variance of the background. - k : Degree of the spline (default quartic spline). """ # Remove pre-indexed peaks for background fitting phase_list = self.phases + self.background_phases q, I = scattering_lengths, intensities for phase in phase_list: for reflection in phase.reflection_list: q, I = remove_peak_from_df(x=q, y=I, xrange=reflection.qrange) # Get an estimate for s from the non-peak data if s is None: s = np.std(I) # Smoothing for background fitting smoothI = savgol_filter(I, window_length=15, polyorder=5) # Determine a background line from the noise without peaks # self.spline = UnivariateSpline( # x=q, # y=I, # s=s / 25, # k=k, # ) self.spline = Chebyshev(coef=np.ones((20,))) self.spline = self.spline.fit(q, smoothI, 10) # background = self.spline.cast(scattering_lengths) # self.spline = splrep(q, I) # Extrapolate the background for the whole pattern # background = self.spline(scattering_lengths) background = self.spline(scattering_lengths) return background
def interpolate_cheb(cheb, bands, wave): bluest = np.min(bands) #effective wavelength of bluest filter reddest = np.max(bands) #effective wavelength of reddest filter if wave[i] >= reddest or wave[i] <= bluest: warnings.warn( "The wavelength at which you're interpolating the Chebyshev polynomial is outside the wavelength range of the used bands" ) func = Chebyshev(cheb, domain=[bluest, reddest ]) # This evaluates the Chebyshev polynomial return func(wave)
def get_free_energy_for_minimize(grid_points): """ Calculates total elastic energy for given radius and pressure. """ global free_energy_elastic_stretching, \ free_energy_elastic_bending, \ free_energy_elastic_tail, \ free_energy_external, \ current_volume u_coef = grid_points[:N_COEF_U] h_coef = grid_points[N_COEF_U:] u = Chebyshev(u_coef, domain=[0, radius]) h = Chebyshev(h_coef, domain=[0, radius]) r = Chebyshev([radius/2, radius/2], domain=[0, radius]) dh_dr = h.deriv(m=1) d2h_dr2 = h.deriv(m=2) du_dr = u.deriv(m=1) current_volume = get_volume_from_h_coefs(h, radius) psi_str_to_integrate = \ (du_dr ** 2 + du_dr * dh_dr ** 2 \ + 0.25 * dh_dr ** 4 \ + (u // r) ** 2) * r free_energy_elastic_stretching = np.pi * YOUNGS_MODULUS \ * (psi_str_to_integrate.integ()(radius) \ - psi_str_to_integrate.integ()(0.0)) free_energy_elastic_tail = np.pi * YOUNGS_MODULUS * u(radius) ** 2 psi_bend_to_integrate = \ (d2h_dr2 ** 2 + (dh_dr // r) ** 2) * r free_energy_elastic_bending = RIGIDITY * np.pi \ * (psi_bend_to_integrate.integ()(radius) \ - psi_bend_to_integrate.integ()(0.0)) # free_energy_elastic_bending = 0.0 free_energy_external = -current_volume * pressure return free_energy_elastic_stretching \ + free_energy_elastic_bending \ + free_energy_elastic_tail \ + free_energy_external
def _normalize(spectra): stars = spectra.index wavelengths = spectra.flux.columns.values.copy() flux = spectra.flux.values.copy() error = spectra.error.reindex(columns=wavelengths).values.copy() #TODO: Should negative fluxes be zero'd too? bad_flux = sp.isnan(flux) | sp.isinf(flux) bad_error = sp.isnan(error) | sp.isinf(error) | (error < 0) bad = bad_flux | bad_error flux[bad] = 1 error[bad] = ERROR_LIM #TODO: Where does pixlist come from? pixlist = sp.loadtxt('pixlist.txt', dtype=int) var = sp.full_like(error, ERROR_LIM**2) var[:, pixlist] = 0 inv_var = 1 / (var**2 + error**2) norm_flux = sp.full_like(flux, 1) norm_error = sp.full_like(error, ERROR_LIM) for star in range(len(stars)): for _, (left, right) in CHIPS.items(): mask = (left < wavelengths) & (wavelengths < right) #TODO: Why are we using Chebyshev polynomials rather than smoothing splines? #TODO: Why are we using three polynomials rather than one? Are spectra discontinuous between chips? #TODO: Is the denominator being zero/negative ever an issue? fit = Chebyshev.fit(x=wavelengths[mask], y=flux[star][mask], w=inv_var[star][mask], deg=2) norm_flux[star][mask] = flux[star][mask] / fit(wavelengths[mask]) norm_error[star][mask] = error[star][mask] / fit(wavelengths[mask]) #TODO: Why is the unreliability threshold different from the limit value? unreliable = (norm_error > .3) norm_flux[unreliable] = 1 norm_error[unreliable] = ERROR_LIM # In the original, the masking is done in the parallax fitting code. # Gonna do it earlier here to save a bit of memory. mask = sp.any( sp.vstack([(l < wavelengths) & (wavelengths < u) for l, u in CHIPS.values()]), 0) norm_flux = pd.DataFrame(norm_flux[:, mask], stars, wavelengths[mask]) norm_error = pd.DataFrame(norm_error[:, mask], stars, wavelengths[mask]) return pd.concat({'flux': norm_flux, 'error': norm_error}, 1)
def fit_func(f): fn = 'fits/%s/fit%s.fits' % (f, f) if os.path.exists(fn): r = {} d = pyfits.getdata('fits/%s/fit%s.fits' % (f, f), 'fit_info')[0] ref = d.field('refwlband') low = d.field('lowdwlband') + ref high = d.field('highdwlband') + ref d = pyfits.getdata('fits/%s/fit%s.fits' % (f, f), 'final_cheb') for n in d.names: r[n] = Chebyshev(d.field(n), (low, high)) else: r = None return r
def cheb_polys(): resolution = 513 X = np.linspace(-1, 1, resolution + 1) n = 6 coeffs = np.zeros(n) ax = plt.subplot(1, 1, 1) for i in xrange(n): coeffs[i] = 1 f = Chebyshev(coeffs) plt.plot(X, f(X), label="$T_" + str(i) + "$") coeffs[i] = 0 plt.ylim((-1.2, 1.2)) handles, labels = ax.get_legend_handles_labels() ax.legend(handles, labels, loc="upper right") plt.savefig("cheb_polys.pdf") plt.clf()
def roots(self): """Utilises Boyd's O(n^2) recursive subdivision algorithm. The chebfun is recursively subsampled until it is successfully represented to machine precision by a sequence of piecewise interpolants of degree 100 or less. A colleague matrix eigenvalue solve is then applied to each of these pieces and the results are concatenated. See: J. P. Boyd, Computing zeros on a real interval through Chebyshev expansion and polynomial rootfinding, SIAM J. Numer. Anal., 40 (2002), pp. 1666–1682. """ if self.size() == 1: return np.array([]) elif self.size() <= 100: ak = self.coefficients() v = np.zeros_like(ak[:-1]) v[1] = 0.5 C1 = toeplitz(v) C2 = np.zeros_like(C1) C1[0, 1] = 1. C2[-1, :] = ak[:-1] C = C1 - .5 / ak[-1] * C2 eigenvalues = eigvals(C) roots = [ eig.real for eig in eigenvalues if np.allclose(eig.imag, 0, atol=1e-10) and np.abs(eig.real) <= 1 ] scaled_roots = self._ui_to_ab(np.array(roots)) return scaled_roots else: try: # divide at a close-to-zero split-point split_point = self._ui_to_ab(0.0123456789) return np.concatenate( (self.restrict([self._domain[0], split_point]).roots(), self.restrict([split_point, self._domain[1]]).roots())) except: # Seems to have many fake roots for high degree fits coeffs = self.coefficients() domain = self._domain possibilities = Chebyshev(coeffs, domain).roots() return np.array( [float(i.real) for i in possibilities if i.imag == 0.0])
def runge_plot(): a, b = -1, 1 resolution = 513 runge = lambda x: 1 / (1 + 25 * x**2) X2 = np.linspace(a, b, resolution) ax = plt.subplot(1, 1, 1) plt.plot(X2, runge(X2), label="$\\frac{1}{1+25x^2}$") for order in [5, 10, 15, 25]: X = nodes(a, b, order) Y = runge(X) C = get_coefs(Y) f = Chebyshev(C) plt.plot(X2, f(X2), label="Order " + str(order)) handles, labels = ax.get_legend_handles_labels() ax.legend(handles, labels, loc="upper right") plt.savefig("runge_chebyshev.pdf") plt.clf()
def cos_interp(): a = -1 b = 1 order = 20 resolution = 501 X = nodes(a, b, resolution) F = lambda x: np.cos(x) A = F(X) cfs = get_coefs(A) print "number of coefficients for cos that are greater than 1E-14: ", ( np.absolute(cfs) > 1E-14).sum() f = Chebyshev(cfs) X2 = np.linspace(a, b, resolution) ax = plt.subplot(1, 1, 1) plt.plot(X2, F(X2), label="$\\cos x$") plt.plot(X2, f(X2), label="Chebyshev Interpolant") handles, labels = ax.get_legend_handles_labels() ax.legend(handles, labels, loc="upper right") plt.show()
def crazy_interp(): # This one takes a little time to run a = -1 b = 1 order = 100000 resolution = 100001 # Where to sample. X = nodes(a, b, order) F = lambda x: np.sin(1. / x) * np.sin(1. / np.sin(1. / x)) A = F(X) cfs = get_coefs(A) print "The last 10 coeffients are: ", cfs[-10:] f = Chebyshev(cfs) # Sample values for plot. X2 = np.linspace(a, b, resolution) ax = plt.subplot(1, 1, 1) plt.plot(X2, f(X2), label="Chebyshev Interpolant") plt.plot(X2, F(X2), label="$\\sin\\frac{1}{x} \\sin\\frac{1}{\\sin\\frac{1}{x}}$") handles, labels = ax.get_legend_handles_labels() ax.legend(handles, labels, loc="upper right") plt.show()
def solve( self, d_mus:np.ndarray, lambd=None, ): n = self.n k = self.k if lambd is None: lambd = np.zeros(self.k) H = np.zeros(shape=(k, k)) fpoly = None for i_step in range(self.n_steps): if fpoly is None: fvals = np.exp(lambd.dot(self.G)) cs = fit_cheby(fvals) fpoly = Chebyshev(cs) e_mu = np.array([ (fpoly*cb(i)).integ(lbnd=-1)(1) for i in range(2*k) ]) grad = e_mu[:k] - d_mus grad_norm = np.linalg.norm(grad) grad_norm_old = grad_norm Pval_old = e_mu[0] - lambd.dot(d_mus) if self.verbose: print("Step: {}, Grad: {}, P: {}".format( i_step, grad_norm, Pval_old )) if grad_norm < self.grad_tol: break for i in range(k): for j in range(k): H[i, j] = (e_mu[i+j] + e_mu[abs(i-j)]) / 2 step = -np.linalg.solve(H, grad) dfdx = step.dot(grad) stepScaleFactor = 1.0 newX = lambd + stepScaleFactor * step alpha = .3 beta = .25 while True: fvals = np.exp(newX.dot(self.G)) cs = fit_cheby(fvals) fpoly = np.polynomial.chebyshev.Chebyshev(cs) e_mu = np.array([ (fpoly * cb(i)).integ(lbnd=-1)(1) for i in range(2 * k) ]) grad = e_mu[:k] - d_mus grad_norm = np.linalg.norm(grad) Pval_new = fpoly.integ(lbnd=-1)(1) - newX.dot(d_mus) delta_change = Pval_old + alpha * stepScaleFactor * dfdx - Pval_new # if (delta_change > -1e-6 and grad_norm < grad_norm_old) or stepScaleFactor < 1e-5: if (delta_change > -1e-6 or stepScaleFactor < 1e-5): break else: stepScaleFactor *= beta if self.verbose: print("step: {}, delta: {}".format(stepScaleFactor, delta_change)) newX = lambd + stepScaleFactor * step lambd = newX self.lambd = lambd self.f_poly = self.get_fpoly(lambd) self.cdf_poly = self.f_poly.integ(lbnd=-1)
def __init__(self, x0): super(ChebyshevQuadrature, self).__init__(11, 11, 2.799761e-03, x0) cp = Chebyshev(1) self.T_all = [cp.basis(i, domain=[0.0, 1.0]) for i in range(11)]
def setup_numpy(): return Chebyshev.interpolate(np.sin, deg=10, domain=(0, 1))
def nextIter(self): VNext = T.interpolate(lambda W: -self.negValue(W), deg=self.order, domain=[self.WMin, self.WMax]) return VNext
def guessSln(self): self.V = T.interpolate(lambda W: self.u(W + self.y), deg=self.order, domain=[self.WMin, self.WMax])
def findPolicy(self): self.policy = T.interpolate(lambda W: W + self.y - (self.findOptW1(W) / self.R), deg=self.order, domain=[self.WMin, self.WMax])
def _derivative(c, m): cheb = Chebyshev(c) dcheb = cheb.deriv(m=m) return dcheb.coef