13 const std::vector<std::pair<SimplexId, SimplexId>> &vertexLink)
const {
15 std::map<SimplexId, SimplexId> global2LowerLink, global2UpperLink;
16 std::map<SimplexId, SimplexId>::iterator neighborIt;
22 SimplexId neighborId = vertexLink[i].first;
26 if(offsets[neighborId] < offsets[vertexId]) {
28 neighborIt = global2LowerLink.find(neighborId);
29 if(neighborIt == global2LowerLink.end()) {
31 global2LowerLink[neighborId] = lowerCount;
37 if(offsets[neighborId] > offsets[vertexId]) {
39 neighborIt = global2UpperLink.find(neighborId);
40 if(neighborIt == global2UpperLink.end()) {
42 global2UpperLink[neighborId] = upperCount;
48 neighborId = vertexLink[i].second;
51 if(offsets[neighborId] < offsets[vertexId]) {
53 neighborIt = global2LowerLink.find(neighborId);
54 if(neighborIt == global2LowerLink.end()) {
56 global2LowerLink[neighborId] = lowerCount;
62 if(offsets[neighborId] > offsets[vertexId]) {
64 neighborIt = global2UpperLink.find(neighborId);
65 if(neighborIt == global2UpperLink.end()) {
67 global2UpperLink[neighborId] = upperCount;
74 printMsg(
"Vertex #" + std::to_string(vertexId) +
" lower link ("
75 + std::to_string(lowerCount) +
" vertices)",
77 printMsg(
"Vertex #" + std::to_string(vertexId) +
" upper link ("
78 + std::to_string(upperCount) +
" vertices)",
96 std::vector<UnionFind> lowerSeeds(lowerCount);
97 std::vector<UnionFind> upperSeeds(upperCount);
98 std::vector<UnionFind *> lowerList(lowerCount);
99 std::vector<UnionFind *> upperList(upperCount);
101 lowerList[i] = &(lowerSeeds[i]);
103 upperList[i] = &(upperSeeds[i]);
107 SimplexId const neighborId0 = vertexLink[i].first;
108 SimplexId const neighborId1 = vertexLink[i].second;
111 if(offsets[neighborId0] < offsets[vertexId]
112 && offsets[neighborId1] < offsets[vertexId]) {
115 std::map<SimplexId, SimplexId>::iterator
const n0It
116 = global2LowerLink.find(neighborId0);
117 std::map<SimplexId, SimplexId>::iterator
const n1It
118 = global2LowerLink.find(neighborId1);
121 lowerList[n0It->second], lowerList[n1It->second]);
122 lowerList[n1It->second] = lowerList[n0It->second];
126 if(offsets[neighborId0] > offsets[vertexId]
127 && offsets[neighborId1] > offsets[vertexId]) {
130 std::map<SimplexId, SimplexId>::iterator
const n0It
131 = global2UpperLink.find(neighborId0);
132 std::map<SimplexId, SimplexId>::iterator
const n1It
133 = global2UpperLink.find(neighborId1);
136 upperList[n0It->second], upperList[n1It->second]);
137 upperList[n1It->second] = upperList[n0It->second];
142 std::vector<UnionFind *>::iterator it;
145 lowerList[i] = lowerList[i]->find();
147 upperList[i] = upperList[i]->find();
149 sort(lowerList.begin(), lowerList.end());
150 it = unique(lowerList.begin(), lowerList.end());
151 lowerList.resize(distance(lowerList.begin(), it));
153 sort(upperList.begin(), upperList.end());
154 it = unique(upperList.begin(), upperList.end());
155 upperList.resize(distance(upperList.begin(), it));
158 printMsg(
"Vertex #" + std::to_string(vertexId)
159 +
": lowerLink-#CC=" + std::to_string(lowerList.size())
160 +
" upperLink-#CC=" + std::to_string(upperList.size()),
164 if((lowerList.size() == 1) && (upperList.size() == 1))
169 if(dimension_ == 2) {
170 if((lowerList.size() > 2) || (upperList.size() > 2)) {
181 }
else if(dimension_ == 3) {
182 if((lowerList.size() == 2) && (upperList.size() == 1)) {
184 }
else if((lowerList.size() == 1) && (upperList.size() == 2)) {
200 SimplexId minimumNumber = 0, maximumNumber = 0, saddleNumber = 0,
201 oneSaddleNumber = 0, twoSaddleNumber = 0, monkeySaddleNumber = 0;
204 if(dimension_ == 3) {
205 for(
size_t i = 0; i < criticalPoints_->size(); i++) {
206 switch((*criticalPoints_)[i].second) {
225 monkeySaddleNumber++;
229 }
else if(dimension_ == 2) {
230 for(
size_t i = 0; i < criticalPoints_->size(); i++) {
231 switch((*criticalPoints_)[i].second) {
246 monkeySaddleNumber++;
253 std::vector<std::vector<std::string>> stats;
254 stats.push_back({
" #Minima", std::to_string(minimumNumber)});
255 if(dimension_ == 3) {
256 stats.push_back({
" #1-saddles", std::to_string(oneSaddleNumber)});
257 stats.push_back({
" #2-saddles", std::to_string(twoSaddleNumber)});
259 if(dimension_ == 2) {
260 stats.push_back({
" #Saddles", std::to_string(saddleNumber)});
262 stats.push_back({
" #Multi-saddles", std::to_string(monkeySaddleNumber)});
263 stats.push_back({
" #Maxima", std::to_string(maximumNumber)});