call this after all append calls
| 137 | |
| 138 | // call this after all append calls |
| 139 | inline void finish() { |
| 140 | if (triplets.size() == 0) |
| 141 | return; |
| 142 | // sort triplets first by row, then by column |
| 143 | std::sort(triplets.begin(), triplets.end()); |
| 144 | size_t i_current = 0; |
| 145 | size_t count = 1; |
| 146 | for (size_t i = 1; i < triplets.size(); ++i) { |
| 147 | auto& it = triplets[i]; |
| 148 | if (!triplets[i_current].accum(it)) { |
| 149 | i_current = i; |
| 150 | ++count; |
| 151 | } |
| 152 | } |
| 153 | // exclude duplicates |
| 154 | std::vector<triplet_t> aux; |
| 155 | aux.swap(triplets); |
| 156 | triplets.resize(count); |
| 157 | count = 0; |
| 158 | for (const auto& it : aux) |
| 159 | if (it.i > -1) |
| 160 | triplets[count++] = it; |
| 161 | // make row structure for fast access |
| 162 | size_t max_row = static_cast<size_t>(triplets.back().i); |
| 163 | rows.resize(max_row + 1); |
| 164 | for (size_t i = 0; i < triplets.size(); ++i) { |
| 165 | const auto& it = triplets[i]; |
| 166 | auto& row_data = rows[static_cast<size_t>(it.i)]; |
| 167 | if (row_data.count == 0) |
| 168 | row_data.pos = i; // on first access, save the position |
| 169 | ++(row_data.count); // increase counter |
| 170 | } |
| 171 | } |
| 172 | }; |
| 173 | |
| 174 | // find domain size |