P_M.py 2.12 KB
Newer Older
jansen31's avatar
jansen31 committed
1
from .proxoperators import ProxOperator, magproj
robin.requadt's avatar
robin.requadt committed
2
3
import numpy as np

jansen31's avatar
jansen31 committed
4

robin.requadt's avatar
robin.requadt committed
5
class P_M(ProxOperator):
jansen31's avatar
jansen31 committed
6
7
8
    """
    Projection onto Fourier magnitude constraints
    """
robin.requadt's avatar
robin.requadt committed
9

jansen31's avatar
jansen31 committed
10
11
12
    def __init__(self, config):
        """
        Initialization
robin.requadt's avatar
robin.requadt committed
13
14
15
16
        
        Parameters
        ----------
        config : dict - Dictionary containing the problem configuration. It must contain the following mapping:
jansen31's avatar
jansen31 committed
17
18
        'M' : array_like - nonegative real FOURIER DOMAIN CONSTRAINT
        """
Matthijs's avatar
Matthijs committed
19
20
21
22
        try:
            self.M = config['M']
        except KeyError:
            self.M = config['data']
robin.requadt's avatar
robin.requadt committed
23

jansen31's avatar
jansen31 committed
24
25
    def work(self, u):
        """
robin.requadt's avatar
robin.requadt committed
26
27
28
29
30
31
32
33
34
        Applies the proxoperator P_M
        
        Parameters
        ----------
        u : array_like - function in the physical domain to be projected
        
        Returns
        -------
        array_like - [p_M,phat_M] ,where p_M = the projection IN THE PHYSICAL (time) DOMAIN and phat_M = projection IN THE FOURIER DOMAIN 
jansen31's avatar
jansen31 committed
35
36
        """
        m = self.M
Matthijs's avatar
Matthijs committed
37
        a = np.fft.fft2(u, axes=None)
jansen31's avatar
jansen31 committed
38
        b = magproj(a, m)
Matthijs's avatar
Matthijs committed
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
        return np.fft.ifft2(b, axes=None)


class P_M_masked(P_M):
    """
    Projection onto Fourier magnitude constraints, leaving alone points masked by 'data_zeros'
    """

    def __init__(self, config):
        """
        Initialization

        Parameters
        ----------
        config : dict - Dictionary containing the problem configuration. It must contain the following mapping:
        'M' : array_like - nonegative real FOURIER DOMAIN CONSTRAINT
        'data_zeros': array_like, true for masked points, false for non-masked points (where the measurement can be applied).
        """
        super(P_M_masked, self).__init__(config)
        self.mask = config['data_zeros']

    def work(self, u):
        """
        Applies the proxoperator P_M_masked

        Parameters
        ----------
        u : array_like - function in the physical domain to be projected

        Returns
        -------
        array_like - p_M: the projection IN THE PHYSICAL (time) DOMAIN
        """
        constrained = super(P_M_masked, self).work(u)
        update = np.where(self.mask, u, constrained)
        return update