Permalink
Browse files

BarcodeTemplate::Project() now uses same parametrization as in the RI…

…VET paper
  • Loading branch information...
mlwright84 committed Jul 21, 2017
1 parent 808c24b commit a2d3d9b2427332d34df9d161fb482826846589f1
View
@@ -140,7 +140,8 @@ bool operator==(BarTemplate const& left, BarTemplate const& right)
&& left.multiplicity == right.multiplicity;
}
//rescales a barcode template by projecting points onto the specified line
//rescales a barcode template by projecting points onto the line specificed by angle and offset
// NOTE: parametrization of the line is as in the RIVET paper
// NOTE: angle in DEGREES
std::unique_ptr<Barcode> BarcodeTemplate::rescale(double angle, double offset,
const std::vector<TemplatePoint>& template_points,
@@ -186,7 +187,7 @@ std::unique_ptr<Barcode> BarcodeTemplate::rescale(double angle, double offset,
}
}
//if the line is vertical or horizontal, we must now add the vertical bars
//if the line is vertical or horizontal, we must now add the infinite bars
if (angle == 0 || angle == 90) {
for (std::map<unsigned, unsigned>::iterator it = infinite_bars.begin(); it != infinite_bars.end(); ++it) {
double birth = project(template_points[it->first], angle, offset, grades);
@@ -197,31 +198,40 @@ std::unique_ptr<Barcode> BarcodeTemplate::rescale(double angle, double offset,
return bc;
} //end rescale_barcode_template()
//computes the projection of an xi support point onto the specified line
//computes the projection of an xi support point onto the line specificed by angle and offset
// NOTE: parametrization of the line is as in the RIVET paper
// NOTE: returns INFTY if the point has no projection (can happen only for horizontal and vertical lines)
// NOTE: angle in DEGREES
double BarcodeTemplate::project(const TemplatePoint& pt, double angle, double offset, const Grades& grades)
{
if (angle == 0) //then line is horizontal
{
if (grades.y[pt.y] <= offset) //then point is below the line, so projection exists
if (angle == 0) { //then line is horizontal
if (grades.y[pt.y] <= offset) { //then point is below the line, so projection exists
return grades.x[pt.x];
else //then no projection
return rivet::numeric::INFTY;
} else if (angle == 90) //then line is vertical
{
if (grades.x[pt.x] <= -1 * offset) //then point is left of the line, so projection exists
} //else: no projection
return rivet::numeric::INFTY;
} else if (angle == 90) { //then line is vertical
if (grades.x[pt.x] <= -1 * offset) { //then point is left of the line, so projection exists
return grades.y[pt.y];
else //then no projection
return rivet::numeric::INFTY;
} //else: no projection
return rivet::numeric::INFTY;
}
//if we get here, then line is neither horizontal nor vertical
double radians = angle * rivet::numeric::PI / 180;
double x = grades.x[pt.x];
double y = grades.y[pt.y];
if (y > x * tan(radians) + offset / cos(radians)) //then point is above line
return y / sin(radians) - offset / tan(radians); //project right
double yL = x * tan(radians) + offset / cos(radians); // the point (x, yL) is on the line
if (y >= yL) { //then point is above line, so project to the right
if (offset >= 0) {
return (y * cos(radians) - offset) / (sin(radians) * cos(radians));
} //else
return y / sin(radians);
} //else: point is below the line, so project up
if (offset >= 0) {
return x / cos(radians);
} //else
return yL / sin(radians);
return x / cos(radians) + offset * tan(radians); //project up
} //end project()
View
@@ -59,13 +59,15 @@ class BarcodeTemplate {
std::set<BarTemplate>::iterator end(); //returns an iterator to the past-the-end element of the barcode
bool is_empty(); //returns true iff this barcode has no bars
//rescales a barcode template by projecting points onto the specified line
// NOTE: angle in DEGREES
//rescales a barcode template by projecting points onto the line specificed by angle and offset
// NOTE: parametrization of the line is as in the RIVET paper
// NOTE: angle in DEGREES
std::unique_ptr<Barcode> rescale(double angle, double offset,
const std::vector<TemplatePoint>& template_points,
const Grades& grades);
//computes the projection of an xi support point onto the specified line
//computes the projection of an xi support point onto the line specificed by angle and offset
// NOTE: parametrization of the line is as in the RIVET paper
// NOTE: returns INFTY if the point has no projection (can happen only for horizontal and vertical lines)
// NOTE: angle in DEGREES
double project(const TemplatePoint& pt, double angle, double offset, const Grades& grades);
@@ -152,9 +152,8 @@ void PersistenceDiagram::resize_diagram(double slice_length, double diagram_scal
} //end resize_diagram()
//sets the barcode and the zero coordinate
void PersistenceDiagram::set_barcode(double zero, const Barcode& bc)
void PersistenceDiagram::set_barcode(const Barcode& bc)
{
zero_coord = zero;
barcode = &bc;
}
@@ -175,8 +174,7 @@ void PersistenceDiagram::draw_dots()
for (std::multiset<MultiBar>::iterator it = barcode->begin(); it != barcode->end(); ++it) {
if (it->death == std::numeric_limits<double>::infinity()) //essential cycle (visualized in the upper horizontal strip of the persistence diagram)
{
//shift coordinate
double birth = it->birth - zero_coord;
double birth = it->birth;
//check to see if a dot already exists in its position
int x_pixel = std::round(birth * scale);
@@ -217,9 +215,8 @@ void PersistenceDiagram::draw_dots()
}
} else //finite bar (visualized as a dot in the triangular part of the persistence diagram)
{
//shift coordinates
double birth = it->birth - zero_coord;
double death = it->death - zero_coord;
double birth = it->birth;
double death = it->death;
//check to see if this dot will be in the lt_inf strip
if (death * scale > diagram_size) //dot is in the lt_inf strip
@@ -299,12 +296,11 @@ void PersistenceDiagram::redraw_dots()
} //void redraw_dots()
//updates the diagram after a change in the slice line
void PersistenceDiagram::update_diagram(double slice_length, double diagram_scale, double zero, const Barcode& bc)
void PersistenceDiagram::update_diagram(double slice_length, double diagram_scale, const Barcode& bc)
{
//update parameters
line_size = slice_length / sqrt(2); //divide by sqrt(2) because the line is drawn at a 45-degree angle
scale = diagram_scale / sqrt(2); //similarly, divide by sqrt(2)
zero_coord = zero;
barcode = &bc;
//modify frame
@@ -40,11 +40,11 @@ class PersistenceDiagram : public QGraphicsScene {
void create_diagram(const QString& filename, int dim); //simply creates all objects; resize_diagram() handles positioning of objects
void resize_diagram(double slice_length, double diagram_scale); //resizes diagram to fill the QGraphicsView; called after every window resize
void set_barcode(double zero, const Barcode& bc); //sets the barcode and the zero coordinate
void set_barcode(const Barcode& bc); //sets the barcode
void draw_dots(); //creates and draws persistence dots at the correct locations, using current parameters
void redraw_dots(); //redraws persistence dots; e.g. used after a change in parameters
void update_diagram(double slice_length, double diagram_scale, double zero, const Barcode& bc); //updates the diagram after a change in the slice line
void update_diagram(double slice_length, double diagram_scale, const Barcode& bc); //updates the diagram after a change in the slice line
void select_dot(PersistenceDot* clicked); //highlight the specified dot, selected in the persistence diagram, and propagate to the slice diagram
void deselect_dot(); //remove selection and propagate to the slice diagram
@@ -85,7 +85,6 @@ public slots:
double scale; //scale of the persistence diagram
int diagram_size; //width and height of the persistence diagram (the square part), in pixels
double line_size; //width and height of the blue line; i.e. length of slice line divided by sqrt(2)
double zero_coord; //data coordinate that we consider zero for the persistence diagram
int inf_dot_vpos; //vertical position (y-coordinate) of dots representing essential cycles
int lt_inf_dot_vpos; //vertical position (y-coordinate) of dots representing non-infinite pairs above the diagram
@@ -43,7 +43,6 @@ SliceDiagram::SliceDiagram(ConfigParameters* params, std::vector<double>& x_grad
, slice_line(nullptr)
, x_grades(x_grades)
, y_grades(y_grades)
, line_zero(0)
, max_xi_value(0)
, padding(20)
, created(false)
@@ -511,17 +510,15 @@ void SliceDiagram::update_window_controls(bool from_dot)
} //end update_window_controls()
//draws the barcode parallel to the slice line
void SliceDiagram::draw_barcode(Barcode const& bc, double zero_coord, bool show)
void SliceDiagram::draw_barcode(Barcode const& bc, bool show)
{
line_zero = zero_coord;
bars.resize(bc.size());
unsigned num_bars = 1;
unsigned index = 0;
for (std::multiset<MultiBar>::iterator it = bc.begin(); it != bc.end(); ++it) {
double start = it->birth - line_zero;
double end = it->death - line_zero;
double start = it->birth;
double end = it->death;
for (unsigned i = 0; i < it->multiplicity; i++) {
std::pair<double, double> p1 = compute_endpoint(start, num_bars);
@@ -540,7 +537,7 @@ void SliceDiagram::draw_barcode(Barcode const& bc, double zero_coord, bool show)
//updates the barcode (e.g. after a change in the slice line)
//TODO: would it be better to move bars, instead of deleting and re-creating them?
void SliceDiagram::update_barcode(Barcode const& bc, double zero_coord, bool show)
void SliceDiagram::update_barcode(Barcode const& bc, bool show)
{
//remove any current selection
primary_selected.clear();
@@ -556,7 +553,7 @@ void SliceDiagram::update_barcode(Barcode const& bc, double zero_coord, bool sho
}
//draw new bars
draw_barcode(bc, zero_coord, show);
draw_barcode(bc, show);
}
//computes an endpoint of a bar in the barcode
@@ -59,8 +59,8 @@ class SliceDiagram : public QGraphicsScene {
void update_line(double angle, double offset); //updates the line, in response to a change in the controls in the VisualizationWindow
void update_window_controls(bool from_dot); //computes new angle and offset in response to a change in the line, emits signal for the VisualizationWindow
void draw_barcode(const Barcode& bc, double zero_coord, bool show); //draws the barcode parallel to the slice line; "show" determines whether or not bars are visible
void update_barcode(const Barcode& bc, double zero_coord, bool show); //updates the barcode (e.g. after a change in the slice line)
void draw_barcode(const Barcode& bc, bool show); //draws the barcode parallel to the slice line; "show" determines whether or not bars are visible
void update_barcode(const Barcode& bc, bool show); //updates the barcode (e.g. after a change in the slice line)
void select_bar(PersistenceBar* clicked); //highlight the specified class of bars, and propagate to the persistence diagram
void deselect_bar(); //remove selection and propagate to the persistence diagram
@@ -143,7 +143,6 @@ public slots:
///TODO: the next four values can be obtained from x_grades and y_grades
double data_xmin, data_xmax, data_ymin, data_ymax; //min and max coordinates of the data
double line_zero; //coordinate of projection of lower-left corner of line-selection window onto selected line
int view_length; //width + height of the QGraphicsView that displays the diagram; used for drawing infinite bars
int max_xi_value; //max value of the bigraded betti numbers
View
@@ -185,11 +185,10 @@ void VisualizationWindow::augmented_arrangement_ready(std::shared_ptr<Arrangemen
if (!grades.x.empty() && !grades.y.empty()) {
//draw the barcode
double zero_coord = rivet::numeric::project_zero(angle_precise, offset_precise, grades.x[0], grades.y[0]);
p_diagram.set_barcode(zero_coord, *barcode);
p_diagram.set_barcode(*barcode);
p_diagram.resize_diagram(slice_diagram.get_slice_length(), slice_diagram.get_pd_scale());
slice_diagram.draw_barcode(*barcode, zero_coord, ui->barcodeCheckBox->isChecked());
slice_diagram.draw_barcode(*barcode, ui->barcodeCheckBox->isChecked());
//enable slice diagram control items
slice_diagram.enable_slice_line();
@@ -294,11 +293,9 @@ void VisualizationWindow::update_persistence_diagram()
barcode->print();
}
double zero_coord = rivet::numeric::project_zero(angle_precise, offset_precise, grades.x[0], grades.y[0]);
//draw the barcode
p_diagram.update_diagram(slice_diagram.get_slice_length(), slice_diagram.get_pd_scale(), zero_coord, *barcode);
slice_diagram.update_barcode(*barcode, zero_coord, ui->barcodeCheckBox->isChecked());
p_diagram.update_diagram(slice_diagram.get_slice_length(), slice_diagram.get_pd_scale(), *barcode);
slice_diagram.update_barcode(*barcode, ui->barcodeCheckBox->isChecked());
}
}
View
@@ -125,14 +125,6 @@ private slots:
void update_persistence_diagram(); //updates the persistence diagram and barcode after a change in the slice line
std::unique_ptr<Barcode> rescale_barcode_template(BarcodeTemplate& dbc, double angle, double offset,
std::vector<double> x_grades, std::vector<double> y_grades);
double project(TemplatePoint& pt, double angle, double offset, std::vector<double> x_grades, std::vector<double> y_grades);
//computes the projection of the lower-left corner of the line-selection window onto the specified line
// TESTING AS REPLACEMENT FOR SliceDiagram::get_zero()
double project_zero(double angle, double offset, double x_0, double y_0);
//other items
void save_arrangement(const QString& filename);

0 comments on commit a2d3d9b

Please sign in to comment.