fft_smoothing_operator.py 1.4 KB
Newer Older
Martin Reinecke's avatar
Martin Reinecke committed
1
2
from .endomorphic_operator import EndomorphicOperator
from .fft_operator import FFTOperator
3
from .diagonal_operator import DiagonalOperator
Martin Reinecke's avatar
Martin Reinecke committed
4
from .. import DomainTuple
5

6

7
class FFTSmoothingOperator(EndomorphicOperator):
8
9
    def __init__(self, domain, sigma, space=None):
        super(FFTSmoothingOperator, self).__init__()
10

11
        dom = DomainTuple.make(domain)
Martin Reinecke's avatar
Martin Reinecke committed
12
        self._sigma = float(sigma)
13
        if space is None:
Martin Reinecke's avatar
Martin Reinecke committed
14
            if len(dom) != 1:
15
16
17
                raise ValueError("need a Field with exactly one domain")
            space = 0
        space = int(space)
Martin Reinecke's avatar
Martin Reinecke committed
18
        if space < 0 or space >= len(dom):
19
20
21
            raise ValueError("space index out of range")
        self._space = space

22
23
24
        self._FFT = FFTOperator(dom, space=space)
        codomain = self._FFT.domain[space].get_default_codomain()
        kernel = codomain.get_k_length_array()
Martin Reinecke's avatar
Martin Reinecke committed
25
        smoother = codomain.get_fft_smoothing_kernel_function(self._sigma)
26
27
28
29
        kernel = smoother(kernel)
        ddom = list(dom)
        ddom[space] = codomain
        self._diag = DiagonalOperator(kernel, ddom, space)
30

31
    def _times(self, x):
Martin Reinecke's avatar
Martin Reinecke committed
32
        if self._sigma == 0:
33
34
            return x.copy()

35
        return self._FFT.adjoint_times(self._diag(self._FFT(x)))
36
37
38

    @property
    def domain(self):
39
        return self._FFT.domain
40
41
42
43
44
45
46
47

    @property
    def self_adjoint(self):
        return True

    @property
    def unitary(self):
        return False