Qucs-core  0.0.19
check_zvr.cpp
Go to the documentation of this file.
00001 /*
00002  * check_zvr.cpp - iterate a zvr file
00003  *
00004  * Copyright (C) 2006, 2007 Stefan Jahn <stefan@lkcc.org>
00005  *
00006  * This is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2, or (at your option)
00009  * any later version.
00010  *
00011  * This software is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this package; see the file COPYING.  If not, write to
00018  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  * $Id$
00022  *
00023  */
00024 
00025 #if HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #include <cmath>
00033 #include <assert.h>
00034 #include <float.h>
00035 #include <ctype.h>
00036 
00037 #include "strlist.h"
00038 #include "object.h"
00039 #include "complex.h"
00040 #include "vector.h"
00041 #include "dataset.h"
00042 #include "constants.h"
00043 #include "check_zvr.h"
00044 
00045 using namespace qucs;
00046 
00047 // Global variables.
00048 dataset * zvr_result = NULL;
00049 struct zvr_data_t * zvr_root = NULL;
00050 
00051 // Creates a valid data vector description.
00052 static char * zvr_vector_txt (struct zvr_vector_t * vec) {
00053   int i, i1 = -1, i2 = -1, off = 0, len = strlen (vec->n1);
00054   static char txt[64];
00055   // strip off leading 're' or 'im'
00056   if (strstr (vec->n1, "re") == vec->n1 ||
00057       strstr (vec->n1, "im") == vec->n1 ||
00058       strstr (vec->n1, "db") == vec->n1) {
00059     off = 2;
00060   }
00061   // strip off leading 'mag' or 'ang'
00062   else if (strstr (vec->n1, "mag") == vec->n1 ||
00063            strstr (vec->n1, "ang") == vec->n1) {
00064     off = 3;
00065   }
00066   for (i = off; i < len; i++) if (!isalpha (vec->n1[i])) break;
00067   // get index 1
00068   if (i < len) {
00069     if (isdigit (vec->n1[i])) { i1 = vec->n1[i] - '0'; vec->n1[i] = '\0'; }
00070   }
00071   // get index 2
00072   if (++i < len) {
00073     if (isdigit (vec->n1[i])) { i2 = vec->n1[i] - '0'; vec->n1[i] = '\0'; }
00074   }
00075   // create vector description
00076   if (i1 >= 0 && i2 >= 0) {
00077     sprintf (txt, "%s[%d,%d]", &vec->n1[off], i1, i2);
00078   }
00079   else if (i1 >= 0) {
00080     sprintf (txt, "%s[%d]", &vec->n1[off], i1);
00081   }
00082   else {
00083     sprintf (txt, "%s", &vec->n1[off]);
00084   }
00085   return txt;
00086 }
00087 
00088 // The function free's the memory used by the ZVR checker.
00089 static void zvr_finalize (void) {
00090   struct zvr_data_t * root, * next;
00091   // go through each dataset
00092   for (root = zvr_root; root; root = next) {
00093     struct zvr_vector_t * vec = root->v;
00094     struct zvr_header_t * hdr = root->h;
00095     next = root->next;
00096     // free each data line
00097     if (root->d) {
00098       struct zvr_line_t * rl, * nl;
00099       for (rl = root->d; rl; rl = nl) {
00100         nl = rl->next;
00101         free (rl);
00102       }
00103     }
00104     // free header
00105     if (hdr) {
00106       free (hdr->funit);
00107       free (hdr->d_UNT);
00108       free (hdr->d_FMT);
00109       free (hdr->d_TYP);
00110       free (hdr);
00111     }
00112     // free data vector
00113     if (vec) {
00114       free (vec->nf);
00115       free (vec->n1);
00116       free (vec->n2);
00117       free (vec);
00118     }
00119   }
00120   zvr_root = NULL;
00121 }
00122 
00123 // Create a dependency string list.
00124 static strlist * zvr_create_dep (char * n) {
00125   strlist * dep = new strlist ();
00126   dep->add (n);
00127   return dep;
00128 }
00129 
00130 // Handles the dependency vectors.
00131 static void zvr_check_dependencies (void) {
00132   vector * dep1 = zvr_result->getDependencies ();
00133   vector * depn = (vector *) dep1->getNext ();
00134   bool equal;
00135 
00136   // check for differing dependency vectors
00137   for (equal = true; depn != NULL; depn = (vector *) depn->getNext ()) {
00138     if (depn->getSize () != dep1->getSize ()) {
00139       equal = false; // differs in size
00140       break;
00141     } else {
00142       for (int i = 0; i < depn->getSize (); i++) {
00143         if (depn->get (i) != dep1->get (i)) {
00144           equal = false; // differs in content
00145           break;
00146         }
00147       }
00148     }
00149   }
00150 
00151   // all dependency vectors equal
00152   if (equal) {
00153     vector * ndep;
00154     // delete unnecessary vectors
00155     for (depn = (vector *) dep1->getNext (); depn != NULL; depn = ndep) {
00156       ndep = (vector *) depn->getNext ();
00157       zvr_result->delDependency (depn);
00158     }
00159   }
00160   // at least one dependency vectors not equal
00161   else {
00162     vector * depn = zvr_result->getDependencies ();
00163     vector * varn = zvr_result->getVariables ();
00164     char txt[64]; int i = 1;
00165     // change name of dependency vectors as well as the dependency
00166     // reference in the appropriate variable vectors
00167     while (depn != NULL && varn != NULL) {
00168       sprintf (txt, "%s.%d", depn->getName (), i);
00169       depn->setName (txt);
00170       varn->setDependencies (zvr_create_dep (txt));
00171       depn = (vector *) depn->getNext ();
00172       varn = (vector *) varn->getNext ();
00173       i++;
00174     }
00175   }
00176 }
00177 
00178 // The function performs the data conversion if necessary.
00179 static void zvr_conversion (struct zvr_data_t * root) {
00180   for (; root != NULL; root = root->next) {
00181     struct zvr_vector_t * vec = root->v;
00182     struct zvr_header_t * hdr = root->h;
00183     vector * var = vec->vd; int n;
00184     // magnitude in [dB] and angle in [degree]
00185     if (!strcmp (hdr->d_FMT, "COMPLEX") && !strcmp (hdr->d_UNT, "dB")) {
00186       for (n = 0; n < var->getSize (); n++) {
00187         nr_double_t r = real (var->get (n));
00188         nr_double_t i = imag (var->get (n));
00189         var->set (std::polar (std::pow (10.0, r / 20.0), deg2rad (i)), n);
00190       }
00191     }
00192     // magnitude in [dB]
00193     else if (!strcmp (hdr->d_FMT, "MAGNITUDE") && !strcmp (hdr->d_UNT, "dB")) {
00194       for (n = 0; n < var->getSize (); n++) {
00195         nr_double_t r = real (var->get (n));
00196         var->set (std::pow (10.0, r / 20.0), n);
00197       }
00198     }
00199     // linear magnitude and angle in [degree]
00200     else if (!strcmp (hdr->d_FMT, "MA")) {
00201       for (n = 0; n < var->getSize (); n++) {
00202         nr_double_t r = real (var->get (n));
00203         nr_double_t i = imag (var->get (n));
00204         var->set (std::polar (r, deg2rad (i)), n);
00205       }
00206     }
00207     // magnitude in [dB] and angle in [degree]
00208     else if (!strcmp (hdr->d_FMT, "DB")) {
00209       for (n = 0; n < var->getSize (); n++) {
00210         nr_double_t r = real (var->get (n));
00211         nr_double_t i = imag (var->get (n));
00212         var->set (std::polar (std::pow (10.0, r / 20.0), deg2rad (i)), n);
00213       }
00214     }
00215   }
00216 }
00217 
00218 /* This function is the overall ZVR data checker.  It returns zero on
00219    success, non-zero otherwise. */
00220 int zvr_check (void) {
00221   int errors = 0;
00222   struct zvr_data_t * root;
00223 
00224   // create a dataset
00225   zvr_result = new dataset ();
00226 
00227   // transfer ZVR tree data into the dataset
00228   for (root = zvr_root; root; root = root->next) {
00229     struct zvr_vector_t * vec = root->v;
00230     vec->vi->setName (vec->nf);
00231     vec->vd->setName (zvr_vector_txt (vec));
00232     for (struct zvr_line_t * line = root->d; line; line = line->next) {
00233       vec->vi->add (line->d);
00234       vec->vd->add (nr_complex_t (line->r, line->i));
00235     }
00236     vec->vd->setDependencies (zvr_create_dep (vec->nf));
00237     zvr_result->appendDependency (vec->vi);
00238     zvr_result->appendVariable (vec->vd);
00239   }
00240 
00241   // handle dependency vectors
00242   zvr_check_dependencies ();
00243 
00244   // perform data conversions
00245   zvr_conversion (zvr_root);
00246 
00247   // free temporary memory
00248   zvr_finalize ();
00249   zvr_root = NULL;
00250 
00251   return errors ? -1 : 0;
00252 }
00253 
00254 // Destroys data used by the ZVR checker.
00255 void zvr_destroy (void) {
00256   if (zvr_result != NULL) {
00257     // delete associated dataset
00258     delete zvr_result;
00259     zvr_result = NULL;
00260   }
00261   if (zvr_root != NULL) {
00262     zvr_finalize ();
00263     zvr_root = NULL;
00264   }
00265 }
00266 
00267 // Initializes the ZVR checker.
00268 void zvr_init (void) {
00269   zvr_result = NULL;
00270   zvr_root = NULL;
00271 }