Carrier frequency correction using real IQ

How do i do carrier frequency correction using real IQ?
If I have complex IQ ```z``` i can just do:
```zn -> zn * exp(i*(phi*n + theta))```
where ```phi``` is some frequency offset and ```theta``` is some phase offset.
But what if ```z``` is real and the IQ is interleaved?

well - if by 'interleaved' you mean z = [real(z0) imag(z0) real(z1) imag(z1) ...] then you need to deinterleave it and do the same:
zout(n) -> (z(2*n) + i*z(2*n+1)) * exp(i*(phi*n + theta))

sorry it's not interleaved, it's just real. I realize now that was wrong.

Can you do this without doing a hilbert transform first?

From memory and without confirming the math I am not sure. Things are easier if the frequency offset is a lot bigger than your bandwidth. Then after modulation with the complex sinusoid you get the negative frequencies in the imaginary part of the result and the positive frequencies in the real part, but I am not quite sure what happens if the frequency offset is smaller than the bandwidth...

Mix it to baseband so that it's complex.

If Z is real it means it is in pass band.Give Z to a hillbert transformer and find the imaginary part.Get the imaginary part.Now Z will have real and imaginary part.Down convert to base band by decimation.Get complex data in base band.Now you do frequency offset correction by multiplying complex exponential.Alternatively add the frequency offset with carrier.Take cosine and sine.Multiply by zn.Each output you give to lowpass filter to remove high frequencies.You gat complex data with frequency offset compensated.