[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)
{
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))) ;
}

View File

@ -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))) ;
}

View File

@ -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) ;
}

View File

@ -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<pkt_id_t, ss_t> 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<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()) ;
// Update the average & variance with the new value:
update_average(ss_dbm) ;
}
@ -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)
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<pkt_id_t, ss_t>::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<double>(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<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 ;
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<int_fast16_t>(i->second)
<< '(' << i->first << ')' ;
}
os << " [AVG=" << m.average_ss << "]" ;
os << " [AVG=" << m.average_dbm << "]" ;
return os ;
}

View File

@ -25,39 +25,54 @@ protected:
AccessPoint *ap ;
/// List of signal strengths captured (in dBm)
std::map<pkt_id_t, ss_t> 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<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):
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<pkt_id_t, ss_t> &_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)) ;
}

View File

@ -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() ;

View File

@ -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<int> 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 ;

View File

@ -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