Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
history.cpp
Go to the documentation of this file.
1 /*
2  * history.cpp - history class implementation
3  *
4  * Copyright (C) 2006, 2007 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 #if HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <cmath>
33 
34 #include "precision.h"
35 #include "tvector.h"
36 #include "poly.h"
37 #include "spline.h"
38 #include "history.h"
39 
40 namespace qucs {
41 
42 // Constructor creates an unnamed instance of the history class.
44  age = 0;
45  t = values = NULL;
46 }
47 
48 /* The copy constructor creates a new instance based on the given
49  history object. */
51  age = h.age;
52  t = h.t;
53  values = h.values ? new tvector<nr_double_t> (*h.values) : NULL;
54 }
55 
56 // Destructor deletes a history object.
58  if (values) delete values;
59 }
60 
61 // The function appends the given value to the history.
62 void history::append (nr_double_t val) {
63  if (values == NULL) values = new tvector<nr_double_t>;
64  values->add (val);
65  if (values != t) drop ();
66 }
67 
68 /* This function drops the most recent n values in the history. */
69 void history::truncate (int n)
70 {
71  t->truncate (n);
72  values->truncate (n);
73 }
74 
75 /* This function drops those values in the history which are newer
76  than the specified time. */
77 void history::truncate (nr_double_t tcut)
78 {
79  int i;
80  int ts = t->getSize ();
81 
82  for (i = leftidx (); i < ts; i++)
83  {
84  if (t->get (i) > tcut)
85  {
86  break;
87  }
88  }
89  truncate (ts - i);
90 }
91 
92 // Returns left-most valid index into the time value vector.
93 int history::leftidx (void) {
94  int ts = t->getSize ();
95  int vs = values->getSize ();
96  return ts - vs > 0 ? ts - vs : 0;
97 }
98 
99 /* Returns number of unused values (time value vector shorter than
100  value vector). */
101 int history::unused (void) {
102  int ts = t->getSize ();
103  int vs = values->getSize ();
104  return vs - ts > 0 ? vs - ts : 0;
105 }
106 
107 // Returns the first (oldest) time value in the history.
108 nr_double_t history::first (void) {
109  return (t != NULL) ? t->get (leftidx ()) : 0.0;
110 }
111 
112 // Returns the last (youngest) time value in the history.
113 nr_double_t history::last (void) {
114  return (t != NULL) ? t->get (t->getSize () - 1) : 0.0;
115 }
116 
117 // Returns the duration of the history.
118 nr_double_t history::duration (void) {
119  return last () - first ();
120 }
121 
122 /* This function drops those values in the history which are older
123  than the specified age of the history instance. */
124 void history::drop (void) {
125  nr_double_t f = first ();
126  nr_double_t l = last ();
127  if (age > 0.0 && l - f > age) {
128  int r, i = leftidx ();
129  for (r = 0; i < t->getSize (); r++, i++)
130  if (l - t->get (i) < age) break;
131  r += unused () - 2; // keep 2 values being older than specified age
132  if (r > 127) values->drop (r);
133  }
134 }
135 
136 /* Interpolates a value using 2 left side and 2 right side values if
137  possible. */
138 nr_double_t history::interpol (nr_double_t tval, int idx, bool left) {
139  static spline spl (SPLINE_BC_NATURAL);
140  static tvector<nr_double_t> x (4);
141  static tvector<nr_double_t> y (4);
142 
143  int n = left ? idx + 1: idx;
144  if (n > 1 && n + 2 < values->getSize ()) {
145  int i, k, l = leftidx ();
146  for (k = 0, i = n - 2; k < 4; i++, k++) {
147  x (k) = t->get (i + l);
148  y (k) = values->get (i);
149  }
150  spl.vectors (y, x);
151  spl.construct ();
152  return spl.evaluate (tval).f0;
153  }
154  return values->get (idx);
155 }
156 
157 /* The function returns the value nearest to the given time value. If
158  the otional parameter is true then additionally cubic spline
159  interpolation is used. */
160 nr_double_t history::nearest (nr_double_t tval, bool interpolate) {
161  if (t != NULL) {
162  int l = leftidx ();
163  int r = t->getSize () - 1;
164  int i = -1;
165  nr_double_t diff = NR_MAX;
166  sign = true;
167  i = seek (tval, l, r, diff, i);
168  i = i - l;
169  if (interpolate) return interpol (tval, i, sign);
170  return values->get (i);
171  }
172  return 0.0;
173 }
174 
175 /* The function is utilized in order to find the nearest value to a
176  given time value. Since the time vector is ordered a recursive
177  lookup algorithm can be used. The function returns the current
178  index into the time vector as well as the error in time. */
179 int history::seek (nr_double_t tval, int l, int r, nr_double_t& diff,
180  int idx) {
181  int i = (l + r) / 2;
182  if (l == r) return i;
183  nr_double_t v = t->get (i);
184  nr_double_t d = v - tval;
185  if (fabs (d) < diff) {
186  // better approximation
187  diff = fabs (d);
188  sign = d < 0.0 ? true : false;
189  idx = i;
190  }
191  else if (i == l) {
192  // no better
193  return idx;
194  }
195  if (d < 0.0) {
196  // look later
197  return seek (tval, i, r, diff, idx);
198  }
199  else if (d > 0.0) {
200  // look earlier
201  return seek (tval, l, i, diff, idx);
202  }
203  return idx;
204 }
205 
206 nr_double_t history::getTfromidx (int idx)
207 {
208  if (t == NULL)
209  {
210  return 0;
211  }
212  else
213  {
214  return t->get(idx);
215  }
216 }
217 
218 nr_double_t history::getValfromidx (int idx)
219 {
220  if (t == NULL)
221  {
222  return 0;
223  }
224  else
225  {
226  return values->get(idx);
227  }
228 }
229 
231 {
232  if (t == NULL)
233  {
234  return 0;
235  }
236  else
237  {
238  return t->getSize ();
239  }
240 }
241 
242 } // namespace qucs
void truncate(int)
Definition: tvector.cpp:155
l
Definition: parse_vcd.y:213
poly evaluate(nr_double_t)
Definition: spline.cpp:285
void vectors(qucs::vector, qucs::vector)
Definition: spline.cpp:85
tvector< nr_double_t > * values
Definition: history.h:65
void construct(void)
Definition: spline.cpp:135
nr_double_t age
Definition: history.h:64
int leftidx(void)
Definition: history.cpp:93
nr_double_t getTfromidx(int)
Definition: history.cpp:206
nr_double_t last(void)
Definition: history.cpp:113
n
Definition: parse_citi.y:147
void append(nr_double_t)
Definition: history.cpp:62
h
Definition: parse_vcd.y:214
r
Definition: parse_mdl.y:515
i
Definition: parse_mdl.y:516
void add(nr_type_t)
Definition: tvector.cpp:127
void drop(int)
Definition: tvector.cpp:145
nr_type_t get(int)
Definition: tvector.cpp:101
void truncate(int)
Definition: history.cpp:69
x
Definition: parse_mdl.y:498
tvector< nr_double_t > * t
Definition: history.h:66
nr_double_t first(void)
Definition: history.cpp:108
vector diff(vector, vector, int n=1)
Definition: vector.cpp:591
v
Definition: parse_zvr.y:141
int getSize(void)
Definition: history.cpp:230
nr_double_t duration(void)
Definition: history.cpp:118
int unused(void)
Definition: history.cpp:101
y
Definition: parse_mdl.y:499
nr_double_t nearest(nr_double_t, bool interpolate=true)
Definition: history.cpp:160
bool sign
Definition: history.h:63
void drop(void)
Definition: history.cpp:124
nr_double_t getValfromidx(int)
Definition: history.cpp:218
int seek(nr_double_t, int, int, nr_double_t &, int)
Definition: history.cpp:179
int getSize(void)
Definition: tvector.h:82
nr_double_t f0
Definition: poly.h:46
nr_double_t interpol(nr_double_t, int, bool)
Definition: history.cpp:138