I have developed a spectrum scope that plots signal vs. frequency starting from IQ signals. I currently do not have a way to balance the IQ signals, so am looking at various ways to do so. I have come across this article, which is reasonably easy for me to follow since I am fairly new to all DSP. The one question I have is concerning the notation of some of the equations: For example, $a^2 = 2\langle t(i) * t(i)\rangle$. What does $\langle\cdot \rangle$ represent? I can find no reference for these in mathematical symbol tables.
-
2$\begingroup$ The paper provides a definition: the average of the signal computed over N periods. $\endgroup$ – pichenettes Nov 1 '14 at 22:29
-
$\begingroup$ Hi Thanks, yes my math is quite rusty! Can anyone explain how many samples would provide a good value? $\endgroup$ – Tom Nov 3 '14 at 22:58
-
$\begingroup$ According to this page, that symbol means "inner product". See this answer to this question. $\endgroup$ – jeremy Oct 5 '16 at 19:20
I wrote code in Java based on that article but it isn't working for me. Alpha (I-data scalar) calculates to be around $100$ and $cos(\omega)$ often calculates to an imaginary number. Did anyone have any luck with this or could point me to a better IQ Correction algorithm?
(To be clear: calculateMatrix
, a
, c
, and d
are all instance variables)
public void correctIQ(int[] data) {
int length = data.length / 2;
// ( I'(t) & Q'(t) )
int[] iData = new int[length];
int[] qData = new int[length];
// Deinterleave IQ data
for (int i = 0; i < length; i++) {
iData[i] = data[i * 2];
qData[i] = data[i * 2 + 1];
}
// ( I''(t) & Q''(t) )
double[] qDataOffset = new double[length];
double[] iDataOffset = new double[length];
// Calculate DC offset
double qOffset = mean(qData);
double iOffset = mean(iData);
// Apply DC offset
for (int i = 0; i < length; i++) {
iDataOffset[i] = iData[i] - iOffset;
qDataOffset[i] = qData[i] - qOffset;
}
// Provided equations calculated on frequency change
if(calculateMatrix) {
double alpha = Math.sqrt(2.0 * multiplyMean(iDataOffset, iDataOffset));
double sinw = (2.0 / alpha) * multiplyMean(iDataOffset, qDataOffset);
double cosw = Math.sqrt(1.0 - (sinw * sinw));
a = 1.0f / alpha;
c = -sinw / (alpha * cosw);
d = 1.0f / cosw;
}
// Replace into interleaved array
for(int i=0;i<length;i++) {
data[i*2]=(int)((iData[i]-iOffset)*a);
data[i*2+1]=(int)((iData[i]-iOffset)*c+(qData[i]-qOffset)*d);
}
}
double mean(int[] values) {
long sum = 0L;
for(int i=0;i<values.length;i++) {
sum+=values[i];
}
return ((double)sum)/values.length;
}
double multiplyMean(double[] values1, double[] values2) {
long sum = 0L;
for(int i=0;i<values1.length;i++) {
sum+=values1[i]*values2[i];
}
return ((double)sum)/values1.length;
}
I didn't get a chance to look through the article in detail, but it looks like taking the inner product between 2 vectors over some index variable (in your case, $i$), as in $<X_i, X_i> = \frac{1}{N}\sum_i |X_i|^2$.
This is the averaging symbol and you see it quite often in DSP and communication systems books and articles. It's right there in article also: