def test_defining_spd_operator_by_taking_real_part(self):
    with self.test_session() as sess:
      # S is real and positive.
      s = linear_operator_test_util.random_uniform(
          shape=(10, 2, 3, 4), dtype=dtypes.float32, minval=1., maxval=2.)

      # Let S = S1 + S2, the Hermitian and anti-hermitian parts.
      # S1 = 0.5 * (S + S^H), S2 = 0.5 * (S - S^H),
      # where ^H is the Hermitian transpose of the function:
      #    f(n0, n1, n2)^H := ComplexConjugate[f(N0-n0, N1-n1, N2-n2)].
      # We want to isolate S1, since
      #   S1 is Hermitian by construction
      #   S1 is real since S is
      #   S1 is positive since it is the sum of two positive kernels

      # IDFT[S] = IDFT[S1] + IDFT[S2]
      #         =      H1  +      H2
      # where H1 is real since it is Hermitian,
      # and H2 is imaginary since it is anti-Hermitian.
      ifft_s = math_ops.ifft3d(math_ops.cast(s, dtypes.complex64))

      # Throw away H2, keep H1.
      real_ifft_s = math_ops.real(ifft_s)

      # This is the perfect spectrum!
      # spectrum = DFT[H1]
      #          = S1,
      fft_real_ifft_s = math_ops.fft3d(
          math_ops.cast(real_ifft_s, dtypes.complex64))

      # S1 is Hermitian ==> operator is real.
      # S1 is real ==> operator is self-adjoint.
      # S1 is positive ==> operator is positive-definite.
      operator = linalg.LinearOperatorCirculant3D(fft_real_ifft_s)

      # Allow for complex output so we can check operator has zero imag part.
      self.assertEqual(operator.dtype, dtypes.complex64)
      matrix, matrix_t = sess.run([
          operator.to_dense(),
          array_ops.matrix_transpose(operator.to_dense())
      ])
      operator.assert_positive_definite().run()  # Should not fail.
      np.testing.assert_allclose(0, np.imag(matrix), atol=1e-6)
      self.assertAllClose(matrix, matrix_t)

      # Just to test the theory, get S2 as well.
      # This should create an imaginary operator.
      # S2 is anti-Hermitian ==> operator is imaginary.
      # S2 is real ==> operator is self-adjoint.
      imag_ifft_s = math_ops.imag(ifft_s)
      fft_imag_ifft_s = math_ops.fft3d(
          1j * math_ops.cast(imag_ifft_s, dtypes.complex64))
      operator_imag = linalg.LinearOperatorCirculant3D(fft_imag_ifft_s)

      matrix, matrix_h = sess.run([
          operator_imag.to_dense(),
          array_ops.matrix_transpose(math_ops.conj(operator_imag.to_dense()))
      ])
      self.assertAllClose(matrix, matrix_h)
      np.testing.assert_allclose(0, np.real(matrix), atol=1e-7)
示例#2
0
    def test_defining_operator_using_real_convolution_kernel(self):
        with self.cached_session():
            convolution_kernel = linear_operator_test_util.random_normal(
                shape=(2, 2, 3, 5), dtype=dtypes.float32)
            # Convolution kernel is real ==> spectrum is Hermitian.
            spectrum = math_ops.fft3d(
                math_ops.cast(convolution_kernel, dtypes.complex64))

            # spectrum is Hermitian ==> operator is real.
            operator = linalg.LinearOperatorCirculant3D(spectrum)
            self.assertAllEqual((2, 2 * 3 * 5, 2 * 3 * 5), operator.shape)

            # 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()
            self.assertAllEqual((2, 2 * 3 * 5, 2 * 3 * 5), matrix.shape)
            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 = linear_operator_test_util.random_normal(
          shape=(2, 2, 3, 5), dtype=dtypes.float32)
      # Convolution kernel is real ==> spectrum is Hermitian.
      spectrum = math_ops.fft3d(
          math_ops.cast(convolution_kernel, dtypes.complex64))

      # spectrum is Hermitian ==> operator is real.
      operator = linalg.LinearOperatorCirculant3D(spectrum)
      self.assertAllEqual((2, 2 * 3 * 5, 2 * 3 * 5), operator.shape)

      # 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()
      self.assertAllEqual((2, 2 * 3 * 5, 2 * 3 * 5), matrix.shape)
      np.testing.assert_allclose(0, np.imag(matrix), atol=1e-6)
示例#4
0
def _IFFT3DGrad(_, grad):
    rsize = 1. / math_ops.cast(array_ops.size(grad), dtypes.float32)
    return math_ops.fft3d(grad) * math_ops.complex(rsize, 0.)
示例#5
0
def _IFFT3DGrad(_, grad):
  rsize = 1. / math_ops.cast(_FFTSizeForGrad(grad, 3), dtypes.float32)
  return math_ops.fft3d(grad) * math_ops.complex(rsize, 0.)
示例#6
0
def _IFFT3DGrad(_, grad):
  rsize = 1. / math_ops.cast(array_ops.size(grad), dtypes.float32)
  return math_ops.fft3d(grad) * math_ops.complex(rsize, 0.)
示例#7
0
    def test_defining_spd_operator_by_taking_real_part(self):
        with self.cached_session() as sess:
            # S is real and positive.
            s = linear_operator_test_util.random_uniform(shape=(10, 2, 3, 4),
                                                         dtype=dtypes.float32,
                                                         minval=1.,
                                                         maxval=2.)

            # Let S = S1 + S2, the Hermitian and anti-hermitian parts.
            # S1 = 0.5 * (S + S^H), S2 = 0.5 * (S - S^H),
            # where ^H is the Hermitian transpose of the function:
            #    f(n0, n1, n2)^H := ComplexConjugate[f(N0-n0, N1-n1, N2-n2)].
            # We want to isolate S1, since
            #   S1 is Hermitian by construction
            #   S1 is real since S is
            #   S1 is positive since it is the sum of two positive kernels

            # IDFT[S] = IDFT[S1] + IDFT[S2]
            #         =      H1  +      H2
            # where H1 is real since it is Hermitian,
            # and H2 is imaginary since it is anti-Hermitian.
            ifft_s = math_ops.ifft3d(math_ops.cast(s, dtypes.complex64))

            # Throw away H2, keep H1.
            real_ifft_s = math_ops.real(ifft_s)

            # This is the perfect spectrum!
            # spectrum = DFT[H1]
            #          = S1,
            fft_real_ifft_s = math_ops.fft3d(
                math_ops.cast(real_ifft_s, dtypes.complex64))

            # S1 is Hermitian ==> operator is real.
            # S1 is real ==> operator is self-adjoint.
            # S1 is positive ==> operator is positive-definite.
            operator = linalg.LinearOperatorCirculant3D(fft_real_ifft_s)

            # Allow for complex output so we can check operator has zero imag part.
            self.assertEqual(operator.dtype, dtypes.complex64)
            matrix, matrix_t = sess.run([
                operator.to_dense(),
                array_ops.matrix_transpose(operator.to_dense())
            ])
            operator.assert_positive_definite().run()  # Should not fail.
            np.testing.assert_allclose(0, np.imag(matrix), atol=1e-6)
            self.assertAllClose(matrix, matrix_t)

            # Just to test the theory, get S2 as well.
            # This should create an imaginary operator.
            # S2 is anti-Hermitian ==> operator is imaginary.
            # S2 is real ==> operator is self-adjoint.
            imag_ifft_s = math_ops.imag(ifft_s)
            fft_imag_ifft_s = math_ops.fft3d(
                1j * math_ops.cast(imag_ifft_s, dtypes.complex64))
            operator_imag = linalg.LinearOperatorCirculant3D(fft_imag_ifft_s)

            matrix, matrix_h = sess.run([
                operator_imag.to_dense(),
                array_ops.matrix_transpose(
                    math_ops.conj(operator_imag.to_dense()))
            ])
            self.assertAllClose(matrix, matrix_h)
            np.testing.assert_allclose(0, np.real(matrix), atol=1e-7)
def _IFFT3DGrad(_, grad):
    rsize = 1. / math_ops.cast(_FFTSizeForGrad(grad, 3), dtypes.float32)
    return math_ops.fft3d(grad) * math_ops.complex(rsize, 0.)