Esempio n. 1
0
    def test_methanical_condition_number(self):
        ''' Mechanical test of condition number calculation '''

        # Unitary Matrix
        F = ops.FourierTransform(image_size, dtype=global_dtype, backend=global_backend)
        assert F.condition_number == 1
        assert not F.condition_number_is_upper_bound

        # Matrix with a condition number
        hh = yp.changeBackend((np.random.rand(image_size[0], image_size[1]) + 0.1).astype(np.complex64), global_backend)
        D = ops.Diagonalize(hh, dtype=global_dtype, backend=global_backend)
        assert not D.condition_number_is_upper_bound

        # Product of two unitary matricies
        assert (F * F).condition_number == 1
        assert not (F * F).condition_number_is_upper_bound

        # Product of one unitary and one non-singular matrix
        assert (F * D).condition_number == D.condition_number
        assert not (F * D).condition_number_is_upper_bound # because one matrix is unitary, this condition number is NOT an upper bound. This can be checked numerically.

        # Product of two non-singular matricies.
        hh_2 = yp.changeBackend((np.random.rand(image_size[0], image_size[1]) + 0.1).astype(np.complex64), global_backend)
        D2 = ops.Diagonalize(hh_2, dtype=global_dtype, backend=global_backend)
        assert (D * D2).condition_number >= D.condition_number
        assert (D * D2).condition_number_is_upper_bound
Esempio n. 2
0
    def test_operator_fourier_transform(self):
        # Define "true" FFTs
        Ft = lambda x: np.fft.fftshift(np.fft.fft2(np.fft.fftshift(x, axes=(0, 1)), axes=(0, 1), norm='ortho'), axes=(0, 1))
        iFt = lambda x: np.fft.fftshift(np.fft.ifft2(np.fft.fftshift(x, axes=(0, 1)), axes=(0, 1), norm='ortho'), axes=(0, 1))

        eps_fft = yp.precision(self.x, for_sum=True)

        if global_backend == 'numpy':
            fft_backends = ['scipy', 'numpy']
        else:
            fft_backends = ['af']

        for fft_backend in fft_backends:

            # Create Operator
            F = ops.FourierTransform(image_size, dtype=global_dtype, axes=(0, 1), fft_backend=fft_backend, center=True, backend=global_backend)

            # Check forward model
            assert yp.sumb(yp.abs(Ft(self.x).reshape(image_size) - yp.changeBackend(F * self.x, 'numpy').reshape(image_size))) < eps_fft, '%f' % yp.sumb(yp.abs(Ft(x).reshape(image_size) - yp.changeBackend(F * vec(self.x), 'numpy').reshape(image_size)))
            assert yp.sumb(yp.abs(iFt(self.x).reshape(image_size) - yp.changeBackend((F.H * self.x), 'numpy').reshape(image_size))) < eps_fft

            # Check reciprocity
            assert yp.sumb(yp.abs(F * F.H * self.x - self.x)) < eps_fft, "%.4e" % yp.sumb(yp.abs(F * F.H * vec(self.x) - vec(self.x)))

            # Check Gradient
            F.gradient_check()
Esempio n. 3
0
    def test_shape(self):
        # Check that shape function is correct

        assert bops.shape(bops.changeBackend(self.x_ocl_rect,
                                             'numpy')) == self.sz
        assert bops.shape(bops.changeBackend(self.x_np_rect,
                                             'arrayfire')) == self.sz
Esempio n. 4
0
    def test_intensity(self):
        I = ops.Intensity(image_size)

        # Check forward operator
        assert yp.sumb(yp.abs((yp.abs(yp.changeBackend(self.x, 'numpy')) ** 2) - yp.changeBackend(I * self.x, 'numpy'))) < eps

        # Check gradient
        I.gradient_check()
Esempio n. 5
0
    def test_operator_matrix_multiply(self):
        matrix_size = (10,10)
        m = yp.rand(matrix_size, global_dtype, global_backend)
        xm = yp.rand(matrix_size[1], global_dtype, global_backend)
        M = ops.MatrixMultiply(m)

        # Check Forward operator
        assert yp.sumb(yp.abs(yp.vec(yp.changeBackend(M * xm, 'numpy')) - yp.vec(yp.changeBackend(m, 'numpy').dot(yp.changeBackend(xm, 'numpy'))))) < eps, "%f" % yp.sumb(yp.abs(yp.changeBackend(M * xm, 'numpy') - yp.changeBackend(m, 'numpy').dot(yp.changeBackend(xm, 'numpy'))[:, np.newaxis]))

        # Check Adjoint
        assert yp.sumb(yp.abs(yp.vec(yp.changeBackend(M.H * xm, 'numpy')) - yp.vec(np.conj(yp.changeBackend(m, 'numpy').T).dot(yp.changeBackend(xm, 'numpy'))))) < eps, "%f" % yp.sumb(yp.abs(yp.changeBackend(M.H * xm, 'numpy') - np.conj(yp.changeBackend(m, 'numpy').T).dot(yp.changeBackend(xm, 'numpy'))[:, np.newaxis]))

        # Check gradient
        M.gradient_check()
Esempio n. 6
0
    def normalize(self, force=False):
        if 'normalization' not in self.metadata.calibration or force:
            # Calculation normalization vectors
            from htdeblur.recon import normalize_measurements
            (frame_normalization_list_y, frame_normalization_list_x) = normalize_measurements(self, debug=False)

            # Convert to numpy for saving
            _frame_normalization_list_y = [yp.changeBackend(norm, 'numpy').tolist() for norm in frame_normalization_list_y]
            _frame_normalization_list_x = [yp.changeBackend(norm, 'numpy').tolist() for norm in frame_normalization_list_x]

            # Save in metadata
            self.metadata.calibration['normalization'] = {'frame_normalization_x': _frame_normalization_list_x,
                                                                  'frame_normalization_y': _frame_normalization_list_y}
            # Save calibration file
            self.saveCalibration()
Esempio n. 7
0
    def setup_method(self, test_method):
        # Initialize arrays

        self.eps = bops.precision(dtype) * np.prod(shape)
        self.x_np_ones = bops.ones(shape, dtype, 'numpy')
        self.x_ocl_ones = bops.ones(shape, dtype, 'arrayfire')

        self.x_ocl_randn = bops.randn(shape, dtype, 'arrayfire')
        self.x_np_randn = np.asarray(self.x_ocl_randn)

        self.x_ocl_randu = bops.randu(shape, dtype, 'arrayfire')
        self.x_np_randu = np.asarray(self.x_ocl_randu)

        # Create random matricies
        self.A_ocl = bops.randn((10, 10), backend='arrayfire')
        self.A_np = np.asarray(self.A_ocl)

        self.sz = (10, 20)
        self.x_np_rect = bops.randn(self.sz, backend='numpy')
        assert bops.shape(self.x_np_rect) == self.sz

        self.x_ocl_rect = bops.randn(self.sz, backend='arrayfire')
        assert bops.shape(self.x_ocl_rect) == self.sz

        # Load object and crop to size
        brain = imageio.imread(object_file_name)
        x_0 = sp.misc.imresize(
            brain, size=image_size)[:, :, object_color_channel].astype(
                bops.getNativeDatatype(dtype, 'numpy')) / 255.

        # Convert object to desired backend
        self.x = bops.changeBackend(x_0, 'arrayfire')
Esempio n. 8
0
    def test_operator_convolution_circular(self):
        ''' Circular Convolution Operator '''
        # Generate circular convolution operator
        C = ops.Convolution(self.h)

        # Test forward operator
        conv2 = lambda x, h: yp.changeBackend(np.fft.ifftshift((np.fft.ifft2(np.fft.fft2(x, axes=(0,1), norm='ortho') * np.fft.fft2(h, axes=(0,1), norm='ortho'), axes=(0,1), norm='ortho')), axes=(0,1)).astype(yp.getNativeDatatype(global_dtype, 'numpy')), global_backend)

        x_np = yp.changeBackend(self.x, 'numpy')
        h_np = yp.changeBackend(self.h, 'numpy')

        assert np.sum(np.abs(yp.reshape(C * yp.vec(self.x), image_size) - conv2(x_np, h_np)) ** 2) < 1e-3, \
            'SSE (%.4e) is greater than tolerance (%.4e)' % ((np.sum(np.abs((C * yp.vec(self.x)).reshape(image_size)-conv2(x,h)))), eps)

        # Check gradient
        C.gradient_check()
Esempio n. 9
0
    def test_indexing(self):
        q = bops.randn((10, 10), backend='numpy', dtype='complex32')
        q_ocl = bops.changeBackend(q, 'arrayfire')
        q_ocl_np = bops.changeBackend(q_ocl, 'numpy')
        assert np.sum(np.abs(q - q_ocl_np)) < eps

        m = bops.rand((10, 20), dtype, "numpy")
        m_ocl = bops.changeBackend(m, 'arrayfire')

        assert abs(m[0, 1] - bops.scalar(m_ocl[0, 1])) < eps
        assert abs(m[1, 1] - bops.scalar(m_ocl[1, 1])) < eps
        assert abs(bops.scalar(m_ocl[4, 1]) - m[4, 1]) < eps

        assert bops.scalar(self.x_np_rect[5, 15]) == bops.scalar(
            bops.changeBackend(self.x_np_rect, 'arrayfire')[5, 15])
        assert bops.scalar(self.x_ocl_rect[5, 15]) == bops.scalar(
            bops.changeBackend(self.x_ocl_rect, 'numpy')[5, 15])
Esempio n. 10
0
    def test_crop(self):
        crop_size = [self.x_np_randn.shape[i] - 2 for i in range(len(shape))]
        assert np.sum(
            np.abs(
                bops.crop(self.x_np_randn, crop_size, crop_start=(0, 0)) -
                np.asarray(
                    bops.crop(self.x_ocl_randn, crop_size, crop_start=(
                        0, 0))))) < 1e-4

        x_full_np = bops.rand((20, 20), dtype=dtype, backend='numpy')
        x_full_ocl = bops.changeBackend(x_full_np, 'arrayfire')
        crop_size = tuple(np.asarray(bops.shape(x_full_np)) // 2)
        crop_start = (2, 2)

        x_crop_np = bops.crop(x_full_np, crop_size, crop_start=crop_start)
        x_crop_ocl = bops.crop(x_full_ocl, crop_size, crop_start=crop_start)

        assert np.sum(
            np.abs(bops.changeBackend(x_crop_ocl, 'numpy') - x_crop_np)) < 1e-4
Esempio n. 11
0
    def test_operator_crop_non_centered(self):
        ''' Non-centered Crop Operator '''
        # Generate Crop Operator
        crop_size = (image_size[0] // 2, image_size[1] // 2)
        crop_start = (6, 6)
        CR = ops.Crop(image_size, crop_size, pad_value=0,  dtype=global_dtype, backend=global_backend, crop_start=crop_start)

        # Check forward operator
        y_1 = yp.changeBackend(CR * self.x, 'numpy')
        y_2 = yp.changeBackend(yp.crop(self.x, crop_size, crop_start), 'numpy')
        assert yp.sumb(yp.abs(y_1 - y_2)) < eps

        # Check Adjoint Operator
        pad_size = [int((image_size[i] - crop_size[i]) / 2) for i in range(len(image_size))]
        y_3 = yp.pad(yp.crop(self.x, crop_size, crop_start), image_size, crop_start, pad_value=0)
        y_4 = yp.reshape(CR.H * CR * self.x, image_size)
        assert yp.sumb(yp.abs(y_3 - y_4)) < eps

        # Check gradient
        CR.gradient_check()
Esempio n. 12
0
    def test_operator_crop(self):
        ''' Crop Operator '''
        # Generate Crop Operator
        crop_size = (image_size[0] // 2, image_size[1] // 2)
        CR = ops.Crop(image_size, crop_size, pad_value=0,  dtype=global_dtype, backend=global_backend)

        # Check forward operator
        crop_start = tuple(np.asarray(image_size) // 2 - np.asarray(crop_size) // 2)
        y_1 = yp.changeBackend(CR * self.x, 'numpy')
        y_2 = yp.changeBackend(yp.crop(self.x, crop_size, crop_start), 'numpy')
        assert yp.sumb(yp.abs(y_1 - y_2)) < eps

        # Check Adjoint Operator
        pad_size = [int((image_size[i] - crop_size[i]) / 2) for i in range(len(image_size))]
        y_3 = yp.pad(yp.crop(self.x, crop_size, crop_start), image_size, crop_start, pad_value=0)
        y_4 = CR.H * CR * self.x
        assert yp.sumb(yp.abs(y_3 - y_4)) < eps

        # Check gradient
        CR.gradient_check()
Esempio n. 13
0
    def test_operator_exponential(self):
        L2 = ops.L2Norm(image_size)
        F = ops.FourierTransform(image_size)
        EXP = ops.Exponential(image_size)

        # Forward model
        assert yp.sumb(yp.abs(yp.changeBackend(EXP * self.x, 'numpy') - np.exp(yp.changeBackend(self.x, 'numpy')))) < eps

        # Check gradient
        EXP.gradient_check()

        # Generate composite operator
        D = ops.Diagonalize(self.h)
        L2 = ops.L2Norm(image_size)

        EXP_COMP = L2 * F * EXP
        EXP_COMP.gradient_check()

        EXP_COMP_2 = L2 * F * EXP * D
        EXP_COMP_2.gradient_check()
Esempio n. 14
0
    def test_operator_stacking_linear(self):
        # Create list of operators
        op_list_linear = [
            ops.FourierTransform(image_size, dtype=global_dtype, backend=global_backend),
            ops.Identity(image_size, dtype=global_dtype, backend=global_backend),
            ops.Exponential(image_size, dtype=global_dtype, backend=global_backend)
        ]

        # Horizontally stacked operators
        H_l = ops.Hstack(op_list_linear)

        # Vertically stack x for forward operator
        x_np = yp.changeBackend(self.x, 'numpy')
        x3 = yp.changeBackend(np.vstack((x_np, x_np, x_np)), global_backend)

        # Check forward operation
        y2 = yp.zeros(op_list_linear[0].N, op_list_linear[0].dtype, op_list_linear[0].backend)

        for op in op_list_linear:
            y2 = y2 + op * self.x

        assert yp.sumb(yp.abs(yp.changeBackend(H_l(x3) - y2, 'numpy'))) < eps, "%.4e" % yp.sumb(yp.abs(H_l(x3) - y2))

        # Check gradient
        H_l.gradient_check()

        # Create vertically stacked operator
        V_l = ops.Vstack(op_list_linear)

        # Check forward operator
        y3 = np.empty((0,image_size[1]), dtype=yp.getNativeDatatype(global_dtype, 'numpy'))
        for index, op in enumerate(op_list_linear):
            y3 = np.append(y3, (op * self.x), axis=0)

        y3 = yp.changeBackend(y3, global_backend)
        assert yp.sumb(yp.abs(V_l * self.x - y3)) < eps, "%.4e" % yp.sumb(yp.abs(V_l * vec(x) - y3))

        # Check gradient
        V_l.gradient_check()
Esempio n. 15
0
    def test_operator_shift(self):
        ''' Shift Operator '''
        # Normal shift
        shift = (0, 10) # should be y, x
        T = ops.Shift(image_size, shift)

        def shift_func(x, shift):
            x = yp.changeBackend(self.x, 'numpy')
            for ax, sh in enumerate(shift):
                x = np.roll(self.x, int(sh), axis=ax)
            return(x)

        # Check Forward Operator
        y_1 = yp.changeBackend(T * self.x, 'numpy')
        y_2 = shift_func(yp.changeBackend(self.x, 'numpy'), shift)
        assert yp.sumb(yp.abs(y_1 - y_2)) < eps

        # Check Adjoint Operator
        assert yp.sumb(yp.abs(T.H * T * self.x - self.x)) < eps

        # Check gradient
        T.gradient_check()
Esempio n. 16
0
    def test_operator_phase_ramp(self):
        eps_phase_ramp = 1e-4
        shift = yp.changeBackend(np.asarray((-5,3)).astype(yp.getNativeDatatype(global_dtype, 'numpy')), global_backend)

        # Generate phase ramp
        R = ops.PhaseRamp(image_size)
        r = R * shift

        F = ops.FourierTransform(image_size, dtype=global_dtype, normalize=False, backend=global_backend)
        D_R = ops.Diagonalize(r, dtype=global_dtype)
        S_R = F.H * D_R * F

        # Pixel-wise shift operator
        S = ops.Shift(image_size, shift)

        # Check that phase ramp is shifting by correct amount
        assert yp.sumb(yp.abs(yp.changeBackend(S_R * self.x, 'numpy') - yp.changeBackend(S * self.x, 'numpy'))) < 1e-3

        # Check gradient of phase ramp convolution
        S_R.gradient_check()

        # Check gradient of phase ramp
        R.gradient_check(eps=1e-1)
Esempio n. 17
0
    def test_operator_sum(self):
        ''' Element-wise Sum Operator '''
        axis_to_sum = (0,1)
        Σ = ops.Sum(image_size, axes=axis_to_sum)

        # Check forward operator
        y_1 = yp.changeBackend(Σ * self.x, 'numpy')
        y_2 = yp.sumb(yp.changeBackend(self.x, 'numpy'), axes=axis_to_sum)
        assert yp.abs(yp.sumb(y_1 - y_2)) < eps

        # Check adjoint operator
        y_3 = yp.changeBackend(Σ.H * Σ * self.x, 'numpy')
        reps = [1, ] * len(image_size)
        axes = list(range(len(image_size))) if axis_to_sum is 'all' else axis_to_sum
        scale = 1
        for axis in axes:
            reps[axis] = image_size[axis]
            scale *= 1 / image_size[axis]
        y_4 = yp.tile(y_2, reps) * scale
        assert yp.sumb(yp.abs(y_3 - y_4)) < eps

        # Check gradient
        Σ.gradient_check(eps=1)
Esempio n. 18
0
def Derivative(N, axis=0, dtype=None, backend=None, label=None):

    # Configure backend and datatype
    backend = backend if backend is not None else config.default_backend
    dtype = dtype if dtype is not None else config.default_dtype

    # Generate shift grid using numpy
    r_x = np.arange(-N[1] / 2, N[1] / 2, 1.0) / N[1]
    r_y = np.arange(-N[0] / 2, N[0] / 2, 1.0) / N[0]
    grid_np = np.meshgrid(r_x, r_y)

    # Convert to correct backend and datatype
    grid = []
    for g in grid_np:
        grid.append(
            changeBackend(g.astype(getNativeDatatype(dtype, 'numpy')),
                          backend))

    # Generate operator
    G = Diagonalize(2 * np.pi * 1j * grid[axis], dtype=dtype, backend=backend)
    F = FourierTransform(N, dtype=dtype, backend=backend)
    op = F.H * G * F

    # Set label and latex representation
    if label is None:
        if (axis == 0):
            op.label = "∂y"
            latex_str = "\\frac{\partial}{\partial y}"
        elif (axis == 1):
            op.label = "∂x"
            latex_str = "\\frac{\partial}{\partial x}"
    else:
        op.label = label
        latex_str = label

    # Set latex to be just label
    def repr_latex(latex_input=None):
        if latex_input is None:
            return latex_str
        else:
            return latex_str + ' \\times ' + latex_input

    op.repr_latex = repr_latex

    # Set condition number to 1 TODO: The operators above should have condition 1
    op.condition_number = 1.0

    return (op)
Esempio n. 19
0
    def setup_method(self, test_method):
        # Load object and crop to size
        x_0 = yp.rand(image_size)

        # Convert object to desired backend
        self.x = yp.changeBackend(x_0, global_backend)

        # Generate convolution kernel h
        h_size = np.array([4, 4])
        self.h = yp.zeros(image_size, global_dtype, global_backend)
        self.h[image_size[0] // 2 - h_size[0] // 2:image_size[0] // 2 + h_size[0] // 2,
          image_size[1] // 2 - h_size[1] // 2:image_size[1] // 2 + h_size[1] // 2] = yp.randn((h_size[0], h_size[1]), global_dtype, global_backend)

        # A = ops.Convolution(image_size, h, dtype=global_dtype, fft_backend='numpy', backend=global_backend)
        self.A = ops.FourierTransform(image_size, dtype=global_dtype, backend=global_backend, center=True)
        self.y = self.A(yp.vectorize(self.x))
Esempio n. 20
0
    def test_operator_wavelet(self):
        ''' Wavelet Transform Operator '''
        import pywt
        wavelet_list = ['db1', 'haar', 'rbio1.1', 'bior1.1', 'bior4.4', 'sym12']
        for wavelet_test in wavelet_list:
            # Wavelet Transform
            W = ops.WaveletTransform(image_size, wavelet_type=wavelet_test, use_cycle_spinning=False)

            # Check forward operation
            coeffs = pywt.wavedecn(self.x, wavelet=wavelet_test)
            x_wavelet, coeff_slices = pywt.coeffs_to_array(coeffs)
            assert yp.sumb(yp.abs(yp.changeBackend(W * self.x, 'numpy') - x_wavelet)) < eps, "Difference %.6e"

            # Check inverse operation
            coeffs_from_arr = pywt.array_to_coeffs(x_wavelet, coeff_slices)
            cam_recon = pywt.waverecn(coeffs_from_arr, wavelet=wavelet_test)
            assert yp.sumb(yp.abs(W.H * W * self.x - self.x)) < 1e-2

            # Ensure that the wavelet transform isn't just identity (weird bug)
            if W.shape[1] is yp.size(self.x):
                assert yp.sumb(yp.abs(W * yp.vec(self.x) - yp.vec(self.x))) > 1e-2, "%s" % wavelet_test
Esempio n. 21
0
def add(signal, type='gaussian', **kwargs):
    """ Add noise to a measurement"""
    if type == 'gaussian':
        snr = kwargs.get('snr', 1.0)
        signal_mean = yp.abs(yp.mean(signal))
        noise_gaussian = np.random.normal(0, signal_mean / snr,
                                          yp.shape(signal))
        return signal + noise_gaussian

    elif type == 'poisson':
        noise_poisson = np.random.poisson(np.real(signal))
        return signal + noise_poisson

    elif type == 'saltpepper' or type == 'saltandpepper':
        salt_pepper_ratio = kwargs.get('ratio', 0.5)
        salt_pepper_saturation = kwargs.get('saturation', 0.004)
        output = yp.changeBackend(signal, 'numpy')

        # Salt mode
        num_salt = np.ceil(salt_pepper_saturation * signal.size *
                           salt_pepper_ratio)
        coords = [
            np.random.randint(0, i - 1, int(num_salt)) for i in signal.shape
        ]
        output[tuple(coords)] = 1

        # Pepper mode
        num_pepper = np.ceil(salt_pepper_saturation * signal.size *
                             (1. - salt_pepper_ratio))
        coords = [
            np.random.randint(0, i - 1, int(num_pepper)) for i in signal.shape
        ]
        output[tuple(coords)] = 0
        return yp.cast_like(output, signal)

    elif type == 'speckle':
        noise_speckle = yp.randn(signal.shape)
        return signal + signal * noise_speckle
Esempio n. 22
0
    def test_matmul(self):
        matrix_size = (10, 20)
        m = bops.rand(matrix_size, dtype, 'arrayfire')
        xm = bops.rand(matrix_size[1], dtype, 'arrayfire')
        assert np.sum(
            np.abs(
                bops.changeBackend(bops.matmul(m, xm), 'numpy') -
                bops.changeBackend(m, 'numpy').dot(
                    bops.changeBackend(xm, 'numpy')))) < eps

        # Check matrix multiply (numpy to arrayfire)
        m_np = bops.rand(matrix_size, dtype, 'numpy')
        xm_np = bops.rand(matrix_size[1], dtype, 'numpy')
        m_ocl = bops.changeBackend(m_np, 'arrayfire')
        xm_ocl = bops.changeBackend(xm_np, 'arrayfire')
        assert np.sum(
            np.abs(
                bops.changeBackend(bops.matmul(m_ocl, xm_ocl), 'numpy') -
                m_np.dot(xm_np))) < eps
Esempio n. 23
0
 def shift_func(x, shift):
     x = yp.changeBackend(self.x, 'numpy')
     for ax, sh in enumerate(shift):
         x = np.roll(self.x, int(sh), axis=ax)
     return(x)