Project

General

Profile

Statistics
| Branch: | Revision:

root / src / scave / windowavg.cc @ e1750c09

History | View | Annotate | Download (4.66 KB)

1 01873262 Georg Kunz
//=========================================================================
2
//  WINDOWAVG.CC - part of
3
//                  OMNeT++/OMNEST
4
//           Discrete System Simulation in C++
5
//
6
//  Author: Andras Varga
7
//
8
//=========================================================================
9
10
/*--------------------------------------------------------------*
11
  Copyright (C) 1992-2008 Andras Varga
12
  Copyright (C) 2006-2008 OpenSim Ltd.
13

14
  This file is distributed WITHOUT ANY WARRANTY. See the file
15
  `license' for details on this and other legal matters.
16
*--------------------------------------------------------------*/
17
18
#include <stdlib.h>
19
#include "channel.h"
20
#include "scaveutils.h"
21
#include "windowavg.h"
22
23
USING_NAMESPACE
24
25
26
WindowAverageNode::WindowAverageNode(int windowSize)
27
{
28
    array = NULL;
29
    if (windowSize<1 || windowSize>100000)
30
        throw opp_runtime_error("winavg: invalid window size %d", windowSize);
31
    winsize = windowSize;
32
    array = new Datum[winsize];
33
}
34
35
WindowAverageNode::~WindowAverageNode()
36
{
37
    delete array;
38
}
39
40
bool WindowAverageNode::isReady() const
41
{
42
    return in()->length()>=winsize || in()->isClosing();
43
}
44
45
void WindowAverageNode::process()
46
{
47
    // do as many winsize-sized chunks as possible, but in the end
48
    // we'll have to do the remaining ones (n<winsize)
49
    do {
50
        int n = in()->read(array,winsize);
51
        double sumy = 0;
52
        for (int i=0; i<n; i++)
53
            sumy += array[i].y;
54
        Datum o;
55
        o.x = array[0].x;
56
        o.y = sumy/n;
57
        out()->write(&o,1);
58
    }
59
    while (in()->length()>=winsize || (in()->isClosing() && in()->length()>0));
60
}
61
62
//-----
63
64
const char *WindowAverageNodeType::getDescription() const
65
{
66
    return "Calculates batched average: replaces every `winsize' input values\n"
67
           "with their mean. Time is the time of the first value in the batch.";
68
}
69
70
void WindowAverageNodeType::getAttributes(StringMap& attrs) const
71
{
72
    attrs["windowSize"] = "size of batch as integer";
73
}
74
75
void WindowAverageNodeType::getAttrDefaults(StringMap& attrs) const
76
{
77
    attrs["windowSize"] = "10";
78
}
79
80
Node *WindowAverageNodeType::create(DataflowManager *mgr, StringMap& attrs) const
81
{
82
    checkAttrNames(attrs);
83
84
    const char *ws = attrs["windowSize"].c_str();
85
    int windowSize = atoi(ws);
86
87
    Node *node = new WindowAverageNode(windowSize);
88
    node->setNodeType(this);
89
    mgr->addNode(node);
90
    return node;
91
}
92
93
void WindowAverageNodeType::mapVectorAttributes(/*inout*/StringMap &attrs, /*out*/StringVector &warnings) const
94
{
95
    if (attrs["type"] == "enum")
96
        warnings.push_back(std::string("Applying '") + getName() + "' to an enum");
97
    attrs["type"] = "double";
98
}
99
100
101
//------------------------------
102
103
TimeWindowAverageNode::TimeWindowAverageNode(simultime_t windowSize)
104
{
105
    winsize = windowSize;
106
    win_end = windowSize;
107
    sum = 0.0;
108
    count = 0;
109
}
110
111
TimeWindowAverageNode::~TimeWindowAverageNode()
112
{
113
}
114
115
bool TimeWindowAverageNode::isFinished() const
116
{
117
    return in()->eof() && count == 0;
118
}
119
120
bool TimeWindowAverageNode::isReady() const
121
{
122
    return in()->length() > 0 || (in()->eof() && count > 0);
123
}
124
125
void TimeWindowAverageNode::process()
126
{
127
    int n = in()->length();
128
129
    for (int i=0; i<n; i++)
130
    {
131
        Datum d;
132
        in()->read(&d,1);
133
        if (inCurrentWindow(d))
134
        {
135
            collect(d);
136
        }
137
        else
138
        {
139
            outputWindowAverage();
140
            moveWindow(d);
141
            collect(d);
142
        }
143
    }
144
145
    if (in()->eof())
146
        outputWindowAverage();
147
}
148
149
//-----
150
151
const char *TimeWindowAverageNodeType::getDescription() const
152
{
153
    return "Calculates time average: replaces input values in every `windowSize' interval with their mean.\n"
154
           "tout[k] = k * winSize\n"
155
           "yout[k] = average of y values in the [(k-1)*winSize, k*winSize) interval";
156
}
157
158
void TimeWindowAverageNodeType::getAttributes(StringMap& attrs) const
159
{
160
    attrs["windowSize"] = "size of window in seconds";
161
}
162
163
void TimeWindowAverageNodeType::getAttrDefaults(StringMap& attrs) const
164
{
165
    attrs["windowSize"] = "1";
166
}
167
168
Node *TimeWindowAverageNodeType::create(DataflowManager *mgr, StringMap& attrs) const
169
{
170
    checkAttrNames(attrs);
171
172
    const char *ws = attrs["windowSize"].c_str();
173
    simultime_t windowSize;
174
    parseSimtime(ws, windowSize);
175
    if (windowSize.isNil() || windowSize <= 0)
176
        windowSize = 1;
177
178
    Node *node = new TimeWindowAverageNode(windowSize);
179
    node->setNodeType(this);
180
    mgr->addNode(node);
181
    return node;
182
}
183
184
void TimeWindowAverageNodeType::mapVectorAttributes(/*inout*/StringMap &attrs, /*out*/StringVector &warnings) const
185
{
186
    if (attrs["type"] == "enum")
187
        warnings.push_back(std::string("Applying '") + getName() + "' to an enum");
188
    attrs["type"] = "double";
189
}