Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members | File Members

SPeval.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002 ***    
00003 *** Copyright (c) 1995-2000 Regents of the University of California,
00004 ***               Andrew E. Caldwell, Andrew B. Kahng and Igor L. Markov
00005 *** Copyright (c) 2000-2004 Regents of the University of Michigan,
00006 ***               Saurabh N. Adya, Jarrod A. Roy and Igor L. Markov
00007 ***
00008 ***  Contact author(s): abk@cs.ucsd.edu, imarkov@umich.edu
00009 ***  Original Affiliation:   UCLA, Computer Science Department,
00010 ***                          Los Angeles, CA 90095-1596 USA
00011 ***
00012 ***  Permission is hereby granted, free of charge, to any person obtaining 
00013 ***  a copy of this software and associated documentation files (the
00014 ***  "Software"), to deal in the Software without restriction, including
00015 ***  without limitation 
00016 ***  the rights to use, copy, modify, merge, publish, distribute, sublicense, 
00017 ***  and/or sell copies of the Software, and to permit persons to whom the 
00018 ***  Software is furnished to do so, subject to the following conditions:
00019 ***
00020 ***  The above copyright notice and this permission notice shall be included
00021 ***  in all copies or substantial portions of the Software.
00022 ***
00023 *** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00024 *** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00025 *** OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
00026 *** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
00027 *** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
00028 *** OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
00029 *** THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00030 ***
00031 ***
00032 ***************************************************************************/
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 #include "SPeval.h"
00046 #include "PlToSP.h"
00047 #include <algorithm>
00048 
00049 using namespace parquetfp;
00050 
00051 SPeval::SPeval(const vector<double>& heights,
00052                const vector<double>& widths,
00053                bool paramUseFastSP)
00054 {
00055    _heights=heights;
00056    _widths=widths;
00057   
00058    unsigned size = heights.size();
00059    _match.resize(size);
00060    _LL.resize(size);
00061    _reverseSeq.resize(size);
00062    _XX.resize(size);
00063    _YY.resize(size);
00064    xloc.resize(size);
00065    yloc.resize(size);
00066    xSlacks.resize(size);
00067    ySlacks.resize(size);
00068    xlocRev.resize(size);
00069    ylocRev.resize(size);
00070    _reverseSeq2.resize(size);
00071    _TCGMatrixInitialized = false;
00072    _paramUseFastSP=paramUseFastSP;
00073 }
00074 
00075 void SPeval::_initializeTCGMatrix(unsigned size)
00076 {
00077    _TCGMatrixVert.resize(size);
00078    _TCGMatrixHoriz.resize(size);
00079    for(unsigned i=0; i<size; ++i)
00080    {
00081       _TCGMatrixVert[i].resize(size);
00082       _TCGMatrixHoriz[i].resize(size);
00083    }
00084    _TCGMatrixInitialized = true;
00085 }
00086 
00087 double SPeval::_lcsCompute(const vector<unsigned>& X,
00088                            const vector<unsigned>& Y,
00089                            const vector<double>& weights,
00090                            vector<unsigned>& match,
00091                            vector<double>& P,
00092                            vector<double>& L)
00093 {
00094    unsigned size = X.size();
00095    for(unsigned i=0;i<size;++i)
00096    {
00097       match[Y[i]]=i;
00098       L[i]=0;
00099    }
00100   
00101    double t;
00102    unsigned j;
00103    for(unsigned i=0;i<size;++i)
00104    {
00105       unsigned p = match[X[i]];
00106       P[X[i]]=L[p];
00107       t = P[X[i]]+weights[X[i]];
00108       
00109       for(j=p;j<size;++j)
00110       {
00111          if(t>L[j])
00112             L[j]=t;
00113          else
00114             break;
00115       }
00116    }
00117    return L[size-1];
00118 }
00119 
00120 
00121 double SPeval::xEval()
00122 {
00123    fill(_match.begin(),_match.end(),0);
00124    return _lcsCompute( _XX, _YY, _widths, _match, xloc, _LL);
00125 }
00126 
00127 double SPeval::yEval()
00128 {
00129    _reverseSeq = _XX;
00130    reverse(_reverseSeq.begin(),_reverseSeq.end());
00131    fill(_match.begin(),_match.end(),0);
00132    return _lcsCompute( _reverseSeq, _YY, _heights, _match, yloc, _LL);
00133 }
00134 
00135 void SPeval::evaluate(const vector<unsigned>& X,
00136                       const vector<unsigned>& Y)
00137 {
00138    if(_paramUseFastSP)
00139    {
00140       evaluateFast(X, Y);
00141       return;
00142    }
00143   
00144    _XX = X;
00145    _YY = Y;
00146    xSize = xEval();
00147    ySize = yEval();
00148 }
00149 
00150 void SPeval::evaluateCompact(const vector<unsigned>& X,
00151                              const vector<unsigned>& Y,
00152                              bool whichDir)
00153 {
00154    _XX = X;
00155    _YY = Y;
00156    if(whichDir == 0)  //evaluate yloc first and then compact
00157    {
00158       ySize = yEval();
00159       xSize = xEvalCompact();
00160    }
00161    else               //evaluate xloc first and then compact
00162    {
00163       xSize = xEval();
00164       ySize = yEvalCompact();
00165    }
00166 }
00167 
00168 double SPeval::xEvalCompact()
00169 {
00170    fill(_match.begin(),_match.end(),0);
00171    return _lcsComputeCompact( _XX, _YY, _widths, _match, xloc, _LL, yloc, 
00172                               _heights);
00173 }
00174 
00175 double SPeval::yEvalCompact()
00176 {
00177    _reverseSeq = _XX;
00178    reverse(_reverseSeq.begin(),_reverseSeq.end());
00179    fill(_match.begin(),_match.end(),0);
00180    return _lcsComputeCompact( _reverseSeq, _YY, _heights, _match, yloc, _LL, 
00181                               xloc, _widths);
00182 }
00183 
00184 double SPeval::_lcsComputeCompact(const vector<unsigned>& X,
00185                                   const vector<unsigned>& Y,
00186                                   const vector<double>& weights,
00187                                   vector<unsigned>& match,
00188                                   vector<double>& P,
00189                                   vector<double>& L,
00190                                   vector<double>& oppLocs,
00191                                   vector<double>& oppWeights
00192    )
00193 {
00194    double finalSize = -1e100;
00195    unsigned size = X.size();
00196    for(unsigned i=0;i<size;++i)
00197    {
00198       match[Y[i]]=i;
00199       L[i]=0;
00200    }
00201   
00202    double t;
00203    unsigned j;
00204    for(unsigned i=0;i<size;++i)
00205    {
00206       unsigned p = match[X[i]];
00207       P[X[i]]=L[p];
00208       t = P[X[i]]+weights[X[i]];
00209       
00210       double iStart = oppLocs[X[i]];
00211       double iEnd = oppLocs[X[i]] + oppWeights[X[i]];
00212 
00213       for(j=p;j<size;++j)
00214       {
00215          double jStart = oppLocs[Y[j]];
00216          double jEnd = oppLocs[Y[j]] + oppWeights[Y[j]];
00217           
00218          if(iStart >= jEnd || iEnd <= jStart) //no constraint
00219             continue;
00220           
00221          if(t>L[j])
00222          {
00223             L[j]=t;
00224             if(t > finalSize)
00225                finalSize = t;
00226          }
00227       }
00228    }
00229    return finalSize;
00230 }
00231 
00232 void SPeval::computeConstraintGraphs()
00233 {
00234    unsigned size = _XX.size();
00235    if(!_TCGMatrixInitialized)
00236       _initializeTCGMatrix(size);
00237 
00238    vector<unsigned> matchX;
00239    vector<unsigned> matchY;
00240    matchX.resize(size);
00241    matchY.resize(size);
00242 
00243    for(unsigned i=0;i<size;++i)
00244    {
00245       matchX[_XX[i]]=i;
00246       matchY[_YY[i]]=i;
00247    }
00248 
00249    for(unsigned i=0;i<size;++i)
00250    {
00251       for(unsigned j=0; j<size; ++j)
00252       {
00253          if(i==j)
00254          {
00255             _TCGMatrixHoriz[i][j] = 1;
00256             _TCGMatrixVert[i][j] = 1;
00257             continue;
00258          }
00259 
00260          _TCGMatrixHoriz[i][j] = 0;
00261          _TCGMatrixVert[i][j] = 0;
00262          _TCGMatrixHoriz[j][i] = 0;
00263          _TCGMatrixVert[j][i] = 0;
00264 
00265           
00266          if(matchX[i] < matchX[j] && matchY[i] < matchY[j])
00267             _TCGMatrixHoriz[i][j] = 1;
00268          else if(matchX[i] > matchX[j] && matchY[i] > matchY[j])
00269             _TCGMatrixHoriz[j][i] = 1;
00270          else if(matchX[i] < matchX[j] && matchY[i] > matchY[j])
00271             _TCGMatrixVert[j][i] = 1;
00272          else if(matchX[i] > matchX[j] && matchY[i] < matchY[j])
00273             _TCGMatrixVert[i][j] = 1;
00274          else
00275             cout<<"ERROR: in computeConstraintGraph \n";
00276       }
00277    }
00278 }
00279 
00280 void SPeval::removeRedundantConstraints(bool knownDir)
00281 {
00282    unsigned size = _XX.size();
00283    double iStart, iEnd, jStart, jEnd;
00284    for(unsigned i=0; i<size; ++i)
00285    {
00286       if(knownDir == 0) //horizontal
00287       {
00288          iStart = xloc[i];
00289          iEnd = iStart+_widths[i];
00290       }
00291       else  //vertical
00292       {
00293          iStart = yloc[i];
00294          iEnd = iStart+_heights[i];
00295       }
00296       for(unsigned j=0; j<size; ++j)
00297       {
00298          if(i == j)
00299             continue;
00300 
00301          if(knownDir == 0)
00302          {
00303             jStart = xloc[j];
00304             jEnd = jStart+_widths[j];
00305          }
00306          else
00307          {
00308             jStart = yloc[j];
00309             jEnd = jStart+_heights[j];
00310          }
00311           
00312          if(knownDir == 0)
00313          {
00314             if(_TCGMatrixVert[i][j] == 1)
00315             {
00316                if(iStart >= jEnd || iEnd <= jStart) //no constraint
00317                {
00318                   _TCGMatrixVert[i][j] = 0;
00319                   if(iStart < jStart)
00320                      _TCGMatrixHoriz[i][j] = 1;
00321                   else
00322                      _TCGMatrixHoriz[j][i] = 1;
00323                }
00324             }
00325          }
00326          else
00327          {
00328             if(_TCGMatrixHoriz[i][j] == 1)
00329             {
00330                if(iStart >= jEnd || iEnd <= jStart) //no constraint
00331                {
00332                   cout<<i<<"\t"<<j<<"\t"<<iStart<<"\t"<<iEnd<<"\t"<<
00333                      jStart<<"\t"<<jEnd<<endl;
00334                   _TCGMatrixHoriz[i][j] = 0;
00335                   if(iStart < jStart)
00336                      _TCGMatrixVert[i][j] = 1;
00337                   else
00338                      _TCGMatrixVert[j][i] = 1;
00339                }
00340             }
00341          }
00342       }
00343    }
00344 }
00345 
00346 void SPeval::computeSPFromCG()
00347 {
00348    unsigned size = _XX.size();
00349    for(unsigned i=0; i<size; ++i)
00350    {
00351       _XX[i] = i;
00352       _YY[i] = i;
00353    }
00354   
00355    SPXRelation SPX(_TCGMatrixHoriz, _TCGMatrixVert);
00356    SPYRelation SPY(_TCGMatrixHoriz, _TCGMatrixVert);
00357 
00358    std::sort(_XX.begin(), _XX.end(), SPX);
00359    std::sort(_YY.begin(), _YY.end(), SPY);
00360 }
00361 
00362 void SPeval::changeWidths(const vector<double>& widths)
00363 {
00364    _widths = widths;
00365 }
00366 
00367 void SPeval::changeHeights(const vector<double>& heights)
00368 {
00369    _heights = heights;
00370 }
00371 
00372 void SPeval::changeNodeWidth(unsigned index, double width)
00373 {
00374    _widths[index] = width;
00375 }
00376 
00377 void SPeval::changeNodeHeight(unsigned index, double height)
00378 {
00379    _heights[index] = height;
00380 }
00381 
00382 void SPeval::changeOrient(unsigned index)
00383 {
00384    double tempWidth = _heights[index];
00385    _heights[index] = _widths[index];
00386    _widths[index] = tempWidth;
00387 }
00388 
00389 
00390 double SPeval::_lcsReverseCompute(const vector<unsigned>& X,
00391                                   const vector<unsigned>& Y,
00392                                   const vector<double>& weights,
00393                                   vector<unsigned>& match,
00394                                   vector<double>& P,
00395                                   vector<double>& L
00396    )
00397 {
00398    unsigned size = X.size();
00399    for(unsigned i=0;i<size;++i)
00400    {
00401       match[Y[i]]=i;
00402       L[i]=0;
00403    }
00404   
00405    double t;
00406    int j;
00407    for(int i=size-1;i>=0;--i)
00408    {
00409       unsigned p = match[X[i]];
00410       P[X[i]]=L[p];
00411       t = P[X[i]]+weights[X[i]];
00412       
00413       for(j=p;j>=0;--j)
00414       {
00415          if(t>L[j])
00416             L[j]=t;
00417          else
00418             break;
00419       }
00420    }
00421    return L[0];
00422 }
00423 
00424 
00425 double SPeval::xEvalRev()
00426 {
00427    fill(_match.begin(),_match.end(),0);
00428    return _lcsReverseCompute( _XX, _YY, _widths, _match, xlocRev, _LL);
00429 }
00430 
00431 double SPeval::yEvalRev()
00432 {
00433    _reverseSeq = _XX;
00434    reverse(_reverseSeq.begin(),_reverseSeq.end());
00435    fill(_match.begin(),_match.end(),0);
00436    return _lcsReverseCompute( _reverseSeq, _YY, _heights, _match, ylocRev, _LL);
00437 }
00438 
00439 void SPeval::evalSlacks(const vector<unsigned>& X,
00440                         const vector<unsigned>& Y)
00441 {
00442    if(_paramUseFastSP)
00443    {
00444       evalSlacksFast(X, Y);
00445       return;
00446    }
00447    _XX = X;
00448    _YY = Y;
00449    xSize = xEval();
00450    ySize = yEval();
00451    xEvalRev();
00452    yEvalRev();
00453 
00454    for(unsigned i=0; i<_XX.size(); ++i)
00455    {
00456       xlocRev[i] = xSize - xlocRev[i] - _widths[i];
00457       ylocRev[i] = ySize - ylocRev[i] - _heights[i];
00458       xSlacks[i] = (xlocRev[i] - xloc[i])*100/xSize;
00459       ySlacks[i] = (ylocRev[i] - yloc[i])*100/ySize;
00460    }
00461 }
00462 
00463 void SPeval::_discardNodesBST(unsigned index, double length)
00464 {
00465    map<unsigned , double>::iterator iter;
00466    map<unsigned , double>::iterator nextIter;
00467    map<unsigned , double>::iterator endIter;
00468    endIter = _BST.end();
00469    iter = _BST.find(index);
00470    nextIter = iter;
00471    ++nextIter;
00472    if(nextIter != _BST.end())
00473    {
00474       ++iter;
00475       while(true)
00476       {
00477          ++nextIter;
00478          if((*iter).second < length)
00479             _BST.erase(iter);
00480          if(nextIter == endIter)
00481             break;
00482          iter = nextIter;
00483       }
00484    }
00485 }
00486 
00487 double SPeval::_findBST(unsigned index)
00488 {
00489    map<unsigned , double>::iterator iter;  
00490    double loc;
00491    iter = _BST.lower_bound(index);
00492    if(iter != _BST.begin())
00493    {
00494       iter--;
00495       loc = (*iter).second;
00496    }
00497    else
00498       loc = 0;
00499    return loc;
00500 }
00501 
00502 double SPeval::_lcsComputeFast(const vector<unsigned>& X,
00503                                const vector<unsigned>& Y,
00504                                const vector<double>& weights,
00505                                vector<unsigned>& match,
00506                                vector<double>& P,
00507                                vector<double>& L
00508    )
00509 {
00510    _BST.clear();
00511    _BST[0] = 0;
00512    unsigned size = X.size();
00513    for(unsigned i=0;i<size;++i)
00514    {
00515       match[Y[i]]=i;
00516    }
00517   
00518    double t;
00519 //unsigned j;
00520    for(unsigned i=0;i<size;++i)
00521    {
00522       unsigned p = match[X[i]];
00523       P[X[i]]=_findBST(p);
00524       t = P[X[i]]+weights[X[i]];
00525       _BST[p] = t;
00526       _discardNodesBST(p,t);
00527    }
00528    double length = _findBST(size);
00529    return length;
00530 }
00531 
00532 
00533 double SPeval::xEvalFast()
00534 {
00535    fill(_match.begin(),_match.end(),0);
00536    return _lcsComputeFast( _XX, _YY, _widths, _match, xloc, _LL);
00537 }
00538 
00539 double SPeval::yEvalFast()
00540 {
00541    _reverseSeq = _XX;
00542    reverse(_reverseSeq.begin(),_reverseSeq.end());
00543    fill(_match.begin(),_match.end(),0);
00544    return _lcsComputeFast( _reverseSeq, _YY, _heights, _match, yloc, _LL);
00545 }
00546 
00547 void SPeval::evaluateFast(const vector<unsigned>& X,
00548                           const vector<unsigned>& Y)
00549 {
00550    _XX = X;
00551    _YY = Y;
00552    xSize = xEvalFast();
00553    ySize = yEvalFast();
00554 }
00555 
00556 double SPeval::xEvalRevFast()
00557 {
00558    fill(_match.begin(),_match.end(),0);
00559    _reverseSeq = _XX;
00560    reverse(_reverseSeq.begin(),_reverseSeq.end());
00561    _reverseSeq2 = _YY;
00562    reverse(_reverseSeq2.begin(),_reverseSeq2.end());
00563    return _lcsComputeFast( _reverseSeq, _reverseSeq2, _widths, _match, xlocRev,
00564                            _LL);
00565 }
00566 
00567 double SPeval::yEvalRevFast()
00568 {
00569    _reverseSeq2 = _YY;
00570    reverse(_reverseSeq2.begin(),_reverseSeq2.end());
00571    fill(_match.begin(),_match.end(),0);
00572    return _lcsComputeFast( _XX, _reverseSeq2, _heights, _match, ylocRev, _LL);
00573 }
00574 
00575 void SPeval::evalSlacksFast(const vector<unsigned>& X,
00576                             const vector<unsigned>& Y)
00577 {
00578    _XX = X;
00579    _YY = Y;
00580    xSize = xEvalFast();
00581    ySize = yEvalFast();
00582    xEvalRevFast();
00583    yEvalRevFast();
00584 
00585    for(unsigned i=0; i<_XX.size(); ++i)
00586    {
00587       xlocRev[i] = xSize - xlocRev[i] - _widths[i];
00588       ylocRev[i] = ySize - ylocRev[i] - _heights[i];
00589       xSlacks[i] = (xlocRev[i] - xloc[i])*100/xSize;
00590       ySlacks[i] = (ylocRev[i] - yloc[i])*100/ySize;
00591    }
00592 }

Generated on Mon Apr 25 01:09:25 2005 for Parquete by doxygen 1.3.2