def conv_sum(x1,nx1,x2,nx2,extent=('<STR_LIT:f>','<STR_LIT:f>')):
nnx1 = np.arange(<NUM_LIT:0>,len(nx1))<EOL>nnx2 = np.arange(<NUM_LIT:0>,len(nx2))<EOL>n1 = nnx1[<NUM_LIT:0>]<EOL>n2 = nnx1[-<NUM_LIT:1>]<EOL>n3 = nnx2[<NUM_LIT:0>]<EOL>n4 = nnx2[-<NUM_LIT:1>]<EOL>if extent[<NUM_LIT:0>] == '<STR_LIT:f>' and extent[<NUM_LIT:1>] == '<STR_LIT:f>':<EOL><INDENT>nny = np.arange(n1+n3,n2+<NUM_LIT:1>+n4+<NUM_LIT:1>-<NUM_LIT:1>)<EOL>ny = np.arange(<NUM_LIT:0>,len(x1)+len(x2)-<NUM_LIT:1>) + nx1[<NUM_LIT:0>]+nx2[<NUM_LIT:0>]<EOL><DEDENT>elif extent[<NUM_LIT:0>] == '<STR_LIT:f>' and extent[<NUM_LIT:1>] == '<STR_LIT:r>':<EOL><INDENT>nny = np.arange(n1+n3,n1+<NUM_LIT:1>+n4+<NUM_LIT:1>-<NUM_LIT:1>)<EOL>ny = nny + nx1[<NUM_LIT:0>]+nx2[<NUM_LIT:0>]<EOL><DEDENT>elif extent[<NUM_LIT:0>] == '<STR_LIT:r>' and extent[<NUM_LIT:1>] == '<STR_LIT:f>':<EOL><INDENT>nny = np.arange(n1+n3,n2+<NUM_LIT:1>+n3+<NUM_LIT:1>-<NUM_LIT:1>)<EOL>ny = nny + nx1[<NUM_LIT:0>]+nx2[<NUM_LIT:0>]<EOL><DEDENT>elif extent[<NUM_LIT:0>] == '<STR_LIT:f>' and extent[<NUM_LIT:1>] == '<STR_LIT:l>':<EOL><INDENT>nny = np.arange(n2+n3,n2+<NUM_LIT:1>+n4+<NUM_LIT:1>-<NUM_LIT:1>)<EOL>ny = nny + nx1[-<NUM_LIT:1>]+nx2[<NUM_LIT:0>]<EOL><DEDENT>elif extent[<NUM_LIT:0>] == '<STR_LIT:l>' and extent[<NUM_LIT:1>] == '<STR_LIT:f>':<EOL><INDENT>nny = np.arange(n1+n4,n2+<NUM_LIT:1>+n4+<NUM_LIT:1>-<NUM_LIT:1>)<EOL>ny = nny + nx1[<NUM_LIT:0>]+nx2[-<NUM_LIT:1>]<EOL><DEDENT>elif extent[<NUM_LIT:0>] == '<STR_LIT:r>' and extent[<NUM_LIT:1>] == '<STR_LIT:r>':<EOL><INDENT>nny = np.arange(n1+n3,min(n1+<NUM_LIT:1>+n4+<NUM_LIT:1>,n2+<NUM_LIT:1>+n3+<NUM_LIT:1>)-<NUM_LIT:1>)<EOL>ny = nny + nx1[<NUM_LIT:0>]+nx2[<NUM_LIT:0>]<EOL><DEDENT>elif extent[<NUM_LIT:0>] == '<STR_LIT:l>' and extent[<NUM_LIT:1>] == '<STR_LIT:l>':<EOL><INDENT>nny = np.arange(max(n1+n4,n2+n3),n2+<NUM_LIT:1>+n4+<NUM_LIT:1>-<NUM_LIT:1>)<EOL>ny = nny + max(nx1[<NUM_LIT:0>]+nx2[-<NUM_LIT:1>],nx1[-<NUM_LIT:1>]+nx2[<NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>y = signal.convolve(x1, x2)<EOL>print('<STR_LIT>' % (ny[<NUM_LIT:0>],ny[-<NUM_LIT:1>]))<EOL>return y[nny], ny<EOL>
Discrete convolution of x1 and x2 with proper tracking of the output time axis.

Convolve two discrete-time signals using the SciPy function :func:`scipy.signal.convolution`.
The time (sequence axis) are managed from input to output. y[n] = x1[n]*x2[n].

Parameters
----------
x1 : ndarray of signal x1 corresponding to nx1
nx1 : ndarray time axis for x1
x2  : ndarray of signal x2 corresponding to nx2
nx2 : ndarray time axis for x2
extent : ('e1','e2') where 'e1', 'e2' may be 'f' finite, 'r' right-sided, or 'l' left-sided

Returns
-------
y : ndarray of output values y
ny : ndarray of the corresponding sequence index n

Notes
-----
The output time axis starts at the sum of the starting values in x1 and x2 
and ends at the sum of the two ending values in x1 and x2. The default 
extents of ('f','f') are used for signals that are active (have support) 
on or within n1 and n2 respectively. A right-sided signal such as 
a^n*u[n] is semi-infinite, so it has extent 'r' and the
convolution output will be truncated to display only the valid results.

Examples
--------
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> import sk_dsp_comm.sigsys as ss
>>> nx = np.arange(-5,10)
>>> x = ss.drect(nx,4)
>>> y,ny = ss.conv_sum(x,nx,x,nx)
>>> plt.stem(ny,y)
>>> plt.show()

Consider a pulse convolved with an exponential. ('r' type extent)

>>> h = 0.5**nx*ss.dstep(nx)
>>> y,ny = ss.conv_sum(x,nx,h,nx,('f','r')) # note extents set
>>> plt.stem(ny,y) # expect a pulse charge and discharge sequence