summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMario Mulansky <mario.mulansky@gmx.net>2015-02-03 10:45:32 +0100
committerMario Mulansky <mario.mulansky@gmx.net>2015-02-03 10:45:32 +0100
commitbe9eeb2e48115134b93ec0cd9035d97117bd019e (patch)
tree94f1b656ee52b1e22c255716cc66cb0bcf8e22e4
parent01fa64bd8a8931544a1734de104e2fe72018694f (diff)
split distance.py into 3 separate modules
-rw-r--r--pyspike/__init__.py14
-rw-r--r--pyspike/distances.py507
-rw-r--r--pyspike/generic.py83
-rw-r--r--pyspike/isi_distance.py132
-rw-r--r--pyspike/spike_distance.py135
-rw-r--r--pyspike/spike_sync.py136
6 files changed, 494 insertions, 513 deletions
diff --git a/pyspike/__init__.py b/pyspike/__init__.py
index f480964..1c2efbc 100644
--- a/pyspike/__init__.py
+++ b/pyspike/__init__.py
@@ -4,18 +4,20 @@ Copyright 2014, Mario Mulansky <mario.mulansky@gmx.net>
Distributed under the BSD License
"""
-__all__ = ["distances", "spikes", "PieceWiseConstFunc", "PieceWiseLinFunc",
+__all__ = ["isi_distance", "spike_distance", "spike_sync",
+ "spikes", "PieceWiseConstFunc", "PieceWiseLinFunc",
"DiscreteFunc"]
from PieceWiseConstFunc import PieceWiseConstFunc
from PieceWiseLinFunc import PieceWiseLinFunc
from DiscreteFunc import DiscreteFunc
-from distances import isi_profile, isi_distance, \
- spike_profile, spike_distance, \
- spike_sync_profile, spike_sync, \
- isi_profile_multi, isi_distance_multi, isi_distance_matrix, \
- spike_profile_multi, spike_distance_multi, spike_distance_matrix, \
+from isi_distance import isi_profile, isi_distance, isi_profile_multi,\
+ isi_distance_multi, isi_distance_matrix
+from spike_distance import spike_profile, spike_distance, spike_profile_multi,\
+ spike_distance_multi, spike_distance_matrix
+from spike_sync import spike_sync_profile, spike_sync,\
spike_sync_profile_multi, spike_sync_multi, spike_sync_matrix
+
from spikes import add_auxiliary_spikes, load_spike_trains_from_txt, \
spike_train_from_string, merge_spike_trains, generate_poisson_spikes
diff --git a/pyspike/distances.py b/pyspike/distances.py
deleted file mode 100644
index 9077871..0000000
--- a/pyspike/distances.py
+++ /dev/null
@@ -1,507 +0,0 @@
-""" distances.py
-
-Module containing several functions to compute spike distances
-
-Copyright 2014, Mario Mulansky <mario.mulansky@gmx.net>
-
-Distributed under the BSD License
-"""
-
-import numpy as np
-import threading
-from functools import partial
-
-from pyspike import PieceWiseConstFunc, PieceWiseLinFunc, DiscreteFunc
-
-
-############################################################
-# isi_profile
-############################################################
-def isi_profile(spikes1, spikes2):
- """ Computes the isi-distance profile :math:`S_{isi}(t)` of the two given
- spike trains. Retruns the profile as a PieceWiseConstFunc object. The S_isi
- values are defined positive S_isi(t)>=0. The spike trains are expected
- to have auxiliary spikes at the beginning and end of the interval. Use the
- function add_auxiliary_spikes to add those spikes to the spike train.
-
- :param spikes1: ordered array of spike times with auxiliary spikes.
- :param spikes2: ordered array of spike times with auxiliary spikes.
- :returns: The isi-distance profile :math:`S_{isi}(t)`
- :rtype: :class:`pyspike.function.PieceWiseConstFunc`
-
- """
- # check for auxiliary spikes - first and last spikes should be identical
- assert spikes1[0] == spikes2[0], \
- "Given spike trains seems not to have auxiliary spikes!"
- assert spikes1[-1] == spikes2[-1], \
- "Given spike trains seems not to have auxiliary spikes!"
-
- # load cython implementation
- try:
- from cython_distance import isi_distance_cython as isi_distance_impl
- except ImportError:
- print("Warning: isi_distance_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 isi_distance_python as isi_distance_impl
-
- times, values = isi_distance_impl(spikes1, spikes2)
- return PieceWiseConstFunc(times, values)
-
-
-############################################################
-# isi_distance
-############################################################
-def isi_distance(spikes1, spikes2, interval=None):
- """ Computes the isi-distance I of the given spike trains. The
- isi-distance is the integral over the isi distance profile
- :math:`S_{isi}(t)`:
-
- .. math:: I = \int_{T_0}^{T_1} S_{isi}(t) dt.
-
- :param spikes1: ordered array of spike times with auxiliary spikes.
- :param spikes2: ordered array of spike times with auxiliary spikes.
- :param interval: averaging interval given as a pair of floats (T0, T1),
- if None the average over the whole function is computed.
- :type interval: Pair of floats or None.
- :returns: The isi-distance I.
- :rtype: double
- """
- return isi_profile(spikes1, spikes2).avrg(interval)
-
-
-############################################################
-# spike_profile
-############################################################
-def spike_profile(spikes1, spikes2):
- """ Computes the spike-distance profile S_spike(t) of the two given spike
- trains. Returns the profile as a PieceWiseLinFunc object. The S_spike
- values are defined positive S_spike(t)>=0. The spike trains are expected to
- have auxiliary spikes at the beginning and end of the interval. Use the
- function add_auxiliary_spikes to add those spikes to the spike train.
-
- :param spikes1: ordered array of spike times with auxiliary spikes.
- :param spikes2: ordered array of spike times with auxiliary spikes.
- :returns: The spike-distance profile :math:`S_{spike}(t)`.
- :rtype: :class:`pyspike.function.PieceWiseLinFunc`
-
- """
- # check for auxiliary spikes - first and last spikes should be identical
- assert spikes1[0] == spikes2[0], \
- "Given spike trains seems not to have auxiliary spikes!"
- assert spikes1[-1] == spikes2[-1], \
- "Given spike trains seems not to have auxiliary spikes!"
-
- # cython implementation
- try:
- from cython_distance import spike_distance_cython \
- as spike_distance_impl
- except ImportError:
- print("Warning: spike_distance_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 spike_distance_python as spike_distance_impl
-
- times, y_starts, y_ends = spike_distance_impl(spikes1, spikes2)
- return PieceWiseLinFunc(times, y_starts, y_ends)
-
-
-############################################################
-# spike_distance
-############################################################
-def spike_distance(spikes1, spikes2, interval=None):
- """ Computes the spike-distance S of the given spike trains. The
- spike-distance is the integral over the isi distance profile S_spike(t):
-
- .. math:: S = \int_{T_0}^{T_1} S_{spike}(t) dt.
-
- :param spikes1: ordered array of spike times with auxiliary spikes.
- :param spikes2: ordered array of spike times with auxiliary spikes.
- :param interval: averaging interval given as a pair of floats (T0, T1),
- if None the average over the whole function is computed.
- :type interval: Pair of floats or None.
- :returns: The spike-distance.
- :rtype: double
-
- """
- return spike_profile(spikes1, spikes2).avrg(interval)
-
-
-############################################################
-# spike_sync_profile
-############################################################
-def spike_sync_profile(spikes1, spikes2):
- """ Computes the spike-synchronization profile S_sync(t) of the two given
- spike trains. Returns the profile as a DiscreteFunction object. The S_sync
- values are either 1 or 0, indicating the presence or absence of a
- coincidence. The spike trains are expected to have auxiliary spikes at the
- beginning and end of the interval. Use the function add_auxiliary_spikes to
- add those spikes to the spike train.
-
- :param spikes1: ordered array of spike times with auxiliary spikes.
- :param spikes2: ordered array of spike times with auxiliary spikes.
- :returns: The spike-distance profile :math:`S_{sync}(t)`.
- :rtype: :class:`pyspike.function.DiscreteFunction`
-
- """
-
- # cython implementation
- try:
- from cython_distance import coincidence_cython \
- as coincidence_impl
- except ImportError:
- print("Warning: spike_distance_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 coincidence_python \
- as coincidence_impl
-
- times, coincidences, multiplicity = coincidence_impl(spikes1, spikes2)
-
- return DiscreteFunc(times, coincidences, multiplicity)
-
-
-############################################################
-# spike_sync
-############################################################
-def spike_sync(spikes1, spikes2, interval=None):
- """ Computes the spike synchronization value SYNC of the given spike
- trains. The spike synchronization value is the computed as the total number
- of coincidences divided by the total number of spikes:
-
- .. math:: SYNC = \sum_n C_n / N.
-
- :param spikes1: ordered array of spike times with auxiliary spikes.
- :param spikes2: ordered array of spike times with auxiliary spikes.
- :param interval: averaging interval given as a pair of floats (T0, T1),
- if None the average over the whole function is computed.
- :type interval: Pair of floats or None.
- :returns: The spike synchronization value.
- :rtype: double
- """
- return spike_sync_profile(spikes1, spikes2).avrg(interval)
-
-
-############################################################
-# _generic_profile_multi
-############################################################
-def _generic_profile_multi(spike_trains, pair_distance_func, indices=None):
- """ Internal implementation detail, don't call this function directly,
- use isi_profile_multi or spike_profile_multi instead.
-
- Computes the multi-variate distance for a set of spike-trains using the
- pair_dist_func to compute pair-wise distances. That is it computes the
- average distance of all pairs of spike-trains:
- :math:`S(t) = 2/((N(N-1)) sum_{<i,j>} S_{i,j}`,
- where the sum goes over all pairs <i,j>.
- Args:
- - spike_trains: list of spike trains
- - pair_distance_func: function computing the distance of two spike trains
- - indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- Returns:
- - The averaged multi-variate distance of all pairs
- """
- if indices is None:
- indices = np.arange(len(spike_trains))
- indices = np.array(indices)
- # check validity of indices
- assert (indices < len(spike_trains)).all() and (indices >= 0).all(), \
- "Invalid index list."
- # generate a list of possible index pairs
- pairs = [(indices[i], j) for i in range(len(indices))
- for j in indices[i+1:]]
- # start with first pair
- (i, j) = pairs[0]
- average_dist = pair_distance_func(spike_trains[i], spike_trains[j])
- for (i, j) in pairs[1:]:
- current_dist = pair_distance_func(spike_trains[i], spike_trains[j])
- average_dist.add(current_dist) # add to the average
- return average_dist, len(pairs)
-
-
-############################################################
-# multi_distance_par
-############################################################
-def _multi_distance_par(spike_trains, pair_distance_func, indices=None):
- """ parallel implementation of the multi-distance. Not currently used as
- it does not improve the performance.
- """
-
- num_threads = 2
- lock = threading.Lock()
-
- def run(spike_trains, index_pairs, average_dist):
- (i, j) = index_pairs[0]
- # print(i,j)
- this_avrg = pair_distance_func(spike_trains[i], spike_trains[j])
- for (i, j) in index_pairs[1:]:
- # print(i,j)
- current_dist = pair_distance_func(spike_trains[i], spike_trains[j])
- this_avrg.add(current_dist)
- with lock:
- average_dist.add(this_avrg)
-
- if indices is None:
- indices = np.arange(len(spike_trains))
- indices = np.array(indices)
- # check validity of indices
- assert (indices < len(spike_trains)).all() and (indices >= 0).all(), \
- "Invalid index list."
- # generate a list of possible index pairs
- pairs = [(indices[i], j) for i in range(len(indices))
- for j in indices[i+1:]]
- num_pairs = len(pairs)
-
- # start with first pair
- (i, j) = pairs[0]
- average_dist = pair_distance_func(spike_trains[i], spike_trains[j])
- # remove the one we already computed
- pairs = pairs[1:]
- # distribute the rest into num_threads pieces
- clustered_pairs = [pairs[n::num_threads] for n in xrange(num_threads)]
-
- threads = []
- for pairs in clustered_pairs:
- t = threading.Thread(target=run, args=(spike_trains, pairs,
- average_dist))
- threads.append(t)
- t.start()
- for t in threads:
- t.join()
- average_dist.mul_scalar(1.0/num_pairs) # normalize
- return average_dist
-
-
-############################################################
-# isi_profile_multi
-############################################################
-def isi_profile_multi(spike_trains, indices=None):
- """ computes the multi-variate isi distance profile for a set of spike
- trains. That is the average isi-distance of all pairs of spike-trains:
- S_isi(t) = 2/((N(N-1)) sum_{<i,j>} S_{isi}^{i,j},
- where the sum goes over all pairs <i,j>
-
- :param spike_trains: list of spike trains
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :type state: list or None
- :returns: The averaged isi profile :math:`<S_{isi}>(t)`
- :rtype: :class:`pyspike.function.PieceWiseConstFunc`
- """
- average_dist, M = _generic_profile_multi(spike_trains, isi_profile,
- indices)
- average_dist.mul_scalar(1.0/M) # normalize
- return average_dist
-
-
-############################################################
-# isi_distance_multi
-############################################################
-def isi_distance_multi(spike_trains, indices=None, interval=None):
- """ computes the multi-variate isi-distance for a set of spike-trains.
- That is the time average of the multi-variate spike profile:
- I = \int_0^T 2/((N(N-1)) sum_{<i,j>} S_{isi}^{i,j},
- where the sum goes over all pairs <i,j>
-
- :param spike_trains: list of spike trains
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :param interval: averaging interval given as a pair of floats, if None
- the average over the whole function is computed.
- :type interval: Pair of floats or None.
- :returns: The time-averaged isi distance :math:`I`
- :rtype: double
- """
- return isi_profile_multi(spike_trains, indices).avrg(interval)
-
-
-############################################################
-# spike_profile_multi
-############################################################
-def spike_profile_multi(spike_trains, indices=None):
- """ Computes the multi-variate spike distance profile for a set of spike
- trains. That is the average spike-distance of all pairs of spike-trains:
- :math:`S_spike(t) = 2/((N(N-1)) sum_{<i,j>} S_{spike}^{i, j}`,
- where the sum goes over all pairs <i,j>
-
- :param spike_trains: list of spike trains
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :type indices: list or None
- :returns: The averaged spike profile :math:`<S_{spike}>(t)`
- :rtype: :class:`pyspike.function.PieceWiseLinFunc`
-
- """
- average_dist, M = _generic_profile_multi(spike_trains, spike_profile,
- indices)
- average_dist.mul_scalar(1.0/M) # normalize
- return average_dist
-
-
-############################################################
-# spike_distance_multi
-############################################################
-def spike_distance_multi(spike_trains, indices=None, interval=None):
- """ Computes the multi-variate spike distance for a set of spike trains.
- That is the time average of the multi-variate spike profile:
- S_{spike} = \int_0^T 2/((N(N-1)) sum_{<i,j>} S_{spike}^{i, j} dt
- where the sum goes over all pairs <i,j>
-
- :param spike_trains: list of spike trains
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :type indices: list or None
- :param interval: averaging interval given as a pair of floats, if None
- the average over the whole function is computed.
- :type interval: Pair of floats or None.
- :returns: The averaged spike distance S.
- :rtype: double
- """
- return spike_profile_multi(spike_trains, indices).avrg(interval)
-
-
-############################################################
-# spike_profile_multi
-############################################################
-def spike_sync_profile_multi(spike_trains, indices=None):
- """ Computes the multi-variate spike synchronization profile for a set of
- spike trains. For each spike in the set of spike trains, the multi-variate
- profile is defined as the number of coincidences divided by the number of
- spike trains pairs involving the spike train of containing this spike,
- which is the number of spike trains minus one (N-1).
-
- :param spike_trains: list of spike trains
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :type indices: list or None
- :returns: The multi-variate spike sync profile :math:`<S_{sync}>(t)`
- :rtype: :class:`pyspike.function.DiscreteFunction`
-
- """
- prof_func = partial(spike_sync_profile)
- average_dist, M = _generic_profile_multi(spike_trains, prof_func,
- indices)
- # average_dist.mul_scalar(1.0/M) # no normalization here!
- return average_dist
-
-
-############################################################
-# spike_distance_multi
-############################################################
-def spike_sync_multi(spike_trains, indices=None, interval=None):
- """ Computes the multi-variate spike synchronization value for a set of
- spike trains.
-
- :param spike_trains: list of spike trains
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :type indices: list or None
- :param interval: averaging interval given as a pair of floats, if None
- the average over the whole function is computed.
- :type interval: Pair of floats or None.
- :returns: The multi-variate spike synchronization value SYNC.
- :rtype: double
- """
- return spike_sync_profile_multi(spike_trains, indices).avrg(interval)
-
-
-############################################################
-# generic_distance_matrix
-############################################################
-def _generic_distance_matrix(spike_trains, dist_function,
- indices=None, interval=None):
- """ Internal implementation detail. Don't use this function directly.
- Instead use isi_distance_matrix or spike_distance_matrix.
- Computes the time averaged distance of all pairs of spike-trains.
- Args:
- - spike_trains: list of spike trains
- - indices: list of indices defining which spike-trains to use
- if None all given spike-trains are used (default=None)
- Return:
- - a 2D array of size len(indices)*len(indices) containing the average
- pair-wise distance
- """
- if indices is None:
- indices = np.arange(len(spike_trains))
- indices = np.array(indices)
- # check validity of indices
- assert (indices < len(spike_trains)).all() and (indices >= 0).all(), \
- "Invalid index list."
- # generate a list of possible index pairs
- pairs = [(indices[i], j) for i in range(len(indices))
- for j in indices[i+1:]]
-
- distance_matrix = np.zeros((len(indices), len(indices)))
- for i, j in pairs:
- d = dist_function(spike_trains[i], spike_trains[j], interval)
- distance_matrix[i, j] = d
- distance_matrix[j, i] = d
- return distance_matrix
-
-
-############################################################
-# isi_distance_matrix
-############################################################
-def isi_distance_matrix(spike_trains, indices=None, interval=None):
- """ Computes the time averaged isi-distance of all pairs of spike-trains.
-
- :param spike_trains: list of spike trains
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :type indices: list or None
- :param interval: averaging interval given as a pair of floats, if None
- the average over the whole function is computed.
- :type interval: Pair of floats or None.
- :returns: 2D array with the pair wise time average isi distances
- :math:`I_{ij}`
- :rtype: np.array
- """
- return _generic_distance_matrix(spike_trains, isi_distance,
- indices, interval)
-
-
-############################################################
-# spike_distance_matrix
-############################################################
-def spike_distance_matrix(spike_trains, indices=None, interval=None):
- """ Computes the time averaged spike-distance of all pairs of spike-trains.
-
- :param spike_trains: list of spike trains
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :type indices: list or None
- :param interval: averaging interval given as a pair of floats, if None
- the average over the whole function is computed.
- :type interval: Pair of floats or None.
- :returns: 2D array with the pair wise time average spike distances
- :math:`S_{ij}`
- :rtype: np.array
- """
- return _generic_distance_matrix(spike_trains, spike_distance,
- indices, interval)
-
-
-############################################################
-# spike_sync_matrix
-############################################################
-def spike_sync_matrix(spike_trains, indices=None, interval=None):
- """ Computes the overall spike-synchronization value of all pairs of
- spike-trains.
-
- :param spike_trains: list of spike trains
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :type indices: list or None
- :param interval: averaging interval given as a pair of floats, if None
- the average over the whole function is computed.
- :type interval: Pair of floats or None.
- :returns: 2D array with the pair wise time spike synchronization values
- :math:`SYNC_{ij}`
- :rtype: np.array
- """
- return _generic_distance_matrix(spike_trains, spike_sync,
- indices, interval)
diff --git a/pyspike/generic.py b/pyspike/generic.py
new file mode 100644
index 0000000..4f278d2
--- /dev/null
+++ b/pyspike/generic.py
@@ -0,0 +1,83 @@
+"""
+
+Generic functions to compute multi-variate profiles and distance matrices.
+
+Copyright 2015, Mario Mulansky <mario.mulansky@gmx.net>
+
+Distributed under the BSD License
+"""
+
+
+import numpy as np
+
+
+############################################################
+# _generic_profile_multi
+############################################################
+def _generic_profile_multi(spike_trains, pair_distance_func, indices=None):
+ """ Internal implementation detail, don't call this function directly,
+ use isi_profile_multi or spike_profile_multi instead.
+
+ Computes the multi-variate distance for a set of spike-trains using the
+ pair_dist_func to compute pair-wise distances. That is it computes the
+ average distance of all pairs of spike-trains:
+ :math:`S(t) = 2/((N(N-1)) sum_{<i,j>} S_{i,j}`,
+ where the sum goes over all pairs <i,j>.
+ Args:
+ - spike_trains: list of spike trains
+ - pair_distance_func: function computing the distance of two spike trains
+ - indices: list of indices defining which spike trains to use,
+ if None all given spike trains are used (default=None)
+ Returns:
+ - The averaged multi-variate distance of all pairs
+ """
+ if indices is None:
+ indices = np.arange(len(spike_trains))
+ indices = np.array(indices)
+ # check validity of indices
+ assert (indices < len(spike_trains)).all() and (indices >= 0).all(), \
+ "Invalid index list."
+ # generate a list of possible index pairs
+ pairs = [(indices[i], j) for i in range(len(indices))
+ for j in indices[i+1:]]
+ # start with first pair
+ (i, j) = pairs[0]
+ average_dist = pair_distance_func(spike_trains[i], spike_trains[j])
+ for (i, j) in pairs[1:]:
+ current_dist = pair_distance_func(spike_trains[i], spike_trains[j])
+ average_dist.add(current_dist) # add to the average
+ return average_dist, len(pairs)
+
+
+############################################################
+# generic_distance_matrix
+############################################################
+def _generic_distance_matrix(spike_trains, dist_function,
+ indices=None, interval=None):
+ """ Internal implementation detail. Don't use this function directly.
+ Instead use isi_distance_matrix or spike_distance_matrix.
+ Computes the time averaged distance of all pairs of spike-trains.
+ Args:
+ - spike_trains: list of spike trains
+ - indices: list of indices defining which spike-trains to use
+ if None all given spike-trains are used (default=None)
+ Return:
+ - a 2D array of size len(indices)*len(indices) containing the average
+ pair-wise distance
+ """
+ if indices is None:
+ indices = np.arange(len(spike_trains))
+ indices = np.array(indices)
+ # check validity of indices
+ assert (indices < len(spike_trains)).all() and (indices >= 0).all(), \
+ "Invalid index list."
+ # generate a list of possible index pairs
+ pairs = [(indices[i], j) for i in range(len(indices))
+ for j in indices[i+1:]]
+
+ distance_matrix = np.zeros((len(indices), len(indices)))
+ for i, j in pairs:
+ d = dist_function(spike_trains[i], spike_trains[j], interval)
+ distance_matrix[i, j] = d
+ distance_matrix[j, i] = d
+ return distance_matrix
diff --git a/pyspike/isi_distance.py b/pyspike/isi_distance.py
new file mode 100644
index 0000000..745d280
--- /dev/null
+++ b/pyspike/isi_distance.py
@@ -0,0 +1,132 @@
+"""
+
+Module containing several functions to compute the ISI profiles and distances
+
+Copyright 2014-2015, Mario Mulansky <mario.mulansky@gmx.net>
+
+Distributed under the BSD License
+"""
+
+from pyspike import PieceWiseConstFunc
+from pyspike.generic import _generic_profile_multi, _generic_distance_matrix
+
+
+############################################################
+# isi_profile
+############################################################
+def isi_profile(spikes1, spikes2):
+ """ Computes the isi-distance profile :math:`S_{isi}(t)` of the two given
+ spike trains. Retruns the profile as a PieceWiseConstFunc object. The S_isi
+ values are defined positive S_isi(t)>=0. The spike trains are expected
+ to have auxiliary spikes at the beginning and end of the interval. Use the
+ function add_auxiliary_spikes to add those spikes to the spike train.
+
+ :param spikes1: ordered array of spike times with auxiliary spikes.
+ :param spikes2: ordered array of spike times with auxiliary spikes.
+ :returns: The isi-distance profile :math:`S_{isi}(t)`
+ :rtype: :class:`pyspike.function.PieceWiseConstFunc`
+
+ """
+ # check for auxiliary spikes - first and last spikes should be identical
+ assert spikes1[0] == spikes2[0], \
+ "Given spike trains seems not to have auxiliary spikes!"
+ assert spikes1[-1] == spikes2[-1], \
+ "Given spike trains seems not to have auxiliary spikes!"
+
+ # load cython implementation
+ try:
+ from cython_distance import isi_distance_cython as isi_distance_impl
+ except ImportError:
+ print("Warning: isi_distance_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 isi_distance_python as isi_distance_impl
+
+ times, values = isi_distance_impl(spikes1, spikes2)
+ return PieceWiseConstFunc(times, values)
+
+
+############################################################
+# isi_distance
+############################################################
+def isi_distance(spikes1, spikes2, interval=None):
+ """ Computes the isi-distance I of the given spike trains. The
+ isi-distance is the integral over the isi distance profile
+ :math:`S_{isi}(t)`:
+
+ .. math:: I = \int_{T_0}^{T_1} S_{isi}(t) dt.
+
+ :param spikes1: ordered array of spike times with auxiliary spikes.
+ :param spikes2: ordered array of spike times with auxiliary spikes.
+ :param interval: averaging interval given as a pair of floats (T0, T1),
+ if None the average over the whole function is computed.
+ :type interval: Pair of floats or None.
+ :returns: The isi-distance I.
+ :rtype: double
+ """
+ return isi_profile(spikes1, spikes2).avrg(interval)
+
+
+############################################################
+# isi_profile_multi
+############################################################
+def isi_profile_multi(spike_trains, indices=None):
+ """ computes the multi-variate isi distance profile for a set of spike
+ trains. That is the average isi-distance of all pairs of spike-trains:
+ S_isi(t) = 2/((N(N-1)) sum_{<i,j>} S_{isi}^{i,j},
+ where the sum goes over all pairs <i,j>
+
+ :param spike_trains: list of spike trains
+ :param indices: list of indices defining which spike trains to use,
+ if None all given spike trains are used (default=None)
+ :type state: list or None
+ :returns: The averaged isi profile :math:`<S_{isi}>(t)`
+ :rtype: :class:`pyspike.function.PieceWiseConstFunc`
+ """
+ average_dist, M = _generic_profile_multi(spike_trains, isi_profile,
+ indices)
+ average_dist.mul_scalar(1.0/M) # normalize
+ return average_dist
+
+
+############################################################
+# isi_distance_multi
+############################################################
+def isi_distance_multi(spike_trains, indices=None, interval=None):
+ """ computes the multi-variate isi-distance for a set of spike-trains.
+ That is the time average of the multi-variate spike profile:
+ I = \int_0^T 2/((N(N-1)) sum_{<i,j>} S_{isi}^{i,j},
+ where the sum goes over all pairs <i,j>
+
+ :param spike_trains: list of spike trains
+ :param indices: list of indices defining which spike trains to use,
+ if None all given spike trains are used (default=None)
+ :param interval: averaging interval given as a pair of floats, if None
+ the average over the whole function is computed.
+ :type interval: Pair of floats or None.
+ :returns: The time-averaged isi distance :math:`I`
+ :rtype: double
+ """
+ return isi_profile_multi(spike_trains, indices).avrg(interval)
+
+
+############################################################
+# isi_distance_matrix
+############################################################
+def isi_distance_matrix(spike_trains, indices=None, interval=None):
+ """ Computes the time averaged isi-distance of all pairs of spike-trains.
+
+ :param spike_trains: list of spike trains
+ :param indices: list of indices defining which spike trains to use,
+ if None all given spike trains are used (default=None)
+ :type indices: list or None
+ :param interval: averaging interval given as a pair of floats, if None
+ the average over the whole function is computed.
+ :type interval: Pair of floats or None.
+ :returns: 2D array with the pair wise time average isi distances
+ :math:`I_{ij}`
+ :rtype: np.array
+ """
+ return _generic_distance_matrix(spike_trains, isi_distance,
+ indices, interval)
diff --git a/pyspike/spike_distance.py b/pyspike/spike_distance.py
new file mode 100644
index 0000000..2c989a4
--- /dev/null
+++ b/pyspike/spike_distance.py
@@ -0,0 +1,135 @@
+"""
+
+Module containing several functions to compute SPIKE profiles and distances
+
+Copyright 2014-2015, Mario Mulansky <mario.mulansky@gmx.net>
+
+Distributed under the BSD License
+"""
+
+from pyspike import PieceWiseLinFunc
+from pyspike.generic import _generic_profile_multi, _generic_distance_matrix
+
+
+############################################################
+# spike_profile
+############################################################
+def spike_profile(spikes1, spikes2):
+ """ Computes the spike-distance profile S_spike(t) of the two given spike
+ trains. Returns the profile as a PieceWiseLinFunc object. The S_spike
+ values are defined positive S_spike(t)>=0. The spike trains are expected to
+ have auxiliary spikes at the beginning and end of the interval. Use the
+ function add_auxiliary_spikes to add those spikes to the spike train.
+
+ :param spikes1: ordered array of spike times with auxiliary spikes.
+ :param spikes2: ordered array of spike times with auxiliary spikes.
+ :returns: The spike-distance profile :math:`S_{spike}(t)`.
+ :rtype: :class:`pyspike.function.PieceWiseLinFunc`
+
+ """
+ # check for auxiliary spikes - first and last spikes should be identical
+ assert spikes1[0] == spikes2[0], \
+ "Given spike trains seems not to have auxiliary spikes!"
+ assert spikes1[-1] == spikes2[-1], \
+ "Given spike trains seems not to have auxiliary spikes!"
+
+ # cython implementation
+ try:
+ from cython_distance import spike_distance_cython \
+ as spike_distance_impl
+ except ImportError:
+ print("Warning: spike_distance_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 spike_distance_python as spike_distance_impl
+
+ times, y_starts, y_ends = spike_distance_impl(spikes1, spikes2)
+ return PieceWiseLinFunc(times, y_starts, y_ends)
+
+
+############################################################
+# spike_distance
+############################################################
+def spike_distance(spikes1, spikes2, interval=None):
+ """ Computes the spike-distance S of the given spike trains. The
+ spike-distance is the integral over the isi distance profile S_spike(t):
+
+ .. math:: S = \int_{T_0}^{T_1} S_{spike}(t) dt.
+
+ :param spikes1: ordered array of spike times with auxiliary spikes.
+ :param spikes2: ordered array of spike times with auxiliary spikes.
+ :param interval: averaging interval given as a pair of floats (T0, T1),
+ if None the average over the whole function is computed.
+ :type interval: Pair of floats or None.
+ :returns: The spike-distance.
+ :rtype: double
+
+ """
+ return spike_profile(spikes1, spikes2).avrg(interval)
+
+
+############################################################
+# spike_profile_multi
+############################################################
+def spike_profile_multi(spike_trains, indices=None):
+ """ Computes the multi-variate spike distance profile for a set of spike
+ trains. That is the average spike-distance of all pairs of spike-trains:
+ :math:`S_spike(t) = 2/((N(N-1)) sum_{<i,j>} S_{spike}^{i, j}`,
+ where the sum goes over all pairs <i,j>
+
+ :param spike_trains: list of spike trains
+ :param indices: list of indices defining which spike trains to use,
+ if None all given spike trains are used (default=None)
+ :type indices: list or None
+ :returns: The averaged spike profile :math:`<S_{spike}>(t)`
+ :rtype: :class:`pyspike.function.PieceWiseLinFunc`
+
+ """
+ average_dist, M = _generic_profile_multi(spike_trains, spike_profile,
+ indices)
+ average_dist.mul_scalar(1.0/M) # normalize
+ return average_dist
+
+
+############################################################
+# spike_distance_multi
+############################################################
+def spike_distance_multi(spike_trains, indices=None, interval=None):
+ """ Computes the multi-variate spike distance for a set of spike trains.
+ That is the time average of the multi-variate spike profile:
+ S_{spike} = \int_0^T 2/((N(N-1)) sum_{<i,j>} S_{spike}^{i, j} dt
+ where the sum goes over all pairs <i,j>
+
+ :param spike_trains: list of spike trains
+ :param indices: list of indices defining which spike trains to use,
+ if None all given spike trains are used (default=None)
+ :type indices: list or None
+ :param interval: averaging interval given as a pair of floats, if None
+ the average over the whole function is computed.
+ :type interval: Pair of floats or None.
+ :returns: The averaged spike distance S.
+ :rtype: double
+ """
+ return spike_profile_multi(spike_trains, indices).avrg(interval)
+
+
+############################################################
+# spike_distance_matrix
+############################################################
+def spike_distance_matrix(spike_trains, indices=None, interval=None):
+ """ Computes the time averaged spike-distance of all pairs of spike-trains.
+
+ :param spike_trains: list of spike trains
+ :param indices: list of indices defining which spike trains to use,
+ if None all given spike trains are used (default=None)
+ :type indices: list or None
+ :param interval: averaging interval given as a pair of floats, if None
+ the average over the whole function is computed.
+ :type interval: Pair of floats or None.
+ :returns: 2D array with the pair wise time average spike distances
+ :math:`S_{ij}`
+ :rtype: np.array
+ """
+ return _generic_distance_matrix(spike_trains, spike_distance,
+ indices, interval)
diff --git a/pyspike/spike_sync.py b/pyspike/spike_sync.py
new file mode 100644
index 0000000..f7cbe1d
--- /dev/null
+++ b/pyspike/spike_sync.py
@@ -0,0 +1,136 @@
+"""
+
+Module containing several functions to compute SPIKE-Synchronization profiles
+and distances
+
+Copyright 2014-2015, Mario Mulansky <mario.mulansky@gmx.net>
+
+Distributed under the BSD License
+"""
+
+from functools import partial
+from pyspike import DiscreteFunc
+from pyspike.generic import _generic_profile_multi, _generic_distance_matrix
+
+
+############################################################
+# spike_sync_profile
+############################################################
+def spike_sync_profile(spikes1, spikes2):
+ """ Computes the spike-synchronization profile S_sync(t) of the two given
+ spike trains. Returns the profile as a DiscreteFunction object. The S_sync
+ values are either 1 or 0, indicating the presence or absence of a
+ coincidence. The spike trains are expected to have auxiliary spikes at the
+ beginning and end of the interval. Use the function add_auxiliary_spikes to
+ add those spikes to the spike train.
+
+ :param spikes1: ordered array of spike times with auxiliary spikes.
+ :param spikes2: ordered array of spike times with auxiliary spikes.
+ :returns: The spike-distance profile :math:`S_{sync}(t)`.
+ :rtype: :class:`pyspike.function.DiscreteFunction`
+
+ """
+
+ # cython implementation
+ try:
+ from cython_distance import coincidence_cython \
+ as coincidence_impl
+ except ImportError:
+ print("Warning: spike_distance_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 coincidence_python \
+ as coincidence_impl
+
+ times, coincidences, multiplicity = coincidence_impl(spikes1, spikes2)
+
+ return DiscreteFunc(times, coincidences, multiplicity)
+
+
+############################################################
+# spike_sync
+############################################################
+def spike_sync(spikes1, spikes2, interval=None):
+ """ Computes the spike synchronization value SYNC of the given spike
+ trains. The spike synchronization value is the computed as the total number
+ of coincidences divided by the total number of spikes:
+
+ .. math:: SYNC = \sum_n C_n / N.
+
+ :param spikes1: ordered array of spike times with auxiliary spikes.
+ :param spikes2: ordered array of spike times with auxiliary spikes.
+ :param interval: averaging interval given as a pair of floats (T0, T1),
+ if None the average over the whole function is computed.
+ :type interval: Pair of floats or None.
+ :returns: The spike synchronization value.
+ :rtype: double
+ """
+ return spike_sync_profile(spikes1, spikes2).avrg(interval)
+
+
+############################################################
+# spike_sync_profile_multi
+############################################################
+def spike_sync_profile_multi(spike_trains, indices=None):
+ """ Computes the multi-variate spike synchronization profile for a set of
+ spike trains. For each spike in the set of spike trains, the multi-variate
+ profile is defined as the number of coincidences divided by the number of
+ spike trains pairs involving the spike train of containing this spike,
+ which is the number of spike trains minus one (N-1).
+
+ :param spike_trains: list of spike trains
+ :param indices: list of indices defining which spike trains to use,
+ if None all given spike trains are used (default=None)
+ :type indices: list or None
+ :returns: The multi-variate spike sync profile :math:`<S_{sync}>(t)`
+ :rtype: :class:`pyspike.function.DiscreteFunction`
+
+ """
+ prof_func = partial(spike_sync_profile)
+ average_dist, M = _generic_profile_multi(spike_trains, prof_func,
+ indices)
+ # average_dist.mul_scalar(1.0/M) # no normalization here!
+ return average_dist
+
+
+############################################################
+# spike_distance_multi
+############################################################
+def spike_sync_multi(spike_trains, indices=None, interval=None):
+ """ Computes the multi-variate spike synchronization value for a set of
+ spike trains.
+
+ :param spike_trains: list of spike trains
+ :param indices: list of indices defining which spike trains to use,
+ if None all given spike trains are used (default=None)
+ :type indices: list or None
+ :param interval: averaging interval given as a pair of floats, if None
+ the average over the whole function is computed.
+ :type interval: Pair of floats or None.
+ :returns: The multi-variate spike synchronization value SYNC.
+ :rtype: double
+ """
+ return spike_sync_profile_multi(spike_trains, indices).avrg(interval)
+
+
+############################################################
+# spike_sync_matrix
+############################################################
+def spike_sync_matrix(spike_trains, indices=None, interval=None):
+ """ Computes the overall spike-synchronization value of all pairs of
+ spike-trains.
+
+ :param spike_trains: list of spike trains
+ :param indices: list of indices defining which spike trains to use,
+ if None all given spike trains are used (default=None)
+ :type indices: list or None
+ :param interval: averaging interval given as a pair of floats, if None
+ the average over the whole function is computed.
+ :type interval: Pair of floats or None.
+ :returns: 2D array with the pair wise time spike synchronization values
+ :math:`SYNC_{ij}`
+ :rtype: np.array
+ """
+ return _generic_distance_matrix(spike_trains, spike_sync,
+ indices, interval)