Beispiel #1
0
    def _prox(self, x, T):
        # Time counter
        t_init = time()

        tol = self.tol
        maxit = self.maxit

        # TODO implement test_gamma
        # Initialization
        sol = x

        if self.dim == 1:
            r = op.grad(x * 0, dim=self.dim, **self.kwargs)
            rr = deepcopy(r)
        elif self.dim == 2:
            r, s = op.grad(x * 0, dim=self.dim, **self.kwargs)
            rr, ss = deepcopy(r), deepcopy(s)
        elif self.dim == 3:
            r, s, k = op.grad(x * 0, dim=self.dim, **self.kwargs)
            rr, ss, kk = deepcopy(r), deepcopy(s), deepcopy(k)
        elif self.dim == 4:
            r, s, k, u = op.grad(x * 0, dim=self.dim, **self.kwargs)
            rr, ss, kk, uu = deepcopy(r), deepcopy(s), deepcopy(k), deepcopy(u)

        if self.dim >= 1:
            pold = r
        if self.dim >= 2:
            qold = s
        if self.dim >= 3:
            kold = k
        if self.dim >= 4:
            uold = u

        told, prev_obj = 1., 0.

        # Initialization for weights
        if self.dim >= 1:
            try:
                wx = self.kwargs["wx"]
            except (KeyError, TypeError):
                wx = 1.
        if self.dim >= 2:
            try:
                wy = self.kwargs["wy"]
            except (KeyError, TypeError):
                wy = 1.
        if self.dim >= 3:
            try:
                wz = self.kwargs["wz"]
            except (KeyError, TypeError):
                wz = 1.
        if self.dim >= 4:
            try:
                wt = self.kwargs["wt"]
            except (KeyError, TypeError):
                wt = 1.

        if self.dim == 1:
            mt = wx
        elif self.dim == 2:
            mt = np.maximum(wx, wy)
        elif self.dim == 3:
            mt = np.maximum(wx, np.maximum(wy, wz))
        elif self.dim == 4:
            mt = np.maximum(np.maximum(wx, wy), np.maximum(wz, wt))

        if self.verbosity in ['LOW', 'HIGH', 'ALL']:
            print("Proximal TV Operator")

        iter = 0
        while iter <= maxit:
            # Current Solution
            if self.dim == 1:
                sol = x - T * op.div(rr, **self.kwargs)
            elif self.dim == 2:
                sol = x - T * op.div(rr, ss, **self.kwargs)
            elif self.dim == 3:
                sol = x - T * op.div(rr, ss, kk, **self.kwargs)
            elif self.dim == 4:
                sol = x - T * op.div(rr, ss, kk, uu, **self.kwargs)

            #  Objective function value
            obj = 0.5 * np.power(np.linalg.norm(x[:] - sol[:]), 2) + \
                T * np.sum(self._eval(sol), axis=0)
            rel_obj = np.abs(obj - prev_obj) / obj
            prev_obj = obj

            if self.verbosity in ['HIGH', 'ALL']:
                print("Iter: ", iter, " obj = ", obj, " rel_obj = ", rel_obj)

            # Stopping criterion
            if rel_obj < tol:
                crit = "TOL_EPS"
                break

            #  Update divergence vectors and project
            if self.dim == 1:
                dx = op.grad(sol, dim=self.dim, **self.kwargs)
                r -= 1. / (4 * T * mt**2) * dx
                weights = np.maximum(1, np.abs(r))

            elif self.dim == 2:
                dx, dy = op.grad(sol, dim=self.dim, **self.kwargs)
                r -= (1. / (8. * T * mt**2.)) * dx
                s -= (1. / (8. * T * mt**2.)) * dy
                weights = np.maximum(
                    1,
                    np.sqrt(np.power(np.abs(r), 2) + np.power(np.abs(s), 2)))

            elif self.dim == 3:
                dx, dy, dz = op.grad(sol, dim=self.dim, **self.kwargs)
                r -= 1. / (12. * T * mt**2) * dx
                s -= 1. / (12. * T * mt**2) * dy
                k -= 1. / (12. * T * mt**2) * dz
                weights = np.maximum(
                    1,
                    np.sqrt(
                        np.power(np.abs(r), 2) + np.power(np.abs(s), 2) +
                        np.power(np.abs(k), 2)))

            elif self.dim == 4:
                dx, dy, dz, dt = op.grad(sol, dim=self.dim, **self.kwargs)
                r -= 1. / (16 * T * mt**2) * dx
                s -= 1. / (16 * T * mt**2) * dy
                k -= 1. / (16 * T * mt**2) * dz
                u -= 1. / (16 * T * mt**2) * dt
                weights = np.maximum(
                    1,
                    np.sqrt(
                        np.power(np.abs(r), 2) + np.power(np.abs(s), 2) +
                        np.power(np.abs(k), 2) + np.power(np.abs(u), 2)))

            # FISTA update
            t = (1 + np.sqrt(4 * told**2)) / 2.

            if self.dim >= 1:
                p = r / weights
                r = p + (told - 1) / t * (p - pold)
                pold = p
                rr = deepcopy(r)

            if self.dim >= 2:
                q = s / weights
                s = q + (told - 1) / t * (q - qold)
                ss = deepcopy(s)
                qold = q

            if self.dim >= 3:
                o = k / weights
                k = o + (told - 1) / t * (o - kold)
                kk = deepcopy(k)
                kold = o

            if self.dim >= 4:
                m = u / weights
                u = m + (told - 1) / t * (m - uold)
                uu = deepcopy(u)
                uold = m

            told = t
            iter += 1

        try:
            type(crit) == str
        except NameError:
            crit = "MAX_IT"

        t_end = time()
        exec_time = t_end - t_init

        if self.verbosity in ['HIGH', 'ALL']:
            print("Prox_TV: obj = {0}, rel_obj = {1}, {2}, iter = {3}".format(
                obj, rel_obj, crit, iter))
            print("exec_time = ", exec_time)
        return sol
Beispiel #2
0
    def test_div(self):
        # Sanity check
        self.assertRaises(ValueError, operators.div)

        # Divergence tests
        # test with 1dim matrices
        dx = np.array([1, 2, 3, 4, 5])

        # test without weights
        nptest.assert_array_equal(np.array([1, 1, 1, 1, -4]),
                                  operators.div(dx))

        # test with weights
        weights = {'wx': 2, 'wy': 3, 'wz': 4, 'wt': 2}
        nptest.assert_array_equal(np.array([2, 2, 2, 2, -8]),
                                  operators.div(dx, **weights))

        # test with 2dim matrices
        dx = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
        dy = np.array([[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]])

        # test without weights
        x_mat = np.array([[1, 2, 3, 4], [4, 4, 4, 4], [-5, -6, -7, -8]])
        xy_mat = np.array([[14, 3, 4, -11], [21, 5, 5, -15], [16, -5, -6,
                                                              -31]])
        nptest.assert_array_equal(x_mat, operators.div(dx))
        nptest.assert_array_equal(xy_mat, operators.div(dx, dy))

        # test with weights
        xy_mat_w = np.array([[41, 7, 9, -37], [59, 11, 11, -49],
                             [53, -9, -11, -85]])
        nptest.assert_array_equal(xy_mat_w, operators.div(dx, dy, **weights))

        # test with 3dim matrices (3x3x3)
        dx = np.array([[[1, 10, 19], [2, 11, 20], [3, 12, 21]],
                       [[4, 13, 22], [5, 14, 23], [6, 15, 24]],
                       [[7, 16, 25], [8, 17, 26], [9, 18, 27]]])
        dy = np.array([[[1, 10, 19], [2, 11, 20], [3, 12, 21]],
                       [[4, 13, 22], [5, 14, 23], [6, 15, 24]],
                       [[7, 16, 25], [8, 17, 26], [9, 18, 27]]])
        dz = np.array([[[1, 10, 19], [2, 11, 20], [3, 12, 21]],
                       [[4, 13, 22], [5, 14, 23], [6, 15, 24]],
                       [[7, 16, 25], [8, 17, 26], [9, 18, 27]]])
        # test without weights
        x_mat = np.array([[[1, 10, 19], [2, 11, 20], [3, 12, 21]],
                          [[3, 3, 3], [3, 3, 3], [3, 3, 3]],
                          [[-4, -13, -22], [-5, -14, -23], [-6, -15, -24]]])
        xy_mat = np.array([[[2, 20, 38], [3, 12, 21], [1, 1, 1]],
                           [[7, 16, 25], [4, 4, 4], [-2, -11, -20]],
                           [[3, 3, 3], [-4, -13, -22], [-14, -32, -50]]])
        xyz_mat = np.array([[[3, 29, 28], [5, 21, 10], [4, 10, -11]],
                            [[11, 25, 12], [9, 13, -10], [4, -2, -35]],
                            [[10, 12, -13], [4, -4, -39], [-5, -23, -68]]])
        xyzt_mat = np.array([[[9, 86, 55], [15, 61, -1], [12, 27, -66]],
                             [[34, 81, 20], [29, 45, -47], [15, 0, -123]],
                             [[41, 58, -33], [25, 11, -111], [0, -45, -198]]])
        nptest.assert_array_equal(x_mat, operators.div(dx))
        nptest.assert_array_equal(xy_mat, operators.div(dx, dy))
        nptest.assert_array_equal(xyz_mat, operators.div(dx, dy, dz))
        # test with weights
        xyz_mat_w = np.array([[[9, 86, 55], [15, 61, -1], [12, 27, -66]],
                              [[34, 81, 20], [29, 45, -47], [15, 0, -123]],
                              [[41, 58, -33], [25, 11, -111], [0, -45, -198]]])
        nptest.assert_array_equal(xyz_mat_w,
                                  operators.div(dx, dy, dz, **weights))

        # test with 4d matrices (3x3x3x3)
        dx = np.array([[[[1, 28, 55], [10, 37, 64], [19, 46, 73]],
                        [[2, 29, 56], [11, 38, 65], [20, 47, 74]],
                        [[3, 30, 57], [12, 39, 66], [21, 48, 75]]],
                       [[[4, 31, 58], [13, 40, 67], [22, 49, 76]],
                        [[5, 32, 59], [14, 41, 68], [23, 50, 77]],
                        [[6, 33, 60], [15, 42, 69], [24, 51, 78]]],
                       [[[7, 34, 61], [16, 43, 70], [25, 52, 79]],
                        [[8, 35, 62], [17, 44, 71], [26, 53, 80]],
                        [[9, 36, 63], [18, 45, 72], [27, 54, 81]]]])
        dy = np.array([[[[1, 28, 55], [10, 37, 64], [19, 46, 73]],
                        [[2, 29, 56], [11, 38, 65], [20, 47, 74]],
                        [[3, 30, 57], [12, 39, 66], [21, 48, 75]]],
                       [[[4, 31, 58], [13, 40, 67], [22, 49, 76]],
                        [[5, 32, 59], [14, 41, 68], [23, 50, 77]],
                        [[6, 33, 60], [15, 42, 69], [24, 51, 78]]],
                       [[[7, 34, 61], [16, 43, 70], [25, 52, 79]],
                        [[8, 35, 62], [17, 44, 71], [26, 53, 80]],
                        [[9, 36, 63], [18, 45, 72], [27, 54, 81]]]])
        dz = np.array([[[[1, 28, 55], [10, 37, 64], [19, 46, 73]],
                        [[2, 29, 56], [11, 38, 65], [20, 47, 74]],
                        [[3, 30, 57], [12, 39, 66], [21, 48, 75]]],
                       [[[4, 31, 58], [13, 40, 67], [22, 49, 76]],
                        [[5, 32, 59], [14, 41, 68], [23, 50, 77]],
                        [[6, 33, 60], [15, 42, 69], [24, 51, 78]]],
                       [[[7, 34, 61], [16, 43, 70], [25, 52, 79]],
                        [[8, 35, 62], [17, 44, 71], [26, 53, 80]],
                        [[9, 36, 63], [18, 45, 72], [27, 54, 81]]]])
        dt = np.array([[[[1, 28, 55], [10, 37, 64], [19, 46, 73]],
                        [[2, 29, 56], [11, 38, 65], [20, 47, 74]],
                        [[3, 30, 57], [12, 39, 66], [21, 48, 75]]],
                       [[[4, 31, 58], [13, 40, 67], [22, 49, 76]],
                        [[5, 32, 59], [14, 41, 68], [23, 50, 77]],
                        [[6, 33, 60], [15, 42, 69], [24, 51, 78]]],
                       [[[7, 34, 61], [16, 43, 70], [25, 52, 79]],
                        [[8, 35, 62], [17, 44, 71], [26, 53, 80]],
                        [[9, 36, 63], [18, 45, 72], [27, 54, 81]]]])
        # test without weights
        x_mat = np.array([[[[1, 28, 55], [10, 37, 64], [19, 46, 73]],
                           [[2, 29, 56], [11, 38, 65], [20, 47, 74]],
                           [[3, 30, 57], [12, 39, 66], [21, 48, 75]]],
                          [[[3, 3, 3], [3, 3, 3], [3, 3, 3]],
                           [[3, 3, 3], [3, 3, 3], [3, 3, 3]],
                           [[3, 3, 3], [3, 3, 3], [3, 3, 3]]],
                          [[[-4, -31, -58], [-13, -40, -67], [-22, -49, -76]],
                           [[-5, -32, -59], [-14, -41, -68], [-23, -50, -77]],
                           [[-6, -33, -60], [-15, -42, -69], [-24, -51,
                                                              -78]]]])
        xy_mat = np.array([[[[2, 56, 110], [20, 74, 128], [38, 92, 146]],
                            [[3, 30, 57], [12, 39, 66], [21, 48, 75]],
                            [[1, 1, 1], [1, 1, 1], [1, 1, 1]]],
                           [[[7, 34, 61], [16, 43, 70], [25, 52, 79]],
                            [[4, 4, 4], [4, 4, 4], [4, 4, 4]],
                            [[-2, -29, -56], [-11, -38, -65], [-20, -47,
                                                               -74]]],
                           [[[3, 3, 3], [3, 3, 3], [3, 3, 3]],
                            [[-4, -31, -58], [-13, -40, -67], [-22, -49, -76]],
                            [[-14, -68, -122], [-32, -86, -140],
                             [-50, -104, -158]]]])
        xyz_mat = np.array([[[[3, 84, 165], [29, 83, 137], [28, 55, 82]],
                             [[5, 59, 113], [21, 48, 75], [10, 10, 10]],
                             [[4, 31, 58], [10, 10, 10], [-11, -38, -65]]],
                            [[[11, 65, 119], [25, 52, 79], [12, 12, 12]],
                             [[9, 36, 63], [13, 13, 13], [-10, -37, -64]],
                             [[4, 4, 4], [-2, -29, -56], [-35, -89, -143]]],
                            [[[10, 37, 64], [12, 12, 12], [-13, -40, -67]],
                             [[4, 4, 4], [-4, -31, -58], [-39, -93, -147]],
                             [[-5, -32, -59], [-23, -77, -131],
                              [-68, -149, -230]]]])
        xyzt_mat = np.array([[[[4, 111, 137], [39, 110, 100], [47, 82, 36]],
                              [[7, 86, 84], [32, 75, 37], [30, 37, -37]],
                              [[7, 58, 28], [22, 37, -29], [10, -11, -113]]],
                             [[[15, 92, 88], [38, 79, 39], [34, 39, -37]],
                              [[14, 63, 31], [27, 40, -28], [13, -10, -114]],
                              [[10, 31, -29], [13, -2, -98], [-11, -62,
                                                              -194]]],
                             [[[17, 64, 30], [28, 39, -31], [12, -13, -119]],
                              [[12, 31, -31], [13, -4, -102], [-13, -66,
                                                               -200]],
                              [[4, -5, -95], [-5, -50, -176],
                               [-41, -122, -284]]]])
        nptest.assert_array_equal(x_mat, operators.div(dx))
        nptest.assert_array_equal(xy_mat, operators.div(dx, dy))
        nptest.assert_array_equal(xyz_mat, operators.div(dx, dy, dz))
        nptest.assert_array_equal(xyzt_mat, operators.div(dx, dy, dz, dt))
        # test with weights
        xyzt_mat_w = np.array([[[[11, 306, 439], [106, 275, 282],
                                 [93, 136, 17]],
                                [[19, 231, 281], [83, 169, 93], [39, -1,
                                                                 -203]],
                                [[18, 147, 114], [51, 54, -105],
                                 [-24, -147, -432]]],
                               [[[42, 277, 350], [107, 216, 163],
                                 [64, 47, -132]],
                                [[39, 191, 181], [73, 99, -37],
                                 [-1, -101, -363]],
                                [[27, 96, 3], [30, -27, -246],
                                 [-75, -258, -603]]],
                               [[[55, 230, 243], [90, 139, 26],
                                 [17, -60, -299]],
                                [[41, 133, 63], [45, 11, -185],
                                 [-59, -219, -541]],
                                [[18, 27, -126], [-9, -126, -405],
                                 [-144, -387, -792]]]])
        nptest.assert_array_equal(xyzt_mat_w,
                                  operators.div(dx, dy, dz, dt, **weights))
Beispiel #3
0
    def _prox(self, x, T):
        # Time counter
        t_init = time()

        tol = self.tol
        maxit = self.maxit

        # TODO implement test_gamma
        # Initialization
        sol = x

        if self.dim == 1:
            r = op.grad(x * 0, dim=self.dim, **self.kwargs)
            rr = deepcopy(r)
        elif self.dim == 2:
            r, s = op.grad(x * 0, dim=self.dim, **self.kwargs)
            rr, ss = deepcopy(r), deepcopy(s)
        elif self.dim == 3:
            r, s, k = op.grad(x * 0, dim=self.dim, **self.kwargs)
            rr, ss, kk = deepcopy(r), deepcopy(s), deepcopy(k)
        elif self.dim == 4:
            r, s, k, u = op.grad(x * 0, dim=self.dim, **self.kwargs)
            rr, ss, kk, uu = deepcopy(r), deepcopy(s), deepcopy(k), deepcopy(u)

        if self.dim >= 1:
            pold = r
        if self.dim >= 2:
            qold = s
        if self.dim >= 3:
            kold = k
        if self.dim >= 4:
            uold = u

        told, prev_obj = 1., 0.

        # Initialization for weights
        if self.dim >= 1:
            try:
                wx = self.kwargs["wx"]
            except (KeyError, TypeError):
                wx = 1.
        if self.dim >= 2:
            try:
                wy = self.kwargs["wy"]
            except (KeyError, TypeError):
                wy = 1.
        if self.dim >= 3:
            try:
                wz = self.kwargs["wz"]
            except (KeyError, TypeError):
                wz = 1.
        if self.dim >= 4:
            try:
                wt = self.kwargs["wt"]
            except (KeyError, TypeError):
                wt = 1.

        if self.dim == 1:
            mt = wx
        elif self.dim == 2:
            mt = np.maximum(wx, wy)
        elif self.dim == 3:
            mt = np.maximum(wx, np.maximum(wy, wz))
        elif self.dim == 4:
            mt = np.maximum(np.maximum(wx, wy), np.maximum(wz, wt))

        if self.verbosity in ['LOW', 'HIGH', 'ALL']:
            print("Proximal TV Operator")

        iter = 0
        while iter <= maxit:
            # Current Solution
            if self.dim == 1:
                sol = x - T * op.div(rr, **self.kwargs)
            elif self.dim == 2:
                sol = x - T * op.div(rr, ss, **self.kwargs)
            elif self.dim == 3:
                sol = x - T * op.div(rr, ss, kk, **self.kwargs)
            elif self.dim == 4:
                sol = x - T * op.div(rr, ss, kk, uu, **self.kwargs)

            #  Objective function value
            obj = 0.5 * np.power(np.linalg.norm(x[:] - sol[:]), 2) + \
                T * np.sum(self._eval(sol), axis=0)
            rel_obj = np.abs(obj - prev_obj) / obj
            prev_obj = obj

            if self.verbosity in ['HIGH', 'ALL']:
                print("Iter: ", iter, " obj = ", obj, " rel_obj = ", rel_obj)

            # Stopping criterion
            if rel_obj < tol:
                crit = "TOL_EPS"
                break

            #  Update divergence vectors and project
            if self.dim == 1:
                dx = op.grad(sol, dim=self.dim, **self.kwargs)
                r -= 1. / (4 * T * mt**2) * dx
                weights = np.maximum(1, np.abs(r))

            elif self.dim == 2:
                dx, dy = op.grad(sol, dim=self.dim, **self.kwargs)
                r -= (1. / (8. * T * mt**2.)) * dx
                s -= (1. / (8. * T * mt**2.)) * dy
                weights = np.maximum(1, np.sqrt(np.power(np.abs(r), 2) +
                                                np.power(np.abs(s), 2)))

            elif self.dim == 3:
                dx, dy, dz = op.grad(sol, dim=self.dim, **self.kwargs)
                r -= 1. / (12. * T * mt**2) * dx
                s -= 1. / (12. * T * mt**2) * dy
                k -= 1. / (12. * T * mt**2) * dz
                weights = np.maximum(1, np.sqrt(np.power(np.abs(r), 2) +
                                                np.power(np.abs(s), 2) +
                                                np.power(np.abs(k), 2)))

            elif self.dim == 4:
                dx, dy, dz, dt = op.grad(sol, dim=self.dim, **self.kwargs)
                r -= 1. / (16 * T * mt**2) * dx
                s -= 1. / (16 * T * mt**2) * dy
                k -= 1. / (16 * T * mt**2) * dz
                u -= 1. / (16 * T * mt**2) * dt
                weights = np.maximum(1, np.sqrt(np.power(np.abs(r), 2) +
                                                np.power(np.abs(s), 2) +
                                                np.power(np.abs(k), 2) +
                                                np.power(np.abs(u), 2)))

            # FISTA update
            t = (1 + np.sqrt(4 * told**2)) / 2.

            if self.dim >= 1:
                p = r / weights
                r = p + (told - 1) / t * (p - pold)
                pold = p
                rr = deepcopy(r)

            if self.dim >= 2:
                q = s / weights
                s = q + (told - 1) / t * (q - qold)
                ss = deepcopy(s)
                qold = q

            if self.dim >= 3:
                o = k / weights
                k = o + (told - 1) / t * (o - kold)
                kk = deepcopy(k)
                kold = o

            if self.dim >= 4:
                m = u / weights
                u = m + (told - 1) / t * (m - uold)
                uu = deepcopy(u)
                uold = m

            told = t
            iter += 1

        try:
            type(crit) == str
        except NameError:
            crit = "MAX_IT"

        t_end = time()
        exec_time = t_end - t_init

        if self.verbosity in ['HIGH', 'ALL']:
            print("Prox_TV: obj = {0}, rel_obj = {1}, {2}, iter = {3}".format(
                obj, rel_obj, crit, iter))
            print("exec_time = ", exec_time)
        return sol
Beispiel #4
0
    def test_div(self):
        # Sanity check
        self.assertRaises(ValueError, operators.div)

        # Divergence tests
        # test with 1dim matrices
        dx = np.array([1, 2, 3, 4, 5])

        # test without weights
        nptest.assert_array_equal(np.array([1, 1, 1, 1, -4]),
                                  operators.div(dx))

        # test with weights
        weights = {'wx': 2, 'wy': 3, 'wz': 4, 'wt': 2}
        nptest.assert_array_equal(np.array([2, 2, 2, 2, -8]),
                                  operators.div(dx, **weights))

        # test with 2dim matrices
        dx = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
        dy = np.array([[13, 14, 15, 16],
                       [17, 18, 19, 20],
                       [21, 22, 23, 24]])

        # test without weights
        x_mat = np.array([[1, 2, 3, 4], [4, 4, 4, 4], [-5, -6, -7, -8]])
        xy_mat = np.array([[14, 3, 4, -11],
                           [21, 5, 5, -15],
                           [16, -5, -6, -31]])
        nptest.assert_array_equal(x_mat, operators.div(dx))
        nptest.assert_array_equal(xy_mat, operators.div(dx, dy))

        # test with weights
        xy_mat_w = np.array([[41, 7, 9, -37],
                             [59, 11, 11, -49],
                             [53, -9, -11, -85]])
        nptest.assert_array_equal(xy_mat_w, operators.div(dx, dy, **weights))

        # test with 3dim matrices (3x3x3)
        dx = np.array([[[1, 10, 19], [2, 11, 20], [3, 12, 21]],
                       [[4, 13, 22], [5, 14, 23], [6, 15, 24]],
                       [[7, 16, 25], [8, 17, 26], [9, 18, 27]]])
        dy = np.array([[[1, 10, 19], [2, 11, 20], [3, 12, 21]],
                       [[4, 13, 22], [5, 14, 23], [6, 15, 24]],
                       [[7, 16, 25], [8, 17, 26], [9, 18, 27]]])
        dz = np.array([[[1, 10, 19], [2, 11, 20], [3, 12, 21]],
                       [[4, 13, 22], [5, 14, 23], [6, 15, 24]],
                       [[7, 16, 25], [8, 17, 26], [9, 18, 27]]])
        # test without weights
        x_mat = np.array([[[1, 10, 19], [2, 11, 20], [3, 12, 21]],
                          [[3, 3, 3], [3, 3, 3], [3, 3, 3]],
                          [[-4, -13, -22], [-5, -14, -23], [-6, -15, -24]]])
        xy_mat = np.array([[[2, 20, 38], [3, 12, 21], [1, 1, 1]],
                           [[7, 16, 25], [4, 4, 4], [-2, -11, -20]],
                           [[3, 3, 3], [-4, -13, -22], [-14, -32, -50]]])
        xyz_mat = np.array([[[3, 29, 28], [5, 21, 10], [4, 10, -11]],
                            [[11, 25, 12], [9, 13, -10], [4, -2, -35]],
                            [[10, 12, -13], [4, -4, -39], [-5, -23, -68]]])
        xyzt_mat = np.array([[[9, 86, 55], [15, 61, -1], [12, 27, -66]],
                             [[34, 81, 20], [29, 45, -47], [15, 0, -123]],
                             [[41, 58, -33], [25, 11, -111], [0, -45, -198]]])
        nptest.assert_array_equal(x_mat, operators.div(dx))
        nptest.assert_array_equal(xy_mat,  operators.div(dx, dy))
        nptest.assert_array_equal(xyz_mat, operators.div(dx, dy, dz))
        # test with weights
        xyz_mat_w = np.array([[[9, 86, 55], [15, 61, -1], [12, 27, -66]],
                              [[34, 81, 20], [29, 45, -47], [15, 0, -123]],
                              [[41, 58, -33], [25, 11, -111], [0, -45, -198]]])
        nptest.assert_array_equal(xyz_mat_w, operators.div(dx, dy, dz,
                                                           **weights))

        # test with 4d matrices (3x3x3x3)
        dx = np.array([[[[1, 28, 55], [10, 37, 64], [19, 46, 73]],
                        [[2, 29, 56], [11, 38, 65], [20, 47, 74]],
                        [[3, 30, 57], [12, 39, 66], [21, 48, 75]]],
                       [[[4, 31, 58], [13, 40, 67], [22, 49, 76]],
                        [[5, 32, 59], [14, 41, 68], [23, 50, 77]],
                        [[6, 33, 60], [15, 42, 69], [24, 51, 78]]],
                       [[[7, 34, 61], [16, 43, 70], [25, 52, 79]],
                        [[8, 35, 62], [17, 44, 71], [26, 53, 80]],
                        [[9, 36, 63], [18, 45, 72], [27, 54, 81]]]])
        dy = np.array([[[[1, 28, 55], [10, 37, 64], [19, 46, 73]],
                        [[2, 29, 56], [11, 38, 65], [20, 47, 74]],
                        [[3, 30, 57], [12, 39, 66], [21, 48, 75]]],
                       [[[4, 31, 58], [13, 40, 67], [22, 49, 76]],
                        [[5, 32, 59], [14, 41, 68], [23, 50, 77]],
                        [[6, 33, 60], [15, 42, 69], [24, 51, 78]]],
                       [[[7, 34, 61], [16, 43, 70], [25, 52, 79]],
                        [[8, 35, 62], [17, 44, 71], [26, 53, 80]],
                        [[9, 36, 63], [18, 45, 72], [27, 54, 81]]]])
        dz = np.array([[[[1, 28, 55], [10, 37, 64], [19, 46, 73]],
                        [[2, 29, 56], [11, 38, 65], [20, 47, 74]],
                        [[3, 30, 57], [12, 39, 66], [21, 48, 75]]],
                       [[[4, 31, 58], [13, 40, 67], [22, 49, 76]],
                        [[5, 32, 59], [14, 41, 68], [23, 50, 77]],
                        [[6, 33, 60], [15, 42, 69], [24, 51, 78]]],
                       [[[7, 34, 61], [16, 43, 70], [25, 52, 79]],
                        [[8, 35, 62], [17, 44, 71], [26, 53, 80]],
                        [[9, 36, 63], [18, 45, 72], [27, 54, 81]]]])
        dt = np.array([[[[1, 28, 55], [10, 37, 64], [19, 46, 73]],
                        [[2, 29, 56], [11, 38, 65], [20, 47, 74]],
                        [[3, 30, 57], [12, 39, 66], [21, 48, 75]]],
                       [[[4, 31, 58], [13, 40, 67], [22, 49, 76]],
                        [[5, 32, 59], [14, 41, 68], [23, 50, 77]],
                        [[6, 33, 60], [15, 42, 69], [24, 51, 78]]],
                       [[[7, 34, 61], [16, 43, 70], [25, 52, 79]],
                        [[8, 35, 62], [17, 44, 71], [26, 53, 80]],
                        [[9, 36, 63], [18, 45, 72], [27, 54, 81]]]])
        # test without weights
        x_mat = np.array([[[[1, 28, 55], [10, 37, 64],
                            [19, 46, 73]],
                           [[2, 29, 56], [11, 38, 65],
                            [20, 47, 74]],
                           [[3, 30, 57], [12, 39, 66],
                            [21, 48, 75]]],
                          [[[3, 3, 3], [3, 3, 3],
                            [3, 3, 3]],
                           [[3, 3, 3], [3, 3, 3],
                              [3, 3, 3]],
                           [[3, 3, 3], [3, 3, 3],
                              [3, 3, 3]]],
                          [[[-4, -31, -58], [-13, -40, -67],
                            [-22, -49, -76]],
                           [[-5, -32, -59], [-14, -41, -68],
                              [-23, -50, -77]],
                           [[-6, -33, -60], [-15, -42, -69],
                              [-24, -51, -78]]]])
        xy_mat = np.array([[[[2, 56, 110], [20, 74, 128],
                             [38, 92, 146]],
                            [[3, 30, 57], [12, 39, 66],
                             [21, 48, 75]],
                            [[1, 1, 1], [1, 1, 1],
                             [1, 1, 1]]],
                           [[[7, 34, 61], [16, 43, 70],
                             [25, 52, 79]],
                            [[4, 4, 4], [4, 4, 4],
                               [4, 4, 4]],
                            [[-2, -29, -56], [-11, -38, -65],
                               [-20, -47, -74]]],
                           [[[3, 3, 3], [3, 3, 3],
                             [3, 3, 3]],
                            [[-4, -31, -58], [-13, -40, -67],
                               [-22, -49, -76]],
                            [[-14, -68, -122], [-32, -86, -140],
                               [-50, -104, -158]]]])
        xyz_mat = np.array([[[[3, 84, 165], [29, 83, 137],
                              [28, 55, 82]],
                             [[5, 59, 113], [21, 48, 75],
                              [10, 10, 10]],
                             [[4, 31, 58], [10, 10, 10],
                              [-11, -38, -65]]],
                            [[[11, 65, 119], [25, 52, 79],
                              [12, 12, 12]],
                             [[9, 36, 63], [13, 13, 13],
                                [-10, -37, -64]],
                             [[4, 4, 4], [-2, -29, -56],
                                [-35, -89, -143]]],
                            [[[10, 37, 64], [12, 12, 12],
                              [-13, -40, -67]],
                             [[4, 4, 4], [-4, -31, -58],
                                [-39, -93, -147]],
                             [[-5, -32, -59], [-23, -77, -131],
                                [-68, -149, -230]]]])
        xyzt_mat = np.array([[[[4, 111, 137], [39, 110, 100],
                               [47, 82, 36]],
                              [[7, 86, 84], [32, 75, 37],
                               [30, 37, -37]],
                              [[7, 58, 28], [22, 37, -29],
                               [10, -11, -113]]],
                             [[[15, 92, 88], [38, 79, 39],
                               [34, 39, -37]],
                              [[14, 63, 31], [27, 40, -28],
                               [13, -10, -114]],
                              [[10, 31, -29], [13, -2, -98],
                                 [-11, -62, -194]]],
                             [[[17, 64, 30], [28, 39, -31],
                               [12, -13, -119]],
                              [[12, 31, -31], [13, -4, -102],
                                 [-13, -66, -200]],
                              [[4, -5, -95], [-5, -50, -176],
                                 [-41, -122, -284]]]])
        nptest.assert_array_equal(x_mat, operators.div(dx))
        nptest.assert_array_equal(xy_mat, operators.div(dx, dy))
        nptest.assert_array_equal(xyz_mat, operators.div(dx, dy, dz))
        nptest.assert_array_equal(xyzt_mat, operators.div(dx, dy, dz, dt))
        # test with weights
        xyzt_mat_w = np.array([[[[11, 306, 439], [106, 275, 282],
                                 [93, 136, 17]],
                                [[19, 231, 281], [83, 169, 93],
                                 [39, -1, -203]],
                                [[18, 147, 114], [51, 54, -105],
                                 [-24, -147, -432]]],
                               [[[42, 277, 350], [107, 216, 163],
                                 [64, 47, -132]],
                                [[39, 191, 181], [73, 99, -37],
                                 [-1, -101, -363]],
                                [[27, 96, 3], [30, -27, -246],
                                   [-75, -258, -603]]],
                               [[[55, 230, 243], [90, 139, 26],
                                 [17, -60, -299]],
                                [[41, 133, 63], [45, 11, -185],
                                   [-59, -219, -541]],
                                [[18, 27, -126], [-9, -126, -405],
                                   [-144, -387, -792]]]])
        nptest.assert_array_equal(xyzt_mat_w, operators.div(dx, dy, dz, dt,
                                                            **weights))
 def test_adjoint(self):
     """Test that 1D div op is the adjoint of grad."""
     dx = operators.grad(np.eye(10), dim=1)
     dxt = operators.div(np.eye(10))
     nptest.assert_equal(dx.T, -dxt)  # we use that definition