392 auto rowPtr =
localP.graph.row_map;
393 auto values =
localP.values;
395 auto nnz = rowPtr(rowIdx+1) - rowPtr(rowIdx);
400 for (
auto entryIdx = rowPtr(rowIdx); entryIdx < rowPtr(rowIdx + 1); entryIdx++) rsumTarget += values(entryIdx);
404 SC rowSumDeviation, temp, delta;
405 SC closestToLeftBoundDist, closestToRghtBoundDist;
406 LO closestToLeftBound, closestToRghtBound;
411 if ((KAT::real(rsumTarget) >= KAT::real(leftBound*(
static_cast<SC>(nnz)))) &&
412 (KAT::real(rsumTarget) <= KAT::real(rghtBound*(
static_cast<SC>(nnz))))){
417 aBigNumber = KAT::zero();
418 for (
auto entryIdx = rowPtr(rowIdx); entryIdx < rowPtr(rowIdx + 1); entryIdx++){
419 if ( KAT::magnitude( values(entryIdx) ) > KAT::magnitude(aBigNumber))
420 aBigNumber = KAT::magnitude( values(entryIdx) );
422 aBigNumber = aBigNumber+ (KAT::magnitude(leftBound) + KAT::magnitude(rghtBound))*(100*
one);
425 for (
auto entryIdx = rowPtr(rowIdx); entryIdx < rowPtr(rowIdx + 1); entryIdx++){
427 inds(rowIdx, ind) = ind;
431 auto sortVals = Kokkos::subview(
origSorted, rowIdx, Kokkos::ALL() );
432 auto sortInds = Kokkos::subview(
inds, rowIdx, Kokkos::make_pair(0,ind));
436 for (
LO i = 1; i < static_cast<LO>(nnz); ++i){
440 if ( KAT::real(sortVals(sortInds(i))) < KAT::real(sortVals(sortInds(0))) ){
441 for ( ; j > 0; --j) sortInds(j) = sortInds(j - 1);
445 for ( ; KAT::real(sortVals(ind)) < KAT::real(sortVals(sortInds(j-1))); --j) sortInds(j) = sortInds(j-1);
452 for (
LO i = 0; i < static_cast<LO>(nnz); i++)
origSorted(rowIdx, i) = values(rowPtr(rowIdx) +
inds(rowIdx, i));
454 closestToLeftBound = 0;
455 while ((closestToLeftBound <
static_cast<LO>(nnz)) && (KAT::real(
origSorted(rowIdx, closestToLeftBound)) <= KAT::real(leftBound))) closestToLeftBound++;
458 closestToRghtBound = closestToLeftBound;
459 while ((closestToRghtBound <
static_cast<LO>(nnz)) && (KAT::real(
origSorted(rowIdx, closestToRghtBound)) <= KAT::real(rghtBound))) closestToRghtBound++;
464 closestToLeftBoundDist =
origSorted(rowIdx, closestToLeftBound) - leftBound;
465 if (closestToRghtBound ==
static_cast<LO>(nnz)) closestToRghtBoundDist= aBigNumber;
466 else closestToRghtBoundDist=
origSorted(rowIdx, closestToRghtBound) - rghtBound;
471 rowSumDeviation = leftBound*(
static_cast<SC>(closestToLeftBound)) + (
static_cast<SC>(nnz-closestToRghtBound))*rghtBound - rsumTarget;
472 for (
LO i=closestToLeftBound; i < closestToRghtBound; i++) rowSumDeviation +=
origSorted(rowIdx, i);
477 if (KAT::real(rowSumDeviation) < KAT::real(KAT::zero())) {
479 temp = leftBound; leftBound = -rghtBound; rghtBound = temp;
485 for (
LO i=0; i < static_cast<LO>(nnz/2); i++) {
493 LO itemp = closestToLeftBound;
494 closestToLeftBound = nnz-closestToRghtBound;
495 closestToRghtBound = nnz-itemp;
496 closestToLeftBoundDist =
origSorted(rowIdx, closestToLeftBound) - leftBound;
497 if (closestToRghtBound ==
static_cast<LO>(nnz)) closestToRghtBoundDist= aBigNumber;
498 else closestToRghtBoundDist=
origSorted(rowIdx, closestToRghtBound) - rghtBound;
500 rowSumDeviation = -rowSumDeviation;
505 for (
LO i = 0; i < closestToLeftBound; i++)
fixedSorted(rowIdx, i) = leftBound;
507 for (
LO i = closestToRghtBound; i < static_cast<LO>(nnz); i++)
fixedSorted(rowIdx, i) = rghtBound;
509 while ((KAT::magnitude(rowSumDeviation) > KAT::magnitude((
one*1.e-10)*rsumTarget))){
510 if (closestToRghtBound != closestToLeftBound)
511 delta = rowSumDeviation/
static_cast<SC>(closestToRghtBound - closestToLeftBound);
512 else delta = aBigNumber;
514 if (KAT::magnitude(closestToLeftBoundDist) <= KAT::magnitude(closestToRghtBoundDist)) {
515 if (KAT::magnitude(delta) <= KAT::magnitude(closestToLeftBoundDist)) {
516 rowSumDeviation =
zero;
517 for (
LO i = closestToLeftBound; i < closestToRghtBound ; i++)
fixedSorted(rowIdx, i) =
origSorted(rowIdx, i) - delta;
520 rowSumDeviation = rowSumDeviation - closestToLeftBoundDist;
521 fixedSorted(rowIdx, closestToLeftBound) = leftBound;
522 closestToLeftBound++;
523 if (closestToLeftBound <
static_cast<LO>(nnz)) closestToLeftBoundDist =
origSorted(rowIdx, closestToLeftBound) - leftBound;
524 else closestToLeftBoundDist = aBigNumber;
528 if (KAT::magnitude(delta) <= KAT::magnitude(closestToRghtBoundDist)) {
530 for (
LO i = closestToLeftBound; i < closestToRghtBound ; i++)
fixedSorted(rowIdx, i) =
origSorted(rowIdx, i) - delta;
533 rowSumDeviation = rowSumDeviation + closestToRghtBoundDist;
536 closestToRghtBound++;
538 if (closestToRghtBound >=
static_cast<LO>(nnz)) closestToRghtBoundDist = aBigNumber;
539 else closestToRghtBoundDist =
origSorted(rowIdx, closestToRghtBound) - rghtBound;
544 auto rowStart = rowPtr(rowIdx);
549 for (
LO i=0; i < static_cast<LO>(nnz/2); i++) {
556 for (
LO i = 0; i < static_cast<LO>(nnz); i++) values(rowStart +
inds(rowIdx, i)) =
fixedSorted(rowIdx, i);
560 for (
auto entryIdx = rowPtr(rowIdx); entryIdx < rowPtr(rowIdx + 1); entryIdx++) values(entryIdx) =
one/(
static_cast<SC>(nnz) );