Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dataset.cpp
Go to the documentation of this file.
1 /*
2  * dataset.cpp - dataset class implementation
3  *
4  * Copyright (C) 2003, 2004, 2005, 2006, 2007 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 <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <assert.h>
34 #include <cmath>
35 
36 #include "logging.h"
37 #include "complex.h"
38 #include "object.h"
39 #include "strlist.h"
40 #include "vector.h"
41 #include "dataset.h"
42 #include "check_dataset.h"
43 #include "check_touchstone.h"
44 #include "check_csv.h"
45 #include "check_citi.h"
46 #include "check_zvr.h"
47 #include "check_mdl.h"
48 
49 namespace qucs {
50 
51 // Constructor creates an unnamed instance of the dataset class.
53  variables = dependencies = NULL;
54  file = NULL;
55 }
56 
57 // Constructor creates an named instance of the dataset class.
58 dataset::dataset (char * n) : object (n) {
59  variables = dependencies = NULL;
60  file = NULL;
61 }
62 
63 /* The copy constructor creates a new instance based on the given
64  dataset object. */
65 dataset::dataset (const dataset & d) : object (d) {
66  file = d.file ? strdup (d.file) : NULL;
67  vector * v;
68  // copy dependency vectors
69  for (v = d.dependencies; v != NULL; v = (vector *) v->getNext ()) {
70  addDependency (new vector (*v));
71  }
72  // copy variable vectors
73  for (v = variables; v != NULL; v = (vector *) v->getNext ()) {
74  addVariable (new vector (*v));
75  }
76 }
77 
78 // Destructor deletes a dataset object.
80  vector * n, * v;
81  // delete dependency vectors
82  for (v = dependencies; v != NULL; v = n) {
83  n = (vector *) v->getNext ();
84  delete v;
85  }
86  // delete variable vectors
87  for (v = variables; v != NULL; v = n) {
88  n = (vector *) v->getNext ();
89  delete v;
90  }
91  if (file) free (file);
92 }
93 
94 // This function adds a dependency vector to the current dataset.
97  v->setNext (dependencies);
98  v->setPrev (NULL);
99  dependencies = v;
100 }
101 
102 // This function removes a dependency vector from the current dataset.
104  if (dependencies == v) {
105  dependencies = (vector *) v->getNext ();
106  if (dependencies) dependencies->setPrev (NULL);
107  }
108  else {
109  vector * next = (vector *) v->getNext ();
110  vector * prev = (vector *) v->getPrev ();
111  prev->setNext (next);
112  if (next) next->setPrev (prev);
113  }
114  delete v;
115 }
116 
117 /* The function adds the given list of vectors to the dependency set
118  of the current dataset. */
120  vector * next;
121  for (vector * t = v; t != NULL; t = next) {
122  next = (vector *) t->getNext ();
123  addDependency (t);
124  }
125 }
126 
127 // This function appends a dependency vector to the current dataset.
129  vector * e;
130  if (dependencies) {
131  for (e = dependencies; e->getNext (); e = (vector *) e->getNext ()) ;
132  v->setPrev (e);
133  e->setNext (v);
134  }
135  else {
136  v->setPrev (NULL);
137  dependencies= v;
138  }
139  v->setNext (NULL);
140 }
141 
142 /* The function appends the given list of vectors to the dependency
143  set of the current dataset. */
145  vector * next;
146  for (vector * t = v; t != NULL; t = next) {
147  next = (vector *) t->getNext ();
149  }
150 }
151 
152 // This function adds a variable vector to the current dataset.
154  if (variables) variables->setPrev (v);
155  v->setNext (variables);
156  v->setPrev (NULL);
157  variables = v;
158 }
159 
160 // This function removes a variable vector from the current dataset.
162  if (variables == v) {
163  variables = (vector *) v->getNext ();
164  if (variables) variables->setPrev (NULL);
165  }
166  else {
167  vector * next = (vector *) v->getNext ();
168  vector * prev = (vector *) v->getPrev ();
169  prev->setNext (next);
170  if (next) next->setPrev (prev);
171  }
172  delete v;
173 }
174 
175 /* The function adds the given list of vectors to the variable set of
176  the current dataset. */
178  vector * next;
179  for (vector * t = v; t != NULL; t = next) {
180  next = (vector *) t->getNext ();
181  addVariable (t);
182  }
183 }
184 
185 // This function appends a variable vector to the current dataset.
187  vector * e;
188  if (variables) {
189  for (e = variables; e->getNext (); e = (vector *) e->getNext ()) ;
190  v->setPrev (e);
191  e->setNext (v);
192  }
193  else {
194  v->setPrev (NULL);
195  variables = v;
196  }
197  v->setNext (NULL);
198 }
199 
200 /* The function appends the given list of vectors to the variable set
201  of the current dataset. */
203  vector * next;
204  for (vector * t = v; t != NULL; t = next) {
205  next = (vector *) t->getNext ();
206  appendVariable (t);
207  }
208 }
209 
210 /* This function applies the dependency string list of the given
211  vector to the list of vectors appended to this vector. */
213  strlist * deps = v->getDependencies ();
214  if (deps != NULL) {
215  vector * next;
216  for (vector * t = (vector *) v->getNext (); t != NULL; t = next) {
217  next = (vector *) t->getNext ();
218  if (t->getDependencies () == NULL) {
219  t->setDependencies (new strlist (*deps));
220  }
221  }
222  }
223 }
224 
225 /* This function returns the dataset vector (both independent and
226  dependent) with the given origin. It returns NULL if there is no
227  such vector. */
229  vector * v;
230  for (v = variables; v != NULL; v = (vector *) v->getNext ()) {
231  char * origin = v->getOrigin ();
232  if (origin != NULL && n != NULL && !strcmp (n, origin))
233  return v;
234  }
235  for (v = dependencies; v != NULL; v = (vector *) v->getNext ()) {
236  char * origin = v->getOrigin ();
237  if (origin != NULL && n != NULL && !strcmp (n, origin))
238  return v;
239  }
240  return NULL;
241 }
242 
243 /* This function assigns dependency entries to variable vectors which
244  do have the specified origin. */
245 void dataset::assignDependency (char * origin, char * depvar) {
246  for (vector * v = variables; v != NULL; v = (vector *) v->getNext ()) {
247  char * n = v->getOrigin ();
248  if (n != NULL && origin != NULL && !strcmp (origin, n)) {
249  strlist * deplist = v->getDependencies ();
250  if (deplist != NULL) {
251  if (!deplist->contains (depvar)) {
252  deplist->append (depvar);
253  }
254  }
255  else {
256  deplist = new strlist ();
257  deplist->add (depvar);
258  v->setDependencies (deplist);
259  }
260  }
261  }
262 }
263 
264 // Return non-zero if the given vector is an independent variable vector.
266  for (vector * v = dependencies; v != NULL; v = (vector *) v->getNext ())
267  if (v == dep) return 1;
268  return 0;
269 }
270 
271 // Return non-zero if the given vector is a dependent variable vector.
273  for (vector * v = variables; v != NULL; v = (vector *) v->getNext ())
274  if (v == var) return 1;
275  return 0;
276 }
277 
278 /* The function goes through the list of dependencies in the dataset
279  and returns the vector specified by the given name. Otherwise the
280  function returns NULL. */
281 vector * dataset::findDependency (const char * n) {
282  for (vector * v = dependencies; v != NULL; v = (vector *) v->getNext ()) {
283  if (!strcmp (v->getName (), n))
284  return v;
285  }
286  return NULL;
287 }
288 
289 /* The function goes through the list of variables in the dataset and
290  returns the vector specified by the given name. If there is no
291  such variable registered the function returns NULL. */
292 vector * dataset::findVariable (const char * n) {
293  for (vector * v = variables; v != NULL; v = (vector *) v->getNext ()) {
294  if (!strcmp (v->getName (), n))
295  return v;
296  }
297  return NULL;
298 }
299 
300 // Returns the number of variable vectors.
302  int count = 0;
303  for (vector * v = variables; v != NULL; v = (vector *) v->getNext ())
304  count++;
305  return count;
306 }
307 
308 // Returns the number of dependency vectors.
310  int count = 0;
311  for (vector * v = dependencies; v != NULL; v = (vector *) v->getNext ())
312  count++;
313  return count;
314 }
315 
316 // Returns the current output file name.
317 char * dataset::getFile (void) {
318  return file;
319 }
320 
321 /* Sets the current output file name. The file name is used during
322  the print functionality of the dataset class. */
323 void dataset::setFile (const char * f) {
324  if (file) free (file);
325  file = f ? strdup (f) : NULL;
326 }
327 
328 /* This function prints the current dataset representation either to
329  the specified file name (given by the function setFile()) or to
330  stdout if there is no such file name given. */
331 void dataset::print (void) {
332 
333  FILE * f = stdout;
334 
335  // open file for writing
336  if (file) {
337  if ((f = fopen (file, "w")) == NULL) {
338  logprint (LOG_ERROR, "cannot create file `%s': %s\n",
339  file, strerror (errno));
340  return;
341  }
342  }
343 
344  // print header
345  fprintf (f, "<Qucs Dataset " PACKAGE_VERSION ">\n");
346 
347  // print dependencies
348  for (vector * d = dependencies; d != NULL; d = (vector *) d->getNext ()) {
349  printDependency (d, f);
350  }
351 
352  // print variables
353  for (vector * v = variables; v != NULL; v = (vector *) v->getNext ()) {
354  if (v->getDependencies () != NULL)
355  printVariable (v, f);
356  else
357  printDependency (v, f);
358  }
359 
360  // close file if necessary
361  if (file) fclose (f);
362 }
363 
364 /* Prints the given vector as independent dataset vector into the
365  given file descriptor. */
366 void dataset::printDependency (vector * v, FILE * f) {
367  // print data header
368  fprintf (f, "<indep %s %d>\n", v->getName (), v->getSize ());
369  // print data itself
370  printData (v, f);
371  // print data footer
372  fprintf (f, "</indep>\n");
373 }
374 
375 /* Prints the given vector as dependent dataset vector into the given
376  file descriptor. */
377 void dataset::printVariable (vector * v, FILE * f) {
378  // print data header
379  fprintf (f, "<dep %s", v->getName ());
380  if (v->getDependencies () != NULL) {
381  for (strlistiterator it (v->getDependencies ()); *it; ++it)
382  fprintf (f, " %s", *it);
383  }
384  fprintf (f, ">\n");
385 
386  // print data itself
387  printData (v, f);
388 
389  // print data footer
390  fprintf (f, "</dep>\n");
391 }
392 
393 /* This function is a helper routine for the print() functionality of
394  the dataset class. It prints the data items of the given vector
395  object to the given output stream. */
396 void dataset::printData (vector * v, FILE * f) {
397  for (int i = 0; i < v->getSize (); i++) {
398  nr_complex_t c = v->get (i);
399  if (imag (c) == 0.0) {
400  fprintf (f, " %+." NR_DECS "e\n", (double) real (c));
401  }
402  else {
403  fprintf (f, " %+." NR_DECS "e%cj%." NR_DECS "e\n", (double) real (c),
404  imag (c) >= 0.0 ? '+' : '-', (double) fabs (imag (c)));
405  }
406  }
407 }
408 
409 /* This static function read a full dataset from the given file and
410  returns it. On failure the function emits appropriate error
411  messages and returns NULL. */
412 dataset * dataset::load (const char * file) {
413  FILE * f;
414  if ((f = fopen (file, "r")) == NULL) {
415  logprint (LOG_ERROR, "error loading `%s': %s\n", file, strerror (errno));
416  return NULL;
417  }
418  dataset_in = f;
420  if (dataset_parse () != 0) {
421  fclose (f);
422  return NULL;
423  }
424  if (dataset_result != NULL) {
425  if (dataset_check (dataset_result) != 0) {
426  fclose (f);
427  delete dataset_result;
428  return NULL;
429  }
430  }
431  fclose (f);
433  dataset_result->setFile (file);
434  return dataset_result;
435 }
436 
437 /* This static function read a full dataset from the given touchstone
438  file and returns it. On failure the function emits appropriate
439  error messages and returns NULL. */
440 dataset * dataset::load_touchstone (const char * file) {
441  FILE * f;
442  if ((f = fopen (file, "r")) == NULL) {
443  logprint (LOG_ERROR, "error loading `%s': %s\n", file, strerror (errno));
444  return NULL;
445  }
446  touchstone_in = f;
448  if (touchstone_parse () != 0) {
449  fclose (f);
450  return NULL;
451  }
452  if (touchstone_check () != 0) {
453  fclose (f);
454  return NULL;
455  }
456  fclose (f);
458  touchstone_result->setFile (file);
459  return touchstone_result;
460 }
461 
462 /* This static function read a full dataset from the given CSV file
463  and returns it. On failure the function emits appropriate error
464  messages and returns NULL. */
465 dataset * dataset::load_csv (const char * file) {
466  FILE * f;
467  if ((f = fopen (file, "r")) == NULL) {
468  logprint (LOG_ERROR, "error loading `%s': %s\n", file, strerror (errno));
469  return NULL;
470  }
471  csv_in = f;
473  if (csv_parse () != 0) {
474  fclose (f);
475  return NULL;
476  }
477  if (csv_check () != 0) {
478  fclose (f);
479  return NULL;
480  }
481  fclose (f);
482  csv_lex_destroy ();
483  csv_result->setFile (file);
484  return csv_result;
485 }
486 
487 /* The function read a full dataset from the given CITIfile and
488  returns it. On failure the function emits appropriate error
489  messages and returns NULL. */
490 dataset * dataset::load_citi (const char * file) {
491  FILE * f;
492  if ((f = fopen (file, "r")) == NULL) {
493  logprint (LOG_ERROR, "error loading `%s': %s\n", file, strerror (errno));
494  return NULL;
495  }
496  citi_in = f;
498  if (citi_parse () != 0) {
499  fclose (f);
500  return NULL;
501  }
502  if (citi_check () != 0) {
503  fclose (f);
504  return NULL;
505  }
506  fclose (f);
507  citi_lex_destroy ();
508  citi_result->setFile (file);
509  return citi_result;
510 }
511 
512 /* The function read a full dataset from the given ZVR file and
513  returns it. On failure the function emits appropriate error
514  messages and returns NULL. */
515 dataset * dataset::load_zvr (const char * file) {
516  FILE * f;
517  if ((f = fopen (file, "r")) == NULL) {
518  logprint (LOG_ERROR, "error loading `%s': %s\n", file, strerror (errno));
519  return NULL;
520  }
521  zvr_in = f;
523  if (zvr_parse () != 0) {
524  fclose (f);
525  return NULL;
526  }
527  if (zvr_check () != 0) {
528  fclose (f);
529  return NULL;
530  }
531  fclose (f);
532  zvr_lex_destroy ();
533  if (zvr_result) zvr_result->setFile (file);
534  return zvr_result;
535 }
536 
537 /* The function read a full dataset from the given MDL file and
538  returns it. On failure the function emits appropriate error
539  messages and returns NULL. */
540 dataset * dataset::load_mdl (const char * file) {
541  FILE * f;
542  if ((f = fopen (file, "r")) == NULL) {
543  logprint (LOG_ERROR, "error loading `%s': %s\n", file, strerror (errno));
544  return NULL;
545  }
546  mdl_in = f;
548  if (mdl_parse () != 0) {
549  fclose (f);
550  return NULL;
551  }
552  if (mdl_check () != 0) {
553  fclose (f);
554  return NULL;
555  }
556  fclose (f);
557  mdl_lex_destroy ();
558  if (mdl_result) mdl_result->setFile (file);
559  return mdl_result;
560 }
561 
562 } // namespace qucs
static dataset * load_zvr(const char *)
Definition: dataset.cpp:515
FILE * citi_in
Definition: parse_citi.y:54
FILE * zvr_in
void addDependency(qucs::vector *)
Definition: dataset.cpp:95
void add(char *)
Definition: strlist.cpp:65
std::complex< nr_double_t > nr_complex_t
Definition: complex.h:31
FILE * touchstone_in
__BEGIN_DECLS int dataset_parse(void)
matrix real(matrix a)
Real part matrix.
Definition: matrix.cpp:568
__BEGIN_DECLS int csv_parse(void)
char * getFile(void)
Definition: dataset.cpp:317
void append(char *)
Definition: strlist.cpp:84
int dataset_check(dataset *data)
int getSize(void) const
Definition: vector.cpp:192
void applyDependencies(qucs::vector *v)
Definition: dataset.cpp:212
FILE * mdl_in
t
Definition: parse_vcd.y:290
int contains(char *)
Definition: strlist.cpp:107
void printVariable(qucs::vector *, FILE *)
Definition: dataset.cpp:377
void printDependency(qucs::vector *, FILE *)
Definition: dataset.cpp:366
int mdl_parse(void)
void printData(qucs::vector *, FILE *)
Definition: dataset.cpp:396
int countVariables(void)
Definition: dataset.cpp:301
void setNext(object *o)
Definition: object.h:60
FILE * csv_in
object * next
Definition: object.h:88
int citi_check(void)
Definition: check_citi.cpp:175
int zvr_parse(void)
n
Definition: parse_citi.y:147
int zvr_check(void)
Definition: check_zvr.cpp:220
static dataset * load_csv(const char *)
Definition: dataset.cpp:465
int mdl_lex_destroy(void)
static dataset * load_mdl(const char *)
Definition: dataset.cpp:540
object * getNext(void)
Definition: object.h:59
void appendVariable(qucs::vector *)
Definition: dataset.cpp:186
void addVariables(qucs::vector *)
Definition: dataset.cpp:177
void print(void)
Definition: dataset.cpp:331
char * getOrigin(void)
Definition: vector.cpp:919
void delDependency(qucs::vector *)
Definition: dataset.cpp:103
i
Definition: parse_mdl.y:516
matrix imag(matrix a)
Imaginary part matrix.
Definition: matrix.cpp:581
object * prev
Definition: object.h:89
void zvr_restart(FILE *)
void csv_restart(FILE *)
void addDependencies(qucs::vector *)
Definition: dataset.cpp:119
void setPrev(object *o)
Definition: object.h:62
int citi_parse(void)
int touchstone_lex_destroy(void)
dataset * dataset_result
dataset * mdl_result
Definition: check_mdl.cpp:52
int zvr_lex_destroy(void)
free($1)
dataset * zvr_result
Definition: check_zvr.cpp:48
void dataset_restart(FILE *)
qucs::vector * variables
Definition: dataset.h:80
void mdl_restart(FILE *)
void delVariable(qucs::vector *)
Definition: dataset.cpp:161
static dataset * load_citi(const char *)
Definition: dataset.cpp:490
qucs::vector * findOrigin(char *)
Definition: dataset.cpp:228
int isVariable(qucs::vector *)
Definition: dataset.cpp:272
generic object class.
Definition: object.h:52
void addVariable(qucs::vector *)
Definition: dataset.cpp:153
int touchstone_parse(void)
static dataset * load(const char *)
Definition: dataset.cpp:412
dataset * csv_result
Definition: check_csv.cpp:50
static dataset * load_touchstone(const char *)
Definition: dataset.cpp:440
v
Definition: parse_zvr.y:141
void appendDependency(qucs::vector *)
Definition: dataset.cpp:128
qucs::vector * dependencies
Definition: dataset.h:79
int csv_lex_destroy(void)
void appendDependencies(qucs::vector *)
Definition: dataset.cpp:144
int citi_lex_destroy(void)
qucs::dataset * citi_result
Definition: check_citi.cpp:48
object * getPrev(void)
Definition: object.h:61
void assignDependency(char *, char *)
Definition: dataset.cpp:245
var
Definition: parse_citi.y:145
int touchstone_check(void)
#define LOG_ERROR
Definition: logging.h:28
char * getName(void)
Definition: object.cpp:84
int csv_check(void)
Definition: check_csv.cpp:128
qucs::vector * findDependency(const char *)
Definition: dataset.cpp:281
void appendVariables(qucs::vector *)
Definition: dataset.cpp:202
void citi_restart(FILE *)
int mdl_check(void)
Definition: check_mdl.cpp:658
qucs::vector * findVariable(const char *)
Definition: dataset.cpp:292
void logprint(int level, const char *format,...)
Definition: logging.c:37
strlist * getDependencies(void)
Definition: vector.cpp:138
int isDependency(qucs::vector *)
Definition: dataset.cpp:265
nr_complex_t get(int)
Definition: vector.cpp:179
void touchstone_restart(FILE *)
dataset * touchstone_result
FILE * dataset_in
int countDependencies(void)
Definition: dataset.cpp:309
char * file
Definition: dataset.h:78
void setFile(const char *)
Definition: dataset.cpp:323
int dataset_lex_destroy(void)