Branch data Line data Source code
1 : : /*
2 : : * matvec.cpp - matrix vector class implementation
3 : : *
4 : : * Copyright (C) 2004-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 <assert.h>
30 : : #include <stdio.h>
31 : : #include <stdlib.h>
32 : : #include <string.h>
33 : : #include <cmath>
34 : :
35 : : #include "logging.h"
36 : : #include "object.h"
37 : : #include "complex.h"
38 : : #include "vector.h"
39 : : #include "matrix.h"
40 : : #include "matvec.h"
41 : :
42 : : #if !HAVE_STRCHR
43 : : # define strchr index
44 : : # define strrchr rindex
45 : : #endif
46 : :
47 : : namespace qucs {
48 : :
49 : : // Constructor creates an unnamed instance of the matvec class.
50 : 0 : matvec::matvec () {
51 : 0 : size = 0;
52 : 0 : rows = cols = 0;
53 : 0 : name = NULL;
54 : 0 : data = NULL;
55 : 0 : }
56 : :
57 : : /* Constructor creates an unnamed instance of the matvec class with a
58 : : certain number of empty matrices. */
59 : 18 : matvec::matvec (int length, int r, int c) {
60 : 18 : size = length;
61 : 18 : rows = r;
62 : 18 : cols = c;
63 : 18 : name = NULL;
64 [ + - ][ # # ]: 18 : if (size > 0) {
65 [ + - ][ + + : 5801 : data = new matrix[size];
# # # # ]
[ # # ][ # #
# # # # ]
66 [ + - ][ + + ]: 5801 : for (int i = 0; i < size; i++) data[i] = matrix (r, c);
[ # # ][ # # ]
67 : : } else {
68 : 0 : data = NULL;
69 : : }
70 : 18 : }
71 : :
72 : : /* The copy constructor creates a new instance based on the given
73 : : matvec object. */
74 : 0 : matvec::matvec (const matvec & m) {
75 : 0 : size = m.size;
76 : 0 : rows = m.rows;
77 : 0 : cols = m.cols;
78 [ # # ][ # # ]: 0 : name = m.name ? strdup (m.name) : NULL;
79 : 0 : data = NULL;
80 : :
81 : : // copy matvec elements
82 [ # # ][ # # ]: 0 : if (size > 0) {
83 [ # # ][ # # : 0 : data = new matrix[size];
# # # # ]
[ # # ][ # #
# # # # ]
84 [ # # ][ # # ]: 0 : for (int i = 0; i < size; i++) data[i] = m.data[i];
85 : : }
86 : 0 : }
87 : :
88 : : // Destructor deletes a matvec object.
89 : 18 : matvec::~matvec () {
90 [ + - ][ # # ]: 18 : if (name) free (name);
91 [ + - ][ + - ]: 5801 : if (data) delete[] data;
[ + + ][ # # ]
[ # # ][ # # ]
92 : 18 : }
93 : :
94 : : // Sets the name of the matvec object.
95 : 18 : void matvec::setName (const char * n) {
96 [ - + ]: 18 : if (name) free (name);
97 [ + - ]: 18 : name = n ? strdup (n) : NULL;
98 : 18 : }
99 : :
100 : : // Returns the name of the matvec object.
101 : 18 : char * matvec::getName (void) {
102 : 18 : return name;
103 : : }
104 : :
105 : : /* This function saves the given vector to the matvec object with the
106 : : appropriate matrix indices. */
107 : 92 : void matvec::set (qucs::vector v, int r, int c) {
108 [ + - ][ + - ]: 92 : assert (v.getSize () == size &&
[ + - ][ + - ]
[ - + ]
109 [ - + ]: 92 : r >= 0 && r < rows && c >= 0 && c < cols);
110 [ + + ]: 24929 : for (int i = 0; i < size; i++) data[i].set (r, c, v.get (i));
111 : 92 : }
112 : :
113 : : /* The function returns the vector specified by the given matrix
114 : : indices. If the matrix vector has a valid name 'A' the returned
115 : : vector gets the name 'A[r,c]'. */
116 : 26 : qucs::vector matvec::get (int r, int c) {
117 [ + - ][ + - ]: 26 : assert (r >= 0 && r < rows && c >= 0 && c < cols);
[ + - ][ - + ]
[ - + ]
118 : 26 : qucs::vector res;
119 [ + - ][ + - ]: 10576 : for (int i = 0; i < size; i++) res.add (data[i].get (r, c));
[ + + ]
120 [ + - ]: 26 : if (name != NULL) {
121 [ + - ]: 26 : res.setName (createMatrixString (name, r, c));
122 : : }
123 : 26 : return res;
124 : : }
125 : :
126 : : /* This function returns a static text representation with the
127 : : 'n[r,c]' scheme indicating a matrix (vector) entry. */
128 : 24863 : char * matvec::createMatrixString (const char * n, int r, int c) {
129 : : static char str[256]; // hopefully enough
130 : 24863 : sprintf (str, "%s[%d,%d]", n, r + 1, c + 1);
131 : 24863 : return str;
132 : : }
133 : :
134 : : /* This function also returns a static text representation with the
135 : : 'n[r,c]' scheme indicating a matrix (vector) entry but with
136 : : different arguments. */
137 : 0 : char * matvec::createMatrixString (char n, int r, int c) {
138 : : static char str[256]; // hopefully enough
139 : 0 : sprintf (str, "%c[%d,%d]", n, r + 1, c + 1);
140 : 0 : return str;
141 : : }
142 : :
143 : : /* The function investigates the given vectors name. If this name
144 : : matches the 'n[r,c]' pattern it returns the name 'n' and saves the
145 : : row and column indices as well. The caller is responsible to
146 : : 'free()' the returned string. If the vectors name does not match
147 : : the pattern the function returns NULL. */
148 : 1218 : char * matvec::isMatrixVector (char * n, int& r, int& c) {
149 : : char * p; int len;
150 [ - + ]: 1218 : if (n == NULL) return NULL; // nothing todo here
151 [ + + ]: 1218 : if ((p = strchr (n, '[')) != NULL) { // find first '['
152 : 184 : r = atoi (p + 1) - 1; // get first index
153 [ + - ]: 184 : if ((p = strchr (p, ',')) != NULL) { // find the ','
154 : 184 : c = atoi (p + 1) - 1; // get second index
155 [ + - ]: 184 : if ((p = strchr (p, ']')) != NULL) { // find trailing ']'
156 [ + - ]: 184 : if (p[1] == '\0') { // identifier must end in ']'
157 : : // parse actual identifier
158 [ + - ]: 184 : if ((len = strchr (n, '[') - n) > 0) {
159 : 184 : p = (char *) malloc (len + 1);
160 : 184 : memcpy (p, n, len);
161 : 184 : p[len] = '\0';
162 : 184 : return p;
163 : : }
164 : : }
165 : : }
166 : : }
167 : : }
168 : 1218 : return NULL;
169 : : }
170 : :
171 : : /* This function looks through the vector list given in `data' to find
172 : : matrix entries specified by `name' and returns the matrix vector
173 : : dimensions. */
174 : 0 : void matvec::getMatrixVectorSize (qucs::vector * data, char * name,
175 : : int& rs, int& cs, int& ss) {
176 : : qucs::vector * v;
177 : : char * vn, * n;
178 : : int r, c, s;
179 : 0 : rs = cs = ss = -1;
180 : : // go through vector list
181 [ # # ]: 0 : for (v = data; v != NULL; v = (qucs::vector *) v->getNext ()) {
182 : 0 : vn = v->getName ();
183 : : // requested matrix name found?
184 [ # # ]: 0 : if (strstr (vn, name) == vn) {
185 [ # # ]: 0 : if ((n = matvec::isMatrixVector (vn, r, c)) != NULL) {
186 [ # # ]: 0 : if (rs < r) rs = r;
187 [ # # ]: 0 : if (cs < c) cs = c;
188 [ # # ]: 0 : s = v->getSize ();
189 [ # # ]: 0 : if (ss < s) ss = s;
190 : 0 : free (n);
191 : : }
192 : : }
193 : : }
194 : 0 : }
195 : :
196 : : /* This function looks through the vector list given in `data' to find
197 : : matrix entries specified by `name' and returns a matrix vector
198 : : object. If there are no such matrices the function returns
199 : : NULL. */
200 : 0 : matvec * matvec::getMatrixVector (qucs::vector * data, char * name) {
201 : :
202 : : // obtain matrix vector dimensions
203 : : int rs, cs, ss;
204 [ # # ]: 0 : getMatrixVectorSize (data, name, rs, cs, ss);
205 : :
206 : : qucs::vector * v;
207 : : char * vn, * n;
208 : : int r, c;
209 : : // valid matrix entries found
210 [ # # ][ # # ]: 0 : if (rs >= 0 && cs >= 0 && ss > 0) {
[ # # ]
211 : : // create matrix vector
212 [ # # ][ # # ]: 0 : matvec * mv = new matvec (ss, rs + 1, cs + 1);
213 [ # # ]: 0 : mv->setName (name);
214 : : // go through vector list again and fill in matrix vectors
215 [ # # ]: 0 : for (v = data; v; v = (qucs::vector *) v->getNext ()) {
216 : 0 : vn = v->getName ();
217 [ # # ]: 0 : if (strstr (vn, name) == vn) {
218 [ # # ]: 0 : if ((n = matvec::isMatrixVector (vn, r, c)) != NULL) {
219 [ # # ][ # # ]: 0 : mv->set (*v, r, c);
[ # # ]
220 : 0 : free (n);
221 : : }
222 : : }
223 : : }
224 : 0 : return mv;
225 : : }
226 : 0 : return NULL;
227 : : }
228 : :
229 : : /* This function saves the given matrix in the matrix vector at the
230 : : specified position. */
231 : 0 : void matvec::set (matrix m, int idx) {
232 [ # # ][ # # ]: 0 : assert (m.getRows () == rows && m.getCols () == cols &&
[ # # ][ # # ]
233 [ # # ]: 0 : idx >= 0 && idx < size);
234 : 0 : data[idx] = m;
235 : 0 : }
236 : :
237 : : /* The function returns the matrix stored within the matrix vector at
238 : : the given position. */
239 : 0 : matrix matvec::get (int idx) {
240 [ # # ][ # # ]: 0 : assert (idx >= 0 && idx < size);
[ # # ]
241 : 0 : matrix res (data[idx]);
242 : 0 : return res;
243 : : }
244 : :
245 : : // Matrix vector addition.
246 : 0 : matvec operator + (matvec a, matvec b) {
247 [ # # ][ # # ]: 0 : assert (a.getRows () == b.getRows () && a.getCols () == b.getCols () &&
[ # # ]
248 [ # # ]: 0 : a.getSize () == b.getSize ());
249 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
250 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) + b.get (i), i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
251 : 0 : return res;
252 : : }
253 : :
254 : : // Matrix vector addition with single matrix.
255 : 0 : matvec operator + (matvec a, matrix b) {
256 [ # # ][ # # ]: 0 : assert (a.getRows () == b.getRows () && a.getCols () == b.getCols ());
[ # # ]
257 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
258 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) + b, i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
259 : 0 : return res;
260 : : }
261 : :
262 : : // Matrix vector addition with vector.
263 : 0 : matvec operator + (matvec a, qucs::vector b) {
264 [ # # ]: 0 : assert (a.getSize () == b.getSize ());
265 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
266 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) + b.get (i), i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
267 : 0 : return res;
268 : : }
269 : :
270 : : // Matrix vector addition with vector in different order.
271 : 0 : matvec operator + (qucs::vector b, matvec a) {
272 [ # # ][ # # ]: 0 : return a + b;
[ # # ]
273 : : }
274 : :
275 : : // Matrix vector addition with single matrix in different order.
276 : 0 : matvec operator + (matrix a, matvec b) {
277 [ # # ][ # # ]: 0 : return b + a;
[ # # ]
278 : : }
279 : :
280 : : // Matrix vector scalar addition.
281 : 0 : matvec operator + (matvec a, nr_complex_t z) {
282 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
283 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) + z, i);
[ # # ][ # # ]
[ # # ][ # # ]
284 : 0 : return res;
285 : : }
286 : :
287 : : // Matrix vector scalar addition in different order.
288 : 0 : matvec operator + (nr_complex_t z, matvec a) {
289 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
290 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (z + a.get (i), i);
[ # # ][ # # ]
[ # # ][ # # ]
291 : 0 : return res;
292 : : }
293 : :
294 : : // Matrix vector scalar addition.
295 : 0 : matvec operator + (matvec a, nr_double_t d) {
296 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
297 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) + d, i);
[ # # ][ # # ]
[ # # ][ # # ]
298 : 0 : return res;
299 : : }
300 : :
301 : : // Matrix vector scalar addition in different order.
302 : 0 : matvec operator + (nr_double_t d, matvec a) {
303 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
304 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (d + a.get (i), i);
[ # # ][ # # ]
[ # # ][ # # ]
305 : 0 : return res;
306 : : }
307 : :
308 : : // Matrix vector scalar subtraction.
309 : 0 : matvec operator - (matvec a, nr_complex_t z) {
310 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
311 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) - z, i);
[ # # ][ # # ]
[ # # ][ # # ]
312 : 0 : return res;
313 : : }
314 : :
315 : : // Matrix vector scalar subtraction in different order.
316 : 0 : matvec operator - (nr_complex_t z, matvec a) {
317 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
318 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (z - a.get (i), i);
[ # # ][ # # ]
[ # # ][ # # ]
319 : 0 : return res;
320 : : }
321 : :
322 : : // Matrix vector scalar subtraction.
323 : 0 : matvec operator - (matvec a, nr_double_t d) {
324 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
325 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) - d, i);
[ # # ][ # # ]
[ # # ][ # # ]
326 : 0 : return res;
327 : : }
328 : :
329 : : // Matrix vector scalar subtraction in different order.
330 : 0 : matvec operator - (nr_double_t d, matvec a) {
331 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
332 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (d - a.get (i), i);
[ # # ][ # # ]
[ # # ][ # # ]
333 : 0 : return res;
334 : : }
335 : :
336 : : // Intrinsic matrix vector addition.
337 : 0 : matvec matvec::operator += (matvec a) {
338 [ # # ][ # # ]: 0 : assert (a.getRows () == rows && a.getCols () == cols &&
[ # # ]
339 [ # # ]: 0 : a.getSize () == size);
340 [ # # ][ # # ]: 0 : for (int i = 0; i < size; i++) data[i] = data[i] + a.get (i);
[ # # ][ # # ]
[ # # ][ # # ]
341 : 0 : return *this;
342 : : }
343 : :
344 : : // Matrix vector subtraction.
345 : 0 : matvec operator - (matvec a, matvec b) {
346 [ # # ][ # # ]: 0 : assert (a.getRows () == b.getRows () && a.getCols () == b.getCols () &&
[ # # ]
347 [ # # ]: 0 : a.getSize () == b.getSize ());
348 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
349 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) - b.get (i), i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
350 : 0 : return res;
351 : : }
352 : :
353 : : // Matrix vector subtraction with single matrix.
354 : 0 : matvec operator - (matvec a, matrix b) {
355 [ # # ][ # # ]: 0 : assert (a.getRows () == b.getRows () && a.getCols () == b.getCols ());
[ # # ]
356 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
357 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) - b, i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
358 : 0 : return res;
359 : : }
360 : :
361 : : // Matrix vector subtraction with single matrix in different order.
362 : 0 : matvec operator - (matrix a, matvec b) {
363 [ # # ][ # # ]: 0 : return -b + a;
[ # # ]
364 : : }
365 : :
366 : : // Matrix vector subtraction with vector.
367 : 0 : matvec operator - (matvec a, qucs::vector b) {
368 [ # # ][ # # ]: 0 : return -b + a;
[ # # ]
369 : : }
370 : :
371 : : // Matrix vector subtraction with vector in different order.
372 : 0 : matvec operator - (qucs::vector b, matvec a) {
373 [ # # ][ # # ]: 0 : return -a + b;
[ # # ]
374 : : }
375 : :
376 : : // Unary minus.
377 : 0 : matvec matvec::operator - () {
378 : 0 : matvec res (getSize (), getRows (), getCols ());
379 [ # # ][ # # ]: 0 : for (int i = 0; i < getSize (); i++) res.set (-data[i], i);
[ # # ][ # # ]
380 : 0 : return res;
381 : : }
382 : :
383 : : // Intrinsic matrix vector subtraction.
384 : 0 : matvec matvec::operator -= (matvec a) {
385 [ # # ][ # # ]: 0 : assert (a.getRows () == rows && a.getCols () == cols &&
[ # # ]
386 [ # # ]: 0 : a.getSize () == size);
387 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) data[i] = data[i] - a.get (i);
[ # # ][ # # ]
[ # # ][ # # ]
388 : 0 : return *this;
389 : : }
390 : :
391 : : // Matrix vector scaling.
392 : 0 : matvec operator * (matvec a, nr_complex_t z) {
393 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
394 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) * z, i);
[ # # ][ # # ]
[ # # ][ # # ]
395 : 0 : return res;
396 : : }
397 : :
398 : : // Matrix vector scaling in different order.
399 : 0 : matvec operator * (nr_complex_t z, matvec a) {
400 [ # # ]: 0 : return a * z;
401 : : }
402 : :
403 : : // Scalar matrix vector scaling.
404 : 0 : matvec operator * (matvec a, nr_double_t d) {
405 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
406 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) * d, i);
[ # # ][ # # ]
[ # # ][ # # ]
407 : 0 : return res;
408 : : }
409 : :
410 : : // Scalar matrix vector scaling in different order.
411 : 0 : matvec operator * (nr_double_t d, matvec a) {
412 [ # # ]: 0 : return a * d;
413 : : }
414 : :
415 : : // Matrix vector scaling by a second vector.
416 : 0 : matvec operator * (matvec a, qucs::vector b) {
417 [ # # ]: 0 : assert (a.getSize () == b.getSize ());
418 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
419 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) * b.get (i), i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
420 : 0 : return res;
421 : : }
422 : :
423 : : // Matrix vector scaling by a second vector in different order.
424 : 0 : matvec operator * (qucs::vector a, matvec b) {
425 [ # # ][ # # ]: 0 : return b * a;
[ # # ]
426 : : }
427 : :
428 : : // Matrix vector scaling.
429 : 0 : matvec operator / (matvec a, nr_complex_t z) {
430 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
431 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) / z, i);
[ # # ][ # # ]
[ # # ][ # # ]
432 : 0 : return res;
433 : : }
434 : :
435 : : // Scalar matrix vector scaling.
436 : 0 : matvec operator / (matvec a, nr_double_t d) {
437 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
438 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) / d, i);
[ # # ][ # # ]
[ # # ][ # # ]
439 : 0 : return res;
440 : : }
441 : :
442 : : // Matrix vector scaling by a second vector.
443 : 0 : matvec operator / (matvec a, qucs::vector b) {
444 [ # # ]: 0 : assert (a.getSize () == b.getSize ());
445 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
446 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) / b.get (i), i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
447 : 0 : return res;
448 : : }
449 : :
450 : : // Matrix vector multiplication.
451 : 0 : matvec operator * (matvec a, matvec b) {
452 [ # # ][ # # ]: 0 : assert (a.getCols () == b.getRows () && a.getSize () == b.getSize ());
[ # # ]
453 : 0 : matvec res (a.getSize (), a.getRows (), b.getCols ());
454 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) * b.get (i), i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
455 : 0 : return res;
456 : : }
457 : :
458 : : // Matrix vector multiplication with a single matrix.
459 : 0 : matvec operator * (matvec a, matrix b) {
460 [ # # ]: 0 : assert (a.getCols () == b.getRows ());
461 : 0 : matvec res (a.getSize (), a.getRows (), b.getCols ());
462 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (a.get (i) * b, i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
463 : 0 : return res;
464 : : }
465 : :
466 : : // Matrix vector multiplication with a single matrix in different order.
467 : 0 : matvec operator * (matrix a, matvec b) {
468 [ # # ][ # # ]: 0 : return b * a;
[ # # ]
469 : : }
470 : :
471 : : // Compute determinants of the given matrix vector.
472 : 0 : qucs::vector det (matvec a) {
473 : 0 : qucs::vector res (a.getSize ());
474 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (det (a.get (i)), i);
[ # # ][ # # ]
[ # # ]
475 : 0 : return res;
476 : : }
477 : :
478 : : // Compute inverse matrices of the given matrix vector.
479 : 0 : matvec inverse (matvec a) {
480 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
481 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (inverse (a.get (i)), i);
[ # # ][ # # ]
[ # # ][ # # ]
482 : 0 : return res;
483 : : }
484 : :
485 : : // Compute inverse matrices of the given matrix vector.
486 : 0 : matvec sqr (matvec a) {
487 [ # # ][ # # ]: 0 : return a * a;
[ # # ]
488 : : }
489 : :
490 : : // Compute n-th power of the given matrix vector.
491 : 0 : matvec pow (matvec a, int n) {
492 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
493 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (pow (a.get (i), n), i);
[ # # ][ # # ]
[ # # ][ # # ]
494 : 0 : return res;
495 : : }
496 : :
497 : : // Compute n-th powers in the vector of the given matrix vector.
498 : 0 : matvec pow (matvec a, qucs::vector v) {
499 [ # # ]: 0 : assert (a.getSize () == v.getSize ());
500 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
501 [ # # ]: 0 : for (int i = 0; i < a.getSize (); i++)
502 [ # # ][ # # ]: 0 : res.set (pow (a.get (i), (int) real (v.get (i))), i);
[ # # ][ # # ]
[ # # ][ # # ]
503 : 0 : return res;
504 : : }
505 : :
506 : : // Conjugate complex matrix vector.
507 : 0 : matvec conj (matvec a) {
508 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
509 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (conj (a.get (i)), i);
[ # # ][ # # ]
[ # # ][ # # ]
510 : 0 : return res;
511 : : }
512 : :
513 : : // Computes magnitude of each matrix vector element.
514 : 0 : matvec abs (matvec a) {
515 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
516 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (abs (a.get (i)), i);
[ # # ][ # # ]
[ # # ][ # # ]
517 : 0 : return res;
518 : : }
519 : :
520 : : // Computes magnitude in dB of each matrix vector element.
521 : 0 : matvec dB (matvec a) {
522 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
523 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (dB (a.get (i)), i);
[ # # ][ # # ]
[ # # ][ # # ]
524 : 0 : return res;
525 : : }
526 : :
527 : : // Computes the argument of each matrix vector element.
528 : 0 : matvec arg (matvec a) {
529 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
530 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (arg (a.get (i)), i);
[ # # ][ # # ]
[ # # ][ # # ]
531 : 0 : return res;
532 : : }
533 : :
534 : : // Real part matrix vector.
535 : 0 : matvec real (matvec a) {
536 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
537 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (real (a.get (i)), i);
[ # # ][ # # ]
[ # # ][ # # ]
538 : 0 : return res;
539 : : }
540 : :
541 : : // Real part matrix vector.
542 : 0 : matvec imag (matvec a) {
543 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
544 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (imag (a.get (i)), i);
[ # # ][ # # ]
[ # # ][ # # ]
545 : 0 : return res;
546 : : }
547 : :
548 : : /* The function returns the adjoint complex matrix vector. This is
549 : : also called the adjugate or transpose conjugate. */
550 : 0 : matvec adjoint (matvec a) {
551 : 0 : matvec res (a.getSize (), a.getRows (), a.getCols ());
552 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (adjoint (a.get (i)), i);
[ # # ][ # # ]
[ # # ][ # # ]
553 : 0 : return res;
554 : : }
555 : :
556 : : // Transpose the matrix vector.
557 : 0 : matvec transpose (matvec a) {
558 : 0 : matvec res (a.getSize (), a.getCols (), a.getRows ());
559 [ # # ][ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) res.set (transpose (a.get (i)), i);
[ # # ][ # # ]
[ # # ][ # # ]
560 : 0 : return res;
561 : : }
562 : :
563 : : /* Convert scattering parameters with the reference impedance 'zref'
564 : : to scattering parameters with the reference impedance 'z0'. */
565 : 0 : matvec stos (matvec s, qucs::vector zref, qucs::vector z0) {
566 [ # # ][ # # ]: 0 : assert (s.getCols () == s.getRows () &&
[ # # ]
567 [ # # ]: 0 : s.getCols () == zref.getSize () && s.getCols () == z0.getSize ());
568 : 0 : matvec res (s.getSize (), s.getCols (), s.getRows ());
569 [ # # ]: 0 : for (int i = 0; i < s.getSize (); i++)
570 [ # # ][ # # ]: 0 : res.set (stos (s.get (i), zref, z0), i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
571 : 0 : return res;
572 : : }
573 : :
574 : 0 : matvec stos (matvec s, nr_complex_t zref, nr_complex_t z0) {
575 : 0 : int d = s.getRows ();
576 [ # # ][ # # ]: 0 : return stos (s, qucs::vector (d, zref), qucs::vector (d, z0));
[ # # ][ # # ]
[ # # ]
577 : : }
578 : :
579 : 0 : matvec stos (matvec s, nr_double_t zref, nr_double_t z0) {
580 [ # # ][ # # ]: 0 : return stos (s, nr_complex_t (zref, 0), nr_complex_t (z0, 0));
[ # # ]
581 : : }
582 : :
583 : 0 : matvec stos (matvec s, qucs::vector zref, nr_complex_t z0) {
584 [ # # ][ # # ]: 0 : return stos (s, zref, qucs::vector (zref.getSize (), z0));
[ # # ][ # # ]
[ # # ]
585 : : }
586 : :
587 : 0 : matvec stos (matvec s, nr_complex_t zref, qucs::vector z0) {
588 [ # # ][ # # ]: 0 : return stos (s, qucs::vector (z0.getSize (), zref), z0);
[ # # ][ # # ]
[ # # ][ # # ]
589 : : }
590 : :
591 : : // Convert scattering parameters to admittance matrix vector.
592 : 0 : matvec stoy (matvec s, qucs::vector z0) {
593 [ # # ][ # # ]: 0 : assert (s.getCols () == s.getRows () && s.getCols () == z0.getSize ());
[ # # ]
594 : 0 : matvec res (s.getSize (), s.getCols (), s.getRows ());
595 [ # # ][ # # ]: 0 : for (int i = 0; i < s.getSize (); i++) res.set (stoy (s.get (i), z0), i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
596 : 0 : return res;
597 : : }
598 : :
599 : 0 : matvec stoy (matvec s, nr_complex_t z0) {
600 [ # # ][ # # ]: 0 : return stoy (s, qucs::vector (s.getCols (), z0));
[ # # ]
601 : : }
602 : :
603 : : // Convert admittance matrix to scattering parameter matrix vector.
604 : 0 : matvec ytos (matvec y, qucs::vector z0) {
605 [ # # ][ # # ]: 0 : assert (y.getCols () == y.getRows () && y.getCols () == z0.getSize ());
[ # # ]
606 : 0 : matvec res (y.getSize (), y.getCols (), y.getRows ());
607 [ # # ][ # # ]: 0 : for (int i = 0; i < y.getSize (); i++) res.set (ytos (y.get (i), z0), i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
608 : 0 : return res;
609 : : }
610 : :
611 : 0 : matvec ytos (matvec y, nr_complex_t z0) {
612 [ # # ][ # # ]: 0 : return ytos (y, qucs::vector (y.getCols (), z0));
[ # # ]
613 : : }
614 : :
615 : : // Convert scattering parameters to impedance matrix vector.
616 : 0 : matvec stoz (matvec s, qucs::vector z0) {
617 [ # # ][ # # ]: 0 : assert (s.getCols () == s.getRows () && s.getCols () == z0.getSize ());
[ # # ]
618 : 0 : matvec res (s.getSize (), s.getCols (), s.getRows ());
619 [ # # ][ # # ]: 0 : for (int i = 0; i < s.getSize (); i++) res.set (stoz (s.get (i), z0), i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
620 : 0 : return res;
621 : : }
622 : :
623 : 0 : matvec stoz (matvec s, nr_complex_t z0) {
624 [ # # ][ # # ]: 0 : return stoz (s, qucs::vector (s.getCols (), z0));
[ # # ]
625 : : }
626 : :
627 : : // Convert impedance matrix vector scattering parameter matrix vector.
628 : 0 : matvec ztos (matvec z, qucs::vector z0) {
629 [ # # ][ # # ]: 0 : assert (z.getCols () == z.getRows () && z.getCols () == z0.getSize ());
[ # # ]
630 : 0 : matvec res (z.getSize (), z.getCols (), z.getRows ());
631 [ # # ][ # # ]: 0 : for (int i = 0; i < z.getSize (); i++) res.set (ztos (z.get (i), z0), i);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
632 : 0 : return res;
633 : : }
634 : :
635 : 0 : matvec ztos (matvec z, nr_complex_t z0) {
636 [ # # ][ # # ]: 0 : return ztos (z, qucs::vector (z.getCols (), z0));
[ # # ]
637 : : }
638 : :
639 : : // Convert impedance matrix vector to admittance matrix vector.
640 : 0 : matvec ztoy (matvec z) {
641 [ # # ]: 0 : assert (z.getCols () == z.getRows ());
642 : 0 : matvec res (z.getSize (), z.getCols (), z.getRows ());
643 [ # # ][ # # ]: 0 : for (int i = 0; i < z.getSize (); i++) res.set (ztoy (z.get (i)), i);
[ # # ][ # # ]
[ # # ][ # # ]
644 : 0 : return res;
645 : : }
646 : :
647 : : // Convert admittance matrix vector to impedance matrix vector.
648 : 0 : matvec ytoz (matvec y) {
649 [ # # ]: 0 : assert (y.getCols () == y.getRows ());
650 : 0 : matvec res (y.getSize (), y.getCols (), y.getRows ());
651 [ # # ][ # # ]: 0 : for (int i = 0; i < y.getSize (); i++) res.set (ytoz (y.get (i)), i);
[ # # ][ # # ]
[ # # ][ # # ]
652 : 0 : return res;
653 : : }
654 : :
655 : : /* This function converts 2x2 matrix vectors from any of the matrix
656 : : forms Y, Z, H, G and A to any other. Also converts S<->(A, T, H, Y
657 : : and Z) matrix vectors. */
658 : 0 : matvec twoport (matvec m, char in, char out) {
659 [ # # ][ # # ]: 0 : assert (m.getCols () >= 2 && m.getRows () >= 2);
[ # # ]
660 : 0 : matvec res (m.getSize (), 2, 2);
661 [ # # ]: 0 : for (int i = 0; i < m.getSize (); i++)
662 [ # # ][ # # ]: 0 : res.set (twoport (m.get (i), in, out), i);
[ # # ][ # # ]
[ # # ]
663 : 0 : return res;
664 : : }
665 : :
666 : : /* The function returns the Rollet stability factor vector of the
667 : : given S-parameter matrix vector. */
668 : 0 : qucs::vector rollet (matvec m) {
669 [ # # ][ # # ]: 0 : assert (m.getCols () >= 2 && m.getRows () >= 2);
[ # # ]
670 : 0 : qucs::vector res (m.getSize ());
671 [ # # ][ # # ]: 0 : for (int i = 0; i < m.getSize (); i++) res.set (rollet (m.get (i)), i);
[ # # ][ # # ]
[ # # ]
672 : 0 : return res;
673 : : }
674 : :
675 : : /* The function returns the stability measure B1 vector of the given
676 : : S-parameter matrix vector. */
677 : 0 : qucs::vector b1 (matvec m) {
678 [ # # ][ # # ]: 0 : assert (m.getCols () >= 2 && m.getRows () >= 2);
[ # # ]
679 : 0 : qucs::vector res (m.getSize ());
680 [ # # ][ # # ]: 0 : for (int i = 0; i < m.getSize (); i++) res.set (b1 (m.get (i)), i);
[ # # ][ # # ]
[ # # ]
681 : 0 : return res;
682 : : }
683 : :
684 : : } // namespace qucs
|