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