dep_vector_is_int = wave.dep_vector.dtype.name.startswith("<STR_LIT:int>")<EOL>dep_vector_is_complex = wave.dep_vector.dtype.name.startswith("<STR_LIT>")<EOL>if (wave.interp, wave.indep_scale) == ("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>wave_interp_func = scipy.interpolate.interp1d(<EOL>np.log10(wave.indep_vector), wave.dep_vector<EOL>)<EOL>ret = wave_interp_func(np.log10(indep_vector))<EOL><DEDENT>elif (wave.interp, wave.indep_scale) == ("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>dep_vector = (<EOL>wave.dep_vector.astype(np.float64)<EOL>if not dep_vector_is_complex<EOL>else wave.dep_vector<EOL>)<EOL>wave_interp_func = scipy.interpolate.interp1d(wave.indep_vector, dep_vector)<EOL>ret = wave_interp_func(indep_vector)<EOL><DEDENT>else:  <EOL><INDENT>wave_interp_func = scipy.interpolate.interp1d(<EOL>wave.indep_vector, wave.dep_vector, kind="<STR_LIT>"<EOL>)<EOL>ret = wave_interp_func(indep_vector)<EOL>eq_comp = np.all(<EOL>np.isclose(wave.indep_vector[-<NUM_LIT:1>], indep_vector[-<NUM_LIT:1>], FP_RTOL, FP_ATOL)<EOL>)<EOL>if eq_comp:<EOL><INDENT>ret[-<NUM_LIT:1>] = wave.dep_vector[-<NUM_LIT:1>]<EOL><DEDENT><DEDENT>round_ret = np.round(ret, <NUM_LIT:0>)<EOL>return (<EOL>round_ret.astype("<STR_LIT:int>")<EOL>if (dep_vector_is_int and np.all(np.isclose(round_ret, ret, FP_RTOL, FP_ATOL)))<EOL>else ret<EOL>)<EOL>


exobj = pexdoc.exh.addex(RuntimeError, "<STR_LIT>")<EOL>min_bound = max(np.min(wave_a.indep_vector), np.min(wave_b.indep_vector))<EOL>max_bound = min(np.max(wave_a.indep_vector), np.max(wave_b.indep_vector))<EOL>exobj(bool(min_bound > max_bound))<EOL>raw_range = np.unique(np.concatenate((wave_a.indep_vector, wave_b.indep_vector)))<EOL>return raw_range[np.logical_and(min_bound <= raw_range, raw_range <= max_bound)]<EOL>


def _verify_compatibility(wave_a, wave_b, check_dep_units=True):

exobj = pexdoc.exh.addex(RuntimeError, "<STR_LIT>")<EOL>ctuple = (<EOL>bool(wave_a.indep_scale != wave_b.indep_scale),<EOL>bool(wave_a.dep_scale != wave_b.dep_scale),<EOL>bool(wave_a.indep_units != wave_b.indep_units),<EOL>(bool(wave_a.dep_units != wave_b.dep_units) if check_dep_units else False),<EOL>bool(wave_a.interp != wave_b.interp),<EOL>)<EOL>exobj(any(ctuple))<EOL>

Verify that two waveforms can be combined with various mathematical functions.


obj = copy.copy(self)<EOL>obj.dep_name = "<STR_LIT>".format(obj.dep_name)<EOL>obj.dep_vector = np.abs(obj.dep_vector).astype(obj.dep_vector.dtype)<EOL>return obj<EOL>

Absolute value of waveform's dependent variable vector.

For example:

    >>> import math, numpy, peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector = np.array([4.0, -5.0, complex(0, 3)])
    >>> obj = peng.Waveform(indep_vector, dep_vector, 'obj')
    >>> print(abs(obj))
    Waveform: abs(obj)
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 4+0j, 5+0j, 3+0j ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS


return self._operation(other, "<STR_LIT:+>")<EOL>

Add dependent variable vectors of two waveforms or a waveform and a number.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([8, 2, 4])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a+obj_b)
    Waveform: obj_a+obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 12, 7, 10 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__add__

:raises:
 * RuntimeError (Waveforms are not compatible)

 * TypeError (Data type not supported)

.. [[[end]]]


return self._operation(other, "<STR_LIT:&>")<EOL>

Bit-wise logic and waveform operation.

The logic operation is done on the dependent variable vectors of two
waveforms or the dependent variable vector of a waveform and a number.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([8, 2, 4])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a&obj_b)
    Waveform: obj_a&obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 0, 0, 4 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__and__

:raises:
 * RuntimeError (Independent variable ranges do not overlap)

 * RuntimeError (Waveforms are not compatible)

 * TypeError (Complex operands not supported)

 * TypeError (Data type not supported)

.. [[[end]]]


return not bool(<EOL>np.all(<EOL>np.isclose(<EOL>self._dep_vector, np.zeros(len(self._dep_vector)), FP_RTOL, FP_ATOL<EOL>)<EOL>)<EOL>)<EOL>

Test if the waveform dependent variable is zero for all its elements.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector = np.array([4, 5, 6])
    >>> obj = peng.Waveform(indep_vector, dep_vector, 'obj_a')
    >>> if obj:
    ...     print('Boolean test returned: True')
    ... else:
    ...     print('Boolean test returned: False')
    Boolean test returned: True
    >>> dep_vector = np.zeros(3)
    >>> obj = peng.Waveform(indep_vector, dep_vector, 'obj_a')
    >>> if obj:
    ...     print('Boolean test returned: True')
    ... else:
    ...     print('Boolean test returned: False')
    Boolean test returned: False


if (not isinstance(item, tuple)) or (<EOL>isinstance(item, tuple) and (len(item) != <NUM_LIT:2>)<EOL>):<EOL><INDENT>return False<EOL><DEDENT>tchk = any([isinstance(item[<NUM_LIT:0>], typ) for typ in [int, float]])<EOL>if not tchk:<EOL><INDENT>return False<EOL><DEDENT>tchk = any([isinstance(item[<NUM_LIT:1>], typ) for typ in [int, float, complex]])<EOL>if not tchk:<EOL><INDENT>return False<EOL><DEDENT>indices = [np.where(self._indep_vector >= item[<NUM_LIT:0>])[<NUM_LIT:0>][<NUM_LIT:0>]]<EOL>if indices[<NUM_LIT:0>]:<EOL><INDENT>indices.append(indices[<NUM_LIT:0>] - <NUM_LIT:1>)<EOL><DEDENT>for index in indices:<EOL><INDENT>icmp = np.isclose(<EOL>np.array([self._indep_vector[index]]),<EOL>np.array([item[<NUM_LIT:0>]]),<EOL>FP_RTOL,<EOL>FP_ATOL,<EOL>)<EOL>dcmp = np.isclose(<EOL>np.array([self._dep_vector[index]]),<EOL>np.array([item[<NUM_LIT:1>]]),<EOL>FP_RTOL,<EOL>FP_ATOL,<EOL>)<EOL>if icmp and dcmp:<EOL><INDENT>return True<EOL><DEDENT><DEDENT>return False<EOL>

Test if an item is a data point in the waveform.

An item is in a waveform when it is a tuple with the characteristics of
the :py:data:`peng.Point` named tuple and its independent and dependent
values match a waveform's data point with :py:data:`peng.FP_ATOL`
absolute tolerance and :py:data:`peng.FP_RTOL` relative tolerance

:param item: Object
:type  item: any


Copy object.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector = np.array([4, 5, 6])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector, 'obj_a')
    >>> obj_b = copy.copy(obj_a)
    >>> obj_a == obj_b
    True
    >>> obj_a is obj_b
    False


try:<EOL><INDENT>self._indep_vector = np.delete(self._indep_vector, key)<EOL>self._dep_vector = np.delete(self._dep_vector, key)<EOL><DEDENT>except:<EOL><INDENT>raise<EOL><DEDENT>if not self._indep_vector.size:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>

Delete a waveform slice.

:param key: Slice key
:type  key: integer or slice object

:raises: Same exceptions as an invalid Numpy array slicing operation


return self._operation(other, "<STR_LIT:/>")<EOL>

Divide the dependent variable vector of a waveform.

The division may be by the dependent variable vector of another
waveform, the dependent variable vector of a waveform by a number, or a
number by the dependent variable vector of a waveform. In the latter
case a :py:class:`peng.Waveform()` object is returned with the result.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([8.0, 2.0, 4.0])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a/obj_b)
    Waveform: obj_a/obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 0.5, 2.5, 1.5 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_doc(cname, no_comment=True)) ]]]

:raises:
 * RuntimeError (Waveforms are not compatible)

 * TypeError (Data type not supported)

.. [[[end]]]


if (<EOL>isinstance(other, float)<EOL>or (isinstance(other, int) and (not isinstance(other, bool)))<EOL>or isinstance(other, complex)<EOL>):<EOL><INDENT>return np.all(<EOL>np.isclose(<EOL>self._dep_vector,<EOL>other * np.ones(len(self._dep_vector)),<EOL>FP_RTOL,<EOL>FP_ATOL,<EOL>)<EOL>)<EOL><DEDENT>if not isinstance(other, Waveform):<EOL><INDENT>return False<EOL><DEDENT>try:<EOL><INDENT>_, dep_vector_a, dep_vector_b = _homogenize_waves(self, other)<EOL><DEDENT>except RuntimeError as exobj:<EOL><INDENT>msg = "<STR_LIT>"<EOL>if _get_ex_msg(exobj) == msg:<EOL><INDENT>return False<EOL><DEDENT>raise<EOL><DEDENT>except:<EOL><INDENT>raise<EOL><DEDENT>ctuple = (<EOL>np.all(np.isclose(dep_vector_a, dep_vector_b, FP_RTOL, FP_ATOL)),<EOL>bool(self.indep_scale == other.indep_scale),<EOL>bool(self.dep_scale == other.dep_scale),<EOL>bool(self.indep_units == other.indep_units),<EOL>bool(self.dep_units == other.dep_units),<EOL>bool(self.interp == other.interp),<EOL>)<EOL>return bool(all(ctuple))<EOL>

Test waveform equality.

Two waveforms are equal if their independent variable vectors are the
same with :py:data:`peng.FP_ATOL` absolute tolerance and
:py:data:`peng.FP_RTOL` relative tolerance, their dependent variable
vectors are the same with :py:data:`peng.FP_ATOL` absolute tolerance
and :py:data:`peng.FP_RTOL` relative tolerance, their independent
variable scales are the same, their dependent variable scales are the
same, their independent variable units are the same, their dependent
variable units are the same and they have the same interpolation
function. Thus if two waveforms are constructed such that they are
identical but for their variable name, they are considered equal.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector = np.array([4, 5, 6])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector, 'obj_b')
    >>> obj_a == obj_b
    True
    >>> obj_a != obj_b
    False
    >>> dep_vector = obj_a.dep_vector+5
    >>> obj_b = peng.Waveform(indep_vector, dep_vector, 'obj_b')
    >>> obj_a == obj_b
    False
    >>> obj_a != obj_b
    True

A waveform is considered equal to a real number when its dependent
variable vector is equal to that number for all of its elements. For
example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector = 12.5*np.ones(len(indep_vector))
    >>> obj = peng.Waveform(indep_vector, dep_vector, 'obj_a')
    >>> 5 == obj
    False
    >>> obj == 12.5
    True


return self._operation(other, "<STR_LIT>")<EOL>

Integer-divide the dependent variable vector of a waveform.

The integer division may be by the dependent variable vector of another
waveform, the dependent variable vector of a waveform by a number, or a
number by the dependent variable vector of a waveform. In the latter
case a :py:class:`peng.Waveform()` object is returned with the result.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([8, 2, 4])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a//obj_b)
    Waveform: obj_a//obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 0, 2, 1 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__floordiv__

:raises:
 * RuntimeError (Independent variable ranges do not overlap)

 * RuntimeError (Waveforms are not compatible)

 * TypeError (Complex operands not supported)

 * TypeError (Data type not supported)

.. [[[end]]]


Test whether waveform is greater or equal than another waveform or real number.

A waveform is greater than or equal to another waveform or a number if
all elements of its dependent variable vector are greater than or equal
to, element-by-element, the elements of the dependent variable vector
of another waveform or a real number with :py:data:`peng.FP_ATOL`
absolute tolerance and :py:data:`peng.FP_RTOL` relative tolerance

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__ge__

:raises:
 * RuntimeError (Independent variable ranges do not overlap)

 * RuntimeError (Waveforms are not compatible)

 * TypeError (Complex operands not supported)

 * TypeError (Data type not supported)

.. [[[end]]]


try:<EOL><INDENT>ivector = self._indep_vector[key]<EOL>dvector = self._dep_vector[key]<EOL>return (<EOL>[Point(iitem, ditem) for iitem, ditem in zip(ivector, dvector)]<EOL>if isinstance(ivector, np.ndarray)<EOL>else Point(ivector, dvector)<EOL>)<EOL><DEDENT>except:<EOL><INDENT>raise<EOL><DEDENT>

Slice waveform.

:param key: Slice key
:type  key: integer or slice object

:returns: :py:data:`peng.Point` named tuple or list of
          :py:data:`peng.Point` named tuples

:raises: Same exceptions as an invalid Numpy array slicing operation


return self._operation(other, "<STR_LIT:>>")<EOL>

Test whether waveform is greater than another waveform or real number.

A waveform is greater than another waveform or a number if all elements
of its dependent variable vector are greater than, element-by-element,
the elements of the dependent variable vector of another waveform or a
real number with :py:data:`peng.FP_ATOL` absolute tolerance and
:py:data:`peng.FP_RTOL` relative tolerance

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__gt__

:raises:
 * RuntimeError (Independent variable ranges do not overlap)

 * RuntimeError (Waveforms are not compatible)

 * TypeError (Complex operands not supported)

 * TypeError (Data type not supported)

.. [[[end]]]


pexdoc.exh.addex(<EOL>TypeError,<EOL>"<STR_LIT>",<EOL>self._dep_vector.dtype.name.startswith("<STR_LIT>"),<EOL>)<EOL>obj = copy.copy(self)<EOL>obj.dep_name = "<STR_LIT>" + obj.dep_name<EOL>obj.dep_vector = np.invert(obj.dep_vector).astype(obj.dep_vector.dtype)<EOL>return obj<EOL>

Bit-wise inversion of the dependent variable vector of a waveform.

For example:

    >>> import math, numpy, peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector = np.array([6, 5, 4])
    >>> obj = peng.Waveform(indep_vector, dep_vector, 'obj')
    >>> print(~obj)
    Waveform: ~obj
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ -7, -6, -5 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__invert__

:raises: TypeError (Complex operand not supported)

.. [[[end]]]


for iitem, ditem in zip(self._indep_vector, self._dep_vector):<EOL><INDENT>yield iitem, ditem<EOL><DEDENT>

Return an iterable over the independent and dependent variable vectors.

Each item returned by an iterator is a :py:data:`peng.Point` named
tuple

:rtype: iterable


Test whether waveform is less than or equal to another waveform or real number.

A waveform is less than or equal to another waveform or a number if
all elements of its dependent variable vector are less than or equal
to, element-by-element, the elements of the dependent variable vector
of another waveform or a real number with :py:data:`peng.FP_ATOL`
absolute tolerance and :py:data:`peng.FP_RTOL` relative tolerance

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__le__

:raises:
 * RuntimeError (Independent variable ranges do not overlap)

 * RuntimeError (Waveforms are not compatible)

 * TypeError (Complex operands not supported)

 * TypeError (Data type not supported)

.. [[[end]]]


return len(self._indep_vector)<EOL>

Return number of elements in independent (or dependent) variable vector.


Left shift the dependent variable vector of a waveform.

The shift amount be set by the dependent variable vector of another
waveform or a number.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([8, 2, 4])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a<<obj_b)
    Waveform: obj_a<<obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 1024, 20, 96 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__lshift__

:raises:
 * RuntimeError (Independent variable ranges do not overlap)

 * RuntimeError (Waveforms are not compatible)

 * TypeError (Complex operands not supported)

 * TypeError (Data type not supported)

.. [[[end]]]


return self._operation(other, "<STR_LIT:<>")<EOL>

Test whether a waveform is less than another waveform or real number.

A waveform is less than another waveform or a number if all elements
of its dependent variable vector are less than, element-by-element,
the elements of the dependent variable vector of another waveform or a
real number with :py:data:`peng.FP_ATOL` absolute tolerance and
:py:data:`peng.FP_RTOL` relative tolerance

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__lt__

:raises:
 * RuntimeError (Independent variable ranges do not overlap)

 * RuntimeError (Waveforms are not compatible)

 * TypeError (Complex operands not supported)

 * TypeError (Data type not supported)

.. [[[end]]]


return self._operation(other, "<STR_LIT:%>")<EOL>

r"""
        Division reminder.

        The division reminder may be computed between the dependent variable
        vectors of two waveforms, between the dependent variable vector of a
        waveform and a number, or a number by the dependent variable vector of
        a waveform. In the latter case a :py:class:`peng.Waveform()` object is
        returned with the result.

        For example:

            >>> import numpy as np
            >>> import peng
            >>> indep_vector = np.array([1, 2, 3])
            >>> dep_vector_a = np.array([4, 5, 6])
            >>> dep_vector_b = np.array([8, 2, 4])
            >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
            >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
            >>> print(obj_a%obj_b)
            Waveform: obj_a%obj_b
            Independent variable: [ 1, 2, 3 ]
            Dependent variable: [ 4, 1, 2 ]
            Independent variable scale: LINEAR
            Dependent variable scale: LINEAR
            Independent variable units: (None)
            Dependent variable units: (None)
            Interpolating function: CONTINUOUS

        .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
        .. Auto-generated exceptions documentation for
        .. peng.wave_core.Waveform.__mod__

        :raises:
         * RuntimeError (Independent variable ranges do not overlap)

         * RuntimeError (Waveforms are not compatible)

         * TypeError (Complex operands not supported)

         * TypeError (Data type not supported)

        .. [[[end]]]


return self._operation(other, "<STR_LIT:*>")<EOL>

Multiply the dependent variable vector of a waveform.

The multiplication may be computed element-by-element using another the
dependent variable vector of another waveform or a number.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([8, 2, 4])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a*obj_b)
    Waveform: obj_a*obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 32, 10, 24 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__mul__

:raises:
 * RuntimeError (Waveforms are not compatible)

 * TypeError (Data type not supported)

.. [[[end]]]


return not self.__eq__(other)<EOL>

Test waveform inequality.

Two waveforms are considered unequal if their independent variable
vectors are different with :py:data:`peng.FP_ATOL` absolute tolerance
and :py:data:`peng.FP_RTOL` relative tolerance, and/or their dependent
variable vectors are different with :py:data:`peng.FP_ATOL` absolute
tolerance and :py:data:`peng.FP_RTOL` relative tolerance, and/or their
independent variable scales are not the same, and/or their dependent
variable scales are not the, and/or their independent variable units
are not the same, and/or their dependent variable units are not the
same and/or they do not have the same interpolation function.

A waveform is considered unequal to a real number when its dependent
variable is not equal to that number at least in one element.


obj = copy.copy(self)<EOL>obj.dep_name = "<STR_LIT:->" + obj.dep_name<EOL>obj.dep_vector = -<NUM_LIT:1> * obj.dep_vector<EOL>return obj<EOL>

Multiply the dependent variable vector by -1.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector = np.array([4, -5, 6])
    >>> obj = peng.Waveform(indep_vector, dep_vector, 'obj')
    >>> print(-obj)
    Waveform: -obj
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ -4, 5, -6 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS


Test if the waveform dependent vector is zero for all its elements.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector = np.array([4, 5, 6])
    >>> obj = peng.Waveform(indep_vector, dep_vector, 'obj_a')
    >>> if obj:
    ...     print('Boolean test returned: True')
    ... else:
    ...     print('Boolean test returned: False')
    Boolean test returned: True
    >>> dep_vector = np.zeros(3)
    >>> obj = peng.Waveform(indep_vector, dep_vector, 'obj_a')
    >>> if obj:
    ...     print('Boolean test returned: True')
    ... else:
    ...     print('Boolean test returned: False')
    Boolean test returned: False


return self._operation(other, "<STR_LIT:|>")<EOL>

Bit-wise logic or the dependent variable of a waveform.

The other operand may be the dependent variable vector of another
waveform or a number.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([8, 2, 4])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a|obj_b)
    Waveform: obj_a|obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 12, 7, 6 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__or__

:raises:
 * RuntimeError (Independent variable ranges do not overlap)

 * RuntimeError (Waveforms are not compatible)

 * TypeError (Complex operands not supported)

 * TypeError (Data type not supported)

.. [[[end]]]


return copy.copy(self)<EOL>

Multiply the dependent variable vector of a waveform by +1.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector = np.array([4, 5, 6])
    >>> obj = peng.Waveform(indep_vector, dep_vector, 'obj')
    >>> print(+obj)
    Waveform: obj
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 4, 5, 6 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS


Raise the dependent variable vector of a waveform to a power exponent.

The exponent specified by the dependent variable vector of another
waveform, the dependent variable vector of a waveform to the power
specified by a number, or a number by the power specified by the
dependent variable vector of a waveform. In the latter case a
:py:class:`peng.Waveform()` object is returned with the result.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([8, 2, 4])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a**obj_b)
    Waveform: obj_a**obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 65536, 25, 1296 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__pow__

:raises:
 * RuntimeError (Independent variable ranges do not overlap)

 * RuntimeError (Waveforms are not compatible)

 * TypeError (Data type not supported)

 * ValueError (Integers to negative integer powers are not allowed)

.. [[[end]]]


return self._operation(other, "<STR_LIT:+>")<EOL>

Reflected addition.

See :py:meth:`peng.Waveform.__add__` for more details


return self._operation(other, "<STR_LIT:&>", reflected=True)<EOL>

Reflected bit-wise logic and.

See :py:meth:`peng.Waveform.__and__` for more details


return self._operation(other, "<STR_LIT:/>", reflected=True)<EOL>

Reflected division.

See :py:meth:`peng.Waveform.__div__` for more details


r"""
        Return a string with the expression needed to re-create the object.

        For example:

            >>> import numpy as np
            >>> import peng
            >>> obj = peng.Waveform(
            ...     np.array([1, 2, 3]),
            ...     np.array([4, 5, 6]),
            ...     'test'
            ... )
            >>> repr(obj)
            "peng.Waveform(indep_vector=array([1, 2, 3]), dep_vector=array([4, 5, 6]), dep_name='test', indep_scale='LINEAR', dep_scale='LINEAR', indep_units='', dep_units='', interp='CONTINUOUS')"


return self._operation(other, "<STR_LIT>", reflected=True)<EOL>

Reflected floor (integer) division.

See :py:meth:`peng.Waveform.__floordiv__` for more details


Reflected left shift.

See :py:meth:`peng.Waveform.__lshift__` for more details


return self._operation(other, "<STR_LIT:%>", reflected=True)<EOL>

Reflected division.

See :py:meth:`peng.Waveform.__mod__` for more details


Reflected multiplication.

See :py:meth:`peng.Waveform.__mul__` for more details


return self._operation(other, "<STR_LIT:|>", reflected=True)<EOL>

Reflected bit-wise logic or.

See :py:meth:`peng.Waveform.__or__` for more details


Reflected power.

See :py:meth:`peng.Waveform.__pow__` for more details


Reflected right shift.

See :py:meth:`peng.Waveform.__rshift__` for more details


Right shift the dependent variable vector of a waveform.

The shift amount be set by the dependent variable vector of another
waveform or a number.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([1, 2, 1])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a>>obj_b)
    Waveform: obj_a>>obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 2, 1, 3 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__rshift__

:raises:
 * RuntimeError (Independent variable ranges do not overlap)

 * RuntimeError (Waveforms are not compatible)

 * TypeError (Complex operands not supported)

 * TypeError (Data type not supported)

.. [[[end]]]


return self._operation(other, "<STR_LIT:->")<EOL>

Reflected subtraction.

See :py:meth:`peng.Waveform.__sub__` for more details


Reflected true (floating) division.

See :py:meth:`peng.Waveform.__truediv__` for more details


Reflected bit-wise logic exclusive or .

See :py:meth:`peng.Waveform.__xor__` for more details


value = [value] if isinstance(value, tuple) else value<EOL>if (<EOL>(value is None)<EOL>or (not isinstance(value, list))<EOL>or (isinstance(value, list) and (not value))<EOL>):<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>if not all([isinstance(item, tuple) for item in value]):<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>if not all([len(item) == <NUM_LIT:2> for item in value]):<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>ivector, dvector = zip(*value)<EOL>ivector = np.array(ivector)<EOL>itype = ivector.dtype.name<EOL>valid_types = ["<STR_LIT:int>", "<STR_LIT:float>"]<EOL>if not any([itype.startswith(item) for item in valid_types]):<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>valid_types = ["<STR_LIT:int>", "<STR_LIT:float>", "<STR_LIT>"]<EOL>dvector = np.array(dvector)<EOL>dtype = dvector.dtype.name<EOL>if not any([dtype.startswith(item) for item in valid_types]):<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>valid_types = ["<STR_LIT:int>", "<STR_LIT:float>"]<EOL>stype = self._indep_vector.dtype.name<EOL>vnum = <NUM_LIT:0><EOL>for vnum, item in enumerate(valid_types):  <EOL><INDENT>if itype.startswith(item):<EOL><INDENT>break<EOL><DEDENT><DEDENT>snum = <NUM_LIT:0><EOL>for snum, item in enumerate(valid_types):  <EOL><INDENT>if stype.startswith(item):<EOL><INDENT>break<EOL><DEDENT><DEDENT>nresult = max(snum, vnum)<EOL>if nresult > snum:<EOL><INDENT>ntype = [np.int, np.float, np.complex][nresult]<EOL>self._indep_vector = self._indep_vector.astype(ntype)<EOL><DEDENT>valid_types = ["<STR_LIT:int>", "<STR_LIT:float>", "<STR_LIT>"]<EOL>stype = self._dep_vector.dtype.name<EOL>vnum = <NUM_LIT:0><EOL>for vnum, item in enumerate(valid_types):  <EOL><INDENT>if dtype.startswith(item):<EOL><INDENT>break<EOL><DEDENT><DEDENT>snum = <NUM_LIT:0><EOL>for snum, item in enumerate(valid_types):  <EOL><INDENT>if stype.startswith(item):<EOL><INDENT>break<EOL><DEDENT><DEDENT>nresult = max(snum, vnum)<EOL>if nresult > snum:<EOL><INDENT>ntype = [np.int, np.float, np.complex][nresult]<EOL>self._dep_vector = self._dep_vector.astype(ntype)<EOL><DEDENT>try:<EOL><INDENT>self._indep_vector[key] = ivector if len(ivector) > <NUM_LIT:1> else ivector[<NUM_LIT:0>]<EOL>if min(np.diff(self._indep_vector)) <= <NUM_LIT:0>:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>self._dep_vector[key] = dvector if len(dvector) > <NUM_LIT:1> else dvector[<NUM_LIT:0>]<EOL><DEDENT>except:<EOL><INDENT>raise<EOL><DEDENT>

Assign a waveform slice.

:param key: Slice key
:type  key: integer or slice object

:param value: Slice value
:type  value: 2-item tuple or list of 2-item tuples

:raises:
 * Argument `value` is not valid

 * Same exceptions as an invalid Numpy array slicing operation


ret = "<STR_LIT>"<EOL>ret += "<STR_LIT>".format(self._dep_name)<EOL>ret += (<EOL>"<STR_LIT>"<EOL>+ pprint_vector(<EOL>vector=self._indep_vector, width=<NUM_LIT> - <NUM_LIT>, limit=True, indent=<NUM_LIT><EOL>)<EOL>+ "<STR_LIT:\n>"<EOL>)<EOL>ret += (<EOL>"<STR_LIT>"<EOL>+ pprint_vector(<EOL>vector=self._dep_vector, width=<NUM_LIT> - <NUM_LIT:20>, limit=True, indent=<NUM_LIT:20><EOL>)<EOL>+ "<STR_LIT:\n>"<EOL>)<EOL>ret += "<STR_LIT>".format(self._indep_scale)<EOL>ret += "<STR_LIT>".format(self._dep_scale)<EOL>ret += "<STR_LIT>".format(<EOL>self._indep_units if self._indep_units else "<STR_LIT>"<EOL>)<EOL>ret += "<STR_LIT>".format(<EOL>self._dep_units if self._dep_units else "<STR_LIT>"<EOL>)<EOL>ret += "<STR_LIT>".format(self._interp)<EOL>return ret<EOL>

Return a string with a detailed description of the object's contents.

For example:

    >>> from __future__ import print_function
    >>> import numpy as np
    >>> import peng
    >>> obj = peng.Waveform(
    ...     np.array([1, 2, 3]),
    ...     np.array([4, 5, 6]),
    ...     'test'
    ... )
    >>> print(obj)
    Waveform: test
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 4, 5, 6 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS


Subtract two waveforms, waveform by a number or a number by a waveform.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([8, 2, 4])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a-obj_b)
    Waveform: obj_a-obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ -4, 3, 2 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__sub__

:raises:
 * RuntimeError (Waveforms are not compatible)

 * TypeError (Data type not supported)

.. [[[end]]]


return self._operation(other, "<STR_LIT:/>")<EOL>

Divide (true division) the dependent variable vector of a waveform.

The division may be between the dependent variable vector of a waveform
by the dependent variable vector of another waveform, the dependent
variable vector of a waveform by a number, or a number by the dependent
variable vector of a waveform. In the latter case a
:py:class:`peng.Waveform()` object is returned with the result.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([8.0, 2.0, 4.0])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a/obj_b)
    Waveform: obj_a/obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 0.5, 2.5, 1.5 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_doc(cname, no_comment=True)) ]]]

:raises:
 * RuntimeError (Waveforms are not compatible)

 * TypeError (Data type not supported)

.. [[[end]]]


return self._operation(other, "<STR_LIT>")<EOL>

Bit-wise logic exclusive or waveform operation.

For example:

    >>> import numpy as np
    >>> import peng
    >>> indep_vector = np.array([1, 2, 3])
    >>> dep_vector_a = np.array([4, 5, 6])
    >>> dep_vector_b = np.array([8, 2, 4])
    >>> obj_a = peng.Waveform(indep_vector, dep_vector_a, 'obj_a')
    >>> obj_b = peng.Waveform(indep_vector, dep_vector_b, 'obj_b')
    >>> print(obj_a^obj_b)
    Waveform: obj_a^obj_b
    Independent variable: [ 1, 2, 3 ]
    Dependent variable: [ 12, 7, 2 ]
    Independent variable scale: LINEAR
    Dependent variable scale: LINEAR
    Independent variable units: (None)
    Dependent variable units: (None)
    Interpolating function: CONTINUOUS

.. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
.. Auto-generated exceptions documentation for
.. peng.wave_core.Waveform.__xor__

:raises:
 * RuntimeError (Independent variable ranges do not overlap)

 * RuntimeError (Waveforms are not compatible)

 * TypeError (Complex operands not supported)

 * TypeError (Data type not supported)

.. [[[end]]]


def _bound_waveform(wave, indep_min, indep_max):

indep_min, indep_max = _validate_min_max(wave, indep_min, indep_max)<EOL>indep_vector = copy.copy(wave._indep_vector)<EOL>if (<EOL>isinstance(indep_min, float) or isinstance(indep_max, float)<EOL>) and indep_vector.dtype.name.startswith("<STR_LIT:int>"):<EOL><INDENT>indep_vector = indep_vector.astype(float)<EOL><DEDENT>min_pos = np.searchsorted(indep_vector, indep_min)<EOL>if not np.isclose(indep_min, indep_vector[min_pos], FP_RTOL, FP_ATOL):<EOL><INDENT>indep_vector = np.insert(indep_vector, min_pos, indep_min)<EOL><DEDENT>max_pos = np.searchsorted(indep_vector, indep_max)<EOL>if not np.isclose(indep_max, indep_vector[max_pos], FP_RTOL, FP_ATOL):<EOL><INDENT>indep_vector = np.insert(indep_vector, max_pos, indep_max)<EOL><DEDENT>dep_vector = _interp_dep_vector(wave, indep_vector)<EOL>wave._indep_vector = indep_vector[min_pos : max_pos + <NUM_LIT:1>]<EOL>wave._dep_vector = dep_vector[min_pos : max_pos + <NUM_LIT:1>]<EOL>

Add independent variable vector bounds if they are not in vector.


def _build_units(indep_units, dep_units, op):

if (not dep_units) and (not indep_units):<EOL><INDENT>return "<STR_LIT>"<EOL><DEDENT>if dep_units and (not indep_units):<EOL><INDENT>return dep_units<EOL><DEDENT>if (not dep_units) and indep_units:<EOL><INDENT>return (<EOL>remove_extra_delims("<STR_LIT>".format(op, indep_units))<EOL>if op == "<STR_LIT:/>"<EOL>else remove_extra_delims("<STR_LIT>".format(indep_units))<EOL>)<EOL><DEDENT>return remove_extra_delims("<STR_LIT>".format(dep_units, op, indep_units))<EOL>


def _operation(wave, desc, units, fpointer):

ret = copy.copy(wave)<EOL>ret.dep_units = units<EOL>ret.dep_name = "<STR_LIT>".format(desc, ret.dep_name)<EOL>ret._dep_vector = fpointer(ret._dep_vector)<EOL>return ret<EOL>

Perform generic operation on a waveform object.


rect_height = np.minimum(dep_vector[:-<NUM_LIT:1>], dep_vector[<NUM_LIT:1>:])<EOL>rect_base = np.diff(indep_vector)<EOL>rect_area = np.multiply(rect_height, rect_base)<EOL>triang_height = np.abs(np.diff(dep_vector))<EOL>triang_area = <NUM_LIT:0.5> * np.multiply(triang_height, rect_base)<EOL>return np.cumsum(np.concatenate((np.array([<NUM_LIT:0.0>]), triang_area + rect_area)))<EOL>


def _validate_min_max(wave, indep_min, indep_max):

imin, imax = False, False<EOL>if indep_min is None:<EOL><INDENT>indep_min = wave._indep_vector[<NUM_LIT:0>]<EOL>imin = True<EOL><DEDENT>if indep_max is None:<EOL><INDENT>indep_max = wave._indep_vector[-<NUM_LIT:1>]<EOL>imax = True<EOL><DEDENT>if imin and imax:<EOL><INDENT>return indep_min, indep_max<EOL><DEDENT>exminmax = pexdoc.exh.addex(<EOL>RuntimeError, "<STR_LIT>"<EOL>)<EOL>exmin = pexdoc.exh.addai("<STR_LIT>")<EOL>exmax = pexdoc.exh.addai("<STR_LIT>")<EOL>exminmax(bool(indep_min >= indep_max))<EOL>exmin(<EOL>bool(<EOL>(indep_min < wave._indep_vector[<NUM_LIT:0>])<EOL>and (not np.isclose(indep_min, wave._indep_vector[<NUM_LIT:0>], FP_RTOL, FP_ATOL))<EOL>)<EOL>)<EOL>exmax(<EOL>bool(<EOL>(indep_max > wave._indep_vector[-<NUM_LIT:1>])<EOL>and (not np.isclose(indep_max, wave._indep_vector[-<NUM_LIT:1>], FP_RTOL, FP_ATOL))<EOL>)<EOL>)<EOL>return indep_min, indep_max<EOL>

Validate min and max bounds are within waveform's independent variable vector.


pexdoc.exh.addex(<EOL>ValueError,<EOL>"<STR_LIT>",<EOL>bool((min(wave._dep_vector) < -<NUM_LIT:1>) or (max(wave._dep_vector) > <NUM_LIT:1>)),<EOL>)<EOL>return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.arccos)<EOL>

r"""
    Return the arc cosine of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.acos

    :raises:
     * RuntimeError (Argument \`wave\` is not valid)

     * ValueError (Math domain error)

    .. [[[end]]]


pexdoc.exh.addex(ValueError, "<STR_LIT>", bool(min(wave._dep_vector) < <NUM_LIT:1>))<EOL>return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.arccosh)<EOL>

r"""
    Return the hyperbolic arc cosine of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.acosh

    :raises:
     * RuntimeError (Argument \`wave\` is not valid)

     * ValueError (Math domain error)

    .. [[[end]]]


pexdoc.exh.addex(<EOL>ValueError,<EOL>"<STR_LIT>",<EOL>bool((min(wave._dep_vector) < -<NUM_LIT:1>) or (max(wave._dep_vector) > <NUM_LIT:1>)),<EOL>)<EOL>return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.arcsin)<EOL>

r"""
    Return the arc sine of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.asin

    :raises:
     * RuntimeError (Argument \`wave\` is not valid)

     * ValueError (Math domain error)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.arcsinh)<EOL>

r"""
    Return the hyperbolic arc sine of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.asinh

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.arctan)<EOL>

r"""
    Return the arc tangent of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.atan

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


pexdoc.exh.addex(<EOL>ValueError,<EOL>"<STR_LIT>",<EOL>bool((min(wave._dep_vector) < -<NUM_LIT:1>) or (max(wave._dep_vector) > <NUM_LIT:1>)),<EOL>)<EOL>return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.arctanh)<EOL>

r"""
    Return the hyperbolic arc tangent of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.atanh

    :raises:
     * RuntimeError (Argument \`wave\` is not valid)

     * ValueError (Math domain error)

    .. [[[end]]]


@pexdoc.pcontracts.contract(<EOL>wave=Waveform, indep_min="<STR_LIT>", indep_max="<STR_LIT>"<EOL>)<EOL>def average(wave, indep_min=None, indep_max=None):

ret = copy.copy(wave)<EOL>_bound_waveform(ret, indep_min, indep_max)<EOL>area = _running_area(ret._indep_vector, ret._dep_vector)<EOL>area[<NUM_LIT:0>] = ret._dep_vector[<NUM_LIT:0>]<EOL>deltas = ret._indep_vector - ret._indep_vector[<NUM_LIT:0>]<EOL>deltas[<NUM_LIT:0>] = <NUM_LIT:1.0><EOL>ret._dep_vector = np.divide(area, deltas)<EOL>ret.dep_name = "<STR_LIT>".format(ret._dep_name)<EOL>return ret<EOL>

r"""
    Return the running average of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.average

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", wave.dep_units, np.ceil)<EOL>

r"""
    Return the ceiling of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.ceil

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.cos)<EOL>

r"""
    Return the cosine of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for peng.wave_functions.cos

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.cosh)<EOL>

r"""
    Return the hyperbolic cosine of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.cosh

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


pexdoc.exh.addex(<EOL>ValueError, "<STR_LIT>", bool((np.min(np.abs(wave._dep_vector)) <= <NUM_LIT:0>))<EOL>)<EOL>ret = copy.copy(wave)<EOL>ret.dep_units = "<STR_LIT>"<EOL>ret.dep_name = "<STR_LIT>".format(ret.dep_name)<EOL>ret._dep_vector = <NUM_LIT> * np.log10(np.abs(ret._dep_vector))<EOL>return ret<EOL>

r"""
    Return a waveform's dependent variable vector expressed in decibels.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for peng.wave_functions.db

    :raises:
     * RuntimeError (Argument \`wave\` is not valid)

     * ValueError (Math domain error)

    .. [[[end]]]


@pexdoc.pcontracts.contract(<EOL>wave=Waveform, indep_min="<STR_LIT>", indep_max="<STR_LIT>"<EOL>)<EOL>def derivative(wave, indep_min=None, indep_max=None):

ret = copy.copy(wave)<EOL>_bound_waveform(ret, indep_min, indep_max)<EOL>delta_indep = np.diff(ret._indep_vector)<EOL>delta_dep = np.diff(ret._dep_vector)<EOL>delta_indep = np.concatenate((np.array([delta_indep[<NUM_LIT:0>]]), delta_indep))<EOL>delta_dep = np.concatenate((np.array([delta_dep[<NUM_LIT:0>]]), delta_dep))<EOL>ret._dep_vector = np.divide(delta_dep, delta_indep)<EOL>ret.dep_name = "<STR_LIT>".format(ret._dep_name)<EOL>ret.dep_units = _build_units(ret.indep_units, ret.dep_units, "<STR_LIT:/>")<EOL>return ret<EOL>

r"""
    Return the numerical derivative of a waveform's dependent variable vector.

    The method used is the `backwards differences
    <https://en.wikipedia.org/wiki/
    Finite_difference#Forward.2C_backward.2C_and_central_differences>`_ method

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: float

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.derivative

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.exp)<EOL>

r"""
    Return the natural exponent of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for peng.wave_functions.exp

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


ret = copy.copy(wave)<EOL>_bound_waveform(ret, indep_min, indep_max)<EOL>npoints = npoints or ret._indep_vector.size<EOL>fs = (npoints - <NUM_LIT:1>) / float(ret._indep_vector[-<NUM_LIT:1>])<EOL>spoints = min(ret._indep_vector.size, npoints)<EOL>sdiff = np.diff(ret._indep_vector[:spoints])<EOL>cond = not np.all(<EOL>np.isclose(sdiff, sdiff[<NUM_LIT:0>] * np.ones(spoints - <NUM_LIT:1>), FP_RTOL, FP_ATOL)<EOL>)<EOL>pexdoc.addex(RuntimeError, "<STR_LIT>", cond)<EOL>finc = fs / float(npoints - <NUM_LIT:1>)<EOL>indep_vector = _barange(-fs / <NUM_LIT>, +fs / <NUM_LIT>, finc)<EOL>dep_vector = np.fft.fft(ret._dep_vector, npoints)<EOL>return Waveform(<EOL>indep_vector=indep_vector,<EOL>dep_vector=dep_vector,<EOL>dep_name="<STR_LIT>".format(ret.dep_name),<EOL>indep_scale="<STR_LIT>",<EOL>dep_scale="<STR_LIT>",<EOL>indep_units="<STR_LIT>",<EOL>dep_units="<STR_LIT>",<EOL>)<EOL>

r"""
    Return the Fast Fourier Transform of a waveform.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for peng.wave_functions.fft

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform sampling)

    .. [[[end]]]


return db(fft(wave, npoints, indep_min, indep_max))<EOL>

r"""
    Return the Fast Fourier Transform of a waveform.

    The dependent variable vector of the returned waveform is expressed in decibels

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.fftdb

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform sampling)

    .. [[[end]]]


return imag(fft(wave, npoints, indep_min, indep_max))<EOL>

r"""
    Return the imaginary part of the Fast Fourier Transform of a waveform.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.ffti

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform sampling)

    .. [[[end]]]


return abs(fft(wave, npoints, indep_min, indep_max))<EOL>

r"""
    Return the magnitude of the Fast Fourier Transform of a waveform.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.fftm

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform sampling)

    .. [[[end]]]


return phase(fft(wave, npoints, indep_min, indep_max), unwrap=unwrap, rad=rad)<EOL>

r"""
    Return the phase of the Fast Fourier Transform of a waveform.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :param unwrap: Flag that indicates whether phase should change phase shifts
                   to their :code:`2*pi` complement (True) or not (False)
    :type  unwrap: boolean

    :param rad: Flag that indicates whether phase should be returned in radians
                (True) or degrees (False)
    :type  rad: boolean

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.fftp

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`rad\` is not valid)

     * RuntimeError (Argument \`unwrap\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform sampling)

    .. [[[end]]]


return real(fft(wave, npoints, indep_min, indep_max))<EOL>

r"""
    Return the real part of the Fast Fourier Transform of a waveform.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.fftr

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform sampling)

    .. [[[end]]]


<EOL>ret = copy.copy(wave)<EOL>_bound_waveform(ret, indep_min, indep_max)<EOL>close_min = np.isclose(min(ret._dep_vector), dep_var, FP_RTOL, FP_ATOL)<EOL>close_max = np.isclose(max(ret._dep_vector), dep_var, FP_RTOL, FP_ATOL)<EOL>if ((np.amin(ret._dep_vector) > dep_var) and (not close_min)) or (<EOL>(np.amax(ret._dep_vector) < dep_var) and (not close_max)<EOL>):<EOL><INDENT>return None<EOL><DEDENT>cross_wave = ret._dep_vector - dep_var<EOL>sign_wave = np.sign(cross_wave)<EOL>exact_idx = np.where(np.isclose(ret._dep_vector, dep_var, FP_RTOL, FP_ATOL))[<NUM_LIT:0>]<EOL>left_idx = np.where(np.diff(sign_wave))[<NUM_LIT:0>]<EOL>left_idx = np.setdiff1d(left_idx, exact_idx)<EOL>left_idx = np.setdiff1d(left_idx, exact_idx - <NUM_LIT:1>)<EOL>right_idx = left_idx + <NUM_LIT:1> if left_idx.size else np.array([])<EOL>indep_var = ret._indep_vector[exact_idx] if exact_idx.size else np.array([])<EOL>dvector = np.zeros(exact_idx.size).astype(int) if exact_idx.size else np.array([])<EOL>if left_idx.size and (ret.interp == "<STR_LIT>"):<EOL><INDENT>idvector = (<EOL><NUM_LIT> * (ret._dep_vector[right_idx] > ret._dep_vector[left_idx]).astype(int)<EOL>- <NUM_LIT:1><EOL>)<EOL>if indep_var.size:<EOL><INDENT>indep_var = np.concatenate((indep_var, ret._indep_vector[right_idx]))<EOL>dvector = np.concatenate((dvector, idvector))<EOL>sidx = np.argsort(indep_var)<EOL>indep_var = indep_var[sidx]<EOL>dvector = dvector[sidx]<EOL><DEDENT>else:<EOL><INDENT>indep_var = ret._indep_vector[right_idx]<EOL>dvector = idvector<EOL><DEDENT><DEDENT>elif left_idx.size:<EOL><INDENT>y_left = ret._dep_vector[left_idx]<EOL>y_right = ret._dep_vector[right_idx]<EOL>x_left = ret._indep_vector[left_idx]<EOL>x_right = ret._indep_vector[right_idx]<EOL>slope = ((y_left - y_right) / (x_left - x_right)).astype(float)<EOL>if indep_var.size:<EOL><INDENT>indep_var = np.concatenate(<EOL>(indep_var, x_left + ((dep_var - y_left) / slope))<EOL>)<EOL>dvector = np.concatenate((dvector, np.where(slope > <NUM_LIT:0>, <NUM_LIT:1>, -<NUM_LIT:1>)))<EOL>sidx = np.argsort(indep_var)<EOL>indep_var = indep_var[sidx]<EOL>dvector = dvector[sidx]<EOL><DEDENT>else:<EOL><INDENT>indep_var = x_left + ((dep_var - y_left) / slope)<EOL>dvector = np.where(slope > <NUM_LIT:0>, +<NUM_LIT:1>, -<NUM_LIT:1>)<EOL><DEDENT><DEDENT>if der is not None:<EOL><INDENT>indep_var = np.extract(dvector == der, indep_var)<EOL><DEDENT>return indep_var[inst - <NUM_LIT:1>] if inst <= indep_var.size else None<EOL>

r"""
    Return the independent variable point associated with a dependent variable point.

    If the dependent variable point is not in the dependent variable vector the
    independent variable vector point is obtained by linear interpolation

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param dep_var: Dependent vector value to search for
    :type  dep_var: integer, float or complex

    :param der: Dependent vector derivative filter. If +1 only independent
                vector points that have positive derivatives when crossing
                the requested dependent vector point are returned; if -1 only
                independent vector points that have negative derivatives when
                crossing the requested dependent vector point are returned;
                if 0 only independent vector points that have null derivatives
                when crossing the requested dependent vector point are
                returned; otherwise if None all independent vector points are
                returned regardless of the dependent vector derivative. The
                derivative of the first and last point of the waveform is
                assumed to be null
    :type  der: integer, float or complex

    :param inst: Instance number filter. If, for example, **inst** equals 3,
                 then the independent variable vector point at which the
                 dependent variable vector equals the requested value for the
                 third time is returned
    :type  inst: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: integer, float or None if the dependent variable point is not found

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.find

    :raises:
     * RuntimeError (Argument \`dep_var\` is not valid)

     * RuntimeError (Argument \`der\` is not valid)

     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`inst\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", wave.dep_units, np.floor)<EOL>

r"""
    Return the floor of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.floor

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


ret = copy.copy(wave)<EOL>_bound_waveform(ret, indep_min, indep_max)<EOL>npoints = npoints or ret._indep_vector.size<EOL>spoints = min(ret._indep_vector.size, npoints)<EOL>sdiff = np.diff(ret._indep_vector[:spoints])<EOL>finc = sdiff[<NUM_LIT:0>]<EOL>cond = not np.all(np.isclose(sdiff, finc * np.ones(spoints - <NUM_LIT:1>), FP_RTOL, FP_ATOL))<EOL>pexdoc.addex(RuntimeError, "<STR_LIT>", cond)<EOL>fs = (npoints - <NUM_LIT:1>) * finc<EOL>tinc = <NUM_LIT:1> / float(fs)<EOL>tend = <NUM_LIT:1> / float(finc)<EOL>indep_vector = _barange(<NUM_LIT:0>, tend, tinc)<EOL>dep_vector = np.fft.ifft(ret._dep_vector, npoints)<EOL>return Waveform(<EOL>indep_vector=indep_vector,<EOL>dep_vector=dep_vector,<EOL>dep_name="<STR_LIT>".format(ret.dep_name),<EOL>indep_scale="<STR_LIT>",<EOL>dep_scale="<STR_LIT>",<EOL>indep_units="<STR_LIT>",<EOL>dep_units="<STR_LIT>",<EOL>)<EOL>

r"""
    Return the inverse Fast Fourier Transform of a waveform.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.ifft

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform frequency spacing)

    .. [[[end]]]


return db(ifft(wave, npoints, indep_min, indep_max))<EOL>

r"""
    Return the inverse Fast Fourier Transform of a waveform.

    The dependent variable vector of the returned waveform is expressed in decibels

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.ifftdb

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform frequency spacing)

    .. [[[end]]]


return imag(ifft(wave, npoints, indep_min, indep_max))<EOL>

r"""
    Return the imaginary part of the inverse Fast Fourier Transform of a waveform.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.iffti

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform frequency spacing)

    .. [[[end]]]


return abs(ifft(wave, npoints, indep_min, indep_max))<EOL>

r"""
    Return the magnitude of the inverse Fast Fourier Transform of a waveform.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.ifftm

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform frequency spacing)

    .. [[[end]]]


return phase(ifft(wave, npoints, indep_min, indep_max), unwrap=unwrap, rad=rad)<EOL>

r"""
    Return the phase of the inverse Fast Fourier Transform of a waveform.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :param unwrap: Flag that indicates whether phase should change phase shifts
                   to their :code:`2*pi` complement (True) or not (False)
    :type  unwrap: boolean

    :param rad: Flag that indicates whether phase should be returned in radians
                (True) or degrees (False)
    :type  rad: boolean

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.ifftp

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`rad\` is not valid)

     * RuntimeError (Argument \`unwrap\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform frequency spacing)

    .. [[[end]]]


return real(ifft(wave, npoints, indep_min, indep_max))<EOL>

r"""
    Return the real part of the inverse Fast Fourier Transform of a waveform.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param npoints: Number of points to use in the transform. If **npoints**
                    is less than the size of the independent variable vector
                    the waveform is truncated; if **npoints** is greater than
                    the size of the independent variable vector, the waveform
                    is zero-padded
    :type  npoints: positive integer

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.ifftr

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`npoints\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

     * RuntimeError (Non-uniform frequency spacing)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", wave.dep_units, np.imag)<EOL>

r"""
    Return the imaginary part of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.imag

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


@pexdoc.pcontracts.contract(<EOL>wave=Waveform, indep_min="<STR_LIT>", indep_max="<STR_LIT>"<EOL>)<EOL>def integral(wave, indep_min=None, indep_max=None):

ret = copy.copy(wave)<EOL>_bound_waveform(ret, indep_min, indep_max)<EOL>ret._dep_vector = _running_area(ret._indep_vector, ret._dep_vector)<EOL>ret.dep_name = "<STR_LIT>".format(ret._dep_name)<EOL>ret.dep_units = _build_units(ret.indep_units, ret.dep_units, "<STR_LIT:*>")<EOL>return ret<EOL>

r"""
    Return the running integral of a waveform's dependent variable vector.

    The method used is the `trapezoidal
    <https://en.wikipedia.org/wiki/Trapezoidal_rule>`_ method

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.integral

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

    .. [[[end]]]


ret = -derivative(phase(wave, unwrap=True) / (<NUM_LIT:2> * math.pi))<EOL>ret.dep_name = "<STR_LIT>".format(wave.dep_name)<EOL>ret.dep_units = "<STR_LIT>"<EOL>return ret<EOL>

r"""
    Return the group delay of a waveform.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.group_delay

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


pexdoc.exh.addex(<EOL>ValueError, "<STR_LIT>", bool((min(wave._dep_vector) <= <NUM_LIT:0>))<EOL>)<EOL>return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.log)<EOL>

r"""
    Return the natural logarithm of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for peng.wave_functions.log

    :raises:
     * RuntimeError (Argument \`wave\` is not valid)

     * ValueError (Math domain error)

    .. [[[end]]]


pexdoc.exh.addex(<EOL>ValueError, "<STR_LIT>", bool((min(wave._dep_vector) <= <NUM_LIT:0>))<EOL>)<EOL>return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.log10)<EOL>

r"""
    Return the base 10 logarithm of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.log10

    :raises:
     * RuntimeError (Argument \`wave\` is not valid)

     * ValueError (Math domain error)

    .. [[[end]]]


@pexdoc.pcontracts.contract(<EOL>wave=Waveform, indep_min="<STR_LIT>", indep_max="<STR_LIT>"<EOL>)<EOL>def naverage(wave, indep_min=None, indep_max=None):

ret = copy.copy(wave)<EOL>_bound_waveform(ret, indep_min, indep_max)<EOL>delta_x = ret._indep_vector[-<NUM_LIT:1>] - ret._indep_vector[<NUM_LIT:0>]<EOL>return np.trapz(ret._dep_vector, x=ret._indep_vector) / delta_x<EOL>

r"""
    Return the numerical average of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.naverage

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

    .. [[[end]]]


@pexdoc.pcontracts.contract(<EOL>wave=Waveform, indep_min="<STR_LIT>", indep_max="<STR_LIT>"<EOL>)<EOL>def nintegral(wave, indep_min=None, indep_max=None):

ret = copy.copy(wave)<EOL>_bound_waveform(ret, indep_min, indep_max)<EOL>return np.trapz(ret._dep_vector, ret._indep_vector)<EOL>

r"""
    Return the numerical integral of a waveform's dependent variable vector.

    The method used is the `trapezoidal
    <https://en.wikipedia.org/wiki/Trapezoidal_rule>`_ method

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: float

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.nintegral

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

    .. [[[end]]]


@pexdoc.pcontracts.contract(<EOL>wave=Waveform, indep_min="<STR_LIT>", indep_max="<STR_LIT>"<EOL>)<EOL>def nmax(wave, indep_min=None, indep_max=None):

ret = copy.copy(wave)<EOL>_bound_waveform(ret, indep_min, indep_max)<EOL>return np.max(ret._dep_vector)<EOL>

r"""
    Return the maximum of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: float

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.nmax

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

    .. [[[end]]]


@pexdoc.pcontracts.contract(<EOL>wave=Waveform, indep_min="<STR_LIT>", indep_max="<STR_LIT>"<EOL>)<EOL>def nmin(wave, indep_min=None, indep_max=None):

ret = copy.copy(wave)<EOL>_bound_waveform(ret, indep_min, indep_max)<EOL>return np.min(ret._dep_vector)<EOL>

r"""
    Return the minimum of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :rtype: float

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.nmin

    :raises:
     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

    .. [[[end]]]


@pexdoc.pcontracts.contract(wave=Waveform, unwrap=bool, rad=bool)<EOL>def phase(wave, unwrap=True, rad=True):

ret = copy.copy(wave)<EOL>ret.dep_units = "<STR_LIT>" if rad else "<STR_LIT>"<EOL>ret.dep_name = "<STR_LIT>".format(ret.dep_name)<EOL>ret._dep_vector = (<EOL>np.unwrap(np.angle(ret._dep_vector)) if unwrap else np.angle(ret._dep_vector)<EOL>)<EOL>if not rad:<EOL><INDENT>ret._dep_vector = np.rad2deg(ret._dep_vector)<EOL><DEDENT>return ret<EOL>

r"""
    Return the phase of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param unwrap: Flag that indicates whether phase should change phase shifts
                   to their :code:`2*pi` complement (True) or not (False)
    :type  unwrap: boolean

    :param rad: Flag that indicates whether phase should be returned in radians
                (True) or degrees (False)
    :type  rad: boolean

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.phase

    :raises:
     * RuntimeError (Argument \`rad\` is not valid)

     * RuntimeError (Argument \`unwrap\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", wave.dep_units, np.real)<EOL>

r"""
    Return the real part of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.real

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


@pexdoc.pcontracts.contract(wave=Waveform, decimals="<STR_LIT>")<EOL>def round(wave, decimals=<NUM_LIT:0>):

<EOL>pexdoc.exh.addex(<EOL>TypeError,<EOL>"<STR_LIT>",<EOL>wave._dep_vector.dtype.name.startswith("<STR_LIT>"),<EOL>)<EOL>ret = copy.copy(wave)<EOL>ret.dep_name = "<STR_LIT>".format(ret.dep_name, decimals)<EOL>ret._dep_vector = np.round(wave._dep_vector, decimals)<EOL>return ret<EOL>

r"""
    Round a waveform's dependent variable vector to a given number of decimal places.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param decimals: Number of decimals to round to
    :type  decimals: integer

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.round

    :raises:
     * RuntimeError (Argument \`decimals\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.sin)<EOL>

r"""
    Return the sine of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for peng.wave_functions.sin

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.sinh)<EOL>

r"""
    Return the hyperbolic sine of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.sinh

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


dep_units = "<STR_LIT>".format(wave.dep_units)<EOL>return _operation(wave, "<STR_LIT>", dep_units, np.sqrt)<EOL>

r"""
    Return the square root of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.sqrt

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


ret = copy.copy(wave)<EOL>if dep_name is not None:<EOL><INDENT>ret.dep_name = dep_name<EOL><DEDENT>_bound_waveform(ret, indep_min, indep_max)<EOL>pexdoc.addai("<STR_LIT>", bool((indep_step is not None) and (indep_step <= <NUM_LIT:0>)))<EOL>exmsg = "<STR_LIT>"<EOL>cond = bool(<EOL>(indep_step is not None)<EOL>and (indep_step > ret._indep_vector[-<NUM_LIT:1>] - ret._indep_vector[<NUM_LIT:0>])<EOL>)<EOL>pexdoc.addex(RuntimeError, exmsg, cond)<EOL>if indep_step:<EOL><INDENT>indep_vector = _barange(indep_min, indep_max, indep_step)<EOL>dep_vector = _interp_dep_vector(ret, indep_vector)<EOL>ret._set_indep_vector(indep_vector, check=False)<EOL>ret._set_dep_vector(dep_vector, check=False)<EOL><DEDENT>return ret<EOL>

r"""
    Return a waveform that is a sub-set of a waveform, potentially re-sampled.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param  dep_name: Independent variable name
    :type   dep_name: `NonNullString <https://pexdoc.readthedocs.io/en/stable/
                        ptypes.html#nonnullstring>`_

    :param indep_min: Independent vector start point of computation
    :type  indep_min: integer or float

    :param indep_max: Independent vector stop point of computation
    :type  indep_max: integer or float

    :param indep_step: Independent vector step
    :type  indep_step: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc(raised=True)) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.subwave

    :raises:
     * RuntimeError (Argument \`dep_name\` is not valid)

     * RuntimeError (Argument \`indep_max\` is not valid)

     * RuntimeError (Argument \`indep_min\` is not valid)

     * RuntimeError (Argument \`indep_step\` is greater than independent
       vector range)

     * RuntimeError (Argument \`indep_step\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * RuntimeError (Incongruent \`indep_min\` and \`indep_max\`
       arguments)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.tan)<EOL>

r"""
    Return the tangent of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for peng.wave_functions.tan

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


return _operation(wave, "<STR_LIT>", "<STR_LIT>", np.tanh)<EOL>

r"""
    Return the hyperbolic tangent of a waveform's dependent variable vector.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.tanh

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


ret = copy.copy(wave)<EOL>ret._dep_vector = ret._dep_vector.astype(np.complex)<EOL>return ret<EOL>

r"""
    Convert a waveform's dependent variable vector to complex.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.wcomplex

    :raises: RuntimeError (Argument \`wave\` is not valid)

    .. [[[end]]]


pexdoc.exh.addex(<EOL>TypeError,<EOL>"<STR_LIT>",<EOL>wave._dep_vector.dtype.name.startswith("<STR_LIT>"),<EOL>)<EOL>ret = copy.copy(wave)<EOL>ret._dep_vector = ret._dep_vector.astype(np.float)<EOL>return ret<EOL>

r"""
    Convert a waveform's dependent variable vector to float.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.wfloat

    :raises:
     * RuntimeError (Argument \`wave\` is not valid)

     * TypeError (Cannot convert complex to float)

    .. [[[end]]]


pexdoc.exh.addex(<EOL>TypeError,<EOL>"<STR_LIT>",<EOL>wave._dep_vector.dtype.name.startswith("<STR_LIT>"),<EOL>)<EOL>ret = copy.copy(wave)<EOL>ret._dep_vector = ret._dep_vector.astype(np.int)<EOL>return ret<EOL>

r"""
    Convert a waveform's dependent variable vector to integer.

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.wint

    :raises:
     * RuntimeError (Argument \`wave\` is not valid)

     * TypeError (Cannot convert complex to integer)

    .. [[[end]]]


@pexdoc.pcontracts.contract(wave=Waveform, indep_var="<STR_LIT>")<EOL>def wvalue(wave, indep_var):

close_min = np.isclose(indep_var, wave._indep_vector[<NUM_LIT:0>], FP_RTOL, FP_ATOL)<EOL>close_max = np.isclose(indep_var, wave._indep_vector[-<NUM_LIT:1>], FP_RTOL, FP_ATOL)<EOL>pexdoc.exh.addex(<EOL>ValueError,<EOL>"<STR_LIT>",<EOL>bool(<EOL>((indep_var < wave._indep_vector[<NUM_LIT:0>]) and (not close_min))<EOL>or ((indep_var > wave._indep_vector[-<NUM_LIT:1>]) and (not close_max))<EOL>),<EOL>)<EOL>if close_min:<EOL><INDENT>return wave._dep_vector[<NUM_LIT:0>]<EOL><DEDENT>if close_max:<EOL><INDENT>return wave._dep_vector[-<NUM_LIT:1>]<EOL><DEDENT>idx = np.searchsorted(wave._indep_vector, indep_var)<EOL>xdelta = wave._indep_vector[idx] - wave._indep_vector[idx - <NUM_LIT:1>]<EOL>ydelta = wave._dep_vector[idx] - wave._dep_vector[idx - <NUM_LIT:1>]<EOL>slope = ydelta / float(xdelta)<EOL>return wave._dep_vector[idx - <NUM_LIT:1>] + slope * (indep_var - wave._indep_vector[idx - <NUM_LIT:1>])<EOL>

r"""
    Return the dependent variable value at a given independent variable point.

    If the independent variable point is not in the independent variable vector
    the dependent variable value is obtained by linear interpolation

    :param wave: Waveform
    :type  wave: :py:class:`peng.eng.Waveform`

    :param indep_var: Independent variable point for which the dependent
                      variable is to be obtained
    :type  indep_var: integer or float

    :rtype: :py:class:`peng.eng.Waveform`

    .. [[[cog cog.out(exobj_eng.get_sphinx_autodoc()) ]]]
    .. Auto-generated exceptions documentation for
    .. peng.wave_functions.wvalue

    :raises:
     * RuntimeError (Argument \`indep_var\` is not valid)

     * RuntimeError (Argument \`wave\` is not valid)

     * ValueError (Argument \`indep_var\` is not in the independent
       variable vector range)

    .. [[[end]]]


found = False<EOL>olines = []<EOL>for line in [item.rstrip() for item in long_desc.split("<STR_LIT:\n>")]:<EOL><INDENT>if found and (((not line) and (not olines)) or (line and olines)):<EOL><INDENT>olines.append(line)<EOL><DEDENT>elif found and olines and (not line):<EOL><INDENT>return ("<STR_LIT:U+0020>".join(olines).split("<STR_LIT:.>")[<NUM_LIT:0>]).strip()<EOL><DEDENT>found = line == "<STR_LIT>" if not found else found<EOL><DEDENT>return "<STR_LIT>"<EOL>

Get first sentence of first paragraph of long description.


encoding = kwargs.get("<STR_LIT>", "<STR_LIT:utf-8>")<EOL>sep = kwargs.get("<STR_LIT>", "<STR_LIT:\n>")<EOL>buf = []<EOL>for filename in filenames:<EOL><INDENT>with io.open(filename, encoding=encoding) as fobj:<EOL><INDENT>buf.append(fobj.read())<EOL><DEDENT><DEDENT>return sep.join(buf)<EOL>


mname = "<STR_LIT>"<EOL>fname = "<STR_LIT>"<EOL>module_prefix = "<STR_LIT>".format(mname)<EOL>callable_names = ("<STR_LIT>",)<EOL>return docs.support.trace_support.run_trace(<EOL>mname, fname, module_prefix, callable_names, no_print<EOL>)<EOL>


mname = "<STR_LIT>"<EOL>fname = "<STR_LIT>"<EOL>module_prefix = "<STR_LIT>".format(mname)<EOL>callable_names = (<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>)<EOL>return docs.support.trace_support.run_trace(<EOL>mname, fname, module_prefix, callable_names, no_print<EOL>)<EOL>


mname = "<STR_LIT>"<EOL>fname = "<STR_LIT>"<EOL>module_prefix = "<STR_LIT>".format(mname)<EOL>callable_names = ("<STR_LIT>", "<STR_LIT>")<EOL>return docs.support.trace_support.run_trace(<EOL>mname, fname, module_prefix, callable_names, no_print<EOL>)<EOL>


def ste(command, nindent, mdir, fpointer):

term_echo(<EOL>"<STR_LIT>".format(sep=os.path.sep, cmd=command),<EOL>nindent,<EOL>{"<STR_LIT>": mdir},<EOL>fpointer,<EOL>)<EOL>

r"""
    Echo terminal output.

    Print STDOUT resulting from a given Bash shell command (relative to the
    package :code:`pypkg` directory) formatted in reStructuredText

    :param command: Bash shell command, relative to
                    :bash:`${PMISC_DIR}/pypkg`
    :type  command: string

    :param nindent: Indentation level
    :type  nindent: integer

    :param mdir: Module directory
    :type  mdir: string

    :param fpointer: Output function pointer. Normally is :code:`cog.out` but
                     :code:`print` or other functions can be used for
                     debugging
    :type  fpointer: function object

    For example::

        .. This is a reStructuredText file snippet
        .. [[[cog
        .. import os, sys
        .. from docs.support.term_echo import term_echo
        .. file_name = sys.modules['docs.support.term_echo'].__file__
        .. mdir = os.path.realpath(
        ..     os.path.dirname(
        ..         os.path.dirname(os.path.dirname(file_name))
        ..     )
        .. )
        .. [[[cog ste('build_docs.py -h', 0, mdir, cog.out) ]]]

        .. code-block:: bash

        $ ${PMISC_DIR}/pypkg/build_docs.py -h
        usage: build_docs.py [-h] [-d DIRECTORY] [-n NUM_CPUS]
        ...

        .. ]]]