예제 #1
0
    def element_equals(self):
        """Verify `LinearSpaceElement.__eq__`."""
        try:
            zero = self.space.zero()
        except NotImplementedError:
            print('*** SPACE HAS NO ZERO VECTOR ***')
            return

        try:
            zero == zero
        except NotImplementedError:
            self.log('Vector has no __eq__')
            return

        with fail_counter(
                test_name='Verify behavior of `element1 == element2`',
                logger=self.log) as counter:

            for [n_x, x], [n_y, y] in samples(self.space, self.space):
                if n_x == n_y:
                    if not x == y:
                        counter.fail('failed x == x with x={:25s}'
                                     ''.format(n_x))

                    if x != y:
                        counter.fail('failed not x != x with x={:25s}'
                                     ''.format(n_x))
                else:
                    if x == y:
                        counter.fail('failed not x == y with x={:25s}, '
                                     'x={:25s}'.format(n_x, n_y))

                    if not x != y:
                        counter.fail('failed x != y with x={:25s}, x={:25s}'
                                     ''.format(n_x, n_y))
예제 #2
0
    def equals(self):
        """Verify `LinearSpace.__eq__`."""

        self.log('\n== Verifying __eq__ ==\n')

        if not self.space == self.space:
            print('** space == space failed ***')

        if self.space != self.space:
            print('** not space != space failed***')

        if self.space != copy(self.space):
            print('** space == copy(space) failed***')

        if self.space != deepcopy(self.space):
            print('** space == deepcopy(space) failed***')

        with fail_counter(
                test_name='Verify behavior of `space == obj` when `obj` '
                'is not a space',
                logger=self.log) as counter:

            for obj in [[1, 2], list(), tuple(), dict(), 5.0]:
                if self.space == obj:
                    counter.fail('space == obj,  with obj={}' ''.format(obj))

                if not self.space != obj:
                    counter.fail('not space != obj,  with obj={}'
                                 ''.format(obj))
예제 #3
0
    def _adjoint_of_adjoint(self):
        """Verify ``(A^*)^* == A``"""
        try:
            self.operator.adjoint.adjoint
        except AttributeError:
            print('A^* has no adjoint')
            return

        if self.operator.adjoint.adjoint is self.operator:
            self.log('(A^*)^* == A')
            return

        with fail_counter(test_name='\nVerifying the identity Ax = (A^*)^* x',
                          err_msg='error = ||Ax - (A^*)^* x|| / ||A|| ||x||',
                          logger=self.log) as counter:
            for [name_x, x] in self.operator.domain.examples:
                opx = self.operator(x)
                op_adj_adj_x = self.operator.adjoint.adjoint(x)

                denom = self.operator_norm * x.norm()
                if denom == 0:
                    error = 0
                else:
                    error = (opx - op_adj_adj_x).norm() / denom

                if error > self.tol:
                    counter.fail('x={:25s} : error={:6.5f}'
                                 ''.format(name_x, error))
예제 #4
0
    def self_adjoint(self):
        """Verify ``<Ax, y> == <x, Ay>``."""
        left_inner_vals = []
        right_inner_vals = []

        with fail_counter(
                test_name='Verifying the identity <Ax, y> = <x, Ay>',
                err_msg='error = |<Ax, y> - <x, Ay>| / ||A|| ||x|| ||y||',
                logger=self.log) as counter:

            for [name_x, x], [name_y, y] in samples(self.operator.domain,
                                                    self.operator.range):
                x_norm = x.norm()
                y_norm = y.norm()

                l_inner = self.operator(x).inner(y)
                r_inner = x.inner(self.operator(y))

                denom = self.operator_norm * x_norm * y_norm
                error = 0 if denom == 0 else abs(l_inner - r_inner) / denom

                if error > self.tol:
                    counter.fail('x={:25s} y={:25s} : error={:6.5f}'
                                 ''.format(name_x, name_y, error))

                left_inner_vals.append(l_inner)
                right_inner_vals.append(r_inner)

        scale = np.polyfit(left_inner_vals, right_inner_vals, 1)[0]
        self.log('\nThe adjoint seems to be scaled according to:')
        self.log('(x, Ay) / (Ax, y) = {}. Should be 1.0'.format(scale))
예제 #5
0
    def element_space(self):
        """Verify `LinearSpaceElement.space`."""
        with fail_counter(test_name='Verify `LinearSpaceElement.space`',
                          logger=self.log) as counter:

            for [n_x, x] in samples(self.space):
                if x.space != self.space:
                    counter.fail('failed with x={:25s}'.format(n_x))
예제 #6
0
    def _commutativity_of_addition(self):
        """Verify addition commutativity."""
        with fail_counter(test_name='Verifying commutativity of addition',
                          err_msg='error = dist(x + y, y + x)',
                          logger=self.log) as counter:

            for [n_x, x], [n_y, y] in samples(self.space, self.space):
                correct = _approx_equal(x + y, y + x, self.tol)
                if not correct:
                    counter.fail('failed with x={:25s} y={:25s}'
                                 ''.format(n_x, n_y))
예제 #7
0
    def _identity_of_mult(self):
        """Verify multiplicative neutral element ('one')."""
        with fail_counter(
                test_name='Verifying identity element of multiplication',
                err_msg='error = dist(1 * x, x)',
                logger=self.log) as counter:

            for [n_x, x] in samples(self.space):
                correct = _approx_equal(1 * x, x, self.tol)
                if not correct:
                    counter.fail('failed with x={:25s}'.format(n_x))
예제 #8
0
    def element_method(self):
        """Verify `LinearSpace.element`."""
        with fail_counter(test_name='Verifying element method',
                          logger=self.log) as counter:
            try:
                elem = self.space.element()
            except NotImplementedError:
                counter.fail('*** element failed ***')
                return

            if elem not in self.space:
                counter.fail('*** space.element() not in space ***')
예제 #9
0
    def _inner_conjugate_symmetry(self):
        """Verify conjugate symmetry of the inner product."""
        with fail_counter(
                test_name='Verifying conjugate symmetry of the inner product',
                err_msg='error = |<x, y> - <y, x>.conj()|',
                logger=self.log) as counter:

            for [n_x, x], [n_y, y] in samples(self.space, self.space):
                error = abs((x).inner(y) - y.inner(x).conjugate())
                if error > self.tol:
                    counter.fail('x={:25s}, y={:25s}: error={}'
                                 ''.format(n_x, n_y, error))
예제 #10
0
    def element_assign(self):
        """Verify `LinearSpaceElement.assign`."""
        with fail_counter(
                test_name='Verify behavior of `LinearSpaceElement.assign`',
                logger=self.log) as counter:

            for [n_x, x], [n_y, y] in samples(self.space, self.space):
                x.assign(y)
                correct = _approx_equal(x, y, self.tol)
                if not correct:
                    counter.fail('failed with x={:25s} y={:25s}'
                                 ''.format(n_x, n_y))
예제 #11
0
    def _division(self):
        """Verify scalar division as multiplication with mult. inverse."""
        with fail_counter(test_name='Verifying scalar division',
                          err_msg='error = dist(x / a, x * (1/a))',
                          logger=self.log) as counter:

            for [n_x, x], [_, a] in samples(self.space, self.space.field):
                if a != 0:
                    correct = _approx_equal(x / a, x * (1.0 / a), self.tol)
                    if not correct:
                        counter.fail('failed with x={:25s}, a={}'
                                     ''.format(n_x, a))
예제 #12
0
    def _subtraction(self):
        """Verify element subtraction as addition of additive inverse."""
        with fail_counter(test_name='Verifying element subtraction',
                          err_msg='error = dist(x - y, x + (-1 * y))',
                          logger=self.log) as counter:

            for [n_x, x], [n_y, y] in samples(self.space, self.space):
                correct = (_approx_equal(x - y, x + (-1 * y), self.tol)
                           and _approx_equal(x - y, x + (-y), self.tol))
                if not correct:
                    counter.fail('failed with x={:25s}, y={:25s}'
                                 ''.format(n_x, n_y))
예제 #13
0
    def _norm_homogeneity(self):
        """Verify positive homogeneity of the norm."""
        with fail_counter(
                test_name='Verifying positive homogeneity of the norm',
                err_msg='error = | ||a*x|| - |a|*||x|| |',
                logger=self.log) as counter:

            for [n_x, x], [_, a] in samples(self.space, self.space.field):
                error = abs((a * x).norm() - abs(a) * x.norm())
                if error > self.tol:
                    counter.fail('x={:25s} a={}: error={}'
                                 ''.format(n_x, a, error))
예제 #14
0
    def _associativity_of_addition(self):
        """Verify addition associativity."""
        with fail_counter(test_name='Verifying associativity of addition',
                          err_msg='error = dist(x + (y + z), (x + y) + z)',
                          logger=self.log) as counter:

            for [n_x, x], [n_y, y], [n_z,
                                     z] in samples(self.space, self.space,
                                                   self.space):
                correct = _approx_equal(x + (y + z), (x + y) + z, self.tol)
                if not correct:
                    counter.fail('failed with x={:25s} y={:25s} z={:25s}'
                                 ''.format(n_x, n_y, n_z))
예제 #15
0
    def _multiply_commutative(self):
        """Verify commutativity of vector multiplication."""
        with fail_counter(
                test_name='Verifying commutativity of vector multiplication',
                err_msg='error = dist(x * y, y * x)',
                logger=self.log) as counter:

            for [n_x, x], [n_y, y], _ in samples(self.space, self.space,
                                                 self.space):
                correct = _approx_equal(x * y, y * x, self.tol)
                if not correct:
                    counter.fail('failed with x={:25s} y={:25s}'
                                 ''.format(n_x, n_y))
예제 #16
0
    def _dist_symmetric(self):
        """Verify symmetry of the distance."""
        with fail_counter(test_name='Verifying symmetry of the distance',
                          err_msg='error = |d(x, y) - d(y, x)|',
                          logger=self.log) as counter:

            for [n_x, x], [n_y, y] in samples(self.space, self.space):
                dist_1 = x.dist(y)
                dist_2 = y.dist(x)
                error = abs(dist_1 - dist_2)

                if error > self.tol:
                    counter.fail('x={:25s}, y={:25s}: error={}'
                                 ''.format(n_x, n_y, error))
예제 #17
0
    def _commutativity_of_scalar_mult(self):
        """Verify scalar multiplication commutativity."""
        with fail_counter(
                test_name='Verifying commutativity of scalar multiplication',
                err_msg='error = dist(a * (b * x), (a * b) * x)',
                logger=self.log) as counter:

            for [n_x, x], [_, a], [_,
                                   b] in samples(self.space, self.space.field,
                                                 self.space.field):
                correct = _approx_equal(a * (b * x), (a * b) * x, self.tol)
                if not correct:
                    counter.fail('failed with x={:25s}, a={}, b={}'
                                 ''.format(n_x, a, b))
예제 #18
0
    def _inner_linear_scalar(self):
        """Verify homogeneity of the inner product in the first argument."""
        with fail_counter(
                test_name='Verifying homogeneity of the inner product in the '
                'first argument',
                err_msg='error = |<a*x, y> - a*<x, y>|',
                logger=self.log) as counter:

            for [n_x, x], [n_y, y], [_, a] in samples(self.space, self.space,
                                                      self.space.field):
                error = abs((a * x).inner(y) - a * x.inner(y))
                if error > self.tol:
                    counter.fail('x={:25s}, y={:25s}, a={}: error={}'
                                 ''.format(n_x, n_y, a, error))
예제 #19
0
    def _multiply_distributive_scalar(self):
        """Verify distributivity of scalar multiplication."""
        with fail_counter(
                test_name='Verifying distributivity of vector multiplication '
                'under scalar multiplication',
                err_msg='error = dist(a * (x + y), a * x + a * y)',
                logger=self.log) as counter:

            for [n_x, x], [n_y, y], [_, a] in samples(self.space, self.space,
                                                      self.space.field):
                correct = _approx_equal(a * (x + y), a * x + a * y, self.tol)
                if not correct:
                    counter.fail('failed with x={:25s} y={:25s} a={}'
                                 ''.format(n_x, n_y, a))
예제 #20
0
    def _multiply_associative(self):
        """Verify associativity of vector multiplication."""
        with fail_counter(
                test_name='Verifying associativity of vector multiplication',
                err_msg='error = dist(x * (y * z), (x * y) * z)',
                logger=self.log) as counter:

            for [n_x, x], [n_y, y], [n_z,
                                     z] in samples(self.space, self.space,
                                                   self.space):
                correct = _approx_equal(x * (y * z), (x * y) * z, self.tol)
                if not correct:
                    counter.fail('failed with x={:25s} y={:25s} z={:25s}'
                                 ''.format(n_x, n_y, n_z))
예제 #21
0
    def field(self):
        """Verify `LinearSpace.field`."""
        with fail_counter(test_name='Verifying field property',
                          logger=self.log) as counter:
            try:
                field = self.space.field
            except NotImplementedError:
                counter.fail('*** field failed ***')
                return

            if not isinstance(field, Field):
                counter.fail('*** space.field not a `Field` ***')
                return

            try:
                zero = field.element(0)
            except NotImplementedError:
                counter.fail('*** field.element(0) failed ***')
                zero = None

            if zero is not None and zero != 0:
                counter.fail('*** field.element(0) != 0 ***')

            if zero is not None and zero != 0.0:
                counter.fail('*** field.element(0) != 0.0 ***')

            try:
                one = field.element(1)
            except NotImplementedError:
                counter.fail('*** field.element(1) failed ***')
                one = None

            if one is not None and one != 1:
                counter.fail('*** field.element(1) != 1 ***')

            if one is not None and one != 1.0:
                counter.fail('*** field.element(1) != 1.0 ***')

            try:
                minus_one = field.element(-1)
            except NotImplementedError:
                counter.fail('field.element(-1) failed')
                minus_one = None

            if minus_one is not None and minus_one != -1:
                counter.fail('field.element(-1) != -1')

            if minus_one is not None and minus_one != -1.0:
                counter.fail('field.element(-1) != -1.0')
예제 #22
0
    def _distributivity_of_mult_scalar(self):
        """Verify scalar multiplication distributivity wrt scalar addition."""
        with fail_counter(
                test_name='Verifying distributivity of scalar multiplication '
                'under scalar addition',
                err_msg='error = dist((a + b) * x, a * x + b * x)',
                logger=self.log) as counter:

            for [n_x, x], [_, a], [_,
                                   b] in samples(self.space, self.space.field,
                                                 self.space.field):
                correct = _approx_equal((a + b) * x, a * x + b * x, self.tol)
                if not correct:
                    counter.fail('failed with x={:25s}, a={}, b={}'
                                 ''.format(n_x, a, b))
예제 #23
0
    def _inner_linear_sum(self):
        """Verify distributivity of the inner product in the first argument."""
        with fail_counter(
                test_name='Verifying distributivity of the inner product'
                'in the first argument',
                err_msg='error = |<x+y, z> - (<x, z> + <y, z>)|',
                logger=self.log) as counter:

            for [n_x, x], [n_y, y], [n_z,
                                     z] in samples(self.space, self.space,
                                                   self.space):
                error = abs((x + y).inner(z) - (x.inner(z) + y.inner(z)))
                if error > self.tol:
                    counter.fail('x={:25s}, y={:25s}, z={:25s}: error={}'
                                 ''.format(n_x, n_y, n_z, error))
예제 #24
0
    def _dist_positivity(self):
        """Verify nonnegativity of the distance."""

        with fail_counter(test_name='Verifying nonnegativity of the distance',
                          logger=self.log) as counter:

            for [n_x, x], [n_y, y] in samples(self.space, self.space):
                dist = x.dist(y)

                if n_x == n_y and dist != 0:
                    counter.fail('d(x, x) != 0.0, x={:25s}: dist={}'
                                 ''.format(n_x, dist))
                elif n_x != n_y and dist <= 0:
                    counter.fail('d(x, y) <= 0,   x={:25s} y={:25s}: dist={}'
                                 ''.format(n_x, n_y, dist))
예제 #25
0
    def _inverse_element_of_addition(self):
        """Verify additive inverse."""
        try:
            zero = self.space.zero()
        except (AttributeError, NotImplementedError):
            print('*** SPACE HAS NO ZERO VECTOR ***')
            return

        with fail_counter(test_name='Verifying inverse element of addition',
                          err_msg='error = dist(x + (-x), 0)',
                          logger=self.log) as counter:

            for [n_x, x] in samples(self.space):
                correct = _approx_equal(x + (-x), zero, self.tol)
                if not correct:
                    counter.fail('failed with x={:25s}'.format(n_x))
예제 #26
0
    def _norm_positive(self):
        """Verify positive definiteness of the norm."""
        with fail_counter(
                test_name='Verifying positive definiteness of the norm',
                logger=self.log) as counter:

            for [n_x, x] in samples(self.space):
                norm = x.norm()

                if n_x == 'Zero' and norm != 0:
                    counter.fail('||0|| != 0.0, x={:25s}: ||x||={}'
                                 ''.format(n_x, norm))

                elif n_x != 'Zero' and norm <= 0:
                    counter.fail('||x|| <= 0,   x={:25s}: ||x||={}'
                                 ''.format(n_x, norm))
예제 #27
0
    def _norm_subadditive(self):
        """Verify subadditivity of the norm."""
        with fail_counter(test_name='Verifying sub-additivity of the norm',
                          err_msg='error = max(||x+y|| - (||x|| + ||y||), 0)',
                          logger=self.log) as counter:

            for [n_x, x], [n_y, y] in samples(self.space, self.space):
                norm_x = x.norm()
                norm_y = y.norm()
                norm_xy = (x + y).norm()

                error = norm_xy - norm_x - norm_y

                if error > 0:
                    counter.fail('x={:25s} y={:25s}: error={}'
                                 ''.format(n_x, n_y, error))
예제 #28
0
    def element_set_zero(self):
        """Verify `LinearSpaceElement.set_zero`."""
        try:
            zero = self.space.zero()
        except NotImplementedError:
            print('*** SPACE HAS NO ZERO VECTOR ***')
            return

        with fail_counter(
                test_name='Verify behavior of `LinearSpaceElement.set_zero`',
                logger=self.log) as counter:

            for [n_x, x] in samples(self.space):
                x.set_zero()
                correct = _approx_equal(x, zero, self.tol)
                if not correct:
                    counter.fail('failed with x={:25s}' ''.format(n_x))
예제 #29
0
    def _multiply_zero(self):
        """Verify that vector multiplication with zero is zero."""
        try:
            zero = self.space.zero()
        except NotImplementedError:
            print('*** SPACE HAS NO ZERO VECTOR ***')
            return

        with fail_counter(
                test_name='Verifying vector multiplication with zero',
                err_msg='error = ||x * 0||',
                logger=self.log) as counter:
            for [n_x, x] in samples(self.space):
                error = (zero * x).norm()

                if error > self.tol:
                    counter.fail('x={:25s},: error={}' ''.format(n_x, error))
예제 #30
0
    def _scale_invariance(self):
        """Verify ``A(c*x) = c * A(x)``."""
        with fail_counter(
                test_name='Verifying homogeneity under scalar multiplication',
                err_msg='error = ||A(c*x)-c*A(x)|| / |c| ||A|| ||x||',
                logger=self.log) as counter:
            for [name_x, x], [_, scale] in samples(self.operator.domain,
                                                   self.operator.domain.field):
                opx = self.operator(x)
                scaled_opx = self.operator(scale * x)

                denom = self.operator_norm * scale * x.norm()
                error = (0 if denom == 0 else
                         (scaled_opx - opx * scale).norm() / denom)

                if error > self.tol:
                    counter.fail('x={:25s} scale={:7.2f} error={:6.5f}'
                                 ''.format(name_x, scale, error))