Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
matlab_producer.cpp
Go to the documentation of this file.
1 /*
2  * matlab_producer.cpp - the Matlab data file producer
3  *
4  * Copyright (C) 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 <stdio.h>
30 #include <stdlib.h>
31 #include <time.h>
32 #include <ctype.h>
33 #include <string.h>
34 
35 #include "matlab_producer.h"
36 #include "matrix.h"
37 #include "matvec.h"
38 #include "constants.h"
39 
40 using namespace qucs;
41 
42 /* Global variables. */
43 FILE * matlab_out = NULL; // output file stream
44 int matlab_symbols = 1; // convert data names to have valid Matlab identifier
45 int nr_bigendian = 0; // endianness
46 
47 // Test endianness.
48 static void initendian (void) {
49  unsigned char EndianTest[2] = { 1, 0 };
50  nr_int16_t x = * (nr_int16_t *) EndianTest;
51  nr_bigendian = (x == 1) ? 0 : 1;
52 }
53 
54 // Writes a Matlab v4 header.
55 static void matlab_header (nr_int32_t rows, nr_int32_t cols, char * name) {
56 
57  // MOPT
58  char mopt[4];
59  mopt[0] = nr_bigendian ? 1 : 0; // endianness
60  mopt[1] = 0; // always zero
61  switch (sizeof (nr_double_t) * 8) {
62  case 32: mopt[2] = 1; break;
63  case 64: mopt[2] = 0; break;
64  }
65  mopt[3] = 0; // numeric full matrix
66  fwrite (mopt, sizeof (mopt), 1, matlab_out);
67 
68  // dimension
69  fwrite (&rows, sizeof (nr_int32_t), 1, matlab_out);
70  fwrite (&cols, sizeof (nr_int32_t), 1, matlab_out);
71 
72  // imaginary flag
73  nr_int32_t imag = 1;
74  fwrite (&imag, sizeof (nr_int32_t), 1, matlab_out);
75 
76  // data name length
77  nr_int32_t len = strlen (name) + 1;
78  fwrite (&len, sizeof (nr_int32_t), 1, matlab_out);
79 
80  // data name
81  if (matlab_symbols) {
82  char * p = name;
83  // convert to valid Matlab identifiers
84  for (unsigned int i = 0; i < strlen (name); i++, p++) {
85  if (!isalnum (*p) && *p != '_')
86  *p = '_';
87  }
88  }
89  fwrite (name, 1, len, matlab_out);
90 }
91 
92 // Writes a Matlab v4 vector.
93 static void matlab_vector (::vector * v) {
94  int n;
95 
96  // real part
97  for (n = 0; n < v->getSize (); n++) {
98  nr_double_t r = real (v->get (n));
99  fwrite (&r, sizeof (nr_double_t), 1, matlab_out);
100  }
101  // imaginary part
102  for (n = 0; n < v->getSize (); n++) {
103  nr_double_t i = imag (v->get (n));
104  fwrite (&i, sizeof (nr_double_t), 1, matlab_out);
105  }
106 }
107 
108 // Writes a Matlab v4 matrix.
109 static void matlab_matrix (matrix * m) {
110  int r, c;
111 
112  // real part
113  for (c = 0; c < m->getCols (); c++) {
114  for (r = 0; r < m->getRows (); r++) {
115  nr_double_t re = real (m->get (r, c));
116  fwrite (&re, sizeof (nr_double_t), 1, matlab_out);
117  }
118  }
119  // imaginary part
120  for (c = 0; c < m->getCols (); c++) {
121  for (r = 0; r < m->getRows (); r++) {
122  nr_double_t im = imag (m->get (r, c));
123  fwrite (&im, sizeof (nr_double_t), 1, matlab_out);
124  }
125  }
126 }
127 
128 // Saves a dataset vector into a Matlab file.
129 static void matlab_save (::vector * v) {
130  int r, c;
131  char * n, * sn;
132  char * vn = v->getName ();
133  matvec * mv = NULL;
134  matrix m;
135 
136  // is vector matrix entry
137  if ((n = matvec::isMatrixVector (vn, r, c)) != NULL) {
138  // valid matrix vector and simple matrix
139  if ((mv = matvec::getMatrixVector (v, n)) != NULL && mv->getSize () == 1) {
140  // only save at first matrix entry [1,1]
141  if (r == 0 && c == 0) {
142  // save matrix
143  matlab_header (mv->getRows (), mv->getCols (), n);
144  m = mv->get (0);
145  matlab_matrix (&m);
146  }
147  }
148  else {
149  // save vector
150  sn = (char *) malloc (strlen (n) + 8);
151  if (matlab_symbols) {
152  // convert indices to valid Matlab identifiers
153  sprintf (sn, "%s_%d_%d", n, r + 1, c + 1);
154  } else {
155  sprintf (sn, "%s", vn);
156  }
157  matlab_header (v->getSize (), 1, sn);
158  matlab_vector (v);
159  free (sn);
160  }
161  free (n);
162  if (mv) delete mv;
163  }
164  else {
165  // save vector
166  matlab_header (v->getSize (), 1, vn);
167  matlab_vector (v);
168  }
169 }
170 
171 /* This is the overall Matlab producer. */
172 void matlab_producer (void) {
173 
174  dataset * data = qucs_data;
175  qucs::vector * v;
176 
177  // initialize endianness
178  initendian ();
179 
180  // independent vectors and matrices
181  for (v = data->getDependencies (); v != NULL; v = (::vector *) v->getNext ()) {
182  matlab_save (v);
183  }
184 
185  // dependent vectors and matrices
186  for (v = data->getVariables (); v != NULL; v = (::vector *) v->getNext ()) {
187  matlab_save (v);
188  }
189 }
matrix real(matrix a)
Real part matrix.
Definition: matrix.cpp:568
name
Definition: parse_mdl.y:352
static void matlab_header(nr_int32_t rows, nr_int32_t cols, char *name)
int nr_bigendian
Global physical constants header file.
void matlab_producer(void)
n
Definition: parse_citi.y:147
r
Definition: parse_mdl.y:515
object * getNext(void)
Definition: object.h:59
static void matlab_save(::vector *v)
i
Definition: parse_mdl.y:516
matrix imag(matrix a)
Imaginary part matrix.
Definition: matrix.cpp:581
static void initendian(void)
static matvec * getMatrixVector(qucs::vector *, char *)
Definition: matvec.cpp:200
static void matlab_vector(::vector *v)
free($1)
x
Definition: parse_mdl.y:498
Dense matrix class header file.
FILE * matlab_out
v
Definition: parse_zvr.y:141
static void matlab_matrix(matrix *m)
qucs::dataset * qucs_data
strlist * getDependencies(void)
Definition: vector.cpp:138
int matlab_symbols
static char * isMatrixVector(char *, int &, int &)
Definition: matvec.cpp:148
data
Definition: parse_citi.y:117