I'm working on adding .s1p touchstone export support to the xnec2c NEC2 antenna simulator for Linux. I would like the S11 dB values in the .s1p to have both real and imaginary values.
NEC2 calculates Gamma by breaking it into real-valued components \$Z_r\$ and \$Z_i\$. It then does a real (ie, not complex) calculation to obtain a real-valued Gamma:
\$\Gamma = \sqrt{ \frac{ (Z_r-Z_0)^2+Z_i^2 }{ (Z_r+Z_0)^2+Z_i^2 } }\$
S11 is then calculated as a real value using Gamma above as:
\$S_{11}\ = 20 log_{10}(\Gamma)\$
My question: Is it correct to calculate a complex Gamma from the real values \$Z_r\$ and \$Z_i\$ by creating a complex number \$Z = (Z_r+Z_i {\bf i})\$ and then calcule Gamma as shown in the Wikipedia article about reflection coefficient?
\$\Gamma = \frac{ Z-Z_0 }{ Z+Z_0 } \$
I ran the numbers and I get the same result for the real S11 value, but I have no way to validate the imaginary value. Is this a mathematically correct way to do this? Is it the "right" way?
If this works then I can split \$Z\$ into its real and imaginary parts for writing to the .s1p file's S11 real and imaginary columns. Here is the actual C code that generates the real-valued gamma and s11 variables:
zrpro2 = impedance_data.zreal[idx] + calc_data.zo;
zrpro2 *= zrpro2;
zrmro2 = impedance_data.zreal[idx] - calc_data.zo;
zrmro2 *= zrmro2;
zimag2 = impedance_data.zimag[idx] * impedance_data.zimag[idx];
gamma = sqrt( (zrmro2 + zimag2) / (zrpro2 + zimag2) );
s11[idx] = 20*log10( gamma );
And here is my proposed change based on that:
double complex z_load = impedance_data.zreal[idx] + I*impedance_data.zimag[idx];
double complex cgamma = (z_load-Zo) / (z_load+Zo);