Qucs-core
0.0.19
|
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 }