aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.cpp12
-rw-r--r--main.h147
-rw-r--r--main_view.qml17
-rw-r--r--projectionobserver.cpp61
-rw-r--r--projectionobserver.h14
5 files changed, 138 insertions, 113 deletions
diff --git a/main.cpp b/main.cpp
index 3add8e7..febeea2 100644
--- a/main.cpp
+++ b/main.cpp
@@ -162,18 +162,22 @@ int main(int argc, char **argv)
QObject::connect(m->rpPlot, SIGNAL(scaleChanged(const LinearScale<float> &, const LinearScale<float> &)),
m->cpPlot, SLOT(setScale(const LinearScale<float> &, const LinearScale<float> &)));
+ QObject::connect(m->splat, SIGNAL(colorScaleChanged(const ColorScale &)),
+ m->colormap, SLOT(setColorScale(const ColorScale &)));
+
m->barChart = engine.rootObjects()[0]->findChild<BarChart *>("barChart");
m->barChart->setAcceptedMouseButtons(Qt::LeftButton);
m->setBarChartColorScale(Main::ColorScaleContinuous);
ProjectionObserver projectionObserver(X, cpIndices);
+ m->projectionObserver = &projectionObserver;
QObject::connect(&interactionHandler, SIGNAL(cpChanged(const arma::mat &)),
- &projectionObserver, SLOT(setMap(const arma::mat &)));
- QObject::connect(&projectionObserver, SIGNAL(mapChanged(const arma::vec &)),
+ m->projectionObserver, SLOT(setMap(const arma::mat &)));
+ QObject::connect(m->projectionObserver, SIGNAL(valuesChanged(const arma::vec &)),
m->rpPlot, SLOT(setColorData(const arma::vec &)));
- QObject::connect(&projectionObserver, SIGNAL(mapChanged(const arma::vec &)),
+ QObject::connect(m->projectionObserver, SIGNAL(valuesChanged(const arma::vec &)),
m->splat, SLOT(setValues(const arma::vec &)));
- QObject::connect(&projectionObserver, SIGNAL(mapChanged(const arma::vec &)),
+ QObject::connect(m->projectionObserver, SIGNAL(valuesChanged(const arma::vec &)),
m->barChart, SLOT(setValues(const arma::vec &)));
//history->addHistoryItem(Ys);
diff --git a/main.h b/main.h
index 69c58f0..f3bcb66 100644
--- a/main.h
+++ b/main.h
@@ -4,17 +4,18 @@
#include <QObject>
#include <armadillo>
-#include "colorscale.h"
-#include "continuouscolorscale.h"
-
#include "barchart.h"
#include "colormap.h"
+#include "colorscale.h"
+#include "continuouscolorscale.h"
+#include "projectionobserver.h"
#include "scatterplot.h"
#include "voronoisplat.h"
class Main : public QObject
{
Q_OBJECT
+ Q_ENUMS(ObserverType)
Q_ENUMS(ColorScaleType)
public:
static Main *instance() {
@@ -57,6 +58,16 @@ public:
arma::mat X() const { return m_dataset.cols(0, m_dataset.n_cols - 2); }
arma::vec labels() const { return m_dataset.col(m_dataset.n_cols - 1); }
+ enum ObserverType {
+ ObserverCurrent = ProjectionObserver::OBSERVER_CURRENT,
+ ObserverDiffPrevious = ProjectionObserver::OBSERVER_DIFF_PREVIOUS,
+ ObserverDiffOriginal = ProjectionObserver::OBSERVER_DIFF_ORIGINAL
+ };
+
+ Q_INVOKABLE bool setObserverType(ObserverType observerType) {
+ return projectionObserver->setType((int) observerType);
+ }
+
enum ColorScaleType {
ColorScaleCategorical,
ColorScaleContinuous,
@@ -64,94 +75,29 @@ public:
ColorScaleRainbow
};
- ColorScale *COLOR_SCALE_CATEGORICAL;
- ColorScale *COLOR_SCALE_CONTINUOUS;
- ColorScale *COLOR_SCALE_DIVERGENT;
- ColorScale *COLOR_SCALE_RAINBOW;
+ ColorScale COLOR_SCALE_CATEGORICAL;
+ ColorScale COLOR_SCALE_CONTINUOUS;
+ ColorScale COLOR_SCALE_DIVERGENT;
+ ColorScale COLOR_SCALE_RAINBOW;
Q_INVOKABLE void setCPPlotColorScale(ColorScaleType colorScaleType) {
- switch (colorScaleType) {
- case ColorScaleCategorical:
- cpPlot->setColorScale(*COLOR_SCALE_CATEGORICAL);
- break;
- case ColorScaleContinuous:
- cpPlot->setColorScale(*COLOR_SCALE_CONTINUOUS);
- break;
- case ColorScaleDivergent:
- cpPlot->setColorScale(*COLOR_SCALE_DIVERGENT);
- break;
- case ColorScaleRainbow:
- cpPlot->setColorScale(*COLOR_SCALE_RAINBOW);
- break;
- }
+ cpPlot->setColorScale(getColorScale(colorScaleType));
}
Q_INVOKABLE void setRPPlotColorScale(ColorScaleType colorScaleType) {
- switch (colorScaleType) {
- case ColorScaleCategorical:
- rpPlot->setColorScale(*COLOR_SCALE_CATEGORICAL);
- break;
- case ColorScaleContinuous:
- rpPlot->setColorScale(*COLOR_SCALE_CONTINUOUS);
- break;
- case ColorScaleDivergent:
- rpPlot->setColorScale(*COLOR_SCALE_DIVERGENT);
- break;
- case ColorScaleRainbow:
- rpPlot->setColorScale(*COLOR_SCALE_RAINBOW);
- break;
- }
+ rpPlot->setColorScale(getColorScale(colorScaleType));
}
Q_INVOKABLE void setColormapColorScale(ColorScaleType colorScaleType) {
- switch (colorScaleType) {
- case ColorScaleCategorical:
- colormap->setColorScale(*COLOR_SCALE_CATEGORICAL);
- break;
- case ColorScaleContinuous:
- colormap->setColorScale(*COLOR_SCALE_CONTINUOUS);
- break;
- case ColorScaleDivergent:
- colormap->setColorScale(*COLOR_SCALE_DIVERGENT);
- break;
- case ColorScaleRainbow:
- colormap->setColorScale(*COLOR_SCALE_RAINBOW);
- break;
- }
+ colormap->setColorScale(getColorScale(colorScaleType));
}
Q_INVOKABLE void setBarChartColorScale(ColorScaleType colorScaleType) {
- switch (colorScaleType) {
- case ColorScaleCategorical:
- barChart->setColorScale(*COLOR_SCALE_CATEGORICAL);
- break;
- case ColorScaleContinuous:
- barChart->setColorScale(*COLOR_SCALE_CONTINUOUS);
- break;
- case ColorScaleDivergent:
- barChart->setColorScale(*COLOR_SCALE_DIVERGENT);
- break;
- case ColorScaleRainbow:
- barChart->setColorScale(*COLOR_SCALE_RAINBOW);
- break;
- }
+ barChart->setColorScale(getColorScale(colorScaleType));
}
Q_INVOKABLE void setSplatColorScale(ColorScaleType colorScaleType) {
- switch (colorScaleType) {
- case ColorScaleCategorical:
- splat->setColorScale(*COLOR_SCALE_CATEGORICAL);
- break;
- case ColorScaleContinuous:
- splat->setColorScale(*COLOR_SCALE_CONTINUOUS);
- break;
- case ColorScaleDivergent:
- splat->setColorScale(*COLOR_SCALE_DIVERGENT);
- break;
- case ColorScaleRainbow:
- splat->setColorScale(*COLOR_SCALE_RAINBOW);
- break;
- }
+ splat->setColorScale(getColorScale(colorScaleType));
}
BarChart *barChart;
@@ -159,6 +105,8 @@ public:
Scatterplot *cpPlot, *rpPlot;
VoronoiSplat *splat;
+ ProjectionObserver *projectionObserver;
+
public slots:
void setCPIndices(const arma::uvec &indices) { m_cpIndices = indices; }
void setCP(const arma::mat &cp) {
@@ -173,34 +121,35 @@ public slots:
private:
Main(QObject *parent = 0)
: QObject(parent)
+ , COLOR_SCALE_CATEGORICAL{
+ QColor("#1f77b4"), QColor("#ff7f0e"), QColor("#2ca02c"),
+ QColor("#d62728"), QColor("#9467bd"), QColor("#8c564b"),
+ QColor("#e377c2"), QColor("#17becf"), QColor("#7f7f7f"),
+ }
+ , COLOR_SCALE_CONTINUOUS{ContinuousColorScale::builtin(ContinuousColorScale::HEATED_OBJECTS)}
+ , COLOR_SCALE_DIVERGENT{ContinuousColorScale::builtin(ContinuousColorScale::RED_GRAY_BLUE)}
+ , COLOR_SCALE_RAINBOW{ContinuousColorScale::builtin(ContinuousColorScale::RAINBOW)}
, barChart(0)
, cpPlot(0)
, rpPlot(0)
, splat(0)
{
- COLOR_SCALE_CATEGORICAL = new ColorScale{
- QColor("#1f77b4"),
- QColor("#ff7f0e"),
- QColor("#2ca02c"),
- QColor("#d62728"),
- QColor("#9467bd"),
- QColor("#8c564b"),
- QColor("#e377c2"),
- QColor("#17becf"),
- QColor("#7f7f7f"),
- };
- COLOR_SCALE_CONTINUOUS =
- new ColorScale{ContinuousColorScale::builtin(ContinuousColorScale::HEATED_OBJECTS)};
- COLOR_SCALE_DIVERGENT =
- new ColorScale{ContinuousColorScale::builtin(ContinuousColorScale::RED_GRAY_BLUE)};
- COLOR_SCALE_RAINBOW =
- new ColorScale{ContinuousColorScale::builtin(ContinuousColorScale::RAINBOW)};
}
- ~Main() {
- delete COLOR_SCALE_CATEGORICAL;
- delete COLOR_SCALE_CONTINUOUS;
- delete COLOR_SCALE_DIVERGENT;
- delete COLOR_SCALE_RAINBOW;
+ ~Main() {}
+
+ ColorScale &getColorScale(ColorScaleType colorScaleType) {
+ switch (colorScaleType) {
+ case ColorScaleCategorical:
+ return COLOR_SCALE_CATEGORICAL;
+ case ColorScaleContinuous:
+ return COLOR_SCALE_CONTINUOUS;
+ case ColorScaleDivergent:
+ return COLOR_SCALE_DIVERGENT;
+ case ColorScaleRainbow:
+ // fall-through
+ default:
+ return COLOR_SCALE_RAINBOW;
+ }
}
arma::mat m_dataset, m_cp;
diff --git a/main_view.qml b/main_view.qml
index e2f27d9..561c07d 100644
--- a/main_view.qml
+++ b/main_view.qml
@@ -311,7 +311,6 @@ ApplicationWindow {
id: splatColormapCombo
model: colormapModel
onActivated: {
- Main.setColormapColorScale(model.get(index).value);
Main.setSplatColorScale(model.get(index).value);
}
}
@@ -382,17 +381,33 @@ ApplicationWindow {
ExclusiveGroup { id: wrtMetricsGroup }
RadioButton {
+ id: currentMetricRadioButton
text: "Current"
exclusiveGroup: wrtMetricsGroup
checked: true
+ onClicked: Main.setObserverType(Main.ObserverCurrent)
}
RadioButton {
+ id: diffPreviousMetricRadioButton
text: "Diff. to previous"
exclusiveGroup: wrtMetricsGroup
+ onClicked: {
+ if (!Main.setObserverType(Main.ObserverDiffPrevious)) {
+ this.checked = false;
+ currentMetricRadioButton.checked = true;
+ }
+ }
}
RadioButton {
+ id: diffOriginalMetricRadioButton
text: "Diff. to original"
exclusiveGroup: wrtMetricsGroup
+ onClicked: {
+ if (!Main.setObserverType(Main.ObserverDiffOriginal)) {
+ this.checked = false;
+ currentMetricRadioButton.checked = true;
+ }
+ }
}
}
}
diff --git a/projectionobserver.cpp b/projectionobserver.cpp
index 781aba9..e500755 100644
--- a/projectionobserver.cpp
+++ b/projectionobserver.cpp
@@ -2,8 +2,12 @@
#include <cmath>
+#include <QDebug>
+
#include "mp.h"
+static const float EPSILON = 1e-6f;
+
static void aggregatedError(const arma::mat &distX, const arma::mat &distY, arma::vec &v)
{
double maxX = distX.max();
@@ -17,37 +21,82 @@ static void aggregatedError(const arma::mat &distX, const arma::mat &distY, arma
continue;
}
- v[i] += fabs(distY(i, j) / maxY - distX(i, j) / maxX);
+ float diff = fabs(distY(i, j) / maxY - distX(i, j) / maxX);
+ if (diff < EPSILON) {
+ continue;
+ }
+
+ v[i] += diff;
}
}
}
ProjectionObserver::ProjectionObserver(const arma::mat &X,
const arma::uvec &cpIndices)
- : m_X(X)
+ : m_type(OBSERVER_CURRENT)
+ , m_X(X)
, m_cpIndices(cpIndices)
{
m_distX = mp::dist(m_X);
m_values.set_size(m_X.n_rows);
}
+bool ProjectionObserver::setType(int type)
+{
+ if (m_type == type) {
+ return true;
+ }
+
+ if (type != OBSERVER_DIFF_PREVIOUS || m_prevValues.n_elem != 0) {
+ m_type = type;
+ return emitValuesChanged();
+ }
+
+ return false;
+}
+
void ProjectionObserver::setMap(const arma::mat &Y)
{
// update previous map
if (m_prevY.n_elem == 0 && m_Y.n_elem > 0) {
m_prevY = m_Y;
- m_distPrevY = m_distY;
+ m_prevDistY = m_distY;
+ m_prevValues = m_values;
}
m_Y = Y;
m_distY = mp::dist(Y);
+ aggregatedError(m_distX, m_distY, m_values);
// method called for the first time; set original Y
if (m_origY.n_elem == 0) {
m_origY = m_Y;
- m_distOrigY = m_distY;
+ m_origDistY = m_distY;
+ m_origValues = m_values;
}
- aggregatedError(m_distX, m_distY, m_values);
- emit mapChanged(m_values);
+ emitValuesChanged();
+}
+
+bool ProjectionObserver::emitValuesChanged() const
+{
+ switch (m_type) {
+ case OBSERVER_CURRENT:
+ emit valuesChanged(m_values);
+ return true;
+ case OBSERVER_DIFF_PREVIOUS:
+ if (m_prevValues.n_elem > 0) {
+ emit valuesChanged(m_values - m_prevValues);
+ return true;
+ }
+ return false;
+ case OBSERVER_DIFF_ORIGINAL:
+ if (m_origValues.n_elem > 0) {
+ emit valuesChanged(m_values - m_origValues);
+ return true;
+ }
+ return false;
+ default:
+ return false;
+ }
}
diff --git a/projectionobserver.h b/projectionobserver.h
index 5ac6988..1c305bd 100644
--- a/projectionobserver.h
+++ b/projectionobserver.h
@@ -10,21 +10,29 @@ class ProjectionObserver : public QObject
{
Q_OBJECT
public:
+ static const int OBSERVER_CURRENT = 0;
+ static const int OBSERVER_DIFF_PREVIOUS = 1;
+ static const int OBSERVER_DIFF_ORIGINAL = 2;
+
ProjectionObserver(const arma::mat &X, const arma::uvec &cpIndices);
signals:
- void mapChanged(const arma::vec &values) const;
+ void valuesChanged(const arma::vec &values) const;
public slots:
void setMap(const arma::mat &Y);
+ bool setType(int type);
private:
+ bool emitValuesChanged() const;
+
+ int m_type;
arma::mat m_X, m_Y, m_origY, m_prevY;
- arma::mat m_distX, m_distY, m_distOrigY, m_distPrevY;
+ arma::mat m_distX, m_distY, m_origDistY, m_prevDistY;
arma::uvec m_cpIndices;
// TODO: one per implemented measure
- arma::vec m_values;
+ arma::vec m_values, m_prevValues, m_origValues;
};
#endif // PROJECTIONOBSERVER_H