aboutsummaryrefslogtreecommitdiff
path: root/projectionobserver.cpp
diff options
context:
space:
mode:
authorSamuel Fadel <samuelfadel@gmail.com>2016-01-28 15:52:39 +0100
committerSamuel Fadel <samuelfadel@gmail.com>2016-01-28 15:55:07 +0100
commitff10df2f8bfc71afe8637eec67d11d6ce87b673b (patch)
tree3e7ba65d7c2cff27a2d13511f25857a4e5326e1d /projectionobserver.cpp
parent5404374a510b4c09bd4d38331a1255583abb28d4 (diff)
ProjectionObsever now responds to selection changes.
* Scatterplot: small fix to selection updates * ProjectionObserver: whenever CP selection changes, compute influence of CPs over all RPs. Whenever RP selection changes, compute influence of RPs by all CPs. * ProjectionObserver: with empty selections, go back to normal mode
Diffstat (limited to 'projectionobserver.cpp')
-rw-r--r--projectionobserver.cpp106
1 files changed, 92 insertions, 14 deletions
diff --git a/projectionobserver.cpp b/projectionobserver.cpp
index 395110c..1293128 100644
--- a/projectionobserver.cpp
+++ b/projectionobserver.cpp
@@ -38,27 +38,37 @@ ProjectionObserver::ProjectionObserver(const arma::mat &X,
, m_X(X)
, m_cpIndices(cpIndices)
, m_rpIndices(X.n_rows - cpIndices.n_elem)
+ , m_cpSelectionEmpty(true)
+ , m_rpSelectionEmpty(true)
{
m_distX = mp::dist(m_X);
m_values.set_size(m_X.n_rows);
- NumericRange<unsigned long long> range(0, m_X.n_rows);
+ NumericRange<arma::uword> range(0, m_X.n_rows);
std::set_symmetric_difference(range.cbegin(), range.cend(),
m_cpIndices.cbegin(), m_cpIndices.cend(), m_rpIndices.begin());
+
+ computeAlphas();
}
-bool ProjectionObserver::setType(int type)
+void ProjectionObserver::computeAlphas()
{
- if (m_type == type) {
- return true;
- }
+ m_influences.set_size(m_X.n_rows);
+ m_alphas.set_size(m_rpIndices.n_elem, m_cpIndices.n_elem);
+
+ for (arma::uword i = 0; i < m_rpIndices.n_elem; i++) {
+ double sum = 0;
+ const arma::rowvec &x = m_X.row(m_rpIndices[i]);
+ for (arma::uword j = 0; j < m_cpIndices.n_elem; j++) {
+ double norm = arma::norm(x - m_X.row(m_cpIndices[j]));
+ m_alphas(i, j) = 1.0f / std::max(norm * norm, 1e-6);
+ sum += m_alphas(i, j);
+ }
- if (type != OBSERVER_DIFF_PREVIOUS || m_prevValues.n_elem != 0) {
- m_type = type;
- return emitValuesChanged();
+ for (arma::uword j = 0; j < m_cpIndices.n_elem; j++) {
+ m_alphas(i, j) /= sum;
+ }
}
-
- return false;
}
void ProjectionObserver::setMap(const arma::mat &Y)
@@ -81,21 +91,90 @@ void ProjectionObserver::setMap(const arma::mat &Y)
m_origValues = m_values;
}
- emitValuesChanged();
+ if (m_cpSelectionEmpty && m_rpSelectionEmpty) {
+ emitValuesChanged();
+ }
+}
+
+bool ProjectionObserver::setType(int type)
+{
+ if (m_type == type) {
+ return true;
+ }
+
+ if (type != OBSERVER_DIFF_PREVIOUS || m_prevValues.n_elem != 0) {
+ m_type = type;
+ if (m_cpSelectionEmpty && m_rpSelectionEmpty) {
+ return emitValuesChanged();
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+void ProjectionObserver::setCPSelection(const std::vector<bool> &cpSelection)
+{
+ m_cpSelection.clear();
+ for (int i = 0; i < cpSelection.size(); i++) {
+ if (cpSelection[i]) {
+ m_cpSelection.push_back(i);
+ }
+ }
+ m_cpSelectionEmpty = m_cpSelection.empty();
+
+ if (!m_cpSelectionEmpty) {
+ // compute the influence of CP selection on each RP
+ for (arma::uword rp = 0; rp < m_rpIndices.n_elem; rp++) {
+ m_influences[m_rpIndices[rp]] = 0;
+ const arma::rowvec &row = m_alphas.row(rp);
+ for (auto cp: m_cpSelection) {
+ m_influences[m_rpIndices[rp]] += row[cp];
+ }
+ }
+
+ emit rpValuesChanged(m_influences(m_rpIndices));
+ } else {
+ emitValuesChanged();
+ }
+}
+
+void ProjectionObserver::setRPSelection(const std::vector<bool> &rpSelection)
+{
+ m_rpSelection.clear();
+ for (int i = 0; i < rpSelection.size(); i++) {
+ if (rpSelection[i]) {
+ m_rpSelection.push_back(i);
+ }
+ }
+ m_rpSelectionEmpty = m_rpSelection.empty();
+
+ if (!m_rpSelectionEmpty) {
+ // compute how influent is each CP on RP selection
+ for (arma::uword cp = 0; cp < m_cpIndices.n_elem; cp++) {
+ m_influences[m_cpIndices[cp]] = 0;
+ for (auto rp: m_rpSelection) {
+ m_influences[m_cpIndices[cp]] += m_alphas(rp, cp);
+ }
+ }
+
+ emit cpValuesChanged(m_influences(m_cpIndices));
+ } else {
+ emit cpValuesChanged(arma::vec());
+ }
}
bool ProjectionObserver::emitValuesChanged() const
{
switch (m_type) {
case OBSERVER_CURRENT:
- emit cpValuesChanged(m_values(m_cpIndices));
emit rpValuesChanged(m_values(m_rpIndices));
emit valuesChanged(m_values);
return true;
case OBSERVER_DIFF_PREVIOUS:
if (m_prevValues.n_elem > 0) {
arma::vec diff = m_values - m_prevValues;
- emit cpValuesChanged(diff(m_cpIndices));
emit rpValuesChanged(diff(m_rpIndices));
emit valuesChanged(diff);
return true;
@@ -104,7 +183,6 @@ bool ProjectionObserver::emitValuesChanged() const
case OBSERVER_DIFF_ORIGINAL:
if (m_origValues.n_elem > 0) {
arma::vec diff = m_values - m_origValues;
- emit cpValuesChanged(diff(m_cpIndices));
emit rpValuesChanged(diff(m_rpIndices));
emit valuesChanged(diff);
return true;