Skip to content

Commit 2e63e58

Browse files
committed
convert compute_frame and localize to filter
1 parent 849f949 commit 2e63e58

14 files changed

+28
-43
lines changed

pygsp/filters/abspline.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ class Abspline(Filter):
3434
>>> G.set_coordinates('line1D')
3535
>>> g = filters.Abspline(G)
3636
>>> s = g.localize(G.N // 2)
37-
>>> s = utils.vec2mat(s, g.Nf)
3837
>>> fig, axes = plt.subplots(1, 2)
3938
>>> g.plot(ax=axes[0])
4039
>>> G.plot_signal(s, ax=axes[1])

pygsp/filters/expwin.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class Expwin(Filter):
2727
>>> G.set_coordinates('line1D')
2828
>>> g = filters.Expwin(G)
2929
>>> s = g.localize(G.N // 2)
30-
>>> s = utils.vec2mat(s, g.Nf)
3130
>>> fig, axes = plt.subplots(1, 2)
3231
>>> g.plot(ax=axes[0])
3332
>>> G.plot_signal(s, ax=axes[1])

pygsp/filters/filter.py

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,9 @@ def localize(self, i, **kwargs):
528528
529529
Examples
530530
--------
531-
Visualize heat diffusion on a grid.
531+
Visualize heat diffusion on a grid by localizing the heat kernel.
532532
533+
>>> import matplotlib
533534
>>> N = 20
534535
>>> G = graphs.Grid2d(N)
535536
>>> G.estimate_lmax()
@@ -540,7 +541,7 @@ def localize(self, i, **kwargs):
540541
"""
541542
s = np.zeros(self.G.N)
542543
s[i] = 1
543-
return np.sqrt(self.G.N) * self.analysis(s, **kwargs)
544+
return np.sqrt(self.G.N) * self.filter(s, **kwargs)
544545

545546
def approx(self, m, N):
546547
r"""
@@ -662,37 +663,31 @@ def compute_frame(self, **kwargs):
662663
663664
Examples
664665
--------
665-
>>>
666-
>>> G = graphs.Logo()
666+
Filtering signals as a matrix multiplication.
667+
668+
>>> G = graphs.Sensor(N=1000, seed=42)
667669
>>> G.estimate_lmax()
670+
>>> f = filters.MexicanHat(G, Nf=6)
671+
>>> s = np.random.uniform(size=G.N)
668672
>>>
669-
>>> f = filters.MexicanHat(G)
670673
>>> frame = f.compute_frame()
671-
>>> print('{} nodes, matrix is {} x {}'.format(G.N, *frame.shape))
672-
1130 nodes, matrix is 1130 x 6780
673-
>>>
674-
>>> s = np.random.uniform(size=G.N)
675-
>>> c1 = frame.T.dot(s)
676-
>>> c2 = f.analysis(s)
674+
>>> frame.shape
675+
(1000, 1000, 6)
676+
>>> frame = frame.reshape(G.N, -1).T
677+
>>> s1 = np.dot(frame, s)
678+
>>> s1 = s1.reshape(G.N, 1, -1)
677679
>>>
678-
>>> np.linalg.norm(c1 - c2) < 1e-10
680+
>>> s2 = f.filter(s)
681+
>>> np.all((s1 - s2) < 1e-10)
679682
True
680683
681684
"""
682-
683-
N = self.G.N
684-
685-
if N > 2000:
685+
if self.G.N > 2000:
686686
_logger.warning('Creating a big matrix, you can use other means.')
687687

688-
Ft = self.analysis(np.identity(N), **kwargs)
689-
F = np.empty(Ft.T.shape)
690-
tmpN = np.arange(N, dtype=int)
691-
692-
for i in range(self.Nf):
693-
F[:, N * i + tmpN] = Ft[N * i + tmpN]
694-
695-
return F
688+
# Filter one delta per vertex.
689+
s = np.identity(self.G.N)
690+
return self.filter(s, **kwargs)
696691

697692
def can_dual(self):
698693
r"""

pygsp/filters/halfcosine.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ class HalfCosine(Filter):
2525
>>> G.set_coordinates('line1D')
2626
>>> g = filters.HalfCosine(G)
2727
>>> s = g.localize(G.N // 2)
28-
>>> s = utils.vec2mat(s, g.Nf)
2928
>>> fig, axes = plt.subplots(1, 2)
3029
>>> g.plot(ax=axes[0])
3130
>>> G.plot_signal(s, ax=axes[1])

pygsp/filters/heat.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ class Heat(Filter):
5555
>>> G.set_coordinates('line1D')
5656
>>> g = filters.Heat(G, tau=[5, 10, 100])
5757
>>> s = g.localize(G.N // 2)
58-
>>> s = utils.vec2mat(s, g.Nf)
5958
>>> fig, axes = plt.subplots(1, 2)
6059
>>> g.plot(ax=axes[0])
6160
>>> G.plot_signal(s, ax=axes[1])

pygsp/filters/held.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ class Held(Filter):
3939
>>> G.set_coordinates('line1D')
4040
>>> g = filters.Held(G)
4141
>>> s = g.localize(G.N // 2)
42-
>>> s = utils.vec2mat(s, g.Nf)
4342
>>> fig, axes = plt.subplots(1, 2)
4443
>>> g.plot(ax=axes[0])
4544
>>> G.plot_signal(s, ax=axes[1])

pygsp/filters/itersine.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ class Itersine(Filter):
3030
>>> G.set_coordinates('line1D')
3131
>>> g = filters.HalfCosine(G)
3232
>>> s = g.localize(G.N // 2)
33-
>>> s = utils.vec2mat(s, g.Nf)
3433
>>> fig, axes = plt.subplots(1, 2)
3534
>>> g.plot(ax=axes[0])
3635
>>> G.plot_signal(s, ax=axes[1])

pygsp/filters/mexicanhat.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ class MexicanHat(Filter):
4949
>>> G.set_coordinates('line1D')
5050
>>> g = filters.MexicanHat(G)
5151
>>> s = g.localize(G.N // 2)
52-
>>> s = utils.vec2mat(s, g.Nf)
5352
>>> fig, axes = plt.subplots(1, 2)
5453
>>> g.plot(ax=axes[0])
5554
>>> G.plot_signal(s, ax=axes[1])

pygsp/filters/meyer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ class Meyer(Filter):
3636
>>> G.set_coordinates('line1D')
3737
>>> g = filters.Meyer(G)
3838
>>> s = g.localize(G.N // 2)
39-
>>> s = utils.vec2mat(s, g.Nf)
4039
>>> fig, axes = plt.subplots(1, 2)
4140
>>> g.plot(ax=axes[0])
4241
>>> G.plot_signal(s, ax=axes[1])

pygsp/filters/papadakis.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ class Papadakis(Filter):
3535
>>> G.set_coordinates('line1D')
3636
>>> g = filters.Papadakis(G)
3737
>>> s = g.localize(G.N // 2)
38-
>>> s = utils.vec2mat(s, g.Nf)
3938
>>> fig, axes = plt.subplots(1, 2)
4039
>>> g.plot(ax=axes[0])
4140
>>> G.plot_signal(s, ax=axes[1])

pygsp/filters/regular.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ class Regular(Filter):
4343
>>> G.set_coordinates('line1D')
4444
>>> g = filters.Regular(G)
4545
>>> s = g.localize(G.N // 2)
46-
>>> s = utils.vec2mat(s, g.Nf)
4746
>>> fig, axes = plt.subplots(1, 2)
4847
>>> g.plot(ax=axes[0])
4948
>>> G.plot_signal(s, ax=axes[1])

pygsp/filters/simoncelli.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ class Simoncelli(Filter):
3535
>>> G.set_coordinates('line1D')
3636
>>> g = filters.Simoncelli(G)
3737
>>> s = g.localize(G.N // 2)
38-
>>> s = utils.vec2mat(s, g.Nf)
3938
>>> fig, axes = plt.subplots(1, 2)
4039
>>> g.plot(ax=axes[0])
4140
>>> G.plot_signal(s, ax=axes[1])

pygsp/filters/simpletight.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ class SimpleTight(Filter):
3636
>>> G.set_coordinates('line1D')
3737
>>> g = filters.SimpleTight(G)
3838
>>> s = g.localize(G.N // 2)
39-
>>> s = utils.vec2mat(s, g.Nf)
4039
>>> fig, axes = plt.subplots(1, 2)
4140
>>> g.plot(ax=axes[0])
4241
>>> G.plot_signal(s, ax=axes[1])

pygsp/tests/test_filters.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import numpy as np
1111

12-
from pygsp import graphs, filters
12+
from pygsp import graphs, filters, utils
1313

1414

1515
class TestCase(unittest.TestCase):
@@ -73,11 +73,13 @@ def _test_methods(self, f, tight):
7373
self._signal, method='lanczos')
7474

7575
if f.Nf < 10:
76-
F = f.compute_frame(method='chebyshev')
77-
c_frame = F.T.dot(self._signal)
76+
F = f.compute_frame(method='chebyshev').reshape(self._G.N, -1)
77+
c_frame = F.T.dot(self._signal).reshape(self._G.N, 1, -1)
78+
c_cheby = utils.vec2mat(c_cheby, f.Nf).reshape((self._G.N, 1, -1))
7879
np.testing.assert_allclose(c_frame, c_cheby)
79-
F = f.compute_frame(method='exact')
80-
c_frame = F.T.dot(self._signal)
80+
F = f.compute_frame(method='exact').reshape(self._G.N, -1)
81+
c_frame = F.T.dot(self._signal).reshape(self._G.N, 1, -1)
82+
c_exact = utils.vec2mat(c_exact, f.Nf).reshape((self._G.N, 1, -1))
8183
np.testing.assert_allclose(c_frame, c_exact)
8284

8385
self._test_synthesis(f)
@@ -107,11 +109,11 @@ def test_localize(self):
107109
# Should be equal to a row / column of the filtering operator.
108110
gL = G.U.dot(np.diag(g.evaluate(G.e)[0]).dot(G.U.T))
109111
s2 = np.sqrt(G.N) * gL[NODE, :]
110-
np.testing.assert_allclose(s1, s2)
112+
np.testing.assert_allclose(s1.squeeze(), s2)
111113

112114
# That is actually a row / column of the analysis operator.
113115
F = g.compute_frame(method='exact')
114-
np.testing.assert_allclose(F, gL)
116+
np.testing.assert_allclose(F.squeeze(), gL)
115117

116118
def test_custom_filter(self):
117119
def kernel(x):

0 commit comments

Comments
 (0)