Permalink
Browse files

Merge branch 'master' into textsize

  • Loading branch information...
mlwright84 committed Aug 4, 2017
2 parents 70b445b + 6ce3c9a commit 63b5b16af7a43ea463b613fd8bf8e642b24d3997
View
@@ -19,7 +19,7 @@ Before starting to build RIVET, you will need to have the following installed:
* Qt 5
* Boost (including boost serialization; version 1.60 or newer required)
Below we give step-by-step instructions for installing these required dependencies and building RIVET on Ubuntu and Mac OS X. Currently, use of RIVET in Windows is not supported; we are working on this.
Below we give step-by-step instructions for installing these required dependencies and building RIVET on Ubuntu and Mac OS X. Building RIVET on Windows is not yet supported (we are working on this), but it is possible to build RIVET using the Bash shell on Windows 10.
## Building On Ubuntu
@@ -135,6 +135,50 @@ To solve the problem, try running:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
## Building in the Bash Shell on Windows 10
First, ensure that you have the [Windows 10 Creators Update](https://support.microsoft.com/en-us/instantanswers/d4efb316-79f0-1aa1-9ef3-dcada78f3fa0/get-the-windows-10-creators-update). Then activate the [Windows 10 Bash Shell](https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/). This will provide a Bash shell with Ubuntu 16.04 inside of Windows 10.
Open the Bash shell and install dependencies. Use the following command to install cmake, a compiler, and Qt5:
sudo apt-get install cmake build-essential qt5-default qt5-qmake qtbase5-dev-tools
The Ubuntu 16.04 repositories include Boost 1.58, but RIVET requires Boost 1.60 or newer. The following instructions install Boost 1.64 into `/usr/local/boost_1_64_0/`:
1. Download a compressed Boost file into your home directory:
cd ~
wget "https://dl.bintray.com/boostorg/release/1.64.0/source/boost_1_64_0.tar.bz2"
2. Unpack Boost to `/usr/local/`:
cd /usr/local
sudo tar xvjf ~/boost_1_64_0.tar.bz2
cd boost_1_64_0
3. Setup Boost:
sudo ./boostrap.sh --prefix=/usr/local
sudo ./b2
sudo ./b2 install
4. Return to home directory and delete the compressed Boost file.
cd ~
rm boost_1_64_0.tar.bz2
In order to use the RIVET viewer, you must install an X server such as [Xming](https://sourceforge.net/projects/xming/).
It is also necessary to set two environment variables, as follows:
export LD_LIBRARY_PATH=/usr/local/boost_1_64_0/stage/lib/:$LD_LIBRARY_PATH
export DISPLAY=:0
These environment variables will be reset when you close the Bash shell. To avoid having to run the two lines above when you reopen the shell, add these lines to the end of the file `~/.bashrc`.
You are now ready to build RIVET. Follow the instructions in the section of this readme under the heading [Building on Ubuntu: Building RIVET](https://github.com/rivetTDA/rivet/#building-rivet).
## Contributing
We welcome your contribution! Code, documentation, unit tests,
View
@@ -54,6 +54,7 @@ std::unique_ptr<ComputationResult> Computation::compute_raw(ComputationInput& in
}
}
}
//STAGE 3: COMPUTE MULTIGRADED BETTI NUMBERS
std::unique_ptr<ComputationResult> result(new ComputationResult);
View
@@ -50,6 +50,7 @@ static const char USAGE[] =
rivet_console --version
rivet_console <input_file> --identify
rivet_console <input_file> --betti [-H <dimension>] [-V <verbosity>] [-x <xbins>] [-y <ybins>]
rivet_console <input_file> <output_file> --betti [-H <dimension>] [-V <verbosity>] [-x <xbins>] [-y <ybins>]
rivet_console <precomputed_file> --bounds
rivet_console <precomputed_file> --barcodes <line_file>
rivet_console <input_file> <output_file> [-H <dimension>] [-V <verbosity>] [-x <xbins>] [-y <ybins>] [-f <format>] [--binary]
@@ -71,10 +72,10 @@ static const char USAGE[] =
-b --betti Print dimension and Betti number information, then exit.
--bounds Print lower and upper bounds for the module in <precomputed_file> and exit
--barcodes <line_file> Print barcodes for the line queries in line_file, then exit.
line_file consists of pairs "m b", each representing a query line.
m is the slope of the query line, given in degrees (0 to 90); b is the
line_file consists of pairs "m o", each representing a query line.
m is the slope of the query line, given in degrees (0 to 90); o is the
signed distance from the query line to the origin, where the sign is
positive if the line is below/right of the origin and negative otherwise.
positive if the line is above/left of the origin and negative otherwise.
Example line_file contents:
@@ -125,9 +126,9 @@ void print_dims(TemplatePointsMessage const& message, std::ostream& ostream)
auto data = message.homology_dimensions.data();
ostream << "Dimensions > 0:" << std::endl;
for (unsigned long row = 0; row < shape[0]; row++) {
for (unsigned long col = 0; col < shape[1]; col++) {
unsigned dim = data[row * shape[0] + col];
for (unsigned long col = 0; col < shape[0]; col++) {
for (unsigned long row = 0; row < shape[1]; row++) {
unsigned dim = data[col * shape[1] + row];
if (dim > 0) {
ostream << "(" << col << ", " << row << ", " << dim << ")" << std::endl;
}
@@ -362,7 +363,7 @@ int main(int argc, char* argv[])
std::clog << "Wrote arrangement to " << params.outputFile << std::endl;
}
});
computation.template_points_ready.connect([&points_message, &binary, &betti_only, &verbosity](TemplatePointsMessage message) {
computation.template_points_ready.connect([&points_message, &binary, &betti_only, &verbosity, &params](TemplatePointsMessage message) {
points_message.reset(new TemplatePointsMessage(message));
if (binary) {
@@ -397,8 +398,27 @@ int main(int argc, char* argv[])
print_dims(message, std::cout);
std::cout << std::endl;
print_betti(message, std::cout);
std::cout.flush();
//if an output file has been specified, then save the Betti numbers in an arrangement file (with no barcode templates)
if (!params.outputFile.empty()) {
std::ofstream file(params.outputFile);
if (file.is_open()) {
std::vector<exact> emptyvec;
std::shared_ptr<Arrangement> temp_arrangement = std::make_shared<Arrangement>(emptyvec, emptyvec, verbosity);
std::shared_ptr<ArrangementMessage> temp_am = std::make_shared<ArrangementMessage>(*temp_arrangement);
if (verbosity > 0) {
debug() << "Writing file:" << params.outputFile;
}
write_boost_file(params, *points_message, *temp_am);
} else {
std::stringstream ss;
ss << "Error: Unable to write file:" << params.outputFile;
throw std::runtime_error(ss.str());
}
}
//TODO: this seems a little abrupt...
std::cout.flush();
exit(0);
}
});
@@ -413,19 +433,21 @@ int main(int argc, char* argv[])
}
std::unique_ptr<ComputationResult> result;
std::unique_ptr<InputData> input;
std::shared_ptr<Arrangement> arrangement;
if (barcodes || bounds) {
result = load_from_precomputed(params.fileName);
if (barcodes) {
if (!slices.empty()) {
process_barcode_queries(slices, *result);
return 0;
}
} else {
process_bounds(*result);
}
} else {
std::unique_ptr<InputData> input;
try {
input = inputManager.start(progress);
} catch (const std::exception& e) {
@@ -441,31 +463,34 @@ int main(int argc, char* argv[])
if (params.verbosity >= 2) {
debug() << "Computation complete; augmented arrangement ready.";
}
auto arrangement = result->arrangement;
arrangement = result->arrangement;
if (params.verbosity >= 4) {
arrangement->print_stats();
}
//if an output file has been specified, then save the arrangement
if (!params.outputFile.empty()) {
std::ofstream file(params.outputFile);
if (file.is_open()) {
if (verbosity > 0) {
debug() << "Writing file:" << params.outputFile;
}
if (params.outputFormat == "R0") {
FileWriter fw(params, *input, *(arrangement), result->template_points);
fw.write_augmented_arrangement(file);
} else if (params.outputFormat == "R1") {
write_boost_file(params, *points_message, *arrangement_message);
} else {
throw std::runtime_error("Unsupported output format: " + params.outputFormat);
}
}
//if an output file has been specified, then save the arrangement
if (!params.outputFile.empty()) {
std::ofstream file(params.outputFile);
if (file.is_open()) {
if (arrangement == nullptr) {
arrangement.reset(new Arrangement());
}
if (verbosity > 0) {
debug() << "Writing file:" << params.outputFile;
}
if (params.outputFormat == "R0") {
FileWriter fw(params, *input, *(arrangement), result->template_points);
fw.write_augmented_arrangement(file);
} else if (params.outputFormat == "R1") {
write_boost_file(params, *points_message, *arrangement_message);
} else {
std::stringstream ss;
ss << "Error: Unable to write file:" << params.outputFile;
throw std::runtime_error(ss.str());
throw std::runtime_error("Unsupported output format: " + params.outputFormat);
}
} else {
std::stringstream ss;
ss << "Error: Unable to write file:" << params.outputFile;
throw std::runtime_error(ss.str());
}
}
if (params.verbosity > 2) {
@@ -530,3 +530,8 @@ Arrangement ArrangementMessage::to_arrangement() const
// std::clog << "All anchors identical in to_arrangement" << std::endl;
return arrangement;
}
bool ArrangementMessage::is_empty() const
{
return ( x_exact.empty() && y_exact.empty() );
}
@@ -51,6 +51,8 @@ class ArrangementMessage {
Arrangement to_arrangement() const;
bool is_empty() const;
private:
friend class boost::serialization::access;
View
@@ -65,6 +65,19 @@ void Barcode::add_bar(double b, double d, unsigned m)
bars.insert(MultiBar(b, d, m));
}
//shifts the barcode by adding amount to each endpoint of each bar
std::unique_ptr<Barcode> Barcode::shift(double amount)
{
std::unique_ptr<Barcode> bc = std::unique_ptr<Barcode>(new Barcode());
for (std::multiset<MultiBar>::iterator it = bars.begin(); it != bars.end(); ++it) {
MultiBar mb = *it;
bc->add_bar(mb.birth + amount, mb.death + amount, mb.multiplicity);
}
return bc;
}
//returns an iterator to the first bar in the barcode
std::set<MultiBar>::const_iterator Barcode::begin() const
{
View
@@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __BARCODE_H__
#define __BARCODE_H__
#include <memory>
#include <set>
struct MultiBar {
@@ -40,6 +41,8 @@ class Barcode {
void add_bar(double b, double d, unsigned m); //adds a bar to the barcode
std::unique_ptr<Barcode> shift(double amount); //shifts the barcode by adding amount to each endpoint of each bar
std::multiset<MultiBar>::const_iterator begin() const; //returns an iterator to the first bar in the barcode
std::multiset<MultiBar>::const_iterator end() const; //returns an iterator to the pst-the-end element the barcode
unsigned size() const; //returns the number of multibars in the barcode
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);
Oops, something went wrong.

0 comments on commit 63b5b16

Please sign in to comment.