Last active
December 26, 2015 06:49
-
-
Save ev-br/7110020 to your computer and use it in GitHub Desktop.
Subclassing PPoly / BPoly to have custom out-of-bounds behavior. Eg: periodic boundary conditions, custom asymptotics.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import division, print_function, absolute_import | |
import numpy as np | |
from scipy.interpolate import BPoly, PPoly | |
class MixinAsympt(object): | |
def _evaluate(self, x, nu, extrapolate, out): | |
super(MixinAsympt, self)._evaluate(x, nu, False, out) | |
below, above = x < self.x[0], x > self.x[-1] | |
np.place(out, below, self.f_below(x[below])) | |
np.place(out, above, self.f_above(x[above])) | |
return out | |
def f_above(self, x): | |
return f_lim(x) | |
def f_below(self, x): | |
return f_lim(x) | |
class BPolyAsympt(MixinAsympt, BPoly): | |
pass | |
class PPolyAsympt(MixinAsympt, PPoly): | |
pass | |
def f(x): | |
return np.log(1. + np.exp(x**4)) | |
def f_lim(x): | |
return x**4 | |
if __name__ == "__main__": | |
xi = np.linspace(-5, 5, 30) | |
yi = [[f(x)] for x in xi] | |
bp = BPolyAsympt.from_derivatives(xi, yi) | |
pp = PPolyAsympt.from_bernstein_basis(bp) | |
import matplotlib.pyplot as plt | |
fig, ax = plt.subplots() | |
xx = np.linspace(-3, 7, 50) | |
ax.plot(xi, yi, 'ro', mec='r', ms=12, label='tabulated') | |
ax.plot(xx, bp(xx), 'm-', lw=6, alpha=0.4, label='bernstein') | |
ax.plot(xx, pp(xx), 'b-', lw=2, label='power, conv') | |
ax.legend(loc='lower left') | |
ax.set_yscale('log') | |
plt.savefig('asympt.png') | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import division, print_function, absolute_import | |
import numpy as np | |
from scipy.interpolate import BPoly, PPoly | |
""" | |
Piecewise polynomials w/ periodic boundary conditions. | |
""" | |
class MixinPBC(object): | |
def _evaluate(self, x, nu, extrapolate, out): | |
x = np.mod(x - self.x[0], self.x[-1] - self.x[0]) + self.x[0] | |
return super(MixinPBC, self)._evaluate(x, nu, False, out) | |
class BPolyPBC(MixinPBC, BPoly): | |
pass | |
class PPolyPBC(MixinPBC, PPoly): | |
pass | |
def plot_cos(): | |
xi = np.linspace(0, np.pi, 20) | |
yi = np.asarray([[np.cos(x), -np.sin(x)] for x in xi]) | |
bp = BPolyPBC.from_derivatives(xi, yi) | |
pp = PPolyPBC.from_bernstein_basis(bp) | |
import matplotlib.pyplot as plt | |
fig, (ax, ax1) = plt.subplots(2,1) | |
xx = np.linspace(-5, 5, 100) | |
ax.plot(xi, yi[:, 0], 'ro', mec='r', ms=12, label='tabulated') | |
ax.plot(xx, bp(xx), 'm-', lw=6, alpha=0.4, label='bernstein') | |
ax.plot(xx, pp(xx), 'b-', lw=2, label='converted') | |
ax.legend(loc='lower left') | |
# derivative | |
bpd = bp.derivative() | |
ppd = pp.derivative() | |
ax1.plot(xi, yi[:, 1], 'ro', mec='r', ms=12, label='f\', tabulated') | |
ax1.plot(xx, bpd(xx), 'm-', lw=6, alpha=0.4, label='f\', bernstein') | |
ax1.plot(xx, ppd(xx), 'b-', lw=2, label='f\', converted') | |
ax1.legend(loc='lower left') | |
plt.savefig('periodic.png') | |
if __name__ == "__main__": | |
plot_cos() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment