mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-06 15:04:11 +00:00
Improve de-embedding
- Add Z parameters with general conversion from and to S parameters - Implement impedance renormalization over general Z parameters - Fix crash after taking de-embedding measurement - Fix various small bugs with new parameter implementation
This commit is contained in:
parent
77a3fc5039
commit
0205ab494d
11 changed files with 286 additions and 77 deletions
|
|
@ -24,18 +24,52 @@ Sparam::Sparam(const ABCDparam &a, Type Z0)
|
|||
{
|
||||
}
|
||||
|
||||
Sparam::Sparam(const Zparam &Z, std::vector<Type> Z0n)
|
||||
{
|
||||
if(Z.ports() != Z0n.size()) {
|
||||
throw std::runtime_error("number of supplied characteristic impedances does not match number of ports");
|
||||
}
|
||||
/* general formula for converting S parameters to Z parameters:
|
||||
* S = (sqrt(y)*Z*sqrt(y)-1)*(sqrt(y)*Z*sqrt(y)+1)^-1
|
||||
* with:
|
||||
* Z = Z parameter matrix
|
||||
* 1 = identity matrix
|
||||
* sqrt(y) = diagonal matrix with the root of characteristic admittances as it non-zero elements
|
||||
*/
|
||||
// create identity matrix
|
||||
auto ident = Eigen::MatrixXcd::Identity(Z.ports(), Z.ports());
|
||||
// create sqrt(y) matrix
|
||||
Eigen::MatrixXcd sqrty = Eigen::MatrixXcd::Zero(Z.ports(), Z.ports());
|
||||
// fill with characteristic admittance
|
||||
for(unsigned int i=0;i<Z.ports();i++) {
|
||||
sqrty(i, i) = 1.0/(sqrt(Z0n[i]));
|
||||
}
|
||||
// apply formula
|
||||
auto yZy = sqrty*Z.data*sqrty;
|
||||
data = (yZy-ident)*(yZy+ident).inverse();
|
||||
}
|
||||
|
||||
Sparam::Sparam(const Zparam &Z, Type Z0)
|
||||
: Sparam(Z, std::vector<Type>(Z.ports(), Z0))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Sparam::swapPorts(unsigned int p1, unsigned int p2)
|
||||
{
|
||||
// swap columns
|
||||
data.col(p1-1).swap(data.col(p2-1));
|
||||
data.row(p1-1).swap(data.row(p2-1));
|
||||
// auto cbuf = data.col(p1-1);
|
||||
// data.col(p1-1) = data.col(p2-1);
|
||||
// data.col(p2-1) = cbuf;
|
||||
// // swap rows
|
||||
// auto rbuf = data.row(p1-1);
|
||||
// data.row(p1-1) = data.row(p2-1);
|
||||
// data.row(p2-1) = rbuf;
|
||||
}
|
||||
|
||||
Sparam Sparam::reduceTo(std::vector<unsigned int> ports) const
|
||||
{
|
||||
auto ret = Sparam(ports.size());
|
||||
for(unsigned int from=0;from<ports.size();from++) {
|
||||
for(unsigned int to=0;to<ports.size();to++) {
|
||||
ret.data(to, from) = get(ports[to], ports[from]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ABCDparam::ABCDparam(const Sparam &s, Type Z01, Type Z02)
|
||||
|
|
@ -68,6 +102,12 @@ ABCDparam::ABCDparam(const Sparam &s, Type Z0)
|
|||
{
|
||||
}
|
||||
|
||||
Parameters::Parameters(Type m11)
|
||||
: Parameters(1)
|
||||
{
|
||||
data(0, 0) = m11;
|
||||
}
|
||||
|
||||
Parameters::Parameters(Type m11, Type m12, Type m21, Type m22)
|
||||
: Parameters(2)
|
||||
{
|
||||
|
|
@ -130,7 +170,7 @@ Yparam::Yparam(const Sparam &s, Type Z01, Type Z02)
|
|||
{
|
||||
// TODO can this be done for any number of ports
|
||||
if(s.ports() != 2) {
|
||||
throw std::runtime_error("Can only create ABCD parameter from 2 port S parameters");
|
||||
throw std::runtime_error("Can only create Y parameter from 2 port S parameters");
|
||||
}
|
||||
data = Eigen::MatrixXcd(2,2);
|
||||
// from https://www.rfcafe.com/references/electrical/s-h-y-z.htm
|
||||
|
|
@ -145,3 +185,33 @@ Yparam::Yparam(const Sparam &s, Type Z0)
|
|||
: Yparam(s, Z0, Z0)
|
||||
{
|
||||
}
|
||||
|
||||
Zparam::Zparam(const Sparam &S, std::vector<Type> Z0n)
|
||||
{
|
||||
if(S.ports() != Z0n.size()) {
|
||||
throw std::runtime_error("number of supplied characteristic impedances does not match number of ports");
|
||||
}
|
||||
/* general formula for converting S parameters to Z parameters:
|
||||
* Z = sqrt(z)*(1+S)*(1-S)^-1*sqrt(z)
|
||||
* with:
|
||||
* S = S parameter matrix
|
||||
* 1 = identity matrix
|
||||
* sqrt(z) = diagonal matrix with the root of characteristic impedances as it non-zero elements
|
||||
*/
|
||||
// create identity matrix
|
||||
auto ident = Eigen::MatrixXcd::Identity(S.ports(), S.ports());
|
||||
// create sqrt(z) matrix
|
||||
Eigen::MatrixXcd sqrtz = Eigen::MatrixXcd::Zero(S.ports(), S.ports());
|
||||
// fill with characteristic impedance
|
||||
for(unsigned int i=0;i<S.ports();i++) {
|
||||
sqrtz(i, i) = sqrt(Z0n[i]);
|
||||
}
|
||||
// apply formula
|
||||
data = sqrtz*(ident+S.data)*(ident-S.data).inverse()*sqrtz;
|
||||
}
|
||||
|
||||
Zparam::Zparam(const Sparam &S, Type Z0)
|
||||
: Zparam(S, std::vector<Type>(S.ports(), Z0))
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue