示例#1
0
class TripleSpline(object):
    _coeffs=[
        [2 / 3.0, 0, -4, 4],
        [4 / 3.0, -4, 4, -4 / 3.0]]


    def __init__(self):
        self.func1=Polynomial(self._coeffs[0])
        self.func2=Polynomial(self._coeffs[1])
        self.func1_diff=self.func1.deriv()
        self.func2_diff=self.func2.deriv()
        self.diff_order=0
        
    def __call__(self,x,result=None):
        if x<0:
            raise ValueError('input value should be nonnegative, not '+str(x))
        if result is None:
            result=np.zeros((self._diff_order+1,),dtype=np.double)
        if x>=1:
            result.fill(0)
            return result
        if x<=0.5:
            result[0]=self.func1(x)
            if self.diff_order>=1:
                result[1]=self.func1_diff(x)
        else:
            result[0]=self.func2(x)
            if self.diff_order>=1:
                result[1]=self.func2_diff(x)
        return result
        
    def values(self,x,result):
        return self.__call__(x, result)
    
    def set_diff_order(self, diff_order):
        if diff_order < 0 or diff_order > 1:
            raise ValueError("only support _diff_order 0/1, not " + str(diff_order))
        self._diff_order = diff_order
    
    def get_diff_order(self):
        return self._diff_order
    
    diff_order = property(get_diff_order, set_diff_order)
示例#2
0
class TripleSpline(object):
    _coeffs = [[2 / 3.0, 0, -4, 4], [4 / 3.0, -4, 4, -4 / 3.0]]

    def __init__(self):
        self.func1 = Polynomial(self._coeffs[0])
        self.func2 = Polynomial(self._coeffs[1])
        self.func1_diff = self.func1.deriv()
        self.func2_diff = self.func2.deriv()
        self.diff_order = 0

    def __call__(self, x, result=None):
        if x < 0:
            raise ValueError('input value should be nonnegative, not ' +
                             str(x))
        if result is None:
            result = np.zeros((self._diff_order + 1, ), dtype=np.double)
        if x >= 1:
            result.fill(0)
            return result
        if x <= 0.5:
            result[0] = self.func1(x)
            if self.diff_order >= 1:
                result[1] = self.func1_diff(x)
        else:
            result[0] = self.func2(x)
            if self.diff_order >= 1:
                result[1] = self.func2_diff(x)
        return result

    def values(self, x, result):
        return self.__call__(x, result)

    def set_diff_order(self, diff_order):
        if diff_order < 0 or diff_order > 1:
            raise ValueError("only support _diff_order 0/1, not " +
                             str(diff_order))
        self._diff_order = diff_order

    def get_diff_order(self):
        return self._diff_order

    diff_order = property(get_diff_order, set_diff_order)
示例#3
0
def newton(width: int,
           height: int,
           *,
           p: Polynomial,
           a: complex,
           xr: Range = (-2.5, 1),
           yr: Range = (-1, 1),
           max_iterations: int = 100) -> (np.array, np.array):
    """ """
    # To make navigation easier we calculate these values
    x_from, x_to = xr
    y_from, y_to = yr

    # Here the actual algorithm starts
    x = np.linspace(x_from, x_to, width).reshape((1, width))
    y = np.linspace(y_from, y_to, height).reshape((height, 1))
    z = x + 1j * y

    # Compute the derivative
    dp = p.deriv()

    # Compute roots
    roots = p.roots()
    epsilon = 1e-5

    # Set the initial conditions
    a = np.full(z.shape, a)

    # To keep track in which iteration the point diverged
    div_time = np.zeros(z.shape, dtype=int)

    # To keep track on which points did not converge so far
    m = np.full(a.shape, True, dtype=bool)

    # To keep track which root each point converged to
    r = np.full(a.shape, 0, dtype=int)

    for i in range(max_iterations):
        z[m] = z[m] - a[m] * p(z[m]) / dp(z[m])

        for j, root in enumerate(roots):
            converged = (np.abs(z.real - root.real) <
                         epsilon) & (np.abs(z.imag - root.imag) < epsilon)
            m[converged] = False
            r[converged] = j + 1

        div_time[m] = i

    return div_time, r
示例#4
0
class NormPoly(object):
    def __init__(self, coef, omega):
        self.h = Poly(coef)
        self.omega = omega

    def __call__(self, x):
        return self.h(self.omega * x) / self.omega

    def deriv(self):
        return NormPoly(self.omega * self.h.deriv().coef, self.omega)

    def degree(self):
        return self.h.degree()

    def split(self):
        return False

    @property
    def coef(self):
        return self.h.coef
示例#5
0
文件: predictor.py 项目: mhvk/pulsar
    def polynomial(self,
                   index,
                   rphase=None,
                   deriv=0,
                   t0=None,
                   time_unit=u.min,
                   out_unit=None,
                   convert=False):
        """Prediction polynomial set up for times in MJD

        Parameters
        ----------
        index : int or float
            index into the polyco table (or MJD for finding closest)
        rphase : None or 'fraction' or float
            phase zero point; if None, use the one stored in polyco.
            (Those are typically large, so one looses some precision.)
            Can also set 'fraction' to use the stored one modulo 1, which is
            fine for folding, but breaks cycle count continuity between sets.
        deriv : int
            derivative of phase to take (1=frequency, 2=fdot, etc.); default 0

        Returns
        -------
        polynomial : Polynomial
            set up for MJDs between mjd_mid ± span

        Notes
        -----
        Units for the polynomial are cycles/second**deriv.  Taking a derivative
        outside will be per day (e.g., self.polynomial(1).deriv() gives
        frequencies in cycles/day)
        """

        out_unit = out_unit or time_unit

        try:
            index = index.__index__()
        except (AttributeError, TypeError):
            index = self.searchclosest(index)
        window = np.array([-1, 1]) * self['span'][index] / 2 * u.min

        polynomial = Polynomial(self['coeff'][index], window.value,
                                window.value)
        polynomial.coef[1] += self['f0'][index] * 60.

        if deriv == 0:
            if rphase is None:
                polynomial.coef[0] += self['rphase'][index]
            elif rphase == 'fraction':
                polynomial.coef[0] += self['rphase'][index] % 1
            else:
                polynomial.coef[0] = rphase
        else:
            polynomial = polynomial.deriv(deriv)
            polynomial.coef /= u.min.to(out_unit)**deriv

        if t0 is None:
            dt = 0. * time_unit
        elif not hasattr(t0, 'jd1') and t0 == 0:
            dt = (-self['mjd_mid'][index] * u.day).to(time_unit)
        else:
            dt = ((t0 - Time(self['mjd_mid'][index], format='mjd',
                             scale='utc')).jd * u.day).to(time_unit)

        polynomial.domain = (window.to(time_unit) - dt).value

        if convert:
            return polynomial.convert()
        else:
            return polynomial
示例#6
0
a = 0
b = 2


P_n = Polynomial([0, 1, 0, 1])  # 0 + 1*x + 0*x^2 + 1*x^3
n = P_n.degree()

# Zero approximation
P_n_min = scipy.optimize.fminbound(P_n, a, b, full_output=True)[1]
P_n_max = -scipy.optimize.fminbound(-P_n, a, b, full_output=True)[1]
Q0 = (P_n_max + P_n_min) / 2

# First approximation
alpha1 = (P_n(b) - P_n(a)) / (b - a)
r = (P_n.deriv() - Polynomial([alpha1])).roots()
d = next(t for t in r if a < t < b)
alpha0 = (P_n(a) + P_n(d) - alpha1 * (a + d)) / 2
Q1 = alpha0 + alpha1 * x
Q1 = sympy.lambdify(x, Q1)

# Second approximation
Q2 = P_n(x) - P_n.coef[n] * T(n)((2 * x - (a + b)) / (b - a)) * ((b - a) ** n) / (2 ** (2 * n - 1))
Q2 = sympy.lambdify(x, Q2)

X = np.linspace(0, 2, 1000)

plt.plot(X, X + X ** 3, color='tab:blue', label='x + x³')
plt.axhline(Q0, color='tab:orange', label='Zero approximation')
plt.plot(X, Q1(X), color='tab:green', label='First approximation')
plt.plot(X, Q2(X), color='tab:red', label='Second approximation')
示例#7
0
    def polynomial(self,
                   index,
                   rphase=None,
                   deriv=0,
                   t0=None,
                   time_unit=u.min,
                   out_unit=None,
                   convert=False):
        """Prediction polynomial set up for times in MJD

        Parameters
        ----------
        index : int or float
            index into the polyco table (or MJD for finding closest)
        rphase : None or 'fraction' or 'ignore' or float
            Phase zero point; if None, use the one stored in polyco.
            (Those are typically large, so one looses some precision.)
            Can also set 'fraction' to use the stored one modulo 1, which is
            fine for folding, but breaks cycle count continuity between sets,
            'ignore' for just keeping the value stored in the coefficients,
            or a value that should replace the zero point.
        deriv : int
            derivative of phase to take (1=frequency, 2=fdot, etc.); default 0

        Returns
        -------
        polynomial : Polynomial
            set up for MJDs between mjd_mid +/- span

        Notes
        -----
        Units for the polynomial are cycles/second**deriv.  Taking a derivative
        outside will be per day (e.g., self.polynomial(1).deriv() gives
        frequencies in cycles/day)
        """

        out_unit = out_unit or time_unit

        try:
            index = index.__index__()
        except (AttributeError, TypeError):
            index = self.searchclosest(index)
        window = np.array([-1, 1]) * self['span'][index] / 2

        polynomial = Polynomial(self['coeff'][index], window.value,
                                window.value)
        polynomial.coef[1] += self['f0'][index].to_value(u.cycle / u.minute)

        if deriv == 0:
            if rphase is None:
                polynomial.coef[0] += self['rphase'][index].value
            elif rphase == 'fraction':
                polynomial.coef[0] += self['rphase']['frac'][index].value % 1
            elif rphase != 'ignore':
                polynomial.coef[0] = rphase
        else:
            polynomial = polynomial.deriv(deriv)
            polynomial.coef /= u.min.to(out_unit)**deriv

        if t0 is not None:
            dt = Time(t0, format='mjd') - self['mjd_mid'][index]
            polynomial.domain = (window - dt).to(time_unit).value

        if convert:
            return polynomial.convert()
        else:
            return polynomial
示例#8
0
    def polynomial(self, index, rphase=None, deriv=0, t0=None, time_unit=u.min, out_unit=None, convert=False):
        """Prediction polynomial set up for times in MJD

        Parameters
        ----------
        index : int or float
            index into the polyco table (or MJD for finding closest)
        rphase : None or 'fraction' or float
            phase zero point; if None, use the one stored in polyco.
            (Those are typically large, so one looses some precision.)
            Can also set 'fraction' to use the stored one modulo 1, which is
            fine for folding, but breaks phase continuity between sets.
        deriv : int
            derivative of phase to take (1=frequency, 2=fdot, etc.); default 0

        Returns
        -------
        polynomial : Polynomial
            set up for MJDs between mjd_mid ± span

        Notes
        -----
        Units for the polynomial are cycles/second**deriv.  Taking a derivative
        outside will be per day (e.g., self.polynomial(1).deriv() gives
        frequencies in cycles/day)
        """

        out_unit = out_unit or time_unit

        try:
            window = np.array([-1, 1]) * self["span"][index] / 2 * u.min
        except (IndexError, TypeError):
            # assume index is really a Time or MJD
            index = self.searchclosest(index)
            window = np.array([-1, 1]) * self["span"][index] / 2 * u.min

        polynomial = Polynomial(self["coeff"][index], window.value, window.value)
        polynomial.coef[1] += self["f0"][index] * 60.0

        if deriv == 0:
            if rphase is None:
                polynomial.coef[0] += self["rphase"][index]
            elif rphase == "fraction":
                polynomial.coef[0] += self["rphase"][index] % 1
            else:
                polynomial.coef[0] = rphase
        else:
            polynomial = polynomial.deriv(deriv)
            polynomial.coef /= u.min.to(out_unit) ** deriv

        if t0 is None:
            dt = 0.0 * time_unit
        elif not hasattr(t0, "jd1") and t0 == 0:
            dt = (-self["mjd_mid"][index] * u.day).to(time_unit)
        else:
            dt = ((t0 - Time(self["mjd_mid"][index], format="mjd", scale="utc")).jd * u.day).to(time_unit)

        polynomial.domain = (window.to(time_unit) - dt).value

        if convert:
            return polynomial.convert()
        else:
            return polynomial
示例#9
0
        b_error = np.append(b_error, [((h_i * Y_correct) / 2.0)])
        c_error = np.append(c_error, [((h_i * h_i * d_correct(x)) / 6)])

    return f_error, b_error, c_error


##################################

fig, ax = plt.subplots()
ax.axhline(y=0, color='k')

p = Polynomial([2.0, 1.0, -6.0, -2.0, 2.5, 1.0])
data = p.linspace(domain=[-2.4, 1.5])
ax.plot(data[0], data[1], label='Function')

p_prime = p.deriv(1)
data2 = p_prime.linspace(domain=[-2.4, 1.5])
ax.plot(data2[0], data2[1], label='Derivative')

ax.legend()

##################################

h = 1
fig, bx = plt.subplots()
bx.axhline(y=0, color='k')

x = np.linspace(-2.0, 1.3, 50, endpoint=True)
y = forward_diff(p, h, x)
bx.plot(x, y, label='Forward; h=1')
y = backward_diff(p, h, x)
def Phi(P):
    return 3 * X * P.deriv() - (1 - X**2) * P.deriv(2)
def Phi(P):
    return 3 * X * P.deriv() - (1 - X**2) * P.deriv(2)
示例#12
0
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from numpy.polynomial import Polynomial

# Define a polynomial named 'f'
f = Polynomial([2.0, 1.0, -6.0, -2.0, 2.5, 1.0])

# Define the first derivative of polynomial 'f' named 'f_prime'
f_prime = f.deriv(1)

# Draw the X-axis
plt.axhline(y=0, color='k')

# Generate 100 values of x.
x = np.linspace(-2.5, 1.6, 100)

# Calculate y-values of corresponding x-values of f(x).
y = f(x)

# Plot the graph of f(x) using x-values and y-values
plt.plot(x, y)

# Plot the roots of the graph
plt.plot(f.roots(), f(f.roots()), 'ro')

# Print the roots of the function f(x)
print(f.roots())

# Calcuate y-values for corresponding x-values of f'(x).
y = f_prime(x)
示例#13
0
      est_definie_positive(calc(J, res[0])))
print()

U00 = np.matrix([-0.5, 0.3, 0.2, -0.1]).T
F = generate_F(4)
J = generate_jacobienne(4)
res2 = Newton_Raphson(F, J, U00, dx, IMAX, EPS)

print("   Tests pour N = ", 4)
print()
print("\t Position initiale = ", U00.T)
print()
print("\t Nombre d'itérations = ", res2[1])
print()
print("\t Position d'équilibre = ", res2[0].T)
print()
print("\t Correspond au minimum d'énergie :",
      est_definie_positive(calc(J, res2[0])))
print()

p = Polynomial([0., 15 / 8, 0., -70 / 8, 0., 63 / 8])

print("\t Les racines de la dérivée du 5ème polynôme de Legendre = ",
      p.deriv().roots())
print()
print("\t Gradient de E évalué en la position d'équilibre = ",
      calc(generate_F(4), res2[0]).T)
print("Correspond au minimum d'énergie :",
      est_definie_positive(calc(J, res2[0])))
print()
示例#14
0
class ToySGDEnv(AbstractEnv):
    """
    Optimize toy functions with SGD + Momentum.


    """
    def __init__(self, config):
        super(ToySGDEnv, self).__init__(config)
        self.n_steps_max = config.get("cutoff", 1000)

        self.velocity = 0
        self.gradient = 0
        self.history = []
        self.n_dim = None  # type: Optional[int]
        self.objective_function = None
        self.objective_function_deriv = None
        self.x_min = None
        self.f_min = None
        self.x_cur = None
        self.f_cur = None
        self.momentum = 0  # type: Optional[float]
        self.learning_rate = None  # type: Optional[float]
        self.n_steps = 0  # type: Optional[int]

    def build_objective_function(self):
        if self.instance["family"] == "polynomial":
            order = int(self.instance["order"])
            if order != 2:
                raise NotImplementedError(
                    "Only order 2 is currently implemented for polynomial functions."
                )
            self.n_dim = order
            coeffs_str = self.instance["coefficients"]
            coeffs_str = coeffs_str.strip("[]")
            coeffs = [float(item) for item in coeffs_str.split()]
            self.objective_function = Polynomial(coef=coeffs)
            self.objective_function_deriv = self.objective_function.deriv(
                m=1
            )  # lambda x0: derivative(self.objective_function, x0, dx=1.0, n=1, args=(), order=3)
            self.x_min = -coeffs[1] / (
                2 * coeffs[0] + 1e-10
            )  # add small epsilon to avoid numerical instabilities
            self.f_min = self.objective_function(self.x_min)

            self.x_cur = self.get_initial_position()
        else:
            raise NotImplementedError(
                "No other function families than polynomial are currently supported."
            )

    def get_initial_position(self):
        return 0  # np.random.uniform(-5, 5, size=self.n_dim-1)

    def step(self, action: Union[float, Tuple[float, float]]):
        done = False
        info = {}

        # parse action
        if np.isscalar(action):
            log_momentum = 1
            log_learning_rate = action
        elif len(action) == 2:
            log_learning_rate, log_momentum = action
        else:
            raise ValueError
        self.momentum = 10**log_momentum
        self.learning_rate = 10**log_learning_rate

        # SGD + Momentum update
        self.velocity = self.momentum * self.velocity + self.learning_rate * self.gradient
        self.x_cur -= self.velocity
        self.gradient = self.objective_function_deriv(self.x_cur)

        # State
        remaining_budget = self.n_steps_max - self.n_steps
        state = {
            "remaining_budget": remaining_budget,
            "gradient": self.gradient,
            "learning_rate": self.learning_rate,
            "momentum": self.momentum
        }

        # Reward
        # current function value
        self.f_cur = self.objective_function(self.x_cur)
        # log regret
        log_regret = np.log(np.abs(self.f_min - self.f_cur))
        reward = -log_regret

        self.history.append(self.x_cur)

        # Stop criterion
        self.n_steps += 1
        if self.n_steps > self.n_steps_max:
            done = True

        return state, reward, done, info

    def reset(self):
        """
        Reset environment

        Returns
        -------
        np.array
            Environment state
        """
        super(ToySGDEnv, self).reset_()

        self.velocity = 0
        self.gradient = 0
        self.history = []
        self.objective_function = None
        self.objective_function_deriv = None
        self.x_min = None
        self.f_min = None
        self.x_cur = None
        self.f_cur = None
        self.momentum = 0
        self.learning_rate = 0
        self.n_steps = 0
        self.build_objective_function()
        return {
            "remaining_budget": self.n_steps_max,
            "gradient": self.gradient,
            "learning_rate": self.learning_rate,
            "momentum": self.momentum
        }

    def render(self, **kwargs):
        import matplotlib.pyplot as plt
        history = np.array(self.history).flatten()
        X = np.linspace(1.05 * np.amin(history), 1.05 * np.amax(history), 100)
        Y = self.objective_function(X)
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.plot(X, Y)
        ax.plot(history,
                self.objective_function(history),
                marker="x",
                color="black")
        ax.plot(self.x_cur,
                self.objective_function(self.x_cur),
                marker="x",
                color="red")
        plt.show()

    def close(self):
        pass