14 #ifndef ZOLTAN2_METRICFUNCTIONS_HPP
15 #define ZOLTAN2_METRICFUNCTIONS_HPP
28 template <
typename metric_t,
typename scalar_t>
32 metrics.resize(metrics.size() + 1);
33 metric_t * newMetric =
new metric_t;
34 env->localMemoryAssertion(__FILE__,__LINE__,1,newMetric);
35 RCP<metric_t> newRCP = rcp(newMetric);
36 metrics[metrics.size()-1] = newRCP;
53 template <
typename scalar_t>
55 int offset, scalar_t &min, scalar_t &max, scalar_t &sum)
57 if (v.size() < 1)
return;
58 min = max = sum = v[offset];
60 for (
int i=offset+stride; i < v.size(); i += stride){
61 if (v[i] < min) min = v[i];
62 else if (v[i] > max) max = v[i];
75 template <
typename scalar_t>
77 int offset, scalar_t &max, scalar_t &sum)
79 if (v.size() < 1)
return;
80 max = sum = v[offset];
82 for (
int i=offset+stride; i < v.size(); i += stride){
83 if (v[i] > max) max = v[i];
106 template <
typename scalar_t,
typename lno_t,
typename part_t>
108 const RCP<const Environment> &env,
110 const ArrayView<const part_t> &parts,
115 env->localInputAssertion(__FILE__, __LINE__,
"parts or weights",
118 int numObjects = parts.size();
119 int vwgtDim = vwgts.size();
121 memset(weights, 0,
sizeof(scalar_t) * numberOfParts);
127 for (
lno_t i=0; i < numObjects; i++){
131 else if (vwgtDim == 1){
132 for (
lno_t i=0; i < numObjects; i++){
133 weights[parts[i]] += vwgts[0][i];
139 for (
int wdim=0; wdim < vwgtDim; wdim++){
140 for (
lno_t i=0; i < numObjects; i++){
141 weights[parts[i]] += vwgts[wdim][i];
147 for (
lno_t i=0; i < numObjects; i++){
149 for (
int wdim=0; wdim < vwgtDim; wdim++)
150 ssum += (vwgts[wdim][i] * vwgts[wdim][i]);
151 weights[parts[i]] += sqrt(ssum);
156 for (
lno_t i=0; i < numObjects; i++){
158 for (
int wdim=0; wdim < vwgtDim; wdim++)
159 if (vwgts[wdim][i] > max)
160 max = vwgts[wdim][i];
161 weights[parts[i]] += max;
166 env->localBugAssertion(__FILE__, __LINE__,
"invalid norm",
false,
203 template <
typename scalar_t,
typename part_t>
207 const scalar_t *psizes,
209 const scalar_t *vals,
217 if (sumVals <= 0 || targetNumParts < 1 || numExistingParts < 1)
220 if (targetNumParts==1) {
226 scalar_t target = sumVals / targetNumParts;
227 for (
part_t p=0; p < numExistingParts; p++){
228 scalar_t diff = vals[p] - target;
229 scalar_t adiff = (diff >= 0 ? diff : -diff);
230 scalar_t tmp = diff / target;
231 scalar_t atmp = adiff / target;
233 if (tmp > max) max = tmp;
234 if (tmp < min) min = tmp;
236 part_t emptyParts = targetNumParts - numExistingParts;
244 for (
part_t p=0; p < targetNumParts; p++){
246 if (p < numExistingParts){
247 scalar_t target = sumVals * psizes[p];
248 scalar_t diff = vals[p] - target;
249 scalar_t adiff = (diff >= 0 ? diff : -diff);
250 scalar_t tmp = diff / target;
251 scalar_t atmp = adiff / target;
253 if (tmp > max) max = tmp;
254 if (tmp < min) min = tmp;
265 avg /= targetNumParts;
301 template <
typename scalar_t,
typename part_t>
306 ArrayView<ArrayRCP<scalar_t> > psizes,
308 const scalar_t *vals,
316 if (sumVals <= 0 || targetNumParts < 1 || numExistingParts < 1)
319 if (targetNumParts==1) {
324 bool allUniformParts =
true;
325 for (
int i=0; i < numSizes; i++){
326 if (psizes[i].size() != 0){
327 allUniformParts =
false;
332 if (allUniformParts){
333 computeImbalances<scalar_t, part_t>(numExistingParts, targetNumParts, NULL,
334 sumVals, vals, min, max, avg);
338 double uniformSize = 1.0 / targetNumParts;
339 std::vector<double> sizeVec(numSizes);
340 for (
int i=0; i < numSizes; i++){
341 sizeVec[i] = uniformSize;
344 for (
part_t p=0; p < numExistingParts; p++){
351 if (p >= targetNumParts)
356 double targetNorm = 0;
357 for (
int i=0; i < numSizes; i++) {
358 if (psizes[i].size() > 0)
359 sizeVec[i] = psizes[i][p];
360 sizeVec[i] *= sumVals;
361 targetNorm += (sizeVec[i] * sizeVec[i]);
363 targetNorm = sqrt(targetNorm);
372 std::vector<double> actual(numSizes);
373 double actualNorm = 0.;
374 for (
int i=0; i < numSizes; i++) {
375 actual[i] = vals[p] * -1.0;
376 actual[i] += sizeVec[i];
377 actualNorm += (actual[i] * actual[i]);
379 actualNorm = sqrt(actualNorm);
383 scalar_t imbalance = actualNorm / targetNorm;
387 else if (imbalance > max)
395 for (
part_t p=numExistingParts; p < targetNumParts; p++){
396 bool nonEmptyPart =
false;
397 for (
int i=0; !nonEmptyPart && i < numSizes; i++)
398 if (psizes[i].size() > 0 && psizes[i][p] > 0.0)
408 if (numEmptyParts > 0){
409 avg += numEmptyParts;
414 avg /= targetNumParts;
419 template <
typename scalar_t>
423 size_t dim = weights.size();
429 scalar_t nweight = 0;
434 for (
size_t i=0; i <dim; i++)
435 nweight += weights[i];
440 for (
size_t i=0; i <dim; i++)
441 nweight += (weights[i] * weights[i]);
443 nweight = sqrt(nweight);
449 nweight = weights[0];
450 for (
size_t i=1; i <dim; i++)
451 if (weights[i] > nweight)
452 nweight = weights[i];
457 std::ostringstream emsg;
458 emsg << __FILE__ <<
":" << __LINE__ << std::endl;
459 emsg <<
"bug: " <<
"invalid norm" << std::endl;
460 throw std::logic_error(emsg.str());
468 template<
typename lno_t,
typename scalar_t>
476 Array<scalar_t> vec(dim, 1.0);
477 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.
map_t::local_ordinal_type lno_t
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.