Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 2009 Stefaan Lippens <soxofaan@gmail.com> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #include "RunningStatistics.h" 00020 #include "../common_source.h" 00021 00022 #include <string> 00023 #include <sstream> 00024 00025 using namespace std; 00026 using namespace Marsyas; 00027 00028 RunningStatistics::RunningStatistics(mrs_string name) : 00029 MarSystem("RunningStatistics", name) 00030 { 00032 addControls(); 00033 } 00034 00035 RunningStatistics::RunningStatistics(const RunningStatistics& a) : 00036 MarSystem(a) 00037 { 00040 ctrl_enable_mean_ = getctrl("mrs_bool/enableMean"); 00041 ctrl_enable_stddev_ = getctrl("mrs_bool/enableStddev"); 00042 ctrl_enable_skewness_ = getctrl("mrs_bool/enableSkewness"); 00043 ctrl_clear_ = getctrl("mrs_bool/clear"); 00044 ctrl_clearPerTick_ = getctrl("mrs_bool/clearPerTick"); 00045 00046 } 00047 00048 RunningStatistics::~RunningStatistics() 00049 { 00050 } 00051 00052 MarSystem* 00053 RunningStatistics::clone() const 00054 { 00055 return new RunningStatistics(*this); 00056 } 00057 00058 void RunningStatistics::addControls() 00059 { 00060 addctrl("mrs_bool/enableMean", true, ctrl_enable_mean_); 00061 ctrl_enable_mean_->setState(true); 00062 addctrl("mrs_bool/enableStddev", true, ctrl_enable_stddev_); 00063 ctrl_enable_stddev_->setState(true); 00064 addctrl("mrs_bool/enableSkewness", false, ctrl_enable_skewness_); 00065 ctrl_enable_skewness_->setState(true); 00066 addctrl("mrs_bool/clear", false, ctrl_clear_); 00067 addctrl("mrs_bool/clearPerTick", false, ctrl_clearPerTick_); 00068 00069 } 00070 00071 void RunningStatistics::myUpdate(MarControlPtr sender) 00072 { 00073 (void) sender; //suppress warning of unused parameter(s) 00074 MRSDIAG("RunningStatistics.cpp - RunningStatistics:myUpdate"); 00075 00076 // Update caches of control values. 00077 enable_mean_ = ctrl_enable_mean_->to<mrs_bool> (); 00078 enable_stddev_ = ctrl_enable_stddev_->to<mrs_bool> (); 00079 enable_skewsness_ = ctrl_enable_skewness_->to<mrs_bool> (); 00080 00081 mrs_natural fanout = (mrs_natural) enable_mean_ 00082 + (mrs_natural) enable_stddev_ + (mrs_natural) enable_skewsness_; 00083 00084 // Set the output slice format and rate based on the 00085 // input slice format and rate. 00086 ctrl_onSamples_->setValue((mrs_natural) 1, NOUPDATE); 00087 onObservations_ = fanout * ctrl_inObservations_->to<mrs_natural> (); 00088 ctrl_onObservations_->setValue(onObservations_, NOUPDATE); 00089 ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE); 00090 00091 // Update the observation names. 00092 mrs_string inObsNames = ctrl_inObsNames_->to<mrs_string> (); 00093 mrs_string onObsNames(""); 00094 if (enable_mean_) 00095 { 00096 onObsNames += obsNamesAddPrefix(inObsNames, "RunningMean_"); 00097 } 00098 if (enable_stddev_) 00099 { 00100 onObsNames += obsNamesAddPrefix(inObsNames, "RunningStddev_"); 00101 } 00102 if (enable_skewsness_) 00103 { 00104 onObsNames += obsNamesAddPrefix(inObsNames, "RunningSkewness_"); 00105 } 00106 00107 ctrl_onObsNames_->setValue(onObsNames, NOUPDATE); 00108 00109 // Allocate and initialize the buffers and counters. 00110 sumxBuffer_.stretch(onObservations_, 1); 00111 sumx2Buffer_.stretch(onObservations_, 1); 00112 sumx3Buffer_.stretch(onObservations_, 1); 00113 // Initialize the buffers. 00114 clear(); 00115 } 00116 00117 void RunningStatistics::clear(void) { 00118 sumxBuffer_.setval(0.0); 00119 sumx2Buffer_.setval(0.0); 00120 sumx3Buffer_.setval(0.0); 00121 samplecounter_ = 0; 00122 // We just cleared the internal buffers, so we should reset the clear control. 00123 ctrl_clear_->setValue(false, NOUPDATE); 00124 } 00125 00126 void RunningStatistics::myProcess(realvec& in, realvec& out) 00127 { 00128 mrs_natural o,t; 00129 if (ctrl_clear_->to<mrs_bool>() || ctrl_clearPerTick_->to<mrs_bool>()) { 00130 clear(); 00131 } 00132 00133 // Update the sample counter. 00134 samplecounter_ += inSamples_; 00135 // Temporary variables for mean, stddev, ... 00136 mrs_real mean, var, stddev, skewness; 00137 // Temporary helper variable. 00138 mrs_real tmp; 00139 00140 // Precalculate offsets where to put stddev and skewness in output. 00141 mrs_natural o_offset_stdev = (mrs_natural) enable_mean_ * inObservations_; 00142 mrs_natural o_offset_skewness = o_offset_stdev 00143 + (mrs_natural) enable_stddev_ * inObservations_; 00144 00145 for (o = 0; o < inObservations_; o++) 00146 { 00147 // Gather the sums. 00148 for (t = 0; t < inSamples_; t++) 00149 { 00150 sumxBuffer_(o, 0) += in(o, t); 00151 sumx2Buffer_(o, 0) += (tmp = in(o, t) * in(o, t)); 00152 sumx3Buffer_(o, 0) += (tmp * in(o, t)); 00153 } 00154 // Calculate the statistics. 00155 mean = sumxBuffer_(o, 0) / samplecounter_; 00156 var = sumx2Buffer_(o, 0) / samplecounter_ - mean * mean; 00157 stddev = sqrt(var); 00158 skewness = (sumx3Buffer_(o, 0) / samplecounter_ - 3 * mean * var - mean 00159 * mean * mean); 00160 skewness = var > 0.0 ? skewness / (var * stddev) : 0.0; 00161 00162 // Store in output slice. 00163 if (enable_mean_) 00164 { 00165 out(o, 0) = mean; 00166 } 00167 if (enable_stddev_) 00168 { 00169 out(o + o_offset_stdev, 0) = stddev; 00170 } 00171 if (enable_skewsness_) 00172 { 00173 out(o + o_offset_skewness, 0) = skewness; 00174 } 00175 00176 } 00177 }