P_Sparsity.py 3.02 KB
Newer Older
1
from numpy import zeros_like
robin.requadt's avatar
robin.requadt committed
2
import numpy as np
jansen31's avatar
jansen31 committed
3
from .proxoperators import ProxOperator
jansen31's avatar
jansen31 committed
4
5


robin.requadt's avatar
robin.requadt committed
6
class P_Sparsity(ProxOperator):
jansen31's avatar
jansen31 committed
7
8
9
10
    def __init__(self, config):
        """
        Initialization

robin.requadt's avatar
robin.requadt committed
11
12
13
        Parameters
        ----------
        config : dict - Dictionary containing the problem configuration. It must contain the following mapping:
jansen31's avatar
jansen31 committed
14
15
16
        'sparsity_parameter' : int
        """
        self.sparsity_parameter = config['sparsity_parameter']
17
18
        self.ny = config['Ny']

jansen31's avatar
jansen31 committed
19
20
21
22
23
        if 'sparsity_support' in config:
            self.support = config['sparsity_support'].real.astype(np.uint)
        else:
            self.support = 1

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
        if self.sparsity_parameter > 30:
            def value_selection(original, indices, sparsity_parameter):
                idx_for_threshold = divmod(indices[-sparsity_parameter], self.ny)
                threshold_val = abs(original[idx_for_threshold].get())
                return (abs(original) >= threshold_val) * original
        else:
            def value_selection(original, indices, sparsity_parameter):
                out = zeros_like(original)
                hits = indices[-sparsity_parameter:].get()
                hit_idx = [divmod(hit, self.ny) for hit in hits]
                for _idx in hit_idx:
                    out[_idx[0], _idx[1]] = original[_idx[0], _idx[1]]
                return out

        self.value_selection = value_selection
jansen31's avatar
jansen31 committed
39

jansen31's avatar
jansen31 committed
40
41
42
    def work(self, u):
        """
        Parameters
robin.requadt's avatar
robin.requadt committed
43
44
        ----------
        u : array_like - Input
jansen31's avatar
jansen31 committed
45

robin.requadt's avatar
robin.requadt committed
46
47
        Returns
        -------
jansen31's avatar
jansen31 committed
48
49
        p_Sparsity : array_like
        """
jansen31's avatar
jansen31 committed
50
        u *= self.support # apply support
jansen31's avatar
jansen31 committed
51
        p_Sparsity = 0 * u
52
        sorting = np.argsort(abs(u), axis=None)  # gives indices of sorted array in ascending order
jansen31's avatar
jansen31 committed
53
        indices = np.asarray([divmod(sorting[i], self.ny) for i in range(-1 * self.sparsity_parameter, 0)])
54
        p_Sparsity[indices[:, 0], indices[:, 1]] = u[indices[:, 0], indices[:, 1]]
robin.requadt's avatar
robin.requadt committed
55

jansen31's avatar
jansen31 committed
56
        return p_Sparsity
57
58
59
60
61
62
63
64


class P_Sparsity_real(P_Sparsity):
    def __init__(self, config):
        super(P_Sparsity_real, self).__init__(config)

    def work(self, u):
        return super(P_Sparsity_real, self).work(u.real)
65
66
67
68
69


class P_Sparsity_Symmetric(P_Sparsity):
    def __init__(self, config):
        super(P_Sparsity_Symmetric, self).__init__(config=config)
jansen31's avatar
jansen31 committed
70
71
        self.symmetry = config['symmetry_type'] # antisymmetric = -1, symmetric = 1
        self.symmetry_axis = config['symmetry_axis']  # -1 for last, 0 for first, 'both', 'all' or None for full flip
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

    def work(self, u):
        if self.symmetry_axis in ['both', 'all']:
            mirror = np.flip(u, axis=None)
        else:
            mirror = np.flip(u, axis=self.symmetry_axis)
        inp = (u + self.symmetry * mirror) / 2
        out = super(P_Sparsity_Symmetric, self).work(inp)
        return out


class P_Sparsity_Symmetric_real(P_Sparsity_Symmetric):
    def __init__(self, config):
        super(P_Sparsity_Symmetric_real, self).__init__(config=config)

    def work(self, u):
jansen31's avatar
jansen31 committed
88
        return super(P_Sparsity_Symmetric_real, self).work(u.real)