Qucs-core
0.0.19
|
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