LCOV - code coverage report
Current view: top level - src/components - spfile.cpp (source / functions) Hit Total Coverage
Test: qucs-core-0.0.19 Code Coverage Lines: 0 269 0.0 %
Date: 2015-01-05 16:01:02 Functions: 0 30 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 701 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * spfile.cpp - S-parameter file class implementation
       3                 :            :  *
       4                 :            :  * Copyright (C) 2004, 2005, 2006, 2008, 2009 Stefan Jahn <stefan@lkcc.org>
       5                 :            :  *
       6                 :            :  * This is free software; you can redistribute it and/or modify
       7                 :            :  * it under the terms of the GNU General Public License as published by
       8                 :            :  * the Free Software Foundation; either version 2, or (at your option)
       9                 :            :  * any later version.
      10                 :            :  *
      11                 :            :  * This software is distributed in the hope that it will be useful,
      12                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14                 :            :  * GNU General Public License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU General Public License
      17                 :            :  * along with this package; see the file COPYING.  If not, write to
      18                 :            :  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
      19                 :            :  * Boston, MA 02110-1301, USA.
      20                 :            :  *
      21                 :            :  * $Id$
      22                 :            :  *
      23                 :            :  */
      24                 :            : 
      25                 :            : #if HAVE_CONFIG_H
      26                 :            : # include <config.h>
      27                 :            : #endif
      28                 :            : 
      29                 :            : #include "component.h"
      30                 :            : #include "matvec.h"
      31                 :            : #include "dataset.h"
      32                 :            : #include "strlist.h"
      33                 :            : #include "poly.h"
      34                 :            : #include "spline.h"
      35                 :            : #include "interpolator.h"
      36                 :            : #include "spfile.h"
      37                 :            : 
      38                 :            : using namespace qucs;
      39                 :            : 
      40                 :            : // Constructor for S-parameter file vector.
      41                 :          0 : spfile_vector::spfile_vector () {
      42                 :          0 :   v = f = 0;
      43                 :          0 :   isreal = 1;
      44                 :          0 :   inter = NULL;
      45                 :          0 :   r = c = 0;
      46                 :          0 : }
      47                 :            : 
      48                 :            : // Destructor for S-parameter file vector.
      49                 :          0 : spfile_vector::~spfile_vector () {
      50 [ #  # ][ #  # ]:          0 :   if (inter) delete inter;
         [ #  # ][ #  # ]
      51                 :          0 : }
      52                 :            : 
      53                 :            : // Passes vectors and their data types to the S-parameter file vector.
      54                 :          0 : void spfile_vector::prepare (qucs::vector * _v, qucs::vector * _f,
      55                 :            :                              bool _isreal, int it, int dt) {
      56                 :          0 :   v = _v;
      57                 :          0 :   f = _f;
      58                 :          0 :   isreal = _isreal;
      59         [ #  # ]:          0 :   inter = new interpolator ();
      60         [ #  # ]:          0 :   if (isreal) {
      61                 :          0 :     inter->rvectors (v, f);
      62                 :          0 :     inter->prepare (it, REPEAT_NO, dt | DATA_REAL);
      63                 :            :   }
      64                 :            :   else {
      65                 :          0 :     inter->cvectors (v, f);
      66                 :          0 :     inter->prepare (it, REPEAT_NO, dt | DATA_COMPLEX);
      67                 :            :   }
      68                 :          0 : }
      69                 :            : 
      70                 :            : // Returns interpolated data.
      71                 :          0 : nr_complex_t spfile_vector::interpolate (nr_double_t x) {
      72         [ #  # ]:          0 :   if (isreal)
      73                 :          0 :     return inter->rinterpolate (x);
      74                 :            :   else
      75                 :          0 :     return inter->cinterpolate (x);
      76                 :            : }
      77                 :            : 
      78                 :            : // Constructor creates an empty and unnamed instance of the spfile class.
      79                 :          0 : spfile::spfile () : circuit () {
      80                 :          0 :   data = NULL;
      81                 :          0 :   sfreq = nfreq = NULL;
      82                 :          0 :   spara = FMIN = SOPT = RN = NULL;
      83                 :          0 :   interpolType = dataType = 0;
      84                 :          0 :   type = CIR_SPFILE;
      85                 :          0 :   setVariableSized (true);
      86                 :          0 : }
      87                 :            : 
      88                 :            : // Destructor deletes spfile object from memory.
      89                 :          0 : spfile::~spfile () {
      90 [ #  # ][ #  # ]:          0 :   if (spara) delete[] spara;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      91 [ #  # ][ #  # ]:          0 :   if (RN) delete RN;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      92 [ #  # ][ #  # ]:          0 :   if (FMIN) delete FMIN;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      93 [ #  # ][ #  # ]:          0 :   if (SOPT) delete SOPT;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      94                 :            : #if DEBUG && 0
      95                 :            :   if (data) {
      96                 :            :     data->setFile ("spfile.dat");
      97                 :            :     data->print ();
      98                 :            :   }
      99                 :            : #endif
     100 [ #  # ][ #  # ]:          0 :   if (data) delete data;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     101 [ #  # ][ #  # ]:          0 : }
     102                 :            : 
     103                 :          0 : void spfile::calcSP (nr_double_t frequency) {
     104                 :            : 
     105                 :            :   // nothing to do if the given file type had errors
     106 [ #  # ][ #  # ]:          0 :   if (spara == NULL || sfreq == NULL) return;
     107                 :            : 
     108                 :            :   // set interpolated S-parameters
     109 [ #  # ][ #  # ]:          0 :   setMatrixS (expandSParaMatrix (getInterpolMatrixS (frequency)));
                 [ #  # ]
     110                 :            : }
     111                 :            : 
     112                 :            : /* This function returns the S-parameter matrix of the circuit for the
     113                 :            :    given frequency.  It uses interpolation for frequency points which
     114                 :            :    are not part of the original touchstone file. */
     115                 :          0 : matrix spfile::getInterpolMatrixS (nr_double_t frequency) {
     116                 :            : 
     117                 :            :   // first interpolate the matrix values
     118                 :          0 :   matrix s (getSize () - 1);
     119         [ #  # ]:          0 :   for (int r = 0; r < getSize () - 1; r++) {
     120         [ #  # ]:          0 :     for (int c = 0; c < getSize () - 1; c++) {
     121                 :          0 :       int i = r * getSize () + c;
     122 [ #  # ][ #  # ]:          0 :       s.set (r, c, spara[i].interpolate (frequency));
     123                 :            :     }
     124                 :            :   }
     125                 :            : 
     126                 :            :   // then convert them to S-parameters if necessary
     127   [ #  #  #  #  :          0 :   switch (paraType) {
                      # ]
     128                 :            :   case 'Y':
     129 [ #  # ][ #  # ]:          0 :     s = ytos (s);
         [ #  # ][ #  # ]
                 [ #  # ]
     130                 :          0 :     break;
     131                 :            :   case 'Z':
     132 [ #  # ][ #  # ]:          0 :     s = ztos (s);
         [ #  # ][ #  # ]
                 [ #  # ]
     133                 :          0 :     break;
     134                 :            :   case 'H':
     135 [ #  # ][ #  # ]:          0 :     s = htos (s);
         [ #  # ][ #  # ]
                 [ #  # ]
     136                 :          0 :     break;
     137                 :            :   case 'G':
     138 [ #  # ][ #  # ]:          0 :     s = gtos (s);
         [ #  # ][ #  # ]
                 [ #  # ]
     139                 :          0 :     break;
     140                 :            :   }
     141                 :          0 :   return s;
     142                 :            : }
     143                 :            : 
     144                 :          0 : void spfile::calcNoiseSP (nr_double_t frequency) {
     145                 :            :   // nothing to do if the given file type had errors
     146 [ #  # ][ #  # ]:          0 :   if (spara == NULL || nfreq == NULL) return;
     147         [ #  # ]:          0 :   setMatrixN (calcMatrixCs (frequency));
     148                 :            : }
     149                 :            : 
     150                 :          0 : matrix spfile::calcMatrixCs (nr_double_t frequency) {
     151                 :            :   // set interpolated noise correlation matrix
     152         [ #  # ]:          0 :   nr_double_t r = real (RN->interpolate (frequency));
     153         [ #  # ]:          0 :   nr_double_t f = real (FMIN->interpolate (frequency));
     154         [ #  # ]:          0 :   nr_complex_t g = SOPT->interpolate (frequency);
     155         [ #  # ]:          0 :   matrix s = getInterpolMatrixS (frequency);
     156 [ #  # ][ #  # ]:          0 :   matrix n = correlationMatrix (f, g, r, s);
                 [ #  # ]
     157 [ #  # ][ #  # ]:          0 :   matrix c = expandNoiseMatrix (n, expandSParaMatrix (s));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     158 [ #  # ][ #  # ]:          0 :   return c;
     159                 :            : }
     160                 :            : 
     161                 :            : /* This function expands the actual S-parameter file data stored
     162                 :            :    within the touchstone file to have an additional reference one-port
     163                 :            :    whose S-parameter is -1 (i.e. ground). */
     164                 :          0 : matrix spfile::expandSParaMatrix (matrix s) {
     165         [ #  # ]:          0 :   assert (s.getCols () == s.getRows ());
     166                 :          0 :   int r, c, ports = s.getCols () + 1;
     167                 :          0 :   nr_double_t g = -1;
     168                 :          0 :   nr_complex_t fr, ss, sr, sc, sa;
     169         [ #  # ]:          0 :   matrix res (ports);
     170                 :            : 
     171                 :            :   // compute S'mm
     172         [ #  # ]:          0 :   for (sa = 0, r = 0; r < ports - 1; r++)
     173 [ #  # ][ #  # ]:          0 :     for (c = 0; c < ports - 1; c++) sa += s.get (r, c);
     174         [ #  # ]:          0 :   ss = (2 - g - ports + sa) / (1 - ports * g - sa);
     175         [ #  # ]:          0 :   res.set (ports - 1, ports - 1, ss);
     176                 :          0 :   fr = (1.0 - g * ss) / (1.0 - g);
     177                 :            : 
     178                 :            :   // compute S'im
     179         [ #  # ]:          0 :   for (r = 0; r < ports - 1; r++) {
     180 [ #  # ][ #  # ]:          0 :     for (sc = 0, c = 0; c < ports - 1; c++) sc += s.get (r, c);
     181 [ #  # ][ #  # ]:          0 :     res.set (r, ports - 1, fr * (1.0 - sc));
     182                 :            :   }
     183                 :            : 
     184                 :            :   // compute S'mj
     185         [ #  # ]:          0 :   for (c = 0; c < ports - 1; c++) {
     186 [ #  # ][ #  # ]:          0 :     for (sr = 0, r = 0; r < ports - 1; r++) sr += s.get (r, c);
     187 [ #  # ][ #  # ]:          0 :     res.set (ports - 1, c, fr * (1.0 - sr));
     188                 :            :   }
     189                 :            : 
     190                 :            :   // compute S'ij
     191         [ #  # ]:          0 :   for (r = 0; r < ports - 1; r++) {
     192         [ #  # ]:          0 :     for (c = 0; c < ports - 1; c++) {
     193 [ #  # ][ #  # ]:          0 :       fr = g * res (r, ports - 1) * res (ports - 1, c) / (1.0 - g * ss);
     194 [ #  # ][ #  # ]:          0 :       res.set (r, c, s.get (r, c) - fr);
                 [ #  # ]
     195                 :            :     }
     196                 :            :   }
     197                 :            : 
     198                 :          0 :   return res;
     199                 :            : }
     200                 :            : 
     201                 :            : /* The function is the counterpart of the above expandSParaMatrix()
     202                 :            :    function.  It shrinks the S-parameter matrix by removing the
     203                 :            :    reference port. */
     204                 :          0 : matrix spfile::shrinkSParaMatrix (matrix s) {
     205 [ #  # ][ #  # ]:          0 :   assert (s.getCols () == s.getRows () && s.getCols () > 0);
                 [ #  # ]
     206                 :          0 :   int r, c, ports = s.getCols ();
     207                 :          0 :   nr_double_t g = -1;
     208         [ #  # ]:          0 :   matrix res (ports - 1);
     209                 :            : 
     210                 :            :   // compute S'ij
     211         [ #  # ]:          0 :   for (r = 0; r < ports - 1; r++) {
     212         [ #  # ]:          0 :     for (c = 0; c < ports - 1; c++) {
     213                 :          0 :       res.set (r, c, s (r, c) + g * s (r, ports - 1)  *
     214         [ #  # ]:          0 :                s (ports - 1, c) / (1.0 - g * s (ports - 1, ports - 1)));
           [ #  #  #  # ]
     215                 :            :     }
     216                 :            :   }
     217                 :          0 :   return res;
     218                 :            : }
     219                 :            : 
     220                 :            : /* This function expands the actual noise correlation matrix to have an
     221                 :            :    additional reference one-port whose S-parameter is -1
     222                 :            :    (i.e. ground).  The given S-parameter matrix is required to perform
     223                 :            :    this transformation and is obtained using the expandSParaMatrix()
     224                 :            :    function. */
     225                 :          0 : matrix spfile::expandNoiseMatrix (matrix n, matrix s) {
     226 [ #  # ][ #  # ]:          0 :   assert (s.getCols () == s.getRows () && n.getCols () == n.getRows () &&
                 [ #  # ]
     227         [ #  # ]:          0 :           n.getCols () == s.getCols () - 1);
     228         [ #  # ]:          0 :   nr_double_t T = getPropertyDouble ("Temp");
     229                 :          0 :   int r, c, ports = n.getCols () + 1;
     230                 :          0 :   nr_double_t g = -1;
     231                 :            : 
     232                 :            :   // create K matrix
     233         [ #  # ]:          0 :   matrix k (ports, ports - 1);
     234         [ #  # ]:          0 :   for (r = 0; r < ports - 1; r++) {
     235         [ #  # ]:          0 :     for (c = 0; c < ports - 1; c++) {
     236         [ #  # ]:          0 :       if (r == c)
     237 [ #  # ][ #  # ]:          0 :         k.set (r, c, 1.0 + g * (s.get (r, ports - 1) - 1.0));
     238                 :            :       else
     239 [ #  # ][ #  # ]:          0 :         k.set (r, c, g * s.get (r, ports - 1));
     240                 :            :     }
     241                 :            :   }
     242         [ #  # ]:          0 :   for (c = 0; c < ports - 1; c++)
     243 [ #  # ][ #  # ]:          0 :     k.set (ports - 1, c, g * s.get (ports - 1, ports - 1) - 1.0);
     244                 :            : 
     245                 :            :   // create D vector
     246         [ #  # ]:          0 :   matrix d (ports, 1);
     247 [ #  # ][ #  # ]:          0 :   for (r = 0; r < ports - 1; r++) d.set (r, 0, s.get (r, ports - 1));
                 [ #  # ]
     248 [ #  # ][ #  # ]:          0 :   d.set (ports - 1, 0, s.get (ports - 1, ports - 1) - 1.0);
     249                 :            : 
     250                 :            :   // expand noise correlation matrix
     251         [ #  # ]:          0 :   matrix res (ports);
     252         [ #  # ]:          0 :   res = (k * n * adjoint (k) - kelvin (T) / T0 * fabs (1 - norm (g)) *
     253 [ #  # ][ #  # ]:          0 :          d * adjoint (d)) * norm (1 / (1 - g));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     254 [ #  # ][ #  # ]:          0 :   return res;
     255                 :            : }
     256                 :            : 
     257                 :            : /* The function is the counterpart of the above expandNoiseMatrix()
     258                 :            :    function.  It shrinks the noise correlation matrix by removing the
     259                 :            :    reference port.  The given S-parameter matrix is required to perform
     260                 :            :    this transformation and is obtained using the expandSParaMatrix()
     261                 :            :    function. */
     262                 :          0 : matrix spfile::shrinkNoiseMatrix (matrix n, matrix s) {
     263 [ #  # ][ #  # ]:          0 :   assert (s.getCols () == s.getRows () && n.getCols () == n.getRows () &&
         [ #  # ][ #  # ]
     264         [ #  # ]:          0 :           n.getCols () == s.getCols () && n.getCols () > 0);
     265                 :          0 :   int r, ports = n.getCols ();
     266                 :          0 :   nr_double_t g = -1;
     267         [ #  # ]:          0 :   nr_double_t T = getPropertyDouble ("Temp");
     268                 :            : 
     269                 :            :   // create K' matrix
     270         [ #  # ]:          0 :   matrix k (ports - 1, ports);
     271 [ #  # ][ #  # ]:          0 :   for (r = 0; r < ports - 1; r++) k.set (r, r, 1);
     272         [ #  # ]:          0 :   for (r = 0; r < ports - 1; r++)
     273         [ #  # ]:          0 :     k.set (r, ports - 1, g * s.get (r, ports - 1) /
     274 [ #  # ][ #  # ]:          0 :            (1.0 - g * s.get (ports - 1, ports - 1)));
                 [ #  # ]
     275                 :            : 
     276                 :            :   // create D' vector
     277         [ #  # ]:          0 :   matrix d (ports - 1, 1);
     278 [ #  # ][ #  # ]:          0 :   for (r = 0; r < ports - 1; r++) d.set (r, 0, s.get (r, ports - 1));
                 [ #  # ]
     279                 :            : 
     280                 :            :   // shrink noise correlation matrix
     281         [ #  # ]:          0 :   matrix res (ports - 1);
     282         [ #  # ]:          0 :   res = k * n * adjoint (k) + kelvin (T) / T0 * fabs (1.0 - norm (g)) /
     283 [ #  # ][ #  # ]:          0 :     norm (1.0 - g * s.get (ports - 1, ports - 1)) * d * adjoint (d);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     284 [ #  # ][ #  # ]:          0 :   return res;
     285                 :            : }
     286                 :            : 
     287                 :          0 : void spfile::prepare (void) {
     288                 :            : 
     289                 :            :   // check type of data
     290                 :          0 :   const char * const dtype = getPropertyString ("Data");
     291         [ #  # ]:          0 :   if (!strcmp (dtype, "rectangular")) {
     292                 :            :     // rectangular data
     293                 :          0 :     dataType = DATA_RECTANGULAR;
     294                 :            :   }
     295         [ #  # ]:          0 :   else if (!strcmp (dtype, "polar")) {
     296                 :            :     // polar data
     297                 :          0 :     dataType = DATA_POLAR;
     298                 :            :   }
     299                 :            : 
     300                 :            :   // check type of interpolator
     301                 :          0 :   const char * const itype = getPropertyString ("Interpolator");
     302         [ #  # ]:          0 :   if (!strcmp (itype, "linear")) {
     303                 :          0 :     interpolType = INTERPOL_LINEAR;
     304                 :            :   }
     305         [ #  # ]:          0 :   else if (!strcmp (itype, "cubic")) {
     306                 :          0 :     interpolType = INTERPOL_CUBIC;
     307                 :            :   }
     308                 :            : 
     309                 :            :   // load S-parameter file
     310                 :          0 :   const char * file = getPropertyString ("File");
     311         [ #  # ]:          0 :   if (data == NULL) data = dataset::load_touchstone (file);
     312         [ #  # ]:          0 :   if (data != NULL) {
     313                 :            :     // determine the number of ports defined by that file
     314                 :          0 :     int ports = (int) std::sqrt ((double) data->countVariables ());
     315         [ #  # ]:          0 :     if (ports == getSize () - 1) {
     316         [ #  # ]:          0 :       if (spara == NULL) {
     317                 :            :         // find matrix vector entries in touchstone dataset
     318                 :          0 :         createIndex ();
     319                 :            :       }
     320         [ #  # ]:          0 :       if (sfreq == NULL) {
     321                 :            :         logprint (LOG_ERROR, "ERROR: file `%s' contains no `frequency' "
     322                 :          0 :                   "vector\n", file);
     323                 :            :       }
     324                 :            :     }
     325                 :            :     else {
     326                 :            :       logprint (LOG_ERROR, "ERROR: file `%s' specifies a %d-port, `%s' "
     327                 :            :                 "requires a %d-port\n", file, ports, getName (),
     328                 :          0 :                 getSize () - 1);
     329                 :            :     }
     330                 :            :   }
     331                 :          0 : }
     332                 :            : 
     333                 :          0 : void spfile::initSP (void) {
     334                 :            :   // allocate S-parameter matrix
     335                 :          0 :   allocMatrixS ();
     336                 :            :   // initialize data
     337                 :          0 :   prepare ();
     338                 :          0 : }
     339                 :            : 
     340                 :            : /* The function creates an additional data vector for the given matrix
     341                 :            :    entry and adds it to the dataset. */
     342                 :          0 : void spfile::createVector (int r, int c) {
     343                 :          0 :   int i = r * getSize () + c;
     344                 :          0 :   spara[i].r = r;
     345                 :          0 :   spara[i].c = c;
     346                 :            :   qucs::vector * v = new qucs::vector (matvec::createMatrixString ("S", r, c),
     347         [ #  # ]:          0 :                                sfreq->getSize ());
     348         [ #  # ]:          0 :   v->setDependencies (new strlist ());
     349                 :          0 :   v->getDependencies()->add (sfreq->getName ());
     350                 :          0 :   data->addVariable (v);
     351                 :          0 :   spara[i].v = v;
     352                 :          0 : }
     353                 :            : 
     354                 :            : /* This function goes through the dataset stored within the original
     355                 :            :    touchstone file and looks for the S-parameter matrices and
     356                 :            :    frequency vector.  It also tries to find the noise parameter
     357                 :            :    data. */
     358                 :          0 : void spfile::createIndex (void) {
     359                 :          0 :   qucs::vector * v; int s = getSize (); char * n;
     360                 :            :   int r, c, i;
     361                 :            : 
     362                 :            :   // go through list of dependency vectors and find frequency vectors
     363         [ #  # ]:          0 :   for (v = data->getDependencies (); v != NULL; v = (::vector *) v->getNext ()) {
     364         [ #  # ]:          0 :     if ((n = v->getName ()) != NULL) {
     365         [ #  # ]:          0 :       if (!strcmp (n, "frequency")) sfreq = v;
     366         [ #  # ]:          0 :       else if (!strcmp (n, "nfreq")) nfreq = v;
     367                 :            :     }
     368                 :            :   }
     369                 :            : 
     370                 :            :   // create vector index
     371 [ #  # ][ #  # ]:          0 :   spara = new spfile_vector[s * s] ();
     372                 :            : 
     373                 :            :   // go through list of variable vectors and find matrix entries
     374         [ #  # ]:          0 :   for (v = data->getVariables (); v != NULL; v = (::vector *) v->getNext ()) {
     375 [ #  # ][ #  # ]:          0 :     if ((n = matvec::isMatrixVector (v->getName (), r, c)) != NULL) {
     376                 :            :       // save matrix vector indices
     377                 :          0 :       i = r * s + c;
     378                 :          0 :       spara[i].r = r;
     379                 :          0 :       spara[i].c = c;
     380         [ #  # ]:          0 :       spara[i].prepare (v, sfreq, false, interpolType, dataType);
     381                 :          0 :       paraType = n[0];  // save type of touchstone data
     382                 :          0 :       free (n);
     383                 :            :     }
     384         [ #  # ]:          0 :     if ((n = v->getName ()) != NULL) {
     385                 :            :       // find noise parameter vectors
     386         [ #  # ]:          0 :       if (!strcmp (n, "Rn")) {
     387         [ #  # ]:          0 :         RN = new spfile_vector ();
     388         [ #  # ]:          0 :         RN->prepare (v, nfreq, true, interpolType, dataType);
     389                 :            :       }
     390         [ #  # ]:          0 :       else if (!strcmp (n, "Fmin")) {
     391         [ #  # ]:          0 :         FMIN = new spfile_vector ();
     392         [ #  # ]:          0 :         FMIN->prepare (v, nfreq, true, interpolType, dataType);
     393                 :            :       }
     394         [ #  # ]:          0 :       else if (!strcmp (n, "Sopt")) {
     395         [ #  # ]:          0 :         SOPT = new spfile_vector ();
     396         [ #  # ]:          0 :         SOPT->prepare (v, nfreq, false, interpolType, dataType);
     397                 :            :       }
     398                 :            :     }
     399                 :            :   }
     400                 :          0 : }
     401                 :            : 
     402                 :            : /* This function computes the noise correlation matrix of a twoport
     403                 :            :    based upon the noise parameters and the given S-parameter
     404                 :            :    matrix. */
     405                 :          0 : matrix spfile::correlationMatrix (nr_double_t Fmin, nr_complex_t Sopt,
     406                 :            :                                   nr_double_t Rn, matrix s) {
     407 [ #  # ][ #  # ]:          0 :   assert (s.getCols () == s.getRows () && s.getCols () == 2);
                 [ #  # ]
     408         [ #  # ]:          0 :   matrix c (2);
     409         [ #  # ]:          0 :   nr_complex_t Kx = 4 * Rn / z0 / norm (1.0 + Sopt);
     410 [ #  # ][ #  # ]:          0 :   c.set (0, 0, (Fmin - 1) * (norm (s.get (0, 0)) - 1) +
     411 [ #  # ][ #  # ]:          0 :          Kx * norm (1.0 - s.get (0, 0) * Sopt));
         [ #  # ][ #  # ]
     412 [ #  # ][ #  # ]:          0 :   c.set (1, 1, norm (s.get (1, 0)) * ((Fmin - 1) + Kx * norm (Sopt)));
         [ #  # ][ #  # ]
     413 [ #  # ][ #  # ]:          0 :   c.set (0, 1, s.get (0, 0) / s.get (1, 0) * c.get (1, 1) -
         [ #  # ][ #  # ]
     414 [ #  # ][ #  # ]:          0 :          conj (s.get (1, 0)) * conj (Sopt) * Kx);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     415 [ #  # ][ #  # ]:          0 :   c.set (1, 0, conj (c.get (0, 1)));
     416                 :          0 :   return c;
     417                 :            : }
     418                 :            : 
     419                 :            : /* The function computes the noise figure and noise parameters for the
     420                 :            :    given S-parameter and noise correlation matrices of a twoport. */
     421                 :          0 : nr_double_t spfile::noiseFigure (matrix s, matrix c, nr_double_t& Fmin,
     422                 :            :                                  nr_complex_t& Sopt, nr_double_t& Rn) {
     423 [ #  # ][ #  # ]:          0 :   assert (s.getCols () == s.getRows () && c.getCols () == c.getRows () &&
         [ #  # ][ #  # ]
     424         [ #  # ]:          0 :           s.getCols () == 2 && c.getCols () == 2);
     425                 :          0 :   nr_complex_t n1, n2;
     426 [ #  # ][ #  # ]:          0 :   n1 = c.get (0, 0) * norm (s.get (1, 0)) -
                 [ #  # ]
     427 [ #  # ][ #  # ]:          0 :     2 * real (c.get (0, 1) * s.get (1, 0) * conj (s.get (0, 0))) +
         [ #  # ][ #  # ]
                 [ #  # ]
     428 [ #  # ][ #  # ]:          0 :     c.get (1, 1) * norm (s.get (0, 0));
                 [ #  # ]
     429 [ #  # ][ #  # ]:          0 :   n2 = 2.0 * (c.get (1, 1) * s.get (0, 0) -
     430 [ #  # ][ #  # ]:          0 :               c.get (0, 1) * s.get (1, 0)) / (c.get (1, 1) + n1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     431                 :            : 
     432                 :            :   // optimal source reflection coefficient
     433         [ #  # ]:          0 :   Sopt = 1 - norm (n2);
     434         [ #  # ]:          0 :   if (real (Sopt) < 0.0)
     435         [ #  # ]:          0 :     Sopt = (1.0 + std::sqrt (Sopt)) / n2;  // avoid a negative radicant
     436                 :            :   else
     437         [ #  # ]:          0 :     Sopt = (1.0 - std::sqrt (Sopt)) / n2;
     438                 :            : 
     439                 :            :   // minimum noise figure
     440 [ #  # ][ #  # ]:          0 :   Fmin = real (1.0 + (c.get (1, 1) - n1 * norm (Sopt)) /
     441 [ #  # ][ #  # ]:          0 :                norm (s.get (1, 0)) / (1.0 + norm (Sopt)));
         [ #  # ][ #  # ]
     442                 :            : 
     443                 :            :   // equivalent noise resistance
     444                 :          0 :   Rn = real ((c (0, 0) - 2.0 *
     445 [ #  # ][ #  # ]:          0 :               real (c (0, 1) * conj ((1.0 + s (0, 0)) / s (1, 0))) +
     446 [ #  # ][ #  # ]:          0 :               c (1, 1) * norm ((1.0 + s (0, 0)) / s (1, 0))) / 4.0);
     447                 :          0 :   Rn = Rn * z0;
     448                 :            : 
     449                 :            :   // noise figure itself
     450 [ #  # ][ #  # ]:          0 :   return real (1.0 + c.get (1, 1) / norm (s.get (1, 0)));
                 [ #  # ]
     451                 :            : }
     452                 :            : 
     453                 :          0 : void spfile::initDC (void) {
     454                 :            :   // get appropriate property value
     455                 :          0 :   const char * const dc = getPropertyString ("duringDC");
     456                 :            : 
     457                 :            :   // a short during DC including the reference node
     458         [ #  # ]:          0 :   if (!strcmp (dc, "shortall")) {
     459                 :          0 :     int v, n, lastnode = getSize () - 1;
     460                 :          0 :     setVoltageSources (lastnode);
     461                 :          0 :     allocMatrixMNA ();
     462                 :            :     // place zero voltage sources
     463         [ #  # ]:          0 :     for (v = VSRC_1, n = NODE_1; n < lastnode; n++, v++) {
     464                 :          0 :       voltageSource (v, n, lastnode);
     465                 :            :     }
     466                 :          0 :     return;
     467                 :            :   }
     468                 :            :   // a short during DC excluding the reference node
     469         [ #  # ]:          0 :   if (!strcmp (dc, "short")) {
     470                 :          0 :     int v, n, lastnode = getSize () - 2;
     471                 :          0 :     setVoltageSources (lastnode);
     472                 :          0 :     allocMatrixMNA ();
     473                 :            :     // place zero voltage sources
     474         [ #  # ]:          0 :     for (v = VSRC_1, n = NODE_1; n < lastnode; n++, v++) {
     475                 :          0 :       voltageSource (v, n, lastnode);
     476                 :            :     }
     477                 :          0 :     return;
     478                 :            :   }
     479                 :            :   // an open during DC
     480         [ #  # ]:          0 :   else if (!strcmp (dc, "open")) {
     481                 :          0 :     setVoltageSources (0);
     482                 :          0 :     allocMatrixMNA ();
     483                 :          0 :     return;
     484                 :            :   }
     485                 :            :   // none specified, DC value of IDFT ?
     486                 :            :   else {
     487                 :          0 :     setVoltageSources (0);
     488                 :          0 :     allocMatrixMNA ();
     489                 :            :   }
     490                 :            : }
     491                 :            : 
     492                 :          0 : void spfile::initAC (void) {
     493                 :          0 :   setVoltageSources (0);
     494                 :          0 :   allocMatrixMNA ();
     495                 :          0 :   initSP ();
     496                 :          0 : }
     497                 :            : 
     498                 :          0 : void spfile::calcAC (nr_double_t frequency) {
     499                 :            :   // nothing to do if the given file type had errors
     500 [ #  # ][ #  # ]:          0 :   if (spara == NULL || sfreq == NULL) return;
     501                 :            :   // calculate interpolated S-parameters
     502                 :          0 :   calcSP (frequency);
     503                 :            :   // convert S-parameters to Y-parameters
     504 [ #  # ][ #  # ]:          0 :   setMatrixY (stoy (getMatrixS ()));
         [ #  # ][ #  # ]
                 [ #  # ]
     505                 :            : }
     506                 :            : 
     507                 :          0 : void spfile::calcNoiseAC (nr_double_t frequency) {
     508                 :            :   // nothing to do if the given file type had errors
     509 [ #  # ][ #  # ]:          0 :   if (spara == NULL || nfreq == NULL) return;
     510 [ #  # ][ #  # ]:          0 :   setMatrixN (cstocy (calcMatrixCs (frequency), getMatrixY () * z0) / z0);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     511                 :            : }
     512                 :            : 
     513                 :          0 : void spfile::initTR (void) {
     514                 :          0 :   initDC ();
     515                 :          0 : }
     516                 :            : 
     517                 :            : // properties
     518                 :            : PROP_REQ [] = {
     519                 :            :   { "File", PROP_STR, { PROP_NO_VAL, "spfile.snp" }, PROP_NO_RANGE },
     520                 :            :   PROP_NO_PROP };
     521                 :            : PROP_OPT [] = {
     522                 :            :   { "Data", PROP_STR, { PROP_NO_VAL, "polar" },
     523                 :            :     PROP_RNG_STR2 ("rectangular", "polar") },
     524                 :            :   { "Interpolator", PROP_STR, { PROP_NO_VAL, "linear" },
     525                 :            :     PROP_RNG_STR2 ("linear", "cubic") },
     526                 :            :   { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
     527                 :            :   { "duringDC", PROP_STR, { PROP_NO_VAL, "open" },
     528                 :            :     PROP_RNG_STR4 ("open", "short", "shortall", "unspecified") },
     529                 :            :   PROP_NO_PROP };
     530                 :            : struct define_t spfile::cirdef =
     531                 :            :   { "SPfile",
     532                 :            :     PROP_NODES, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };

Generated by: LCOV version 1.11