diff options
author | Mario Mulansky <mario.mulansky@gmx.net> | 2015-01-19 17:58:04 +0100 |
---|---|---|
committer | Mario Mulansky <mario.mulansky@gmx.net> | 2015-01-19 17:58:04 +0100 |
commit | 66968eedd276eb5d661b25d92775203546a3d646 (patch) | |
tree | 82abff1e9d67cc1672cedb44c73ee79eb29ccbc8 /pyspike/function.py | |
parent | e0a3b5468364342d4468e07029e4daf2cacfd6b9 (diff) |
renamed IntervalSequence -> DiscreteFunction, cython implementation of add
Diffstat (limited to 'pyspike/function.py')
-rw-r--r-- | pyspike/function.py | 269 |
1 files changed, 135 insertions, 134 deletions
diff --git a/pyspike/function.py b/pyspike/function.py index f10c136..6fb7537 100644 --- a/pyspike/function.py +++ b/pyspike/function.py @@ -171,140 +171,6 @@ that PySpike is installed by running\n 'python setup.py build_ext --inplace'! \ ############################################################## -# MultipleValueSequence -############################################################## -class MultipleValueSequence(object): - """ A class representing a sequence of values defined in some interval. - """ - - def __init__(self, x, y, multiplicity): - """ Constructs the value sequence. - - :param x: array of length N defining the points at which the values are - defined. - :param y: array of length N degining the values at the points x. - :param multiplicity: array of length N defining the multiplicity of the - values. - """ - # convert parameters to arrays, also ensures copying - self.x = np.array(x) - self.y = np.array(y) - self.mp = np.array(multiplicity) - - def copy(self): - """ Returns a copy of itself - - :rtype: :class:`IntervalSequence` - """ - return MultipleValueSequence(self.x, self.y, self.mp) - - def almost_equal(self, other, decimal=14): - """ Checks if the function is equal to another function up to `decimal` - precision. - - :param other: another :class:`IntervalSequence` - :returns: True if the two functions are equal up to `decimal` decimals, - False otherwise - :rtype: bool - """ - eps = 10.0**(-decimal) - return np.allclose(self.x, other.x, atol=eps, rtol=0.0) and \ - np.allclose(self.y, other.y, atol=eps, rtol=0.0) and \ - np.allclose(self.mp, other.mp, atol=eps, rtol=0.0) - - def get_plottable_data(self, k=0): - """ Returns two arrays containing x- and y-coordinates for immeditate - plotting of the interval sequence. - - :returns: (x_plot, y_plot) containing plottable data - :rtype: pair of np.array - - Example:: - - x, y = f.get_plottable_data() - plt.plot(x, y, '-o', label="Piece-wise const function") - """ - - if k > 0: - raise NotImplementedError() - - return 1.0*self.x, 1.0*self.y/self.mp - - def integral(self, interval=None): - """ Returns the integral over the given interval. For the interval - sequence this amounts to the sum over all values divided by the count - of intervals. - - :param interval: integration interval given as a pair of floats, if - None the integral over the whole function is computed. - :type interval: Pair of floats or None. - :returns: the integral - :rtype: float - """ - if interval is None: - # no interval given, integrate over the whole spike train - # don't count the first value, which is zero by definition - a = 1.0*np.sum(self.y[1:-1]) - else: - raise NotImplementedError() - return a - - def avrg(self, interval=None): - """ Computes the average of the interval sequence: - :math:`a = 1/N sum f_n ` where N is the number of intervals. - - :param interval: averaging interval given as a pair of floats, a - sequence of pairs for averaging multiple intervals, or - None, if None the average over the whole function is - computed. - :type interval: Pair, sequence of pairs, or None. - :returns: the average a. - :rtype: float - """ - if interval is None: - # no interval given, average over the whole spike train - # don't count the first interval for normalization - return self.integral() / np.sum(self.mp[1:-1]) - else: - raise NotImplementedError() - - def add(self, f): - """ Adds another `MultipleValueSequence` function to this function. - Note: only functions defined on the same interval can be summed. - - :param f: :class:`MultipleValueSequence` function to be added. - :rtype: None - """ - assert self.x[0] == f.x[0], "The functions have different intervals" - assert self.x[-1] == f.x[-1], "The functions have different intervals" - - # cython version - try: - from cython_add import add_interval_sequence_cython as \ - add_interval_sequence_impl - except ImportError: -# print("Warning: add_piece_wise_const_cython not found. Make sure \ -# that PySpike is installed by running\n 'python setup.py build_ext --inplace'! \ -# \n Falling back to slow python backend.") - # use python backend - from python_backend import add_multiple_value_sequence_python as \ - add_multiple_value_sequence_impl - - self.x, self.y, self.mp = \ - add_multiple_value_sequence_impl(self.x, self.y, self.mp, - f.x, f.y, f.mp) - - def mul_scalar(self, fac): - """ Multiplies the function with a scalar value - - :param fac: Value to multiply - :type fac: double - :rtype: None - """ - self.y *= fac - - -############################################################## # PieceWiseLinFunc ############################################################## class PieceWiseLinFunc: @@ -489,6 +355,141 @@ that PySpike is installed by running\n 'python setup.py build_ext --inplace'! \ self.y2 *= fac +############################################################## +# DiscreteFunction +############################################################## +class DiscreteFunction(object): + """ A class representing values defined on a discrete set of points. + """ + + def __init__(self, x, y, multiplicity): + """ Constructs the discrete function. + + :param x: array of length N defining the points at which the values are + defined. + :param y: array of length N degining the values at the points x. + :param multiplicity: array of length N defining the multiplicity of the + values. + """ + # convert parameters to arrays, also ensures copying + self.x = np.array(x) + self.y = np.array(y) + self.mp = np.array(multiplicity) + + def copy(self): + """ Returns a copy of itself + + :rtype: :class:`DiscreteFunction` + """ + return DiscreteFunction(self.x, self.y, self.mp) + + def almost_equal(self, other, decimal=14): + """ Checks if the function is equal to another function up to `decimal` + precision. + + :param other: another :class:`DiscreteFunction` + :returns: True if the two functions are equal up to `decimal` decimals, + False otherwise + :rtype: bool + """ + eps = 10.0**(-decimal) + return np.allclose(self.x, other.x, atol=eps, rtol=0.0) and \ + np.allclose(self.y, other.y, atol=eps, rtol=0.0) and \ + np.allclose(self.mp, other.mp, atol=eps, rtol=0.0) + + def get_plottable_data(self, k=0): + """ Returns two arrays containing x- and y-coordinates for immeditate + plotting of the interval sequence. + + :returns: (x_plot, y_plot) containing plottable data + :rtype: pair of np.array + + Example:: + + x, y = f.get_plottable_data() + plt.plot(x, y, '-o', label="Discrete function") + """ + + if k > 0: + raise NotImplementedError() + + return 1.0*self.x, 1.0*self.y/self.mp + + def integral(self, interval=None): + """ Returns the integral over the given interval. For the interval + sequence this amounts to the sum over all values divided by the count + of intervals. + + :param interval: integration interval given as a pair of floats, if + None the integral over the whole function is computed. + :type interval: Pair of floats or None. + :returns: the integral + :rtype: float + """ + if interval is None: + # no interval given, integrate over the whole spike train + # don't count the first value, which is zero by definition + a = 1.0*np.sum(self.y[1:-1]) + else: + raise NotImplementedError() + return a + + def avrg(self, interval=None): + """ Computes the average of the interval sequence: + :math:`a = 1/N sum f_n ` where N is the number of intervals. + + :param interval: averaging interval given as a pair of floats, a + sequence of pairs for averaging multiple intervals, or + None, if None the average over the whole function is + computed. + :type interval: Pair, sequence of pairs, or None. + :returns: the average a. + :rtype: float + """ + if interval is None: + # no interval given, average over the whole spike train + # don't count the first interval for normalization + return self.integral() / np.sum(self.mp[1:-1]) + else: + raise NotImplementedError() + + def add(self, f): + """ Adds another `DiscreteFunction` function to this function. + Note: only functions defined on the same interval can be summed. + + :param f: :class:`DiscreteFunction` function to be added. + :rtype: None + """ + assert self.x[0] == f.x[0], "The functions have different intervals" + assert self.x[-1] == f.x[-1], "The functions have different intervals" + + # cython version + try: + from cython_add import add_discrete_function_cython as \ + add_discrete_function_impl + except ImportError: + print("Warning: add_discrete_function_cython not found. Make \ +sure that PySpike is installed by running\n\ +'python setup.py build_ext --inplace'! \ +\n Falling back to slow python backend.") + # use python backend + from python_backend import add_discrete_function_python as \ + add_discrete_function_impl + + self.x, self.y, self.mp = \ + add_discrete_function_impl(self.x, self.y, self.mp, + f.x, f.y, f.mp) + + def mul_scalar(self, fac): + """ Multiplies the function with a scalar value + + :param fac: Value to multiply + :type fac: double + :rtype: None + """ + self.y *= fac + + def average_profile(profiles): """ Computes the average profile from the given ISI- or SPIKE-profiles. |