Skip to content

Commit

Permalink
string representation of filters for print
Browse files Browse the repository at this point in the history
  • Loading branch information
mdeff committed Apr 9, 2018
1 parent dc8ba62 commit 9c44c5c
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 12 deletions.
5 changes: 5 additions & 0 deletions pygsp/filters/abspline.py
Expand Up @@ -77,6 +77,8 @@ def kernel_abspline3(x, alpha, beta, t1, t2):

return r

self.lpfactor = lpfactor

lmin = G.lmax / lpfactor

if scales is None:
Expand All @@ -100,3 +102,6 @@ def kernel_abspline3(x, alpha, beta, t1, t2):
g[0] = lambda x: gamma_l * gl(x / lminfac)

super(Abspline, self).__init__(G, g)

def _get_extra_repr(self):
return dict(lpfactor='{:.2f}'.format(self.lpfactor))
7 changes: 7 additions & 0 deletions pygsp/filters/expwin.py
Expand Up @@ -37,6 +37,9 @@ class Expwin(Filter):

def __init__(self, G, band_max=0.2, slope=1):

self.band_max = band_max
self.slope = slope

def fx(x):
# Canary to avoid division by zero and overflow.
y = np.where(x <= 0, -1, x)
Expand All @@ -53,3 +56,7 @@ def ffin(x):
g = [lambda x: ffin(x/band_max/G.lmax)]

super(Expwin, self).__init__(G, g)

def _get_extra_repr(self):
return dict(band_max='{:.2f}'.format(self.band_max),
slope='{:.2f}'.format(self.slope))
18 changes: 16 additions & 2 deletions pygsp/filters/filter.py
Expand Up @@ -58,7 +58,21 @@ def __init__(self, G, kernels):
kernels = [kernels]
self._kernels = kernels

self.Nf = len(kernels)
# Only used by subclasses to instantiate a single filterbank.
self.n_features_in, self.n_features_out = (1, len(kernels))
self.n_filters = self.n_features_in * self.n_features_out
self.Nf = self.n_filters # TODO: kept for backward compatibility only.

def _get_extra_repr(self):
return dict()

def __repr__(self):
attrs = {'in': self.n_features_in, 'out': self.n_features_out}
attrs.update(self._get_extra_repr())
s = ''
for key, value in attrs.items():
s += '{}={}, '.format(key, value)
return '{}({})'.format(self.__class__.__name__, s[:-2])

def evaluate(self, x):
r"""Evaluate the kernels at given frequencies.
Expand Down Expand Up @@ -497,7 +511,7 @@ def can_dual_func(g, n, x):

return Filter(self.G, kernels)

def plot(self, n=500, eigenvalues=None, sum=None, title='', save=None,
def plot(self, n=500, eigenvalues=None, sum=None, title=None, save=None,
ax=None, **kwargs):
r"""Docstring overloaded at import time."""
from pygsp.plotting import _plot_filter
Expand Down
6 changes: 6 additions & 0 deletions pygsp/filters/heat.py
Expand Up @@ -68,6 +68,9 @@ def __init__(self, G, tau=10, normalize=False):
except TypeError:
tau = [tau]

self.tau = tau
self.normalize = normalize

def kernel(x, t):
return np.exp(-t * x / G.lmax)

Expand All @@ -78,3 +81,6 @@ def kernel(x, t):

super(Heat, self).__init__(G, kernels)

def _get_extra_repr(self):
tau = '[' + ', '.join('{:.2f}'.format(t) for t in self.tau) + ']'
return dict(tau=tau, normalize=self.normalize)
5 changes: 5 additions & 0 deletions pygsp/filters/held.py
Expand Up @@ -47,6 +47,8 @@ class Held(Filter):

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

self.a = a

kernels = [lambda x: held(x * (2./G.lmax), a)]
def dual(x):
y = held(x * (2./G.lmax), a)
Expand All @@ -70,3 +72,6 @@ def held(val, a):
return y

super(Held, self).__init__(G, kernels)

def _get_extra_repr(self):
return dict(a='{:.2f}'.format(self.a))
5 changes: 5 additions & 0 deletions pygsp/filters/itersine.py
Expand Up @@ -40,6 +40,8 @@ class Itersine(Filter):

def __init__(self, G, Nf=6, overlap=2):

self.overlap = overlap

scales = G.lmax / (Nf - overlap + 1) * overlap

def kernel(x):
Expand All @@ -57,3 +59,6 @@ def kernel_centered(x, i=i):
kernels.append(kernel_centered)

super(Itersine, self).__init__(G, kernels)

def _get_extra_repr(self):
return dict(overlap='{:.2f}'.format(self.overlap))
8 changes: 8 additions & 0 deletions pygsp/filters/mexicanhat.py
Expand Up @@ -57,10 +57,14 @@ class MexicanHat(Filter):

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

self.lpfactor = lpfactor
self.normalize = normalize

lmin = G.lmax / lpfactor

if scales is None:
scales = utils.compute_log_scales(lmin, G.lmax, Nf-1)
self.scales = scales

if len(scales) != Nf - 1:
raise ValueError('len(scales) should be Nf-1.')
Expand All @@ -82,3 +86,7 @@ def kernel(x, i=i):
kernels.append(kernel)

super(MexicanHat, self).__init__(G, kernels)

def _get_extra_repr(self):
return dict(lpfactor='{:.2f}'.format(self.lpfactor),
normalize=self.normalize)
1 change: 1 addition & 0 deletions pygsp/filters/meyer.py
Expand Up @@ -46,6 +46,7 @@ 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))
self.scales = scales

if len(scales) != Nf - 1:
raise ValueError('len(scales) should be Nf-1.')
Expand Down
5 changes: 5 additions & 0 deletions pygsp/filters/papadakis.py
Expand Up @@ -43,6 +43,8 @@ class Papadakis(Filter):

def __init__(self, G, a=0.75):

self.a = a

kernels = [lambda x: papadakis(x * (2./G.lmax), a)]
def dual(x):
y = papadakis(x * (2./G.lmax), a)
Expand All @@ -65,3 +67,6 @@ def papadakis(val, a):
return y

super(Papadakis, self).__init__(G, kernels)

def _get_extra_repr(self):
return dict(a='{:.2f}'.format(self.a))
2 changes: 2 additions & 0 deletions pygsp/filters/regular.py
Expand Up @@ -53,6 +53,8 @@ class Regular(Filter):

def __init__(self, G, degree=3):

self.degree = degree

kernels = [lambda x: regular(x * (2/G.lmax), degree)]
def dual(x):
y = regular(x * (2/G.lmax), degree)
Expand Down
5 changes: 5 additions & 0 deletions pygsp/filters/simoncelli.py
Expand Up @@ -45,6 +45,8 @@ class Simoncelli(Filter):

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

self.a = a

kernels = [lambda x: simoncelli(x * (2/G.lmax), a)]
def dual(x):
y = simoncelli(x * (2/G.lmax), a)
Expand All @@ -67,3 +69,6 @@ def simoncelli(val, a):
return y

super(Simoncelli, self).__init__(G, kernels)

def _get_extra_repr(self):
return dict(a='{:.2f}'.format(self.a))
1 change: 1 addition & 0 deletions pygsp/filters/simpletight.py
Expand Up @@ -89,6 +89,7 @@ def h(x):

if not scales:
scales = (1./(2.*G.lmax) * np.power(2, np.arange(Nf-2, -1, -1)))
self.scales = scales

if len(scales) != Nf - 1:
raise ValueError('len(scales) should be Nf-1.')
Expand Down
28 changes: 18 additions & 10 deletions pygsp/plotting.py
Expand Up @@ -316,8 +316,7 @@ def _qtg_plot_graph(G, edges, vertex_size, title):
_qtg_widgets.append(widget)


@_plt_handle_figure
def _plot_filter(filters, n, eigenvalues, sum, ax, **kwargs):
def _plot_filter(filters, n, eigenvalues, sum, title, save, ax, **kwargs):
r"""Plot the spectral response of a filter bank, a set of graph filters.
Parameters
Expand Down Expand Up @@ -357,18 +356,27 @@ def _plot_filter(filters, n, eigenvalues, sum, ax, **kwargs):
"""

G = filters.G

if eigenvalues is None:
eigenvalues = hasattr(G, '_e')
eigenvalues = hasattr(filters.G, '_e')

if sum is None:
sum = filters.Nf > 1
sum = filters.n_filters > 1

if title is None:
title = repr(filters)

_plt_plot_filter(filters, n=n, eigenvalues=eigenvalues, sum=sum,
title=title, save=save, ax=ax, **kwargs)


@_plt_handle_figure
def _plt_plot_filter(filters, n, eigenvalues, sum, ax, **kwargs):

if eigenvalues:
for e in G.e:
for e in filters.G.e:
ax.axvline(x=e, color=[0.9]*3, linewidth=1)

x = np.linspace(0, G.lmax, n)
x = np.linspace(0, filters.G.lmax, n)
y = filters.evaluate(x).T
ax.plot(x, y, **kwargs)

Expand All @@ -377,8 +385,8 @@ def _plot_filter(filters, n, eigenvalues, sum, ax, **kwargs):
if sum:
ax.plot(x, np.sum(y**2, 1), 'k', **kwargs)

ax.set_xlabel("$\lambda$: laplacian's eigenvalues / graph frequencies")
ax.set_ylabel('$\hat{g}(\lambda)$: filter response')
ax.set_xlabel(r"$\lambda$: laplacian's eigenvalues / graph frequencies")
ax.set_ylabel(r'$\hat{g}(\lambda)$: filter response')


def _plot_signal(G, signal, edges, vertex_size, highlight, colorbar,
Expand Down

0 comments on commit 9c44c5c

Please sign in to comment.