Exemplo n.º 1
0
def log2(x, name=None):
    """
  Computes log_2(x)

  numpy compatibility:
  Equivalent to numpy.log2
  """
    with _tf.name_scope(name, op_util.resolve_op_name("Log2"), [x]):
        return log(x, 2)
Exemplo n.º 2
0
def log(x, base, name=None):
    """
  Computes log_{base}(x)
  """
    with _tf.name_scope(name, op_util.resolve_op_name("Log"), [x, base]):
        n = _tf.log(x)
        base = _tf.convert_to_tensor(base, dtype=n.dtype)
        d = _tf.log(base)
        return n / d
Exemplo n.º 3
0
def to_decibel(x, ref_val, name=None):
  """
  Converts to decibel scale.

  :param x Tensor with values to convert to dB scale.
  :param ref_val Scalar representing reference value in bel scale
  :return: 10*log10(value/reference_value)
  """
  with tf.name_scope(name, op_util.resolve_op_name("ToDecibel"), [x]):
    zero = tf.constant(0, dtype=ref_val.dtype)
    with tf.control_dependencies([
      tf.assert_greater(ref_val, zero, data=[ref_val],
                        message="reference value must be > 0")
      ]):
      return 10*math_ops.log10(x / ref_val)
Exemplo n.º 4
0
def analytic_signal(input, dt=1, axis=None, name=None):
    """
  Computes the analytic signal:
  x_a = x + j*h(x)
  Where x is the input signal, h(x) - the Hilbert transform of x.

  For more information see:
  https://en.wikipedia.org/wiki/Analytic_signal

  scipy compatibility
  Equivalent to scipy.signal.hilbert(input)
  """
    with tf.name_scope(name, op_util.resolve_op_name("AnalyticSignal"),
                       [input]):
        return input + 1j * tf.cast(hilbert(input, dt=dt, axis=axis),
                                    dtype=tf.complex64)
Exemplo n.º 5
0
def clip_by_decibel(input, clip_value_min, clip_value_max, name=None):
    """
  Converts to dB scale and limits dynamic range of input signal.

  :param range pair (min, max) of allowed dB values. Each output value will be
         limited to this range, i.e.:
          if result[i] > max => result[i] = max
          if result[i] < min => result[i] = min
  :return: input in dB scale, with values limited to given range
  """
    with tf.name_scope(name, op_util.resolve_op_name("ClipByDecibel"),
                       [input, clip_value_min, clip_value_max]):
        clip_value_max = tf.convert_to_tensor(clip_value_max,
                                              dtype=input.dtype)
        clip_value_min = tf.convert_to_tensor(clip_value_min,
                                              dtype=input.dtype)
        zero = tf.constant(0, dtype=input.dtype)
        with tf.control_dependencies([
                tf.assert_greater_equal(
                    clip_value_max,
                    clip_value_min,
                    data=[clip_value_min, clip_value_max],
                    message="must be: clip_value_max >= clip_value_min"),
                tf.assert_greater_equal(
                    clip_value_max,
                    zero,
                    data=[clip_value_max],
                    message="clip value max must be >= 0 "),
                tf.assert_greater_equal(clip_value_min,
                                        zero,
                                        data=[clip_value_min],
                                        message="clip value min must be >= 0 ")
        ]):
            abs_input = tf.abs(input)
            ref_value = tf.reduce_max(abs_input)
            input_db = tf.cond(
                tf.equal(ref_value, zero),
                # We cannot use 0 as ref. value in dB scale.
                true_fn=lambda: abs_input,
                false_fn=lambda: wf.to_decibel(abs_input, ref_value))
            # input_db has non-positive values
            return tf.clip_by_value(input_db, -1 * clip_value_max,
                                    -1 * clip_value_min)
Exemplo n.º 6
0
def hilbert(input, dt=1, axis=None, name=None):
    """
  Computes Hilbert transform of complex-valued signal. Computations will be done along given axis.

  Disclaimer:
  This function currently does not support tensors with undefined dimensions.

  scipy compatibility
  Equivalent to (-1)*scipy.fftpack.hilbert(input)

  :param input: tensor of tf.complex64 values
  :param dt: time step between consecutive samples
  :param axis input's dimension
  :return: tensor with values of type tf.complex64
  """
    with tf.name_scope(name, op_util.resolve_op_name("Hilbert"), [input]):
        input = tf.convert_to_tensor(value=input,
                                     name="input",
                                     dtype=tf.complex64)
        # TODO(pjarosik) axis parameter should be handled by tf.fft
        if axis is not None:
            rank = len(input.get_shape().as_list())
            assert 0 <= axis < rank
            perm = [x for x in range(0, rank)]
            perm[axis] = rank - 1
            perm[rank - 1] = axis
            input = tf.transpose(input, perm=perm)

        input_shape = tf.shape(input)
        input_rank = tf.rank(input)
        with tf.control_dependencies([
                tf.assert_greater(input_rank,
                                  0,
                                  data=[input],
                                  message="input can not be a scalar")
        ]):
            n = input_shape[input_rank - 1]
            y_f = tf.fft(input)
            f = tf.cast(fftfreq(n, d=dt), dtype=tf.complex64)
            output = tf.real(tf.ifft(-1j * tf.sign(f) * y_f))
            if axis is not None:
                output = tf.transpose(output, perm=perm)
            return output
Exemplo n.º 7
0
def fftfreq(n, d=1.0, name=None):
    """
  Returns tf.fft sample frequencies.

  numpy compatibility
  Equivalent to np.fft.fftfreq

  :param n: 0-D tensor - number of samples of signal in time-domain
  :param d: value - sample spacing
  :return: 1-D tensor of length n with sample frequencies.
  """
    with tf.name_scope(name, op_util.resolve_op_name("Fftfreq"), [n]):
        n = tf.cast(n, dtype=tf.float32)
        with tf.control_dependencies([
                tf.assert_equal(tf.rank(n),
                                0,
                                data=[n],
                                message="n must be a scalar."),
                tf.assert_greater_equal(n,
                                        2.,
                                        data=[n],
                                        message="n must be > 2")
        ]):
            T = d * n
            dtype = tf.float32
            non_negative_range = tf.cond(
                tf.equal(tf.mod(n, 2), 0),
                true_fn=lambda: tf.range(start=0, limit=n // 2, dtype=dtype),
                false_fn=lambda: tf.range(
                    start=0, limit=((n - 1) // 2) + 1, dtype=dtype))
            negative_range = tf.cond(
                tf.equal(tf.mod(n, 2), 0),
                true_fn=lambda: tf.range(
                    start=-1 * (n // 2), limit=0, dtype=dtype),
                false_fn=lambda: tf.range(
                    start=-1 * ((n - 1) // 2), limit=0, dtype=dtype))
            return tf.concat(
                [tf.div(non_negative_range, T),
                 tf.div(negative_range, T)], -1)