50 #ifndef ZOLTAN2_METRICFUNCTIONS_HPP 51 #define ZOLTAN2_METRICFUNCTIONS_HPP 70 template <
typename scalar_t>
72 int offset, scalar_t &min, scalar_t &max, scalar_t &sum)
74 if (v.size() < 1)
return;
75 min = max = sum = v[offset];
77 for (
int i=offset+stride; i < v.size(); i += stride){
78 if (v[i] < min) min = v[i];
79 else if (v[i] > max) max = v[i];
92 template <
typename scalar_t>
94 int offset, scalar_t &max, scalar_t &sum)
96 if (v.size() < 1)
return;
97 max = sum = v[offset];
99 for (
int i=offset+stride; i < v.size(); i += stride){
100 if (v[i] > max) max = v[i];
123 template <
typename scalar_t,
typename lno_t,
typename part_t>
125 const RCP<const Environment> &env,
126 part_t numberOfParts,
127 const ArrayView<const part_t> &parts,
132 env->localInputAssertion(__FILE__, __LINE__,
"parts or weights",
135 int numObjects = parts.size();
136 int vwgtDim = vwgts.size();
138 memset(
weights, 0,
sizeof(scalar_t) * numberOfParts);
144 for (lno_t i=0; i < numObjects; i++){
148 else if (vwgtDim == 1){
149 for (lno_t i=0; i < numObjects; i++){
150 weights[parts[i]] += vwgts[0][i];
156 for (
int wdim=0; wdim < vwgtDim; wdim++){
157 for (lno_t i=0; i < numObjects; i++){
158 weights[parts[i]] += vwgts[wdim][i];
164 for (lno_t i=0; i < numObjects; i++){
166 for (
int wdim=0; wdim < vwgtDim; wdim++)
167 ssum += (vwgts[wdim][i] * vwgts[wdim][i]);
168 weights[parts[i]] += sqrt(ssum);
173 for (lno_t i=0; i < numObjects; i++){
175 for (
int wdim=0; wdim < vwgtDim; wdim++)
176 if (vwgts[wdim][i] > max)
177 max = vwgts[wdim][i];
183 env->localBugAssertion(__FILE__, __LINE__,
"invalid norm",
false,
220 template <
typename scalar_t,
typename part_t>
222 part_t numExistingParts,
223 part_t targetNumParts,
224 const scalar_t *psizes,
226 const scalar_t *
vals,
234 if (sumVals <= 0 || targetNumParts < 1 || numExistingParts < 1)
237 if (targetNumParts==1) {
243 scalar_t target = sumVals / targetNumParts;
244 for (part_t p=0; p < numExistingParts; p++){
245 scalar_t diff =
vals[p] - target;
246 scalar_t adiff = (diff >= 0 ? diff : -diff);
247 scalar_t tmp = diff / target;
248 scalar_t atmp = adiff / target;
250 if (tmp > max) max = tmp;
251 if (tmp < min) min = tmp;
253 part_t emptyParts = targetNumParts - numExistingParts;
261 for (part_t p=0; p < targetNumParts; p++){
263 if (p < numExistingParts){
264 scalar_t target = sumVals * psizes[p];
265 scalar_t diff =
vals[p] - target;
266 scalar_t adiff = (diff >= 0 ? diff : -diff);
267 scalar_t tmp = diff / target;
268 scalar_t atmp = adiff / target;
270 if (tmp > max) max = tmp;
271 if (tmp < min) min = tmp;
282 avg /= targetNumParts;
318 template <
typename scalar_t,
typename part_t>
320 part_t numExistingParts,
321 part_t targetNumParts,
323 ArrayView<ArrayRCP<scalar_t> > psizes,
325 const scalar_t *
vals,
333 if (sumVals <= 0 || targetNumParts < 1 || numExistingParts < 1)
336 if (targetNumParts==1) {
341 bool allUniformParts =
true;
342 for (
int i=0; i < numSizes; i++){
343 if (psizes[i].size() != 0){
344 allUniformParts =
false;
349 if (allUniformParts){
350 computeImbalances<scalar_t, part_t>(numExistingParts, targetNumParts, NULL,
351 sumVals,
vals, min, max, avg);
355 double uniformSize = 1.0 / targetNumParts;
356 std::vector<double> sizeVec(numSizes);
357 for (
int i=0; i < numSizes; i++){
358 sizeVec[i] = uniformSize;
361 for (part_t p=0; p < numExistingParts; p++){
368 if (p >= targetNumParts)
373 double targetNorm = 0;
374 for (
int i=0; i < numSizes; i++) {
375 if (psizes[i].size() > 0)
376 sizeVec[i] = psizes[i][p];
377 sizeVec[i] *= sumVals;
378 targetNorm += (sizeVec[i] * sizeVec[i]);
380 targetNorm = sqrt(targetNorm);
389 std::vector<double> actual(numSizes);
390 double actualNorm = 0.;
391 for (
int i=0; i < numSizes; i++) {
392 actual[i] =
vals[p] * -1.0;
393 actual[i] += sizeVec[i];
394 actualNorm += (actual[i] * actual[i]);
396 actualNorm = sqrt(actualNorm);
400 scalar_t imbalance = actualNorm / targetNorm;
404 else if (imbalance > max)
410 part_t numEmptyParts = 0;
412 for (part_t p=numExistingParts; p < targetNumParts; p++){
413 bool nonEmptyPart =
false;
414 for (
int i=0; !nonEmptyPart && i < numSizes; i++)
415 if (psizes[i].size() > 0 && psizes[i][p] > 0.0)
425 if (numEmptyParts > 0){
426 avg += numEmptyParts;
431 avg /= targetNumParts;
436 template <
typename scalar_t>
446 scalar_t nweight = 0;
451 for (
size_t i=0; i <dim; i++)
457 for (
size_t i=0; i <dim; i++)
460 nweight = sqrt(nweight);
467 for (
size_t i=1; i <dim; i++)
485 template<
typename lno_t,
typename scalar_t>
493 Array<scalar_t> vec(dim, 1.0);
494 for (
size_t i=0; i < dim; i++)
fast typical checks for valid arguments
void normedPartWeights(const RCP< const Environment > &env, part_t numberOfParts, const ArrayView< const part_t > &parts, const ArrayView< StridedData< lno_t, scalar_t > > &vwgts, multiCriteriaNorm mcNorm, scalar_t *weights)
Compute the total weight in each part on this process.
void getStridedStats(const ArrayView< scalar_t > &v, int stride, int offset, scalar_t &min, scalar_t &max, scalar_t &sum)
Find min, max and sum of metric values.
void localBugAssertion(const char *file, int lineNum, const char *msg, bool ok, AssertionLevel level) const
Test for valid library behavior on local process only.
The StridedData class manages lists of weights or coordinates.
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
multiCriteriaNorm
Enumerator used in code for multicriteria norm choice.
void computeImbalances(part_t numExistingParts, part_t targetNumParts, const scalar_t *psizes, scalar_t sumVals, const scalar_t *vals, scalar_t &min, scalar_t &max, scalar_t &avg)
Compute the imbalance.
This file defines the StridedData class.
scalar_t normedWeight(ArrayView< scalar_t > weights, multiCriteriaNorm norm)
Compute the norm of the vector of weights.