6 #include "../typedefs.hpp"
7 #include "../PersistentLaplacians.hpp"
8 #include "../core/up_algorithms.hpp"
9 #include "../eigenvalues/eigs_algorithms.hpp"
12 #include <unsupported/Eigen/SparseExtra>
29 template <
typename eigs_Algorithm = PersistentLaplacians::selfadjo
int,
typename up_Algorithm = PersistentLaplacians::schur >
68 std::vector<std::vector<filtration_type>> filtrations){
96 std::vector<std::vector<filtration_type>> filtrations){
119 for (
unsigned long int dim = 1; dim <= (
unsigned long int)
top_dim; dim++){
120 if(boundaries[dim-1].cols() != (
long int) filtrations[dim].size()){
121 std::cout <<
"boundaries[" << dim -1 <<
"].cols()=" << boundaries[dim-1].cols() <<
" != filtrations[" << dim <<
"].size()=" << filtrations[dim].size() << std::endl;
123 if (boundaries[dim-1].rows() != (
long int) filtrations[dim-1].size()){
124 std::cout <<
"boundaries[" << dim -1 <<
"].rows()=" << boundaries[dim-1].rows() <<
" != filtrations[" << dim-1 <<
"].size()=" << filtrations[dim-1].size() << std::endl;
212 }
else if (down.size() == 0){
216 assert (L.cols() == down.cols() && L.rows() == down.rows() &&
"up and down Laplacians must have same dimensions");
256 L = (B*B.transpose()).cast<coefficient_type>();
313 L_down = B.transpose()*B;
352 return std::vector<spectra_type>();
374 eigenvalues.setZero(0);
376 return std::vector<spectra_type>();
383 if (use_dummy_harmonic_basis){
386 std::cout <<
"using inneficient harmonic basis" << std::endl;
387 Eigen::CompleteOrthogonalDecomposition<DenseMatrix_PL> cod;
390 DenseMatrix_PL Null_space = V.block(0, cod.rank(),V.rows(), V.cols() - cod.rank());
393 std::cout <<
"PH_basis_dense computed";
396 int n = PH_basis_dense.cols();
398 change_of_basis.rightCols(PH_basis_dense.cols()) = PH_basis_dense;
402 int n = PH_basis.cols();
404 change_of_basis.rightCols(PH_basis.cols()) = PH_basis;
410 change_of_basis.leftCols(nonharmonic_basis.cols()) = nonharmonic_basis;
413 DenseMatrix_PL temp = change_of_basis.inverse()*L*change_of_basis;
419 Eigen::BDCSVD<DenseMatrix_PL>
bdcsvd(Schur);
420 eigenvalues =
bdcsvd.singularValues();
424 std::vector<spectra_type> std_eigenvalues(eigenvalues.data(), eigenvalues.data() + eigenvalues.size());
425 std::sort(std_eigenvalues.begin(),std_eigenvalues.end());
427 return std_eigenvalues;
453 return std::vector<spectra_type>(betti0,0.0);
470 int zero_pad_length = L_rows - L_rows_flipped;
473 if (L_rows_flipped < L_rows){
482 eigenvalues.setZero(0);
486 return std::vector<spectra_type>();
492 Eigen::SelfAdjointEigenSolver<SparseMatrix_spectra_PL> es(L, Eigen::EigenvaluesOnly);
494 std::vector<spectra_type> std_eigs_flipped(eigs.data(), eigs.data() + eigs.size());
495 if (zero_pad_length <= 0){
496 std::cout <<
"zero_pag_length <= 0 (should not happen)"<< std::endl;
501 return std_eigs_flipped;
505 std::vector<spectra_type> zero_pad(zero_pad_length, 0.0);
506 std::move(std_eigs_flipped.begin(), std_eigs_flipped.end(), std::back_inserter(zero_pad));
523 eigenvalues.setZero(0);
525 return std::vector<spectra_type>();
531 eigenvalues = es.eigenvalues(L);
533 std::vector<spectra_type> std_eigenvalues(eigenvalues.data(), eigenvalues.data() + eigenvalues.size());
534 return std_eigenvalues;
541 std::vector<std::tuple<int, filtration_type, filtration_type, std::vector<spectra_type>>>
spectra(){
547 std::vector<int> dims(
top_dim+1);
548 std::iota (std::begin(dims), std::end(dims), 0);
558 std::vector<std::tuple<int, filtration_type, filtration_type, std::vector<spectra_type>>> requested_spectra =
spectra(requests);
561 for (
int i = 0; i < (int) requested_spectra.size(); i++){
562 std::tuple<int, filtration_type, filtration_type, std::vector<spectra_type>> current = requested_spectra[i];
573 return requested_spectra;
581 std::vector<std::tuple<int, filtration_type, filtration_type, std::vector<spectra_type>>>
spectra(std::vector<std::tuple<int,filtration_type,filtration_type>> spectra_request_list){
586 std::tuple<int,filtration_type,filtration_type> spectra_request;
587 std::vector<spectra_vec> spectra_list;
588 std::vector<std::tuple<int, filtration_type, filtration_type, std::vector<spectra_type>>> requested_spectra;
589 requested_spectra.reserve(spectra_request_list.size());
592 for (
unsigned long int i = 0; i < spectra_request_list.size(); i++){
594 spectra_request = spectra_request_list[i];
595 dim = std::get<0>(spectra_request);
596 a = std::get<1>(spectra_request);
597 b = std::get<2>(spectra_request);
601 requested_spectra.push_back(std::make_tuple(dim, a, b,
spectra(dim, a, b)));
604 std::cout <<
"duration spectra for dim=" << dim <<
", a= " << a <<
", b=" << b <<
": " << this->profile.
all.
duration << std::endl;
606 return requested_spectra;
634 std::vector<spectra_type> std_eigs = std::vector<spectra_type>(betti0,0.0);
635 eigenvectors.setIdentity(betti0,betti0);
636 return std::pair<std::vector<spectra_type>,
DenseMatrix_PL>(std_eigs, eigenvectors);
655 eigenvalues.setZero(0);
663 std::pair<spectra_vec,DenseMatrix_spectra_PL>
eigenpairs = es.eigenpairs(L);
666 std::vector<spectra_type> std_eigenvalues(eigenvalues.data(), eigenvalues.data() + eigenvalues.size());
677 std::vector<int> dims(
top_dim+1);
678 std::iota (std::begin(dims), std::end(dims), 0);
688 std::vector<std::tuple<int, filtration_type, filtration_type, std::vector<spectra_type>,
DenseMatrix_PL>> requested_spectra =
eigenpairs(requests);
691 for (
int i = 0; i < (int) requested_spectra.size(); i++){
692 std::tuple<int, filtration_type, filtration_type, std::vector<spectra_type>,
DenseMatrix_PL> current = requested_spectra[i];
703 return requested_spectra;
711 std::vector<std::tuple<int, filtration_type, filtration_type, std::vector<spectra_type>,
DenseMatrix_PL>>
eigenpairs(std::vector<std::tuple<int,filtration_type,filtration_type>> spectra_request_list){
716 std::tuple<int,filtration_type,filtration_type> spectra_request;
717 std::vector<spectra_vec> spectra_list;
718 std::vector<std::tuple<int, filtration_type, filtration_type, std::vector<spectra_type>,
DenseMatrix_PL>> requested_spectra;
719 requested_spectra.reserve(spectra_request_list.size());
722 for (
unsigned long int i = 0; i < spectra_request_list.size(); i++){
724 spectra_request = spectra_request_list[i];
725 dim = std::get<0>(spectra_request);
726 a = std::get<1>(spectra_request);
727 b = std::get<2>(spectra_request);
732 std::vector<spectra_type> eigenvalues =
eigenpairs.first;
734 requested_spectra.push_back(std::make_tuple(dim, a, b, eigenvalues, eigenvectors));
737 std::cout <<
"duration spectra for dim=" << dim <<
", a= " << a <<
", b=" << b <<
": " << this->profile.
all.
duration << std::endl;
739 return requested_spectra;
751 int current_betti = 0;
753 for (
int k = 0; k < (int) eigenvalues.size(); k++){
754 if (eigenvalues[k] > tol){
755 return std::make_pair(current_betti, eigenvalues[k]);
760 if (current_betti == 0){
761 if ((
int) eigenvalues.size() > 0){
762 return std::make_pair(0,eigenvalues[0]);
764 return std::make_pair(0,0.0);
767 return std::make_pair(current_betti,0.0);
788 bool success = Eigen::saveMarket(L_sparse, filename);
790 std::cout <<
"saved matrix to file " << filename << std::endl;
792 std::cout <<
"failed saving matrix to file " << filename << std::endl;
800 for (
int i = 0; i <=
top_dim; i++){
819 std::vector<std::ofstream> out_streams(
top_dim+1);
820 for (
int i = 0; i <=
top_dim; i++){
821 out_streams[i] = std::ofstream(
"./" + out_prefix +
"_spectra_" + std::to_string(i) +
".txt");
825 for (
int i = 0; i < (int)
spectra.size(); i++){
826 std::tuple<int, filtration_type, filtration_type, std::vector<spectra_type>> spectrum_record =
spectra[i];
827 int dim = std::get<0>(spectrum_record);
828 std::vector<spectra_type> eigs = std::get<3>(spectrum_record);
829 for (
int j = 0; j < (int) eigs.size(); j++){
830 out_streams[dim] << eigs[j] <<
" ";
832 out_streams[dim] << std::endl;
835 for (
int i = 0; i <=
top_dim; i++){
836 out_streams[i].close();
849 std::set<std::pair<filtration_type, filtration_type>> filtration_values_set;
852 for (
int i = 0 ; i < (int)
spectra.size(); i++){
855 filtration_values_set.insert(
856 std::make_pair(a,b));
858 int num_filtrations = filtration_values_set.size();
859 std::vector<std::pair<filtration_type,filtration_type>> filtration_values_vec(filtration_values_set.begin(), filtration_values_set.end());
863 std::map<std::pair<filtration_type,filtration_type>,
int> filtration_index_map;
864 std::vector<std::vector<spectra_type>> output_lines(num_filtrations);
865 int items_per_line = 2 + 2*(
top_dim+1);
866 for (
int i = 0; i < num_filtrations; i++){
867 filtration_index_map[filtration_values_vec[i]] = i;
869 std::vector<spectra_type> temp_line(items_per_line);
870 temp_line[0] = (
spectra_type) filtration_values_vec[i].first;
871 temp_line[1] = (
spectra_type) filtration_values_vec[i].second;
872 output_lines[i] = temp_line;
875 for (
int i = 0; i < (int)
spectra.size(); i++){
877 std::tuple<int, filtration_type, filtration_type, std::vector<spectra_type>> spectrum_record =
spectra[i];
878 int dim = std::get<0>(spectrum_record);
883 std::pair<filtration_type, filtration_type> filtration_pair = std::make_pair(a,b);
884 std::vector<spectra_type> eigs = std::get<3>(spectrum_record);
889 int line_index = filtration_index_map[filtration_pair];
892 output_lines[line_index][2+dim] = betti;
893 output_lines[line_index][3+
top_dim+dim] = lambda;
897 std::ofstream outstream(
"./" + out_prefix +
"_spectra_summary.txt");
899 for (
int i = 0; i <=
top_dim; i++){
900 outstream <<
"\tbetti_" << i;
902 for (
int i = 0; i <=
top_dim; i++){
903 outstream <<
"\tlambda_" << i;
905 outstream << std::endl;
908 for (
int i = 0; i < (int) num_filtrations; i++){
909 outstream << output_lines[i][0];
910 for (
int j = 1; j < items_per_line; j++){
911 outstream <<
"\t" << output_lines[i][j];
913 outstream << std::endl;
930 std::vector<std::tuple<int, filtration_type, filtration_type>> requests;
931 std::tuple<int, filtration_type, filtration_type> spectra_request;
934 for(
unsigned long int filtration_index = 0; filtration_index < filtrations.size()-1; filtration_index++){
935 a = filtrations[filtration_index];
936 b = filtrations[filtration_index+1];
937 for (
unsigned long int dim_index = 0; dim_index < dims.size(); dim_index++){
938 dim = dims[dim_index];
939 spectra_request = std::make_tuple(dim, a, b);
940 requests.push_back(spectra_request);
944 a = filtrations[filtrations.size()-1];
946 for (
unsigned long int dim_index = 0; dim_index < dims.size(); dim_index++){
947 dim = dims[dim_index];
948 spectra_request = std::make_tuple(dim, a, b);
949 requests.push_back(spectra_request);
958 std::set<filtration_type> all_filtrations;
962 for (
unsigned long int i = 0; i < c0.size(); i++){
963 all_filtrations.insert(c0[i]);
966 std::vector<filtration_type> temp;
967 for (
unsigned long int dim = 1; dim <= (
unsigned long int)
top_dim; dim++){
969 for (
unsigned long int i = 0; i < temp.size(); i++){
970 all_filtrations.insert(temp[i]);
973 std::vector<filtration_type> all_filtrations_vector(all_filtrations.begin(), all_filtrations.end());
974 return all_filtrations_vector;
982 std::vector<filtration_type> domain_filtrations = {0.0};
983 std::vector<filtration_type> range_filtrations = {0.0};
Definition: FilteredBoundaryMatrix.hpp:16
Definition: PersistentLaplacian.hpp:30
void store_spectra_summary(std::vector< std::tuple< int, filtration_type, filtration_type, std::vector< spectra_type >>> spectra, std::string out_prefix)
Definition: PersistentLaplacian.hpp:848
void store_spectra(std::vector< std::tuple< int, filtration_type, filtration_type, std::vector< spectra_type >>> spectra, std::string out_prefix)
Definition: PersistentLaplacian.hpp:817
void get_L(int dim, filtration_type a, filtration_type b, DenseMatrix_PL &L)
Definition: PersistentLaplacian.hpp:155
void store_L(int dim, filtration_type a, filtration_type b, std::string filename)
Definition: PersistentLaplacian.hpp:782
std::vector< spectra_type > nonzero_spectra(int dim, filtration_type a, filtration_type b, SparseMatrixFloat PH_basis, bool use_dummy_harmonic_basis)
Definition: PersistentLaplacian.hpp:345
void get_L_top_dim_flipped(filtration_type a, SparseMatrix_PL &L)
Definition: PersistentLaplacian.hpp:252
std::pair< std::vector< spectra_type >, DenseMatrix_PL > eigenpairs(int dim, filtration_type a, filtration_type b)
Definition: PersistentLaplacian.hpp:621
std::vector< std::tuple< int, filtration_type, filtration_type, std::vector< spectra_type >, DenseMatrix_PL > > eigenpairs(std::vector< std::tuple< int, filtration_type, filtration_type >> spectra_request_list)
Definition: PersistentLaplacian.hpp:711
DenseMatrix_PL get_L(int dim, filtration_type a, filtration_type b)
Definition: PersistentLaplacian.hpp:241
DenseMatrix_PL get_up(int dim, filtration_type a, filtration_type b)
Definition: PersistentLaplacian.hpp:298
std::vector< filtration_type > get_all_filtrations()
Definition: PersistentLaplacian.hpp:957
PersistentLaplacian()
Definition: PersistentLaplacian.hpp:50
std::vector< std::tuple< int, filtration_type, filtration_type, std::vector< spectra_type > > > spectra(std::vector< std::tuple< int, filtration_type, filtration_type >> spectra_request_list)
Definition: PersistentLaplacian.hpp:581
PersistentLaplacian(std::vector< SparseMatrixInt > boundaries, std::vector< std::vector< filtration_type >> filtrations)
Definition: PersistentLaplacian.hpp:67
std::vector< std::tuple< int, filtration_type, filtration_type, std::vector< spectra_type > > > spectra()
Definition: PersistentLaplacian.hpp:541
std::vector< FilteredBoundaryMatrix< storage > > filtered_boundaries
Boundary matrix assuming real (or integer) coefficients.
Definition: PersistentLaplacian.hpp:38
bool verbose
Print progress if spectra() is called.
Definition: PersistentLaplacian.hpp:39
int top_dim
Top dimension of the complex.
Definition: PersistentLaplacian.hpp:37
Profile profile
Profiler to track time usage of various steps.
Definition: PersistentLaplacian.hpp:41
std::vector< spectra_type > spectra(int dim, filtration_type a, filtration_type b)
Definition: PersistentLaplacian.hpp:442
void set_verbose(bool verbose)
Definition: PersistentLaplacian.hpp:135
void get_down(int dim, filtration_type a, SparseMatrix_storage &L_down)
Definition: PersistentLaplacian.hpp:310
~PersistentLaplacian()
Definition: PersistentLaplacian.hpp:79
std::pair< int, spectra_type > eigenvalues_summarize(std::vector< spectra_type > eigenvalues)
Definition: PersistentLaplacian.hpp:748
void get_up(int dim, filtration_type a, filtration_type b, DenseMatrix_PL &L_up)
Definition: PersistentLaplacian.hpp:284
void set_flipped(bool use_flipped)
Definition: PersistentLaplacian.hpp:141
PersistentLaplacians::FilteredBoundaryMatrix< storage > dummy_d0()
Definition: PersistentLaplacian.hpp:979
SparseMatrix_PL get_L_top_dim_flipped(filtration_type a)
Definition: PersistentLaplacian.hpp:268
std::vector< std::tuple< int, filtration_type, filtration_type > > filtration_list_to_spectra_request(std::vector< filtration_type > filtrations, std::vector< int > dims)
Definition: PersistentLaplacian.hpp:925
std::vector< std::tuple< int, filtration_type, filtration_type, std::vector< spectra_type >, DenseMatrix_PL > > eigenpairs()
Definition: PersistentLaplacian.hpp:674
SparseMatrix_storage get_down(int dim, filtration_type a)
Definition: PersistentLaplacian.hpp:330
void set_boundaries_filtrations(std::vector< SparseMatrixInt > boundaries, std::vector< std::vector< filtration_type >> filtrations)
Definition: PersistentLaplacian.hpp:95
void print_boundaries()
Definition: PersistentLaplacian.hpp:799
bool use_flipped
Compute the top-dimensional Laplacian's eigenvalues in spectra function via the eigenvalues of the sm...
Definition: PersistentLaplacian.hpp:40
Definition: eigs_algorithms.hpp:101
Definition: PersistentLaplacians.cpp:7
Definition: PersistentLaplacians.hpp:43
void stop_sum_up_down()
Definition: PersistentLaplacians.hpp:81
std::vector< filtration_type > filtration_b
Definition: PersistentLaplacians.hpp:47
void start_L_down()
Definition: PersistentLaplacians.hpp:73
std::vector< int > durations_L_up
Definition: PersistentLaplacians.hpp:57
std::vector< int > durations_eigs
Definition: PersistentLaplacians.hpp:55
void start_L()
Definition: PersistentLaplacians.hpp:71
std::vector< int > durations_L_down
Definition: PersistentLaplacians.hpp:58
void start_L_up()
Definition: PersistentLaplacians.hpp:72
std::vector< spectra_type > lambdas
Definition: PersistentLaplacians.hpp:63
void stop_L()
Definition: PersistentLaplacians.hpp:78
void to_csv(std::string filename)
Definition: PersistentLaplacians.cpp:174
std::vector< filtration_type > filtration_a
Definition: PersistentLaplacians.hpp:46
std::vector< int > bettis
Definition: PersistentLaplacians.hpp:62
void start_all()
Definition: PersistentLaplacians.hpp:69
timer all
Definition: PersistentLaplacians.hpp:48
void start_eigs()
Definition: PersistentLaplacians.hpp:70
void stop_L_down()
Definition: PersistentLaplacians.hpp:80
void start_sum_up_down()
Definition: PersistentLaplacians.hpp:74
std::vector< int > L_rows
Definition: PersistentLaplacians.hpp:61
void stop_all()
Definition: PersistentLaplacians.hpp:76
std::vector< int > dims
Definition: PersistentLaplacians.hpp:45
std::vector< int > durations_sum_up_down
Definition: PersistentLaplacians.hpp:59
void stop_L_up()
Definition: PersistentLaplacians.hpp:79
void stop_eigs()
Definition: PersistentLaplacians.hpp:77
int duration
Definition: PersistentLaplacians.hpp:32
float coefficient_type
Definition: typedefs.hpp:13
Eigen::Matrix< coefficient_type, Eigen::Dynamic, Eigen::Dynamic > DenseMatrix_PL
Definition: typedefs.hpp:24
Eigen::Matrix< spectra_type, Eigen::Dynamic, 1 > spectra_vec
Definition: typedefs.hpp:27
Eigen::SparseMatrix< float, Eigen::ColMajor > SparseMatrixFloat
Definition: typedefs.hpp:31
Eigen::SparseMatrix< storage, Eigen::ColMajor > SparseMatrix_storage
Definition: typedefs.hpp:21
Eigen::SparseMatrix< coefficient_type, Eigen::ColMajor > SparseMatrix_PL
Definition: typedefs.hpp:23
float spectra_type
Definition: typedefs.hpp:14
double filtration_type
Definition: typedefs.hpp:34