10 #ifndef TPETRA_DETAILS_MERGE_HPP
11 #define TPETRA_DETAILS_MERGE_HPP
13 #include "TpetraCore_config.h"
14 #include "Teuchos_TestForException.hpp"
40 template <
class OrdinalType,
class IndexType>
43 const IndexType numCurInds,
44 const OrdinalType inputInds[],
45 const IndexType numInputInds) {
46 IndexType mergeCount = 0;
48 if (numCurInds <= numInputInds) {
51 for (IndexType inPos = 0; inPos < numInputInds; ++inPos) {
52 const OrdinalType inVal = inputInds[inPos];
53 for (IndexType curPos = 0; curPos < numCurInds; ++curPos) {
54 if (curInds[curPos] == inVal) {
62 for (IndexType curPos = 0; curPos < numCurInds; ++curPos) {
63 const OrdinalType curVal = curInds[curPos];
64 for (IndexType inPos = 0; inPos < numInputInds; ++inPos) {
65 if (inputInds[inPos] == curVal) {
72 #ifdef HAVE_TPETRA_DEBUG
73 TEUCHOS_TEST_FOR_EXCEPTION(mergeCount > numInputInds, std::logic_error,
"mergeCount = " << mergeCount <<
" > numInputInds = " << numInputInds <<
".");
74 #endif // HAVE_TPETRA_DEBUG
95 template <
class OrdinalType,
class IndexType>
98 const IndexType numCurInds,
99 const OrdinalType inputInds[],
100 const IndexType numInputInds) {
104 IndexType curPos = 0;
106 IndexType mergeCount = 0;
107 while (inPos < numInputInds && curPos < numCurInds) {
108 const OrdinalType inVal = inputInds[inPos];
109 const OrdinalType curVal = curInds[curPos];
111 if (curVal == inVal) {
114 }
else if (curVal < inVal) {
121 #ifdef HAVE_TPETRA_DEBUG
122 TEUCHOS_TEST_FOR_EXCEPTION(inPos > numInputInds, std::logic_error,
"inPos = " << inPos <<
" > numInputInds = " << numInputInds <<
".");
123 TEUCHOS_TEST_FOR_EXCEPTION(curPos > numCurInds, std::logic_error,
"curPos = " << curPos <<
" > numCurInds = " << numCurInds <<
".");
124 TEUCHOS_TEST_FOR_EXCEPTION(mergeCount > numInputInds, std::logic_error,
"mergeCount = " << mergeCount <<
" > numInputInds = " << numInputInds <<
".");
125 #endif // HAVE_TPETRA_DEBUG
159 template <
class OrdinalType,
class IndexType>
160 std::pair<bool, IndexType>
162 const IndexType midPos,
163 const IndexType endPos,
164 const OrdinalType inputInds[],
165 const IndexType numInputInds) {
182 if (endPos >= numInputInds) {
184 for (IndexType k = 0; k < numInputInds; ++k) {
185 curInds[k] = inputInds[k];
187 std::sort(curInds, curInds + numInputInds);
188 return std::make_pair(
true, numInputInds);
190 return std::make_pair(
false, numInputInds);
196 const IndexType mergeCount =
197 countMergeSortedIndices<OrdinalType, IndexType>(curInds, midPos,
200 const IndexType extraSpaceNeeded = numInputInds - mergeCount;
201 const IndexType newRowLen = midPos + extraSpaceNeeded;
202 if (newRowLen > endPos) {
203 return std::make_pair(
false, newRowLen);
205 IndexType curPos = 0;
207 IndexType newPos = midPos;
208 while (inPos < numInputInds && curPos < midPos) {
209 const OrdinalType inVal = inputInds[inPos];
210 const OrdinalType curVal = curInds[curPos];
212 if (curVal == inVal) {
214 }
else if (curVal < inVal) {
219 curInds[newPos] = inVal;
227 for (; inPos < numInputInds && newPos < newRowLen; ++inPos, ++newPos) {
228 curInds[newPos] = inputInds[inPos];
231 #ifdef HAVE_TPETRA_DEBUG
232 TEUCHOS_TEST_FOR_EXCEPTION(newPos != newRowLen, std::logic_error,
"mergeSortedIndices: newPos = " << newPos <<
" != newRowLen = " << newRowLen <<
" = " << midPos <<
" + " << extraSpaceNeeded <<
". Please report this bug to the Tpetra "
234 #endif // HAVE_TPETRA_DEBUG
236 if (newPos != midPos) {
245 return std::make_pair(
true, newPos);
271 template <
class OrdinalType,
class IndexType>
272 std::pair<bool, IndexType>
274 const IndexType midPos,
275 const IndexType endPos,
276 const OrdinalType inputInds[],
277 const IndexType numInputInds) {
294 if (endPos >= numInputInds) {
296 for (IndexType k = 0; k < numInputInds; ++k) {
297 curInds[k] = inputInds[k];
299 return std::make_pair(
true, numInputInds);
301 return std::make_pair(
false, numInputInds);
307 const IndexType mergeCount =
308 countMergeUnsortedIndices<OrdinalType, IndexType>(curInds, midPos,
311 const IndexType extraSpaceNeeded = numInputInds - mergeCount;
312 const IndexType newRowLen = midPos + extraSpaceNeeded;
313 if (newRowLen > endPos) {
314 return std::make_pair(
false, newRowLen);
318 IndexType newPos = midPos;
319 for (IndexType inPos = 0; inPos < numInputInds; ++inPos) {
320 const OrdinalType inVal = inputInds[inPos];
322 for (IndexType curPos = 0; curPos < midPos; ++curPos) {
323 if (curInds[curPos] == inVal) {
328 curInds[newPos] = inVal;
332 return std::make_pair(
true, newPos);
361 template <
class OrdinalType,
class ValueType,
class IndexType>
362 std::pair<bool, IndexType>
365 const IndexType midPos,
366 const IndexType endPos,
367 const OrdinalType inputInds[],
368 const ValueType inputVals[],
369 const IndexType numInputInds) {
386 if (endPos >= numInputInds) {
388 for (IndexType k = 0; k < numInputInds; ++k) {
389 curInds[k] = inputInds[k];
390 curVals[k] = inputVals[k];
392 return std::make_pair(
true, numInputInds);
394 return std::make_pair(
false, numInputInds);
400 const IndexType mergeCount =
401 countMergeUnsortedIndices<OrdinalType, IndexType>(curInds, midPos,
404 const IndexType extraSpaceNeeded = numInputInds - mergeCount;
405 const IndexType newRowLen = midPos + extraSpaceNeeded;
406 if (newRowLen > endPos) {
407 return std::make_pair(
false, newRowLen);
411 IndexType newPos = midPos;
412 for (IndexType inPos = 0; inPos < numInputInds; ++inPos) {
413 const OrdinalType inInd = inputInds[inPos];
415 for (IndexType curPos = 0; curPos < midPos; ++curPos) {
416 if (curInds[curPos] == inInd) {
418 curVals[curPos] += inputVals[inPos];
422 curInds[newPos] = inInd;
423 curVals[newPos] = inputVals[inPos];
427 return std::make_pair(
true, newPos);
435 #endif // TPETRA_DETAILS_MERGE_HPP
std::pair< bool, IndexType > mergeUnsortedIndicesAndValues(OrdinalType curInds[], ValueType curVals[], const IndexType midPos, const IndexType endPos, const OrdinalType inputInds[], const ValueType inputVals[], const IndexType numInputInds)
Attempt to merge the input indices and values into the current row's column indices and corresponding...
std::pair< bool, IndexType > mergeSortedIndices(OrdinalType curInds[], const IndexType midPos, const IndexType endPos, const OrdinalType inputInds[], const IndexType numInputInds)
Attempt to merge the input indices into the current row's column indices, assuming that both the curr...
IndexType countMergeUnsortedIndices(const OrdinalType curInds[], const IndexType numCurInds, const OrdinalType inputInds[], const IndexType numInputInds)
Count the number of column indices that can be merged into the current row, assuming that both the cu...
void sort(View &view, const size_t &size)
Convenience wrapper for std::sort for host-accessible views.
IndexType countMergeSortedIndices(const OrdinalType curInds[], const IndexType numCurInds, const OrdinalType inputInds[], const IndexType numInputInds)
Count the number of column indices that can be merged into the current row, assuming that both the cu...
std::pair< bool, IndexType > mergeUnsortedIndices(OrdinalType curInds[], const IndexType midPos, const IndexType endPos, const OrdinalType inputInds[], const IndexType numInputInds)
Attempt to merge the input indices into the current row's column indices, assuming that both the curr...