Skip to content

Commit

Permalink
Merge branch 'master' into nn_refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
naspert authored Mar 22, 2018
2 parents 1309e92 + 361f025 commit 1fbb816
Show file tree
Hide file tree
Showing 18 changed files with 93 additions and 41 deletions.
39 changes: 39 additions & 0 deletions .zenodo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"title": "PyGSP: Graph Signal Processing in Python",
"description": "The PyGSP facilitates a wide variety of operations on graphs, like computing their Fourier basis, filtering or interpolating signals, plotting graphs, signals, and filters.",
"upload_type": "software",
"license": "BSD-3-Clause",
"access_right": "open",
"creators": [
{
"name": "Micha\u00ebl Defferrard",
"affiliation": "EPFL",
"orcid": "0000-0002-6028-9024"
},
{
"name": "Lionel Martin",
"affiliation": "EPFL"
},
{
"name": "Rodrigo Pena",
"affiliation": "EPFL"
},
{
"name": "Nathana\u00ebl Perraudin",
"affiliation": "EPFL",
"orcid": "0000-0001-8285-1308"
}
],
"related_identifiers": [
{
"scheme": "url",
"identifier": "https://github.com/epfl-lts2/pygsp",
"relation": "isSupplementTo"
},
{
"scheme": "doi",
"identifier": "10.5281/zenodo.1003157",
"relation": "isPartOf"
}
]
}
3 changes: 3 additions & 0 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ Making a release

Log in as the LTS2 user.
#. Build and upload the distribution to the real PyPI with ``make release``.
#. Update the conda feedstock (at least the version number and sha256 in
``recipe/meta.yaml``) by sending a PR to
`conda-forge <https://github.com/conda-forge/pygsp-feedstock>`_.

Repository organization
-----------------------
Expand Down
35 changes: 25 additions & 10 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ PyGSP: Graph Signal Processing in Python
:target: https://pygsp.readthedocs.io
.. |pypi| image:: https://img.shields.io/pypi/v/pygsp.svg
:target: https://pypi.python.org/pypi/PyGSP
.. |zenodo| image:: https://zenodo.org/badge/16276560.svg
.. |zenodo| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.1003157.svg
:target: https://doi.org/10.5281/zenodo.1003157
.. |license| image:: https://img.shields.io/pypi/l/pygsp.svg
:target: https://github.com/epfl-lts2/pygsp/blob/master/LICENSE.txt
Expand All @@ -33,13 +33,11 @@ PyGSP: Graph Signal Processing in Python

The PyGSP is a Python package to ease
`Signal Processing on Graphs <https://arxiv.org/abs/1211.0053>`_.
It is a free software, distributed under the BSD license, and
available on `PyPI <https://pypi.python.org/pypi/PyGSP>`_.
The documentation is available on
`Read the Docs <https://pygsp.readthedocs.io>`_
and development takes place on
`GitHub <https://github.com/epfl-lts2/pygsp>`_.
(A `Matlab counterpart <https://epfl-lts2.github.io/gspbox-html>`_ exists.)
A (mostly unmaintained) `Matlab version <https://epfl-lts2.github.io/gspbox-html>`_ exists.

The PyGSP facilitates a wide variety of operations on graphs, like computing
their Fourier basis, filtering or interpolating signals, plotting graphs,
Expand All @@ -60,8 +58,15 @@ main objects of the package.

>>> from pygsp import graphs, filters
>>> G = graphs.Logo()
>>> G.estimate_lmax()
>>> g = filters.Heat(G, tau=100)
>>> G.compute_fourier_basis() # Fourier to plot the eigenvalues.
>>> # G.estimate_lmax() is otherwise sufficient.
>>> g = filters.Heat(G, tau=50)
>>> g.plot()

.. image:: ../pygsp/data/readme_example_filter.png
:alt:
.. image:: pygsp/data/readme_example_filter.png
:alt:

Let's now create a graph signal: a set of three Kronecker deltas for that
example. We can now look at one step of heat diffusion by filtering the deltas
Expand All @@ -73,11 +78,11 @@ structure!
>>> s = np.zeros(G.N)
>>> s[DELTAS] = 1
>>> s = g.filter(s)
>>> G.plot_signal(s, highlight=DELTAS, backend='matplotlib')
>>> G.plot_signal(s, highlight=DELTAS)

.. image:: ../pygsp/data/readme_example.png
.. image:: ../pygsp/data/readme_example_graph.png
:alt:
.. image:: pygsp/data/readme_example.png
.. image:: pygsp/data/readme_example_graph.png
:alt:

You can
Expand All @@ -86,7 +91,7 @@ look at the
`tutorials <https://pygsp.readthedocs.io/en/stable/tutorials/index.html>`_
to learn how to use it, or look at the
`reference guide <https://pygsp.readthedocs.io/en/stable/reference/index.html>`_
for an exhaustive documentation of the API. Enjoy the package!
for an exhaustive documentation of the API. Enjoy!

Installation
------------
Expand Down Expand Up @@ -115,6 +120,16 @@ research purpose at the `EPFL LTS2 laboratory <https://lts2.epfl.ch>`_.
This project has been partly funded by the Swiss National Science Foundation
under grant 200021_154350 "Towards Signal Processing on Graphs".

The code in this repository is released under the terms of the `BSD 3-Clause license <LICENSE.txt>`_.

If you are using the library for your research, for the sake of
reproducibility, please cite the version you used as indexed by
`Zenodo <https://doi.org/10.5281/zenodo.1003157>`_.
Or cite the generic concept as::

@misc{pygsp,
title = {PyGSP: Graph Signal Processing in Python},
author = {Defferrard, Micha\"el and Martin, Lionel and Pena, Rodrigo and Perraudin, Nathana\"el},
doi = {10.5281/zenodo.1003157},
url = {https://github.com/epfl-lts2/pygsp/},
}
Binary file added pygsp/data/readme_example_filter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
4 changes: 2 additions & 2 deletions pygsp/filters/abspline.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Abspline(Filter):
"""

def __init__(self, G, Nf=6, lpfactor=20, scales=None, **kwargs):
def __init__(self, G, Nf=6, lpfactor=20, scales=None):

def kernel_abspline3(x, alpha, beta, t1, t2):
M = np.array([[1, t1, t1**2, t1**3],
Expand Down Expand Up @@ -98,4 +98,4 @@ def kernel_abspline3(x, alpha, beta, t1, t2):
lminfac = .6 * G.lmin
g[0] = lambda x: gamma_l * gl(x / lminfac)

super(Abspline, self).__init__(G, g, **kwargs)
super(Abspline, self).__init__(G, g)
4 changes: 2 additions & 2 deletions pygsp/filters/expwin.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Expwin(Filter):
"""

def __init__(self, G, bmax=0.2, a=1., **kwargs):
def __init__(self, G, bmax=0.2, a=1.):

def fx(x, a):
y = np.exp(-float(a)/x)
Expand All @@ -53,4 +53,4 @@ def ffin(x, a):

g = [lambda x: ffin(np.float64(x)/bmax/G.lmax, a)]

super(Expwin, self).__init__(G, g, **kwargs)
super(Expwin, self).__init__(G, g)
8 changes: 2 additions & 6 deletions pygsp/filters/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ class Filter(object):
G : Graph
The graph to which the filter bank was tailored. It is a reference to
the graph passed when instantiating the class.
kernels : function or list of functions
A (list of) function defining the filter bank. One function per filter.
Either passed by the user when instantiating the base class, either
constructed by the derived classes.
Nf : int
Number of filters in the filter bank.
Expand Down Expand Up @@ -93,8 +89,8 @@ def evaluate(self, x):
"""
# Avoid to copy data as with np.array([g(x) for g in self._kernels]).
y = np.empty((self.Nf, len(x)))
for i, g in enumerate(self._kernels):
y[i] = g(x)
for i, kernel in enumerate(self._kernels):
y[i] = kernel(x)
return y

def filter(self, s, method='chebyshev', order=30):
Expand Down
4 changes: 2 additions & 2 deletions pygsp/filters/halfcosine.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class HalfCosine(Filter):
"""

def __init__(self, G, Nf=6, **kwargs):
def __init__(self, G, Nf=6):

if Nf <= 2:
raise ValueError('The number of filters must be higher than 2.')
Expand All @@ -45,4 +45,4 @@ def __init__(self, G, Nf=6, **kwargs):
for i in range(Nf):
g.append(lambda x, ind=i: main_window(x - dila_fact/3. * (ind - 2)))

super(HalfCosine, self).__init__(G, g, **kwargs)
super(HalfCosine, self).__init__(G, g)
4 changes: 2 additions & 2 deletions pygsp/filters/heat.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class Heat(Filter):
"""

def __init__(self, G, tau=10, normalize=False, **kwargs):
def __init__(self, G, tau=10, normalize=False):

try:
iter(tau)
Expand All @@ -76,4 +76,4 @@ def kernel(x, t):
norm = np.linalg.norm(kernel(G.e, t)) if normalize else 1
g.append(lambda x, t=t, norm=norm: kernel(x, t) / norm)

super(Heat, self).__init__(G, g, **kwargs)
super(Heat, self).__init__(G, g)
4 changes: 2 additions & 2 deletions pygsp/filters/held.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class Held(Filter):
"""

def __init__(self, G, a=2./3, **kwargs):
def __init__(self, G, a=2./3):

g = [lambda x: held(x * (2./G.lmax), a)]
g.append(lambda x: np.real(np.sqrt(1 - (held(x * (2./G.lmax), a))
Expand All @@ -67,4 +67,4 @@ def held(val, a):

return y

super(Held, self).__init__(G, g, **kwargs)
super(Held, self).__init__(G, g)
4 changes: 2 additions & 2 deletions pygsp/filters/itersine.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Itersine(Filter):
>>> G.plot_signal(s, ax=axes[1])
"""
def __init__(self, G, Nf=6, overlap=2., **kwargs):
def __init__(self, G, Nf=6, overlap=2.):

def k(x):
return np.sin(0.5*np.pi*np.power(np.cos(x*np.pi), 2)) * ((x >= -0.5)*(x <= 0.5))
Expand All @@ -46,4 +46,4 @@ def k(x):
for i in range(1, Nf + 1):
g.append(lambda x, ind=i: k(x/scale - (ind - overlap/2.)/overlap) / np.sqrt(overlap)*np.sqrt(2))

super(Itersine, self).__init__(G, g, **kwargs)
super(Itersine, self).__init__(G, g)
5 changes: 2 additions & 3 deletions pygsp/filters/mexicanhat.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ class MexicanHat(Filter):
"""

def __init__(self, G, Nf=6, lpfactor=20, scales=None, normalize=False,
**kwargs):
def __init__(self, G, Nf=6, lpfactor=20, scales=None, normalize=False):

lmin = G.lmax / lpfactor

Expand All @@ -82,4 +81,4 @@ def kernel(x, i=i):

kernels.append(kernel)

super(MexicanHat, self).__init__(G, kernels, **kwargs)
super(MexicanHat, self).__init__(G, kernels)
4 changes: 2 additions & 2 deletions pygsp/filters/meyer.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Meyer(Filter):
"""

def __init__(self, G, Nf=6, scales=None, **kwargs):
def __init__(self, G, Nf=6, scales=None):

if scales is None:
scales = (4./(3 * G.lmax)) * np.power(2., np.arange(Nf-2, -1, -1))
Expand Down Expand Up @@ -90,4 +90,4 @@ def v(x):

return r

super(Meyer, self).__init__(G, g, **kwargs)
super(Meyer, self).__init__(G, g)
4 changes: 2 additions & 2 deletions pygsp/filters/papadakis.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Papadakis(Filter):
>>> G.plot_signal(s, ax=axes[1])
"""
def __init__(self, G, a=0.75, **kwargs):
def __init__(self, G, a=0.75):

g = [lambda x: papadakis(x * (2./G.lmax), a)]
g.append(lambda x: np.real(np.sqrt(1 - (papadakis(x*(2./G.lmax), a)) **
Expand All @@ -61,4 +61,4 @@ def papadakis(val, a):

return y

super(Papadakis, self).__init__(G, g, **kwargs)
super(Papadakis, self).__init__(G, g)
4 changes: 2 additions & 2 deletions pygsp/filters/regular.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Regular(Filter):
>>> G.plot_signal(s, ax=axes[1])
"""
def __init__(self, G, d=3, **kwargs):
def __init__(self, G, d=3):

g = [lambda x: regular(x * (2./G.lmax), d)]
g.append(lambda x: np.real(np.sqrt(1 - (regular(x * (2./G.lmax), d))
Expand All @@ -65,4 +65,4 @@ def regular(val, d):

return np.sin(np.pi / 4.*(1 + output))

super(Regular, self).__init__(G, g, **kwargs)
super(Regular, self).__init__(G, g)
4 changes: 2 additions & 2 deletions pygsp/filters/simoncelli.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Simoncelli(Filter):
"""

def __init__(self, G, a=2./3, **kwargs):
def __init__(self, G, a=2./3):

g = [lambda x: simoncelli(x * (2./G.lmax), a)]
g.append(lambda x: np.real(np.sqrt(1 -
Expand All @@ -63,4 +63,4 @@ def simoncelli(val, a):

return y

super(Simoncelli, self).__init__(G, g, **kwargs)
super(Simoncelli, self).__init__(G, g)
4 changes: 2 additions & 2 deletions pygsp/filters/simpletight.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class SimpleTight(Filter):
"""

def __init__(self, G, Nf=6, scales=None, **kwargs):
def __init__(self, G, Nf=6, scales=None):

def kernel(x, kerneltype):
r"""
Expand Down Expand Up @@ -98,4 +98,4 @@ def h(x):
for i in range(Nf - 1):
g.append(lambda x, i=i: kernel(scales[i] * x, 'wavelet'))

super(SimpleTight, self).__init__(G, g, **kwargs)
super(SimpleTight, self).__init__(G, g)

0 comments on commit 1fbb816

Please sign in to comment.