diff --git a/config/characterisation.ini b/config/characterisation.ini index 9360f8c3..bfed4546 100644 --- a/config/characterisation.ini +++ b/config/characterisation.ini @@ -13,13 +13,13 @@ S_mean = 0 S_skew = 0 [edges_lab] -el_active = 1 -config_entropy = 1 -S_mean = 1 -S_skew = 1 -j_fractions = 1 -d_fractions = 1 -analytical = 1 +el_active = 0 +config_entropy = 0 +S_mean = 0 +S_skew = 0 +j_fractions = 0 +d_fractions = 0 +analytical = 0 [nodes_lab] nl_active = 0 @@ -28,7 +28,8 @@ S_mean = 0 S_skew = 0 [spectra_lab] -laplacians = 0 +calc_steps_numb = 50 +laplacians = 1 laplacians_spectra = 0 laplacians_betti = 0 diff --git a/config/main.ini b/config/main.ini index 2661bc0a..2f725234 100644 --- a/config/main.ini +++ b/config/main.ini @@ -11,7 +11,7 @@ PCC_Writer=ON [general] dim=3 -source_dir=/Users/user/Dropbox/OFFICE/NEPER/Kinetic_PCC_examples_/Voronoi_1k/ -;source_dir=/Users/user/Dropbox/OFFICE/EGitHub/_Kinetic_PCC_examples/Siying500Complex/ -output_dir=/Users/user/Dropbox/OFFICE/NEPER/resultsFebruary2023/v1k_processing/ -;output_dir=/Users/user/Dropbox/OFFICE/NEPER/resultsMay2023/500cells_processing/ \ No newline at end of file +; source_dir=/Users/user/Dropbox/OFFICE/NEPER/Kinetic_PCC_examples_/Voronoi_1k/ +source_dir=/Users/user/Dropbox/OFFICE/EGitHub/_Kinetic_PCC_examples/Siying500Complex/ +;output_dir=/Users/user/Dropbox/OFFICE/NEPER/resultsFebruary2023/v1k_processing/ +output_dir=/Users/user/Dropbox/OFFICE/NEPER/resultsMay2023/500cells_processing/ \ No newline at end of file diff --git a/config/processing.ini b/config/processing.ini index ef554653..9dfdba0e 100644 --- a/config/processing.ini +++ b/config/processing.ini @@ -14,7 +14,7 @@ pmax_fraction3 = 0.0 [faces] face_types_number = 1 -pf_mode = S +pf_mode = R ; "S" - read from source, "R" or "F" -> Smax, "D" -> Smin (max S_deviatoric (skew) part) or "L" source = /Users/user/Dropbox/OFFICE/NEPER/resultsFebruary2023/v1k_processing/Random099/s_cells_sequence.txt pf_index = 0 diff --git a/config/writer.ini b/config/writer.ini index 1812240d..a1fc1d96 100644 --- a/config/writer.ini +++ b/config/writer.ini @@ -1,25 +1,27 @@ ; writer specifications [sequences] -isSequencesOutput = 1 -isDesignvectorsOutput = 1 +isSequencesOutput = 0 +isDesignvectorsOutput = 0 [entropic_polyhedrons] isPolyhedronFractions = 0 - [entropic_faces] isFaceFractions = 0 isConfEntropy = 0 [entropic_edges] -isConfEntropy = 1 -isFractions = 1 -isDegreeFractions = 1 +isConfEntropy = 0 +isFractions = 0 +isDegreeFractions = 0 [entropic_nodes] isNodeFractions = 0 [entropic_analytical] -isEdgeFractions = 1 -isEdgeConfEntropies = 1 +isEdgeFractions = 0 +isEdgeConfEntropies = 0 + +[component_analysis] +isBetti = 1 \ No newline at end of file diff --git a/src/lib/PCC_Characterisation/LaplaciansLab.h b/src/lib/PCC_Characterisation/LaplaciansLab.h index b7a95b68..3a1291dd 100644 --- a/src/lib/PCC_Characterisation/LaplaciansLab.h +++ b/src/lib/PCC_Characterisation/LaplaciansLab.h @@ -4,136 +4,217 @@ ///=======================================================================================================================/// /// # 0 # reduced laplacians (vector of their sparse matrices) -// std::vector> ReducedFaceLaplacians(CellsDesign &cells_design, std::vector const &CellNumbs) { // OSM - operator's sparse matrix -std::vector> ReducedFaceLaplacians(CellsDesign &cells_design) { // OSM - operator's sparse matrix - +std::vector> ReducedFaceLaplacians(std::vector &face_sequence_vector, SpMat &ENS, SpMat &FES, SpMat &GFS) { std::vector> laplacians_vector; // function output: { ENM_laplacian, FEM_laplacian, GFM_laplacian } -// AN - Nodes (Vertices or 0-Cells) sparse adjacency matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values -// AE - Edges (Triple Junctions or 1-Cells) sparse adjacency matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values -// AF - Faces (Grain Boundaries or 2-Cells) sparse adjacency matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values -// AG - Grains (Volumes or 3-Cells) sparse adjacency matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values -// MEN - Edges - Nodes (1-Cells to 0-Cells) sparse incidence matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values -// MFE - Faces - Edges (2-Cells to 1-Cells) sparse incidence matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values -// MGF - Grains - Faces (3-Cells to 2-Cells) sparse incidence matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values // odir - source path - -/// Adjacency sparse matrix for nodes /// Adjacency sparse matrix for edges /// Adjacency sparse matrix for faces /// Adjacency sparse matrix for grains -// SpMat ANS(CellNumbs.at(0), CellNumbs.at(0)), AES(CellNumbs.at(1 + (dim - 3)), CellNumbs.at(1 + (dim - 3))), AFS(CellNumbs.at(2 + (dim - 3)), CellNumbs.at(2 + (dim - 3))), AGS(CellNumbs.at(3 + (dim - 3)), CellNumbs.at(3 + (dim - 3))); -// ANS = SMatrixReader(paths.at(0), (CellNumbs.at(0)), (CellNumbs.at(0))); //all Nodes -// ANS = 0.5 * (ANS + SparseMatrix(ANS.transpose())); // Full matrix instead of triagonal -// AES = SMatrixReader(paths.at(1 + (dim - 3)), (CellNumbs.at(1 + (dim - 3))), (CellNumbs.at(1 + (dim - 3)))); //all Edges -// AES = 0.5 * (AES + SparseMatrix(AES.transpose())); // Full matrix instead of triagonal -// AFS = SMatrixReader(paths.at(2 + (dim - 3)), (CellNumbs.at(2 + (dim - 3))), (CellNumbs.at(2 + (dim - 3)))); //all Faces -// AFS = 0.5 * (AFS + SparseMatrix(AFS.transpose())); // Full matrix instead of triagonal -// AGS = SMatrixReader(paths.at(3 + (dim - 3)), (CellNumbs.at(3 + (dim - 3))), (CellNumbs.at(3 + (dim - 3)))); //all Volumes -// AGS = 0.5 * (AGS + SparseMatrix(AGS.transpose())); // Full matrix instead of triagonal - -/// Incidence sparse matrix for Edges and Nodes /// Incidence sparse matrix for Faces and Edges /// Incidence sparse matrix for Grains and Faces - SpMat ENS(CellNumbs.at(0), CellNumbs.at(1)), FES(CellNumbs.at(1 + (dim - 3)), CellNumbs.at(2 + (dim - 3))), GFS(CellNumbs.at(2 + (dim - 3)), CellNumbs.at(3 + (dim - 3))); - - ENS = SMatrixReader(paths.at(4 + (dim - 3)), (CellNumbs.at(0)), (CellNumbs.at(1))); //all Nodes-Edges - FES = SMatrixReader(paths.at(5 + (dim - 3)), (CellNumbs.at(1 + (dim - 3))), (CellNumbs.at(2 + (dim - 3)))); //all Edges-Faces - GFS = SMatrixReader(paths.at(6 + (dim - 3)), (CellNumbs.at(2 + (dim - 3))), (CellNumbs.at(3 + (dim - 3)))); //all Faces-Grains /// Triplet lists vector sEN_triplet_list, sFE_triplet_list, sGF_triplet_list; -/// Sparse matrices (Eigen/ Spectra) - SpMat ENM_SpecialCells, FEM_SpecialCells, GFM_SpecialCells, L0_laplacian, L1_laplacian, L2_laplacian; - /// Special face-related PCC elements - std::vector node_fsequence_vector, edge_fsequence_vector, face_sequence_vector, grain_fsequence_vector; // number of different sequences based on the face design vector - std::vector node_fstate_vector(CellNumbs.at(0),0), edge_fstate_vector(CellNumbs.at(1 + (dim - 3)),0), - face_state_vector(CellNumbs.at(2 + (dim - 3)),0), grain_fstate_vector(CellNumbs.at(3 + (dim - 3)),0); // number of different sequences based on the face design vector + std::vector node_fsequence_vector, edge_fsequence_vector, grain_fsequence_vector; // number of different sequences based on the face design vector + std::vector node_ori_vector(CellNumbs.at(0),0), edge_ori_vector(CellNumbs.at(1 + (dim - 3)),0), + face_ori_vector(CellNumbs.at(2 + (dim - 3)),0), grain_ori_vector(CellNumbs.at(3 + (dim - 3)),0); // number of different sequences based on the face design vector - unsigned int node_numerator = 0, edge_numerator = 0, face_numerator = 0, grain_numerator = 0; - face_sequence_vector = cells_design.Get_f_sequence(); // face sequence from cells_design after Processing +// unsigned int node_numerator = 0, edge_numerator = 0, grain_numerator = 0; /// faces loop for (auto itf = face_sequence_vector.begin(); itf != face_sequence_vector.end(); ++itf) { // grains for (unsigned int g = 0; g < CellNumbs.at(3 + (dim - 3)); ++g) // Loop over all the Grains in the PCC if (GFS.coeff(*itf, g) != 0) { - grain_fsequence_vector.push_back(g); + std::vector::iterator pointer_to_grain = std::find(grain_fsequence_vector.begin(), grain_fsequence_vector.end(),g); + +// if(grain_fsequence_vector.size() == 0) +// grain_fsequence_vector.push_back(g); + + if(pointer_to_grain == grain_fsequence_vector.end()) { + + if (GFS.coeff(*itf, g) == 1) { + grain_ori_vector.at(g) = 1; + sGF_triplet_list.push_back(Tr(distance(face_sequence_vector.begin(), itf), distance(grain_fsequence_vector.begin(), grain_fsequence_vector.end()), +1)); + } else if (GFS.coeff(*itf, g) == -1) { + grain_ori_vector.at(g) = -1; + sGF_triplet_list.push_back(Tr(distance(face_sequence_vector.begin(), itf), distance(grain_fsequence_vector.begin(), grain_fsequence_vector.end()), -1)); + } + /// push back + grain_fsequence_vector.push_back(g); + } // end if(pointer_to_grain == grain_fsequence_vector.end()) + else if(pointer_to_grain != grain_fsequence_vector.end()) { + if (GFS.coeff(*itf, g) == 1) { + grain_ori_vector.at(g) = 1; + sGF_triplet_list.push_back(Tr(distance(face_sequence_vector.begin(), itf), distance(grain_fsequence_vector.begin(), pointer_to_grain), +1)); + } else if (GFS.coeff(*itf, g) == -1) { + grain_ori_vector.at(g) = -1; + sGF_triplet_list.push_back(Tr(distance(face_sequence_vector.begin(), itf), distance(grain_fsequence_vector.begin(), pointer_to_grain), -1)); + } + } // else if(pointer_to_grain != grain_fsequence_vector.end()) { + } // end if (GFS.coeff(*itf, g) == 1) + + // edges + for (unsigned int e = 0; e < CellNumbs.at(1 + (dim - 3)); ++e) // Loop over all the Edges in the PCC + if (FES.coeff(e, *itf) != 0) { + std::vector::iterator pointer_to_edge = std::find(edge_fsequence_vector.begin(), edge_fsequence_vector.end(),e); + +// if(edge_fsequence_vector.size() == 0) +// edge_fsequence_vector.push_back(e); - if (GFS.coeff(*itf, g) == 1) { - grain_fstate_vector.at(g) = 1; - sGF_triplet_list.push_back(Tr(distance(face_sequence_vector.begin(), itf),grain_numerator++,+1)); + if(pointer_to_edge == edge_fsequence_vector.end()) { + + if (FES.coeff(e, *itf) == 1) { + edge_ori_vector.at(e) = 1; + sFE_triplet_list.push_back(Tr(distance(edge_fsequence_vector.begin(), edge_fsequence_vector.end()), distance(face_sequence_vector.begin(), itf),1)); + } else if (FES.coeff(e, *itf) == -1) { + edge_ori_vector.at(e) = -1; + sFE_triplet_list.push_back(Tr(distance(edge_fsequence_vector.begin(), edge_fsequence_vector.end()), distance(face_sequence_vector.begin(), itf),-1)); } - else if (GFS.coeff(*itf, g) == -1) { - grain_fstate_vector.at(g) = -1; - sGF_triplet_list.push_back(Tr(distance(face_sequence_vector.begin(), itf), grain_numerator++, -1)); + /// push back + edge_fsequence_vector.push_back(e); + } // end of if(pointer_to_edge == edge_fsequence_vector.end()) + else if(pointer_to_edge != edge_fsequence_vector.end()) { + if (FES.coeff(e, *itf) == 1) { + edge_ori_vector.at(e) = 1; + sFE_triplet_list.push_back(Tr(distance(edge_fsequence_vector.begin(), pointer_to_edge), distance(face_sequence_vector.begin(), itf),1)); + } else if (FES.coeff(e, *itf) == -1) { + edge_ori_vector.at(e) = -1; + sFE_triplet_list.push_back(Tr(distance(edge_fsequence_vector.begin(), pointer_to_edge), distance(face_sequence_vector.begin(), itf),-1)); } - } // end if (GFS.coeff(*itf, g) == 1) + } // end of if(pointer_to_edge == edge_fsequence_vector.end()) - for (unsigned int e = 0; e < CellNumbs.at(1 + (dim - 3)); ++e) // Loop over all the Edges in the PCC - if (FES.coeff(e, *itf) != 0) { - edge_fsequence_vector.push_back(e); - - if (FES.coeff(e, *itf) == 1) { - edge_fstate_vector.at(e) = 1; - sFE_triplet_list.push_back(Tr(edge_numerator++,distance(face_sequence_vector.begin(), itf),+1)); - } - else if (FES.coeff(e, *itf) == -1) { - edge_fstate_vector.at(e) = -1; - sFE_triplet_list.push_back(Tr(edge_numerator++,distance(face_sequence_vector.begin(), itf),-1)); - } - } // end of if (FES.coeff(e, fseq) != 0) + } // end of if (FES.coeff(e, fseq) != 0) } // end for (auto itf = face_sequence_vector.begin(); itf != face_sequence_vector.end(); ++itf) +// REPAIR for (auto sge : sGF_triplet_list) +// cout << "sfe: " << sge.row() << " " << sge.col() << " " << sge.value() << endl; +// cout << endl; +// REPAIR for (auto sfe : sFE_triplet_list) +// cout << "sfe: " << sfe.row() << " " << sfe.col() << " " << sfe.value() << endl; + + /// Sparse matrices (Eigen/ Spectra) + SpMat FEM_SpecialCells(edge_fsequence_vector.size(), face_sequence_vector.size()), + GFM_SpecialCells(face_sequence_vector.size(),grain_fsequence_vector.size()); + +// cout << "F_G" << endl; +// for (auto gtl : sGF_triplet_list) +// cout << gtl.col() << " " << gtl.row() << " " << gtl.value() << endl; +//cout << endl; +// cout << "E_F" << endl; +// for (auto ftl : sFE_triplet_list) +// cout << ftl.col() << " " << ftl.row() << " " << ftl.value() << endl; +// cout << endl; +// cout << edge_fsequence_vector.size() << " " << face_sequence_vector.size() << " " << grain_fsequence_vector.size() << endl; + +// for (auto fss : face_sequence_vector) +// cout << fss << " "; +// cout << endl; + + /// Forming sparse Incidence matrices: B1 and B2 + GFM_SpecialCells.setFromTriplets(sGF_triplet_list.begin(), sGF_triplet_list.end()); + FEM_SpecialCells.setFromTriplets(sFE_triplet_list.begin(), sFE_triplet_list.end()); + if (dim == 3) { // nodes - only for the 3D case + /// faces loop for (auto ite = edge_fsequence_vector.begin(); ite != edge_fsequence_vector.end(); ++ite) { - for (unsigned int n = 0; n < CellNumbs.at(0); ++n) // Loop over all the Nodes in the PCC + for (unsigned int n = 0; n < CellNumbs.at(0); ++n) {// Loop over all the Nodes in the PCC +// cout << "HERE3: " << *ite << " " << n << endl; + if (ENS.coeff(n, *ite) != 0) { - node_fsequence_vector.push_back(n); - - if (edge_fstate_vector.at(distance(edge_fsequence_vector.begin(), ite)) == 1) { - node_fstate_vector.at(n) = 1; - sEN_triplet_list.push_back( - Tr(node_numerator++, distance(edge_fsequence_vector.begin(), ite), +1)); - } else if (edge_fstate_vector.at(distance(edge_fsequence_vector.begin(), ite)) == -1) { - node_fstate_vector.at(n) = -1; - sEN_triplet_list.push_back( - Tr(node_numerator++, distance(edge_fsequence_vector.begin(), ite), -1)); - } + std::vector::iterator pointer_to_node = std::find(node_fsequence_vector.begin(), node_fsequence_vector.end(),n); + +// if(node_fsequence_vector.size() == 0) +// node_fsequence_vector.push_back(n); + + if(pointer_to_node == node_fsequence_vector.end()) { + if (ENS.coeff(n, *ite) == 1) { +// cout << "HERE33: " << *ite << " " << n << endl; + node_ori_vector.at(n) = 1; + // cout << "HERE34: " << *ite << " " << n << endl; + sEN_triplet_list.push_back(Tr(distance(node_fsequence_vector.begin(), node_fsequence_vector.end()), distance(edge_fsequence_vector.begin(), ite),1)); + + } else if (ENS.coeff(n, *ite) == -1) { + node_ori_vector.at(n) = -1; + sEN_triplet_list.push_back(Tr(distance(node_fsequence_vector.begin(), node_fsequence_vector.end()), distance(edge_fsequence_vector.begin(), ite),-1)); + // cout << "HERE5: " << *ite << " " << n << endl; + } + /// push back + node_fsequence_vector.push_back(n); + } // end of if(pointer_to_node == edge_fsequence_vector.end()) + else if(pointer_to_node != node_fsequence_vector.end()) { + if (ENS.coeff(n, *ite) == 1) { + node_ori_vector.at(n) = 1; +// cout << "HERE34: " << *ite << " " << n << endl; + sEN_triplet_list.push_back(Tr(distance(node_fsequence_vector.begin(), pointer_to_node), distance(edge_fsequence_vector.begin(), ite),1)); + } else if (ENS.coeff(n, *ite) == -1) { + node_ori_vector.at(n) = -1; + sEN_triplet_list.push_back(Tr(distance(node_fsequence_vector.begin(), pointer_to_node), distance(edge_fsequence_vector.begin(), ite),-1)); +// cout << "HERE5: " << *ite << " " << n << endl; + } + } // end of else if(pointer_to_node != node_fsequence_vector.end()) + } // end of if (ENS.coeff(n, *ite) != 0) + } // end of for (unsigned int n = 0; n < CellNumbs.at(0); ++n) + } // end of for (auto ite = edge_fsequence_vector.begin(); ite != edge_fsequence_vector.end(); ++ite) } // end of if (dim == 3) + SpMat ENM_SpecialCells(node_fsequence_vector.size(),edge_fsequence_vector.size()); -/// Forming sparse Incidence matrices: B0, B1 and B2 + /// Forming sparse Incidence matrix: B0 ENM_SpecialCells.setFromTriplets(sEN_triplet_list.begin(), sEN_triplet_list.end()); - FEM_SpecialCells.setFromTriplets(sFE_triplet_list.begin(), sFE_triplet_list.end()); - GFM_SpecialCells.setFromTriplets(sGF_triplet_list.begin(), sGF_triplet_list.end()); /// Identity matrices + std::vector NSize_tr_list, ESize_tr_list, FSize_tr_list; SpMat Id_NSize(ENM_SpecialCells.rows(), ENM_SpecialCells.rows()), Id_ESize(ENM_SpecialCells.cols(),ENM_SpecialCells.cols()), Id_FSize(FEM_SpecialCells.cols(), FEM_SpecialCells.cols()); +// cout << "HERE1" << endl; + for (auto i = 0; i < ENM_SpecialCells.rows(); ++i) for (auto j = 0; j < ENM_SpecialCells.rows(); ++j) - if (i == j) Id_NSize.coeffRef(i,j) = 1; - else Id_NSize.coeffRef(i,j) = 0; + if (i == j) NSize_tr_list.push_back(Tr(i, j, 1)); + else NSize_tr_list.push_back(Tr(i, j, 0)); + + Id_NSize.setFromTriplets(NSize_tr_list.begin(), NSize_tr_list.end()); +// cout << "HERE2" << endl; + for (auto i = 0; i < ENM_SpecialCells.cols(); ++i) for (auto j = 0; j < ENM_SpecialCells.cols(); ++j) - if (i == j) Id_ESize.coeffRef(i,j) = 1; - else Id_ESize.coeffRef(i,j) = 0; + if (i == j) ESize_tr_list.push_back(Tr(i, j, 1)); + else ESize_tr_list.push_back(Tr(i, j, 0)); + + Id_ESize.setFromTriplets(ESize_tr_list.begin(), ESize_tr_list.end()); +// cout << "HERE3" << endl; + for (auto i = 0; i < FEM_SpecialCells.cols(); ++i) for (auto j = 0; j < FEM_SpecialCells.cols(); ++j) - if (i == j) Id_FSize.coeffRef(i,j) = 1; - else Id_FSize.coeffRef(i,j) = 0; + if (i == j) FSize_tr_list.push_back(Tr(i, j, 1)); + else FSize_tr_list.push_back(Tr(i, j, 0)); + + Id_FSize.setFromTriplets(FSize_tr_list.begin(), FSize_tr_list.end()); +// cout << "HERE4" << endl; + +// cout << "HERE and Now 9 ! " << FEM_SpecialCells.cols() << " " << ENM_SpecialCells.cols() << " " << ENM_SpecialCells.rows() << endl; +// cout << "HERE and Now 9 ! " << Id_FSize.rows() << " " << Id_ESize.cols() << " " << Id_NSize.rows() << endl; +// cout << "HERE and Now 9 ! " << Id_FSize.nonZeros() << " " << Id_ESize.nonZeros() << " " << Id_NSize.nonZeros() << endl; + + SpMat L0_laplacian, L1_laplacian, L2_laplacian; +// cout << "HERE5" << endl; L0_laplacian = ENM_SpecialCells * ENM_SpecialCells.transpose(); - L1_laplacian = ENM_SpecialCells.transpose()*Id_NSize*ENM_SpecialCells*Id_ESize + Id_ESize*FEM_SpecialCells*Id_FSize*FEM_SpecialCells.transpose(); +// cout << "HERE51" << endl; + SpMat L11_laplacian = ENM_SpecialCells.transpose()*Id_NSize*ENM_SpecialCells*Id_ESize; +// cout << "HERE52" << endl; + SpMat L12_laplacian = Id_ESize*FEM_SpecialCells*Id_FSize*FEM_SpecialCells.transpose(); +// cout << "HERE53" << endl; + L1_laplacian = L11_laplacian + L12_laplacian; +// cout << "HERE4" << endl; L2_laplacian = FEM_SpecialCells.transpose()*Id_ESize*FEM_SpecialCells*Id_FSize; +// cout << "HERE6" << endl; laplacians_vector = { L0_laplacian, L1_laplacian, L2_laplacian }; -/// Adjacency matrices A0, A1, A2, A3 -// SpAM_SpecFaces = 0.5 * (SpAM_SpecFaces + SparseMatrix(SpAM_SpecFaces.transpose())); // Full matrix instead of triagonal - return laplacians_vector; } // end of std::vector> ReducedLaplacians( ) /// # 1 # All eigenvalues (spectrum) of a Linear Operator OSM -std::vector OperatorSpectrum(Eigen::SparseMatrix const &OSM, std::vector &CellNumbs) { // OSM - operator's sparse matrix +std::vector OperatorSpectrum(Eigen::SparseMatrix const &OSM) { // OSM - operator's sparse matrix std::vector operator_spectrum; // function's output Eigen::VectorXcd eigval; @@ -169,7 +250,7 @@ return operator_spectrum; } //END of OperatorSpectrum() /// # 2 # All eigenvectors of a Linear Operator OSM -Eigen::MatrixXcd OperatorEigvectors(Eigen::SparseMatrix const &OSM, std::vector &CellNumbs) { // OSM - operator's sparse matrix +Eigen::MatrixXcd OperatorEigvectors(Eigen::SparseMatrix const &OSM) { // OSM - operator's sparse matrix //std::vector operator_spectrum; // function's output Eigen::MatrixXcd eigvec; @@ -191,4 +272,41 @@ eigvec = eigs.eigenvectors(); } return eigvec; -} //END of OperatorSpectrum() \ No newline at end of file +} //END of OperatorSpectrum() + +/// # 3 # Betti numbers + +std::vector OperatorsBetti(std::vector &face_sequence_vector, SpMat &ENS, SpMat &FES, SpMat &GFS) { + std::vector Betti_vector; + std::vector> Laplace_spectra; + + std::vector Laplacians_vector; // [0] -> L0, [1] -> L1, [2] -> L2 + cout << "[OperatorsBetti] Start of the creation Reduced Face Laplacians: " << endl; + Laplacians_vector = ReducedFaceLaplacians(face_sequence_vector, ENS, FES, GFS); + + cout << "[OperatorsBetti] face sequence vector size: " << face_sequence_vector.size() << endl; + cout << "[OperatorsBetti] Reduced Laplacians row sizes: " << Laplacians_vector.at(0).rows() << " " << Laplacians_vector.at(0).cols() << " " << Laplacians_vector.at(1).rows() << " " << Laplacians_vector.at(1).cols() << " " << Laplacians_vector.at(2).rows() << " " << Laplacians_vector.at(2).cols() << endl; + Out_logfile_stream << "[OperatorsBetti] face sequence vector size: " << face_sequence_vector.size() << endl; + Out_logfile_stream << "[OperatorsBetti] Reduced Laplacians row sizes: " << Laplacians_vector.at(0).rows() << " " << Laplacians_vector.at(0).cols() << " " << Laplacians_vector.at(1).rows() << " " << Laplacians_vector.at(1).cols() << " " << Laplacians_vector.at(2).rows() << " " << Laplacians_vector.at(2).cols() << endl; + + cout << "[OperatorsBetti] Start of the Laplacians' spectra calculation: " << endl; + Out_logfile_stream << "[OperatorsBetti] Start of the Laplacians' spectra calculation: " << endl; + +#pragma omp parallel for // parallel execution by OpenMP + for (auto LVS : Laplacians_vector) { + Laplace_spectra.push_back(OperatorSpectrum(LVS)); + cout << "[OperatorsBetti] Reduced Laplacians' spectra size: " << Laplace_spectra.back().size() << " "; + Out_logfile_stream << "[OperatorsBetti] Reduced Laplacians' spectra size: " << Laplace_spectra.back().size() << " "; +// REPAIR for(auto sp : Laplace_spectra.back()) // cout << sp << " "; cout << endl; + } + + cout << endl << "[OperatorsBetti] Start of the Betti numbers calculation: " << endl; + Out_logfile_stream << endl << "[OperatorsBetti] Start of the Betti numbers calculation: " << endl; + int Betticounter = 0; + for (auto ls : Laplace_spectra) { // normally only 3 vectors + Betti_vector.push_back(std::count(ls.begin(), ls.end(), 0)); + cout << "[OperatorsBetti] Betti " << Betticounter++ << " is equal to " << Betti_vector.back() << endl; + Out_logfile_stream << "[OperatorsBetti] Betti " << Betticounter << " is equal to " << Betti_vector.back() << endl; + } + return Betti_vector; +} \ No newline at end of file diff --git a/src/lib/PCC_Characterisation/PCC_StructureCharacterisation.h b/src/lib/PCC_Characterisation/PCC_StructureCharacterisation.h index 3d5595fa..2bc5a289 100644 --- a/src/lib/PCC_Characterisation/PCC_StructureCharacterisation.h +++ b/src/lib/PCC_Characterisation/PCC_StructureCharacterisation.h @@ -10,8 +10,8 @@ ProcessedComplex PCC_StructureCharacterisation(CellsDesign &new_cells_design) { ProcessedComplex PCC_characteristics; // module output /// Read simulation configuration from file :: the number of special face types and calculating parameters. Then Output of the current configuration to the screen - std::vector charlabs_polyhedrons, charlabs_faces, charlabs_edges, charlabs_nodes; - std::vector ConfigVector = config_reader_characterisation(source_path, charlabs_polyhedrons, charlabs_faces, charlabs_edges, charlabs_nodes, Out_logfile_stream); // vector (!) from ini_readers.h library + std::vector charlabs_polyhedrons, charlabs_faces, charlabs_edges, charlabs_nodes, charlabs_laplacians; + std::vector ConfigVector = config_reader_characterisation(source_path, charlabs_polyhedrons, charlabs_faces, charlabs_edges, charlabs_nodes, charlabs_laplacians, Out_logfile_stream); // vector (!) from ini_readers.h library /// # 1 # Creation of the State Vectors // Faces @@ -26,49 +26,119 @@ ProcessedComplex PCC_StructureCharacterisation(CellsDesign &new_cells_design) { } // end for(auto fseq...) - for (int i = 0; i < 4; ++i) { // for all types of cells + for (int i = 0; i < 4; ++i) { /// for all types of cells + + /// # 2 # Measures: fractions and entropies + if(i == 1 && charlabs_edges.size() > 0) { // Edges lab + if (charlabs_edges.at(0) == 1) { + vector EdgeTypes_char(CellNumbs.at(1 + (dim - 3)), + 0); // vector in the form [ 0 2 3 3 2 1 ...] with the TJs type ID as its values + std::vector j_edge_fractions(dim + 1, 0), d_edge_fractions(dim, + 0); // fractions of (1) edges of different types and (2) edges of different degrees + + /// for each state: + tuple conf_entropy_t; + for (auto current_seq: PCC_characteristics.face_process_seq) { + EdgeTypes_char.clear(); + std::fill(j_edge_fractions.begin(), j_edge_fractions.end(), 0); + std::fill(d_edge_fractions.begin(), d_edge_fractions.end(), 0); + + EdgeTypes_char = Edge_types_byFaces(CellNumbs, current_seq, j_edge_fractions, d_edge_fractions); + + conf_entropy_t = Configuration_Entropy_tuple(j_edge_fractions); // conf entropy + + PCC_characteristics.e_entropy_mean_vector.push_back(std::get<0>( + conf_entropy_t)); // std::tuple Configuration_Entropy_tuple(std::vector const &j_fractions) based on Edges fraction vector + PCC_characteristics.e_entropy_skrew_vector.push_back(std::get<1>(conf_entropy_t)); // tuple + //// MUST BE IMPROVED (!) : + PCC_characteristics.e_entropy_full_vector.push_back( + std::get<0>(conf_entropy_t) + std::get<1>(conf_entropy_t)); + + PCC_characteristics.je_fractions_vector.push_back(j_edge_fractions); + PCC_characteristics.de_fractions_vector.push_back(d_edge_fractions); + } // for (auto current_seq : PCC_characteristics.face_process_seq) + + if (charlabs_edges.at(4) == 1) { // analytical + /// Measures: Analytical solutions for edge fractions and configuration entropies + std::vector> AnalyticalRandEntropies, AnalyticalCrystEntropies; + PCC_characteristics.j_analytical_rand_vector = TJsAnalytics_random(CellNumbs.at(2 + (dim - 3)), + AnalyticalRandEntropies); + PCC_characteristics.AnRandEntropies_vector = AnalyticalRandEntropies; + + PCC_characteristics.j_analytical_cryst_vector = TJsAnalytics_crystallography( + CellNumbs.at(2 + (dim - 3)), AnalyticalCrystEntropies); + PCC_characteristics.AnCrystEntropies_vector = AnalyticalCrystEntropies; + + // analytical edge degree fractions + PCC_characteristics.d_analytical_rand_vector = TJDsAnalytics_random(CellNumbs.at(2 + (dim - 3))); + PCC_characteristics.d_analytical_cryst_vector = TJDsAnalytics_crystallography( + CellNumbs.at(2 + (dim - 3))); + } // enf if(charlabs_edges.at(4) == 1) + + } // end of if(charlabs_edges.at(0) == 1) + } // end of if(i == 1 && charlabs_edges.at(0) == 1) { // Edges lab - /// # 2 # Measures: fractions and entropies - if(i == 1 && charlabs_edges.at(0) == 1) { // Edges lab - vector EdgeTypes_char(CellNumbs.at(1 + (dim - 3)), 0); // vector in the form [ 0 2 3 3 2 1 ...] with the TJs type ID as its values - std::vector j_edge_fractions(dim+1,0), d_edge_fractions(dim,0); // fractions of (1) edges of different types and (2) edges of different degrees - - /// for each state: - tuple conf_entropy_t; - for (auto current_seq : PCC_characteristics.face_process_seq) { - EdgeTypes_char.clear(); - std::fill(j_edge_fractions.begin(), j_edge_fractions.end(),0); - std::fill(d_edge_fractions.begin(), d_edge_fractions.end(),0); - - EdgeTypes_char = Edge_types_byFaces(CellNumbs, current_seq, j_edge_fractions, d_edge_fractions); - - conf_entropy_t = Configuration_Entropy_tuple(j_edge_fractions); // conf entropy - - PCC_characteristics.e_entropy_mean_vector.push_back(std::get<0>(conf_entropy_t)); // std::tuple Configuration_Entropy_tuple(std::vector const &j_fractions) based on Edges fraction vector - PCC_characteristics.e_entropy_skrew_vector.push_back(std::get<1>(conf_entropy_t)); // tuple - //// MUST BE IMPROVED (!) : - PCC_characteristics.e_entropy_full_vector.push_back( std::get<0>(conf_entropy_t) + std::get<1>(conf_entropy_t)); - - PCC_characteristics.je_fractions_vector.push_back(j_edge_fractions); - PCC_characteristics.de_fractions_vector.push_back(d_edge_fractions); - } - - if(charlabs_edges.at(4) == 1) { // analytical - /// Measures: Analytical solutions for edge fractions and configuration entropies - std::vector> AnalyticalRandEntropies, AnalyticalCrystEntropies; - PCC_characteristics.j_analytical_rand_vector = TJsAnalytics_random(CellNumbs.at(2 + (dim - 3)), AnalyticalRandEntropies); - PCC_characteristics.AnRandEntropies_vector = AnalyticalRandEntropies; - - PCC_characteristics.j_analytical_cryst_vector = TJsAnalytics_crystallography(CellNumbs.at(2 + (dim - 3)), AnalyticalCrystEntropies); - PCC_characteristics.AnCrystEntropies_vector = AnalyticalCrystEntropies; - - // analytical edge degree fractions - PCC_characteristics.d_analytical_rand_vector = TJDsAnalytics_random(CellNumbs.at(2 + (dim - 3))); - PCC_characteristics.d_analytical_cryst_vector = TJDsAnalytics_crystallography(CellNumbs.at(2 + (dim - 3))); - } // enf if(charlabs_edges.at(4) == 1) - - } // if(i == 1 && charlabs_edges.at(0) == 1) { // Edges lab } // end for (int i = 0; i < 4; ++i) + /// # 3 # Laplacians of specail cells + if(charlabs_laplacians.at(1) == 1) { +// AN - Nodes (Vertices or 0-Cells) sparse adjacency matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values +// AE - Edges (Triple Junctions or 1-Cells) sparse adjacency matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values +// AF - Faces (Grain Boundaries or 2-Cells) sparse adjacency matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values +// AG - Grains (Volumes or 3-Cells) sparse adjacency matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values +// MEN - Edges - Nodes (1-Cells to 0-Cells) sparse incidence matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values +// MFE - Faces - Edges (2-Cells to 1-Cells) sparse incidence matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values +// MGF - Grains - Faces (3-Cells to 2-Cells) sparse incidence matrix in the form of three column {i, j, value}, where i and j are the indices of elements with non-zero values // odir - source path + +/// Adjacency sparse matrix for nodes /// Adjacency sparse matrix for edges /// Adjacency sparse matrix for faces /// Adjacency sparse matrix for grains +// SpMat ANS(CellNumbs.at(0), CellNumbs.at(0)), AES(CellNumbs.at(1 + (dim - 3)), CellNumbs.at(1 + (dim - 3))), AFS(CellNumbs.at(2 + (dim - 3)), CellNumbs.at(2 + (dim - 3))), AGS(CellNumbs.at(3 + (dim - 3)), CellNumbs.at(3 + (dim - 3))); +// ANS = SMatrixReader(paths.at(0), (CellNumbs.at(0)), (CellNumbs.at(0))); //all Nodes +// ANS = 0.5 * (ANS + SparseMatrix(ANS.transpose())); // Full matrix instead of triagonal +// AES = SMatrixReader(paths.at(1 + (dim - 3)), (CellNumbs.at(1 + (dim - 3))), (CellNumbs.at(1 + (dim - 3)))); //all Edges +// AES = 0.5 * (AES + SparseMatrix(AES.transpose())); // Full matrix instead of triagonal +// AFS = SMatrixReader(paths.at(2 + (dim - 3)), (CellNumbs.at(2 + (dim - 3))), (CellNumbs.at(2 + (dim - 3)))); //all Faces +// AFS = 0.5 * (AFS + SparseMatrix(AFS.transpose())); // Full matrix instead of triagonal +// AGS = SMatrixReader(paths.at(3 + (dim - 3)), (CellNumbs.at(3 + (dim - 3))), (CellNumbs.at(3 + (dim - 3)))); //all Volumes +// AGS = 0.5 * (AGS + SparseMatrix(AGS.transpose())); // Full matrix instead of triagonal + +/// Incidence sparse matrix for Edges and Nodes /// Incidence sparse matrix for Faces and Edges /// Incidence sparse matrix for Grains and Faces + SpMat ENS(CellNumbs.at(0), CellNumbs.at(1)), FES(CellNumbs.at(1 + (dim - 3)), CellNumbs.at(2 + (dim - 3))), GFS( + CellNumbs.at(2 + (dim - 3)), CellNumbs.at(3 + (dim - 3))); + + ENS = SMatrixReader(paths.at(4 + (dim - 3)), (CellNumbs.at(0)), (CellNumbs.at(1))); //all Nodes-Edges + FES = SMatrixReader(paths.at(5 + (dim - 3)), (CellNumbs.at(1 + (dim - 3))), + (CellNumbs.at(2 + (dim - 3)))); //all Edges-Faces + GFS = SMatrixReader(paths.at(6 + (dim - 3)), (CellNumbs.at(2 + (dim - 3))), + (CellNumbs.at(3 + (dim - 3)))); //all Faces-Grains + + double number_of_steps = (double) charlabs_laplacians.at(0); // reading from Characterisation.ini file (!) + unsigned int d_seq = std::floor((double) PCC_characteristics.face_process_seq.size() / number_of_steps); + std::vector new_current_seq; + std::vector new_Betti_numbers; + + std::vector Betti_calc_time; + +#pragma omp parallel for // parallel execution by OpenMP + for (unsigned int i = 0; i <= number_of_steps; ++i) { + new_current_seq = PCC_characteristics.face_process_seq.at(i*d_seq); + cout << "---------------------------------------------------------------------------" << endl; + cout << "[CHAR] Current special faces fraction: " << new_current_seq.size()/ (double) CellNumbs.at(2 + (dim - 3)) << endl; + Out_logfile_stream << "---------------------------------------------------------------------------" << endl; + Out_logfile_stream << "[CHAR] Current special faces fraction: " << new_current_seq.size()/ (double) CellNumbs.at(2 + (dim - 3)) << endl; + // Elapsing time for 3 Betti numbers + clock_t t; + Betti_calc_time.push_back(clock()); + + new_Betti_numbers = OperatorsBetti(new_current_seq, ENS, FES, GFS); + cout << "[CHAR] p & Betti numbers: " << new_current_seq.size()/ (double) CellNumbs.at(2) << " " << new_Betti_numbers.at(0) << " " << new_Betti_numbers.at(1) << " " << new_Betti_numbers.at(2) << endl; + Out_logfile_stream << "[CHAR] p & Betti numbers: " << new_current_seq.size()/ (double) CellNumbs.at(2) << " " << new_Betti_numbers.at(0) << " " << new_Betti_numbers.at(1) << " " << new_Betti_numbers.at(2) << endl; + // + Betti_calc_time.back() = clock() - Betti_calc_time.back(); + cout << "[CHAR] Calculation time [s] of the Betti numbers is equal to " << Betti_calc_time.back()/ pow(10.0,6.0)<< endl; + Out_logfile_stream << "[CHAR] Calculation time [s] of the Betti numbers is equal to " << Betti_calc_time.back()/ pow(10.0,6.0)<< endl; + + PCC_characteristics.Betti_vector.push_back({new_current_seq.size()/(double) CellNumbs.at(2), new_Betti_numbers.at(0), new_Betti_numbers.at(1), new_Betti_numbers.at(2)}); + } + } // end of for (int i = 0; i < number_of_steps, ++i) return PCC_characteristics; } \ No newline at end of file diff --git a/src/lib/PCC_Objects.h b/src/lib/PCC_Objects.h index 784e17f7..3a5d8e9b 100644 --- a/src/lib/PCC_Objects.h +++ b/src/lib/PCC_Objects.h @@ -695,18 +695,22 @@ class ProcessedComplex { // Essential for Characterisation module pcc_design = pcc_design; } + // Sequences of special k-cells std::vector> face_process_seq; std::vector> face_process_state; + // Entropic analysis std::vector e_entropy_mean_vector, e_entropy_skrew_vector, e_entropy_full_vector; - std::vector> je_fractions_vector, de_fractions_vector; - // analytical solutions + // Analytical solutions std::vector> j_analytical_rand_vector, d_analytical_rand_vector; std::vector> j_analytical_cryst_vector, d_analytical_cryst_vector; std::vector> AnRandEntropies_vector, AnCrystEntropies_vector; + // Laplacian lab + std::vector> Betti_vector; + }; /// end of class ProcessedComplex #endif diff --git a/src/lib/PCC_Writer/PCC_Writer.h b/src/lib/PCC_Writer/PCC_Writer.h index f530b022..2d75013b 100644 --- a/src/lib/PCC_Writer/PCC_Writer.h +++ b/src/lib/PCC_Writer/PCC_Writer.h @@ -16,9 +16,14 @@ config_reader_writer(source_path, writer_specifications, Out_logfile_stream); // int output_counter = 0; // special counter for output numeration /// Output special and ordinary face sequences to the output directory specified in config.txt - PCC_CellSequences_Writer(new_cells_design, output_counter); - PCC_Entropic_Writer(pcc_processed, output_counter); - PCC_AnalyticalFractions_Writer(pcc_processed, output_counter); // analytical solutions + if (writer_specifications.at(0) == 1) + PCC_CellSequences_Writer(new_cells_design, output_counter); + if (writer_specifications.at(2) == 1) + PCC_Entropic_Writer(pcc_processed, output_counter); + if (writer_specifications.at(5) == 1) + PCC_AnalyticalFractions_Writer(pcc_processed, output_counter); // analytical solutions + if(writer_specifications.at(7) == 1) + PCC_Laplacians_Writer(pcc_processed, output_counter); /* char* stype = const_cast(P_type.c_str()); // Processing type variable diff --git a/src/lib/PCC_Writer/Writer_Functions.h b/src/lib/PCC_Writer/Writer_Functions.h index c04cbd4b..f43df68d 100644 --- a/src/lib/PCC_Writer/Writer_Functions.h +++ b/src/lib/PCC_Writer/Writer_Functions.h @@ -175,6 +175,19 @@ void PCC_AnalyticalFractions_Writer(ProcessedComplex &pcc_processed, int &output } // END of PCC_AnalyticalFractions_Writer( ) +void PCC_Laplacians_Writer(ProcessedComplex &pcc_processed, int &output_counter) { + ofstream OutBettiFile; // Betti numbers output + string betti_odir = output_dir + "Betti numbers.txt"s; // output directory + + for (auto BV : pcc_processed.Betti_vector) + OutBettiFile << BV.at(0) << " " << BV.at(1) << " " << BV.at(2) << " " << BV.at(3) << endl; + + OutBettiFile.close(); + + cout << "(" << output_counter++ << ") " << "Betti numbers of the special cell structure evolution has been successfully written in " << betti_odir << endl; + Out_logfile_stream << "(" << output_counter << ") " << "Betti numbers of the special cell structure evolution has been successfully written in " << betti_odir << endl; +} // END of PCC_Laplacians_Writer() + /// * NEW HEAP * /// /** diff --git a/src/lib/ini/ini_readers.h b/src/lib/ini/ini_readers.h index 16106134..d282ea9e 100644 --- a/src/lib/ini/ini_readers.h +++ b/src/lib/ini/ini_readers.h @@ -500,7 +500,7 @@ vector max_fractions_output(3, 0); // temporary vector serving as an out return; } /// END of config_reader_processing function -std::vector config_reader_characterisation(std::string const &source_path, std::vector &charlabs_polyhedrons, std::vector &charlabs_faces, std::vector &charlabs_edges, std::vector &charlabs_nodes, std::ofstream &Out_logfile_stream) { +std::vector config_reader_characterisation(std::string const &source_path, std::vector &charlabs_polyhedrons, std::vector &charlabs_faces, std::vector &charlabs_edges, std::vector &charlabs_nodes, std::vector &charlabs_laplacians, std::ofstream &Out_logfile_stream) { std::vector config_characterisation_vector; // ini files reader - external (MIT license) library @@ -645,6 +645,21 @@ std::vector config_reader_characterisation(std::string const &source_pat charlabs_nodes.push_back(stoi(char_ini.get("nodes_lab").get("S_skew"))); } } +/// Laplacians + if (char_ini.has("spectra_lab")) { + auto& collection = char_ini["spectra_lab"]; + if (collection.has("calc_steps_numb")) + { + charlabs_laplacians.push_back(stoi(char_ini.get("spectra_lab").get("calc_steps_numb"))); // 0 + } } + + if (char_ini.has("spectra_lab")) { + auto& collection = char_ini["spectra_lab"]; + if (collection.has("laplacians")) + { + charlabs_laplacians.push_back(stoi(char_ini.get("spectra_lab").get("laplacians"))); // 1 + } } + /// Output to the screen/console cout<< "______________________________________________________________________________________" << endl; cout << "The Characterisation module simulation type and initial parameters:\t\t" << endl; @@ -675,7 +690,6 @@ if(charlabs_polyhedrons.at(0) == 1) { // Polyhedrons cout << "Conf entropy mean part:\t"s << charlabs_edges.at(2) << "\t\t" << endl; cout << "Conf entropy skew part:\t"s << charlabs_edges.at(3) << "\t\t" << endl; cout << "Analytical solutions :\t"s << charlabs_edges.at(4) << "\t\t" << endl; - cout << endl; } // if(charlabs_edges.at(0) == 1) if(charlabs_nodes.at(0) == 1) { // Nodes @@ -685,6 +699,15 @@ if(charlabs_polyhedrons.at(0) == 1) { // Polyhedrons cout << endl; } // if(charlabs_polyhedrons.at(0) == 1) + if(charlabs_laplacians.at(0) > 0) { // Laplacians lab + cout << "Laplacians: number of calculation steps \t"s << charlabs_laplacians.at(0) << "\t\t" << endl; + cout << endl; + } // if(charlabs_laplacians.at(0) == 1) + + if(charlabs_laplacians.at(1) == 1) { // Laplacians lab + cout << "Special cell Laplacians:\t"s << charlabs_laplacians.at(1) << "\t\t" << endl; + cout << endl; + } // if(charlabs_laplacians.at(0) == 1) cout<< "______________________________________________________________________________________" << endl; /// Output into .log file @@ -724,8 +747,16 @@ if(charlabs_polyhedrons.at(0) == 1) { // Polyhedrons Out_logfile_stream << endl; } // if(charlabs_polyhedrons.at(0) == 1) - Out_logfile_stream<< "______________________________________________________________________________________" << endl; + if(charlabs_laplacians.at(0) > 0) { // Laplacians lab + Out_logfile_stream << "Laplacians: number of calculation steps \t"s << charlabs_laplacians.at(0) << "\t\t" << endl; + Out_logfile_stream << endl; + } // if(charlabs_laplacians.at(0) == 1) + if(charlabs_laplacians.at(1) == 1) { // Laplacians lab + Out_logfile_stream << "Special cell Laplacians:\t"s << charlabs_laplacians.at(1) << "\t\t" << endl; + Out_logfile_stream << endl; + } // if(charlabs_laplacians.at(0) == 1) + Out_logfile_stream<< "______________________________________________________________________________________" << endl; return config_characterisation_vector; } @@ -737,6 +768,7 @@ void config_reader_writer(std::string &source_path, std::vector writer_spec int isSequencesOutput; // - > [0] int isDesignvectorsOutput; // - > [1] int isEdgeConfEntropy = 0, isEdgeFractions = 0, isDegreeEdgeFractions = 0, isEdgeAnFractions = 0, isEdgeAnConfEntropies = 0; // [2], [3], [4], [5], [6] +int isBetti = 0; // Laplacians lab // ini files reader - external (MIT license) library mINI::INIFile file(source_path + "writer.ini"s); @@ -802,6 +834,14 @@ int isEdgeConfEntropy = 0, isEdgeFractions = 0, isDegreeEdgeFractions = 0, isEdg } } writer_specifications.push_back(isEdgeAnConfEntropies); // [6] +// III Laplacians + if (writer_ini.has("component_analysis")) { + auto& collection = writer_ini["component_analysis"]; + if (collection.has("isBetti")) + { + isBetti = stoi(writer_ini.get("component_analysis").get("isBetti")); + } } + writer_specifications.push_back(isBetti); // [7] /// Output to the screen/console // cout << endl; @@ -816,6 +856,7 @@ int isEdgeConfEntropy = 0, isEdgeFractions = 0, isDegreeEdgeFractions = 0, isEdg cout << "Analytical Edge fractions \t\t\t"s << writer_specifications.at(5) << endl; cout << "Analytical Edge degree fractions \t\t\t"s << writer_specifications.at(5) << endl; cout << "Analytical configuration Edges entropy \t\t\t"s << writer_specifications.at(6) << endl; + cout << "Laplacians and Betti numbers \t\t\t"s << writer_specifications.at(7) << endl; cout << endl; /// Output into .log file @@ -831,7 +872,7 @@ int isEdgeConfEntropy = 0, isEdgeFractions = 0, isDegreeEdgeFractions = 0, isEdg Out_logfile_stream << "Analytical Edge fractions \t\t\t"s << writer_specifications.at(5) << endl; Out_logfile_stream << "Analytical Edge degree fractions \t\t\t"s << writer_specifications.at(5) << endl; Out_logfile_stream << "Analytical configuration Edges entropy \t\t\t"s << writer_specifications.at(6) << endl; - + Out_logfile_stream << "Laplacians and Betti numbers \t\t\t"s << writer_specifications.at(7) << endl; Out_logfile_stream << endl; return;