" << std::endl
#ifdef USE_COEFFICIENTS
<< " --modulus compute homology with coefficients in the prime field Z/
Z"
#endif
<< std::endl;
exit(exit_code);
}
int main(int argc, char** argv) {
const char* ifilename = nullptr;
const char* oprefix = nullptr;
file_format format = DISTANCE_MATRIX;
index_t dim_max = 1;
value_t threshold = std::numeric_limits::max();
float ratio = 1;
#ifdef USE_COEFFICIENTS
coefficient_t modulus = 2;
#else
const coefficient_t modulus = 2;
#endif
for (index_t i = 1; i < argc; ++i) {
const std::string arg(argv[i]);
if (arg == "--help") {
print_usage_and_exit(0);
} else if (arg == "--dim") {
std::string parameter = std::string(argv[++i]);
size_t next_pos;
dim_max = std::stol(parameter, &next_pos);
if (next_pos != parameter.size()) print_usage_and_exit(-1);
} else if (arg == "--threshold") {
std::string parameter = std::string(argv[++i]);
size_t next_pos;
threshold = std::stof(parameter, &next_pos);
if (next_pos != parameter.size()) print_usage_and_exit(-1);
} else if (arg == "--ratio") {
std::string parameter = std::string(argv[++i]);
size_t next_pos;
ratio = std::stof(parameter, &next_pos);
if (next_pos != parameter.size()) print_usage_and_exit(-1);
} else if (arg == "--format") {
std::string parameter = std::string(argv[++i]);
if (parameter == "lower-distance")
format = LOWER_DISTANCE_MATRIX;
else if (parameter == "upper-distance")
format = UPPER_DISTANCE_MATRIX;
else if (parameter == "distance")
format = DISTANCE_MATRIX;
else if (parameter == "point-cloud")
format = POINT_CLOUD;
else if (parameter == "dipha")
format = DIPHA;
else if (parameter == "ripser")
format = RIPSER;
else
print_usage_and_exit(-1);
#ifdef USE_COEFFICIENTS
} else if (arg == "--modulus") {
std::string parameter = std::string(argv[++i]);
size_t next_pos;
modulus = std::stol(parameter, &next_pos);
if (next_pos != parameter.size() || !is_prime(modulus)) print_usage_and_exit(-1);
#endif
} else if (i == argc - 2) {
ifilename = argv[i];
} else if (i == argc - 1) {
oprefix = argv[i];
} else {
print_usage_and_exit(-1);
}
}
if (ifilename == nullptr || oprefix == nullptr)
{
std::cerr << "Need input and output file names." << std::endl;
exit(-1);
}
std::ifstream file_stream(ifilename);
if (ifilename && file_stream.fail()) {
std::cerr << "couldn't open file " << ifilename << std::endl;
exit(-1);
}
std::ofstream outstream_pds(std::string(oprefix) + std::string(".pd.dipha"), std::ios::binary);
if (!outstream_pds.is_open())
{
std::cerr << "Failed to open PD output file." << std::endl;
exit(-1);
}
std::ofstream outstream_reps(std::string(oprefix) + std::string(".reps.txt"));
if (!outstream_reps.is_open())
{
std::cerr << "Failed to open representative cocycles output file." << std::endl;
exit(-1);
}
int64_t pair_count = 0;
write(outstream_pds, DIPHA_MAGIC);
write(outstream_pds, DIPHA_TYPE_PERSISTENCE_DIAGRAM);
write(outstream_pds, DIPHA_MAGIC); // This is to later be replaced by the number of pairs in the persistence diagram.
compressed_lower_distance_matrix dist = read_file(ifilename ? file_stream : std::cin, format);
value_t min = std::numeric_limits::infinity(),
max = -std::numeric_limits::infinity(), max_finite = max;
int num_edges = 0;
value_t enclosing_radius = std::numeric_limits::infinity();
for (index_t i = 0; i < dist.size(); ++i) {
value_t r_i = -std::numeric_limits::infinity();
for (index_t j = 0; j < dist.size(); ++j) r_i = std::max(r_i, dist(i, j));
enclosing_radius = std::min(enclosing_radius, r_i);
}
if (threshold == std::numeric_limits::max()) threshold = enclosing_radius;
for (auto d : dist.distances) {
min = std::min(min, d);
max = std::max(max, d);
max_finite = d != std::numeric_limits::infinity() ? std::max(max, d) : max_finite;
if (d <= threshold) ++num_edges;
}
std::cout << "value range: [" << min << "," << max_finite << "]" << std::endl;
if (threshold >= max) {
std::cout << "distance matrix with " << dist.size() << " points" << std::endl;
ripser(std::move(dist), dim_max, threshold, ratio,
modulus)
.compute_barcodes(outstream_pds, outstream_reps, pair_count);
} else {
std::cout << "sparse distance matrix with " << dist.size() << " points and " << num_edges
<< " entries" << std::endl;
ripser(sparse_distance_matrix(std::move(dist), threshold), dim_max,
threshold, ratio, modulus)
.compute_barcodes(outstream_pds, outstream_reps, pair_count);
}
outstream_pds.seekp(2*sizeof(int64_t), std::ios_base::beg); // Rewind to the spot in the DIPHA file where we write the number of intervals.
write(outstream_pds, pair_count);
outstream_pds.close();
outstream_reps.close();
}