* vector.cpp - vector class implementation
*
* Copyright (C) 2003, 2004, 2005, 2006, 2007 Stefan Jahn <stefan@lkcc.org>
* Copyright (C) 2006, 2007 Gunther Kraut <gn.kraut@t-online.de>
*
* 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$
*
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <limits>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cmath>
#include <float.h>
#include <assert.h>
#include "real.h"
#include "complex.h"
#include "object.h"
#include "logging.h"
#include "strlist.h"
#include "vector.h"
#include "consts.h"
namespace qucs {
vector::vector () : object () {
capacity = size = 0;
data = NULL;
dependencies = NULL;
origin = NULL;
requested = 0;
next = prev = nullptr;
}
given initial size. */
vector::vector (int s) : object () {
assert (s >= 0);
capacity = size = s;
data = s > 0 ? (nr_complex_t *)
calloc (capacity, sizeof (nr_complex_t)) : NULL;
dependencies = NULL;
origin = NULL;
requested = 0;
next = prev = nullptr;
}
given initial size and content. */
vector::vector (int s, nr_complex_t val) : object () {
assert (s >= 0);
capacity = size = s;
data = s > 0 ? (nr_complex_t *)
calloc (capacity, sizeof (nr_complex_t)) : NULL;
for (int i = 0; i < s; i++) data[i] = val;
dependencies = NULL;
origin = NULL;
requested = 0;
next = prev = nullptr;
}
vector::vector (const std::string &n) : object (n) {
capacity = size = 0;
data = NULL;
dependencies = NULL;
origin = NULL;
requested = 0;
next = prev = nullptr;
}
a given initial size. */
vector::vector (const std::string &n, int s) : object (n) {
assert (s >= 0);
capacity = size = s;
data = s > 0 ? (nr_complex_t *)
calloc (capacity, sizeof (nr_complex_t)) : NULL;
dependencies = NULL;
origin = NULL;
requested = 0;
next = prev = nullptr;
}
vector object. */
vector::vector (const vector & v) : object (v) {
size = v.size;
capacity = v.capacity;
data = (nr_complex_t *) malloc (sizeof (nr_complex_t) * capacity);
memcpy (data, v.data, sizeof (nr_complex_t) * size);
dependencies = v.dependencies ? new strlist (*v.dependencies) : NULL;
origin = v.origin ? strdup (v.origin) : NULL;
requested = v.requested;
next = v.next;
prev = v.prev;
}
given vector object. It copies the data only and leaves any other
properties untouched. */
const vector& vector::operator=(const vector & v) {
if (&v != this) {
size = v.size;
capacity = v.capacity;
if (data) { free (data); data = NULL; }
if (capacity > 0) {
data = (nr_complex_t *) malloc (sizeof (nr_complex_t) * capacity);
if (size > 0) memcpy (data, v.data, sizeof (nr_complex_t) * size);
}
}
return *this;
}
vector::~vector () {
free (data);
delete dependencies;
free (origin);
}
strlist * vector::getDependencies (void) {
return dependencies;
}
void vector::setDependencies (strlist * s) {
delete dependencies;
dependencies = s;
}
vector and ensures that the vector can hold the increasing number
of data items. */
void vector::add (nr_complex_t c) {
if (data == NULL) {
size = 0; capacity = 64;
data = (nr_complex_t *) malloc (sizeof (nr_complex_t) * capacity);
}
else if (size >= capacity) {
capacity *= 2;
data = (nr_complex_t *) realloc (data, sizeof (nr_complex_t) * capacity);
}
data[size++] = c;
}
void vector::add (vector * v) {
if (v != NULL) {
if (data == NULL) {
size = 0; capacity = v->getSize ();
data = (nr_complex_t *) malloc (sizeof (nr_complex_t) * capacity);
}
else if (size + v->getSize () > capacity) {
capacity += v->getSize ();
data = (nr_complex_t *) realloc (data, sizeof (nr_complex_t) * capacity);
}
for (int i = 0; i < v->getSize (); i++) data[size++] = v->get (i);
}
}
nr_complex_t vector::get (int i) {
return data[i];
}
void vector::set (nr_double_t d, int i) {
data[i] = nr_complex_t (d);
}
void vector::set (const nr_complex_t z, int i) {
data[i] = nr_complex_t (z);
}
int vector::getSize (void) const {
return size;
}
int vector::checkSizes (vector v1, vector v2) {
if (v1.getSize () != v2.getSize ()) {
logprint (LOG_ERROR, "vector '%s' and '%s' have different sizes\n",
v1.getName (), v2.getName ());
return 0;
}
return 1;
}
nr_double_t vector::maximum (void) {
nr_complex_t c;
nr_double_t d, max_D = -std::numeric_limits<nr_double_t>::max();
for (int i = 0; i < getSize (); i++) {
c = data[i];
d = fabs (arg (c)) < pi_over_2 ? abs (c) : -abs (c);
if (d > max_D) max_D = d;
}
return max_D;
}
nr_double_t vector::minimum (void) {
nr_complex_t c;
nr_double_t d, min_D = +std::numeric_limits<nr_double_t>::max();
for (int i = 0; i < getSize (); i++) {
c = data[i];
d = fabs (arg (c)) < pi_over_2 ? abs (c) : -abs (c);
if (d < min_D) min_D = d;
}
return min_D;
}
values jump about |Pi|. */
vector unwrap (vector v, nr_double_t tol, nr_double_t step) {
vector result (v.getSize ());
nr_double_t add = 0;
result (0) = v (0);
for (int i = 1; i < v.getSize (); i++) {
nr_double_t diff = real (v (i) - v (i-1));
if (diff > +tol) {
add -= step;
} else if (diff < -tol) {
add += step;
}
result (i) = v (i) + add;
}
return result;
}
nr_complex_t sum (vector v) {
nr_complex_t result (0.0);
for (int i = 0; i < v.getSize (); i++) result += v.get (i);
return result;
}
nr_complex_t prod (vector v) {
nr_complex_t result (1.0);
for (int i = 0; i < v.getSize (); i++) result *= v.get (i);
return result;
}
nr_complex_t avg (vector v) {
nr_complex_t result (0.0);
for (int i = 0; i < v.getSize (); i++) result += v.get (i);
return result / (nr_double_t) v.getSize ();
}
vector signum (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (signum (v.get (i)), i);
return result;
}
vector sign (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (sign (v.get (i)), i);
return result;
}
vector xhypot (vector v, const nr_complex_t z) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (xhypot (v.get(i), z), i);
return result;
}
vector xhypot (vector v, const nr_double_t d) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (xhypot (v.get(i), d), i);
return result;
}
vector xhypot (const nr_complex_t z, vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (xhypot (z, v.get (i)), i);
return result;
}
vector xhypot (const nr_double_t d, vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (xhypot (d, v.get (i)), i);
return result;
}
vector xhypot (vector v1, vector v2) {
int j, i, n, len, len1 = v1.getSize (), len2 = v2.getSize ();
if (len1 >= len2) {
assert (len1 % len2 == 0);
len = len1;
} else {
assert (len2 % len1 == 0);
len = len2;
}
vector res (len);
for (j = i = n = 0; n < len; n++) {
res (n) = xhypot (v1 (i), v2 (j));
if (++i >= len1) i = 0; if (++j >= len2) j = 0;
}
return res;
}
vector sinc (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (sinc (v.get (i)), i);
return result;
}
vector abs (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (abs (v.get (i)), i);
return result;
}
vector norm (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (norm (v.get (i)), i);
return result;
}
vector arg (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (arg (v.get (i)), i);
return result;
}
vector real (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (real (v.get (i)), i);
return result;
}
vector imag (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (imag (v.get (i)), i);
return result;
}
vector conj (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (conj (v.get (i)), i);
return result;
}
vector dB (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++)
result.set (10.0 * std::log10 (norm (v.get (i))), i);
return result;
}
vector sqrt (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (sqrt (v.get (i)), i);
return result;
}
vector exp (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (exp (v.get (i)), i);
return result;
}
vector limexp (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (limexp (v.get (i)), i);
return result;
}
vector log (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (log (v.get (i)), i);
return result;
}
vector log10 (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (log10 (v.get (i)), i);
return result;
}
vector log2 (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (log2 (v.get (i)), i);
return result;
}
vector pow (vector v, const nr_complex_t z) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (pow (v.get(i), z), i);
return result;
}
vector pow (vector v, const nr_double_t d) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (pow (v.get(i), d), i);
return result;
}
vector pow (const nr_complex_t z, vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (pow (z, v.get (i)), i);
return result;
}
vector pow (const nr_double_t d, vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (pow (d, v.get (i)), i);
return result;
}
vector pow (vector v1, vector v2) {
int j, i, n, len, len1 = v1.getSize (), len2 = v2.getSize ();
if (len1 >= len2) {
assert (len1 % len2 == 0);
len = len1;
} else {
assert (len2 % len1 == 0);
len = len2;
}
vector res (len);
for (j = i = n = 0; n < len; n++) {
res (n) = pow (v1 (i), v2 (j));
if (++i >= len1) i = 0; if (++j >= len2) j = 0;
}
return res;
}
vector sin (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (sin (v.get (i)), i);
return result;
}
vector asin (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (asin (v.get (i)), i);
return result;
}
vector acos (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (acos (v.get (i)), i);
return result;
}
vector cos (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (cos (v.get (i)), i);
return result;
}
vector tan (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (tan (v.get (i)), i);
return result;
}
vector atan (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (atan (v.get (i)), i);
return result;
}
vector cot (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (cot (v.get (i)), i);
return result;
}
vector acot (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (acot (v.get (i)), i);
return result;
}
vector sinh (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (sinh (v.get (i)), i);
return result;
}
vector asinh (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (asinh (v.get (i)), i);
return result;
}
vector cosh (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (cosh (v.get (i)), i);
return result;
}
vector sech (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (sech (v.get (i)), i);
return result;
}
vector cosech (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (cosech (v.get (i)), i);
return result;
}
vector acosh (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (acosh (v.get (i)), i);
return result;
}
vector asech (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (asech (v.get (i)), i);
return result;
}
vector tanh (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (tanh (v.get (i)), i);
return result;
}
vector atanh (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (atanh (v.get (i)), i);
return result;
}
vector coth (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (coth (v.get (i)), i);
return result;
}
vector acoth (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (acoth (v.get (i)), i);
return result;
}
vector ztor (vector v, nr_complex_t zref) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result (i) = ztor (v (i), zref);
return result;
}
vector ytor (vector v, nr_complex_t zref) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result (i) = ytor (v (i), zref);
return result;
}
vector rtoz (vector v, nr_complex_t zref) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result (i) = rtoz (v (i), zref);
return result;
}
vector rtoy (vector v, nr_complex_t zref) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result (i) = rtoy (v (i), zref);
return result;
}
vector diff (vector var, vector dep, int n) {
int k, xi, yi, exchange = 0;
vector x, y;
if (var.getSize () < dep.getSize ()) {
x = vector (var);
y = vector (dep);
exchange++;
}
else {
x = vector (dep);
y = vector (var);
}
assert (y.getSize () % x.getSize () == 0 && x.getSize () >= 2);
vector result (y);
nr_complex_t c;
for (k = 0; k < n; k++) {
for (yi = xi = 0; yi < y.getSize (); yi++, xi++) {
if (xi == x.getSize ()) xi = 0;
if (xi == 0) {
c = (y.get (yi + 1) - y.get (yi)) / (x.get (xi + 1) - x.get (xi));
} else if (xi == x.getSize () - 1) {
c = (y.get (yi) - y.get (yi - 1)) / (x.get (xi) - x.get (xi - 1));
}
else {
c =
((y.get (yi) - y.get (yi - 1)) / (x.get (xi) - x.get (xi - 1)) +
(y.get (yi + 1) - y.get (yi)) / (x.get (xi + 1) - x.get (xi))) /
2.0;
}
result.set (exchange ? 1.0 / c : c, yi);
}
y = result;
}
return result;
}
vector vector::operator=(const nr_complex_t c) {
for (int i = 0; i < size; i++) data[i] = c;
return *this;
}
vector vector::operator=(const nr_double_t d) {
for (int i = 0; i < size; i++) data[i] = d;
return *this;
}
vector vector::operator+=(vector v) {
int i, n, len = v.getSize ();
assert (size % len == 0);
for (i = n = 0; i < size; i++) { data[i] += v (n); if (++n >= len) n = 0; }
return *this;
}
vector vector::operator+=(const nr_complex_t c) {
for (int i = 0; i < size; i++) data[i] += c;
return *this;
}
vector vector::operator+=(const nr_double_t d) {
for (int i = 0; i < size; i++) data[i] += d;
return *this;
}
vector operator+(vector v1, vector v2) {
int len1 = v1.getSize (), len2 = v2.getSize ();
vector result;
if (len1 >= len2) {
result = v1;
result += v2;
} else {
result = v2;
result += v1;
}
return result;
}
vector operator+(vector v, const nr_complex_t c) {
vector result (v);
result += c;
return result;
}
vector operator+(const nr_complex_t c, vector v) {
return v + c;
}
vector operator+(vector v, const nr_double_t d) {
vector result (v);
result += d;
return result;
}
vector operator+(const nr_double_t d, vector v) {
return v + d;
}
vector vector::operator-() {
vector result (size);
for (int i = 0; i < size; i++) result (i) = -data[i];
return result;
}
vector vector::operator-=(vector v) {
int i, n, len = v.getSize ();
assert (size % len == 0);
for (i = n = 0; i < size; i++) { data[i] -= v (n); if (++n >= len) n = 0; }
return *this;
}
vector vector::operator-=(const nr_complex_t c) {
for (int i = 0; i < size; i++) data[i] -= c;
return *this;
}
vector vector::operator-=(const nr_double_t d) {
for (int i = 0; i < size; i++) data[i] -= d;
return *this;
}
vector operator-(vector v1, vector v2) {
int len1 = v1.getSize (), len2 = v2.getSize ();
vector result;
if (len1 >= len2) {
result = v1;
result -= v2;
} else {
result = -v2;
result += v1;
}
return result;
}
vector operator-(vector v, const nr_complex_t c) {
vector result (v);
result -= c;
return result;
}
vector operator-(vector v, const nr_double_t d) {
vector result (v);
result -= d;
return result;
}
vector operator-(const nr_complex_t c, vector v) {
vector result (-v);
result += c;
return result;
}
vector operator-(const nr_double_t d, vector v) {
vector result (-v);
result += d;
return result;
}
vector vector::operator*=(vector v) {
int i, n, len = v.getSize ();
assert (size % len == 0);
for (i = n = 0; i < size; i++) { data[i] *= v (n); if (++n >= len) n = 0; }
return *this;
}
vector vector::operator*=(const nr_complex_t c) {
for (int i = 0; i < size; i++) data[i] *= c;
return *this;
}
vector vector::operator*=(const nr_double_t d) {
for (int i = 0; i < size; i++) data[i] *= d;
return *this;
}
vector operator*(vector v1, vector v2) {
int len1 = v1.getSize (), len2 = v2.getSize ();
vector result;
if (len1 >= len2) {
result = v1;
result *= v2;
} else {
result = v2;
result *= v1;
}
return result;
}
vector operator*(vector v, const nr_complex_t c) {
vector result (v);
result *= c;
return result;
}
vector operator*(vector v, const nr_double_t d) {
vector result (v);
result *= d;
return result;
}
vector operator*(const nr_complex_t c, vector v) {
return v * c;
}
vector operator*(const nr_double_t d, vector v) {
return v * d;
}
vector vector::operator/=(vector v) {
int i, n, len = v.getSize ();
assert (size % len == 0);
for (i = n = 0; i < size; i++) { data[i] /= v (n); if (++n >= len) n = 0; }
return *this;
}
vector vector::operator/=(const nr_complex_t c) {
for (int i = 0; i < size; i++) data[i] /= c;
return *this;
}
vector vector::operator/=(const nr_double_t d) {
for (int i = 0; i < size; i++) data[i] /= d;
return *this;
}
vector operator/(vector v1, vector v2) {
int len1 = v1.getSize (), len2 = v2.getSize ();
vector result;
if (len1 >= len2) {
assert (len1 % len2 == 0);
result = v1;
result /= v2;
} else {
assert (len2 % len1 == 0);
result = 1 / v2;
result *= v1;
}
return result;
}
vector operator/(vector v, const nr_complex_t c) {
vector result (v);
result /= c;
return result;
}
vector operator/(vector v, const nr_double_t d) {
vector result (v);
result /= d;
return result;
}
vector operator/(const nr_complex_t c, vector v) {
vector result (v);
result = c;
result /= v;
return result;
}
vector operator/(const nr_double_t d, vector v) {
vector result (v);
result = d;
result /= v;
return result;
}
vector operator%(vector v, const nr_complex_t z) {
int len = v.getSize ();
vector result (len);
for (int i = 0; i < len; i++) result (i) = v (i) % z;
return result;
}
vector operator%(vector v, const nr_double_t d) {
int len = v.getSize ();
vector result (len);
for (int i = 0; i < len; i++) result (i) = v (i) % d;
return result;
}
vector operator%(const nr_complex_t z, vector v) {
int len = v.getSize ();
vector result (len);
for (int i = 0; i < len; i++) result (i) = z % v (i);
return result;
}
vector operator%(const nr_double_t d, vector v) {
int len = v.getSize ();
vector result (len);
for (int i = 0; i < len; i++) result (i) = d % v (i);
return result;
}
vector operator%(vector v1, vector v2) {
int j, i, n, len, len1 = v1.getSize (), len2 = v2.getSize ();
if (len1 >= len2) {
assert (len1 % len2 == 0);
len = len1;
} else {
assert (len2 % len1 == 0);
len = len2;
}
vector res (len);
for (j = i = n = 0; n < len; n++) {
res (n) = v1 (i) % v2 (j);
if (++i >= len1) i = 0; if (++j >= len2) j = 0;
}
return res;
}
void vector::reverse (void) {
nr_complex_t * buffer = (nr_complex_t *)
malloc (sizeof (nr_complex_t) * size);
for (int i = 0; i < size; i++) buffer[i] = data[size - 1 - i];
free (data);
data = buffer;
capacity = size;
}
void vector::setOrigin (const char * n) {
free (origin);
origin = n ? strdup (n) : NULL;
}
char * vector::getOrigin (void) {
return origin;
}
deviating no more than the given epsilon. */
int vector::contains (nr_complex_t val, nr_double_t eps) {
int count = 0;
for (int i = 0; i < size; i++) {
if (abs (data[i] - val) <= eps) count++;
}
return count;
}
void vector::sort (bool ascending) {
nr_complex_t t;
for (int i = 0; i < size; i++) {
for (int n = 0; n < size - 1; n++) {
if (ascending ? data[n] > data[n+1] : data[n] < data[n+1]) {
t = data[n];
data[n] = data[n+1];
data[n+1] = t;
}
}
}
}
the given start value, ending with the given stop value and
containing points elements. */
vector linspace (nr_double_t start, nr_double_t stop, int points) {
vector result (points);
nr_double_t val, step = (stop - start) / (points - 1);
for (int i = 0; i < points; i++) {
val = start + (i * step);
if (i != 0 && fabs (val) < fabs (step) / 4 && fabs (val) < std::numeric_limits<nr_double_t>::epsilon())
val = 0.0;
result.set (val, i);
}
return result;
}
starting at the given start value, ending with the given stop value
and containing points elements. */
vector logspace (nr_double_t start, nr_double_t stop, int points) {
assert (start * stop > 0);
vector result (points);
nr_double_t step, first, last, d;
if (fabs (start) > fabs (stop)) {
first = fabs (stop);
last = fabs (start);
}
else {
first = fabs (start);
last = fabs (stop);
}
d = fabs (start) > fabs (stop) ? -1 : 1;
step = (::log (last) - ::log (first)) / (points - 1);
for (int i = 0, j = points - 1; i < points; i++, j--) {
if (d > 0)
result.set (start * ::exp (step * i), i);
else
result.set (stop * ::exp (step * i), j);
}
return result;
}
vector cumsum (vector v) {
vector result (v);
nr_complex_t val (0.0);
for (int i = 0; i < v.getSize (); i++) {
val += v.get (i);
result.set (val, i);
}
return result;
}
vector cumavg (vector v) {
vector result (v);
nr_complex_t val (0.0);
for (int i = 0; i < v.getSize (); i++) {
val = (val * (nr_double_t) i + v.get (i)) / (i + 1.0);
result.set (val, i);
}
return result;
}
vector cumprod (vector v) {
vector result (v);
nr_complex_t val (1.0);
for (int i = 0; i < v.getSize (); i++) {
val *= v.get (i);
result.set (val, i);
}
return result;
}
vector ceil (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (ceil (v.get (i)), i);
return result;
}
vector fix (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (fix (v.get (i)), i);
return result;
}
vector floor (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (floor (v.get (i)), i);
return result;
}
vector round (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (round (v.get (i)), i);
return result;
}
vector sqr (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (sqr (v.get (i)), i);
return result;
}
vector step (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (step (v.get (i)), i);
return result;
}
static nr_double_t integrate_n (vector v) {
nr_double_t result = 0.0;
for (int i = 1; i < v.getSize () - 1; i++) result += norm (v.get (i));
result += 0.5 * norm (v.get (0));
result += 0.5 * norm (v.get (v.getSize () - 1));
return result;
}
nr_double_t vector::rms (void) {
nr_double_t result = std::sqrt (integrate_n (*this) / getSize ());
return result;
}
nr_double_t vector::variance (void) {
nr_double_t result = 0.0;
nr_complex_t average = avg (*this);
for (int i = 0; i < getSize (); i++) result += norm (get (i) - average);
if (getSize () > 1)
return result / (getSize () - 1);
return 0.0;
}
nr_double_t vector::stddev (void) {
return std::sqrt (variance ());
}
vector erf (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (erf (v.get (i)), i);
return result;
}
vector erfc (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (erfc (v.get (i)), i);
return result;
}
vector erfinv (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (erfinv (v.get (i)), i);
return result;
}
vector erfcinv (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (erfcinv (v.get (i)), i);
return result;
}
vector rad2deg (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (rad2deg (v.get (i)), i);
return result;
}
vector deg2rad (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (deg2rad (v.get (i)), i);
return result;
}
vector i0 (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (i0 (v.get (i)), i);
return result;
}
vector jn (const int n, vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (jn (n, v.get (i)), i);
return result;
}
vector yn (const int n, vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (yn (n, v.get (i)), i);
return result;
}
vector polar (const nr_complex_t a, vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (qucs::polar (a, v.get (i)), i);
return result;
}
vector polar (vector v, const nr_complex_t p) {
vector result (v);
for (int i = 0; i < v.getSize (); i++) result.set (qucs::polar (v.get (i), p), i);
return result;
}
vector polar (vector a, vector p) {
int j, i, n, len, len1 = a.getSize (), len2 = p.getSize ();
if (len1 >= len2) {
assert (len1 % len2 == 0);
len = len1;
} else {
assert (len2 % len1 == 0);
len = len2;
}
vector res (len);
for (j = i = n = 0; n < len; n++) {
res (n) = qucs::polar (a (i), p (j));
if (++i >= len1) i = 0; if (++j >= len2) j = 0;
}
return res;
}
vector atan2 (const nr_double_t y, vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++)
result.set (atan2 (y, v.get (i)), i);
return result;
}
vector atan2 (vector v, const nr_double_t x) {
vector result (v);
for (int i = 0; i < v.getSize (); i++)
result.set (atan2 (v.get (i), x) , i);
return result;
}
vector atan2 (vector y, vector x) {
int j, i, n, len, len1 = y.getSize (), len2 = x.getSize ();
if (len1 >= len2) {
assert (len1 % len2 == 0);
len = len1;
} else {
assert (len2 % len1 == 0);
len = len2;
}
vector res (len);
for (j = i = n = 0; n < len; n++) {
res (n) = atan2 (y (i), x (j));
if (++i >= len1) i = 0; if (++j >= len2) j = 0;
}
return res;
}
vector w2dbm (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++)
result.set (10.0 * log10 (v.get (i) / 0.001), i);
return result;
}
vector dbm2w (vector v) {
vector result (v);
for (int i = 0; i < v.getSize (); i++)
result.set (0.001 * pow (10.0 , v.get (i) / 10.0), i);
return result;
}
nr_double_t integrate (vector v, const nr_double_t h) {
nr_double_t s = real (v.get (0) ) / 2;
for (int i = 1; i < v.getSize () - 1; i++)
s += real (v.get (i));
return (s + real (v.get (v.getSize () - 1) ) / 2) * h;
}
nr_complex_t integrate (vector v, const nr_complex_t h) {
nr_complex_t s;
s = v.get (0) / 2.0;
for (int i = 1; i < v.getSize () - 1; i++)
s += v.get (i);
return (s + v.get (v.getSize () - 1) / 2.0) * h;
}
vector dbm (vector v, const nr_complex_t z) {
vector result (v);
for (int i = 0; i < v.getSize (); i++)
result.set (10.0 * log10 (norm (v.get (i)) / conj (z) / 0.001), i);
return result;
}
vector runavg (const nr_complex_t x, const int n) {
vector result (n);
for (int i = 0; i < n; i++) result.set (x, i);
return result;
}
vector runavg (vector v, const int n) {
nr_complex_t s (0.0), y;
int len = v.getSize () - n + 1, i;
vector result (len);
for (i = 0; i < n; i++) s += v.get (i);
y = s / (nr_double_t) n;
result.set (y, 0);
for (i = 0; i < len - 1; i++) {
y += (v.get (i + n) - v.get (i)) / (nr_double_t) n;
result.set (y, i + 1);
}
return result;
}
vector smooth(vector v, nr_double_t a) {
int len = v.getSize (), i;
int t2 = floor(len/2 * a / 100);
int extvlen = len + 2 * t2;
vector extv(extvlen), result (len);
for (i = 0; i < extvlen; i++) {
if (i < t2) {
extv.set (v(0), i);
} else if (i >= (len + t2)) {
extv.set (v(len-1), i);
} else {
extv.set (v(i - t2), i);
}
}
return runavg(extv, 2*t2+1);
}
vector groupdelay(vector svec, vector freq)
{
return -diff(unwrap(arg(svec)), (2*pi)*(freq));
}
#ifdef DEBUG
void vector::print (void) {
for (int r = 0; r < size; r++) {
fprintf (stderr, "%+.2e%+.2ei\n", (double) real (get (r)),
(double) imag (get (r)));
}
}
#endif
}