From 24622e4c3ab4a4de7fb3b30215ee3abb6ee4885b Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 3 Feb 2012 11:55:24 +0100 Subject: [PATCH] [Positioner] Measurement: compute the variance The variance is now computed along with the average. Measurement has three new attributes: - average_mw (average in mW), - variance, - variance_m2 (variable used for the variance calculation). In addition, average_ss has been renamed average_dbm (ditto for its getter). The computation method of the average has been changed to allow the computation of the variance simultaneously. --- owlps-positioner/src/fbcm.cc | 4 +- owlps-positioner/src/frbhmbasic.cc | 4 +- owlps-positioner/src/interlinknetworks.cc | 4 +- owlps-positioner/src/measurement.cc | 63 ++++++++++++---------- owlps-positioner/src/measurement.hh | 53 ++++++++++++------ owlps-positioner/src/referencepoint.cc | 4 +- owlps-positioner/tests/measurement_test.hh | 6 +-- owlps-positioner/tests/testutil.cc | 4 +- 8 files changed, 86 insertions(+), 56 deletions(-) diff --git a/owlps-positioner/src/fbcm.cc b/owlps-positioner/src/fbcm.cc index f5c74b8..b914d7b 100644 --- a/owlps-positioner/src/fbcm.cc +++ b/owlps-positioner/src/fbcm.cc @@ -24,9 +24,9 @@ Result FBCM::compute(const Request &_request) float FBCM::estimate_distance(const Measurement &measurement) { double constant_term = make_constant_term(measurement) ; - const float &average_ss = measurement.get_average_ss() ; + const float &average_dbm = measurement.get_average_dbm() ; const AccessPoint *ap = measurement.get_ap() ; - return pow(10, (constant_term - average_ss) / + return pow(10, (constant_term - average_dbm) / (10 * friis_index(ap))) ; } diff --git a/owlps-positioner/src/frbhmbasic.cc b/owlps-positioner/src/frbhmbasic.cc index 41aebec..0d3bb9f 100644 --- a/owlps-positioner/src/frbhmbasic.cc +++ b/owlps-positioner/src/frbhmbasic.cc @@ -32,9 +32,9 @@ Result FRBHMBasic::compute(const Request &_request) float FRBHMBasic::estimate_distance(const Measurement &measurement) { double constant_term = make_constant_term(measurement) ; - const float &average_ss = measurement.get_average_ss() ; + const float &average_dbm = measurement.get_average_dbm() ; const AccessPoint *ap = measurement.get_ap() ; - return pow(10, (constant_term - average_ss) / + return pow(10, (constant_term - average_dbm) / (10 * friis_index(ap))) ; } diff --git a/owlps-positioner/src/interlinknetworks.cc b/owlps-positioner/src/interlinknetworks.cc index f70b790..4dd0e12 100644 --- a/owlps-positioner/src/interlinknetworks.cc +++ b/owlps-positioner/src/interlinknetworks.cc @@ -13,6 +13,6 @@ float InterlinkNetworks:: estimate_distance(const Measurement &measurement) { double constant_term = make_constant_term(measurement) ; - const float &average_ss = measurement.get_average_ss() ; - return pow(10, (constant_term - average_ss) / 35) ; + const float &average_dbm = measurement.get_average_dbm() ; + return pow(10, (constant_term - average_dbm) / 35) ; } diff --git a/owlps-positioner/src/measurement.cc b/owlps-positioner/src/measurement.cc index 22a303b..a5f7854 100644 --- a/owlps-positioner/src/measurement.cc +++ b/owlps-positioner/src/measurement.cc @@ -39,8 +39,6 @@ Measurement::~Measurement() void Measurement:: add_ss(const pkt_id_t packet_id, const ss_t ss_dbm) { - unsigned int ss_list_size = ss_list.size() ; - // Add the new value (in dBm) along with the packet identifier: pair packet(make_pair(packet_id, ss_dbm)) ; if (! ss_list.insert(packet).second) @@ -51,12 +49,8 @@ add_ss(const pkt_id_t packet_id, const ss_t ss_dbm) return ; } - // Update the average with the new value - double total_ss_mwatts = - pow(10, static_cast(ss_dbm) / 10.0) + // New SS in mW - (ss_list_size * pow(10, average_ss / 10.0)) ; // Other values in mW - // Convert the average back in dBm: - average_ss = 10.0 * log10(total_ss_mwatts / ss_list.size()) ; + // Update the average & variance with the new value: + update_average(ss_dbm) ; } @@ -74,7 +68,7 @@ add_ss_list(const map &_ss_list) i = _ss_list.begin() ; i != _ss_list.end() ; ++i) ss_list[i->first] = i->second ; - update_average_ss() ; + recalculate_average() ; } @@ -96,12 +90,15 @@ void Measurement::merge(const Measurement &source) /** * - #ap is not deleted, only initialised to NULL. * - #ss_list is cleared. - * - #average_ss is initialised to 0. + * - #average_dbm, #average_mw and #variance are reset to 0. */ void Measurement::clear() { ss_list.clear() ; - average_ss = 0 ; + average_dbm = 0 ; + average_mw = 0 ; + variance = 0 ; + variance_m2 = 0 ; ap = NULL ; } @@ -110,23 +107,33 @@ void Measurement::clear() /* *** Operations *** */ -void Measurement::update_average_ss() +void Measurement::recalculate_average() { - if (ss_list.empty()) - { - average_ss = 0 ; - return ; - } - - double total_ss_mwatts = 0 ; + average_dbm = 0 ; + average_mw = 0 ; + variance = 0 ; + variance_m2 = 0 ; for (map::const_iterator i = ss_list.begin() ; i != ss_list.end() ; ++i) - // Add the current value in mW to the total - total_ss_mwatts += pow(10, static_cast(i->second) / 10.0) ; + update_average(i->second) ; +} - // Compute the average in mW and convert it to dBm - average_ss = 10 * log10(total_ss_mwatts / ss_list.size()) ; + +void Measurement::update_average(ss_t ss_dbm) +{ + // Convert the new SS in mW: + double ss_mw = pow(10, static_cast(ss_dbm) / 10.0) ; + + // Update the average: + double delta = ss_mw - average_mw ; + average_mw += delta / ss_list.size() ; + average_dbm = 10.0 * log10(average_mw) ; + + // Update the variance: + variance_m2 += delta * (ss_mw - average_mw) ; + if (ss_list.size() > 1) + variance = variance_m2 / (ss_list.size() - 1) ; } @@ -141,7 +148,10 @@ Measurement& Measurement::operator=(const Measurement &m) ap = m.ap ; ss_list = m.ss_list ; - average_ss = m.average_ss ; + average_dbm = m.average_dbm ; + average_mw = m.average_mw ; + variance = m.variance ; + variance_m2 = m.variance_m2 ; return *this ; } @@ -154,8 +164,7 @@ bool Measurement::operator==(const Measurement &m) const return ap == m.ap && - ss_list == m.ss_list && - average_ss == m.average_ss ; + ss_list == m.ss_list ; } @@ -206,7 +215,7 @@ ostream &operator<<(ostream &os, const Measurement &m) os << static_cast(i->second) << '(' << i->first << ')' ; } - os << " [AVG=" << m.average_ss << "]" ; + os << " [AVG=" << m.average_dbm << "]" ; return os ; } diff --git a/owlps-positioner/src/measurement.hh b/owlps-positioner/src/measurement.hh index dcd8d78..afad750 100644 --- a/owlps-positioner/src/measurement.hh +++ b/owlps-positioner/src/measurement.hh @@ -25,39 +25,54 @@ protected: AccessPoint *ap ; /// List of signal strengths captured (in dBm) std::map ss_list ; - /// Average of all signal strength captured (dBm) - double average_ss ; + /// Average of all the captured signal strengths (dBm) + double average_dbm ; + /// Average of all the captured signal strengths (mW) + double average_mw ; + /// Variance of all the captured signal strengths + double variance ; +private: + /// Intermediate variable used to compute the variance + double variance_m2 ; + + +protected: /** @name Operations */ //@{ - /// Recalculates #average_ss from #ss_list - void update_average_ss(void) ; + /// Recalculates entirely the average and variance from #ss_list + void recalculate_average(void) ; + /// Update the average and variance with a new SS + void update_average(ss_t ss_dbm) ; //@} public: Measurement(const AccessPoint *_ap = NULL): - ap(const_cast(_ap)), average_ss(0) {} + ap(const_cast(_ap)), average_dbm(0), + average_mw(0), variance(0), variance_m2(0) {} Measurement(const Measurement &source): ap(source.ap), ss_list(source.ss_list), - average_ss(source.average_ss) {} + average_dbm(source.average_dbm), average_mw(source.average_mw), + variance(source.variance), variance_m2(0) {} ~Measurement(void) ; /** @name Read accessors */ //@{ AccessPoint* get_ap() const ; - double get_average_ss() const ; + double get_average_dbm() const ; + double get_variance() const ; int get_ss_list_size() const ; //@} /** @name Write accessors */ //@{ void set_ap(const AccessPoint *_ap) ; - /// Adds a signal strength to #ss_list + /// Adds a signal strength (in dBm) to #ss_list void add_ss(const pkt_id_t packet_id, const ss_t ss_dbm) ; - /// Adds several signal strengths to #ss_list + /// Adds several signal strengths (in dBm) to #ss_list void add_ss_list(const std::map &_ss_list) ; /// Merges a given Measurement into the current Measurement void merge(const Measurement &source) ; @@ -68,8 +83,8 @@ public: //@{ /// Computes the distance to another Measurement in SS space float ss_square_distance(const Measurement &source) const ; - /// Computes the distance to another SS value - float ss_square_distance(const float &ss) const ; + /// Computes the distance to another SS value (in dBm) + float ss_square_distance(const float &ss_dbm) const ; //@} /** @name Operators */ @@ -101,9 +116,15 @@ inline AccessPoint* Measurement::get_ap() const } -inline double Measurement::get_average_ss() const +inline double Measurement::get_average_dbm() const { - return average_ss ; + return average_dbm ; +} + + +inline double Measurement::get_variance() const +{ + return variance ; } @@ -130,13 +151,13 @@ inline void Measurement::set_ap(const AccessPoint *_ap) inline float Measurement:: ss_square_distance(const Measurement &source) const { - return ss_square_distance(source.average_ss) ; + return ss_square_distance(source.average_dbm) ; } -inline float Measurement::ss_square_distance(const float &ss) const +inline float Measurement::ss_square_distance(const float &ss_dbm) const { - return ((ss - average_ss) * (ss - average_ss)) ; + return ((ss_dbm - average_dbm) * (ss_dbm - average_dbm)) ; } diff --git a/owlps-positioner/src/referencepoint.cc b/owlps-positioner/src/referencepoint.cc index 4e0f823..f9ea970 100644 --- a/owlps-positioner/src/referencepoint.cc +++ b/owlps-positioner/src/referencepoint.cc @@ -44,7 +44,7 @@ average_measurements(const std::string &mac_transmitter) const measurements.begin() ; i != measurements.end() ; ++i) { - avg += i->second.get_average_ss() ; + avg += i->second.get_average_dbm() ; ++n_ss ; } @@ -257,7 +257,7 @@ float ReferencePoint::friis_indexes_for_ap( measurements.find(ap_mac) ; if (measurement != measurements.end()) { - double ss = measurement->second.get_average_ss() ; + double ss = measurement->second.get_average_dbm() ; assert((*request)->get_mobile()) ; float mobile_gain = (*request)->get_mobile()->get_antenna_gain() ; diff --git a/owlps-positioner/tests/measurement_test.hh b/owlps-positioner/tests/measurement_test.hh index 0f44880..f36b4f0 100644 --- a/owlps-positioner/tests/measurement_test.hh +++ b/owlps-positioner/tests/measurement_test.hh @@ -30,7 +30,7 @@ public: Measurement m1(&ap1, vi1) ; TS_ASSERT_EQUALS(m1.get_ap(), &ap1) ; TS_ASSERT_EQUALS(m1.get_ss_list(), vi1) ; - TS_ASSERT_EQUALS(m1.get_average_ss(), 0) ; + TS_ASSERT_EQUALS(m1.get_average_dbm(), 0) ; // Write & read accessors AccessPoint ap2 ; @@ -61,7 +61,7 @@ public: * Back to dBm: * 0.0028148 mW = -25.505481 dBm */ - TS_ASSERT_DELTA(m1.get_average_ss(), -25.505481, 0.0001) ; + TS_ASSERT_DELTA(m1.get_average_dbm(), -25.505481, 0.0001) ; m1.clear() ; std::vector vi2 ; @@ -69,7 +69,7 @@ public: vi2.push_back(-1) ; m1.set_ss_list(vi2) ; TS_ASSERT_EQUALS(m1.get_ss_list(), vi2) ; - TS_ASSERT_DELTA(m1.get_average_ss(), -4.0102782, 0.0001) ; + TS_ASSERT_DELTA(m1.get_average_dbm(), -4.0102782, 0.0001) ; m1.clear() ; Measurement m2 ; diff --git a/owlps-positioner/tests/testutil.cc b/owlps-positioner/tests/testutil.cc index c94a465..b9b5bac 100644 --- a/owlps-positioner/tests/testutil.cc +++ b/owlps-positioner/tests/testutil.cc @@ -345,8 +345,8 @@ bool TestUtil::measurement_equals(const Measurement &first, if (first == second) return true ; - // Compare average_ss - if (first.get_average_ss() != second.get_average_ss()) + // Compare average_dbm + if (first.get_average_dbm() != second.get_average_dbm()) return false ; // Compare ap values