[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.
This commit is contained in:
Matteo Cypriani 2012-02-03 11:55:24 +01:00
parent 9f8c85d9c7
commit 24622e4c3a
8 changed files with 86 additions and 56 deletions

View File

@ -24,9 +24,9 @@ Result FBCM::compute(const Request &_request)
float FBCM::estimate_distance(const Measurement &measurement) float FBCM::estimate_distance(const Measurement &measurement)
{ {
double constant_term = make_constant_term(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() ; const AccessPoint *ap = measurement.get_ap() ;
return pow(10, (constant_term - average_ss) / return pow(10, (constant_term - average_dbm) /
(10 * friis_index(ap))) ; (10 * friis_index(ap))) ;
} }

View File

@ -32,9 +32,9 @@ Result FRBHMBasic::compute(const Request &_request)
float FRBHMBasic::estimate_distance(const Measurement &measurement) float FRBHMBasic::estimate_distance(const Measurement &measurement)
{ {
double constant_term = make_constant_term(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() ; const AccessPoint *ap = measurement.get_ap() ;
return pow(10, (constant_term - average_ss) / return pow(10, (constant_term - average_dbm) /
(10 * friis_index(ap))) ; (10 * friis_index(ap))) ;
} }

View File

@ -13,6 +13,6 @@ float InterlinkNetworks::
estimate_distance(const Measurement &measurement) estimate_distance(const Measurement &measurement)
{ {
double constant_term = make_constant_term(measurement) ; double constant_term = make_constant_term(measurement) ;
const float &average_ss = measurement.get_average_ss() ; const float &average_dbm = measurement.get_average_dbm() ;
return pow(10, (constant_term - average_ss) / 35) ; return pow(10, (constant_term - average_dbm) / 35) ;
} }

View File

@ -39,8 +39,6 @@ Measurement::~Measurement()
void Measurement:: void Measurement::
add_ss(const pkt_id_t packet_id, const ss_t ss_dbm) 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: // Add the new value (in dBm) along with the packet identifier:
pair<pkt_id_t, ss_t> packet(make_pair(packet_id, ss_dbm)) ; pair<pkt_id_t, ss_t> packet(make_pair(packet_id, ss_dbm)) ;
if (! ss_list.insert(packet).second) if (! ss_list.insert(packet).second)
@ -51,12 +49,8 @@ add_ss(const pkt_id_t packet_id, const ss_t ss_dbm)
return ; return ;
} }
// Update the average with the new value // Update the average & variance with the new value:
double total_ss_mwatts = update_average(ss_dbm) ;
pow(10, static_cast<double>(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()) ;
} }
@ -74,7 +68,7 @@ add_ss_list(const map<pkt_id_t, ss_t> &_ss_list)
i = _ss_list.begin() ; i != _ss_list.end() ; ++i) i = _ss_list.begin() ; i != _ss_list.end() ; ++i)
ss_list[i->first] = i->second ; 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. * - #ap is not deleted, only initialised to NULL.
* - #ss_list is cleared. * - #ss_list is cleared.
* - #average_ss is initialised to 0. * - #average_dbm, #average_mw and #variance are reset to 0.
*/ */
void Measurement::clear() void Measurement::clear()
{ {
ss_list.clear() ; ss_list.clear() ;
average_ss = 0 ; average_dbm = 0 ;
average_mw = 0 ;
variance = 0 ;
variance_m2 = 0 ;
ap = NULL ; ap = NULL ;
} }
@ -110,23 +107,33 @@ void Measurement::clear()
/* *** Operations *** */ /* *** Operations *** */
void Measurement::update_average_ss() void Measurement::recalculate_average()
{ {
if (ss_list.empty()) average_dbm = 0 ;
{ average_mw = 0 ;
average_ss = 0 ; variance = 0 ;
return ; variance_m2 = 0 ;
}
double total_ss_mwatts = 0 ;
for (map<pkt_id_t, ss_t>::const_iterator for (map<pkt_id_t, ss_t>::const_iterator
i = ss_list.begin() ; i != ss_list.end() ; ++i) i = ss_list.begin() ; i != ss_list.end() ; ++i)
// Add the current value in mW to the total update_average(i->second) ;
total_ss_mwatts += pow(10, static_cast<double>(i->second) / 10.0) ; }
// 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<double>(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 ; ap = m.ap ;
ss_list = m.ss_list ; 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 ; return *this ;
} }
@ -154,8 +164,7 @@ bool Measurement::operator==(const Measurement &m) const
return return
ap == m.ap && ap == m.ap &&
ss_list == m.ss_list && ss_list == m.ss_list ;
average_ss == m.average_ss ;
} }
@ -206,7 +215,7 @@ ostream &operator<<(ostream &os, const Measurement &m)
os << static_cast<int_fast16_t>(i->second) os << static_cast<int_fast16_t>(i->second)
<< '(' << i->first << ')' ; << '(' << i->first << ')' ;
} }
os << " [AVG=" << m.average_ss << "]" ; os << " [AVG=" << m.average_dbm << "]" ;
return os ; return os ;
} }

View File

@ -25,39 +25,54 @@ protected:
AccessPoint *ap ; AccessPoint *ap ;
/// List of signal strengths captured (in dBm) /// List of signal strengths captured (in dBm)
std::map<pkt_id_t, ss_t> ss_list ; std::map<pkt_id_t, ss_t> ss_list ;
/// Average of all signal strength captured (dBm) /// Average of all the captured signal strengths (dBm)
double average_ss ; 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 */ /** @name Operations */
//@{ //@{
/// Recalculates #average_ss from #ss_list /// Recalculates entirely the average and variance from #ss_list
void update_average_ss(void) ; void recalculate_average(void) ;
/// Update the average and variance with a new SS
void update_average(ss_t ss_dbm) ;
//@} //@}
public: public:
Measurement(const AccessPoint *_ap = NULL): Measurement(const AccessPoint *_ap = NULL):
ap(const_cast<AccessPoint*>(_ap)), average_ss(0) {} ap(const_cast<AccessPoint*>(_ap)), average_dbm(0),
average_mw(0), variance(0), variance_m2(0) {}
Measurement(const Measurement &source): Measurement(const Measurement &source):
ap(source.ap), ss_list(source.ss_list), 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) ; ~Measurement(void) ;
/** @name Read accessors */ /** @name Read accessors */
//@{ //@{
AccessPoint* get_ap() const ; AccessPoint* get_ap() const ;
double get_average_ss() const ; double get_average_dbm() const ;
double get_variance() const ;
int get_ss_list_size() const ; int get_ss_list_size() const ;
//@} //@}
/** @name Write accessors */ /** @name Write accessors */
//@{ //@{
void set_ap(const AccessPoint *_ap) ; 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) ; 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<pkt_id_t, ss_t> &_ss_list) ; void add_ss_list(const std::map<pkt_id_t, ss_t> &_ss_list) ;
/// Merges a given Measurement into the current Measurement /// Merges a given Measurement into the current Measurement
void merge(const Measurement &source) ; void merge(const Measurement &source) ;
@ -68,8 +83,8 @@ public:
//@{ //@{
/// Computes the distance to another Measurement in SS space /// Computes the distance to another Measurement in SS space
float ss_square_distance(const Measurement &source) const ; float ss_square_distance(const Measurement &source) const ;
/// Computes the distance to another SS value /// Computes the distance to another SS value (in dBm)
float ss_square_distance(const float &ss) const ; float ss_square_distance(const float &ss_dbm) const ;
//@} //@}
/** @name Operators */ /** @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:: inline float Measurement::
ss_square_distance(const Measurement &source) const 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)) ;
} }

View File

@ -44,7 +44,7 @@ average_measurements(const std::string &mac_transmitter) const
measurements.begin() ; measurements.begin() ;
i != measurements.end() ; ++i) i != measurements.end() ; ++i)
{ {
avg += i->second.get_average_ss() ; avg += i->second.get_average_dbm() ;
++n_ss ; ++n_ss ;
} }
@ -257,7 +257,7 @@ float ReferencePoint::friis_indexes_for_ap(
measurements.find(ap_mac) ; measurements.find(ap_mac) ;
if (measurement != measurements.end()) if (measurement != measurements.end())
{ {
double ss = measurement->second.get_average_ss() ; double ss = measurement->second.get_average_dbm() ;
assert((*request)->get_mobile()) ; assert((*request)->get_mobile()) ;
float mobile_gain = float mobile_gain =
(*request)->get_mobile()->get_antenna_gain() ; (*request)->get_mobile()->get_antenna_gain() ;

View File

@ -30,7 +30,7 @@ public:
Measurement m1(&ap1, vi1) ; Measurement m1(&ap1, vi1) ;
TS_ASSERT_EQUALS(m1.get_ap(), &ap1) ; TS_ASSERT_EQUALS(m1.get_ap(), &ap1) ;
TS_ASSERT_EQUALS(m1.get_ss_list(), vi1) ; 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 // Write & read accessors
AccessPoint ap2 ; AccessPoint ap2 ;
@ -61,7 +61,7 @@ public:
* Back to dBm: * Back to dBm:
* 0.0028148 mW = -25.505481 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() ; m1.clear() ;
std::vector<int> vi2 ; std::vector<int> vi2 ;
@ -69,7 +69,7 @@ public:
vi2.push_back(-1) ; vi2.push_back(-1) ;
m1.set_ss_list(vi2) ; m1.set_ss_list(vi2) ;
TS_ASSERT_EQUALS(m1.get_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() ; m1.clear() ;
Measurement m2 ; Measurement m2 ;

View File

@ -345,8 +345,8 @@ bool TestUtil::measurement_equals(const Measurement &first,
if (first == second) if (first == second)
return true ; return true ;
// Compare average_ss // Compare average_dbm
if (first.get_average_ss() != second.get_average_ss()) if (first.get_average_dbm() != second.get_average_dbm())
return false ; return false ;
// Compare ap values // Compare ap values