finish examples for the steady state collectors. draft
authorLi Li <ll024@bucknell.edu>
Tue, 12 Aug 2014 01:03:11 -0400
changeset 10572 b8a960513c71
parent 10571 65245211f753
child 10573 508c97a1750a
finish examples for the steady state collectors.
src/stats/examples/mean-crossings-steady-state-collector-example.cc
src/stats/examples/moving-average-collector-example.cc
src/stats/examples/mser5-steady-state-collector-example.cc
src/stats/examples/wscript
src/stats/model/mean-crossings-steady-state-collector.cc
src/stats/model/moving-average-collector.cc
src/stats/model/mser5-steady-state-collector.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/examples/mean-crossings-steady-state-collector-example.cc	Tue Aug 12 01:03:11 2014 -0400
@@ -0,0 +1,148 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014 Bucknell University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Li Li (ll024@bucknell.edu)
+ */
+
+#include <vector>
+#include <iostream>
+#include <string>
+
+#include "ns3/core-module.h"
+#include "ns3/mean-crossings-steady-state-collector.h"
+#include "ns3/stats-module.h"
+#include "ns3/gnuplot.h"
+#include "ns3/gnuplot-aggregator.h"
+
+using namespace ns3;
+NS_LOG_COMPONENT_DEFINE ("MeanCrossingsSteadyStateCollectorExample");
+
+
+class MeanCrossingsEmitter : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+  MeanCrossingsEmitter(unsigned int totalRunTime);
+private:
+  void Emit (double value);
+  unsigned int totalRunTime;
+  TracedValue<double> m_output;
+};
+
+NS_OBJECT_ENSURE_REGISTERED(MeanCrossingsEmitter);
+
+TypeId
+MeanCrossingsEmitter::GetTypeId(void)
+{
+  static TypeId tid = TypeId("ns3::MeanCrossingsEmitter")
+    .AddConstructor<MeanCrossingsEmitter> ()
+    .SetParent<Object> ()
+    .AddTraceSource("Output",
+                    "The output value",
+                    MakeTraceSourceAccessor (&MeanCrossingsEmitter::m_output))
+    ;
+    return tid;
+}
+
+MeanCrossingsEmitter::MeanCrossingsEmitter (unsigned int runTime = 5000)
+{
+  NS_LOG_FUNCTION (this);
+  totalRunTime = runTime;
+  m_output = 0;
+
+  double steadyStateMeanKnown     = 0.0;
+  double steadyStateVarianceKnown = 1.0;
+  NormalVariable normalVariable (steadyStateMeanKnown, steadyStateVarianceKnown);
+  double bias;
+  double multiple = 5.0;
+  double value;
+  double steadyStateSignal;
+  
+  for (unsigned int i = 0; i < totalRunTime; i++)
+  {
+    bias = multiple * exp (-0.005 * i);
+    steadyStateSignal = normalVariable.GetValue();
+    value = steadyStateSignal + bias;
+    Simulator::Schedule(Seconds(i), &MeanCrossingsEmitter::Emit, this, value);
+  }
+}
+
+void 
+MeanCrossingsEmitter::Emit(double value)
+{
+  m_output = value;
+}
+
+
+int main(int argc, char *argv[])
+{
+  using namespace std;
+
+  NS_LOG_INFO("here");
+  //***************************************************************************
+  // Create a simulated data set.
+  //***************************************************************************
+
+  vector<Time> times;
+  vector<double> values;
+
+  unsigned int totalRunTime = 5000;
+  // Create a MeanCrossingsEmitter object
+  Ptr<MeanCrossingsEmitter> meanCrossingsEmitter = CreateObject<MeanCrossingsEmitter> (totalRunTime);
+
+  // Create a Double Probe object
+  Ptr<DoubleProbe> testProbe = CreateObject<DoubleProbe>();
+  testProbe ->SetName("Mser5DoubleProbe");
+
+  // Hook up the emitter to the probe
+  testProbe->ConnectByObject ("Output", meanCrossingsEmitter);
+  testProbe->Enable();
+
+  // Create the steady-state collector.
+  Ptr<MeanCrossingsSteadyStateCollector> meanCrossingsCollector = CreateObject<MeanCrossingsSteadyStateCollector> ();
+
+  // Hook up the probe to the collector
+  testProbe ->TraceConnectWithoutContext("Output", MakeCallback(&MeanCrossingsSteadyStateCollector::TraceSinkDouble, meanCrossingsCollector));
+  meanCrossingsCollector ->Enable();
+  
+  // Create a Gnuplot Aggregator
+  string fileNameWithoutExtention = "mean-crossings-collector-example-output";
+  string plotTitle = "Mean Crossings Collector Example";
+  string plotXAxisHeading = "Time (seconds)";
+  string plotYAxisHeading = "Double Values";
+  string plotDatasetLabel = "Data Values";
+  string datasetContext = "Dataset/Context/String";
+  Ptr<GnuplotAggregator> aggregator =
+    CreateObject<GnuplotAggregator> (fileNameWithoutExtention);
+  // Set the aggregator's properties.
+  aggregator->SetTerminal ("png");
+  aggregator->SetTitle (plotTitle);
+  aggregator->SetLegend (plotXAxisHeading, plotYAxisHeading);
+  // Add a data set to the aggregator.
+  aggregator->Add2dDataset (datasetContext, plotDatasetLabel);
+  // aggregator must be turned on
+  aggregator->Enable ();
+
+  // Hook up the collector to the aggregator
+  meanCrossingsCollector ->TraceConnect("FilteredData", "Dataset/Context/String", MakeCallback(&GnuplotAggregator::Write2d, aggregator));
+
+  Simulator::Stop(Seconds (totalRunTime + 1));
+  Simulator::Run();
+  Simulator::Destroy();
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/examples/moving-average-collector-example.cc	Tue Aug 12 01:03:11 2014 -0400
@@ -0,0 +1,168 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014 Bucknell University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Li Li (ll024@bucknell.edu)
+ */
+
+/*
+ * This example is designed to show the main features of an
+ * ns3::MovingAverageCollector. The example is modified from double-probe-example.cc.
+ * The ns3::MovingAverageCollector collects a series of data and calculates the moving
+ * average of every few data specified by the WindowSize attribute. It generates the moving
+ * average for every WindowSize of data. This example belows defines a class called Emitter
+ * to spit out data, creates a MovingAverageCollector to collect and calculate the mean, and
+ * outputs the mean to a file using FileAggregator.
+ */
+
+#include <iostream>
+#include <string>
+
+#include "ns3/core-module.h"
+#include "ns3/double-probe.h"
+#include "ns3/moving-average-collector.h"
+#include "ns3/stats-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("MovingAverageCollectorExample");
+
+
+// Declare a MovingAverageCollector as a global variable
+Ptr<MovingAverageCollector> collector = CreateObject<MovingAverageCollector> ();
+
+
+/*
+ * This is our test object, an object that increments counters at
+ * various times and emits one of them as a trace source.
+ */
+class Emitter : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+  Emitter ();
+private:
+  void DoInitialize (void);
+  void Emit (void);
+  void Count (void);
+
+  TracedValue<double> m_counter;  // normally this would be integer type
+  Ptr<ExponentialRandomVariable> m_var;
+
+};
+
+NS_OBJECT_ENSURE_REGISTERED (Emitter)
+  ;
+
+TypeId
+Emitter::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Emitter")
+    .AddConstructor<Emitter> ()
+    .SetParent<Object> ()
+    .AddTraceSource ("Counter",
+                     "sample counter",
+                     MakeTraceSourceAccessor (&Emitter::m_counter))
+  ;
+  return tid;
+}
+
+Emitter::Emitter (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_counter = 0;
+  m_var = CreateObject<ExponentialRandomVariable> ();
+}
+
+void
+Emitter::DoInitialize (void)
+{
+  NS_LOG_FUNCTION (this);
+  Simulator::Schedule (Seconds (m_var->GetValue ()), &Emitter::Emit, this);
+  Simulator::Schedule (Seconds (m_var->GetValue ()), &Emitter::Count, this);
+}
+
+void
+Emitter::Emit (void)
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_DEBUG ("Emitting at " << Simulator::Now ().GetSeconds ());
+  Simulator::Schedule (Seconds (m_var->GetValue ()), &Emitter::Emit, this);
+}
+
+void
+Emitter::Count (void)
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_DEBUG ("Counting at " << Simulator::Now ().GetSeconds ());
+  m_counter += 1.0;
+  DoubleProbe::SetValueByPath ("/Names/StaticallyAccessedProbe", m_counter);
+  Simulator::Schedule (Seconds (m_var->GetValue ()), &Emitter::Count, this);
+}
+
+
+int main (int argc, char *argv[])
+{
+  CommandLine cmd;
+  cmd.Parse (argc, argv);
+  bool connected;
+
+  // Set the WindowSize attribute of the collector. By default the value is 3
+  collector->SetAttribute("WindowSize", UintegerValue(5));
+
+  Ptr<Emitter> emitter = CreateObject<Emitter> ();
+  Names::Add ("/Names/Emitter", emitter);
+
+  //
+  // testProbe will be called by the emitter directly through the
+  // static method SetValueByPath().
+  //
+  Ptr<DoubleProbe> testProbe = CreateObject<DoubleProbe> ();
+  testProbe ->SetName ("StaticallyAccessedProbe");
+  // We must add it to the config database
+  Names::Add ("/Names/Probes", testProbe ->GetName (), testProbe);
+
+  // hook the probe to the callback function
+  connected = testProbe ->TraceConnectWithoutContext ("Output",  MakeCallback (&MovingAverageCollector::TraceSinkDouble, collector));
+  NS_ASSERT (connected == true);
+
+  // enable the collector
+  collector->Enable();
+
+  // Set up a FileAggregator
+  std::string outputFileName = "moving-average-collector-output.txt";
+  enum FileAggregator::FileType m_fileType = FileAggregator::SPACE_SEPARATED;
+  
+  Ptr<FileAggregator> aggregator = CreateObject<FileAggregator> (outputFileName, m_fileType);
+  
+  aggregator-> SetHeading("time moving_average");
+  aggregator-> Enable();
+
+  // connect the collector with the aggregator
+  connected = collector-> TraceConnect("Output", "/Names/Probes/StaticallyAccessedProbe/Output", MakeCallback(&FileAggregator::Write2d, aggregator));
+  NS_ASSERT (connected == true);
+  NS_UNUSED (connected);
+
+  // The Emitter object is not associated with an ns-3 node, so
+  // it won't get started automatically, so we need to do this ourselves
+  Simulator::Schedule (Seconds (0.0), &Emitter::Initialize, emitter);
+
+  Simulator::Stop (Seconds (100.0));
+  Simulator::Run ();
+  Simulator::Destroy ();
+
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/examples/mser5-steady-state-collector-example.cc	Tue Aug 12 01:03:11 2014 -0400
@@ -0,0 +1,160 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014 Bucknell University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Li Li (ll024@bucknell.edu)
+ */
+
+#include <vector>
+#include <iostream>
+#include <string>
+
+#include "ns3/core-module.h"
+#include "ns3/mser5-steady-state-collector.h"
+#include "ns3/stats-module.h"
+#include "ns3/gnuplot.h"
+#include "ns3/gnuplot-aggregator.h"
+
+using namespace ns3;
+NS_LOG_COMPONENT_DEFINE ("Mser5SteadyStateCollectorExample");
+
+class Mser5Emitter : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+  Mser5Emitter(unsigned int totalRunTime);
+private:
+  void Emit (double value);
+  unsigned int totalRunTime;
+  TracedValue<double> m_output;
+};
+
+NS_OBJECT_ENSURE_REGISTERED(Mser5Emitter);
+
+TypeId
+Mser5Emitter::GetTypeId(void)
+{
+  static TypeId tid = TypeId("ns3::Mser5Emitter")
+    .AddConstructor<Mser5Emitter> ()
+    .SetParent<Object> ()
+    .AddTraceSource("Output",
+                    "The output value",
+                    MakeTraceSourceAccessor (&Mser5Emitter::m_output))
+    ;
+    return tid;
+}
+
+Mser5Emitter::Mser5Emitter (unsigned int runTime = 5000)
+{
+  NS_LOG_FUNCTION (this);
+  totalRunTime = runTime;
+  m_output = 0;
+
+  // The code below generates a series of converging values every second.
+  // These values will be used by the steady state collectors to calculate
+  // the steady state.
+  double steadyStateMeanKnown     = 0.0;
+  double steadyStateVarianceKnown = 1.0;
+  NormalVariable normalVariable (steadyStateMeanKnown, steadyStateVarianceKnown);
+  double bias;
+  double multiple = 5.0;
+  double value;
+  double steadyStateSignal;
+  
+  for (unsigned int i = 0; i < totalRunTime; i++)
+  {
+    bias = multiple * exp (-0.005 * i);
+    steadyStateSignal = normalVariable.GetValue();
+    // Get the value to be emitted at time i
+    value = steadyStateSignal + bias;
+    // Schedule all future events of the emitter
+    Simulator::Schedule(Seconds(i), &Mser5Emitter::Emit, this, value);
+  }
+}
+
+void 
+Mser5Emitter::Emit(double value)
+{
+  // output the value
+  m_output = value;
+}
+
+int main(int argc, char *argv[])
+{
+  using namespace std;
+
+  //***************************************************************************
+  // Create a simulated data set.
+  //***************************************************************************
+
+  vector<Time> times;
+  vector<double> values;
+
+  unsigned int totalRunTime = 5000;
+  // Create a Mser5Emitter object
+  Ptr<Mser5Emitter> mser5Emitter = CreateObject<Mser5Emitter> (totalRunTime);
+
+  // Create a Double Probe object
+  Ptr<DoubleProbe> testProbe = CreateObject<DoubleProbe>();
+  testProbe ->SetName("Mser5DoubleProbe");
+
+  // Hook up the emitter to the probe
+  testProbe->ConnectByObject ("Output", mser5Emitter);
+  testProbe->Enable();
+
+  // Create the steady-state collector.
+  Ptr<Mser5SteadyStateCollector> mser5Collector = CreateObject<Mser5SteadyStateCollector> ();
+  // Set some of the collector's properties.
+  mser5Collector->SetAttribute ("TransObsMaxFraction", DoubleValue (0.25));
+  mser5Collector->SetAttribute ("BatchMeansSize", UintegerValue(5));
+  mser5Collector ->Enable();
+
+  // Schedule the CalculateSteadyStateStatistics method at the end of
+  // the simulation to calculate steady state stats
+  Simulator::Schedule(Seconds(totalRunTime), &Mser5SteadyStateCollector::CalculateSteadyStateStatistics, mser5Collector);
+
+  // Hook up the probe to the collector
+  testProbe ->TraceConnectWithoutContext("Output", MakeCallback(&Mser5SteadyStateCollector::TraceSinkDouble, mser5Collector));
+  
+  // Create a Gnuplot Aggregator
+  string fileNameWithoutExtention = "mser5-collector-example-output";
+  string plotTitle = "Mser5 Collector Example";
+  string plotXAxisHeading = "Time (seconds)";
+  string plotYAxisHeading = "Double Values";
+  string plotDatasetLabel = "Data Values";
+  string datasetContext = "Dataset/Context/String";
+  Ptr<GnuplotAggregator> aggregator =
+    CreateObject<GnuplotAggregator> (fileNameWithoutExtention);
+  // Set the aggregator's properties.
+  aggregator->SetTerminal ("png");
+  aggregator->SetTitle (plotTitle);
+  aggregator->SetLegend (plotXAxisHeading, plotYAxisHeading);
+  // Add a data set to the aggregator.
+  aggregator->Add2dDataset (datasetContext, plotDatasetLabel);
+  // aggregator must be turned on
+  aggregator->Enable ();
+
+  // Hook up the collector to the aggregator.
+  // You can try to change the trace source from "UnfilteredData"
+  // to "FilteredData" to see the effect of the collector
+  mser5Collector ->TraceConnect("UnfilteredData", "Dataset/Context/String", MakeCallback(&GnuplotAggregator::Write2d, aggregator));
+
+  Simulator::Stop(Seconds (totalRunTime + 1));
+  Simulator::Run();
+  Simulator::Destroy();
+}
+
+
--- a/src/stats/examples/wscript	Sun Aug 10 17:34:19 2014 -0400
+++ b/src/stats/examples/wscript	Tue Aug 12 01:03:11 2014 -0400
@@ -33,3 +33,9 @@
 
     program = bld.create_ns3_program('sum-collector-example', ['network', 'stats'])
     program.source = 'sum-collector-example.cc'
+
+    program = bld.create_ns3_program('mser5-steady-state-collector-example', ['network', 'stats'])
+    program.source = 'mser5-steady-state-collector-example.cc'
+
+    program = bld.create_ns3_program('mean-crossings-steady-state-collector-example', ['network', 'stats'])
+    program.source = 'mean-crossings-steady-state-collector-example.cc'
--- a/src/stats/model/mean-crossings-steady-state-collector.cc	Sun Aug 10 17:34:19 2014 -0400
+++ b/src/stats/model/mean-crossings-steady-state-collector.cc	Tue Aug 12 01:03:11 2014 -0400
@@ -178,6 +178,7 @@
 MeanCrossingsSteadyStateCollector::TraceSinkDouble (double oldData, double newData)
 {
   Observation(newData);
+  ReportData();
 }
 
 void
--- a/src/stats/model/moving-average-collector.cc	Sun Aug 10 17:34:19 2014 -0400
+++ b/src/stats/model/moving-average-collector.cc	Tue Aug 12 01:03:11 2014 -0400
@@ -95,6 +95,7 @@
   //Add this mean to the output list
   m_outputBuffer.push_back(m_movingAverage);
   m_timeBuffer.push_back(Simulator::Now ());
+  ReportData();
 
 }
 
--- a/src/stats/model/mser5-steady-state-collector.cc	Sun Aug 10 17:34:19 2014 -0400
+++ b/src/stats/model/mser5-steady-state-collector.cc	Tue Aug 12 01:03:11 2014 -0400
@@ -246,6 +246,7 @@
 
       // Steady-state has been reached.
       m_isSteadyState = true;
+      ReportData();
     }
   else
     {
@@ -285,10 +286,7 @@
   m_currBatchTimeSum             (Time(Seconds(0))),
   m_currBatchValueSum            (0),  
   m_ssMean                       (0),
-  m_ssVariance                   (0),
-  m_lastUnfilteredReportedIndex  (0),
-  m_lastFilteredReportedIndex    (0)
-
+  m_ssVariance                   (0)
 {
 }
 
@@ -318,24 +316,20 @@
 void
 Mser5SteadyStateCollector::DoReportData (void)
 {
-  uint32_t i, reportBegin;
+  uint32_t i;
   //Report the unfiltered data
-  for (i=0; i<m_totalObs-m_lastUnfilteredReportedIndex; i++) {
+  for (i=0; i<m_totalObs; i++) {
     // Report the values.
-    m_unfilteredData(m_times[m_lastUnfilteredReportedIndex+i].GetSeconds(), m_values[m_lastUnfilteredReportedIndex+i]);
+    m_unfilteredData(m_times[i].GetSeconds(), m_values[i]);
   }
-  //Forward last reported Index
-  m_lastUnfilteredReportedIndex += i;
 
   //Report the filtered data
   if (m_isSteadyState) {
     //If we already started reporting the steady-state, just report next elements. 
-    reportBegin= std::max(m_lastFilteredReportedIndex, m_steadyStateValueIndex);     
-    for (i=0; i<m_totalObs-reportBegin; i++) {
+    for (i=m_steadyStateValueIndex; i<m_totalObs; i++) {
       // Report the values.
-      m_filteredData(m_times[m_lastFilteredReportedIndex+i].GetSeconds(), m_values[m_lastFilteredReportedIndex+i]);
+      m_filteredData(m_times[i].GetSeconds(), m_values[i]);
     }
-    m_lastFilteredReportedIndex += i;
   }
 }