Branch data Line data Source code
1 : : /*
2 : : * tvector.cpp - simple vector template class implementation
3 : : *
4 : : * Copyright (C) 2004, 2005, 2006, 2008 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 : : #include <assert.h>
26 : : #include <stdio.h>
27 : : #include <stdlib.h>
28 : : #include <string.h>
29 : : #include <cmath>
30 : :
31 : : #include "compat.h"
32 : : #include "complex.h"
33 : : #include "tvector.h"
34 : : #include "precision.h"
35 : :
36 : : namespace qucs {
37 : :
38 : : // Constructor creates an unnamed instance of the tvector class.
39 : : template <class nr_type_t>
40 : 524 : tvector<nr_type_t>::tvector () {
41 : 524 : external = 0;
42 : 524 : capacity = size = 0;
43 : 524 : data = NULL;
44 : 524 : }
45 : :
46 : : /* Constructor creates an unnamed instance of the tvector class with a
47 : : certain length. */
48 : : template <class nr_type_t>
49 : 1006765 : tvector<nr_type_t>::tvector (int s) {
50 : 1006765 : external = 0;
51 : 1006765 : capacity = size = s;
52 [ + - ][ # # ]: 1006765 : if (s > 0) {
53 [ + + ][ # # ]: 1486681 : data = new nr_type_t[s];
54 : 1006765 : memset (data, 0, sizeof (nr_type_t) * s);
55 : : }
56 : 0 : else data = NULL;
57 : 1006765 : }
58 : :
59 : : /* The copy constructor creates a new instance based on the given
60 : : tvector object. */
61 : : template <class nr_type_t>
62 : 1027046 : tvector<nr_type_t>::tvector (const tvector & v) {
63 : 1027046 : external = 0;
64 : 1027046 : size = v.size;
65 : 1027046 : capacity = v.capacity;
66 : 1027046 : data = NULL;
67 : :
68 : : // copy tvector elements
69 [ + + ][ # # ]: 1027046 : if (size > 0) {
70 [ + + ]: 1818506 : data = new nr_type_t[size];
71 : 1027044 : memcpy (data, v.data, sizeof (nr_type_t) * size);
72 : : }
73 : 1027046 : }
74 : :
75 : : /* The assignment copy constructor creates a new instance based on the
76 : : given tvector object. */
77 : : template <class nr_type_t>
78 : : const tvector<nr_type_t>&
79 : 1776387 : tvector<nr_type_t>::operator=(const tvector<nr_type_t> & v) {
80 [ + - ][ # # ]: 1776387 : if (&v != this) {
81 : 1776387 : size = v.size;
82 : 1776387 : capacity = v.capacity;
83 [ + + ][ + - ]: 1776387 : if (data && !external) { delete[] data; data = NULL; }
[ + - ][ # # ]
[ # # ][ # # ]
84 : 1776387 : external = 0;
85 [ + - ][ # # ]: 1776387 : if (size > 0) {
86 [ + + ]: 2027883 : data = new nr_type_t[size];
87 : 1776387 : memcpy (data, v.data, sizeof (nr_type_t) * size);
88 : : }
89 : : }
90 : 1776387 : return *this;
91 : : }
92 : :
93 : : // Destructor deletes a tvector object.
94 : : template <class nr_type_t>
95 : 2034333 : tvector<nr_type_t>::~tvector () {
96 [ + + ][ + - ]: 2034333 : if (data && !external) delete[] data;
[ + - ][ # # ]
[ # # ][ # # ]
97 : 2034333 : }
98 : :
99 : : // Returns the tvector element at the given position.
100 : : template <class nr_type_t>
101 : 49794213 : nr_type_t tvector<nr_type_t>::get (int i) {
102 [ + - ][ - + ]: 49794213 : assert (i >= 0 && i < size);
[ - + ][ # # ]
[ # # ][ # # ]
103 : 49794213 : return data[i];
104 : : }
105 : :
106 : : // Sets the tvector element at the given position.
107 : : template <class nr_type_t>
108 : 9200508 : void tvector<nr_type_t>::set (int i, nr_type_t z) {
109 [ + - ][ - + ]: 9200508 : assert (i >= 0 && i < size);
[ - + ][ + - ]
[ - + ][ - + ]
110 : 9200508 : data[i] = z;
111 : 9200508 : }
112 : :
113 : : // Sets all the tvector elements to the given value.
114 : : template <class nr_type_t>
115 : 25742 : void tvector<nr_type_t>::set (nr_type_t z) {
116 [ + + ]: 253078 : for (int i = 0; i < size; i++) data[i] = z;
117 : 25742 : }
118 : :
119 : : // Sets the specified tvector elements to the given value.
120 : : template <class nr_type_t>
121 : : void tvector<nr_type_t>::set (nr_type_t z, int start, int stop) {
122 : : for (int i = start; i < stop; i++) data[i] = z;
123 : : }
124 : :
125 : : // Appends the given value to the tvector.
126 : : template <class nr_type_t>
127 : 42 : void tvector<nr_type_t>::add (nr_type_t z) {
128 [ + + ]: 42 : if (size >= capacity) {
129 [ + + ]: 10 : if (data) {
130 : : // double the vectors capacity
131 : 6 : capacity *= 2;
132 : 6 : data = (nr_type_t *) realloc (data, capacity * sizeof (nr_type_t));
133 : : }
134 : : else {
135 : : // initial capacity
136 : 4 : capacity = 4;
137 : 4 : data = (nr_type_t *) malloc (capacity * sizeof (nr_type_t));
138 : : }
139 : : }
140 : 42 : data[size++] = z;
141 : 42 : }
142 : :
143 : : // Rejects the given number of values from the start of the tvector.
144 : : template <class nr_type_t>
145 : : void tvector<nr_type_t>::drop (int n) {
146 : : if (n < size) {
147 : : for (int i = 0; i < size - n; i++) data[i] = data[i + n];
148 : : size -= n;
149 : : }
150 : : else size = 0;
151 : : }
152 : :
153 : : // Rejects the given number of values from the end of the tvector.
154 : : template <class nr_type_t>
155 : : void tvector<nr_type_t>::truncate (int n) {
156 : : if (n < size) {
157 : : size -= n;
158 : : }
159 : : else size = 0;
160 : : }
161 : :
162 : : // Sets size to zero. Does not reduce the capacity.
163 : : template <class nr_type_t>
164 : 6 : void tvector<nr_type_t>::clear (void) {
165 : 6 : size = 0;
166 : 6 : }
167 : :
168 : : /* The function returns the number of entries with the given value
169 : : deviating no more than the given epsilon. */
170 : : template <class nr_type_t>
171 : 1 : int tvector<nr_type_t>::contains (nr_type_t val, nr_double_t eps) {
172 : 1 : int count = 0;
173 [ # # ][ - + ]: 1 : for (int i = 0; i < size; i++) if (abs (data[i] - val) <= eps) count++;
174 : 1 : return count;
175 : : }
176 : :
177 : : // Copies the specified elements from the given tvector.
178 : : template <class nr_type_t>
179 : : void tvector<nr_type_t>::set (tvector<nr_type_t> a, int start, int stop) {
180 : : for (int i = start; i < stop; i++) data[i] = a.get (i);
181 : : }
182 : :
183 : : // Applies external data vector to the vector.
184 : : template <class nr_type_t>
185 : 0 : void tvector<nr_type_t>::setData (nr_type_t * d, int len) {
186 [ # # ][ # # ]: 0 : if (data && !external) delete[] data;
[ # # ]
187 : 0 : external = 1;
188 : 0 : data = d;
189 : 0 : capacity = size = len;
190 : 0 : }
191 : :
192 : : // The function swaps the given rows with each other.
193 : : template <class nr_type_t>
194 : 0 : void tvector<nr_type_t>::exchangeRows (int r1, int r2) {
195 [ # # ][ # # ]: 0 : assert (r1 >= 0 && r2 >= 0 && r1 < size && r2 < size);
[ # # ][ # # ]
[ # # ]
196 : 0 : nr_type_t s = data[r1];
197 : 0 : data[r1] = data[r2];
198 : 0 : data[r2] = s;
199 : 0 : }
200 : :
201 : : // Addition.
202 : : template <class nr_type_t>
203 : 9903 : tvector<nr_type_t> operator + (tvector<nr_type_t> a, tvector<nr_type_t> b) {
204 [ - + ]: 9903 : assert (a.getSize () == b.getSize ());
205 : 9903 : int n = a.getSize ();
206 : 9903 : tvector<nr_type_t> res (n);
207 [ + - ][ + - ]: 146033 : for (int i = 0; i < n; i++) res.set (i, a.get (i) + b.get (i));
[ - # ][ + # ]
[ + ][ + ]
208 : 9903 : return res;
209 : : }
210 : :
211 : : // Intrinsic vector addition.
212 : : template <class nr_type_t>
213 : : tvector<nr_type_t> tvector<nr_type_t>::operator += (tvector<nr_type_t> a) {
214 : : assert (a.getSize () == size);
215 : : nr_type_t * src = a.getData ();
216 : : nr_type_t * dst = data;
217 : : for (int i = 0; i < size; i++) *dst++ += *src++;
218 : : return *this;
219 : : }
220 : :
221 : : // Subtraction.
222 : : template <class nr_type_t>
223 : 10557 : tvector<nr_type_t> operator - (tvector<nr_type_t> a, tvector<nr_type_t> b) {
224 [ - + ]: 10557 : assert (a.getSize () == b.getSize ());
225 : 10557 : int n = a.getSize ();
226 : 10557 : tvector<nr_type_t> res (n);
227 [ + - ][ + - ]: 155197 : for (int i = 0; i < n; i++) res.set (i, a.get (i) - b.get (i));
[ - # ][ + # ]
[ + ][ + ]
228 : 10557 : return res;
229 : : }
230 : :
231 : : // Intrinsic vector substration.
232 : : template <class nr_type_t>
233 : : tvector<nr_type_t> tvector<nr_type_t>::operator -= (tvector<nr_type_t> a) {
234 : : assert (a.getSize () == size);
235 : : nr_type_t * src = a.getData ();
236 : : nr_type_t * dst = data;
237 : : for (int i = 0; i < size; i++) *dst++ -= *src++;
238 : : return *this;
239 : : }
240 : :
241 : : // Intrinsic scalar multiplication.
242 : : template <class nr_type_t>
243 : : tvector<nr_type_t> tvector<nr_type_t>::operator *= (nr_double_t s) {
244 : : nr_type_t * dst = data;
245 : : for (int i = 0; i < size; i++) *dst++ *= s;
246 : : return *this;
247 : : }
248 : :
249 : : // Intrinsic scalar division.
250 : : template <class nr_type_t>
251 : : tvector<nr_type_t> tvector<nr_type_t>::operator /= (nr_double_t s) {
252 : : nr_type_t * dst = data;
253 : : for (int i = 0; i < size; i++) *dst++ /= s;
254 : : return *this;
255 : : }
256 : :
257 : : // Scalar multiplication.
258 : : template <class nr_type_t>
259 : 9903 : tvector<nr_type_t> operator * (nr_double_t s, tvector<nr_type_t> a) {
260 : 9903 : int n = a.getSize ();
261 : 9903 : tvector<nr_type_t> res (n);
262 [ + - ][ - # ]: 146033 : for (int i = 0; i < n; i++) res.set (i, s * a.get (i));
[ + # ][ + ]
[ + ]
263 : 9903 : return res;
264 : : }
265 : :
266 : : template <class nr_type_t>
267 : : tvector<nr_type_t> operator * (tvector<nr_type_t> a, nr_double_t s) {
268 : : return s * a;
269 : : }
270 : :
271 : : // Vector multiplication (element by element).
272 : : template <class nr_type_t>
273 : 9249 : tvector<nr_type_t> operator * (tvector<nr_type_t> a, tvector<nr_type_t> b) {
274 [ - + ]: 9249 : assert (a.getSize () == b.getSize ());
275 : 9249 : int n = a.getSize ();
276 : 9249 : tvector<nr_type_t> res (n);
277 [ + - ][ + - ]: 136869 : for (int i = 0; i < n; i++) res.set (i, a.get (i) * b.get (i));
[ + - ][ # # ]
[ # # ][ + + ]
278 : 9249 : return res;
279 : : }
280 : :
281 : : // Computes the scalar product of two vectors.
282 : : template <class nr_type_t>
283 : 25662 : nr_type_t scalar (tvector<nr_type_t> a, tvector<nr_type_t> b) {
284 [ - + ]: 25662 : assert (a.getSize () == b.getSize ());
285 : 25662 : nr_type_t n = 0;
286 [ + - ][ + - ]: 251160 : for (int i = 0; i < a.getSize (); i++) n += a.get (i) * b.get (i);
[ + - ][ + + ]
287 : 25662 : return n;
288 : : }
289 : :
290 : : // Constant assignment operation.
291 : : template <class nr_type_t>
292 : : tvector<nr_type_t> tvector<nr_type_t>::operator = (const nr_type_t val) {
293 : : for (int i = 0; i < size; i++) data[i] = val;
294 : : return *this;
295 : : }
296 : :
297 : : // Returns the sum of the vector elements.
298 : : template <class nr_type_t>
299 : 9249 : nr_type_t sum (tvector<nr_type_t> a) {
300 : 9249 : nr_type_t res = 0;
301 [ # # ]: 136869 : for (int i = 0; i < a.getSize (); i++) res += a.get (i);
[ # # + + ]
302 : 9249 : return res;
303 : : }
304 : :
305 : : // Vector negation.
306 : : template <class nr_type_t>
307 : 9249 : tvector<nr_type_t> operator - (tvector<nr_type_t> a) {
308 : 9249 : int n = a.getSize ();
309 : 9249 : tvector<nr_type_t> res (n);
310 [ + - ][ - # ]: 136869 : for (int i = 0; i < n; i++) res.set (i, -a.get (i));
[ + # ][ + ]
[ + ]
311 : 9249 : return res;
312 : : }
313 : :
314 : : // Vector less comparison.
315 : : template <class nr_type_t>
316 : : bool operator < (tvector<nr_type_t> a, tvector<nr_type_t> b) {
317 : : assert (a.getSize () == b.getSize ());
318 : : int n = a.getSize ();
319 : : for (int i = 0; i < n; i++) if (a.get (i) >= b.get (i)) return false;
320 : : return true;
321 : : }
322 : :
323 : : // Vector greater comparison.
324 : : template <class nr_type_t>
325 : : bool operator > (tvector<nr_type_t> a, tvector<nr_type_t> b) {
326 : : assert (a.getSize () == b.getSize ());
327 : : int n = a.getSize ();
328 : : for (int i = 0; i < n; i++) if (a.get (i) <= b.get (i)) return false;
329 : : return true;
330 : : }
331 : :
332 : : // Scalar addition.
333 : : template <class nr_type_t>
334 : : tvector<nr_type_t> operator + (nr_type_t s, tvector<nr_type_t> a) {
335 : : int n = a.getSize ();
336 : : tvector<nr_type_t> res (n);
337 : : for (int i = 0; i < n; i++) res.set (i, s + a.get (i));
338 : : return res;
339 : : }
340 : :
341 : : template <class nr_type_t>
342 : : tvector<nr_type_t> operator + (tvector<nr_type_t> a, nr_type_t s) {
343 : : return s + a;
344 : : }
345 : :
346 : : // Mean square norm.
347 : : template <class nr_type_t>
348 : 9903 : nr_double_t norm (tvector<nr_type_t> a) {
349 : : #if 0
350 : : nr_double_t k = 0;
351 : : for (int i = 0; i < a.getSize (); i++) k += norm (a.get (i));
352 : : return n;
353 : : #else
354 : 9903 : nr_double_t scale = 0, n = 1, x, ax;
355 [ + + ]: 146033 : for (int i = 0; i < a.getSize (); i++) {
356 [ + + ]: 136130 : if ((x = real (a (i))) != 0) {
357 : 69201 : ax = fabs (x);
358 [ + + ]: 69201 : if (scale < ax) {
359 : 22917 : x = scale / ax;
360 : 22917 : n = 1 + n * x * x;
361 : 22917 : scale = ax;
362 : : }
363 : : else {
364 : 46284 : x = ax / scale;
365 : 46284 : n += x * x;
366 : : }
367 : : }
368 [ - + ]: 136130 : if ((x = imag (a (i))) != 0) {
369 : 0 : ax = fabs (x);
370 [ # # ]: 0 : if (scale < ax) {
371 : 0 : x = scale / ax;
372 : 0 : n = 1 + n * x * x;
373 : 0 : scale = ax;
374 : : }
375 : : else {
376 : 0 : x = ax / scale;
377 : 0 : n += x * x;
378 : : }
379 : : }
380 : : }
381 : 9903 : return scale * scale * n;
382 : : #endif
383 : : }
384 : :
385 : : // Maximum norm.
386 : : template <class nr_type_t>
387 : 0 : nr_double_t maxnorm (tvector<nr_type_t> a) {
388 : 0 : nr_double_t nMax = 0, n;
389 [ # # ]: 0 : for (int i = 0; i < a.getSize (); i++) {
390 : 0 : n = norm (a.get (i));
391 [ # # ]: 0 : if (n > nMax) nMax = n;
392 : : }
393 : 0 : return nMax;
394 : : }
395 : :
396 : : // Conjugate vector.
397 : : template <class nr_type_t>
398 : 25662 : tvector<nr_type_t> conj (tvector<nr_type_t> a) {
399 : 25662 : int n = a.getSize ();
400 : 25662 : tvector<nr_type_t> res (n);
401 [ + - ][ + - ]: 251160 : for (int i = 0; i < n; i++) res.set (i, conj (a.get (i)));
[ + + ]
402 : 25662 : return res;
403 : : }
404 : :
405 : : // Checks validity of vector.
406 : : template <class nr_type_t>
407 : : int tvector<nr_type_t>::isFinite (void) {
408 : : for (int i = 0; i < size; i++)
409 : : if (!std::isfinite (real (data[i]))) return 0;
410 : : return 1;
411 : : }
412 : :
413 : : // The functions reorders the vector according to the given index array.
414 : : template <class nr_type_t>
415 : : void tvector<nr_type_t>::reorder (int * idx) {
416 : : tvector<nr_type_t> old = *this;
417 : : for (int i = 0; i < size; i++) data[i] = old.get (idx[i]);
418 : : }
419 : :
420 : : #ifdef DEBUG
421 : : // Debug function: Prints the vector object.
422 : : template <class nr_type_t>
423 : : void tvector<nr_type_t>::print (void) {
424 : : for (int r = 0; r < size; r++) {
425 : : fprintf (stderr, "%+.2e%+.2ei\n", (double) real (get (r)),
426 : : (double) imag (get (r)));
427 : : }
428 : : }
429 : : #endif /* DEBUG */
430 : :
431 : : } // namespace qucs
|