Qucs-core  0.0.19
tvector.cpp
Go to the documentation of this file.
00001 /*
00002  * tvector.cpp - simple vector template class implementation
00003  *
00004  * Copyright (C) 2004, 2005, 2006, 2008 Stefan Jahn <stefan@lkcc.org>
00005  *
00006  * This is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2, or (at your option)
00009  * any later version.
00010  *
00011  * This software is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this package; see the file COPYING.  If not, write to
00018  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  * $Id$
00022  *
00023  */
00024 
00025 #include <assert.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <cmath>
00030 #include <vector>
00031 
00032 #include "compat.h"
00033 #include "complex.h"
00034 #include "tvector.h"
00035 #include "precision.h"
00036 
00037 namespace qucs {
00038 
00039 
00040 
00041 // Returns the tvector element at the given position.
00042 template <class nr_type_t>
00043 nr_type_t tvector<nr_type_t>::get (int i) {
00044   return data.at(i);
00045 }
00046 
00047 // Sets the tvector element at the given position.
00048 template <class nr_type_t>
00049 void tvector<nr_type_t>::set (int i, nr_type_t z) {
00050   data.at(i) = z;
00051 }
00052 
00053 // Sets all the tvector elements to the given value.
00054 template <class nr_type_t>
00055 void tvector<nr_type_t>::set (nr_type_t z) {
00056   for (std::size_t i = 0; i < data.size (); i++)
00057     data[i] = z;
00058 }
00059 
00060 // Sets the specified tvector elements to the given value.
00061 template <class nr_type_t>
00062 void tvector<nr_type_t>::set (nr_type_t z, int start, int stop) {
00063   for (std::size_t i = start; i < stop; i++)
00064     data[i] = z;
00065 }
00066 
00067 // Sets size to zero.  Does not reduce the capacity.
00068 template <class nr_type_t>
00069 void tvector<nr_type_t>::clear (void) {
00070   data.clear ();
00071   //size = 0;
00072 }
00073 
00074 /* The function returns the number of entries with the given value
00075    deviating no more than the given epsilon. */
00076 template <class nr_type_t>
00077 int tvector<nr_type_t>::contains (nr_type_t val, nr_double_t eps) {
00078   int count = 0;
00079   for (int i = 0; i < (int)data.size (); i++) if (abs ((data)[i] - val) <= eps) count++;
00080   return count;
00081 }
00082 
00083 // Copies the specified elements from the given tvector.
00084 template <class nr_type_t>
00085 void tvector<nr_type_t>::set (tvector<nr_type_t> a, int start, int stop) {
00086   for (int i = start; i < stop; i++) (*data)[i] = a.get (i);
00087 }
00088 
00089 // The function swaps the given rows with each other.
00090 template <class nr_type_t>
00091 void tvector<nr_type_t>::exchangeRows (int r1, int r2) {
00092   assert (r1 >= 0 && r2 >= 0 && r1 < (int)data.size () && r2 < (int)data.size ());
00093   nr_type_t s = (data)[r1];
00094   (data)[r1] = (data)[r2];
00095   (data)[r2] = s;
00096 }
00097 
00098 // Addition.
00099 template <class nr_type_t>
00100 tvector<nr_type_t> operator + (tvector<nr_type_t> a, tvector<nr_type_t> b) {
00101   assert (a.size () == b.size ());
00102   int n = a.size ();
00103   tvector<nr_type_t> res (n);
00104   for (int i = 0; i < n; i++) res.set (i, a.get (i) + b.get (i));
00105   return res;
00106 }
00107 
00108 // Intrinsic vector addition.
00109 template <class nr_type_t>
00110 tvector<nr_type_t> tvector<nr_type_t>::operator += (tvector<nr_type_t> a) {
00111   assert (a.getSize () == (int)data.size ());
00112   std::vector<nr_type_t> * src = a.getData ();
00113   std::vector<nr_type_t> * dst = data;
00114   for (int i = 0; i < (int)data.size (); i++) (*dst)[i] += (*src)[i];
00115   return *this;
00116 }
00117 
00118 // Subtraction.
00119 template <class nr_type_t>
00120 tvector<nr_type_t> operator - (tvector<nr_type_t> a, tvector<nr_type_t> b) {
00121   assert (a.size () == b.size ());
00122   int n = a.size ();
00123   tvector<nr_type_t> res (n);
00124   for (int i = 0; i < n; i++) res.set (i, a.get (i) - b.get (i));
00125   return res;
00126 }
00127 
00128 // Intrinsic vector subtraction.
00129 template <class nr_type_t>
00130 tvector<nr_type_t> tvector<nr_type_t>::operator -= (tvector<nr_type_t> a) {
00131   assert (a.size () == (int)data.size ());
00132   std::vector<nr_type_t> * src = a.getData ();
00133   std::vector<nr_type_t> * dst = data;
00134   for (int i = 0; i < (int)data.size (); i++) (*dst)[i] -= (*src)[i];
00135   return *this;
00136 }
00137 
00138 // Intrinsic scalar multiplication.
00139 template <class nr_type_t>
00140 tvector<nr_type_t> tvector<nr_type_t>::operator *= (nr_double_t s) {
00141   std::vector<nr_type_t> * dst = data;
00142   for (int i = 0; i < (int)data.size (); i++) (*dst)[i] *= s;
00143   return *this;
00144 }
00145 
00146 // Intrinsic scalar division.
00147 template <class nr_type_t>
00148 tvector<nr_type_t> tvector<nr_type_t>::operator /= (nr_double_t s) {
00149   std::vector<nr_type_t> * dst = data;
00150   for (int i = 0; i < (int)data.size (); i++) (*dst)[i] /= s;
00151   return *this;
00152 }
00153 
00154 // Scalar multiplication.
00155 template <class nr_type_t>
00156 tvector<nr_type_t> operator * (nr_double_t s, tvector<nr_type_t> a) {
00157   int n = a.size ();
00158   tvector<nr_type_t> res (n);
00159   for (int i = 0; i < n; i++) res.set (i, s * a.get (i));
00160   return res;
00161 }
00162 
00163 template <class nr_type_t>
00164 tvector<nr_type_t> operator * (tvector<nr_type_t> a, nr_double_t s) {
00165   return s * a;
00166 }
00167 
00168 // Vector multiplication (element by element).
00169 template <class nr_type_t>
00170 tvector<nr_type_t> operator * (tvector<nr_type_t> a, tvector<nr_type_t> b) {
00171   assert (a.size () == b.size ());
00172   int n = a.size ();
00173   tvector<nr_type_t> res (n);
00174   for (int i = 0; i < n; i++) res.set (i, a.get (i) * b.get (i));
00175   return res;
00176 }
00177 
00178 // Computes the scalar product of two vectors.
00179 template <class nr_type_t>
00180 nr_type_t scalar (tvector<nr_type_t> a, tvector<nr_type_t> b) {
00181   assert (a.size () == b.size ());
00182   nr_type_t n = 0;
00183   for (int i = 0; i < a.size (); i++) n += a.get (i) * b.get (i);
00184   return n;
00185 }
00186 
00187 // Constant assignment operation.
00188 template <class nr_type_t>
00189 tvector<nr_type_t> tvector<nr_type_t>::operator = (const nr_type_t val) {
00190   for (int i = 0; i < (int)data.size (); i++) (*data)[i] = val;
00191   return *this;
00192 }
00193 
00194 // Returns the sum of the vector elements.
00195 template <class nr_type_t>
00196 nr_type_t sum (tvector<nr_type_t> a) {
00197   nr_type_t res = 0;
00198   for (int i = 0; i < a.size (); i++) res += a.get (i);
00199   return res;
00200 }
00201 
00202 // Vector negation.
00203 template <class nr_type_t>
00204 tvector<nr_type_t> operator - (tvector<nr_type_t> a) {
00205   int n = a.size ();
00206   tvector<nr_type_t> res (n);
00207   for (int i = 0; i < n; i++) res.set (i, -a.get (i));
00208   return res;
00209 }
00210 
00211 // Vector less comparison.
00212 template <class nr_type_t>
00213 bool operator < (tvector<nr_type_t> a, tvector<nr_type_t> b) {
00214   assert (a.size () == b.size ());
00215   int n = a.size ();
00216   for (int i = 0; i < n; i++) if (a.get (i) >= b.get (i)) return false;
00217   return true;
00218 }
00219 
00220 // Vector greater comparison.
00221 template <class nr_type_t>
00222 bool operator > (tvector<nr_type_t> a, tvector<nr_type_t> b) {
00223   assert (a.size () == b.size ());
00224   int n = a.size ();
00225   for (int i = 0; i < n; i++) if (a.get (i) <= b.get (i)) return false;
00226   return true;
00227 }
00228 
00229 // Scalar addition.
00230 template <class nr_type_t>
00231 tvector<nr_type_t> operator + (nr_type_t s, tvector<nr_type_t> a) {
00232   int n = a.size ();
00233   tvector<nr_type_t> res (n);
00234   for (int i = 0; i < n; i++) res.set (i, s + a.get (i));
00235   return res;
00236 }
00237 
00238 template <class nr_type_t>
00239 tvector<nr_type_t> operator + (tvector<nr_type_t> a, nr_type_t s) {
00240   return s + a;
00241 }
00242 
00243 // Mean square norm.
00244 template <class nr_type_t>
00245 nr_double_t norm (tvector<nr_type_t> a) {
00246 #if 0
00247   nr_double_t k = 0;
00248   for (int i = 0; i < a.size (); i++) k += norm (a.get (i));
00249   return n;
00250 #else
00251   nr_double_t scale = 0, n = 1, x, ax;
00252   for (int i = 0; i < a.size (); i++) {
00253     if ((x = real (a (i))) != 0) {
00254       ax = fabs (x);
00255       if (scale < ax) {
00256         x = scale / ax;
00257         n = 1 + n * x * x;
00258         scale = ax;
00259       }
00260       else {
00261         x = ax / scale;
00262         n += x * x;
00263       }
00264     }
00265     if ((x = imag (a (i))) != 0) {
00266       ax = fabs (x);
00267       if (scale < ax) {
00268         x = scale / ax;
00269         n = 1 + n * x * x;
00270         scale = ax;
00271       }
00272       else {
00273         x = ax / scale;
00274         n += x * x;
00275       }
00276     }
00277   }
00278   return scale * scale * n;
00279 #endif
00280 }
00281 
00282 // Maximum norm.
00283 template <class nr_type_t>
00284 nr_double_t maxnorm (tvector<nr_type_t> a) {
00285   nr_double_t nMax = 0, n;
00286   for (int i = 0; i < a.size (); i++) {
00287     n = norm (a.get (i));
00288     if (n > nMax) nMax = n;
00289   }
00290   return nMax;
00291 }
00292 
00293 // Conjugate vector.
00294 template <class nr_type_t>
00295 tvector<nr_type_t> conj (tvector<nr_type_t> a) {
00296   int n = a.size ();
00297   tvector<nr_type_t> res (n);
00298   for (int i = 0; i < n; i++) res.set (i, conj (a.get (i)));
00299   return res;
00300 }
00301 
00302 // Checks validity of vector.
00303 template <class nr_type_t>
00304 int tvector<nr_type_t>::isFinite (void) {
00305   for (int i = 0; i < (int)data.size (); i++)
00306     if (!std::isfinite (real ((*data)[i]))) return 0;
00307   return 1;
00308 }
00309 
00310 // The functions reorders the vector according to the given index array.
00311 template <class nr_type_t>
00312 void tvector<nr_type_t>::reorder (int * idx) {
00313   tvector<nr_type_t> old = *this;
00314   for (int i = 0; i < (int)data.size (); i++) (*data)[i] = old.get (idx[i]);
00315 }
00316 
00317 #ifdef DEBUG
00318 // Debug function: Prints the vector object.
00319 template <class nr_type_t>
00320 void tvector<nr_type_t>::print (void) {
00321   for (int r = 0; r < (int)data.size (); r++) {
00322     fprintf (stderr, "%+.2e%+.2ei\n", (double) real (get (r)),
00323              (double) imag (get (r)));
00324   }
00325 }
00326 #endif /* DEBUG */
00327 
00328 } // namespace qucs