コード例 #1
0
    def invert(self, phis, prc, phi_offset=0):
        """ Find the resulting probability density function after
        applying a perturbation, resulting in phase response curve prc,
        at time 0. Returns a phase_distribution class of the perturbed
        system. """

        prc_interp = PeriodicSpline(phis, prc)
        ptc_interp = ptc_from_prc(prc_interp)

        res = self.invert_res
        iphis = np.linspace(0, 2*np.pi, num=res, endpoint=True)
        spacing = iphis[1]
        x = np.linspace(-2*np.pi, 4*np.pi, num=3*res, endpoint=True) 

        # Is the phase transition curve monotonic?
        # if so, use abbreviated formula
        if ptc_interp(phis, 1).min() > 1E-2:
            invertedptc = UnivariateSpline(ptc_interp(x), x, s=0)
            f_perturbed = (invertedptc(iphis, 1) *
                           self.phase_offset(invertedptc(iphis),
                                             phi_offset))

        # Not monotonic, must calculate roots at each point
        else: 
            f_perturbed = np.zeros(res)
            root_interp = RootFindingSpline(x, ptc_interp(x))
     
            # import matplotlib.pylab as plt
            # fig = plt.figure()
            # ax = fig.add_subplot(111)
            # ax.plot(x, root_interp(x))

            for i,phi in enumerate(iphis):
                start = phi - spacing/2
                stop  = phi + spacing/2
                roots_above = root_interp.root_offset(stop)
                roots_below = root_interp.root_offset(start)
                roots = np.hstack([roots_below, roots_above])
                roots.sort()
                roots = roots.reshape((-1, 2))
                for pair in roots:
                    # ax.fill_between([pair[0], pair[1]], start, stop,
                    # alpha=0.3)
                    # dx = pair[1] - pair[0]
                    dy = spacing
                    int_fx = self.integrate(pair[0], pair[1],
                                            phi_offset)
                    f_perturbed[i] += int_fx/dy


        scale = p_integrate(iphis, f_perturbed)
        assert scale > 0.975, \
        "pdf inversion error (Error = %0.3f)"%scale
        f_perturbed *= 1./scale 

        f_p_interp = PeriodicSpline(iphis, f_perturbed)

        return phase_distribution(f_p_interp, self.phase_diffusivity,
                                  invert_res=self.invert_res)
コード例 #2
0
    def calc_pulse_responses(self, pulse_creator, trans_duration=3, res=100):
        """ Integrate pulses starting at different initial phases to
        find x(phi, t), create interpolation object, and find amplitude
        and phase response curves for the given pulse """

        self._create_arc_integrator(trans_duration)
        if not hasattr(self, 'avg'): self.average()
        if not hasattr(self, 'lc'): self.limitCycle()

        pulse = pulse_creator(0.)

        phis = np.linspace(0, 2 * np.pi, num=res)
        trajectories = []
        references = []
        arc = []
        prc = []

        if pulse['type'] is 'param':
            pulse_traj = []

        for phi in phis:
            out = self._simulate_pulse_and_ref(pulse_creator(phi),
                                               trans_duration)
            trajectories += [out['traj']]
            references += [out['ref']]
            prc += [out['p_diff']]
            arc += [
                self._calc_amp_change(self.arc_traj_ts, out['traj'],
                                      out['ref'])
            ]

            if pulse['type'] is 'param':
                pulse_traj += [out['pulse_traj']]

        trajectories = np.array(trajectories)
        references = np.array(references)

        self.traj_interp = cyl_interp(phis, self.arc_traj_ts, trajectories)
        self.ref_interp = cyl_interp(phis, self.arc_traj_ts, references)

        if pulse['type'] is 'param':
            pulse_traj = np.array(pulse_traj)
            comb_ts = np.hstack([pulse['ts'][:-1], self.arc_traj_ts])
            comb_traj = np.concatenate([pulse_traj[:, :-1, :], trajectories],
                                       axis=1)
            self.comb_interp = cyl_interp(phis, comb_ts, comb_traj)

        self.pulse_creator = pulse_creator
        self.prc_single_cell = np.array(prc)  # Single Cell PRC
        self.arc_single_cell = np.array(arc)  # Single Cell ARC
        self.phis = phis

        self.prc_interp = PeriodicSpline(self.phis,
                                         self.prc_single_cell,
                                         period=2 * np.pi)

        self.ptc_interp = lambda x: x + self.prc_interp(x)
コード例 #3
0
    def __init__(self, phis, prc):

        self.prc_interp = PeriodicSpline(phis, prc, k=4)
        self.ptc_interp = ptc_from_prc(self.prc_interp)

        res = len(phis)

        self.prc_deriv = self.prc_interp.derivative()
        self.div_points = self.prc_deriv.root_offset(-1)

        # Rescale phis and points such that phi=0 is the first
        # division
        offset = self.div_points[0]
        # phi_scaled = (phis - offset)%2*np.pi




        # self.phi_to_theta = lambda phi: (phi - offset)%(2*np.pi)
        # self.theta_to_phi = lambda theta: (theta + offset)%(2*np.pi)
        self.div_scaled = self.div_points - offset

        # Add 2pi to the end of region for final segment
        self.div_scaled = np.hstack([self.div_scaled, 2*np.pi])

        self.fwd_sections = fnlist([])
        self.inv_sections = fnlist([])
        for i, point in enumerate(self.div_scaled[1:]):
            start = self.div_scaled[i]
            stop = point
            section_length = stop - start
            section_res = int(res*section_length/(2*np.pi) + 20)
            x = np.linspace(start, stop, num=section_res,
                            endpoint=True)
            y = x + self.prc_interp(x + offset)
            fwd_spline = BoundedUniveriateSpline(x, y, bbox=[x.min(),
                                                             x.max()])
            inv_spline = BoundedUniveriateSpline(y, x, bbox=[y.min(),
                                                             y.max()])
            

            self.fwd_sections += [fwd_spline]
            self.inv_sections += [inv_spline]
コード例 #4
0
    def __init__(self, mu, sigma, phase_diffusivity,
                 invert_res=60):
        """ mu and sigma should be the mean and standard deviation of
        the trajectory. """

        assert np.isfinite(mu), "Mu must be a number"
        assert np.isfinite(sigma), "Sigma must be a number"
        assert np.isfinite(phase_diffusivity), "D must be a number"
        
        # General phase distribution variables
        self.phase_diffusivity = phase_diffusivity
        self.period = 2*np.pi
        self.invert_res = invert_res

        # Gaussian specific variables
        self.mu = mu%(2*np.pi)
        self.sigma = sigma
        self.length = np.exp((self.sigma**2)/(-2))


        self.fo_phi = lambda phis: wrapped_gaussian(phis%(2*np.pi), mu,
                                                    sigma)
        phis = np.linspace(0, 2*np.pi, 100)
        self.fo_phi_interp = PeriodicSpline(phis, self.fo_phi(phis))
コード例 #5
0
class gaussian_phase_distribution(phase_distribution):
    """ Class to handle the specific case where the phase distribution
    is a wrapped gaussian function, with methods that take into account
    the more tractable nature of gaussian distributions. """

    def __init__(self, mu, sigma, phase_diffusivity,
                 invert_res=60):
        """ mu and sigma should be the mean and standard deviation of
        the trajectory. """

        assert np.isfinite(mu), "Mu must be a number"
        assert np.isfinite(sigma), "Sigma must be a number"
        assert np.isfinite(phase_diffusivity), "D must be a number"
        
        # General phase distribution variables
        self.phase_diffusivity = phase_diffusivity
        self.period = 2*np.pi
        self.invert_res = invert_res

        # Gaussian specific variables
        self.mu = mu%(2*np.pi)
        self.sigma = sigma
        self.length = np.exp((self.sigma**2)/(-2))


        self.fo_phi = lambda phis: wrapped_gaussian(phis%(2*np.pi), mu,
                                                    sigma)
        phis = np.linspace(0, 2*np.pi, 100)
        self.fo_phi_interp = PeriodicSpline(phis, self.fo_phi(phis))

    def __call__(self, ts, phi_res=100, advance_t=True):
        """ Convolute the original gaussian with the diffusion update to
        generate the pdf at time t. Advance_t=False hold the mean in
        place for x_hat """

        # Set up time variables
        ts = np.atleast_1d(ts)
        phis = np.linspace(0, 2*np.pi, num=phi_res, endpoint=True)

        # Return distribution matrix, evaluated at phis and ts
        ret_phis = np.zeros((len(ts), phi_res))

        # For every time point, find distribution
        for i, t in enumerate(ts): ##Parallelize?
            sigma_d = np.sqrt(2*self.phase_diffusivity*np.abs(t))
            mu_d = (t * (2*np.pi)/self.period)%(2*np.pi)

            # From the convolution of two gaussian functions
            mu_f = self.mu + mu_d if advance_t else self.mu,

            # Allow negative times to reverse diffusion
            var = self.sigma**2 + np.sign(t)*sigma_d**2
            sigma_f = np.sqrt(var) if var > 0 else 0.

            ret_phis[i] = wrapped_gaussian(phis, mu_f, sigma_f)

        return ret_phis

    def integrate(self, a, b, phi_offset=0):
        """ implement a wrapped error function eventually? """
        return self.fo_phi_interp.integrate(a-phi_offset, b-phi_offset)
コード例 #6
0
    # axmatrix[0].plot(test.phis, test.prc_single_cell)
    # axmatrix[0].set_title('Single Cell PRC')
    # axmatrix[1].plot(test.phis, test.arc_single_cell[:,0])
    # axmatrix[1].set_title('Single Cell ARC')
    # plot_grey_zero(axmatrix[0])
    # plot_grey_zero(axmatrix[1])
    # format_2pi_axis(axmatrix[1])


    period = 2*np.pi
    mean = np.pi/4
    std = 0.5
    decay = 0.01
    phis = np.linspace(0, 2*np.pi, num=100, endpoint=True)
    po = wrapped_gaussian(phis, mean, std)
    po_interp = PeriodicSpline(phis, po)
    
    test_population = gaussian_phase_distribution(mean, std, decay,
                                                  invert_res=60)
    perturbed_popul = test_population.invert(test.phis,
                                             test.prc_single_cell)

    test.calc_population_responses(test_population, tarc=False)

    mean_p, std_p = mean_std(test.z_hat(0))
    mean_pert_pop = gaussian_phase_distribution(mean_p, std_p, decay)

    fig = plt.figure()
    ax = fig.add_subplot(111)
    iphis = np.linspace(0, 2*np.pi, 60)
コード例 #7
0
    from CommonFiles.Amplitude2 import Amplitude
    from CommonFiles.Models.tyson2statemodel import model, paramset


    amp = Amplitude(model(), paramset)
    state_pulse_creator = amp._s_pulse_creator(1, 0.5)
    amp.calc_pulse_responses(state_pulse_creator)

    res = len(amp.phis)
    phis = amp.phis
    prc = np.hstack([amp.prc_single_cell[:-1][(res/2):],
                     amp.prc_single_cell[:-1][:(res/2)]])

    prc = np.hstack([prc, prc[0]])

    prc_interp = PeriodicSpline(phis, prc)
    ptc = ptc_from_prc(prc_interp)


    # ax.plot(test.ptc_interp(phis), phis, '.')

    test = InvertedPTC(phis, prc)

    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(phis, ptc(phis))
    ax.plot(test.div_points, ptc(test.div_points), 'o')
    
    # thetas = test.phi_to_theta(phis)