LCOV - code coverage report
Current view: top level - src - tvector.cpp (source / functions) Hit Total Coverage
Test: qucs-core-0.0.19 Code Coverage Lines: 115 141 81.6 %
Date: 2015-01-05 16:01:02 Functions: 26 38 68.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 80 188 42.6 %

           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

Generated by: LCOV version 1.11