Esempio n. 1
0
    def _operator_and_matrix(self, build_info, dtype, use_placeholder):
        shape = build_info.shape
        # For this test class, we are creating Hermitian spectrums.
        # We also want the spectrum to have eigenvalues bounded away from zero.
        #
        # pre_spectrum is bounded away from zero.
        pre_spectrum = linear_operator_test_util.random_uniform(
            shape=self._shape_to_spectrum_shape(shape), minval=1., maxval=2.)
        pre_spectrum_c = _to_complex(pre_spectrum)

        # Real{IFFT[pre_spectrum]}
        #  = IFFT[EvenPartOf[pre_spectrum]]
        # is the IFFT of something that is also bounded away from zero.
        # Therefore, FFT[pre_h] would be a well-conditioned spectrum.
        pre_h = math_ops.ifft(pre_spectrum_c)

        # A spectrum is Hermitian iff it is the DFT of a real convolution kernel.
        # So we will make spectrum = FFT[h], for real valued h.
        h = math_ops.real(pre_h)
        h_c = _to_complex(h)

        spectrum = math_ops.fft(h_c)

        lin_op_spectrum = spectrum

        if use_placeholder:
            lin_op_spectrum = array_ops.placeholder_with_default(spectrum,
                                                                 shape=None)

        operator = linalg.LinearOperatorCirculant(lin_op_spectrum,
                                                  input_output_dtype=dtype)

        mat = self._spectrum_to_circulant_1d(spectrum, shape, dtype=dtype)

        return operator, mat
Esempio n. 2
0
    def _spectrum_to_circulant_1d(self, spectrum, shape, dtype):
        """Creates a circulant matrix from a spectrum.

    Intentionally done in an explicit yet inefficient way.  This provides a
    cross check to the main code that uses fancy reshapes.

    Args:
      spectrum: Float or complex `Tensor`.
      shape:  Python list.  Desired shape of returned matrix.
      dtype:  Type to cast the returned matrix to.

    Returns:
      Circulant (batch) matrix of desired `dtype`.
    """
        spectrum = _to_complex(spectrum)
        spectrum_shape = self._shape_to_spectrum_shape(shape)
        domain_dimension = spectrum_shape[-1]
        if not domain_dimension:
            return array_ops.zeros(shape, dtype)

        # Explicitly compute the action of spectrum on basis vectors.
        matrix_rows = []
        for m in range(domain_dimension):
            x = np.zeros([domain_dimension])
            # x is a basis vector.
            x[m] = 1.0
            fft_x = math_ops.fft(x.astype(np.complex64))
            h_convolve_x = math_ops.ifft(spectrum * fft_x)
            matrix_rows.append(h_convolve_x)
        matrix = array_ops.stack(matrix_rows, axis=-1)
        return math_ops.cast(matrix, dtype)
  def _spectrum_to_circulant_1d(self, spectrum, shape, dtype):
    """Creates a circulant matrix from a spectrum.

    Intentionally done in an explicit yet inefficient way.  This provides a
    cross check to the main code that uses fancy reshapes.

    Args:
      spectrum: Float or complex `Tensor`.
      shape:  Python list.  Desired shape of returned matrix.
      dtype:  Type to cast the returned matrix to.

    Returns:
      Circulant (batch) matrix of desired `dtype`.
    """
    spectrum = _to_complex(spectrum)
    spectrum_shape = self._shape_to_spectrum_shape(shape)
    domain_dimension = spectrum_shape[-1]
    if not domain_dimension:
      return array_ops.zeros(shape, dtype)

    # Explicitly compute the action of spectrum on basis vectors.
    matrix_rows = []
    for m in range(domain_dimension):
      x = np.zeros([domain_dimension])
      # x is a basis vector.
      x[m] = 1.0
      fft_x = math_ops.fft(x.astype(np.complex64))
      h_convolve_x = math_ops.ifft(spectrum * fft_x)
      matrix_rows.append(h_convolve_x)
    matrix = array_ops.stack(matrix_rows, axis=-1)
    return math_ops.cast(matrix, dtype)
  def _operator_and_matrix(self, build_info, dtype, use_placeholder):
    shape = build_info.shape
    # For this test class, we are creating Hermitian spectrums.
    # We also want the spectrum to have eigenvalues bounded away from zero.
    #
    # pre_spectrum is bounded away from zero.
    pre_spectrum = linear_operator_test_util.random_uniform(
        shape=self._shape_to_spectrum_shape(shape), minval=1., maxval=2.)
    pre_spectrum_c = _to_complex(pre_spectrum)

    # Real{IFFT[pre_spectrum]}
    #  = IFFT[EvenPartOf[pre_spectrum]]
    # is the IFFT of something that is also bounded away from zero.
    # Therefore, FFT[pre_h] would be a well-conditioned spectrum.
    pre_h = math_ops.ifft(pre_spectrum_c)

    # A spectrum is Hermitian iff it is the DFT of a real convolution kernel.
    # So we will make spectrum = FFT[h], for real valued h.
    h = math_ops.real(pre_h)
    h_c = _to_complex(h)

    spectrum = math_ops.fft(h_c)

    lin_op_spectrum = spectrum

    if use_placeholder:
      lin_op_spectrum = array_ops.placeholder_with_default(spectrum, shape=None)

    operator = linalg.LinearOperatorCirculant(
        lin_op_spectrum, input_output_dtype=dtype)

    mat = self._spectrum_to_circulant_1d(spectrum, shape, dtype=dtype)

    return operator, mat
 def test_hermitian_spectrum_gives_operator_with_zero_imag_part(self):
   with self.test_session():
     # Make spectrum the FFT of a real convolution kernel h.  This ensures that
     # spectrum is Hermitian.
     h = linear_operator_test_util.random_normal(shape=(3, 4))
     spectrum = math_ops.fft(math_ops.cast(h, dtypes.complex64))
     operator = linalg.LinearOperatorCirculant(
         spectrum, input_output_dtype=dtypes.complex64)
     matrix = operator.to_dense()
     imag_matrix = math_ops.imag(matrix)
     eps = np.finfo(np.float32).eps
     np.testing.assert_allclose(
         0, imag_matrix.eval(), rtol=0, atol=eps * 3 * 4)
Esempio n. 6
0
 def test_hermitian_spectrum_gives_operator_with_zero_imag_part(self):
     with self.cached_session():
         # Make spectrum the FFT of a real convolution kernel h.  This ensures that
         # spectrum is Hermitian.
         h = linear_operator_test_util.random_normal(shape=(3, 4))
         spectrum = math_ops.fft(math_ops.cast(h, dtypes.complex64))
         operator = linalg.LinearOperatorCirculant(
             spectrum, input_output_dtype=dtypes.complex64)
         matrix = operator.to_dense()
         imag_matrix = math_ops.imag(matrix)
         eps = np.finfo(np.float32).eps
         np.testing.assert_allclose(0,
                                    imag_matrix.eval(),
                                    rtol=0,
                                    atol=eps * 3 * 4)
Esempio n. 7
0
    def test_defining_operator_using_real_convolution_kernel(self):
        with self.cached_session():
            convolution_kernel = [1., 2., 1.]
            spectrum = math_ops.fft(
                math_ops.cast(convolution_kernel, dtypes.complex64))

            # spectrum is shape [3] ==> operator is shape [3, 3]
            # spectrum is Hermitian ==> operator is real.
            operator = linalg.LinearOperatorCirculant(spectrum)

            # Allow for complex output so we can make sure it has zero imag part.
            self.assertEqual(operator.dtype, dtypes.complex64)

            matrix = operator.to_dense().eval()
            np.testing.assert_allclose(0, np.imag(matrix), atol=1e-6)
  def test_defining_operator_using_real_convolution_kernel(self):
    with self.test_session():
      convolution_kernel = [1., 2., 1.]
      spectrum = math_ops.fft(
          math_ops.cast(convolution_kernel, dtypes.complex64))

      # spectrum is shape [3] ==> operator is shape [3, 3]
      # spectrum is Hermitian ==> operator is real.
      operator = linalg.LinearOperatorCirculant(spectrum)

      # Allow for complex output so we can make sure it has zero imag part.
      self.assertEqual(operator.dtype, dtypes.complex64)

      matrix = operator.to_dense().eval()
      np.testing.assert_allclose(0, np.imag(matrix), atol=1e-6)
    def _operator_and_mat_and_feed_dict(self, build_info, dtype,
                                        use_placeholder):
        shape = build_info.shape
        # For this test class, we are creating Hermitian spectrums.
        # We also want the spectrum to have eigenvalues bounded away from zero.
        #
        # pre_spectrum is bounded away from zero.
        pre_spectrum = linear_operator_test_util.random_uniform(
            shape=self._shape_to_spectrum_shape(shape), minval=1., maxval=2.)
        pre_spectrum_c = _to_complex(pre_spectrum)

        # Real{IFFT[pre_spectrum]}
        #  = IFFT[EvenPartOf[pre_spectrum]]
        # is the IFFT of something that is also bounded away from zero.
        # Therefore, FFT[pre_h] would be a well-conditioned spectrum.
        pre_h = math_ops.ifft(pre_spectrum_c)

        # A spectrum is Hermitian iff it is the DFT of a real convolution kernel.
        # So we will make spectrum = FFT[h], for real valued h.
        h = math_ops.real(pre_h)
        h_c = _to_complex(h)

        spectrum = math_ops.fft(h_c)

        if use_placeholder:
            spectrum_ph = array_ops.placeholder(dtypes.complex64)
            # Evaluate here because (i) you cannot feed a tensor, and (ii)
            # it is random and we want the same value used for both mat and feed_dict.
            spectrum = spectrum.eval()
            operator = linalg.LinearOperatorCirculant(spectrum_ph,
                                                      input_output_dtype=dtype)
            feed_dict = {spectrum_ph: spectrum}
        else:
            operator = linalg.LinearOperatorCirculant(spectrum,
                                                      input_output_dtype=dtype)
            feed_dict = None

        mat = self._spectrum_to_circulant_1d(spectrum, shape, dtype=dtype)

        return operator, mat, feed_dict
  def _operator_and_mat_and_feed_dict(self, build_info, dtype, use_placeholder):
    shape = build_info.shape
    # For this test class, we are creating Hermitian spectrums.
    # We also want the spectrum to have eigenvalues bounded away from zero.
    #
    # pre_spectrum is bounded away from zero.
    pre_spectrum = linear_operator_test_util.random_uniform(
        shape=self._shape_to_spectrum_shape(shape), minval=1., maxval=2.)
    pre_spectrum_c = _to_complex(pre_spectrum)

    # Real{IFFT[pre_spectrum]}
    #  = IFFT[EvenPartOf[pre_spectrum]]
    # is the IFFT of something that is also bounded away from zero.
    # Therefore, FFT[pre_h] would be a well-conditioned spectrum.
    pre_h = math_ops.ifft(pre_spectrum_c)

    # A spectrum is Hermitian iff it is the DFT of a real convolution kernel.
    # So we will make spectrum = FFT[h], for real valued h.
    h = math_ops.real(pre_h)
    h_c = _to_complex(h)

    spectrum = math_ops.fft(h_c)

    if use_placeholder:
      spectrum_ph = array_ops.placeholder(dtypes.complex64)
      # Evaluate here because (i) you cannot feed a tensor, and (ii)
      # it is random and we want the same value used for both mat and feed_dict.
      spectrum = spectrum.eval()
      operator = linalg.LinearOperatorCirculant(
          spectrum_ph, input_output_dtype=dtype)
      feed_dict = {spectrum_ph: spectrum}
    else:
      operator = linalg.LinearOperatorCirculant(
          spectrum, input_output_dtype=dtype)
      feed_dict = None

    mat = self._spectrum_to_circulant_1d(spectrum, shape, dtype=dtype)

    return operator, mat, feed_dict
Esempio n. 11
0
def _IFFTGrad(_, grad):
    rsize = 1. / math_ops.cast(array_ops.size(grad), dtypes.float32)
    return math_ops.fft(grad) * math_ops.complex(rsize, 0.)
Esempio n. 12
0
def _IFFTGrad(_, grad):
  rsize = 1. / math_ops.cast(_FFTSizeForGrad(grad, 1), dtypes.float32)
  return math_ops.fft(grad) * math_ops.complex(rsize, 0.)
Esempio n. 13
0
def _IFFTGrad(_, grad):
  rsize = 1. / math_ops.cast(array_ops.size(grad), dtypes.float32)
  return math_ops.fft(grad) * math_ops.complex(rsize, 0.)
def _IFFTGrad(_, grad):
    rsize = 1. / math_ops.cast(_FFTSizeForGrad(grad, 1), dtypes.float32)
    return math_ops.fft(grad) * math_ops.complex(rsize, 0.)