50 #ifndef ZOLTAN2_METRICFUNCTIONS_HPP
51 #define ZOLTAN2_METRICFUNCTIONS_HPP
64 template <
typename metric_t,
typename scalar_t>
68 metrics.resize(metrics.size() + 1);
69 metric_t * newMetric =
new metric_t;
70 env->localMemoryAssertion(__FILE__,__LINE__,1,newMetric);
71 RCP<metric_t> newRCP = rcp(newMetric);
72 metrics[metrics.size()-1] = newRCP;
89 template <
typename scalar_t>
91 int offset, scalar_t &min, scalar_t &max, scalar_t &sum)
93 if (v.size() < 1)
return;
94 min = max = sum = v[offset];
96 for (
int i=offset+stride; i < v.size(); i += stride){
97 if (v[i] < min) min = v[i];
98 else if (v[i] > max) max = v[i];
111 template <
typename scalar_t>
113 int offset, scalar_t &max, scalar_t &sum)
115 if (v.size() < 1)
return;
116 max = sum = v[offset];
118 for (
int i=offset+stride; i < v.size(); i += stride){
119 if (v[i] > max) max = v[i];
142 template <
typename scalar_t,
typename lno_t,
typename part_t>
144 const RCP<const Environment> &env,
146 const ArrayView<const part_t> &parts,
151 env->localInputAssertion(__FILE__, __LINE__,
"parts or weights",
154 int numObjects = parts.size();
155 int vwgtDim = vwgts.size();
157 memset(weights, 0,
sizeof(scalar_t) * numberOfParts);
163 for (lno_t i=0; i < numObjects; i++){
167 else if (vwgtDim == 1){
168 for (lno_t i=0; i < numObjects; i++){
169 weights[parts[i]] += vwgts[0][i];
175 for (
int wdim=0; wdim < vwgtDim; wdim++){
176 for (lno_t i=0; i < numObjects; i++){
177 weights[parts[i]] += vwgts[wdim][i];
183 for (lno_t i=0; i < numObjects; i++){
185 for (
int wdim=0; wdim < vwgtDim; wdim++)
186 ssum += (vwgts[wdim][i] * vwgts[wdim][i]);
187 weights[parts[i]] += sqrt(ssum);
192 for (lno_t i=0; i < numObjects; i++){
194 for (
int wdim=0; wdim < vwgtDim; wdim++)
195 if (vwgts[wdim][i] > max)
196 max = vwgts[wdim][i];
197 weights[parts[i]] += max;
202 env->localBugAssertion(__FILE__, __LINE__,
"invalid norm",
false,
239 template <
typename scalar_t,
typename part_t>
243 const scalar_t *psizes,
245 const scalar_t *
vals,
253 if (sumVals <= 0 || targetNumParts < 1 || numExistingParts < 1)
256 if (targetNumParts==1) {
262 scalar_t target = sumVals / targetNumParts;
263 for (
part_t p=0; p < numExistingParts; p++){
264 scalar_t diff = vals[p] - target;
265 scalar_t adiff = (diff >= 0 ? diff : -diff);
266 scalar_t tmp = diff / target;
267 scalar_t atmp = adiff / target;
269 if (tmp > max) max = tmp;
270 if (tmp < min) min = tmp;
272 part_t emptyParts = targetNumParts - numExistingParts;
280 for (
part_t p=0; p < targetNumParts; p++){
282 if (p < numExistingParts){
283 scalar_t target = sumVals * psizes[p];
284 scalar_t diff = vals[p] - target;
285 scalar_t adiff = (diff >= 0 ? diff : -diff);
286 scalar_t tmp = diff / target;
287 scalar_t atmp = adiff / target;
289 if (tmp > max) max = tmp;
290 if (tmp < min) min = tmp;
301 avg /= targetNumParts;
337 template <
typename scalar_t,
typename part_t>
342 ArrayView<ArrayRCP<scalar_t> > psizes,
344 const scalar_t *
vals,
352 if (sumVals <= 0 || targetNumParts < 1 || numExistingParts < 1)
355 if (targetNumParts==1) {
360 bool allUniformParts =
true;
361 for (
int i=0; i < numSizes; i++){
362 if (psizes[i].size() != 0){
363 allUniformParts =
false;
368 if (allUniformParts){
369 computeImbalances<scalar_t, part_t>(numExistingParts, targetNumParts, NULL,
370 sumVals,
vals, min, max, avg);
374 double uniformSize = 1.0 / targetNumParts;
375 std::vector<double> sizeVec(numSizes);
376 for (
int i=0; i < numSizes; i++){
377 sizeVec[i] = uniformSize;
380 for (
part_t p=0; p < numExistingParts; p++){
387 if (p >= targetNumParts)
392 double targetNorm = 0;
393 for (
int i=0; i < numSizes; i++) {
394 if (psizes[i].size() > 0)
395 sizeVec[i] = psizes[i][p];
396 sizeVec[i] *= sumVals;
397 targetNorm += (sizeVec[i] * sizeVec[i]);
399 targetNorm = sqrt(targetNorm);
408 std::vector<double> actual(numSizes);
409 double actualNorm = 0.;
410 for (
int i=0; i < numSizes; i++) {
411 actual[i] = vals[p] * -1.0;
412 actual[i] += sizeVec[i];
413 actualNorm += (actual[i] * actual[i]);
415 actualNorm = sqrt(actualNorm);
419 scalar_t imbalance = actualNorm / targetNorm;
423 else if (imbalance > max)
431 for (
part_t p=numExistingParts; p < targetNumParts; p++){
432 bool nonEmptyPart =
false;
433 for (
int i=0; !nonEmptyPart && i < numSizes; i++)
434 if (psizes[i].size() > 0 && psizes[i][p] > 0.0)
444 if (numEmptyParts > 0){
445 avg += numEmptyParts;
450 avg /= targetNumParts;
455 template <
typename scalar_t>
459 size_t dim = weights.size();
465 scalar_t nweight = 0;
470 for (
size_t i=0; i <dim; i++)
471 nweight += weights[i];
476 for (
size_t i=0; i <dim; i++)
477 nweight += (weights[i] * weights[i]);
479 nweight = sqrt(nweight);
485 nweight = weights[0];
486 for (
size_t i=1; i <dim; i++)
487 if (weights[i] > nweight)
488 nweight = weights[i];
493 std::ostringstream emsg;
494 emsg << __FILE__ <<
":" << __LINE__ << std::endl;
495 emsg <<
"bug: " <<
"invalid norm" << std::endl;
496 throw std::logic_error(emsg.str());
504 template<
typename lno_t,
typename scalar_t>
512 Array<scalar_t> vec(dim, 1.0);
513 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.
RCP< metric_t > addNewMetric(const RCP< const Environment > &env, ArrayRCP< RCP< BaseClassMetrics< scalar_t > > > &metrics)
SparseMatrixAdapter_t::part_t part_t
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.
The StridedData class manages lists of weights or coordinates.
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.