def OFDM_rx(x, Nf, N, Np=<NUM_LIT:0>, cp=False, Ncp=<NUM_LIT:0>, alpha=<NUM_LIT>, ht=None):
N_symb = len(x) // (N + Ncp)<EOL>y_out = np.zeros(N_symb * N, dtype=np.complex128)<EOL>for k in range(N_symb):<EOL><INDENT>if cp:<EOL><INDENT>buff = x[k * (N + Ncp) + Ncp:(k + <NUM_LIT:1>) * (N + Ncp)]<EOL><DEDENT>else:<EOL><INDENT>buff = x[k * N:(k + <NUM_LIT:1>) * N]<EOL><DEDENT>y_out[k * N:(k + <NUM_LIT:1>) * N] = fft.fft(buff)<EOL><DEDENT>z_out = np.reshape(y_out, (N_symb, N))<EOL>z_out = np.hstack((z_out[:, <NUM_LIT:1>:Nf // <NUM_LIT:2> + <NUM_LIT:1>], z_out[:, N - Nf // <NUM_LIT:2>:N]))<EOL>if Np > <NUM_LIT:0>:<EOL><INDENT>if isinstance(type(None), type(ht)):<EOL><INDENT>z_out, H = chan_est_equalize(z_out, Np, alpha)<EOL><DEDENT>else:<EOL><INDENT>Ht = fft.fft(ht, N)<EOL>Hht = np.hstack((Ht[<NUM_LIT:1>:Nf // <NUM_LIT:2> + <NUM_LIT:1>], Ht[N - Nf // <NUM_LIT:2>:]))<EOL>z_out, H = chan_est_equalize(z_out, Np, alpha, Hht)<EOL><DEDENT><DEDENT>elif Np == -<NUM_LIT:1>:  <EOL><INDENT>Ht = fft.fft(ht, N)<EOL>H = np.hstack((Ht[<NUM_LIT:1>:Nf // <NUM_LIT:2> + <NUM_LIT:1>], Ht[N - Nf // <NUM_LIT:2>:]))<EOL>for k in range(N_symb):<EOL><INDENT>z_out[k, :] /= H<EOL><DEDENT><DEDENT>else:<EOL><INDENT>H = np.ones(Nf)<EOL><DEDENT>return z_out.flatten(), H<EOL>
Parameters
----------
x : Received complex baseband OFDM signal
Nf : Number of filled carriers, must be even and Nf < N
N : Total number of carriers; generally a power 2, e.g., 64, 1024, etc
Np : Period of pilot code blocks; 0 <=> no pilots; -1 <=> use the ht impulse response input to equalize the OFDM symbols; note equalization still requires Ncp > 0 to work on a delay spread channel.
cp : False/True <=> if False assume no CP is present
Ncp : The length of the cyclic prefix
alpha : The filter forgetting factor in the channel estimator. Typically alpha is 0.9 to 0.99.
nt : Input the known theoretical channel impulse response

Returns
-------
z_out : Recovered complex baseband QAM symbols as a serial stream; as appropriate channel estimation has been applied.
H : channel estimate (in the frequency domain at each subcarrier)

See Also
--------
OFDM_tx

Examples
--------

>>> import matplotlib.pyplot as plt
>>> from sk_dsp_comm import digitalcom as dc
>>> from scipy import signal
>>> from numpy import array
>>> hc = array([1.0, 0.1, -0.05, 0.15, 0.2, 0.05]) # impulse response spanning five symbols
>>> # Quick example using the above channel with no cyclic prefix
>>> x1,b1,IQ_data1 = dc.QAM_bb(50000,1,'16qam')
>>> x_out = dc.OFDM_tx(IQ_data1,32,64,0,True,0)
>>> c_out = signal.lfilter(hc,1,x_out) # Apply channel distortion
>>> r_out = dc.cpx_AWGN(c_out,100,64/32) # Es/N0 = 100 dB
>>> z_out,H = dc.OFDM_rx(r_out,32,64,-1,True,0,alpha=0.95,ht=hc)
>>> plt.plot(z_out[200:].real,z_out[200:].imag,'.')
>>> plt.xlabel('In-Phase')
>>> plt.ylabel('Quadrature')
>>> plt.axis('equal')
>>> plt.grid()
>>> plt.show()

Another example with noise using a 10 symbol cyclic prefix and channel estimation:

>>> x_out = dc.OFDM_tx(IQ_data1,32,64,100,True,10)
>>> c_out = signal.lfilter(hc,1,x_out) # Apply channel distortion
>>> r_out = dc.cpx_AWGN(c_out,25,64/32) # Es/N0 = 25 dB
>>> z_out,H = dc.OFDM_rx(r_out,32,64,100,True,10,alpha=0.95,ht=hc);
>>> plt.figure() # if channel estimation is turned on need this
>>> plt.plot(z_out[-2000:].real,z_out[-2000:].imag,'.') # allow settling time
>>> plt.xlabel('In-Phase')
>>> plt.ylabel('Quadrature')
>>> plt.axis('equal')
>>> plt.grid()
>>> plt.show()