/* * tvector.cpp - simple vector template class implementation * * Copyright (C) 2004, 2005, 2006, 2008 Stefan Jahn * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this package; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, * Boston, MA 02110-1301, USA. * * $Id$ * */ #include #include #include #include #include #include #include "compat.h" #include "complex.h" #include "tvector.h" #include "precision.h" namespace qucs { // Returns the tvector element at the given position. template nr_type_t tvector::get (int i) { return data.at(i); } // Sets the tvector element at the given position. template void tvector::set (int i, nr_type_t z) { data.at(i) = z; } // Sets all the tvector elements to the given value. template void tvector::set (nr_type_t z) { for (std::size_t i = 0; i < data.size (); i++) data[i] = z; } // Sets the specified tvector elements to the given value. template void tvector::set (nr_type_t z, int start, int stop) { for (std::size_t i = start; i < stop; i++) data[i] = z; } // Sets size to zero. Does not reduce the capacity. template void tvector::clear (void) { data.clear (); //size = 0; } /* The function returns the number of entries with the given value deviating no more than the given epsilon. */ template int tvector::contains (nr_type_t val, nr_double_t eps) { int count = 0; for (int i = 0; i < (int)data.size (); i++) if (abs ((data)[i] - val) <= eps) count++; return count; } // Copies the specified elements from the given tvector. template void tvector::set (tvector a, int start, int stop) { for (int i = start; i < stop; i++) (*data)[i] = a.get (i); } // The function swaps the given rows with each other. template void tvector::exchangeRows (int r1, int r2) { assert (r1 >= 0 && r2 >= 0 && r1 < (int)data.size () && r2 < (int)data.size ()); nr_type_t s = (data)[r1]; (data)[r1] = (data)[r2]; (data)[r2] = s; } // Addition. template tvector operator + (tvector a, tvector b) { assert (a.size () == b.size ()); int n = a.size (); tvector res (n); for (int i = 0; i < n; i++) res.set (i, a.get (i) + b.get (i)); return res; } // Intrinsic vector addition. template tvector tvector::operator += (tvector a) { assert (a.getSize () == (int)data.size ()); std::vector * src = a.getData (); std::vector * dst = data; for (int i = 0; i < (int)data.size (); i++) (*dst)[i] += (*src)[i]; return *this; } // Subtraction. template tvector operator - (tvector a, tvector b) { assert (a.size () == b.size ()); int n = a.size (); tvector res (n); for (int i = 0; i < n; i++) res.set (i, a.get (i) - b.get (i)); return res; } // Intrinsic vector subtraction. template tvector tvector::operator -= (tvector a) { assert (a.size () == (int)data.size ()); std::vector * src = a.getData (); std::vector * dst = data; for (int i = 0; i < (int)data.size (); i++) (*dst)[i] -= (*src)[i]; return *this; } // Intrinsic scalar multiplication. template tvector tvector::operator *= (nr_double_t s) { std::vector * dst = data; for (int i = 0; i < (int)data.size (); i++) (*dst)[i] *= s; return *this; } // Intrinsic scalar division. template tvector tvector::operator /= (nr_double_t s) { std::vector * dst = data; for (int i = 0; i < (int)data.size (); i++) (*dst)[i] /= s; return *this; } // Scalar multiplication. template tvector operator * (nr_double_t s, tvector a) { int n = a.size (); tvector res (n); for (int i = 0; i < n; i++) res.set (i, s * a.get (i)); return res; } template tvector operator * (tvector a, nr_double_t s) { return s * a; } // Vector multiplication (element by element). template tvector operator * (tvector a, tvector b) { assert (a.size () == b.size ()); int n = a.size (); tvector res (n); for (int i = 0; i < n; i++) res.set (i, a.get (i) * b.get (i)); return res; } // Computes the scalar product of two vectors. template nr_type_t scalar (tvector a, tvector b) { assert (a.size () == b.size ()); nr_type_t n = 0; for (int i = 0; i < a.size (); i++) n += a.get (i) * b.get (i); return n; } // Constant assignment operation. template tvector tvector::operator = (const nr_type_t val) { for (int i = 0; i < (int)data.size (); i++) (*data)[i] = val; return *this; } // Returns the sum of the vector elements. template nr_type_t sum (tvector a) { nr_type_t res = 0; for (int i = 0; i < a.size (); i++) res += a.get (i); return res; } // Vector negation. template tvector operator - (tvector a) { int n = a.size (); tvector res (n); for (int i = 0; i < n; i++) res.set (i, -a.get (i)); return res; } // Vector less comparison. template bool operator < (tvector a, tvector b) { assert (a.size () == b.size ()); int n = a.size (); for (int i = 0; i < n; i++) if (a.get (i) >= b.get (i)) return false; return true; } // Vector greater comparison. template bool operator > (tvector a, tvector b) { assert (a.size () == b.size ()); int n = a.size (); for (int i = 0; i < n; i++) if (a.get (i) <= b.get (i)) return false; return true; } // Scalar addition. template tvector operator + (nr_type_t s, tvector a) { int n = a.size (); tvector res (n); for (int i = 0; i < n; i++) res.set (i, s + a.get (i)); return res; } template tvector operator + (tvector a, nr_type_t s) { return s + a; } // Mean square norm. template nr_double_t norm (tvector a) { #if 0 nr_double_t k = 0; for (int i = 0; i < a.size (); i++) k += norm (a.get (i)); return n; #else nr_double_t scale = 0, n = 1, x, ax; for (int i = 0; i < a.size (); i++) { if ((x = real (a (i))) != 0) { ax = fabs (x); if (scale < ax) { x = scale / ax; n = 1 + n * x * x; scale = ax; } else { x = ax / scale; n += x * x; } } if ((x = imag (a (i))) != 0) { ax = fabs (x); if (scale < ax) { x = scale / ax; n = 1 + n * x * x; scale = ax; } else { x = ax / scale; n += x * x; } } } return scale * scale * n; #endif } // Maximum norm. template nr_double_t maxnorm (tvector a) { nr_double_t nMax = 0, n; for (int i = 0; i < a.size (); i++) { n = norm (a.get (i)); if (n > nMax) nMax = n; } return nMax; } // Conjugate vector. template tvector conj (tvector a) { int n = a.size (); tvector res (n); for (int i = 0; i < n; i++) res.set (i, conj (a.get (i))); return res; } // Checks validity of vector. template int tvector::isFinite (void) { for (int i = 0; i < (int)data.size (); i++) if (!std::isfinite (real ((*data)[i]))) return 0; return 1; } // The functions reorders the vector according to the given index array. template void tvector::reorder (int * idx) { tvector old = *this; for (int i = 0; i < (int)data.size (); i++) (*data)[i] = old.get (idx[i]); } #ifdef DEBUG // Debug function: Prints the vector object. template void tvector::print (void) { for (int r = 0; r < (int)data.size (); r++) { fprintf (stderr, "%+.2e%+.2ei\n", (double) real (get (r)), (double) imag (get (r))); } } #endif /* DEBUG */ } // namespace qucs