Path: blob/devel/elmergrid/src/metis-5.1.0/libmetis/mcutil.c
3206 views
/*1* mutil.c2*3* This file contains various utility functions for the MOC portion of the4* code5*6* Started 2/15/987* George8*9* $Id: mcutil.c 13901 2013-03-24 16:17:03Z karypis $10*11*/1213#include "metislib.h"141516/*************************************************************************/17/*! This function compares two vectors x & y and returns true18if \forall i, x[i] <= y[i].19*/20/**************************************************************************/21int rvecle(idx_t n, real_t *x, real_t *y)22{23for (n--; n>=0; n--) {24if (x[n] > y[n])25return 0;26}2728return 1;29}303132/*************************************************************************/33/*! This function compares two vectors x & y and returns true34if \forall i, x[i] >= y[i].35*/36/**************************************************************************/37int rvecge(idx_t n, real_t *x, real_t *y)38{39for (n--; n>=0; n--) {40if (x[n] < y[n])41return 0;42}4344return 1;45}464748/*************************************************************************/49/*! This function compares vectors x1+x2 against y and returns true50if \forall i, x1[i]+x2[i] <= y[i].51*/52/**************************************************************************/53int rvecsumle(idx_t n, real_t *x1, real_t *x2, real_t *y)54{55for (n--; n>=0; n--) {56if (x1[n]+x2[n] > y[n])57return 0;58}5960return 1;61}626364/*************************************************************************/65/*! This function returns max_i(x[i]-y[i]) */66/**************************************************************************/67real_t rvecmaxdiff(idx_t n, real_t *x, real_t *y)68{69real_t max;7071max = x[0]-y[0];7273for (n--; n>0; n--) {74if (max < x[n]-y[n])75max = x[n]-y[n];76}7778return max;79}808182/*************************************************************************/83/*! This function returns true if \forall i, x[i] <= z[i]. */84/**************************************************************************/85int ivecle(idx_t n, idx_t *x, idx_t *z)86{87for (n--; n>=0; n--) {88if (x[n] > z[n])89return 0;90}9192return 1;93}949596/*************************************************************************/97/*! This function returns true if \forall i, x[i] >= z[i]. */98/**************************************************************************/99int ivecge(idx_t n, idx_t *x, idx_t *z)100{101for (n--; n>=0; n--) {102if (x[n] < z[n])103return 0;104}105106return 1;107}108109110/*************************************************************************/111/*! This function returns true if \forall i, a*x[i]+y[i] <= z[i]. */112/**************************************************************************/113int ivecaxpylez(idx_t n, idx_t a, idx_t *x, idx_t *y, idx_t *z)114{115for (n--; n>=0; n--) {116if (a*x[n]+y[n] > z[n])117return 0;118}119120return 1;121}122123124/*************************************************************************/125/*! This function returns true if \forall i, a*x[i]+y[i] >= z[i]. */126/**************************************************************************/127int ivecaxpygez(idx_t n, idx_t a, idx_t *x, idx_t *y, idx_t *z)128{129for (n--; n>=0; n--) {130if (a*x[n]+y[n] < z[n])131return 0;132}133134return 1;135}136137138/*************************************************************************/139/*! This function checks if v+u2 provides a better balance in the weight140vector that v+u1 */141/*************************************************************************/142int BetterVBalance(idx_t ncon, real_t *invtvwgt, idx_t *v_vwgt, idx_t *u1_vwgt,143idx_t *u2_vwgt)144{145idx_t i;146real_t sum1=0.0, sum2=0.0, diff1=0.0, diff2=0.0;147148for (i=0; i<ncon; i++) {149sum1 += (v_vwgt[i]+u1_vwgt[i])*invtvwgt[i];150sum2 += (v_vwgt[i]+u2_vwgt[i])*invtvwgt[i];151}152sum1 = sum1/ncon;153sum2 = sum2/ncon;154155for (i=0; i<ncon; i++) {156diff1 += rabs(sum1 - (v_vwgt[i]+u1_vwgt[i])*invtvwgt[i]);157diff2 += rabs(sum2 - (v_vwgt[i]+u2_vwgt[i])*invtvwgt[i]);158}159160return (diff1 - diff2 >= 0);161}162163164/*************************************************************************/165/*! This function takes two ubfactor-centered load imbalance vectors x & y,166and returns true if y is better balanced than x. */167/*************************************************************************/168int BetterBalance2Way(idx_t n, real_t *x, real_t *y)169{170real_t nrm1=0.0, nrm2=0.0;171172for (--n; n>=0; n--) {173if (x[n] > 0) nrm1 += x[n]*x[n];174if (y[n] > 0) nrm2 += y[n]*y[n];175}176return nrm2 < nrm1;177}178179180/*************************************************************************/181/*! Given a vertex and two weights, this function returns 1, if the second182partition will be more balanced than the first after the weighted183additional of that vertex.184The balance determination takes into account the ideal target weights185of the two partitions.186*/187/*************************************************************************/188int BetterBalanceKWay(idx_t ncon, idx_t *vwgt, real_t *ubvec,189idx_t a1, idx_t *pt1, real_t *bm1,190idx_t a2, idx_t *pt2, real_t *bm2)191{192idx_t i;193real_t tmp, nrm1=0.0, nrm2=0.0, max1=0.0, max2=0.0;194195for (i=0; i<ncon; i++) {196tmp = bm1[i]*(pt1[i]+a1*vwgt[i]) - ubvec[i];197//printf("BB: %d %+.4f ", (int)i, (float)tmp);198nrm1 += tmp*tmp;199max1 = (tmp > max1 ? tmp : max1);200201tmp = bm2[i]*(pt2[i]+a2*vwgt[i]) - ubvec[i];202//printf("%+.4f ", (float)tmp);203nrm2 += tmp*tmp;204max2 = (tmp > max2 ? tmp : max2);205206//printf("%4d %4d %4d %4d %4d %4d %4d %.2f\n",207// (int)vwgt[i],208// (int)a1, (int)pt1[i], (int)tpt1[i],209// (int)a2, (int)pt2[i], (int)tpt2[i], ubvec[i]);210}211//printf(" %.3f %.3f %.3f %.3f\n", (float)max1, (float)nrm1, (float)max2, (float)nrm2);212213if (max2 < max1)214return 1;215216if (max2 == max1 && nrm2 < nrm1)217return 1;218219return 0;220}221222223/*************************************************************************/224/*! Computes the maximum load imbalance of a partitioning solution over225all the constraints. */226/**************************************************************************/227real_t ComputeLoadImbalance(graph_t *graph, idx_t nparts, real_t *pijbm)228{229idx_t i, j, ncon, *pwgts;230real_t max, cur;231232ncon = graph->ncon;233pwgts = graph->pwgts;234235max = 1.0;236for (i=0; i<ncon; i++) {237for (j=0; j<nparts; j++) {238cur = pwgts[j*ncon+i]*pijbm[j*ncon+i];239if (cur > max)240max = cur;241}242}243244return max;245}246247248/*************************************************************************/249/*! Computes the maximum load imbalance difference of a partitioning250solution over all the constraints.251The difference is defined with respect to the allowed maximum252unbalance for the respective constraint.253*/254/**************************************************************************/255real_t ComputeLoadImbalanceDiff(graph_t *graph, idx_t nparts, real_t *pijbm,256real_t *ubvec)257{258idx_t i, j, ncon, *pwgts;259real_t max, cur;260261ncon = graph->ncon;262pwgts = graph->pwgts;263264max = -1.0;265for (i=0; i<ncon; i++) {266for (j=0; j<nparts; j++) {267cur = pwgts[j*ncon+i]*pijbm[j*ncon+i] - ubvec[i];268if (cur > max)269max = cur;270}271}272273return max;274}275276277/*************************************************************************/278/*! Computes the difference between load imbalance of each constraint across279the partitions minus the desired upper bound on the load imabalnce.280It also returns the maximum load imbalance across the partitions &281constraints. */282/**************************************************************************/283real_t ComputeLoadImbalanceDiffVec(graph_t *graph, idx_t nparts, real_t *pijbm,284real_t *ubfactors, real_t *diffvec)285{286idx_t i, j, ncon, *pwgts;287real_t cur, max;288289ncon = graph->ncon;290pwgts = graph->pwgts;291292for (max=-1.0, i=0; i<ncon; i++) {293diffvec[i] = pwgts[i]*pijbm[i] - ubfactors[i];294for (j=1; j<nparts; j++) {295cur = pwgts[j*ncon+i]*pijbm[j*ncon+i] - ubfactors[i];296if (cur > diffvec[i])297diffvec[i] = cur;298}299if (max < diffvec[i])300max = diffvec[i];301}302303return max;304}305306307/*************************************************************************/308/*! Computes the load imbalance of each constraint across the partitions. */309/**************************************************************************/310void ComputeLoadImbalanceVec(graph_t *graph, idx_t nparts, real_t *pijbm,311real_t *lbvec)312{313idx_t i, j, ncon, *pwgts;314real_t cur;315316ncon = graph->ncon;317pwgts = graph->pwgts;318319for (i=0; i<ncon; i++) {320lbvec[i] = pwgts[i]*pijbm[i];321for (j=1; j<nparts; j++) {322cur = pwgts[j*ncon+i]*pijbm[j*ncon+i];323if (cur > lbvec[i])324lbvec[i] = cur;325}326}327}328329330331332