pax_global_header00006660000000000000000000000064126635612150014521gustar00rootroot0000000000000052 comment=ffa4e4130011537bdc4658ebb78ab3088f0ea6dc ColPack-1.0.10/000077500000000000000000000000001266356121500131145ustar00rootroot00000000000000ColPack-1.0.10/.gitignore000066400000000000000000000005021266356121500151010ustar00rootroot00000000000000*.Plo *.Po *.a *.exe *.la *.lai *.lo *.o *.so .deps/ .dirstamp .libs/ .svn/ /ColPack /INSTALL /Makefile /Makefile.in /aclocal.m4 /ar-lib /autom4te.cache/ /build /compile /config.guess /config.h /config.h.in /config.log /config.status /config.sub /configure /depcomp /install-sh /libtool /ltmain.sh /m4/ /missing /stamp-h1 ColPack-1.0.10/.travis.yml000066400000000000000000000001761266356121500152310ustar00rootroot00000000000000language: cpp compiler: - gcc - clang before_script: - autoreconf -fi script: - ./configure && make && make check ColPack-1.0.10/AUTHORS000066400000000000000000000001721266356121500141640ustar00rootroot00000000000000COLPACK Copyright (C) 2005-2010 Assefaw H. Gebremedhin, Duc Nguyen, Arijit Tarafdar, Md. Mostofa Ali Patwary, Alex Pothen ColPack-1.0.10/BipartiteGraphBicoloring/000077500000000000000000000000001266356121500200315ustar00rootroot00000000000000ColPack-1.0.10/BipartiteGraphBicoloring/BipartiteGraphBicoloring.cpp000066400000000000000000004417061266356121500254660ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Private Function 3501 void BipartiteGraphBicoloring::PresetCoveredVertexColors() { int i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); int i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); m_i_LeftVertexColorCount = m_i_RightVertexColorCount = m_i_VertexColorCount = _UNKNOWN; m_vi_LeftVertexColors.clear(); m_vi_LeftVertexColors.resize((unsigned) i_LeftVertexCount, _FALSE); m_vi_RightVertexColors.clear(); m_vi_RightVertexColors.resize((unsigned) i_RightVertexCount, _FALSE); int i_CoveredLeftVertexCount = m_vi_CoveredLeftVertices.size(); int i_CoveredRightVertexCount = m_vi_CoveredRightVertices.size(); for(int i=0; i m_vi_LeftVertexColorFrequency[i]) { m_i_SmallestLeftVertexColorClass = i; m_i_SmallestLeftVertexColorClassSize = m_vi_LeftVertexColorFrequency[i]; } } m_vi_RightVertexColorFrequency.clear(); m_vi_RightVertexColorFrequency.resize((unsigned) m_i_RightVertexColorCount, _FALSE); int i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); for(int i = 0; i < i_RightVertexCount; i++) { m_vi_RightVertexColorFrequency[m_vi_RightVertexColors[i]]++; } for(int i = 0; i < m_i_RightVertexColorCount; i++) { if(m_i_LargestRightVertexColorClassSize < m_vi_RightVertexColorFrequency[i]) { m_i_LargestRightVertexColorClass = i; m_i_LargestRightVertexColorClassSize = m_vi_RightVertexColorFrequency[i]; } if(m_i_SmallestRightVertexColorClassSize == _UNKNOWN) { m_i_SmallestRightVertexColorClass = i; m_i_SmallestRightVertexColorClassSize = m_vi_RightVertexColorFrequency[i]; } else if(m_i_SmallestRightVertexColorClassSize > m_vi_RightVertexColorFrequency[i]) { m_i_SmallestRightVertexColorClass = i; m_i_SmallestRightVertexColorClassSize = m_vi_RightVertexColorFrequency[i]; } } m_i_LargestVertexColorClassSize = m_i_LargestLeftVertexColorClassSize>m_i_LargestRightVertexColorClassSize?m_i_LargestLeftVertexColorClassSize:m_i_LargestRightVertexColorClassSize; m_i_LargestVertexColorClass = m_i_LargestVertexColorClassSize==m_i_LargestLeftVertexColorClassSize?m_i_LargestLeftVertexColorClass:m_i_LargestRightVertexColorClass; m_i_SmallestVertexColorClassSize = m_i_SmallestLeftVertexColorClassSize vi_CandidateColors, vi_VertexColors; int i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); int i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); int i_LeftVertexCoverSize = (signed) m_vi_CoveredLeftVertices.size(); int i_RightVertexCoverSize = (signed) m_vi_CoveredRightVertices.size(); m_i_VertexColorCount = STEP_UP(i_LeftVertexCoverSize) + STEP_UP(i_RightVertexCoverSize); vi_VertexColors.clear(); vi_VertexColors.resize((unsigned) i_LeftVertexCount + i_RightVertexCount, _FALSE); vi_CandidateColors.clear(); vi_CandidateColors.resize((unsigned) m_i_VertexColorCount, _UNKNOWN); i_ColorViolationCount = _FALSE; for(i=0; i0) { free_2DMatrix(dp2_lSeed, i_lseed_rowCount); } else { cerr<<"ERR: freeing left seed matrix with 0 row"<0) { free_2DMatrix(dp2_rSeed, i_rseed_rowCount); } else { cerr<<"ERR: freeing right seed matrix with 0 row"< vi_CandidateColors; vector vi_EdgeStarMap, vi_LeftStarHubMap, vi_RightStarHubMap; vector vi_FirstTreated; vector vi_FirstNeighborOne, vi_FirstNeighborTwo; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_LargerVertexCount = i_LeftVertexCount>i_RightVertexCount?i_LeftVertexCount:i_RightVertexCount; i_EdgeCount = (signed) m_vi_Edges.size()/2; vi_EdgeStarMap.clear(); vi_EdgeStarMap.resize((unsigned) i_EdgeCount, _UNKNOWN); m_mimi2_VertexEdgeMap.clear(); k=_FALSE; for(i=0; i _FALSE) { vi_CandidateColors[m_vi_LeftVertexColors[i_SecondNeighboringVertex]] = i_PresentVertex; } } } } for(j=_TRUE; j vi_CandidateColors; vector vi_EdgeStarMap, vi_LeftStarHubMap, vi_RightStarHubMap; vector vi_FirstTreated; vector vi_FirstNeighborOne, vi_FirstNeighborTwo; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_LargerVertexCount = i_LeftVertexCount>i_RightVertexCount?i_LeftVertexCount:i_RightVertexCount; i_EdgeCount = (signed) m_vi_Edges.size()/2; vi_EdgeStarMap.clear(); vi_EdgeStarMap.resize((unsigned) i_EdgeCount, _UNKNOWN); m_mimi2_VertexEdgeMap.clear(); k=_FALSE; for(i=0; i _FALSE) { vi_CandidateColors[m_vi_RightVertexColors[i_SecondNeighboringVertex]] = i_PresentVertex; } } } } for(j=_TRUE; j vi_CandidateColors; vector vi_EdgeCodes; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_EdgeCount = (signed) m_vi_Edges.size()/2; m_mimi2_VertexEdgeMap.clear(); k=_FALSE; for(i=0; i vi_CandidateColors; vector vi_EdgeStarMap, vi_LeftStarHubMap, vi_RightStarHubMap; vector vi_LeftTreated, vi_RightTreated; vector vi_FirstNeighborOne, vi_FirstNeighborTwo; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_EdgeCount = (signed) m_vi_Edges.size()/2; vi_EdgeStarMap.clear(); vi_EdgeStarMap.resize((unsigned) i_EdgeCount, _UNKNOWN); m_mimi2_VertexEdgeMap.clear(); k=_FALSE; for(i=0; i vi_CandidateColors; vector vi_EdgeStarMap, vi_LeftStarHubMap, vi_RightStarHubMap; vector vi_LeftTreated, vi_RightTreated; vector vi_FirstNeighborOne, vi_FirstNeighborTwo; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_EdgeCount = (signed) m_vi_Edges.size()/2; vi_EdgeStarMap.clear(); vi_EdgeStarMap.resize((unsigned) i_EdgeCount, _UNKNOWN); m_mimi2_VertexEdgeMap.clear(); k=_FALSE; for(i=0; i vi_IncludedEdges; vector vi_CandidateColors; vector vi_EdgeStarMap, vi_LeftStarHubMap, vi_RightStarHubMap; vector vi_LeftTreated, vi_RightTreated; vector vi_FirstNeighborOne, vi_FirstNeighborTwo; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_EdgeCount = (signed) m_vi_Edges.size()/2; vi_EdgeStarMap.clear(); vi_EdgeStarMap.resize((unsigned) i_EdgeCount, _UNKNOWN); m_mimi2_VertexEdgeMap.clear(); i_IncludedEdgeCount =_FALSE; for(i=0; i= i_EdgeCount) { break; } } i_LeftVertexDefaultColor = _FALSE; i_RightVertexDefaultColor = _FALSE; for(i=0; i vi_IncludedEdges; vector vi_CandidateColors; vector vi_EdgeStarMap, vi_LeftStarHubMap, vi_RightStarHubMap; vector vi_LeftTreated, vi_RightTreated; vector vi_FirstNeighborOne, vi_FirstNeighborTwo; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_EdgeCount = (signed) m_vi_Edges.size()/2; vi_EdgeStarMap.clear(); vi_EdgeStarMap.resize((unsigned) i_EdgeCount, _UNKNOWN); m_mimi2_VertexEdgeMap.clear(); i_IncludedEdgeCount =_FALSE; for(i=0; i= i_EdgeCount) { break; } } i_LeftVertexDefaultColor = _FALSE; i_RightVertexDefaultColor = _FALSE; for(i=0; i vi_IncludedEdges; vector vi_CandidateColors; vector vi_EdgeStarMap, vi_LeftStarHubMap, vi_RightStarHubMap; vector vi_LeftTreated, vi_RightTreated; vector vi_FirstNeighborOne, vi_FirstNeighborTwo; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_EdgeCount = (signed) m_vi_Edges.size()/2; vi_EdgeStarMap.clear(); vi_EdgeStarMap.resize((unsigned) i_EdgeCount, _UNKNOWN); m_mimi2_VertexEdgeMap.clear(); i_IncludedEdgeCount =_FALSE; for(i=0; i= i_EdgeCount) { break; } } i_LeftVertexDefaultColor = _FALSE; i_RightVertexDefaultColor = _FALSE; for(i=0; i vi_CandidateColors; vector vi_IncludedEdges; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_EdgeCount = (signed) m_vi_Edges.size()/2; m_mimi2_VertexEdgeMap.clear(); i_IncludedEdgeCount =_FALSE; for(i=0; i= i_EdgeCount) { break; } } i_LeftVertexDefaultColor = _FALSE; i_RightVertexDefaultColor = _FALSE; for(i=0; i vi_VertexColors; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_MaximumColorCount = STEP_UP(i_LeftVertexCount) + STEP_UP(i_RightVertexCount); vi_VertexColors.clear(); vi_VertexColors.resize((unsigned) i_MaximumColorCount, _FALSE); i_ColorViolationCount = _FALSE; for(i=0; i &output) { output = m_vi_LeftVertexColors; } //Public Function 3574 void BipartiteGraphBicoloring::GetRightVertexColors(vector &output) { output = m_vi_RightVertexColors; } void BipartiteGraphBicoloring::GetRightVertexColors_Transformed(vector &output) { int rowCount = GetRowVertexCount(); int columnCount = GetColumnVertexCount(); output = m_vi_RightVertexColors; for (int i=0; i < output.size(); i++) { output[i] -= rowCount; if (output[i] == columnCount + 1) output[i] = 0; //color 0, the rows with this color should be ignored. } } //Public Function 3575 void BipartiteGraphBicoloring::PrintVertexBicolorClasses() { if(CalculateVertexColorClasses() != _TRUE) { cout<(*ip1_SeedColumnCount)) { printf("**WARNING: Out of bound: Seed[%d >= %d][%d] = 1. \n",m_vi_LeftVertexColors[i]-1,(*ip1_SeedColumnCount), i); } #endif if(m_vi_LeftVertexColors[i] != 0) { //ignore color 0 Seed[m_vi_LeftVertexColors[i]-1][i] = 1.; } } return Seed; } double** BipartiteGraphBicoloring::GetRightSeedMatrix_unmanaged(int* ip1_SeedRowCount, int* ip1_SeedColumnCount) { int i_size = GetRightVertexCount(); vector RightVertexColors_Transformed; GetRightVertexColors_Transformed(RightVertexColors_Transformed); int i_num_of_colors = m_i_RightVertexColorCount; if (i_RightVertexDefaultColor == 1) i_num_of_colors--; //color ID 0 is used, ignore it (*ip1_SeedRowCount) = i_size; (*ip1_SeedColumnCount) = i_num_of_colors; if((*ip1_SeedRowCount) == 0 || (*ip1_SeedColumnCount) == 0) return NULL; #if DEBUG != _UNKNOWN printf("Seed[%d][%d] \n",(*ip1_SeedRowCount),(*ip1_SeedColumnCount)); #endif // allocate and initialize Seed matrix double** Seed = new double*[(*ip1_SeedRowCount)]; for (int i=0; i<(*ip1_SeedRowCount); i++) { Seed[i] = new double[(*ip1_SeedColumnCount)]; for(int j=0; j<(*ip1_SeedColumnCount); j++) Seed[i][j]=0.; } // populate Seed matrix for (int i=0; i < (*ip1_SeedRowCount); i++) { #if DEBUG != _UNKNOWN if(RightVertexColors_Transformed[i]>(*ip1_SeedRowCount)) { printf("**WARNING: Out of bound: Seed[%d][%d >= %d] = 1. \n",i, RightVertexColors_Transformed[i] - 1, (*ip1_SeedRowCount)); } #endif if(RightVertexColors_Transformed[i] != 0) { //ignore color 0 Seed[i][RightVertexColors_Transformed[i] - 1] = 1.; } } return Seed; } double BipartiteGraphBicoloring::GetVertexColoringTime() { return m_d_ColoringTime; } void BipartiteGraphBicoloring::GetSeedMatrix(double*** dp3_LeftSeed, int* ip1_LeftSeedRowCount, int* ip1_LeftSeedColumnCount, double*** dp3_RightSeed, int* ip1_RightSeedRowCount, int* ip1_RightSeedColumnCount) { (*dp3_LeftSeed) = GetLeftSeedMatrix(ip1_LeftSeedRowCount, ip1_LeftSeedColumnCount); (*dp3_RightSeed) = GetRightSeedMatrix(ip1_RightSeedRowCount, ip1_RightSeedColumnCount); } void BipartiteGraphBicoloring::GetSeedMatrix_unmanaged(double*** dp3_LeftSeed, int* ip1_LeftSeedRowCount, int* ip1_LeftSeedColumnCount, double*** dp3_RightSeed, int* ip1_RightSeedRowCount, int* ip1_RightSeedColumnCount) { (*dp3_LeftSeed) = GetLeftSeedMatrix_unmanaged(ip1_LeftSeedRowCount, ip1_LeftSeedColumnCount); (*dp3_RightSeed) = GetRightSeedMatrix_unmanaged(ip1_RightSeedRowCount, ip1_RightSeedColumnCount); } } ColPack-1.0.10/BipartiteGraphBicoloring/BipartiteGraphBicoloring.h000066400000000000000000000242301266356121500251200ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ using namespace std; #ifndef BIPARTITEGRAPHBICOLORING_H #define BIPARTITEGRAPHBICOLORING_H namespace ColPack { /** @ingroup group22 * @brief class BipartiteGraphBicoloring in @link group22@endlink. Bipartite graph bicoloring is an assignment of colors to subsets of column and row vertices of the bipartite graph of a Jacobian matrix. The present version of ColPack provides methods for star bicoloring only. The distance-one coloring constraint is satisfied by all bicoloring algorithms by selecting colors for row and column vertices from two disjoint sets of colors. Sizes of the sets are equal to the number of row and column vertices respectively, which are the maximum number of colors that can be required by the row or column vertices. In star bicoloring, vertex cover can be computed either explicitly or implicitly. An explicit vertex cover is computed and used to determine which vertices are to be colored. An implicit vertex cover is computed by including vertices as they get colored, into the cover and is used to determine the end of coloring as a vertex cover is reached. In both cases pre-computed vertex ordering determines the order in which vertices are colored. In implicit vertex cover, a vertex is not selected as a candidate vertex to be colored if no edge is incident on the vertex which has not been covered by any other colored vertex. */ class BipartiteGraphBicoloring : public BipartiteGraphOrdering { public: //DOCUMENTED //Public Function 3573 /// Get the color IDs for the left vertices (rows). Color IDs start from 1, color ID 0 should be ignored void GetLeftVertexColors(vector &output); //Public Function 3574 /// Get the color IDs for the right vertices (columns). Color IDs start from (# of rows + 1), color ID (# of rows + # of columns + 1) should be ignored void GetRightVertexColors(vector &output); /// Get the color IDs for the right vertices (columns) in the format similar to GetLeftVertexColor(). Color IDs start from 1, color ID 0 should be ignored void GetRightVertexColors_Transformed(vector &output); ///Generate and return the Left Seed matrix. This Seed matrix is managed and freed by ColPack /**Precondition: - the Graph has been Bicolored Postcondition: - Size of the returned matrix is (*ip1_SeedRowCount) rows x (*ip1_SeedColumnCount) columns. (*ip1_SeedColumnCount) == num of rows of the original matrix == GetRowVertexCount() (*ip1_SeedRowCount) == num of colors used to color the left (row) vertices excluding color 0. Notes: - Vertices with color 0 are ignored. That also means left (row) vertices with color 1 will be grouped together into the first row (row 0) of the seed matrix and so on. */ double** GetLeftSeedMatrix(int* ip1_SeedRowCount, int* ip1_SeedColumnCount); /// Same as GetLeftSeedMatrix(), except that this Seed matrix is NOT managed by ColPack /** Notes: - This Seed matrix is NOT managed by ColPack. Therefore, the user should free the Seed matrix manually when the matrix is no longer needed. */ double** GetLeftSeedMatrix_unmanaged(int* ip1_SeedRowCount, int* ip1_SeedColumnCount); ///Return the Right Seed matrix. This Seed matrix is managed and freed by ColPack /** Precondition: - the Graph has been Bicolored Postcondition: - Size of the returned matrix is (*ip1_SeedRowCount) rows x (*ip1_SeedColumnCount) columns. (*ip1_SeedRowCount) == num of columns of the original matrix == GetColumnVertexCount() (*ip1_SeedColumnCount) == num of colors used to color the right (column) vertices excluding color 0. Notes: - Vertices with color 0 are ignored. That also means right (column) vertices with color 1 will be grouped together into the first column (column 0) of the seed matrix and so on. */ double** GetRightSeedMatrix(int* ip1_SeedRowCount, int* ip1_SeedColumnCount); /// Same as GetRightSeedMatrix(), except that this Seed matrix is NOT managed by ColPack /** Notes: - This Seed matrix is NOT managed by ColPack. Therefore, the user should free the Seed matrix manually when the matrix is no longer needed. */ double** GetRightSeedMatrix_unmanaged(int* ip1_SeedRowCount, int* ip1_SeedColumnCount); ///Return both the Left and Right Seed matrix. These Seed matrices are managed and freed by ColPack /** Notes: - These Seed matrices are NOT managed by ColPack. Therefore, the user should free the Seed matrices manually when the matrices are no longer needed. */ void GetSeedMatrix(double*** dp3_LeftSeed, int* ip1_LeftSeedRowCount, int* ip1_LeftSeedColumnCount, double*** dp3_RightSeed, int* ip1_RightSeedRowCount, int* ip1_RightSeedColumnCount); /// Same as GetSeedMatrix(), except that These Seed matrices are NOT managed by ColPack /** Notes: - These Seed matrices are NOT managed by ColPack. Therefore, the user should free the Seed matrices manually when the matrices are no longer needed. */ void GetSeedMatrix_unmanaged(double*** dp3_LeftSeed, int* ip1_LeftSeedRowCount, int* ip1_LeftSeedColumnCount, double*** dp3_RightSeed, int* ip1_RightSeedRowCount, int* ip1_RightSeedColumnCount); protected: //DOCUMENTED /// Whether or not color 0 is used for left vertices /** i_LeftVertexDefaultColor == - 0 if color 0 is not used - 1 if color 0 is used //*/ int i_LeftVertexDefaultColor; /// Whether or not color 0 is used for right vertices /** i_RightVertexDefaultColor == - 0 if color 0 is not used - 1 if color 0 is used //*/ int i_RightVertexDefaultColor; /// The number of colors used to color Left Vertices /** Note: Color 0 is also counted if used. If color 0 is used, i_LeftVertexDefaultColor will be set to 1. //*/ int m_i_LeftVertexColorCount; /// The number of colors used to color Right Vertices /** Note: Color 0 (or actually (i_LeftVertexCount + i_RightVertexCount + 1)) is also counted if used. If color 0 is used, i_RightVertexDefaultColor will be set to 1. //*/ int m_i_RightVertexColorCount; int m_i_VertexColorCount; /// The color IDs used to color the left vertices (rows). /** Note: Color IDs start from 1, color ID 0 should be ignored //*/ vector m_vi_LeftVertexColors; /// The color IDs used to color the right vertices (columns). /** Note: Color IDs start from (# of rows + 1), color ID (# of rows + # of columns + 1), which is color 0, should be ignored //*/ vector m_vi_RightVertexColors; bool lseed_available; int i_lseed_rowCount; double** dp2_lSeed; bool rseed_available; int i_rseed_rowCount; double** dp2_rSeed; void Seed_init(); void Seed_reset(); private: //Private Function 3501 void PresetCoveredVertexColors(); //Private Function 3506 int CheckVertexColoring(string s_VertexColoringVariant); //Private Function 3507 int CalculateVertexColorClasses(); //Private Function 3508 int FixMinimalCoverStarBicoloring(); protected: int m_i_ViolationCount; //int m_i_ColoringUnits; // used in ImplicitCoveringAcyclicBicoloring() int m_i_LargestLeftVertexColorClass; int m_i_LargestRightVertexColorClass; int m_i_LargestLeftVertexColorClassSize; int m_i_LargestRightVertexColorClassSize; int m_i_SmallestLeftVertexColorClass; int m_i_SmallestRightVertexColorClass; int m_i_SmallestLeftVertexColorClassSize; int m_i_SmallestRightVertexColorClassSize; int m_i_LargestVertexColorClass; int m_i_SmallestVertexColorClass; int m_i_LargestVertexColorClassSize; int m_i_SmallestVertexColorClassSize; double m_d_AverageLeftVertexColorClassSize; double m_d_AverageRightVertexColorClassSize; double m_d_AverageVertexColorClassSize; double m_d_ColoringTime; double m_d_CheckingTime; string m_s_VertexColoringVariant; vector m_vi_LeftVertexColorFrequency; vector m_vi_RightVertexColorFrequency; public: //Public Constructor 3551 BipartiteGraphBicoloring(); //Public Destructor 3552 ~BipartiteGraphBicoloring(); //Virtual Function 3553 virtual void Clear(); //Virtual Function 3554 virtual void Reset(); //Public Function 3562 int ImplicitCoveringStarBicoloring(); //Public Function 3560 int ExplicitCoveringStarBicoloring(); //Public Function 3559 int ExplicitCoveringModifiedStarBicoloring(); //Public Function 3564 int ImplicitCoveringGreedyStarBicoloring(); //Public Function 3556 int MinimalCoveringRowMajorStarBicoloring(); //???? //Public Function 3557 int MinimalCoveringColumnMajorStarBicoloring(); //???? //Public Function 3558 int ImplicitCoveringConservativeStarBicoloring(); // CRASH //Public Function 3561 int MinimalCoveringStarBicoloring(); // CRASH //Public Function 3563 int ImplicitCoveringRestrictedStarBicoloring(); // CRASH //Public Function 3565 int CheckStarBicoloring(); //Public Function 3568 int GetLeftVertexColorCount(); //Public Function 3569 int GetRightVertexColorCount(); //Public Function 3570 int GetVertexColorCount(); //Public Function 3571 int GetViolationCount(); int GetRightVertexDefaultColor(); //Public Function 3572 string GetVertexBicoloringVariant(); string GetVertexColoringVariant(); //Public Function 3575 void PrintVertexBicolors(); //Public Function 3576 void PrintVertexBicoloringMetrics(); //Public Function 3577 void PrintVertexBicolorClasses(); double GetVertexColoringTime(); }; } #endif ColPack-1.0.10/BipartiteGraphBicoloring/BipartiteGraphBicoloringInterface.cpp000066400000000000000000000211321266356121500272720ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Public Destructor 3702 BipartiteGraphBicoloringInterface::~BipartiteGraphBicoloringInterface() { BipartiteGraphBicoloring::Clear(); Seed_reset(); } //Virtual Function 3703 void BipartiteGraphBicoloringInterface::Clear() { BipartiteGraphBicoloring::Clear(); return; } //Virtual Function 3704 void BipartiteGraphBicoloringInterface::Reset() { BipartiteGraphBicoloring::Reset(); return; } void BipartiteGraphBicoloringInterface::GenerateSeedJacobian(double*** dp3_LeftSeed, int *ip1_LeftSeedRowCount, int *ip1_LeftSeedColumnCount, double*** dp3_RightSeed, int *ip1_RightSeedRowCount, int *ip1_RightSeedColumnCount, string s_OrderingVariant, string s_BicoloringVariant) { //void BipartiteGraphBicoloringInterface::GenerateSeedJacobian(unsigned int ** uip2_JacobianSparsityPattern, int i_RowCount, int i_ColumnCount, double*** dp3_LeftSeed, int *ip1_LeftSeedRowCount, int *ip1_LeftSeedColumnCount, double*** dp3_RightSeed, int *ip1_RightSeedRowCount, int *ip1_RightSeedColumnCount, string s_OrderingVariant, string s_BicoloringVariant) { //Clear (Re-initialize) the bipartite graph //Clear(); //Read the sparsity pattern of the given Jacobian matrix (compressed sparse rows format) //and create the corresponding bipartite graph //BuildBPGraphFromRowCompressedFormat(uip2_JacobianSparsityPattern, i_RowCount, i_ColumnCount); //Color the graph based on the specified ordering and (Star) Bicoloring Bicoloring(s_OrderingVariant, s_BicoloringVariant); //From the coloring information, create and return the Left and Right seed matrices *dp3_LeftSeed = GetLeftSeedMatrix(ip1_LeftSeedRowCount, ip1_LeftSeedColumnCount); *dp3_RightSeed = GetRightSeedMatrix(ip1_RightSeedRowCount, ip1_RightSeedColumnCount); } void BipartiteGraphBicoloringInterface::GenerateSeedJacobian_unmanaged(double*** dp3_LeftSeed, int *ip1_LeftSeedRowCount, int *ip1_LeftSeedColumnCount, double*** dp3_RightSeed, int *ip1_RightSeedRowCount, int *ip1_RightSeedColumnCount, string s_OrderingVariant, string s_BicoloringVariant) { //Color the graph based on the specified ordering and (Star) Bicoloring Bicoloring(s_OrderingVariant, s_BicoloringVariant); //From the coloring information, create and return the Left and Right seed matrices *dp3_LeftSeed = GetLeftSeedMatrix_unmanaged(ip1_LeftSeedRowCount, ip1_LeftSeedColumnCount); *dp3_RightSeed = GetRightSeedMatrix_unmanaged(ip1_RightSeedRowCount, ip1_RightSeedColumnCount); } int BipartiteGraphBicoloringInterface::Bicoloring(string s_OrderingVariant, string s_BicoloringVariant) { m_T_Timer.Start(); int i_OrderingStatus = OrderVertices(s_OrderingVariant); m_T_Timer.Stop(); m_d_OrderingTime = m_T_Timer.GetWallTime(); if(i_OrderingStatus != _TRUE) { cerr< &output) { BipartiteGraphOrdering::GetOrderedVertices(output); } } ColPack-1.0.10/BipartiteGraphBicoloring/BipartiteGraphBicoloringInterface.h000066400000000000000000000174371266356121500267540ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ using namespace std; #ifndef BIPARTITEGRAPHBICOLORINGINTERFACE_H #define BIPARTITEGRAPHBICOLORINGINTERFACE_H namespace ColPack { /** @ingroup group22 * @brief class BipartiteGraphBicoloringInterface in @link group22@endlink. To be completed. */ class BipartiteGraphBicoloringInterface : public BipartiteGraphBicoloring { public: //DOCUMENTED /// Build a BipartiteGraphBicoloringInterface object and create the bipartite graph based on the graph structure specified by the input source /** This function will: - 0. Create initial BipartiteGraphPartialColoringInterface object - 1. Create the bipartite graph based on the graph structure specified by the input source Structure of this variadic function's parameters: BipartiteGraphBicoloringInterface(int i_type, [2 or more parameters for input source depending on the value of i_type]). Here are some examples: - Just create the BipartiteGraphBicoloringInterface object: BipartiteGraphBicoloringInterface(SRC_WAIT); - Get the input from file: BipartiteGraphBicoloringInterface(SRC_FILE, s_InputFile.c_str() ,"AUTO_DETECTED"); - Get input from ADOLC: BipartiteGraphBicoloringInterface(SRC_MEM_ADOLC,uip2_SparsityPattern, i_rowCount, i_columnCount); About input parameters: - int i_type: specified the input source. i_type can be either: - -1 (SRC_WAIT): only step 0 will be done. - 0 (SRC_FILE): The graph structure will be read from file. The next 2 parameters are: - char* fileName: name of the input file. If the full path is not given, the file is assumed to be in the current directory - char* fileType can be either: - "AUTO_DETECTED" or "". ColPack will decide the format of the file based on the file extension: - ".mtx": MatrixMarket format - ".hb", or any combination of ".": HarwellBoeing format - ".graph": MeTiS format - ".gen": Generic Matrix format - ".gens": Generic Square Matrix format - If the above extensions are not found, MatrixMarket format will be assumed. - "MM" for MatrixMarket format (http://math.nist.gov/MatrixMarket/formats.html#MMformat). Notes: - ColPack only accepts MatrixMarket coordinate format (NO array format) - List of arithmetic fields accepted by ColPack: real, pattern or integer - List of symmetry structures accepted by ColPack: general or symmetric - The first line of the input file should be similar to this: "%%MatrixMarket matrix coordinate real general" - "HB" for HarwellBoeing format (http://math.nist.gov/MatrixMarket/formats.html#hb) - "MeTiS" for MeTiS format (http://people.sc.fsu.edu/~burkardt/data/metis_graph/metis_graph.html) - "GEN" for Generic Matrix format - "GENS" for Generic Square Matrix format - 1 (SRC_MEM_ADOLC): The graph structure will be read from Row Compressed Structure (used by ADOLC). The next 3 parameters are: - unsigned int **uip2_SparsityPattern: The pattern of Jacobian matrix stored in Row Compressed Format - int i_rowCount: number of rows in the Jacobian matrix. Number of rows in uip2_SparsityPattern. - int i_ColumnCount: number of columns in the Jacobian matrix. Number of columns in uip2_SparsityPattern. - 2 (SRC_MEM_ADIC): TO BE IMPLEMENTED so that ColPack can interface with ADIC //*/ BipartiteGraphBicoloringInterface(int i_type, ...); /// Generate and return the Left and Right Seed matrices /** This function will - 1. Color the graph based on the specified ordering and (Star) Bicoloring - 2. From the coloring information, create and return the Left (*dp3_LeftSeed[*ip1_RowColorCount][i_RowCount]) and Right (*dp3_RightSeed[i_ColumnCount][*ip1_ColumnColorCount]) seed matrices About input parameters: - s_OrderingVariant can be either - "NATURAL" (default) - "LARGEST_FIRST" - "DYNAMIC_LARGEST_FIRST" - "SMALLEST_LAST" - "INCIDENCE_DEGREE" - "RANDOM" - s_BicoloringVariant can be either - "IMPLICIT_COVERING__STAR_BICOLORING" (default) - "EXPLICIT_COVERING__STAR_BICOLORING" - "EXPLICIT_COVERING__MODIFIED_STAR_BICOLORING" - "IMPLICIT_COVERING__GREEDY_STAR_BICOLORING" Postcondition: - *dp3_LeftSeed: the size will be: - Row count (*ip1_LeftSeedRowCount): Row Color Count - Column count (*ip1_LeftSeedColumnCount): Jacobian's Row Count - *dp3_RightSeed: the size will be: - Row count (*ip1_RightSeedRowCount): Jacobian's Column Count - Column count (*ip1_RightSeedColumnCount): Column Color Count */ void GenerateSeedJacobian(double*** dp3_LeftSeed, int *ip1_LeftSeedRowCount, int *ip1_LeftSeedColumnCount, double*** dp3_RightSeed, int *ip1_RightSeedRowCount, int *ip1_RightSeedColumnCount, string s_OrderingVariant="NATURAL", string s_BicoloringVariant = "IMPLICIT_COVERING__STAR_BICOLORING"); /// Same as GenerateSeedJacobian(), except that these Seed matrices are NOT managed by ColPack /** Notes: - These Seed matrices are NOT managed by ColPack. Therefore, the user should free the Seed matrices manually when the matrices are no longer needed. */ void GenerateSeedJacobian_unmanaged(double*** dp3_LeftSeed, int *ip1_LeftSeedRowCount, int *ip1_LeftSeedColumnCount, double*** dp3_RightSeed, int *ip1_RightSeedRowCount, int *ip1_RightSeedColumnCount, string s_OrderingVariant="NATURAL", string s_BicoloringVariant = "IMPLICIT_COVERING__STAR_BICOLORING"); /// Bicolor the bipartite graph based on the requested s_BicoloringVariant and s_OrderingVariant /** This function will - 1. Order the vertices based on the requested Ordering variant (s_OrderingVariant) - 2. Bicolor the graph based on the requested Bicoloring variant (s_BicoloringVariant) - Ordering Time and Coloring Time will be recorded. About input parameters: - s_OrderingVariant can be either - "NATURAL" (default) - "LARGEST_FIRST" - "DYNAMIC_LARGEST_FIRST" - "SMALLEST_LAST" - "INCIDENCE_DEGREE" - "RANDOM" - s_BicoloringVariant can be either - "IMPLICIT_COVERING__STAR_BICOLORING" (default) - "EXPLICIT_COVERING__STAR_BICOLORING" - "EXPLICIT_COVERING__MODIFIED_STAR_BICOLORING" - "IMPLICIT_COVERING__GREEDY_STAR_BICOLORING" Postcondition: - The Bipartite Graph is Bicolored, i.e., m_vi_LeftVertexColors and m_vi_RightVertexColors will be populated. */ int Bicoloring(string s_OrderingVariant = "NATURAL", string s_BicoloringVariant = "IMPLICIT_COVERING__STAR_BICOLORING"); ///Return the Left Seed matrix double** GetLeftSeedMatrix(int* ip1_LeftSeedRowCount, int* ip1_LeftSeedColumnCount); ///Return the Right Seed matrix double** GetRightSeedMatrix(int* ip1_RightSeedRowCount, int* ip1_RightSeedColumnCount); void GetOrderedVertices(vector &output); private: Timer m_T_Timer; public: //Public Destructor 3702 ~BipartiteGraphBicoloringInterface(); //Virtual Function 3703 virtual void Clear(); //Virtual Function 3704 virtual void Reset(); }; } #endif ColPack-1.0.10/BipartiteGraphBicoloring/BipartiteGraphCore.cpp000066400000000000000000000141261266356121500242570ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Virtual Function 2102:3102 void BipartiteGraphCore::Clear() { m_i_MaximumLeftVertexDegree = _UNKNOWN; m_i_MaximumRightVertexDegree = _UNKNOWN; m_i_MaximumVertexDegree = _UNKNOWN; m_i_MinimumLeftVertexDegree = _UNKNOWN; m_i_MinimumRightVertexDegree = _UNKNOWN; m_i_MinimumVertexDegree = _UNKNOWN; m_d_AverageLeftVertexDegree = _UNKNOWN; m_d_AverageRightVertexDegree = _UNKNOWN; m_d_AverageVertexDegree = _UNKNOWN; m_s_InputFile.clear(); m_vi_LeftVertices.clear(); m_vi_RightVertices.clear(); m_vi_Edges.clear(); m_mimi2_VertexEdgeMap.clear(); } //Public Function 2103:3103 string BipartiteGraphCore::GetInputFile() { return(m_s_InputFile); } vector* BipartiteGraphCore::GetLeftVerticesPtr() { return &m_vi_LeftVertices; } vector* BipartiteGraphCore::GetRightVerticesPtr() { return &m_vi_RightVertices; } //Public Function 2104:3104 void BipartiteGraphCore::GetRowVertices(vector &output) const { output = (m_vi_LeftVertices); } unsigned int BipartiteGraphCore::GetRowVertices(unsigned int** ip2_RowVertex) { (*ip2_RowVertex) = (unsigned int*) malloc(m_vi_LeftVertices.size() * sizeof(unsigned int)); for(unsigned int i=0; i < m_vi_LeftVertices.size(); i++) { (*ip2_RowVertex)[i] = m_vi_LeftVertices[i]; } return m_vi_LeftVertices.size(); } unsigned int BipartiteGraphCore::GetColumnIndices(unsigned int** ip2_ColumnIndex) { unsigned int ui_UpperBound = m_vi_LeftVertices[m_vi_LeftVertices.size() - 1]; (*ip2_ColumnIndex) = (unsigned int*) malloc(ui_UpperBound * sizeof(unsigned int)); for(unsigned int i=0; i < ui_UpperBound; i++) { (*ip2_ColumnIndex)[i] = m_vi_Edges[i]; } return ui_UpperBound; } void BipartiteGraphCore::GetLeftVertices(vector &output) const { output = (m_vi_LeftVertices); } //Public Function 2105:3105 void BipartiteGraphCore::GetColumnVertices(vector &output) const { output = (m_vi_RightVertices); } void BipartiteGraphCore::GetRightVertices(vector &output) const { output = (m_vi_RightVertices); } //Public Function 2106:3106 void BipartiteGraphCore::GetEdges(vector &output) const { output = (m_vi_Edges); } //Public Function 2107:3107 void BipartiteGraphCore::GetVertexEdgeMap(map< int, map > &output) { output = (m_mimi2_VertexEdgeMap); } //Public Function 2108:3108 int BipartiteGraphCore::GetRowVertexCount() { return(STEP_DOWN(m_vi_LeftVertices.size())); } int BipartiteGraphCore::GetLeftVertexCount() { return(STEP_DOWN(m_vi_LeftVertices.size())); } //Public Function 2109:3109 int BipartiteGraphCore::GetColumnVertexCount() { return(STEP_DOWN(m_vi_RightVertices.size())); } int BipartiteGraphCore::GetRightVertexCount() { return(STEP_DOWN(m_vi_RightVertices.size())); } //Public Function 2110:3110 int BipartiteGraphCore::GetEdgeCount() { return(m_vi_Edges.size()/2); } //Public Function 2111:3111 int BipartiteGraphCore::GetMaximumRowVertexDegree() { return(m_i_MaximumLeftVertexDegree); } //Public Function 2112:3112 int BipartiteGraphCore::GetMaximumColumnVertexDegree() { return(m_i_MaximumRightVertexDegree); } //Public Function 2113:3113 int BipartiteGraphCore::GetMaximumVertexDegree() { return(m_i_MaximumVertexDegree); } //Public Function 2114:3114 int BipartiteGraphCore::GetMinimumRowVertexDegree() { return(m_i_MinimumLeftVertexDegree); } //Public Function 2115:3115 int BipartiteGraphCore::GetMinimumColumnVertexDegree() { return(m_i_MinimumRightVertexDegree); } //Public Function 2116:3116 int BipartiteGraphCore::GetMinimumVertexDegree() { return(m_i_MinimumVertexDegree); } //Public Function 2117:3117 double BipartiteGraphCore::GetAverageRowVertexDegree() { return(m_d_AverageLeftVertexDegree); } //Public Function 2118:3118 double BipartiteGraphCore::GetAverageColumnVertexDegree() { return(m_d_AverageRightVertexDegree); } //Public Function 2119:3119 double BipartiteGraphCore::GetAverageVertexDegree() { return(m_d_AverageVertexDegree); } bool BipartiteGraphCore::operator==(const BipartiteGraphCore &other) const { // Check for self-assignment! if (this == &other) // Same object? return true; // Yes, so the 2 objects are equal //Compare vector m_vi_LeftVertices; vector m_vi_RightVertices; vector m_vi_Edges; vector other_LeftVertices, other_RightVertices, other_Edges; other.GetLeftVertices(other_LeftVertices); other.GetRightVertices(other_RightVertices); other.GetEdges(other_Edges); /* if(m_vi_LeftVertices==other_LeftVertices) cout<<"m_vi_LeftVertices==other_LeftVertices"<. ************************************************************************************/ using namespace std; #ifndef BIPARTITEGRAPHCORE_H #define BIPARTITEGRAPHCORE_H namespace ColPack { /** @ingroup group2 * @brief class BipartiteGraphCore in @link group2@endlink. Base class for Bipartite Graph. Define a Bipartite Graph: left vertices, right vertices and edges; and its statisitcs: max, min and average degree. */ class BipartiteGraphCore { public: //DOCUMENTED /// LeftVertexCount = RowVertexCount = m_vi_LeftVertices.size() -1 int GetRowVertexCount(); /// LeftVertexCount = RowVertexCount = m_vi_LeftVertices.size() -1 int GetLeftVertexCount(); /// RightVertexCount = ColumnVertexCount = m_vi_RightVertices.size() -1 int GetColumnVertexCount(); /// RightVertexCount = ColumnVertexCount = m_vi_RightVertices.size() -1 int GetRightVertexCount(); bool operator==(const BipartiteGraphCore &other) const; protected: int m_i_MaximumLeftVertexDegree; int m_i_MaximumRightVertexDegree; int m_i_MaximumVertexDegree; int m_i_MinimumLeftVertexDegree; int m_i_MinimumRightVertexDegree; int m_i_MinimumVertexDegree; double m_d_AverageLeftVertexDegree; double m_d_AverageRightVertexDegree; double m_d_AverageVertexDegree; string m_s_InputFile; vector m_vi_LeftVertices; vector m_vi_RightVertices; vector m_vi_Edges; map< int, map > m_mimi2_VertexEdgeMap; public: virtual ~BipartiteGraphCore(){} virtual void Clear(); string GetInputFile(); vector* GetLeftVerticesPtr() ; vector* GetRightVerticesPtr() ; void GetRowVertices(vector &output) const; void GetLeftVertices(vector &output) const; void GetColumnVertices(vector &output) const; void GetRightVertices(vector &output) const; unsigned int GetRowVertices(unsigned int** ip2_RowVertex); unsigned int GetColumnIndices(unsigned int** ip2_ColumnIndex); void GetEdges(vector &output) const; void GetVertexEdgeMap(map< int, map > &output); int GetEdgeCount(); int GetMaximumRowVertexDegree(); int GetMaximumColumnVertexDegree(); int GetMaximumVertexDegree(); int GetMinimumRowVertexDegree(); int GetMinimumColumnVertexDegree(); int GetMinimumVertexDegree(); double GetAverageRowVertexDegree(); double GetAverageColumnVertexDegree(); double GetAverageVertexDegree(); }; } #endif ColPack-1.0.10/BipartiteGraphBicoloring/BipartiteGraphInputOutput.cpp000066400000000000000000001000361266356121500257030ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Private Function 2201;3201 void BipartiteGraphInputOutput::CalculateVertexDegrees() { int i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); int i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); int i_TotalLeftVertexDegree = _FALSE; int i_TotalRightVertexDegree = _FALSE; i_TotalLeftVertexDegree = i_TotalRightVertexDegree = m_vi_Edges.size()/2; for(int i = 0; i < i_LeftVertexCount; i++) { int i_VertexDegree = m_vi_LeftVertices[i + 1] - m_vi_LeftVertices[i]; if(m_i_MaximumLeftVertexDegree < i_VertexDegree) { m_i_MaximumLeftVertexDegree = i_VertexDegree; } if(m_i_MinimumLeftVertexDegree == _UNKNOWN) { m_i_MinimumLeftVertexDegree = i_VertexDegree; } else if(m_i_MinimumLeftVertexDegree > i_VertexDegree) { m_i_MinimumLeftVertexDegree = i_VertexDegree; } } for(int i = 0; i < i_RightVertexCount; i++) { int i_VertexDegree = m_vi_RightVertices[i + 1] - m_vi_RightVertices[i]; if(m_i_MaximumRightVertexDegree < i_VertexDegree) { m_i_MaximumRightVertexDegree = i_VertexDegree; } if(m_i_MinimumRightVertexDegree == _UNKNOWN) { m_i_MinimumRightVertexDegree = i_VertexDegree; } else if(m_i_MinimumRightVertexDegree > i_VertexDegree) { m_i_MinimumRightVertexDegree = i_VertexDegree; } } m_i_MaximumVertexDegree = m_i_MaximumLeftVertexDegree>m_i_MaximumRightVertexDegree?m_i_MaximumLeftVertexDegree:m_i_MaximumRightVertexDegree; m_i_MinimumVertexDegree = m_i_MinimumLeftVertexDegree vs_InputTokens; vector< vector > v2i_LeftVertexAdjacency, v2i_RightVertexAdjacency; Clear(); i_EdgeCount = _FALSE; i_LeftVertexCount = i_RightVertexCount = _FALSE; m_s_InputFile = s_InputFile; //READ IN BANNER MM_typecode matcode; FILE *f; if ((f = fopen(m_s_InputFile.c_str(), "r")) == NULL) { cout<>i_RowCount>>i_ColumnCount>>num_of_entries; i_EdgeCount = num_of_entries; i_LeftVertexCount = i_RowCount; i_RightVertexCount = i_ColumnCount; v2i_LeftVertexAdjacency.clear(); v2i_LeftVertexAdjacency.resize((unsigned) i_LeftVertexCount); v2i_RightVertexAdjacency.clear(); v2i_RightVertexAdjacency.resize((unsigned) i_RightVertexCount); } if((i_LineCount > _TRUE) && (i_LineCount <= STEP_UP(i_EdgeCount))) { //cout<<"i_LineCount = "<>i_LeftVertex>>i_RightVertex>>d_Value; entry_counter++; if(d_Value == -999999999. && in2.eof()) { // "d_Value" entry is not specified value_not_specified = true; } else if (d_Value == 0) { continue; } //cout<<"\t i_LeftVertex = "< > colList; getline(InputStream,line); rowCounter++; in2.str(line); in2>>row>>edges; m_vi_LeftVertices.push_back(m_vi_Edges.size()); while(!InputStream.eof()) { getline(InputStream,line); if(line!="") { //cout<<"["<>num) { num--; m_vi_Edges.push_back(num); colList[num].push_back(rowCounter-1); numCount++; //cout<<"\tpush_back "< > vvi_LeftVertexAdjacency, vvi_RightVertexAdjacency; vector vi_ColumnStartPointers; //ignore the first line, which is the tittle and key getline(in, line); // Get line 2 int TOTCRD; // (ignored) Total number of lines excluding header int PTRCRD; // (ignored) Number of lines for pointers int INDCRD; // (ignored) Number of lines for row (or variable) indices int VALCRD; // (ignored) Number of lines for numerical values. VALCRD == 0 if no values is presented int RHSCRD; // (ignored) Number of lines for right-hand sides. RHSCRD == 0 if no right-hand side data is presented getline(in, line); iin.clear(); iin.str(line); iin >> TOTCRD >> PTRCRD >> INDCRD >> VALCRD >> RHSCRD; // Get line 3 string MXTYPE; //Matrix type. We only accept: (R | P) (*) (A) int NROW; // Number of rows (or left vertices) int NCOL; // Number of columns (or right vertices) int NNZERO; // (ignored) Number of nonzeros // in case of symmetric matrix, it is the number of nonzeros IN THE UPPER TRIANGULAR including the diagonal int NELTVL; // (ignored) Number of elemental matrix entries (zero in the case of assembled matrices) bool b_symmetric; // true if this matrix is symmetric (MXTYPE[1] == 'S'), false otherwise. getline(in, line); iin.clear(); iin.str(line); iin >> MXTYPE >> NROW >> NCOL >> NNZERO >> NELTVL; if(MXTYPE[2] == 'E') { cerr<<"ERR: Elemental matrices (unassembled) format is not supported"<> vi_ColumnStartPointers[i]; } //populate vvi_LeftVertexAdjacency & vvi_RightVertexAdjacency nnz = 0; for(i=0; i> num; num--; vvi_RightVertexAdjacency[i].push_back(num); vvi_LeftVertexAdjacency[num].push_back(i); nnz++; if(b_symmetric && num != i) { vvi_RightVertexAdjacency[num].push_back(i); vvi_LeftVertexAdjacency[i].push_back(num); nnz++; } } } m_vi_Edges.clear(); m_vi_Edges.resize(2*nnz, _UNKNOWN); //populate the m_vi_LeftVertices and their edges at the same time m_vi_LeftVertices[0]=0; for(i=0; i > colList; ifstream InputStream (m_s_InputFile.c_str()); if(!InputStream) { cout<<"Not Found File "<-1;tempCounter--) { if(s_InputFile[tempCounter]=='\\') {tempCounter=0; continue;}//end of the filename if(getRow) { if(s_InputFile[tempCounter]<'0'||s_InputFile[tempCounter]>'9') { if(firstTime) continue; else break; } else firstTime=0; sRow=s_InputFile[tempCounter]+sRow; } else { //touch the "by", switch to getRow if(s_InputFile[tempCounter]<'0'||s_InputFile[tempCounter]>'9') { if(firstTime) continue; else {firstTime=1;getRow=1; continue;} } else firstTime=0; sCol=s_InputFile[tempCounter]+sCol; //finish with sCol, switch to sRow } } if (tempCounter==-1) { cout<<"Input file\""<>row; in2.clear();in2.str(sCol);in2>>col; cout<<"Matrix: "<>tempNum) { if(tempNum) { m_vi_Edges.push_back(colCounter); colList[colCounter].push_back(rowCounter); } colCounter++; } m_vi_LeftVertices.push_back(m_vi_Edges.size()); if (colCounter!=col) { cerr<<"WARNING: BipartiteGraphInputOutput::ReadGenericMatrixBipartiteGraph()"< > colList; ifstream InputStream (m_s_InputFile.c_str()); if(!InputStream) { cout<<"Not Found File "<-1;tempCounter--) { if(s_InputFile[tempCounter]=='\\') {tempCounter=0; continue;}//end of the filename if(getRow) { if(s_InputFile[tempCounter]<'0'||s_InputFile[tempCounter]>'9') { if(firstTime) continue; else break; } else firstTime=0; sRow=s_InputFile[tempCounter]+sRow; } else { //touch the "by", switch to getRow if(s_InputFile[tempCounter]<'0'||s_InputFile[tempCounter]>'9') { if(firstTime) continue; else {firstTime=1;getRow=1; continue;} } else firstTime=0; sCol=s_InputFile[tempCounter]+sCol; //finish with sCol, switch to sRow } } if (tempCounter==-1) { cout<<"Input file\""<>row; in2.clear();in2.str(sCol);in2>>col; if(row>col) row=col; else col=row; cout<<"Matrix: "< > colList; m_vi_LeftVertices.clear(); m_vi_LeftVertices.reserve(i_RowCount+1); m_vi_RightVertices.clear(); m_vi_RightVertices.reserve(i_RowCount+1); m_vi_Edges.clear(); m_vi_Edges.reserve(2*ip_RowIndex[i_RowCount]); //??? !!! m_vi_LeftVertices.push_back(0); //equivalent to m_vi_LeftVertices.push_back(m_vi_Edges.size()); //PrintBipartiteGraph (); //Pause(); for(i=0; i < i_RowCount; i++) { for(j=ip_RowIndex[i]; j >::iterator curr; m_vi_RightVertices.push_back(m_vi_Edges.size()); for(int i=0; i <= i_ColumnCount; i++) { curr = colList.find(i); if(curr !=colList.end()) { m_vi_Edges.insert(m_vi_Edges.end(),curr->second.begin(),curr->second.end()); }//else We have an empty column m_vi_RightVertices.push_back(m_vi_Edges.size()); } CalculateVertexDegrees(); return (_TRUE); } int BipartiteGraphInputOutput::BuildBPGraphFromADICFormat(std::list > * lsi_SparsityPattern, int i_ColumnCount) { int i; unsigned int j; map< int,vector > colList; int i_RowCount = (*lsi_SparsityPattern).size(); m_vi_LeftVertices.clear(); m_vi_LeftVertices.reserve(i_RowCount+1); m_vi_RightVertices.clear(); m_vi_RightVertices.reserve(i_ColumnCount+1); m_vi_Edges.clear(); m_vi_LeftVertices.push_back(0); // equivalent to m_vi_LeftVertices.push_back(m_vi_Edges.size()); int rowIndex=-1, colIndex=-1; std::list >::iterator valsetlistiter = (*lsi_SparsityPattern).begin(); for (; valsetlistiter != (*lsi_SparsityPattern).end(); valsetlistiter++){ rowIndex++; std::set::iterator valsetiter = (*valsetlistiter).begin(); for (; valsetiter != (*valsetlistiter).end() ; valsetiter++) { colIndex = *valsetiter; m_vi_Edges.push_back(colIndex); colList[colIndex].push_back(rowIndex); } m_vi_LeftVertices.push_back(m_vi_Edges.size()); } m_vi_Edges.reserve(2*m_vi_Edges.size()); //put together the right vertices map< int,vector >::iterator curr; m_vi_RightVertices.push_back(m_vi_Edges.size()); for(int i=0; i < i_ColumnCount; i++) { curr = colList.find(i); if(curr !=colList.end()) { m_vi_Edges.insert(m_vi_Edges.end(),curr->second.begin(),curr->second.end()); }//else We have an empty column m_vi_RightVertices.push_back(m_vi_Edges.size()); } CalculateVertexDegrees(); //cout<<"PrintBipartiteGraph()"< > colList; m_vi_LeftVertices.clear(); m_vi_LeftVertices.reserve(i_RowCount+1); m_vi_RightVertices.clear(); m_vi_RightVertices.reserve(i_ColumnCount+1); m_vi_Edges.clear(); m_vi_LeftVertices.push_back(m_vi_Edges.size()); for(i=0; i < i_RowCount; i++) { for(j=1; j <= uip2_JacobianSparsityPattern[i][0]; j++) { m_vi_Edges.push_back(uip2_JacobianSparsityPattern[i][j]); colList[ uip2_JacobianSparsityPattern[i][j] ].push_back(i); } m_vi_LeftVertices.push_back(m_vi_Edges.size()); } m_vi_Edges.reserve(2*m_vi_Edges.size()); //put together the right vertices map< int,vector >::iterator curr; m_vi_RightVertices.push_back(m_vi_Edges.size()); for(int i=0; i < i_ColumnCount; i++) { curr = colList.find(i); if(curr !=colList.end()) { m_vi_Edges.insert(m_vi_Edges.end(),curr->second.begin(),curr->second.end()); }//else We have an empty column m_vi_RightVertices.push_back(m_vi_Edges.size()); } CalculateVertexDegrees(); //cout<<"PrintBipartiteGraph()"<. ************************************************************************************/ using namespace std; #ifndef BIPARTITEGRAPHINPUTOUTPUT_H #define BIPARTITEGRAPHINPUTOUTPUT_H namespace ColPack { /** @ingroup group2 * @brief class BipartiteGraphInputOutput in @link group2@endlink. BipartiteGraphInputOutput class provides the input methods for reading in matrix or graph files in supported formats for generating bipartite graphs. Three input formats are supported by default - Matrix Market, Harwell Boeing and MeTiS. This class is similar to the GraphInputOutput class discussed in Section 2.1 in functionalities with the difference that it stores bipartite graphs in CES scheme. */ class BipartiteGraphInputOutput : public BipartiteGraphCore { public: // -----INPUT FUNCTIONS----- // !!! TO BE DOCUMENTED int BuildBPGraphFromADICFormat(std::list > * lsi_SparsityPattern, int i_ColumnCount); /// Read the sparsity pattern of Jacobian matrix represented in zero-based indexing, 3-array variation CSR format and build a corresponding adjacency graph. /** Zero-based indexing, 3-array variation CSR format: http://software.intel.com/sites/products/documentation/hpc/mkl/webhelp/appendices/mkl_appA_SMSF.html#table_79228E147DA0413086BEFF4EFA0D3F04 Return value: - _TRUE upon successful */ int BuildBPGraphFromCSRFormat(int* ip_RowIndex, int i_RowCount, int i_ColumnCount, int* ip_ColumnIndex); /// Read the sparsity pattern of Jacobian matrix represented in ADOLC format (Row Compressed format) and build a corresponding adjacency graph. /** Equivalent to RowCompressedFormat2BipartiteGraph Precondition: - The Jacobian matrix must be stored in Row Compressed Format Return value: - _TRUE upon successful */ int BuildBPGraphFromRowCompressedFormat(unsigned int ** uip2_JacobianSparsityPattern, int i_RowCount, int i_ColumnCount); /// Given a compressed sparse row representation, build the corresponding bipartite graph representation /** Precondition: - The Jacobian matrix must be stored in Row Compressed Format Return value: - _TRUE upon successful */ int RowCompressedFormat2BipartiteGraph(unsigned int ** uip2_JacobianSparsityPattern, int i_RowCount, int i_ColumnCount); /// Read the sparsity pattern of a matrix in the specified file format from the specified filename and build a Bipartite Graph /** This function will - 1. Read the name of the matrix file and decide which matrix format the file used (based on the file extension). If the file name has no extension, the user will need to pass the 2nd parameter "s_fileFormat" explicitly to tell ColPack which matrix format is used - 2. Call the corresponding reading routine to generate the graph About input parameters: - s_InputFile: name of the input file. If the full path is not given, the file is assumed to be in the current directory - s_fileFormat can be either - "AUTO_DETECTED" (default) or "". ColPack will decide the format of the file based on the file extension: - ".mtx": MatrixMarket format - ".hb", or any combination of ".": HarwellBoeing format - ".graph": MeTiS format - ".gen": Generic Matrix format - ".gens": Generic Square Matrix format - If the above extensions are not found, MatrixMarket format will be assumed. - "MM" for MatrixMarket format (http://math.nist.gov/MatrixMarket/formats.html#MMformat). Notes: - ColPack only accepts MatrixMarket coordinate format (NO array format) - List of arithmetic fields accepted by ColPack: real, pattern or integer - List of symmetry structures accepted by ColPack: general or symmetric - The first line of the input file should be similar to this: "%%MatrixMarket matrix coordinate real general" - "HB" for HarwellBoeing format (http://math.nist.gov/MatrixMarket/formats.html#hb) - "MeTiS" for MeTiS format (http://people.sc.fsu.edu/~burkardt/data/metis_graph/metis_graph.html) - "GEN" for Generic Matrix format - "GENS" for Generic Square Matrix format */ int ReadBipartiteGraph(string s_InputFile, string s_fileFormat="AUTO_DETECTED"); /// Read a file with explicit 1 and 0 representing sparsity structure and build corresponding bipartite graph /** The format of the matrix is specified bellow (this file format .gen is NOT the same as the .gen2 files used by ReadGenericSquareMatrixBipartiteGraph() ): - A matrix is specified row by row, each row ending with and endofline. - In each row, a nonzero is indicated by 1 and a zero is indicated by 0. - The number of rows, columns or nonzeros is not given in the file, but the filename indicates the number of rows and columns. Format: -by.gen - There are empty spaces between consecutive matrix entries. Example: testmatrix-5by5.gen

1 1 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1
1 0 1 1 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 1 1 0 1 0
0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 1 1 0
0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 1
0 1 0 1 0 1 0 1 0 1
*/ int ReadGenericMatrixBipartiteGraph(string s_InputFile); /// Read a file with explicit 1 and 0 representing sparsity sturcture of a square matrix whose order is specified in the extension of the filename and build a Bipartite Graph /** The format of the matrix is specified bellow (this file format .gen2 is NOT the same as the .gen files used by ReadGenericMatrixBipartiteGraph() ): - The number of rows, columns or nonzeros is not given in the file, but the filename indicates the number of rows and columns. Format: -by.gens - NOTE: The number of rows should be equal to the number of columns. If the 2 numbers are different, take row = column = min of given row and column - The file contains a series of 0s and 1s with no space in between (endline should be ignore). - A nonzero is indicated by 1 and a zero is indicated by 0.. Example: testmatrix-12by10.gens (because the min is 10 => real size: 10x10)

11101010100101010101101110101001010101011010111010
01010101011010101110010101010110101010110101010101
*/ int ReadGenericSquareMatrixBipartiteGraph(string s_InputFile); /// Read sparsity pattern of a matrix specified in Harwell Boeing format from a file and build a corresponding bipartite graph /** Supported sub-format: MXTYPE[3] = (R | P) (*) (A) */ int ReadHarwellBoeingBipartiteGraph(string s_InputFile); /// Read sparsity pattern of a matrix specified in Matrix Market format from a file and build a corresponding bipartite graph int ReadMatrixMarketBipartiteGraph(string s_InputFile); /// Read sparsity pattern of a matrix specified in MeTiS format from a file and build a corresponding bipartite graph int ReadMeTiSBipartiteGraph(string s_InputFile); // -----OUTPUT FUNCTIONS----- void PrintBipartiteGraph(); void PrintVertexDegrees(); /// Given a bipartite graph representation, build the corresponding compressed sparse row representation /** Postcondition: - The Jacobian matrix is in compressed sparse rows format - (*uip3_JacobianSparsityPattern) size is (GetRowVertexCount()) rows x (GetColumnVertexCount()) columns Return value: - _TRUE upon successful */ int BipartiteGraph2RowCompressedFormat(unsigned int *** uip3_JacobianSparsityPattern, unsigned int * uip1_RowCount, unsigned int * uip1_ColumnCount); /// Write the structure of the bipartite graph into a file using Matrix Market format int WriteMatrixMarket(string s_OutputFile = "-ColPack_debug.mtx"); private: void CalculateVertexDegrees(); public: BipartiteGraphInputOutput(); ~BipartiteGraphInputOutput(); virtual void Clear(); }; } #endif ColPack-1.0.10/BipartiteGraphBicoloring/BipartiteGraphOrdering.cpp000066400000000000000000001377201266356121500251460ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Private Function 3401 int BipartiteGraphOrdering::CheckVertexOrdering(string s_VertexOrderingVariant) { if(m_s_VertexOrderingVariant.compare(s_VertexOrderingVariant) == 0) { return(_TRUE); } if(m_s_VertexOrderingVariant.compare("ALL") != 0) { m_s_VertexOrderingVariant = s_VertexOrderingVariant; } return(_FALSE); } //Public Constructor 3451 BipartiteGraphOrdering::BipartiteGraphOrdering() { Clear(); } //Public Destructor 3452 BipartiteGraphOrdering::~BipartiteGraphOrdering() { Clear(); } //Virtual Function 3453 void BipartiteGraphOrdering::Clear() { BipartiteGraphVertexCover::Clear(); m_d_OrderingTime = _UNKNOWN; m_s_VertexOrderingVariant.clear(); m_vi_OrderedVertices.clear(); return; } //Virtual Function 3454 void BipartiteGraphOrdering::Reset() { BipartiteGraphVertexCover::Reset(); m_d_OrderingTime = _UNKNOWN; m_s_VertexOrderingVariant.clear(); m_vi_OrderedVertices.clear(); return; } int BipartiteGraphOrdering::NaturalOrdering() { if(CheckVertexOrdering("NATURAL")) { return(_TRUE); } int i; int i_LeftVertexCount, i_RightVertexCount; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); m_vi_OrderedVertices.clear(); m_vi_OrderedVertices.reserve(i_LeftVertexCount + i_RightVertexCount); for(i=0; i tempOrdering; tempOrdering.resize((unsigned) i_RightVertexCount); for(unsigned int i = 0; i > vvi_GroupedVertexDegree; m_i_MaximumVertexDegree = _FALSE; i_HighestDegreeVertex = _UNKNOWN; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); vvi_GroupedVertexDegree.clear(); vvi_GroupedVertexDegree.resize((unsigned) i_LeftVertexCount + i_RightVertexCount); for(i=0; i=0; i--) { i_VertexDegreeCount = (signed) vvi_GroupedVertexDegree[i].size(); for(j=0; j=0; i--) { i_VertexDegreeCount = (signed) vvi_GroupedVertexDegree[i].size(); for(j=STEP_DOWN(i_VertexDegreeCount); j>=0; j--) { m_vi_OrderedVertices.push_back(vvi_GroupedVertexDegree[i][j]); } } } vvi_GroupedVertexDegree.clear(); return(_TRUE); } int BipartiteGraphOrdering::SmallestLastOrdering() { if(CheckVertexOrdering("SMALLEST_LAST")) { return(_TRUE); } int i, u, l, v; int _FOUND; int i_HighestInducedVertexDegree, i_HighestInducedDegreeVertex; int i_LeftVertexCount, i_RightVertexCount; int i_VertexCountMinus1; // = i_LeftVertexCount + i_RightVertexCount - 1, used when inserting selected vertices into m_vi_OrderedVertices int i_InducedVertexDegree; int i_InducedVertexDegreeCount; int i_SelectedVertex, i_SelectedVertexCount; vector vi_InducedVertexDegree; vector < vector < int > > vvi_GroupedInducedVertexDegree; vector < int > vi_VertexLocation; vector < int > vi_LeftSidedVertexinBucket; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_VertexCountMinus1 = i_LeftVertexCount + i_RightVertexCount - 1; vi_InducedVertexDegree.clear(); vi_InducedVertexDegree.reserve((unsigned) i_LeftVertexCount + i_RightVertexCount); vvi_GroupedInducedVertexDegree.clear(); vvi_GroupedInducedVertexDegree.resize((unsigned) i_LeftVertexCount + i_RightVertexCount); vi_VertexLocation.clear(); vi_VertexLocation.reserve((unsigned) i_LeftVertexCount + i_RightVertexCount); vi_LeftSidedVertexinBucket.clear(); vi_LeftSidedVertexinBucket.reserve((unsigned) i_LeftVertexCount + i_RightVertexCount); i_HighestInducedVertexDegree = _FALSE; i_HighestInducedDegreeVertex = _UNKNOWN; i_SelectedVertex = _UNKNOWN; for(i=0; i 0) { vi_LeftSidedVertexinBucket[i]--; i_SelectedVertex = vvi_GroupedInducedVertexDegree[i][vi_LeftSidedVertexinBucket[i]]; vvi_GroupedInducedVertexDegree[i][vi_LeftSidedVertexinBucket[i]] = vvi_GroupedInducedVertexDegree[i].back(); vi_VertexLocation[vvi_GroupedInducedVertexDegree[i].back()] = vi_VertexLocation[u]; _FOUND = _TRUE; } */ if(vi_LeftSidedVertexinBucket[i] > 0) for(int j = 0; j < vvi_GroupedInducedVertexDegree[i].size(); j++) { u = vvi_GroupedInducedVertexDegree[i][j]; if(u < i_LeftVertexCount) { i_SelectedVertex = u; if(vvi_GroupedInducedVertexDegree[i].size() > 1) { // swap this node with the last node vvi_GroupedInducedVertexDegree[i][j] = vvi_GroupedInducedVertexDegree[i].back(); vi_VertexLocation[vvi_GroupedInducedVertexDegree[i].back()] = vi_VertexLocation[u]; } _FOUND = _TRUE; vi_LeftSidedVertexinBucket[i]--; break; } } if(!_FOUND) i_SelectedVertex = vvi_GroupedInducedVertexDegree[i].back(); break; } else { _FOUND = _FALSE; if((i_InducedVertexDegreeCount - vi_LeftSidedVertexinBucket[i]) > 0) for(int j = 0; j < vvi_GroupedInducedVertexDegree[i].size(); j++) { u = vvi_GroupedInducedVertexDegree[i][j]; if(u >= i_LeftVertexCount) { i_SelectedVertex = u; if(vvi_GroupedInducedVertexDegree[i].size() > 1) { vvi_GroupedInducedVertexDegree[i][j] = vvi_GroupedInducedVertexDegree[i].back(); vi_VertexLocation[vvi_GroupedInducedVertexDegree[i].back()] = vi_VertexLocation[u]; } _FOUND = _TRUE; break; } } if(!_FOUND) { i_SelectedVertex = vvi_GroupedInducedVertexDegree[i].back(); vi_LeftSidedVertexinBucket[i]--; } } break; } vvi_GroupedInducedVertexDegree[i].pop_back(); // remove the selected vertex from the bucket if(i_SelectedVertex < i_LeftVertexCount) { for(i=m_vi_LeftVertices[i_SelectedVertex]; i 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].pop_back(); // reduce degree of u by 1 vi_InducedVertexDegree[u]--; // move u to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].push_back(u); // update vi_VertexLocation[u] since it has now been changed vi_VertexLocation[u] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].size() - 1; /* if(u < i_LeftVertexCount) { // swap this vertex and location v = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].size() - 1; if(v > 0) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][v]; swap(vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][vi_LeftSidedVertexinBucket[vi_InducedVertexDegree[u]]], vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][v]); swap(vi_VertexLocation[u], vi_VertexLocation[l]); } vi_LeftSidedVertexinBucket[vi_InducedVertexDegree[u]]++; }*/ } } else { for(i=m_vi_RightVertices[i_SelectedVertex - i_LeftVertexCount]; i 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].pop_back(); vi_LeftSidedVertexinBucket[vi_InducedVertexDegree[u]]--; // reduce degree of u by 1 vi_InducedVertexDegree[u]--; vi_LeftSidedVertexinBucket[vi_InducedVertexDegree[u]]++; // move u to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].push_back(u); // update vi_VertexLocation[u] since it has now been changed vi_VertexLocation[u] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].size() - 1; /* if(u < i_LeftVertexCount) { // swap this vertex and location v = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].size() - 1; if(v > 0) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][v]; swap(vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][vi_LeftSidedVertexinBucket[vi_InducedVertexDegree[u]]], vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][v]); swap(vi_VertexLocation[u], vi_VertexLocation[l]); } vi_LeftSidedVertexinBucket[vi_InducedVertexDegree[u]]++; }*/ } } vi_InducedVertexDegree[i_SelectedVertex] = _UNKNOWN; m_vi_OrderedVertices[i_VertexCountMinus1 - i_SelectedVertexCount] = i_SelectedVertex; i_SelectedVertexCount = STEP_UP(i_SelectedVertexCount); } vi_InducedVertexDegree.clear(); vvi_GroupedInducedVertexDegree.clear(); vi_VertexLocation.clear(); vi_LeftSidedVertexinBucket.clear(); return(_TRUE); } int BipartiteGraphOrdering::IncidenceDegreeOrdering() { if(CheckVertexOrdering("INCIDENCE_DEGREE")) { return(_TRUE); } int i, u, l; int i_HighestIncidenceVertexDegree; int i_LeftVertexCount, i_RightVertexCount, i_VertexCount; int i_VertexDegree; int i_IncidenceVertexDegree, i_IncidenceVertexDegreeCount; int i_SelectedVertex, i_SelectedVertexCount; vector vi_IncidenceVertexDegree; //Vertices of the same IncidenceDegree are differenciated into // LeftVertices (vpvi_GroupedIncidenceVertexDegree.first) and // RightVertices (vpvi_GroupedIncidenceVertexDegree.second) vector< pair, vector > > vpvi_GroupedIncidenceVertexDegree; vector< int > vi_VertexLocation; list::iterator lit_ListIterator; //??? i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_VertexCount = i_LeftVertexCount + i_RightVertexCount; vi_IncidenceVertexDegree.clear(); vi_IncidenceVertexDegree.reserve((unsigned) (i_VertexCount)); vpvi_GroupedIncidenceVertexDegree.clear(); vpvi_GroupedIncidenceVertexDegree.resize((unsigned) (i_VertexCount)); vi_VertexLocation.clear(); vi_VertexLocation.reserve((unsigned) (i_VertexCount)); i_HighestIncidenceVertexDegree = _UNKNOWN; i_IncidenceVertexDegree = _FALSE; i_SelectedVertex = _UNKNOWN; for(i=0; i 1) { l = vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].second.back(); vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].second[vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } //remove the last element from vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].second vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].second.pop_back(); // increase incidence degree of u vi_IncidenceVertexDegree[u]++; // insert u into appropriate bucket vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].second.push_back(u); // update location of u vi_VertexLocation[u] = vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].second.size() - 1; } } else { for(i=m_vi_RightVertices[i_SelectedVertex - i_LeftVertexCount]; i 1) { l = vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].first.back(); vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].first[vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } //remove the last element from vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].first vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].first.pop_back(); // increase incidence degree of u vi_IncidenceVertexDegree[u]++; // insert u into appropriate bucket vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].first.push_back(u); // update location of u vi_VertexLocation[u] = vpvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].first.size() - 1; } } // Mark that this vertex has been visited vi_IncidenceVertexDegree[i_SelectedVertex] = _UNKNOWN; m_vi_OrderedVertices.push_back(i_SelectedVertex); i_SelectedVertexCount = STEP_UP(i_SelectedVertexCount); } #if DEBUG == 3458 int i_OrderedVertexCount; cout< vi_InducedVertexDegree; vector< pair, vector > > vpvi_GroupedInducedVertexDegree; vector< int > vi_VertexLocation; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); i_VertexCount = i_LeftVertexCount + i_RightVertexCount; vi_InducedVertexDegree.clear(); vi_InducedVertexDegree.reserve((unsigned) i_VertexCount); vpvi_GroupedInducedVertexDegree.clear(); vpvi_GroupedInducedVertexDegree.resize((unsigned) i_VertexCount); vi_VertexLocation.clear(); vi_VertexLocation.reserve((unsigned) i_VertexCount); i_SelectedVertex = _UNKNOWN; for(i=0; i 1) { l = vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].second.back(); vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].second[vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } //remove the last element from vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].second vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].second.pop_back(); // increase incidence degree of u vi_InducedVertexDegree[u]--; // insert u into appropriate bucket vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].second.push_back(u); // update location of u vi_VertexLocation[u] = vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].second.size() - 1; } } else { for(i=m_vi_RightVertices[i_SelectedVertex - i_LeftVertexCount]; i 1) { l = vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].first.back(); vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].first[vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } //remove the last element from vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].first vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].first.pop_back(); // increase incidence degree of u vi_InducedVertexDegree[u]--; // insert u into appropriate bucket vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].first.push_back(u); // update location of u vi_VertexLocation[u] = vpvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].first.size() - 1; } } // Mark that this vertex has been visited vi_InducedVertexDegree[i_SelectedVertex] = _UNKNOWN; m_vi_OrderedVertices.push_back(i_SelectedVertex); i_SelectedVertexCount++; } #if DEBUG == 3462 int i_OrderedVertexCount; cout< > vvi_GroupedVertexDegree; m_i_MaximumVertexDegree = _FALSE; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); vvi_GroupedVertexDegree.clear(); vvi_GroupedVertexDegree.resize((unsigned) i_LeftVertexCount + i_RightVertexCount); for(i=0; i=0; i--) { i_VertexDegreeCount = (signed) vvi_GroupedVertexDegree[i].size(); for(j=0; j vi_InducedVertexDegree; vector< list > vli_GroupedInducedVertexDegree; vector< list::iterator > vlit_VertexLocation; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); vi_InducedVertexDegree.clear(); vi_InducedVertexDegree.resize((signed) i_LeftVertexCount + i_RightVertexCount, _UNKNOWN); vli_GroupedInducedVertexDegree.clear(); vli_GroupedInducedVertexDegree.resize((unsigned) i_LeftVertexCount + i_RightVertexCount); vlit_VertexLocation.clear(); vlit_VertexLocation.resize((unsigned) i_LeftVertexCount + i_RightVertexCount); i_IncludedVertexCount = _FALSE; i_HighestInducedVertexDegree = _FALSE; i_SelectedVertex = _UNKNOWN; for(i=0; i::iterator lit_ListIterator; cout< vi_IncidenceVertexDegree; vector< list > vli_GroupedIncidenceVertexDegree; vector< list::iterator > vlit_VertexLocation; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); vi_IncidenceVertexDegree.clear(); vi_IncidenceVertexDegree.resize((unsigned) i_LeftVertexCount + i_RightVertexCount, _UNKNOWN); vli_GroupedIncidenceVertexDegree.clear(); vli_GroupedIncidenceVertexDegree.resize((unsigned) i_LeftVertexCount + i_RightVertexCount); vlit_VertexLocation.clear(); vlit_VertexLocation.resize((unsigned) i_LeftVertexCount + i_RightVertexCount); i_SelectedVertex = _UNKNOWN; i_IncludedVertexCount = _FALSE; i_HighestDegreeVertex = m_i_MaximumVertexDegree = _UNKNOWN; for(i=0; i::iterator lit_ListIterator; cout<=0; i--) { cout<<"Degree "<=0; i--) { i_IncidenceVertexDegreeCount = (signed) vli_GroupedIncidenceVertexDegree[i].size(); if(i_IncidenceVertexDegreeCount != _FALSE) { i_SelectedVertex = vli_GroupedIncidenceVertexDegree[i].front(); break; } } } if(i_SelectedVertex < i_LeftVertexCount) { #if DEBUG == 3461 cout<<"DEBUG 3461 | Vertex Ordering | Incidence Degree | Selected Left Vertex | "< &output) { output = (m_vi_OrderedVertices); } int BipartiteGraphOrdering::OrderVertices(string s_OrderingVariant) { s_OrderingVariant = toUpper(s_OrderingVariant); if((s_OrderingVariant.compare("NATURAL") == 0)) { return(NaturalOrdering()); } else if((s_OrderingVariant.compare("LARGEST_FIRST") == 0)) { return(LargestFirstOrdering()); } else if((s_OrderingVariant.compare("DYNAMIC_LARGEST_FIRST") == 0)) { return(DynamicLargestFirstOrdering()); } else if((s_OrderingVariant.compare("SMALLEST_LAST") == 0)) { return(SmallestLastOrdering()); } else if((s_OrderingVariant.compare("INCIDENCE_DEGREE") == 0)) { return(IncidenceDegreeOrdering()); } else if((s_OrderingVariant.compare("RANDOM") == 0)) { return(RandomOrdering()); } else { cerr<. ************************************************************************************/ //using namespace std; #ifndef BIPARTITEGRAPHORDERING_H #define BIPARTITEGRAPHORDERING_H using namespace std; namespace ColPack { /** @ingroup group22 * @brief class BipartiteGraphOrdering in @link group22@endlink. The BipartiteGraphOrderingClass stores the ordered row and column vertices as a vector of vertex identifiers to be used by bipartite graph bicoloring methods. Since the row and column vertices use the same set of identifiers, number of row vertices is added the column vertex identifiers in the ordered vector. */ class BipartiteGraphOrdering : public BipartiteGraphVertexCover { public: int OrderVertices(string s_OrderingVariant); private: //Private Function 3401 int CheckVertexOrdering(string s_VertexOrderingVariant); protected: double m_d_OrderingTime; string m_s_VertexOrderingVariant; vector m_vi_OrderedVertices; public: BipartiteGraphOrdering(); ~BipartiteGraphOrdering(); virtual void Clear(); virtual void Reset(); int NaturalOrdering(); int RandomOrdering(); int LargestFirstOrdering(); int SmallestLastOrdering(); int IncidenceDegreeOrdering(); int DynamicLargestFirstOrdering(); int SelectiveLargestFirstOrdering(); int SelectiveSmallestLastOrdering(); int SelectiveIncidenceDegreeOrdering(); string GetVertexOrderingVariant(); void GetOrderedVertices(vector &output); void PrintVertexOrdering(); double GetVertexOrderingTime(); }; } #endif ColPack-1.0.10/BipartiteGraphBicoloring/BipartiteGraphVertexCover.cpp000066400000000000000000001651051266356121500256470ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Public Constructor 3351 BipartiteGraphVertexCover::BipartiteGraphVertexCover() { Clear(); } //Public Destructor 3352 BipartiteGraphVertexCover::~BipartiteGraphVertexCover() { Clear(); } //Virtual Function 3353 void BipartiteGraphVertexCover::Clear() { BipartiteGraphInputOutput::Clear(); m_d_CoveringTime = _UNKNOWN; m_vi_IncludedLeftVertices.clear(); m_vi_IncludedRightVertices.clear(); m_vi_CoveredLeftVertices.clear(); m_vi_CoveredRightVertices.clear(); return; } //Virtual Function 3354 void BipartiteGraphVertexCover::Reset() { m_d_CoveringTime = _UNKNOWN; m_vi_IncludedLeftVertices.clear(); m_vi_IncludedRightVertices.clear(); m_vi_CoveredLeftVertices.clear(); m_vi_CoveredRightVertices.clear(); return; } //Public Function 3355 int BipartiteGraphVertexCover::CoverVertex() { int i, j; int i_EdgeCount, i_CodeZeroEdgeCount; int i_CandidateLeftVertex, i_CandidateRightVertex; int i_LeftVertexCount, i_RightVertexCount; int i_PresentEdge, i_NeighboringEdge; int i_QuotientOne, i_QuotientTwo; int i_VertexDegree, i_CodeZeroDegreeVertexCount; int i_CodeZeroOneLeftVertexDegree, i_CodeZeroOneRightVertexDegree; int i_HighestCodeZeroLeftVertexDegree, i_LowestCodeZeroLeftVertexDegree; int i_HighestCodeZeroRightVertexDegree, i_LowestCodeZeroRightVertexDegree; int i_HighestCodeTwoLeftVertexDegree, i_HighestCodeThreeRightVertexDegree; vector vi_EdgeCodes; vector vi_LeftVertexDegree, vi_CodeZeroLeftVertexDegree, vi_CodeOneLeftVertexDegree, vi_CodeTwoLeftVertexDegree, vi_CodeThreeLeftVertexDegree; vector vi_RightVertexDegree, vi_CodeZeroRightVertexDegree, vi_CodeOneRightVertexDegree, vi_CodeTwoRightVertexDegree, vi_CodeThreeRightVertexDegree; vector< list > vli_GroupedCodeZeroLeftVertexDegree, vli_GroupedCodeZeroRightVertexDegree; vector< list::iterator > vlit_CodeZeroLeftVertexLocation, vlit_CodeZeroRightVertexLocation; list::iterator lit_ListIterator; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); m_vi_IncludedLeftVertices.clear(); m_vi_IncludedLeftVertices.resize((unsigned) i_LeftVertexCount, _TRUE); m_vi_IncludedRightVertices.clear(); m_vi_IncludedRightVertices.resize((unsigned) i_RightVertexCount, _TRUE); #if DEBUG == 3355 cout< i_VertexDegree) { i_LowestCodeZeroLeftVertexDegree = i_VertexDegree; } } vi_RightVertexDegree.clear(); vi_RightVertexDegree.resize((unsigned) i_RightVertexCount); vi_CodeZeroRightVertexDegree.clear(); vli_GroupedCodeZeroRightVertexDegree.clear(); vli_GroupedCodeZeroRightVertexDegree.resize((unsigned) STEP_UP(i_LeftVertexCount)); vlit_CodeZeroRightVertexLocation.clear(); i_HighestCodeZeroRightVertexDegree = _FALSE; i_LowestCodeZeroRightVertexDegree = i_RightVertexCount; for(i=0; i i_VertexDegree) { i_LowestCodeZeroRightVertexDegree = i_VertexDegree; } } vi_CodeOneLeftVertexDegree.clear(); vi_CodeOneLeftVertexDegree.resize((unsigned) i_LeftVertexCount, _FALSE); vi_CodeTwoLeftVertexDegree.clear(); vi_CodeTwoLeftVertexDegree.resize((unsigned) i_LeftVertexCount, _FALSE); vi_CodeThreeLeftVertexDegree.clear(); vi_CodeThreeLeftVertexDegree.resize((unsigned) i_LeftVertexCount, _FALSE); vi_CodeOneRightVertexDegree.clear(); vi_CodeOneRightVertexDegree.resize((unsigned) i_RightVertexCount, _FALSE); vi_CodeTwoRightVertexDegree.clear(); vi_CodeTwoRightVertexDegree.resize((unsigned) i_RightVertexCount, _FALSE); vi_CodeThreeRightVertexDegree.clear(); vi_CodeThreeRightVertexDegree.resize((unsigned) i_RightVertexCount, _FALSE); #if DEBUG == 3355 cout< vi_LeftVertexDegree[*lit_ListIterator]) { i_VertexDegree = vi_LeftVertexDegree[*lit_ListIterator]; i_CandidateLeftVertex = *lit_ListIterator; } } } break; } } for(i=0; i vi_RightVertexDegree[*lit_ListIterator]) { i_VertexDegree = vi_RightVertexDegree[*lit_ListIterator]; i_CandidateRightVertex = *lit_ListIterator; } } } break; } } #if DEBUG == 3355 cout< _UNKNOWN) { vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[i]]].erase(vlit_CodeZeroRightVertexLocation[m_vi_Edges[i]]); } vi_CodeZeroRightVertexDegree[m_vi_Edges[i]] = _UNKNOWN; } else { vi_CodeOneRightVertexDegree[m_vi_Edges[i]] = STEP_DOWN(vi_CodeOneRightVertexDegree[m_vi_Edges[i]]); } #if DEBUG == 3355 cout<<"Edge "< _UNKNOWN) { vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]]].erase(vlit_CodeZeroLeftVertexLocation[m_vi_Edges[j]]); } vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]] = STEP_DOWN(vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]]); if(vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]] > _UNKNOWN) { vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]]].push_front(m_vi_Edges[j]); vlit_CodeZeroLeftVertexLocation[m_vi_Edges[j]] = vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]]].begin(); } if(vi_CodeZeroRightVertexDegree[m_vi_Edges[i]] > _UNKNOWN) { vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[i]]].erase(vlit_CodeZeroRightVertexLocation[m_vi_Edges[i]]); } vi_CodeZeroRightVertexDegree[m_vi_Edges[i]] = STEP_DOWN(vi_CodeZeroRightVertexDegree[m_vi_Edges[i]]); if(vi_CodeZeroRightVertexDegree[m_vi_Edges[i]] > _UNKNOWN) { vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[i]]].push_front(m_vi_Edges[i]); vlit_CodeZeroRightVertexLocation[m_vi_Edges[i]] = vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[i]]].begin(); } #if DEBUG == 3355 cout<<"Edge "< _UNKNOWN) { vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]]].erase(vlit_CodeZeroLeftVertexLocation[m_vi_Edges[i]]); } vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]] = _UNKNOWN; } else { vi_CodeOneLeftVertexDegree[m_vi_Edges[i]] = STEP_DOWN(vi_CodeOneLeftVertexDegree[m_vi_Edges[i]]); } #if DEBUG == 3355 cout<<"Edge "< _UNKNOWN) { vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]]].erase(vlit_CodeZeroLeftVertexLocation[m_vi_Edges[i]]); } vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]] = STEP_DOWN(vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]]); if(vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]] > _UNKNOWN) { vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]]].push_front(m_vi_Edges[i]); vlit_CodeZeroLeftVertexLocation[m_vi_Edges[i]] = vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]]].begin(); } if(vi_CodeZeroRightVertexDegree[m_vi_Edges[j]] > _UNKNOWN) { vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[j]]].erase(vlit_CodeZeroRightVertexLocation[m_vi_Edges[j]]); } vi_CodeZeroRightVertexDegree[m_vi_Edges[j]] = STEP_DOWN(vi_CodeZeroRightVertexDegree[m_vi_Edges[j]]); if(vi_CodeZeroRightVertexDegree[m_vi_Edges[j]] > _UNKNOWN) { vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[j]]].push_front(m_vi_Edges[j]); vlit_CodeZeroRightVertexLocation[m_vi_Edges[j]] = vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[j]]].begin(); } #if DEBUG == 3355 cout<<"Edge "< & vi_EdgeCodes) { int i, j; int i_EdgeCount, i_CodeZeroEdgeCount; int i_CandidateLeftVertex, i_CandidateRightVertex; int i_LeftVertexCount, i_RightVertexCount; int i_PresentEdge, i_NeighboringEdge; int i_QuotientOne, i_QuotientTwo; int i_VertexDegree, i_CodeZeroDegreeVertexCount; int i_CodeZeroOneLeftVertexDegree, i_CodeZeroOneRightVertexDegree; int i_HighestCodeZeroLeftVertexDegree, i_LowestCodeZeroLeftVertexDegree; int i_HighestCodeZeroRightVertexDegree, i_LowestCodeZeroRightVertexDegree; int i_HighestCodeTwoLeftVertexDegree, i_HighestCodeThreeRightVertexDegree; vector vi_LeftVertexDegree, vi_CodeZeroLeftVertexDegree, vi_CodeOneLeftVertexDegree, vi_CodeTwoLeftVertexDegree, vi_CodeThreeLeftVertexDegree; vector vi_RightVertexDegree, vi_CodeZeroRightVertexDegree, vi_CodeOneRightVertexDegree, vi_CodeTwoRightVertexDegree, vi_CodeThreeRightVertexDegree; vector< list > vli_GroupedCodeZeroLeftVertexDegree, vli_GroupedCodeZeroRightVertexDegree; vector< list::iterator > vlit_CodeZeroLeftVertexLocation, vlit_CodeZeroRightVertexLocation; list::iterator lit_ListIterator; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); m_vi_IncludedLeftVertices.clear(); m_vi_IncludedLeftVertices.resize((unsigned) i_LeftVertexCount, _TRUE); m_vi_IncludedRightVertices.clear(); m_vi_IncludedRightVertices.resize((unsigned) i_RightVertexCount, _TRUE); #if DEBUG == 3356 cout< i_VertexDegree) { i_LowestCodeZeroLeftVertexDegree = i_VertexDegree; } } vi_RightVertexDegree.clear(); vi_RightVertexDegree.resize((unsigned) i_RightVertexCount); vi_CodeZeroRightVertexDegree.clear(); vli_GroupedCodeZeroRightVertexDegree.clear(); vli_GroupedCodeZeroRightVertexDegree.resize((unsigned) STEP_UP(i_LeftVertexCount)); vlit_CodeZeroRightVertexLocation.clear(); i_HighestCodeZeroRightVertexDegree = _FALSE; i_LowestCodeZeroRightVertexDegree = i_RightVertexCount; for(i=0; i i_VertexDegree) { i_LowestCodeZeroRightVertexDegree = i_VertexDegree; } } vi_CodeOneLeftVertexDegree.clear(); vi_CodeOneLeftVertexDegree.resize((unsigned) i_LeftVertexCount, _FALSE); vi_CodeTwoLeftVertexDegree.clear(); vi_CodeTwoLeftVertexDegree.resize((unsigned) i_LeftVertexCount, _FALSE); vi_CodeThreeLeftVertexDegree.clear(); vi_CodeThreeLeftVertexDegree.resize((unsigned) i_LeftVertexCount, _FALSE); vi_CodeOneRightVertexDegree.clear(); vi_CodeOneRightVertexDegree.resize((unsigned) i_RightVertexCount, _FALSE); vi_CodeTwoRightVertexDegree.clear(); vi_CodeTwoRightVertexDegree.resize((unsigned) i_RightVertexCount, _FALSE); vi_CodeThreeRightVertexDegree.clear(); vi_CodeThreeRightVertexDegree.resize((unsigned) i_RightVertexCount, _FALSE); #if DEBUG == 3356 cout< vi_LeftVertexDegree[*lit_ListIterator]) { i_VertexDegree = vi_LeftVertexDegree[*lit_ListIterator]; i_CandidateLeftVertex = *lit_ListIterator; } } } break; } } for(i=0; i vi_RightVertexDegree[*lit_ListIterator]) { i_VertexDegree = vi_RightVertexDegree[*lit_ListIterator]; i_CandidateRightVertex = *lit_ListIterator; } } } break; } } #if DEBUG == 3356 cout< _UNKNOWN) { vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[i]]].erase(vlit_CodeZeroRightVertexLocation[m_vi_Edges[i]]); } vi_CodeZeroRightVertexDegree[m_vi_Edges[i]] = _UNKNOWN; } else { vi_CodeOneRightVertexDegree[m_vi_Edges[i]] = STEP_DOWN(vi_CodeOneRightVertexDegree[m_vi_Edges[i]]); } #if DEBUG == 3356 cout<<"Edge "< _UNKNOWN) { vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]]].erase(vlit_CodeZeroLeftVertexLocation[m_vi_Edges[j]]); } vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]] = STEP_DOWN(vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]]); if(vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]] > _UNKNOWN) { vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]]].push_front(m_vi_Edges[j]); vlit_CodeZeroLeftVertexLocation[m_vi_Edges[j]] = vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[j]]].begin(); } if(vi_CodeZeroRightVertexDegree[m_vi_Edges[i]] > _UNKNOWN) { vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[i]]].erase(vlit_CodeZeroRightVertexLocation[m_vi_Edges[i]]); } vi_CodeZeroRightVertexDegree[m_vi_Edges[i]] = STEP_DOWN(vi_CodeZeroRightVertexDegree[m_vi_Edges[i]]); if(vi_CodeZeroRightVertexDegree[m_vi_Edges[i]] > _UNKNOWN) { vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[i]]].push_front(m_vi_Edges[i]); vlit_CodeZeroRightVertexLocation[m_vi_Edges[i]] = vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[i]]].begin(); } #if DEBUG == 3356 cout<<"Edge "< _UNKNOWN) { vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]]].erase(vlit_CodeZeroLeftVertexLocation[m_vi_Edges[i]]); } vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]] = _UNKNOWN; } else { vi_CodeOneLeftVertexDegree[m_vi_Edges[i]] = STEP_DOWN(vi_CodeOneLeftVertexDegree[m_vi_Edges[i]]); } #if DEBUG == 3356 cout<<"Edge "< _UNKNOWN) { vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]]].erase(vlit_CodeZeroLeftVertexLocation[m_vi_Edges[i]]); } vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]] = STEP_DOWN(vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]]); if(vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]] > _UNKNOWN) { vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]]].push_front(m_vi_Edges[i]); vlit_CodeZeroLeftVertexLocation[m_vi_Edges[i]] = vli_GroupedCodeZeroLeftVertexDegree[vi_CodeZeroLeftVertexDegree[m_vi_Edges[i]]].begin(); } if(vi_CodeZeroRightVertexDegree[m_vi_Edges[j]] > _UNKNOWN) { vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[j]]].erase(vlit_CodeZeroRightVertexLocation[m_vi_Edges[j]]); } vi_CodeZeroRightVertexDegree[m_vi_Edges[j]] = STEP_DOWN(vi_CodeZeroRightVertexDegree[m_vi_Edges[j]]); if(vi_CodeZeroRightVertexDegree[m_vi_Edges[j]] > _UNKNOWN) { vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[j]]].push_front(m_vi_Edges[j]); vlit_CodeZeroRightVertexLocation[m_vi_Edges[j]] = vli_GroupedCodeZeroRightVertexDegree[vi_CodeZeroRightVertexDegree[m_vi_Edges[j]]].begin(); } #if DEBUG == 3356 cout<<"Edge "< vi_AvailableVertices; vector vi_IndependentSet; vector vi_VertexDegree; vector< list > vli_GroupedVertexDegree; vector< list::iterator > vlit_VertexLocation; i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); vi_VertexDegree.clear(); vli_GroupedVertexDegree.clear(); vli_GroupedVertexDegree.resize(STEP_UP(i_LeftVertexCount + i_RightVertexCount)); vlit_VertexLocation.clear(); m_i_MaximumVertexDegree = _UNKNOWN; for(i=0; i &output) { output = (m_vi_IncludedLeftVertices); } //Public Function 3360 void BipartiteGraphVertexCover::GetIncludedRightVertices(vector &output) { output = (m_vi_IncludedRightVertices); } //Public Function 3361 void BipartiteGraphVertexCover::GetCoveredLeftVertices(vector &output) { output = (m_vi_CoveredLeftVertices); } //Public Function 3362 void BipartiteGraphVertexCover::GetCoveredRightVertices(vector &output) { output = (m_vi_CoveredRightVertices); } } ColPack-1.0.10/BipartiteGraphBicoloring/BipartiteGraphVertexCover.h000066400000000000000000000063211266356121500253060ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ using namespace std; #ifndef BIPARTITEGRAPHVERTEXCOVER_H #define BIPARTITEGRAPHVERTEXCOVER_H namespace ColPack { /** @ingroup group22 * @brief class BipartiteGraphVertexCover in @link group22@endlink. The bipartite graph bicoloring algorithms included in ColPack are variations of greedy, star and acyclic bicolorings combined with explicit and implicit vertex coverings and guided by pre-computed vertex orderings. The row and column vertices are initalized with two default colors, which are generally the color 0 for row vertices and for column vertices the color equal to one more than the sum of the numbers of row and column vertices. The vertices whose colors are subsequently changed by the algorithms constitute a vertex cover for the bipartite graph. The goal is to get the smallest vertex cover that can be colored to conform to the bicoloring constraints. The computation of vertex cover has given rise to two types of algorithms, in one of which a specialized vertex cover is computed explicitly for consumption by bicoloring algorithms and in the other implicitly within the bicoloring algorithms. The bipartite graph covering class provides methods for explicitly computing these specialized vertex covers. */ class BipartiteGraphVertexCover : public BipartiteGraphInputOutput { protected: double m_d_CoveringTime; vector m_vi_IncludedLeftVertices; vector m_vi_IncludedRightVertices; vector m_vi_CoveredLeftVertices; vector m_vi_CoveredRightVertices; public: //Public Constructor 3351 BipartiteGraphVertexCover(); //Public Destructor 3352 ~BipartiteGraphVertexCover(); //Virtual Function 3353 virtual void Clear(); //Virtual Function 3354 virtual void Reset(); //Public Function 3355 int CoverVertex(); //Public Function 3356 int CoverVertex(vector &); //Public Function 3357 int CoverMinimalVertex(); //Public Function 3358 void GetIncludedLeftVertices(vector &output); //Public Function 3359 void GetIncludedRightVertices(vector &output); //Public Function 3360 void GetCoveredLeftVertices(vector &output); //Public Function 3361 void GetCoveredRightVertices(vector &output); //Public Function 3362 void PrintBicoloringVertexCover(); }; } #endif ColPack-1.0.10/BipartiteGraphPartialColoring/000077500000000000000000000000001266356121500210335ustar00rootroot00000000000000ColPack-1.0.10/BipartiteGraphPartialColoring/.BipartiteGraphPartialOrdering.cpp.kate-swp000066400000000000000000000002701266356121500312620ustar00rootroot00000000000000Kate Swap File - Version 1.0SI^();W^I_#elseRbRa$'UbESWa$Ia$();Ib#elseR_U_R^EColPack-1.0.10/BipartiteGraphPartialColoring/BipartiteGraphPartialColoring.cpp000066400000000000000000001121151266356121500274570ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Private Function 2401 int BipartiteGraphPartialColoring::CalculateVertexColorClasses() { if(m_s_VertexColoringVariant.empty()) { return(_FALSE); } if(m_i_LeftVertexColorCount != _UNKNOWN) { int i_TotalLeftVertexColors = STEP_UP(m_i_LeftVertexColorCount); m_vi_LeftVertexColorFrequency.clear(); m_vi_LeftVertexColorFrequency.resize((unsigned) i_TotalLeftVertexColors, _FALSE); int i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); for(int i = 0; i < i_LeftVertexCount; i++) { m_vi_LeftVertexColorFrequency[m_vi_LeftVertexColors[i]]++; } for(int i = 0; i < i_TotalLeftVertexColors; i++) { if(m_i_LargestLeftVertexColorClassSize < m_vi_LeftVertexColorFrequency[i]) { m_i_LargestLeftVertexColorClass = i; m_i_LargestLeftVertexColorClassSize = m_vi_LeftVertexColorFrequency[i]; } if(m_i_SmallestLeftVertexColorClassSize == _UNKNOWN) { m_i_SmallestLeftVertexColorClass = i; m_i_SmallestLeftVertexColorClassSize = m_vi_LeftVertexColorFrequency[i]; } else if(m_i_SmallestLeftVertexColorClassSize > m_vi_LeftVertexColorFrequency[i]) { m_i_SmallestLeftVertexColorClass = i; m_i_SmallestLeftVertexColorClassSize = m_vi_LeftVertexColorFrequency[i]; } } m_d_AverageLeftVertexColorClassSize = i_LeftVertexCount / i_TotalLeftVertexColors; } if(m_i_RightVertexColorCount != _UNKNOWN) { int i_TotalRightVertexColors = STEP_UP(m_i_RightVertexColorCount); m_vi_RightVertexColorFrequency.clear(); m_vi_RightVertexColorFrequency.resize((unsigned) i_TotalRightVertexColors, _FALSE); int i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); for(int i = 0; i < i_RightVertexCount; i++) { m_vi_RightVertexColorFrequency[m_vi_RightVertexColors[i]]++; } for(int i = 0; i < i_TotalRightVertexColors; i++) { if(m_i_LargestRightVertexColorClassSize < m_vi_RightVertexColorFrequency[i]) { m_i_LargestRightVertexColorClass = i; m_i_LargestRightVertexColorClassSize = m_vi_RightVertexColorFrequency[i]; } if(m_i_SmallestRightVertexColorClassSize == _UNKNOWN) { m_i_SmallestRightVertexColorClass = i; m_i_SmallestRightVertexColorClassSize = m_vi_RightVertexColorFrequency[i]; } else if(m_i_SmallestRightVertexColorClassSize > m_vi_RightVertexColorFrequency[i]) { m_i_SmallestRightVertexColorClass = i; m_i_SmallestRightVertexColorClassSize = m_vi_RightVertexColorFrequency[i]; } } m_d_AverageRightVertexColorClassSize = i_RightVertexCount / i_TotalRightVertexColors; } return(_TRUE); } //Private Function 2402 int BipartiteGraphPartialColoring::CheckVertexColoring(string s_VertexColoringVariant) { if(m_s_VertexColoringVariant.compare(s_VertexColoringVariant) == 0) { return(_TRUE); } if(m_s_VertexColoringVariant.compare("ALL") != 0) { m_s_VertexColoringVariant = s_VertexColoringVariant; } if(m_s_VertexColoringVariant.compare("ROW_PARTIAL_DISTANCE_TWO") == 0) { if(m_s_VertexOrderingVariant.empty()) { RowNaturalOrdering(); } } else if(m_s_VertexColoringVariant.compare("COLUMN_PARTIAL_DISTANCE_TWO") == 0) { if(m_s_VertexOrderingVariant.empty()) { ColumnNaturalOrdering(); } } else { if(m_s_VertexOrderingVariant.empty()) { RowNaturalOrdering(); } } return(_FALSE); } //Public Constructor 2451 BipartiteGraphPartialColoring::BipartiteGraphPartialColoring() { Clear(); Seed_init(); } //Public Destructor 2452 BipartiteGraphPartialColoring::~BipartiteGraphPartialColoring() { Clear(); Seed_reset(); } void BipartiteGraphPartialColoring::Seed_init() { seed_available = false; i_seed_rowCount = 0; dp2_Seed = NULL; } void BipartiteGraphPartialColoring::Seed_reset() { if(seed_available) { seed_available = false; free_2DMatrix(dp2_Seed, i_seed_rowCount); dp2_Seed = NULL; i_seed_rowCount = 0; } } //Virtual Function 2453 void BipartiteGraphPartialColoring::Clear() { BipartiteGraphPartialOrdering::Clear(); m_i_LeftVertexColorCount = _UNKNOWN; m_i_RightVertexColorCount = _UNKNOWN; m_i_VertexColorCount = _UNKNOWN; m_i_ViolationCount =_UNKNOWN; m_i_ColoringUnits = _UNKNOWN; m_i_LargestLeftVertexColorClass = _UNKNOWN; m_i_LargestRightVertexColorClass = _UNKNOWN; m_i_LargestLeftVertexColorClassSize = _UNKNOWN; m_i_LargestRightVertexColorClassSize = _UNKNOWN; m_i_SmallestLeftVertexColorClass = _UNKNOWN; m_i_SmallestRightVertexColorClass = _UNKNOWN; m_i_SmallestLeftVertexColorClassSize = _UNKNOWN; m_i_SmallestRightVertexColorClassSize = _UNKNOWN; m_d_AverageLeftVertexColorClassSize = _UNKNOWN; m_d_AverageRightVertexColorClassSize = _UNKNOWN; m_d_ColoringTime = _UNKNOWN; m_d_CheckingTime = _UNKNOWN; m_s_VertexColoringVariant.clear(); m_vi_LeftVertexColors.clear(); m_vi_RightVertexColors.clear(); m_vi_LeftVertexColorFrequency.clear(); m_vi_RightVertexColorFrequency.clear(); return; } //Virtual Function 2454 void BipartiteGraphPartialColoring::Reset() { BipartiteGraphPartialOrdering::Reset(); m_i_LeftVertexColorCount = _UNKNOWN; m_i_RightVertexColorCount = _UNKNOWN; m_i_VertexColorCount = _UNKNOWN; m_i_ViolationCount = _UNKNOWN; m_i_ColoringUnits = _UNKNOWN; m_i_LargestLeftVertexColorClass = _UNKNOWN; m_i_LargestRightVertexColorClass = _UNKNOWN; m_i_LargestLeftVertexColorClassSize = _UNKNOWN; m_i_LargestRightVertexColorClassSize = _UNKNOWN; m_i_SmallestLeftVertexColorClass = _UNKNOWN; m_i_SmallestRightVertexColorClass = _UNKNOWN; m_i_SmallestLeftVertexColorClassSize = _UNKNOWN; m_i_SmallestRightVertexColorClassSize = _UNKNOWN; m_d_AverageLeftVertexColorClassSize = _UNKNOWN; m_d_AverageRightVertexColorClassSize = _UNKNOWN; m_d_ColoringTime = _UNKNOWN; m_d_CheckingTime = _UNKNOWN; m_s_VertexColoringVariant.clear(); m_vi_LeftVertexColors.clear(); m_vi_RightVertexColors.clear(); m_vi_LeftVertexColorFrequency.clear(); m_vi_RightVertexColorFrequency.clear(); return; } int f(int x) {return x;} int BipartiteGraphPartialColoring::PartialDistanceTwoRowColoring_OMP() { if(CheckVertexColoring("ROW_PARTIAL_DISTANCE_TWO")) { return(_TRUE); } int i_LeftVertexCount, i_RightVertexCount, i_CurrentVertex; bool cont=false; vector vi_forbiddenColors, vi_VerticesToBeColored, vi_verticesNeedNewColor; i_LeftVertexCount = (int) m_vi_LeftVertices.size() - 1; i_RightVertexCount = (int)m_vi_RightVertices.size () - 1; m_i_LeftVertexColorCount = m_i_RightVertexColorCount = m_i_VertexColorCount = 0; // !!! do sections for this part ? forbiddenColors may need to be private for each thread // resize the colors m_vi_LeftVertexColors.resize ( i_LeftVertexCount, _UNKNOWN ); // resize the forbidden colors. !!! should be resize to max D2 degree instead vi_forbiddenColors.resize ( i_LeftVertexCount, _UNKNOWN ); //Algo 4 - Line 2: U <- V . U is vi_VerticesToBeColored vi_VerticesToBeColored.reserve(i_LeftVertexCount); for(int i=0; i=m_vi_Edges.size()"< vi_forbiddenColors; i_LeftVertexCount = (int)m_vi_LeftVertices.size () - 1; // resize the colors m_vi_LeftVertexColors.resize ( i_LeftVertexCount, _UNKNOWN ); // resize the forbidden colors vi_forbiddenColors.resize ( i_LeftVertexCount, _UNKNOWN ); m_i_LeftVertexColorCount = m_i_RightVertexColorCount = m_i_VertexColorCount = 0; for ( i=0; i0:forbiddenColors[c]=/=vi for ( c=0; c vi_forbiddenColors, vi_VerticesToBeColored, vi_verticesNeedNewColor; i_LeftVertexCount = (int) m_vi_LeftVertices.size() - 1; i_RightVertexCount = (int)m_vi_RightVertices.size () - 1; m_i_LeftVertexColorCount = m_i_RightVertexColorCount = m_i_VertexColorCount = 0; // !!! do sections for this part ? forbiddenColors may need to be private for each thread // resize the colors m_vi_RightVertexColors.resize ( i_RightVertexCount, _UNKNOWN ); // resize the forbidden colors. !!! should be resize to max D2 degree instead vi_forbiddenColors.resize ( i_RightVertexCount, _UNKNOWN ); //Algo 4 - Line 2: U <- V . U is vi_VerticesToBeColored vi_VerticesToBeColored.reserve(i_RightVertexCount); for(int i=0; i vi_forbiddenColors; i_LeftVertexCount = (int) m_vi_LeftVertices.size() - 1; i_RightVertexCount = (int)m_vi_RightVertices.size () - 1; // resize the colors m_vi_RightVertexColors.resize ( i_RightVertexCount, _UNKNOWN ); // resize the forbidden colors vi_forbiddenColors.resize ( i_RightVertexCount, _UNKNOWN ); m_i_LeftVertexColorCount = m_i_RightVertexColorCount = m_i_VertexColorCount = 0; //cout<<" i_RightVertexCount = " <0:forbiddenColors[c]=/=vi for ( c=0; c &output) { output = (m_vi_LeftVertexColors); } //Public Function 2464 void BipartiteGraphPartialColoring::GetRightVertexColors(vector &output) { output = (m_vi_RightVertexColors); } //Public Function 2465 void BipartiteGraphPartialColoring::PrintRowPartialColors() { int i; int i_LeftVertexCount; string _SLASH("/"); StringTokenizer SlashTokenizer(m_s_InputFile, _SLASH); m_s_InputFile = SlashTokenizer.GetLastToken(); i_LeftVertexCount = (signed) m_vi_LeftVertexColors.size(); cout<=i_num_of_colors) { // cout<<"i="< &output) { if ( m_s_VertexColoringVariant == "COLUMN_PARTIAL_DISTANCE_TWO") { GetRightVertexColors(output); } else if (m_s_VertexColoringVariant == "ROW_PARTIAL_DISTANCE_TWO") { GetLeftVertexColors(output); } else { // Unrecognized Coloring Method cerr<<" Unknown Partial Distance Two Coloring Method: "<. ************************************************************************************/ using namespace std; #ifndef BIPARTITEGRAPHPARTIALCOLORING_H #define BIPARTITEGRAPHPARTIALCOLORING_H namespace ColPack { /** @ingroup group21 * @brief class BipartiteGraphPartialColoring in @link group21@endlink. To be completed. */ class BipartiteGraphPartialColoring : public BipartiteGraphPartialOrdering { public: //DOCUMENTED /// Based on m_s_VertexColoringVariant, either PrintRowPartialColors() or PrintColumnPartialColors() will be called. void PrintPartialColors(); /// Based on m_s_VertexColoringVariant, either PrintRowPartialColoringMetrics() or PrintColumnPartialColoringMetrics() will be called. void PrintPartialColoringMetrics(); /// Based on m_s_VertexColoringVariant, either PrintRowPartialColoringMetrics() or PrintColumnPartialColoringMetrics() will be called. int CheckPartialDistanceTwoColoring(); /// Based on m_s_VertexColoringVariant, either GetLeftVertexColors() or GetRightVertexColors() will be called. void GetVertexPartialColors(vector &output); /// Based on m_s_VertexColoringVariant, either GetLeftSeedMatrix() or GetRightSeedMatrix() will be called. double** GetSeedMatrix(int* i_SeedRowCount, int* i_SeedColumnCount); /// Based on m_s_VertexColoringVariant, either GetLeftSeedMatrix_unmanaged() or GetRightSeedMatrix_unmanaged() will be called. double** GetSeedMatrix_unmanaged(int* i_SeedRowCount, int* i_SeedColumnCount); ///Generate and return the Left Seed matrix. This Seed matrix is managed and freed by ColPack /**Precondition: - the Graph has been colored by PartialDistanceTwoRowColoring() Postcondition: - Size of the returned matrix is (*i_SeedRowCount) rows x (*i_SeedColumnCount) columns. (*i_SeedColumnCount) == num of rows of the original matrix == GetRowVertexCount() (*i_SeedRowCount) == num of colors used to color the left (row) vertices == GetVertexColorCount(). Notes: - This Seed matrix is managed and automatically freed by ColPack when the Graph object is deleted. Therefore, the user should NOT attempt to free the Seed matrix again. */ double** GetLeftSeedMatrix(int* i_SeedRowCount, int* i_SeedColumnCount); /// Same as GetLeftSeedMatrix(), except that this Seed matrix is NOT managed by ColPack /** Notes: - This Seed matrix is NOT managed by ColPack. Therefore, the user should free the Seed matrix manually when the matrix is no longer needed. */ double** GetLeftSeedMatrix_unmanaged(int* i_SeedRowCount, int* i_SeedColumnCount); /// Return the Right Seed matrix. This Seed matrix is managed and freed by ColPack /** Precondition: - the Graph has been colored by PartialDistanceTwoColumnColoring() Postcondition: - Size of the returned matrix is (*i_SeedRowCount) rows x (*i_SeedColumnCount) columns. (*i_SeedRowCount) == num of columns of the original matrix == GetColumnVertexCount() (*i_SeedColumnCount) == num of colors used to color the right (column) vertices == GetVertexColorCount(). Notes: - This Seed matrix is managed and automatically freed by ColPack when the Graph object is deleted. Therefore, the user should NOT attempt to free the Seed matrix again. */ double** GetRightSeedMatrix(int* i_SeedRowCount, int* i_SeedColumnCount); /// Same as GetRightSeedMatrix(), except that this Seed matrix is NOT managed by ColPack /** Notes: - This Seed matrix is NOT managed by ColPack. Therefore, the user should free the Seed matrix manually when the matrix is no longer needed. */ double** GetRightSeedMatrix_unmanaged(int* i_SeedRowCount, int* i_SeedColumnCount); private: //Private Function 2401 int CalculateVertexColorClasses(); //Private Function 2402 int CheckVertexColoring(string s_VertexColoringVariant); protected: int m_i_LeftVertexColorCount; int m_i_RightVertexColorCount; int m_i_VertexColorCount; int m_i_ViolationCount; int m_i_ColoringUnits; int m_i_LargestLeftVertexColorClass; int m_i_LargestRightVertexColorClass; int m_i_LargestLeftVertexColorClassSize; int m_i_LargestRightVertexColorClassSize; int m_i_SmallestLeftVertexColorClass; int m_i_SmallestRightVertexColorClass; int m_i_SmallestLeftVertexColorClassSize; int m_i_SmallestRightVertexColorClassSize; double m_d_AverageLeftVertexColorClassSize; double m_d_AverageRightVertexColorClassSize; double m_d_ColoringTime; double m_d_CheckingTime; string m_s_VertexColoringVariant; vector m_vi_LeftVertexColors; vector m_vi_RightVertexColors; vector m_vi_LeftVertexColorFrequency; vector m_vi_RightVertexColorFrequency; bool seed_available; int i_seed_rowCount; double** dp2_Seed; void Seed_init(); void Seed_reset(); public: //Public Constructor 2451 BipartiteGraphPartialColoring(); //Public Destructor 2452 ~BipartiteGraphPartialColoring(); //Virtual Function 2453 virtual void Clear(); //Virtual Function 2454 virtual void Reset(); //Public Function 2455 int PartialDistanceTwoRowColoring(); int PartialDistanceTwoRowColoring_serial(); int PartialDistanceTwoRowColoring_OMP(); //Public Function 2456 int PartialDistanceTwoColumnColoring(); int PartialDistanceTwoColumnColoring_serial(); int PartialDistanceTwoColumnColoring_OMP(); //Public Function 2457 int CheckPartialDistanceTwoRowColoring(); //Public Function 2458 int CheckPartialDistanceTwoColumnColoring(); //Public Function 2459 int GetLeftVertexColorCount(); //Public Function 2460 int GetRightVertexColorCount(); //Public Function 2461 int GetVertexColorCount(); //Public Function 2462 string GetVertexColoringVariant(); //Public Function 2463 void GetLeftVertexColors(vector &output); //Public Function 2464 void GetRightVertexColors(vector &output); //Public Function 2465 void PrintRowPartialColors(); //Public Function 2466 void PrintColumnPartialColors(); //Public Function 2467 void PrintRowPartialColoringMetrics(); //Public Function 2468 void PrintColumnPartialColoringMetrics(); //Public Function 2469 void PrintVertexPartialColorClasses(); double GetVertexColoringTime(); void SetVertexColoringVariant(string s_VertexColoringVariant); }; } #endif ColPack-1.0.10/BipartiteGraphPartialColoring/BipartiteGraphPartialColoringInterface.cpp000066400000000000000000000174411266356121500313060ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Public Destructor 2602 BipartiteGraphPartialColoringInterface::~BipartiteGraphPartialColoringInterface() { BipartiteGraphPartialColoring::Clear(); Seed_reset(); } //Public Function 2603 void BipartiteGraphPartialColoringInterface::Clear() { BipartiteGraphPartialColoring::Clear(); return; } //Public Function 2604 void BipartiteGraphPartialColoringInterface::Reset() { BipartiteGraphPartialColoring::Reset(); return; } void BipartiteGraphPartialColoringInterface::GenerateSeedJacobian(double*** dp3_seed, int *ip1_SeedRowCount, int *ip1_SeedColumnCount, string s_OrderingVariant, string s_ColoringVariant) { //void BipartiteGraphPartialColoringInterface::GenerateSeedJacobian(unsigned int ** uip2_JacobianSparsityPattern, int i_RowCount, int i_ColumnCount, double*** dp3_seed, int *ip1_SeedRowCount, int *ip1_SeedColumnCount, string s_OrderingVariant, string s_ColoringVariant) { //Clear (Re-initialize) the bipartite graph //Clear(); //Read the sparsity pattern of the given Jacobian matrix (compressed sparse rows format) //and create the corresponding bipartite graph //BuildBPGraphFromRowCompressedFormat(uip2_JacobianSparsityPattern, i_RowCount, i_ColumnCount); //Do Partial-Distance-Two-Coloring the bipartite graph with the specified ordering PartialDistanceTwoColoring(s_OrderingVariant, s_ColoringVariant); //Create the seed matrix from the coloring information (*dp3_seed) = GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); } void BipartiteGraphPartialColoringInterface::GenerateSeedJacobian_unmanaged(double*** dp3_seed, int *ip1_SeedRowCount, int *ip1_SeedColumnCount, string s_OrderingVariant, string s_ColoringVariant) { //Do Partial-Distance-Two-Coloring the bipartite graph with the specified ordering PartialDistanceTwoColoring(s_OrderingVariant, s_ColoringVariant); //Create the seed matrix from the coloring information (*dp3_seed) = GetSeedMatrix_unmanaged(ip1_SeedRowCount, ip1_SeedColumnCount); } int BipartiteGraphPartialColoringInterface::PartialDistanceTwoColoring(string s_OrderingVariant, string s_ColoringVariant) { m_T_Timer.Start(); int i_OrderingStatus = OrderVertices(s_OrderingVariant, s_ColoringVariant); m_T_Timer.Stop(); m_d_OrderingTime = m_T_Timer.GetWallTime(); if(i_OrderingStatus != _TRUE) { cerr< > * lsi_SparsityPattern = va_arg(ap,std::list > *); int i_ColumnCount = va_arg(ap,int); BuildBPGraphFromADICFormat(lsi_SparsityPattern, i_ColumnCount); } else if (i_type == SRC_MEM_SSF || i_type == SRC_MEM_CSR) { int* ip_RowIndex = va_arg(ap,int*); int i_RowCount = va_arg(ap,int); int i_ColumnCount = va_arg(ap,int); int* ip_ColumnIndex = va_arg(ap,int*); BuildBPGraphFromCSRFormat(ip_RowIndex, i_RowCount, i_ColumnCount, ip_ColumnIndex); } else if (i_type == SRC_FILE) { // get string s_InputFile, string s_fileFormat string s_InputFile ( va_arg(ap,char *) ); string s_fileFormat ( va_arg(ap,char *) ); ReadBipartiteGraph(s_InputFile, s_fileFormat); } else { cerr<<"ERR: BipartiteGraphBicoloringInterface(): i_type =\""<< i_type <<"\" unknown or unspecified"< &output) { BipartiteGraphPartialOrdering::GetOrderedVertices(output); } double** BipartiteGraphPartialColoringInterface::GetSeedMatrix(int* ip1_SeedRowCount, int* ip1_SeedColumnCount) { return BipartiteGraphPartialColoring::GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); } } ColPack-1.0.10/BipartiteGraphPartialColoring/BipartiteGraphPartialColoringInterface.h000066400000000000000000000216671266356121500307600ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ using namespace std; #ifndef BIPARTITEGRAPHPARTIALCOLORINGINTERFACE_H #define BIPARTITEGRAPHPARTIALCOLORINGINTERFACE_H namespace ColPack { /** @ingroup group21 * @brief class BipartiteGraphPartialColoringInterface in @link group21@endlink. To be completed. Note that for each object, only one type of Coloring (either Row or Column) should be used. The reason is because both of RowColoring and ColumnColoring will update (share) the value of m_i_VertexColorCount. If RowColoring is run and then ColumnColoring is run, both PrintColumnPartialColoringMetrics() and PrintRowPartialColoringMetrics() will display the result of the later run (ColumnColoring) only. */ class BipartiteGraphPartialColoringInterface : public BipartiteGraphPartialColoring { public: //DOCUMENTED /// Build a BipartiteGraphPartialColoringInterface object and create the bipartite graph based on the graph structure specified by the input source /** This function will: - 0. Create initial BipartiteGraphPartialColoringInterface object - 1. Create the bipartite graph based on the graph structure specified by the input source Structure of this variadic function's parameters: BipartiteGraphPartialColoringInterface(int i_type, [2 or more parameters for input source depending on the value of i_type]). Here are some examples: - Just create the BipartiteGraphPartialColoringInterface object: BipartiteGraphPartialColoringInterface(SRC_WAIT); - Get the input from file: BipartiteGraphPartialColoringInterface(SRC_FILE, s_InputFile.c_str() ,"AUTO_DETECTED"); - Get input from ADOLC: BipartiteGraphPartialColoringInterface(SRC_MEM_ADOLC,uip2_SparsityPattern, i_rowCount, i_columnCount); About input parameters: - int i_type: specified the input source. i_type can be either: - -1 (SRC_WAIT): only step 0 will be done. - 0 (SRC_FILE): The graph structure will be read from file. The next 2 parameters are: - fileName: name of the input file. If the full path is not given, the file is assumed to be in the current directory - fileType can be either: - "AUTO_DETECTED" or "". ColPack will decide the format of the file based on the file extension: - ".mtx": MatrixMarket format - ".hb", or any combination of ".": HarwellBoeing format - ".graph": MeTiS format - ".gen": Generic Matrix format - ".gens": Generic Square Matrix format - If the above extensions are not found, MatrixMarket format will be assumed. - "MM" for MatrixMarket format (http://math.nist.gov/MatrixMarket/formats.html#MMformat). Notes: - ColPack only accepts MatrixMarket coordinate format (NO array format) - List of arithmetic fields accepted by ColPack: real, pattern or integer - List of symmetry structures accepted by ColPack: general or symmetric - The first line of the input file should be similar to this: "%%MatrixMarket matrix coordinate real general" - "HB" for HarwellBoeing format (http://math.nist.gov/MatrixMarket/formats.html#hb) - "MeTiS" for MeTiS format (http://people.sc.fsu.edu/~burkardt/data/metis_graph/metis_graph.html) - "GEN" for Generic Matrix format - "GENS" for Generic Square Matrix format - 1 (SRC_MEM_ADOLC): The graph structure will be read from Row Compressed Structure (used by ADOLC). The next 3 parameters are: - unsigned int **uip2_SparsityPattern: The pattern of Jacobian matrix stored in Row Compressed Format - int i_rowCount: number of rows in the Jacobian matrix. Number of rows in uip2_SparsityPattern. - int i_ColumnCount: number of columns in the Jacobian matrix. Number of columns in uip2_SparsityPattern. - 2 (SRC_MEM_ADIC): The graph structure will be read from the sparsity structure generated by ADIC. The next 2 parameters are: - std::list >* lsi_SparsityPattern: The pattern of Jacobian matrix. This structure has a list of rows and the positions of the nonzeros in a row is hold in a set. - int i_ColumnCount: number of columns in the Jacobian matrix. - 3 (SRC_MEM_SSF) or 4 (SRC_MEM_CSR): The graph structure will be read from zero-based indexing, 3-array variation CSR format http://software.intel.com/sites/products/documentation/hpc/mkl/webhelp/appendices/mkl_appA_SMSF.html#table_79228E147DA0413086BEFF4EFA0D3F04 The next 3 parameters are: - int* ip_RowIndex: Element j of the array gives the index of the element in the ip_ColumnIndex array that is first non-zero element in a row j. Size of vector (*ip_RowIndex) = i_rowCount + 1. - int i_RowCount: number of rows in the Jacobian matrix. - int i_ColumnCount: number of columns in the Jacobian matrix. - int* ip_ColumnIndex: Element I of the array is the number of the column that contains the I-th non-zero element in the matrix. Size of vector (*ip_ColumnIndex) = ip_RowIndex[i_rowCount] //*/ BipartiteGraphPartialColoringInterface(int i_type, ...); /// (Partial-Distance-Two) Color the bipartite graph based on the requested s_ColoringVariant and s_OrderingVariant /** This function will - 1. Order the vertices based on the requested Ordering variant (s_OrderingVariant) - 2. Bicolor the graph based on the requested Coloring variant (s_ColoringVariant) - Ordering Time and Coloring Time will be recorded. About input parameters: - s_OrderingVariant can be either - "NATURAL" (default) - "LARGEST_FIRST" - "SMALLEST_LAST" - "INCIDENCE_DEGREE" - "RANDOM" - s_ColoringVariant can be either - "COLUMN_PARTIAL_DISTANCE_TWO" (default) - "ROW_PARTIAL_DISTANCE_TWO" Postcondition: - The Bipartite Graph is (Partial-Distance-Two) colored, i.e., either m_vi_LeftVertexColors or m_vi_RightVertexColors will be populated. */ int PartialDistanceTwoColoring(string s_OrderingVariant = "NATURAL", string s_ColoringVariant = "COLUMN_PARTIAL_DISTANCE_TWO"); /// Generate and return the seed matrix (OpenMP enabled) /** This function will - 1. Color the graph by (Row or Column)-Partial-Distance-2-Coloring with the specified ordering - 2. Create and return the seed matrix (*dp3_seed) from the coloring information About input parameters: - s_ColoringVariant: - if == "COLUMN_PARTIAL_DISTANCE_TWO" (default), PartialDistanceTwoColumnColoring() will be used and the right seed matrix will be return - if == "ROW_PARTIAL_DISTANCE_TWO", PartialDistanceTwoRowColoring() will be used and the left seed matrix will be return - s_OrderingVariant can be either - "NATURAL" (default) - "LARGEST_FIRST" - "SMALLEST_LAST" - "INCIDENCE_DEGREE" - "RANDOM" Postcondition: - *dp3_seed: the size will be [*ip1_SeedRowCount] [*ip1_SeedColumnCount] - if (s_ColoringVariant == "COLUMN_PARTIAL_DISTANCE_TWO"): [num of columns of the original matrix == i_ColumnCount] [ColorCount] - if (s_ColoringVariant == "ROW_PARTIAL_DISTANCE_TWO"): [ColorCount] [num of rows of the original matrix == i_RowCount] */ void GenerateSeedJacobian(double*** dp3_seed, int *ip1_SeedRowCount, int *ip1_SeedColumnCount, string s_OrderingVariant="NATURAL", string s_ColoringVariant = "COLUMN_PARTIAL_DISTANCE_TWO"); /// Same as GenerateSeedJacobian(), except that this Seed matrix is NOT managed by ColPack (OpenMP enabled) /** Notes: - This Seed matrix is NOT managed by ColPack. Therefore, the user should free the Seed matrix manually when the matrix is no longer needed. */ void GenerateSeedJacobian_unmanaged(double*** dp3_seed, int *ip1_SeedRowCount, int *ip1_SeedColumnCount, string s_OrderingVariant="NATURAL", string s_ColoringVariant = "COLUMN_PARTIAL_DISTANCE_TWO"); /// Based on m_s_VertexColoringVariant, either GetLeftSeedMatrix() or GetRightSeedMatrix() will be called. double** GetSeedMatrix(int* ip1_SeedRowCount, int* ip1_SeedColumnCount); void GetOrderedVertices(vector &output); private: Timer m_T_Timer; public: //Public Destructor 2602 ~BipartiteGraphPartialColoringInterface(); //Public Function 2603 void Clear(); //Public Function 2604 void Reset(); }; } #endif ColPack-1.0.10/BipartiteGraphPartialColoring/BipartiteGraphPartialOrdering.cpp000066400000000000000000001752011266356121500274610ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Private Function 2301 int BipartiteGraphPartialOrdering::CheckVertexOrdering(string s_VertexOrderingVariant) { if(m_s_VertexOrderingVariant.compare(s_VertexOrderingVariant) == 0) { return(_TRUE); } if(m_s_VertexOrderingVariant.compare("ALL") != 0) { m_s_VertexOrderingVariant = s_VertexOrderingVariant; } return(_FALSE); } //Public Constructor 2351 BipartiteGraphPartialOrdering::BipartiteGraphPartialOrdering() { Clear(); } //Public Destructor 2352 BipartiteGraphPartialOrdering::~BipartiteGraphPartialOrdering() { Clear(); } //Virtual Function 2353 void BipartiteGraphPartialOrdering::Clear() { BipartiteGraphInputOutput::Clear(); m_d_OrderingTime = _UNKNOWN; m_s_VertexOrderingVariant.clear(); m_vi_OrderedVertices.clear(); return; } //Virtual Function 2354 void BipartiteGraphPartialOrdering::Reset() { m_d_OrderingTime = _UNKNOWN; m_s_VertexOrderingVariant.clear(); m_vi_OrderedVertices.clear(); return; } //Public Function 2355 int BipartiteGraphPartialOrdering::RowNaturalOrdering() { if(CheckVertexOrdering("ROW_NATURAL")) { return(_TRUE); } int i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); m_vi_OrderedVertices.clear(); m_vi_OrderedVertices.reserve((unsigned) i_LeftVertexCount); for(int i = 0; i vi_Visited; vector< vector > vvi_GroupedVertexDegree; i_VertexCount = (int)m_vi_LeftVertices.size () - 1; m_i_MaximumVertexDegree = 0; m_i_MinimumVertexDegree = i_VertexCount; vvi_GroupedVertexDegree.resize ( i_VertexCount ); vi_Visited.resize ( i_VertexCount, _UNKNOWN ); // enter code here for ( i=0; i i_DegreeCount) { m_i_MinimumVertexDegree = i_DegreeCount; } } if(i_VertexCount <2) m_i_MinimumVertexDegree = i_DegreeCount; // clear the vertexorder m_vi_OrderedVertices.clear (); // take the bucket and place it in the vertexorder for ( i=m_i_MaximumVertexDegree; i>=m_i_MinimumVertexDegree; --i ) { // j = size of the bucket // get the size of the i-th bucket j = (int)vvi_GroupedVertexDegree [i].size (); // place it into vertex ordering for ( k=0; k vi_Visited; vector< vector > vvi_GroupedVertexDegree; i_VertexCount = (int)m_vi_RightVertices.size () - 1; m_i_MaximumVertexDegree = 0; m_i_MinimumVertexDegree = i_VertexCount; vvi_GroupedVertexDegree.resize ( i_VertexCount ); vi_Visited.resize ( i_VertexCount, _UNKNOWN ); int i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); // enter code here for ( i=0; i i_DegreeCount) { m_i_MinimumVertexDegree = i_DegreeCount; } } if(i_VertexCount <2) m_i_MinimumVertexDegree = i_DegreeCount; // clear the vertexorder m_vi_OrderedVertices.clear (); // take the bucket and place it in the vertexorder for ( i=m_i_MaximumVertexDegree; i>=m_i_MinimumVertexDegree; --i ) { // j = size of the bucket // get the size of the i-th bucket j = (int)vvi_GroupedVertexDegree [i].size (); // place it into vertex ordering for ( k=0; k vi_Visited; vi_Visited.clear(); vi_Visited.resize ( i_LeftVertexCount, _UNKNOWN ); m_vi_OrderedVertices.clear(); vector d; // current distance-2 degree of each Left vertex d.resize(i_LeftVertexCount, _UNKNOWN); vector VertexThreadGroup; VertexThreadGroup.resize(i_LeftVertexCount, _UNKNOWN); int i_MaxNumThreads; #ifdef _OPENMP i_MaxNumThreads = omp_get_max_threads(); #else i_MaxNumThreads = 1; #endif int i_MaxDegree = 0; int* i_MaxDegree_Private = new int[i_MaxNumThreads]; int* i_MinDegree_Private = new int[i_MaxNumThreads]; // ??? is this really neccessary ? => #pragma omp parallel for default(none) schedule(static) shared() for(int i=0; i < i_MaxNumThreads; i++) { i_MaxDegree_Private[i] = 0; i_MinDegree_Private[i] = i_LeftVertexCount; } int* delta = new int[i_MaxNumThreads]; vector** B; //private buckets. Each thread i will have their own buckets B[i][] B = new vector*[i_MaxNumThreads]; #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) shared(B, i_MaxDegree, i_MaxNumThreads) #endif for(int i=0; i < i_MaxNumThreads; i++) { B[i] = new vector[i_MaxDegree]; } //DONE Line 2: for each vertex v in V in parallel do #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) shared(B, d, i_LeftVertexCount, i_MaxDegree_Private, i_MinDegree_Private) firstprivate(vi_Visited) #endif for(int v=0; v < i_LeftVertexCount; v++) { //DONE Line 3: d(v) <- d2(v,G) . Also find i_MaxDegree_Private d[v] = 0; for(int i=m_vi_LeftVertices[v]; id[v]) { i_MinDegree_Private[i_thread_num]=d[v]; } } // find i_MaxDegree; populate delta for(int i=0; i < i_MaxNumThreads; i++) { if(i_MaxDegree[i_MaxDegree+1]; } //DONE Line 2: for each vertex v in V in parallel do #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) shared(B, d, i_LeftVertexCount, VertexThreadGroup) #endif for(int v=0; v < i_LeftVertexCount; v++) { int i_thread_num; #ifdef _OPENMP i_thread_num = omp_get_thread_num(); #else i_thread_num = 0; #endif //DONE Line 4: add v to B_t(v) [d (v)] B[ i_thread_num ][ d[v] ].push_back(v); //record that v is in B_t(v) VertexThreadGroup[v] = i_thread_num; } //DONE Line 5: i_NumOfVerticesToBeColored <- |V| int i_NumOfVerticesToBeColored = i_LeftVertexCount; //Line 6: for k = 1 to p in parallel do #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) shared(i_MaxNumThreads, i_NumOfVerticesToBeColored, B, delta, VertexThreadGroup, d, cout, i_MaxDegree, i_MaxDegree_Private ) firstprivate(vi_Visited) #endif for(int k=0; k< i_MaxNumThreads; k++) { //reset vi_Visited for(int i=0; i< vi_Visited.size();i++) vi_Visited[i] = _UNKNOWN; //Line 7: while i_NumOfVerticesToBeColored >= 0 do // !!! ??? why not i_NumOfVerticesToBeColored > 0 while(i_NumOfVerticesToBeColored > 0) { int i_thread_num; #ifdef _OPENMP i_thread_num = omp_get_thread_num(); #else i_thread_num = 0; #endif //Line 8: Let delta be the smallest index j such that B_k [j] is non-empty //update delta // cout<<"delta[i_thread_num] 1="<< delta[i_thread_num] < vi_InducedVertexDegree; vector vi_Visited; vector< vector > vvi_GroupedInducedVertexDegree; vector< int > vi_VertexLocation; // initialize i_SelectedVertex = _UNKNOWN; i_VertexCount = (int)m_vi_LeftVertices.size () - 1; i_VertexCountMinus1 = i_VertexCount - 1; i_HighestInducedVertexDegree = 0; vi_Visited.clear(); vi_Visited.resize ( i_VertexCount, _UNKNOWN ); m_vi_OrderedVertices.clear(); m_vi_OrderedVertices.resize(i_VertexCount, _UNKNOWN); vi_InducedVertexDegree.clear(); vi_InducedVertexDegree.reserve((unsigned) i_VertexCount); vvi_GroupedInducedVertexDegree.clear(); vvi_GroupedInducedVertexDegree.resize((unsigned) i_VertexCount); vi_VertexLocation.clear(); vi_VertexLocation.reserve((unsigned) i_VertexCount); for ( i=0; i 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].pop_back(); // reduce degree of u by 1 vi_InducedVertexDegree[u]--; // move u to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].push_back(u); // update vi_VertexLocation[u] since it has now been changed vi_VertexLocation[u] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].size() - 1; } } // end of go to the neighbors of i_SelectedVertex and decrease the degrees by 1 //Mark the i_SelectedVertex as _UNKNOWN, so that we don't look at it again vi_InducedVertexDegree [i_SelectedVertex] = _UNKNOWN; m_vi_OrderedVertices[i_VertexCountMinus1 - i_SelectedVertexCount] = i_SelectedVertex; // go to next vertex ++i_SelectedVertexCount; } // clear the buffer vi_InducedVertexDegree.clear(); vi_VertexLocation.clear(); vvi_GroupedInducedVertexDegree.clear(); return(_TRUE); } int BipartiteGraphPartialOrdering::ColumnSmallestLastOrdering() { return BipartiteGraphPartialOrdering::ColumnSmallestLastOrdering_serial(); /*#ifdef _OPENMP return BipartiteGraphPartialOrdering::ColumnSmallestLastOrdering_OMP(); #else return BipartiteGraphPartialOrdering::ColumnSmallestLastOrdering_serial(); #endif*/ } //Line 1: procedure SMALLESTLASTORDERING-EASY(G = (V;E)) int BipartiteGraphPartialOrdering::ColumnSmallestLastOrdering_OMP() { // cout<<"IN COLUMN_SMALLEST_LAST_OMP()"< vi_Visited; vi_Visited.clear(); vi_Visited.resize ( i_RightVertexCount, _UNKNOWN ); m_vi_OrderedVertices.clear(); vector d; // current distance-2 degree of each right vertex d.resize(i_RightVertexCount, _UNKNOWN); vector VertexThreadGroup; VertexThreadGroup.resize(i_RightVertexCount, _UNKNOWN); int i_MaxNumThreads; #ifdef _OPENMP i_MaxNumThreads = omp_get_max_threads(); #else i_MaxNumThreads = 1; #endif int i_MaxDegree = 0; int* i_MaxDegree_Private = new int[i_MaxNumThreads]; int* i_MinDegree_Private = new int[i_MaxNumThreads]; // ??? is this really neccessary ? => #pragma omp parallel for default(none) schedule(static) shared() for(int i=0; i < i_MaxNumThreads; i++) { i_MaxDegree_Private[i] = 0; i_MinDegree_Private[i] = i_RightVertexCount; } int* delta = new int[i_MaxNumThreads]; vector** B; //private buckets. Each thread i will have their own buckets B[i][] B = new vector*[i_MaxNumThreads]; #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) shared(B, i_MaxDegree, i_MaxNumThreads) #endif for(int i=0; i < i_MaxNumThreads; i++) { B[i] = new vector[i_MaxDegree]; } //DONE Line 2: for each vertex v in V in parallel do #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) shared(B, d, i_RightVertexCount, i_MaxDegree_Private, i_MinDegree_Private) firstprivate(vi_Visited) #endif for(int v=0; v < i_RightVertexCount; v++) { //DONE Line 3: d(v) <- d2(v,G) . Also find i_MaxDegree_Private d[v] = 0; for(int i=m_vi_RightVertices[v]; id[v]) { i_MinDegree_Private[i_thread_num]=d[v]; } } // find i_MaxDegree; populate delta for(int i=0; i < i_MaxNumThreads; i++) { if(i_MaxDegree[i_MaxDegree+1]; } //DONE Line 2: for each vertex v in V in parallel do #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) shared(B, d, i_RightVertexCount, VertexThreadGroup) #endif for(int v=0; v < i_RightVertexCount; v++) { int i_thread_num; #ifdef _OPENMP i_thread_num = omp_get_thread_num(); #else i_thread_num = 0; #endif //DONE Line 4: add v to B_t(v) [d (v)] B[ i_thread_num ][ d[v] ].push_back(v); //record that v is in B_t(v) VertexThreadGroup[v] = i_thread_num; } //DONE Line 5: i_NumOfVerticesToBeColored <- |V| int i_NumOfVerticesToBeColored = i_RightVertexCount; //Line 6: for k = 1 to p in parallel do #ifdef _OPENMP #pragma omp parallel for default(none) schedule(static) shared(i_LeftVertexCount, i_MaxNumThreads, i_NumOfVerticesToBeColored, B, delta, VertexThreadGroup, d, cout, i_MaxDegree, i_MaxDegree_Private ) firstprivate(vi_Visited) #endif for(int k=0; k< i_MaxNumThreads; k++) { //reset vi_Visited for(int i=0; i< vi_Visited.size();i++) vi_Visited[i] = _UNKNOWN; //Line 7: while i_NumOfVerticesToBeColored >= 0 do // !!! ??? why not i_NumOfVerticesToBeColored > 0 while(i_NumOfVerticesToBeColored > 0) { int i_thread_num; #ifdef _OPENMP i_thread_num = omp_get_thread_num(); #else i_thread_num = 0; #endif //Line 8: Let delta be the smallest index j such that B_k [j] is non-empty //update delta // cout<<"delta[i_thread_num] 1="<< delta[i_thread_num] < vi_InducedVertexDegree; vector vi_Visited; vector< vector > vvi_GroupedInducedVertexDegree; vector< int > vi_VertexLocation; // initialize i_SelectedVertex = _UNKNOWN; i_VertexCount = (int)m_vi_RightVertices.size () - 1; i_VertexCountMinus1 = i_VertexCount - 1; i_HighestInducedVertexDegree = 0; vi_Visited.clear(); vi_Visited.resize ( i_VertexCount, _UNKNOWN ); m_vi_OrderedVertices.clear(); m_vi_OrderedVertices.resize(i_VertexCount, _UNKNOWN); vi_InducedVertexDegree.clear(); vi_InducedVertexDegree.reserve((unsigned) i_VertexCount); vvi_GroupedInducedVertexDegree.clear(); vvi_GroupedInducedVertexDegree.resize((unsigned) i_VertexCount); vi_VertexLocation.clear(); vi_VertexLocation.reserve((unsigned) i_VertexCount); int i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); for ( i=0; i 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].pop_back(); // reduce degree of u by 1 vi_InducedVertexDegree[u]--; // move u to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].push_back(u); // update vi_VertexLocation[u] since it has now been changed vi_VertexLocation[u] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].size() - 1; } } // end of go to the neighbors of i_SelectedVertex and decrease the degrees by 1 //Mark the i_SelectedVertex as _UNKNOWN, so that we don't look at it again vi_InducedVertexDegree [i_SelectedVertex] = _UNKNOWN; m_vi_OrderedVertices[i_VertexCountMinus1 - i_SelectedVertexCount] = i_SelectedVertex + i_LeftVertexCount; // go to next vertex ++i_SelectedVertexCount; } // clear the buffer vi_InducedVertexDegree.clear(); vi_VertexLocation.clear(); vvi_GroupedInducedVertexDegree.clear(); return(_TRUE); } int BipartiteGraphPartialOrdering::ColumnDynamicLargestFirstOrdering() { if(CheckVertexOrdering("COLUMN_DYNAMIC_LARGEST_FIRST")) { return(_TRUE); } int i, j, k, u, l; int i_Current; int i_SelectedVertex, i_SelectedVertexCount; int i_VertexCount; int i_HighestInducedVertexDegree, i_InducedVertexDegree; vector < int > vi_InducedVertexDegree; vector < int > vi_Visited; vector < vector < int > > vvi_GroupedInducedVertexDegree; vector < int > vi_VertexLocation; // initialize i_SelectedVertex = _UNKNOWN; i_VertexCount = (int)m_vi_RightVertices.size () - 1; i_HighestInducedVertexDegree = 0; vi_Visited.clear(); vi_Visited.resize ( i_VertexCount, _UNKNOWN ); m_vi_OrderedVertices.clear(); m_vi_OrderedVertices.reserve(i_VertexCount); vi_InducedVertexDegree.clear(); vi_InducedVertexDegree.reserve((unsigned) i_VertexCount); vvi_GroupedInducedVertexDegree.clear(); vvi_GroupedInducedVertexDegree.resize((unsigned) i_VertexCount); vi_VertexLocation.clear(); vi_VertexLocation.reserve((unsigned) i_VertexCount); int i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); for ( i=0; i= 0; i-- ) { if ( vvi_GroupedInducedVertexDegree[i].size () != 0 ) { i_SelectedVertex = vvi_GroupedInducedVertexDegree[i].back (); //remove the i_SelectedVertex from vvi_GroupedInducedVertexDegree vvi_GroupedInducedVertexDegree[i].pop_back(); break; } else i_HighestInducedVertexDegree--; } // end select first nonzero item from the bucket // go to the neighbors of i_SelectedVertex and decrease the degrees by 1 for ( i=m_vi_RightVertices [i_SelectedVertex]; i 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].pop_back(); // reduce degree of u by 1 vi_InducedVertexDegree[u]--; // move u to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].push_back(u); // update vi_VertexLocation[u] since it has now been changed vi_VertexLocation[u] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].size() - 1; } } // end of go to the neighbors of i_SelectedVertex and decrease the degrees by 1 //Mark the i_SelectedVertex as _UNKNOWN, so that we don't look at it again vi_InducedVertexDegree [i_SelectedVertex] = _UNKNOWN; m_vi_OrderedVertices.push_back(i_SelectedVertex + i_LeftVertexCount); // go to next vertex ++i_SelectedVertexCount; } // clear the buffer vi_InducedVertexDegree.clear(); vi_VertexLocation.clear(); vvi_GroupedInducedVertexDegree.clear(); vi_Visited.clear (); return(_TRUE); } int BipartiteGraphPartialOrdering::RowDynamicLargestFirstOrdering() { if(CheckVertexOrdering("ROW_DYNAMIC_LARGEST_FIRST")) { return(_TRUE); } int i, j, k, u, l; int i_Current; int i_SelectedVertex, i_SelectedVertexCount; int i_VertexCount; int i_HighestInducedVertexDegree, i_InducedVertexDegree; vector vi_InducedVertexDegree; vector vi_Visited; vector< vector > vvi_GroupedInducedVertexDegree; vector< int > vi_VertexLocation; // initialize i_SelectedVertex = _UNKNOWN; i_VertexCount = (int)m_vi_LeftVertices.size () - 1; i_HighestInducedVertexDegree = 0; vi_Visited.clear(); vi_Visited.resize ( i_VertexCount, _UNKNOWN ); m_vi_OrderedVertices.clear(); m_vi_OrderedVertices.reserve(i_VertexCount); vi_InducedVertexDegree.clear(); vi_InducedVertexDegree.reserve((unsigned) i_VertexCount); vvi_GroupedInducedVertexDegree.clear(); vvi_GroupedInducedVertexDegree.resize((unsigned) i_VertexCount); vi_VertexLocation.clear(); vi_VertexLocation.reserve((unsigned) i_VertexCount); for ( i=0; i= 0; i-- ) { if ( vvi_GroupedInducedVertexDegree[i].size () != 0 ) { i_SelectedVertex = vvi_GroupedInducedVertexDegree[i].back (); //remove the i_SelectedVertex from vvi_GroupedInducedVertexDegree vvi_GroupedInducedVertexDegree[i].pop_back(); break; } else i_HighestInducedVertexDegree--; } // end select first nonzero item from the bucket // go to the neighbors of i_SelectedVertex and decrease the degrees by 1 for ( i=m_vi_LeftVertices [i_SelectedVertex]; i 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].pop_back(); // reduce degree of u by 1 vi_InducedVertexDegree[u]--; // move u to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].push_back(u); // update vi_VertexLocation[u] since it has now been changed vi_VertexLocation[u] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].size() - 1; } } // end of go to the neighbors of i_SelectedVertex and decrease the degrees by 1 //Mark the i_SelectedVertex as _UNKNOWN, so that we don't look at it again vi_InducedVertexDegree [i_SelectedVertex] = _UNKNOWN; m_vi_OrderedVertices.push_back(i_SelectedVertex); // go to next vertex ++i_SelectedVertexCount; } // clear the buffer vi_InducedVertexDegree.clear(); vi_VertexLocation.clear(); vvi_GroupedInducedVertexDegree.clear(); vi_Visited.clear(); return(_TRUE); } //Public Function 2361 int BipartiteGraphPartialOrdering::RowIncidenceDegreeOrdering() { if(CheckVertexOrdering("ROW_INCIDENCE_DEGREE")) { return(_TRUE); } int i, j, k, l, u; int i_Current; int i_HighestDegreeVertex, m_i_MaximumVertexDegree; int i_VertexCount, i_VertexDegree, i_IncidenceVertexDegree; int i_SelectedVertex, i_SelectedVertexCount; vector vi_IncidenceVertexDegree; vector vi_Visited; vector< vector > vvi_GroupedIncidenceVertexDegree; vector< int > vi_VertexLocation; // initialize i_SelectedVertex = _UNKNOWN; i_VertexCount = (int)m_vi_LeftVertices.size () - 1; vvi_GroupedIncidenceVertexDegree.clear(); vvi_GroupedIncidenceVertexDegree.resize ( i_VertexCount ); i_HighestDegreeVertex = _UNKNOWN; m_i_MaximumVertexDegree = _UNKNOWN; i_IncidenceVertexDegree = 0; vi_Visited.resize ( i_VertexCount, _UNKNOWN ); m_vi_OrderedVertices.clear(); m_vi_OrderedVertices.reserve(i_VertexCount); vi_VertexLocation.clear(); vi_VertexLocation.reserve(i_VertexCount); vi_IncidenceVertexDegree.clear(); vi_IncidenceVertexDegree.reserve(i_VertexCount); for ( i=0; i=0; i-- ) { if ( (int)vvi_GroupedIncidenceVertexDegree [i].size () != 0 ) { i_SelectedVertex = vvi_GroupedIncidenceVertexDegree [i].back (); // now we remove i_SelectedVertex from the bucket vvi_GroupedIncidenceVertexDegree [i].pop_back(); break; } } // end select the vertex with the highest Incidence degree // tell the neighbors of i_SelectedVertex that we are removing it for ( i=m_vi_LeftVertices [i_SelectedVertex]; i 1) { l = vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].back(); vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]][vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } // remove the last element from vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]] vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].pop_back(); // now update that we are visiting u vi_Visited [u] = i_SelectedVertex; // end now update that we are visiting u // now we tell that neighbor to increase its degree by 1 ++vi_IncidenceVertexDegree [u]; // place the neighbor in 1 degree up in the bucket vvi_GroupedIncidenceVertexDegree [vi_IncidenceVertexDegree [u]].push_back ( u ); // update the location of the now moved neighbor vi_VertexLocation [u] = vvi_GroupedIncidenceVertexDegree [vi_IncidenceVertexDegree [u]].size () -1; } } // end tell the neighbors of i_SelectedVertex that we are removing it // now we say that i_SelectedVertex's degree is unknown to us vi_IncidenceVertexDegree [i_SelectedVertex] = _UNKNOWN; // now we push i_SelectedVertex to the back or VertexOrder m_vi_OrderedVertices.push_back ( i_SelectedVertex ); // loop it again ++i_SelectedVertexCount; } // clear the buffer vi_IncidenceVertexDegree.clear(); vi_VertexLocation.clear(); vvi_GroupedIncidenceVertexDegree.clear(); return(_TRUE); } //Public Function 2362 int BipartiteGraphPartialOrdering::ColumnIncidenceDegreeOrdering() { if(CheckVertexOrdering("COLUMN_INCIDENCE_DEGREE")) { return(_TRUE); } int i, j, k, l, u; int i_Current; int i_HighestDegreeVertex, m_i_MaximumVertexDegree; int i_VertexCount, i_VertexDegree, i_IncidenceVertexDegree; int i_SelectedVertex, i_SelectedVertexCount; vector vi_IncidenceVertexDegree; vector vi_Visited; vector< vector > vvi_GroupedIncidenceVertexDegree; vector< int > vi_VertexLocation; // initialize i_SelectedVertex = _UNKNOWN; i_VertexCount = (int)m_vi_RightVertices.size () - 1; vvi_GroupedIncidenceVertexDegree.resize ( i_VertexCount ); i_HighestDegreeVertex = _UNKNOWN; m_i_MaximumVertexDegree = _UNKNOWN; i_IncidenceVertexDegree = 0; vi_Visited.resize ( i_VertexCount, _UNKNOWN ); m_vi_OrderedVertices.clear(); int i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); // enter code here for ( i=0; i=0; i-- ) { if ( (int)vvi_GroupedIncidenceVertexDegree [i].size () != 0 ) { i_SelectedVertex = vvi_GroupedIncidenceVertexDegree [i].back (); // now we remove i_SelectedVertex from the bucket vvi_GroupedIncidenceVertexDegree [i].pop_back(); break; } } // end select the vertex with the highest Incidence degree // tell the neighbors of i_SelectedVertex that we are removing it for ( i=m_vi_RightVertices [i_SelectedVertex]; i 1) { l = vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].back(); vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]][vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } // remove the last element from vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]] vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].pop_back(); // now update that we are visiting u vi_Visited [u] = i_SelectedVertex; // end now update that we are visiting u // now we tell that neighbor to increase its degree by 1 ++vi_IncidenceVertexDegree [u]; // place the neighbor in 1 degree up in the bucket vvi_GroupedIncidenceVertexDegree [vi_IncidenceVertexDegree [u]].push_back ( u ); // update the location of the now moved neighbor vi_VertexLocation [u] = vvi_GroupedIncidenceVertexDegree [vi_IncidenceVertexDegree [u]].size () -1; } } // end tell the neighbors of i_SelectedVertex that we are removing it // now we say that i_SelectedVertex's degree is unknown to us vi_IncidenceVertexDegree [i_SelectedVertex] = _UNKNOWN; // now we push i_SelectedVertex to the back or VertexOrder m_vi_OrderedVertices.push_back ( i_SelectedVertex + i_LeftVertexCount ); // loop it again ++i_SelectedVertexCount; } // clear the buffer vi_IncidenceVertexDegree.clear(); vi_VertexLocation.clear(); vvi_GroupedIncidenceVertexDegree.clear(); return(_TRUE); } //Public Function 2363 string BipartiteGraphPartialOrdering::GetVertexOrderingVariant() { if(m_s_VertexOrderingVariant.compare("ROW_NATURAL") == 0) { return("Row Natural"); } else if(m_s_VertexOrderingVariant.compare("COLUMN_NATURAL") == 0) { return("Column Natural"); } else if(m_s_VertexOrderingVariant.compare("ROW_LARGEST_FIRST") == 0) { return("Row Largest First"); } else if(m_s_VertexOrderingVariant.compare("COLUMN_LARGEST_FIRST") == 0) { return("Column Largest First"); } else if(m_s_VertexOrderingVariant.compare("ROW_SMALLEST_LAST") == 0) { return("Row Smallest Last"); } else if(m_s_VertexOrderingVariant.compare("COLUMN_SMALLEST_LAST") == 0) { return("Column Smallest Last"); } else if(m_s_VertexOrderingVariant.compare("ROW_INCIDENCE_DEGREE") == 0) { return("Row Incidence Degree"); } else if(m_s_VertexOrderingVariant.compare("COLUMN_INCIDENCE_DEGREE") == 0) { return("Column Incidence Degree"); } else { return("Unknown"); } } //Public Function 2364 void BipartiteGraphPartialOrdering::GetOrderedVertices(vector &output) { output = (m_vi_OrderedVertices); } int BipartiteGraphPartialOrdering::OrderVertices(string s_OrderingVariant, string s_ColoringVariant) { s_ColoringVariant = toUpper(s_ColoringVariant); s_OrderingVariant = toUpper(s_OrderingVariant); if(s_ColoringVariant == "ROW_PARTIAL_DISTANCE_TWO") { if((s_OrderingVariant.compare("NATURAL") == 0)) { return(RowNaturalOrdering()); } else if((s_OrderingVariant.compare("LARGEST_FIRST") == 0)) { return(RowLargestFirstOrdering()); } else if((s_OrderingVariant.compare("SMALLEST_LAST") == 0)) { return(RowSmallestLastOrdering()); } else if((s_OrderingVariant.compare("INCIDENCE_DEGREE") == 0)) { return(RowIncidenceDegreeOrdering()); } else if((s_OrderingVariant.compare("RANDOM") == 0)) { return(RowRandomOrdering()); } else { cerr<. ************************************************************************************/ using namespace std; #ifndef BIPARTITEGRAPHPARTIALORDERING_H #define BIPARTITEGRAPHPARTIALORDERING_H #define RIGHT_PARTIAL_DISTANCE_TWO COLUMN_PARTIAL_DISTANCE_TWO #define LEFT_PARTIAL_DISTANCE_TWO ROW_PARTIAL_DISTANCE_TWO namespace ColPack { /** @ingroup group21 * @brief class BipartiteGraphPartialOrdering in @link group21@endlink. The BipartiteGraphPartialOrderingClass stores either the ordered row or column vertices as a vector of vertex identifiers to be used by bipartite graph partial coloring methods. */ class BipartiteGraphPartialOrdering : public BipartiteGraphInputOutput { public: int OrderVertices(string s_OrderingVariant = "NATURAL", string s_ColoringVariant = "COLUMN_PARTIAL_DISTANCE_TWO"); private: int CheckVertexOrdering(string s_VertexOrderingVariant); protected: double m_d_OrderingTime; string m_s_VertexOrderingVariant; vector m_vi_OrderedVertices; public: BipartiteGraphPartialOrdering(); ~BipartiteGraphPartialOrdering(); virtual void Clear(); virtual void Reset(); int RowNaturalOrdering(); int ColumnNaturalOrdering(); int RowRandomOrdering(); int ColumnRandomOrdering(); int RowLargestFirstOrdering(); int ColumnLargestFirstOrdering(); int RowSmallestLastOrdering(); int RowSmallestLastOrdering_serial(); int RowSmallestLastOrdering_OMP(); int ColumnSmallestLastOrdering(); int ColumnSmallestLastOrdering_serial(); int ColumnSmallestLastOrdering_OMP(); int RowIncidenceDegreeOrdering(); int ColumnIncidenceDegreeOrdering(); int RowDynamicLargestFirstOrdering(); int ColumnDynamicLargestFirstOrdering(); string GetVertexOrderingVariant(); void GetOrderedVertices(vector &output); void PrintVertexOrdering(); double GetVertexOrderingTime(); }; } #endif ColPack-1.0.10/COPYING000066400000000000000000001045131266356121500141530ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ColPack-1.0.10/COPYING.LESSER000066400000000000000000000167251266356121500151560ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. ColPack-1.0.10/ChangeLog000066400000000000000000000050041266356121500146650ustar00rootroot000000000000002011-09-01 Duc Nguyen displayGraph() is updated to accept BipartiteGraphPartialColoringInterface &g At this point, displayGraph(BipartiteGraphPartialColoringInterface &g) cannot highlight coloring conflicts yet 2011-09-01 Duc Nguyen Add "int displayGraph(ColPack::GraphColoring &g);" in extra.cpp to support debugging this function will create the DOT-file that describe the graph (with or without color) , and then utilize GraphViz to display the graph in image. In the case of Star Coloring, if there are conflict(s), the conflict(s) will be highlighted in bold edges. Each node in the graph will have name in this form "v#_c#" (vertex ID follow by color ID (0-based indexing)) 2011-03-22 Duc Nguyen Version 1.0.3 Fixed HessianRecovery::IndirectRecover_CoordinateFormat_vectors() bug that cause ColPack to crash PROBLEM: vd_IncludedVertices[] is used to keep both the values stored at the vertices and to mark that a vertex is no longer a part of the tree by setting vd_IncludedVertices[] = _UNKNOWN (-1) => ColPack crashed when some of the recovered values are -1 SOLUTION: use a separate array vb_IncludedVertices[] to mark that a vertex is no longer a part of the tree Support for "make -j EXTRA_FLAGS=-D_COLPACK_CHECKPOINT_" are added for Bug Report purpose If you use ColPack indirrectly via another tool like ADIC or ADOL-C, you can generate the graph by running "make clean && make -j EXTRA_FLAGS=-D_COLPACK_CHECKPOINT_". When the program is executed, ColPack library will generate a Matrix Market format file ColPack_input_graph.mtx in the same directory as the running program. If this does not work, you can also force ColPack to generate the file by calling g->WriteMatrixMarket() with g is a GraphColoringInterface, BipartiteGraphPartialColoringInterface, or BipartiteGraphBicoloringInterface object Interface functions for ADIC partially developed BipartiteGraphPartialColoringInterface() now accepts input from ADIC (int i_type=SRC_MEM_ADIC) BipartiteGraphPartialColoringInterface(int i_type, std::list >* valsetlist, int rowCount) a bipartite graph can be built by calling: BipartiteGraphPartialColoringInterface *g = new BipartiteGraphPartialColoringInterface(SRC_MEM_ADIC, &valsetlist, rowCount); add int JacobianRecovery1D::RecoverD2Cln_ADICFormat( BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, std::list >& lsi_SparsityPattern, std::list > &lvd_NewValue)ColPack-1.0.10/GraphColoring/000077500000000000000000000000001266356121500156525ustar00rootroot00000000000000ColPack-1.0.10/GraphColoring/GraphColoring.cpp000066400000000000000000005346331266356121500211320ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.GraphColoring::GraphColoring() ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Private Function 1401 int GraphColoring::FindCycle(int i_Vertex, int i_AdjacentVertex, int i_DistanceOneVertex, int i_SetID, vector & vi_CandidateColors, vector & vi_FirstVisitedOne, vector & vi_FirstVisitedTwo) { int i_VertexOne, i_VertexTwo; if(i_SetID != _UNKNOWN) { i_VertexOne = vi_FirstVisitedOne[i_SetID]; i_VertexTwo = vi_FirstVisitedTwo[i_SetID]; if(i_VertexOne != i_Vertex) { vi_FirstVisitedOne[i_SetID] = i_Vertex; vi_FirstVisitedTwo[i_SetID] = i_AdjacentVertex; } else if((i_VertexOne == i_Vertex) && (i_VertexTwo != i_AdjacentVertex)) { vi_CandidateColors[m_vi_VertexColors[i_DistanceOneVertex]] = i_Vertex; #if DEBUG == 1401 cout<<"DEBUG 1401 | Acyclic Coloring | Found Cycle | Vertex "< > & mimi2_VertexEdgeMap, vector & vi_FirstSeenOne, vector & vi_FirstSeenTwo, vector & vi_FirstSeenThree) { int i_ColorID; int i_VertexOne, i_VertexTwo, i_VertexThree; i_ColorID = m_vi_VertexColors[i_AdjacentVertex]; i_VertexOne = vi_FirstSeenOne[i_ColorID]; i_VertexTwo = vi_FirstSeenTwo[i_ColorID]; i_VertexThree = vi_FirstSeenThree[i_ColorID]; if(i_VertexOne != i_Vertex) { vi_FirstSeenOne[i_ColorID] = i_Vertex; vi_FirstSeenTwo[i_ColorID] = i_AdjacentVertex; vi_FirstSeenThree[i_ColorID] = i_DistanceOneVertex; } else { if(i_VertexTwo < i_VertexThree) { return(mimi2_VertexEdgeMap[i_VertexTwo][i_VertexThree]); } else { return(mimi2_VertexEdgeMap[i_VertexThree][i_VertexTwo]); } } return(_UNKNOWN); } //Private Function 1403 int GraphColoring::SearchDepthFirst(int i_RootVertex, int i_ParentVertex, int i_Vertex, vector & vi_TouchedVertices) { int i; int i_VertexCount; int i_ViolationCount; i_ViolationCount = _FALSE; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); for(i=m_vi_Vertices[i_Vertex]; i m_vi_VertexColorFrequency[i]) { m_i_SmallestColorClass = i; m_i_SmallestColorClassSize = m_vi_VertexColorFrequency[i]; } } m_d_AverageColorClassSize = i_TotalVertexColors / i_VertexCount; return(_TRUE); } //Public Constructor 1451 GraphColoring::GraphColoring() : GraphOrdering() { Clear(); Seed_init(); } //Public Destructor 1452 GraphColoring::~GraphColoring() { Clear(); Seed_reset(); } //Virtual Function 1453 void GraphColoring::Clear() { GraphOrdering::Clear(); m_i_VertexColorCount = _UNKNOWN; m_i_LargestColorClass = _UNKNOWN; m_i_SmallestColorClass = _UNKNOWN; m_i_LargestColorClassSize = _UNKNOWN; m_i_SmallestColorClassSize = _UNKNOWN; m_d_AverageColorClassSize = _UNKNOWN; m_i_ColoringUnits = _UNKNOWN; m_d_ColoringTime = _UNKNOWN; m_d_CheckingTime = _UNKNOWN; m_s_VertexColoringVariant.clear(); m_vi_VertexColors.clear(); m_vi_VertexColorFrequency.clear(); return; } void GraphColoring::ClearColoringONLY() { m_i_VertexColorCount = _UNKNOWN; m_i_LargestColorClass = _UNKNOWN; m_i_SmallestColorClass = _UNKNOWN; m_i_LargestColorClassSize = _UNKNOWN; m_i_SmallestColorClassSize = _UNKNOWN; m_d_AverageColorClassSize = _UNKNOWN; m_i_ColoringUnits = _UNKNOWN; m_d_ColoringTime = _UNKNOWN; m_d_CheckingTime = _UNKNOWN; m_s_VertexColoringVariant.clear(); m_vi_VertexColors.clear(); m_vi_VertexColorFrequency.clear(); return; } //Public Function 1454 int GraphColoring::DistanceOneColoring() { //* if(CheckVertexColoring("DISTANCE ONE")) { return(_TRUE); } //*/ int i, j; int i_PresentVertex; int i_VertexCount; vector vi_CandidateColors; m_i_VertexColorCount = _UNKNOWN; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); m_vi_VertexColors.clear(); m_vi_VertexColors.resize((unsigned) i_VertexCount, _UNKNOWN); vi_CandidateColors.clear(); vi_CandidateColors.resize((unsigned) i_VertexCount, _UNKNOWN); for(i=0; i vi_CandidateColors; m_i_VertexColorCount = _UNKNOWN; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); m_vi_VertexColors.clear(); m_vi_VertexColors.resize((unsigned) i_VertexCount, _UNKNOWN); vi_CandidateColors.clear(); vi_CandidateColors.resize((unsigned) i_VertexCount, _UNKNOWN); for(i=0; i vi_CandidateColors; m_i_VertexColorCount = _UNKNOWN; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); m_vi_VertexColors.clear(); m_vi_VertexColors.resize((unsigned) i_VertexCount, _UNKNOWN); vi_CandidateColors.clear(); vi_CandidateColors.resize((unsigned) i_VertexCount, _UNKNOWN); for(i=0; i vi_CandidateColors; m_i_VertexColorCount = _UNKNOWN; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); m_vi_VertexColors.clear(); m_vi_VertexColors.resize((unsigned) i_VertexCount, _UNKNOWN); vi_CandidateColors.clear(); vi_CandidateColors.resize((unsigned) i_VertexCount, _UNKNOWN); for(i=0; i* VertexColorCombination) { cout<<"PrintVertexColorCombination"<::iterator mii_iter; mii_iter = (*VertexColorCombination).begin(); for(;mii_iter != (*VertexColorCombination).end(); mii_iter++) { cout<<"\t c "<first<<": "; if( mii_iter->second > -1) { cout<<" NO hub, connect to v "<second<<" c "<second]; } else if ( mii_iter->second == -1) { cout<<" HUB"; } else { // (*itr)[iii].second < -1 cout<<" LEAF of hub v "<<-(mii_iter->second+2) <<" c "<second+2)]; } cout< *PotentialHub_Private, int i_thread_num, pair pii_ColorCombination) { cout<<"PrintPotentialHub - Star collection of combination "<< pii_ColorCombination.first << " "<< pii_ColorCombination.second <::iterator mii_iter; mii_iter = PotentialHub_Private[i_thread_num].begin(); for(;mii_iter != PotentialHub_Private[i_thread_num].end(); mii_iter++) { cout<<"\t v "<first<<" c "<first]<<":"; if( mii_iter->second > -1) { cout<<" NO hub, connect to v "<second<<" c "<second]; } else if ( mii_iter->second == -1) { cout<<" HUB"; } else { // (*itr)[iii].second < -1 cout<<" LEAF of hub v "<<-(mii_iter->second+2) <<" c "<second+2)]; } cout< make this function run faster) int GraphColoring::BuildStarFromColorCombination_forChecking(int i_Mode, int i_MaxNumThreads, int i_thread_num, pair pii_ColorCombination, map< pair, Colors2Edge_Value , lt_pii>* Colors2Edge_Private, map< int, int> * PotentialHub_Private) { map< pair, Colors2Edge_Value, lt_pii >::iterator mpii_iter; map< int, int>::iterator mii_iter; int i_PotentialHub=0; int i_ConflictVertex=-1; bool b_isConflict=false; // reset PotentialHub_Private; PotentialHub_Private[i_thread_num].clear(); for(int i= 0; i vi_ConflictedEdgeIndices; vector< pair >* vpii_EdgesPtr = &(mpii_iter->second.value); pair pii_Edge; // now start counting the appearance of vertices and detect conflict for(int j=0; j< vpii_EdgesPtr->size(); j++ ) { pii_Edge = (*vpii_EdgesPtr)[j]; #ifdef COLPACK_DEBUG cout<<"\t Looking at "<second >=-1) { //pii_Edge.first is a potential hub i_PotentialHub += 1; } else { b_isConflict=true; i_ConflictVertex=pii_Edge.second; } } mii_iter = PotentialHub_Private[i_thread_num].find(pii_Edge.second); if(mii_iter != PotentialHub_Private[i_thread_num].end()) { if( mii_iter->second >=-1) { //pii_Edge.second is a potential hub i_PotentialHub += 2; } else { b_isConflict=true; i_ConflictVertex=pii_Edge.first; } } if(i_PotentialHub == 3 || b_isConflict) { // pii_Edge.first and pii_Edge.second are both potential hubs || conflict has been detected CoutLock::set(); { //Detect conflict cerr< > *graph = new map< int, map >; map *mib_FilterByColors = new map; { (*mib_FilterByColors)[m_vi_VertexColors[pii_Edge.first]] = true; (*mib_FilterByColors)[m_vi_VertexColors[pii_Edge.second]] = true; } //BuildSubGraph(graph, pii_Edge.first, 4, mib_FilterByColors); BuildColorsSubGraph(graph,mib_FilterByColors); vector vi_VertexColors; GetVertexColors(vi_VertexColors); displayGraph(graph, &vi_VertexColors, true, FDP); delete graph; delete mib_FilterByColors; //Pause(); #if COLPACK_DEBUG_LEVEL > 100 cout<<" FAILED"<, Colors2Edge_Value, lt_pii> *Colors2Edge_Private = new map< pair, Colors2Edge_Value, lt_pii> [i_MaxNumThreads]; // map 2-color combination to edges that have those 2 colors bool b_Stop = false; #ifdef _OPENMP #pragma omp parallel for default(none) shared(i_ConflictVertex, i_VertexCount, Colors2Edge_Private, cout , i_MaxNumThreads, i_Mode, b_Stop) #endif for(int i=0; i pii_ColorCombination; pair pii_Edge; for(int j=m_vi_Vertices[i]; j m_vi_VertexColors[ m_vi_Edges[j] ] ) { pii_ColorCombination.second = m_vi_VertexColors[i]; pii_ColorCombination.first = m_vi_VertexColors[m_vi_Edges[j]]; Colors2Edge_Private[i_thread_num][pii_ColorCombination].value.push_back(pii_Edge); } else { //m_vi_VertexColors[i] == m_vi_VertexColors[ m_vi_Edges[j] ] // conflict found! CoutLock::set(); { //Detect conflict cout< 100 cout<<" FAILED"<, Colors2Edge_Value, lt_pii >::iterator iter = Colors2Edge_Private[i].begin(); iter != Colors2Edge_Private[i].end() ; iter++) { #pragma omp single nowait { if(iter->second.visited == false && !b_Stop) { iter->second.visited=true; // mark the same color combination in other Colors2Edge_Private[] as visited so that a thread can freely work on this color combination in all Colors2Edge_Private[] for(int ii = i; ii, Colors2Edge_Value, lt_pii >::iterator iter2 = Colors2Edge_Private[ii].find(iter->first); if(iter2!=Colors2Edge_Private[ii].end()) { // if the combination exists, we mark it as visited iter2->second.visited = true; } } int i_thread_num; #ifdef _OPENMP i_thread_num = omp_get_thread_num(); #else i_thread_num = 0; #endif // now, let a thread works on this combination: // build stars and identify conflict edges i_ConflictVertex[i_thread_num] = BuildStarFromColorCombination_forChecking(i_Mode, i_MaxNumThreads, i_thread_num, iter->first, Colors2Edge_Private, PotentialHub_Private); if(i_ConflictVertex[i_thread_num] != -1) { #pragma omp critial { if(pii_ConflictColorCombination!=NULL) { (*pii_ConflictColorCombination).first = iter->first.first; (*pii_ConflictColorCombination).second = iter->first.second; } } b_Stop = true; cout<<"IN CheckStarColoring_OMP i_ConflictVertex["<< i_thread_num<<"]="<< i_ConflictVertex[i_thread_num] <first).first<<" "<<(iter->first).second< make this function run faster) int GraphColoring::BuildStarFromColorCombination(int i_MaxNumThreads, int i_thread_num, pair pii_ColorCombination, map< pair, Colors2Edge_Value , lt_pii>* Colors2Edge_Private, map< int, vector< pair > > *Vertex2ColorCombination_Private, map< int, int> * PotentialHub_Private) { int i_VertexCount = m_vi_Vertices.size() - 1; map< pair, Colors2Edge_Value, lt_pii >::iterator mpii_iter; map< int, int>::iterator mii_iter; int i_PotentialHub=0; bool b_isConflict=false; // reset PotentialHub_Private; PotentialHub_Private[i_thread_num].clear(); #ifdef COLPACK_DEBUG cout<<"Color combination "< vi_ConflictedEdgeIndices; vector< pair >* vpii_EdgesPtr = &(mpii_iter->second.value); pair pii_Edge; // now start counting the appearance of vertices and detect conflict for(int j=0; j< vpii_EdgesPtr->size(); j++ ) { pii_Edge = (*vpii_EdgesPtr)[j]; #ifdef COLPACK_DEBUG cout<<"\t Looking at "<second >=-1) { //pii_Edge.first is a potential hub i_PotentialHub += 1; } else { b_isConflict=true; } } mii_iter = PotentialHub_Private[i_thread_num].find(pii_Edge.second); if(mii_iter != PotentialHub_Private[i_thread_num].end()) { if( mii_iter->second >=-1) { //pii_Edge.second is a potential hub i_PotentialHub += 2; } else { b_isConflict=true; } } if(i_PotentialHub == 3 || b_isConflict) { // pii_Edge.first and pii_Edge.second are both potential hubs || conflict has been detected => add this edge into ConflictedEdges_Private CoutLock::set(); { //Detect conflict cerr< 100 cout<<" FAILED"<second >=0) { // This is a single edge hub => mark the pii_Edge.first vertex as hub and (the other connected vertex + pii_Edge.second) as a leaf PotentialHub_Private[i_thread_num][PotentialHub_Private[i_thread_num][pii_Edge.first] ] = -(pii_Edge.first+2); PotentialHub_Private[i_thread_num][pii_Edge.second] = -(pii_Edge.first+2); PotentialHub_Private[i_thread_num][pii_Edge.first] = -1; } else { // mii_iter->second = -1 : This is a hub with more than one edge => mark pii_Edge.second as a leaf PotentialHub_Private[i_thread_num][pii_Edge.second] = -(pii_Edge.first+2); } } else if(i_PotentialHub == 2) { //only pii_Edge.second is a potential hub mii_iter = PotentialHub_Private[i_thread_num].find(pii_Edge.second); if(mii_iter->second >=0) { // This is a single edge hub => mark the pii_Edge.second vertex as hub and (the other connected vertex + pii_Edge.first) as a leaf PotentialHub_Private[i_thread_num][ PotentialHub_Private[i_thread_num][pii_Edge.second] ] = -(pii_Edge.second+2); PotentialHub_Private[i_thread_num][pii_Edge.first] = -(pii_Edge.second+2); PotentialHub_Private[i_thread_num][pii_Edge.second] = -1; } else { // mii_iter->second = -1 : This is a hub with more than one edge => mark pii_Edge.first as a leaf PotentialHub_Private[i_thread_num][pii_Edge.first] = -(pii_Edge.second+2); } } else { // Both end of the vertices are seen for the first time => make them potential hubs PotentialHub_Private[i_thread_num][pii_Edge.second] = pii_Edge.first; PotentialHub_Private[i_thread_num][pii_Edge.first] = pii_Edge.second; } #ifdef COLPACK_DEBUG cout<<" PASSED"< pii_pair; mii_iter = PotentialHub_Private[i_thread_num].begin(); for(;mii_iter != PotentialHub_Private[i_thread_num].end(); mii_iter++) { if(m_vi_VertexColors[mii_iter->first] == pii_ColorCombination.first) i_TheOtherColor = pii_ColorCombination.second; else i_TheOtherColor = pii_ColorCombination.first; pii_pair.first = i_TheOtherColor; pii_pair.second = mii_iter->second; // if pii_pair.second < -1, then mii_iter->first is a leaf and its hub can be calculated as [-(pii_pair.second+2)] Vertex2ColorCombination_Private[i_thread_num][ mii_iter->first ].push_back(pii_pair); } return (_TRUE); } /** This function will go through 2-color combination, attemp to build stars and identify conflict edges. * Conflict edges will be pushed into (thread private) ConflictedEdges. ConflictCount of each vertex will be increased accordingly */ int GraphColoring::DetectConflictInColorCombination(int i_MaxNumThreads, int i_thread_num, pair pii_ColorCombination, map< pair, Colors2Edge_Value , lt_pii>* Colors2Edge_Private, map< int, vector< pair > > *Vertex2ColorCombination_Private, map< int, int> * PotentialHub_Private, vector< pair >* ConflictedEdges_Private, vector* ConflictCount_Private) { int i_VertexCount = m_vi_Vertices.size() - 1; map< pair, Colors2Edge_Value, lt_pii >::iterator mpii_iter; map< int, int>::iterator mii_iter; int i_PotentialHub=0; bool b_isConflict=false; // reset PotentialHub_Private; PotentialHub_Private[i_thread_num].clear(); // !!! consider remove AppearanceCount_Private (if not used) //reset AppearanceCount_Private[i_thread_num] //for(int i=0; isecond >=-1) { //pii_Edge.first is a potential hub i_PotentialHub += 1; } else { b_isConflict=true; } } mii_iter = PotentialHub_Private[i_thread_num].find(pii_Edge.second); if(mii_iter != PotentialHub_Private[i_thread_num].end()) { if( mii_iter->second >=-1) { //pii_Edge.second is a potential hub i_PotentialHub += 2; } else { b_isConflict=true; } } if(i_PotentialHub == 3 || b_isConflict) { // pii_Edge.first and pii_Edge.second are both potential hubs || conflict has been detected => add this edge into ConflictedEdges_Private //Detect conflict ConflictedEdges_Private[i_thread_num].push_back(pii_Edge); //vi_ConflictedEdgeIndices.push_back(j); ConflictCount_Private[i_thread_num][pii_Edge.first]++; ConflictCount_Private[i_thread_num][pii_Edge.second]++; #if COLPACK_DEBUG_LEVEL > 100 cout<<"\t\t"<second >=0) { // This is a single edge hub => mark the pii_Edge.first vertex as hub and (the other connected vertex + pii_Edge.second) as a leaf PotentialHub_Private[i_thread_num][PotentialHub_Private[i_thread_num][pii_Edge.first] ] = -(pii_Edge.first+2); PotentialHub_Private[i_thread_num][pii_Edge.second] = -(pii_Edge.first+2); PotentialHub_Private[i_thread_num][pii_Edge.first] = -1; } else { // mii_iter->second = -1 : This is a hub with more than one edge => mark pii_Edge.second as a leaf PotentialHub_Private[i_thread_num][pii_Edge.second] = -(pii_Edge.first+2); } } else if(i_PotentialHub == 2) { //only pii_Edge.second is a potential hub mii_iter = PotentialHub_Private[i_thread_num].find(pii_Edge.second); if(mii_iter->second >=0) { // This is a single edge hub => mark the pii_Edge.second vertex as hub and (the other connected vertex + pii_Edge.first) as a leaf PotentialHub_Private[i_thread_num][ PotentialHub_Private[i_thread_num][pii_Edge.second] ] = -(pii_Edge.second+2); PotentialHub_Private[i_thread_num][pii_Edge.first] = -(pii_Edge.second+2); PotentialHub_Private[i_thread_num][pii_Edge.second] = -1; } else { // mii_iter->second = -1 : This is a hub with more than one edge => mark pii_Edge.first as a leaf PotentialHub_Private[i_thread_num][pii_Edge.first] = -(pii_Edge.second+2); } } else { // Both end of the vertices are seen for the first time => make them potential hubs PotentialHub_Private[i_thread_num][pii_Edge.second] = pii_Edge.first; PotentialHub_Private[i_thread_num][pii_Edge.first] = pii_Edge.second; } #if COLPACK_DEBUG_LEVEL > 100 cout<<"\t\t"<0 && AppearanceCount_Private[i_thread_num][pii_Edge.second]>0) { //Detect conflict ConflictedEdges_Private[i_thread_num].push_back(pii_Edge); ConflictCount_Private[i_thread_num][pii_Edge.first]++; ConflictCount_Private[i_thread_num][pii_Edge.second]++; continue; } AppearanceCount_Private[i_thread_num][pii_Edge.first]++; AppearanceCount_Private[i_thread_num][pii_Edge.second]++; //*/ } /* //Remove conflict edges out of this ColorCombination for(int j=vi_ConflictedEdgeIndices.size()-1; j>=0;j--) { if(vi_ConflictedEdgeIndices[j] != (vpii_EdgesPtr->size()-1)) { (*vpii_EdgesPtr)[ vi_ConflictedEdgeIndices[j] ] = (*vpii_EdgesPtr)[ vpii_EdgesPtr->size()-1 ]; } vpii_EdgesPtr->pop_back(); } //Make each vertex remember this combination and whether or not it is a leaf in this combination int i_TheOtherColor = 0; pair pii_pair; mii_iter = PotentialHub_Private[i_thread_num].begin(); for(;mii_iter != PotentialHub_Private[i_thread_num].end(); mii_iter++) { if(m_vi_VertexColors[mii_iter->first] == pii_ColorCombination.first) i_TheOtherColor = pii_ColorCombination.second; else i_TheOtherColor = pii_ColorCombination.first; pii_pair.first = i_TheOtherColor; pii_pair.second = mii_iter->second; // if pii_pair.second < -1, then mii_iter->first is a leaf and its hub can be calculated as [-(pii_pair.second+2)] Vertex2ColorCombination_Private[i_thread_num][ mii_iter->first ].push_back(pii_pair); } //*/ } } return(_TRUE); } int GraphColoring::PrintColorCombination(map< pair, Colors2Edge_Value , lt_pii>* Colors2Edge_Private, int i_MaxNumThreads, pair pii_ColorCombination, int i_MaxElementsOfCombination) { cout<<"PrintColorCombination "<, Colors2Edge_Value , lt_pii>::iterator itr = Colors2Edge_Private[i].find(pii_ColorCombination); if(itr != Colors2Edge_Private[i].end()) { i_TotalElementsOfCombination += (itr->second.value).size(); } } for(int i=0; i< i_MaxNumThreads; i++) { map< pair, Colors2Edge_Value , lt_pii>::iterator itr = Colors2Edge_Private[i].find(pii_ColorCombination); if(itr != Colors2Edge_Private[i].end()) { cout<<"(thread "< > *Edges = &(itr->second.value); for(int ii=0; ii< (*Edges).size(); ii++) { cout<<(*Edges)[ii].first<<"-"<<(*Edges)[ii].second<<"; "; i_ElementCount++; if( i_ElementCount >= i_MaxElementsOfCombination) { cout<<" MAX #="<, bool, lt_pii > mpiib_VisitedColorCombination; for(int i=0; i< i_MaxNumThreads; i++) { map< pair, Colors2Edge_Value , lt_pii>::iterator itr = Colors2Edge_Private[i].begin(); for(; itr != Colors2Edge_Private[i].end(); itr++) { if(mpiib_VisitedColorCombination.find(itr->first) == mpiib_VisitedColorCombination.end()) { mpiib_VisitedColorCombination[itr->first] = true; cout<<"Combination "<first.first<<"-"<first.second<<": "<, Colors2Edge_Value , lt_pii>::iterator itr2 = Colors2Edge_Private[ii].find(itr->first); if(itr2 != Colors2Edge_Private[ii].end()) { cout<<"(thread "< > *Edges = &(itr2->second.value); for(int iii=0; iii< (*Edges).size(); iii++) { cout<<(*Edges)[iii].first<<"-"<<(*Edges)[iii].second<<"; "; i_ElementCount++; if( i_ElementCount >= i_MaxElementsOfCombination) break; } if( i_ElementCount >= i_MaxElementsOfCombination) break; } } cout<= i_MaxNumOfCombination) break; } if(mpiib_VisitedColorCombination.size() >= i_MaxNumOfCombination) break; } cout< > > *Vertex2ColorCombination_Private) { int i_VertexCount = m_vi_Vertices.size() - 1; map< int, vector< pair > >::iterator itr; cout<<"PrintVertex2ColorCombination"<second)[iii].first<< ";"; if( (itr->second)[iii].second > -1) { cout<<" NO hub, connect to "<<(itr->second)[iii].second; } else if ( (itr->second)[iii].second == -1) { cout<<" HUB"; } else { // (*itr)[iii].second < -1 cout<<" LEAF of hub "<<-((itr->second)[iii].second+2); } cout<<")"< > *ConflictedEdges_Private, int i_MaxNumThreads) { cout<<"PrintConflictEdges"< &ConflictCount) { cout<<"PrintConflictCount"< > *ConflictedEdges_Private, vector &ConflictCount) { #if COLPACK_DEBUG_LEVEL > 100 fout<<"PickVerticesToBeRecolored ..."< pii_Edge = ConflictedEdges_Private[i][j]; //before decide which end, remember to check if one end's color is already removed. If this is the case, just skip to the next conflicted edge. if(m_vi_VertexColors[pii_Edge.first] == _UNKNOWN || m_vi_VertexColors[pii_Edge.second] == _UNKNOWN ) continue; if(ConflictCount[pii_Edge.first] > ConflictCount[pii_Edge.second]) { m_vi_VertexColors[pii_Edge.first] = _UNKNOWN; #if COLPACK_DEBUG_LEVEL > 100 cout<<"\t Pick "<< pii_Edge.first < 100 cout<<"\t Pick "<< pii_Edge.second < 100 cout<<"\t Pick "<< pii_Edge.first < 100 cout<<"\t Pick "<< pii_Edge.second < pii_Edge = ConflictedEdges_Private[i][j]; if(ConflictCount[pii_Edge.first] > ConflictCount[pii_Edge.second]) { ip_VerticesToBeRecolored[pii_Edge.first] = true; } else if (ConflictCount[pii_Edge.first] < ConflictCount[pii_Edge.second]) { ip_VerticesToBeRecolored[pii_Edge.second] = true; } else { //ConflictCount[pii_Edge.first] == ConflictCount[pii_Edge.second] if(pii_Edge.first < pii_Edge.second) { ip_VerticesToBeRecolored[pii_Edge.first] = true; } else { ip_VerticesToBeRecolored[pii_Edge.second] = true; } } } } int i_TotalVertexToBeRecolored=0; #ifdef _OPENMP #pragma omp parallel for schedule(static,50) default(none) shared(i_VertexCount, ip_VerticesToBeRecolored) reduction(+:i_TotalVertexToBeRecolored) #endif for(int i=0; i > > *Vertex2ColorCombination_Private, vector< map > *Vertex2ColorCombination) { int i_VertexCount = m_vi_Vertices.size() - 1; (*Vertex2ColorCombination).resize(i_VertexCount); // Build Vertex2ColorCombination #ifdef _OPENMP #pragma omp parallel for default(none) shared(i_VertexCount, Vertex2ColorCombination_Private, Vertex2ColorCombination, i_MaxNumThreads) #endif for(int i=0; i > >::iterator iter; for(int ii=0; ii >* vpii_Ptr = & (iter->second); for(int iii=0; iii< vpii_Ptr->size(); iii++) { (*Vertex2ColorCombination)[i][(*vpii_Ptr)[iii].first] = (*vpii_Ptr)[iii].second; } } } } // Deallocate memory for Vertex2ColorCombination_Private for(int i=0; i* D1Colors, int i_thread_num) { cout<<"PrintD1Colors"<::iterator mib_itr = D1Colors[i_thread_num].begin(); // Note: Theoratically, the locks should have been released in the reverse order.Hope this won't cause any problem for(;mib_itr != D1Colors[i_thread_num].end(); mib_itr++) { cout<first<<"; count "<second<* mip_ForbiddenColors,int i_thread_num) { map< int, bool >::iterator itr = mip_ForbiddenColors[i_thread_num].begin(); cout<<"PrintForbiddenColors for thread "<first<<", "; } cout< > *graph) { cout<<"PrintSubGraph (0-based indexing)"< >::iterator itr = graph->begin(); for(; itr != graph->end(); itr++) { cout<<"\t v "<first<<": "; map::iterator itr2 = (itr->second).begin(); for(; itr2 != (itr->second).end(); itr2++) { cout<<" v "<first<<";"; } cout< (int)m_vi_Vertices.size() - 2) { cout<<"Illegal request. VertexIndex is too large. VertexIndex > m_vi_Vertices.size() - 2"< pii_tmp; pii_tmp.first = v1; //.first is the vertexID pii_tmp.second = -1; // .second is the parent map mib_IncludedVertices; // Step *: Run a BFS to get all vertices within distance- of i_CenterVertex queue > Q; //cout<<"Push in v "<< pii_tmp.first<< " l "< > *graph, map *mib_Colors) { cout<<"BuildColorsSubGraph for colors: "<::iterator itr= (*mib_Colors).begin(); for(;itr != (*mib_Colors).end(); itr++) { cout<<"\t c "<first< > *graph, int i_CenterVertex, int distance, map *mib_FilterByColors) { cout<<"BuildSubGraph centered at v "< mib_IncludedVertices; pair pii_tmp; pii_tmp.first = i_CenterVertex; //.first is the vertexID pii_tmp.second = 0; // .second is the level/distance // Step *: Run a BFS to get all vertices within distance- of i_CenterVertex queue > Q; //cout<<"Push in v "<< pii_tmp.first<< " l "< mib_tmp; for(int i=0; i0 && (*mib_FilterByColors).find(m_vi_VertexColors[i])!=(*mib_FilterByColors).end() ) // filter by colors ) { for(int ii=m_vi_Vertices[i]; ii0 && (*mib_FilterByColors).find(m_vi_VertexColors[i_D1Neighbor])!=(*mib_FilterByColors).end() ) // filter by colors ){ if(mib_IncludedVertices.find(i_D1Neighbor) != mib_IncludedVertices.end()){ (*graph)[i][i_D1Neighbor] = true; } } } } } //PrintSubGraph(graph); //vector vi_VertexColors; //GetVertexColors(vi_VertexColors); //displayGraph(graph, &vi_VertexColors); //Pause(); cout<<"DONE"< > *graph, int i_CenterVertex, int distance, map *mib_FilterByColors) { cout<<"BuildConnectedSubGraph i_CenterVertex="< mib_IncludedVertices; pair pii_tmp; pii_tmp.first = i_CenterVertex; //.first is the vertexID pii_tmp.second = 0; // .second is the level/distance // Step *: Run a BFS to get all vertices within distance- of i_CenterVertex queue > Q; //cout<<"Push in v "<< pii_tmp.first<< " l "< mib_tmp; for(int i=0; i vi_VertexColors; //GetVertexColors(vi_VertexColors); //displayGraph(graph, &vi_VertexColors); //Pause(); cout<<"DONE"< > *vi_VertexAndColorAdded, int i_LastNEntries) { int i_MaxSize = vi_VertexAndColorAdded[0].size(); for(int i=1; ii_MaxSize) i_MaxSize=vi_VertexAndColorAdded[i].size(); } if(i_LastNEntries>i_MaxSize) i_LastNEntries=i_MaxSize; cout<<"PrintVertexAndColorAdded the last "<< i_LastNEntries<<" entries"<* mip_ForbiddenColors, map* D1Colors, vector< map > *Vertex2ColorCombination) { mip_ForbiddenColors[i_thread_num].clear(); D1Colors[i_thread_num].clear(); #if COLPACK_DEBUG_LEVEL > 10 //cout< 10 cout< make a function for this so I can improve latter * - if vertex with color appear once and is NOT a hub, forbid all of its hubs color */ // !!! could to be improved ??? for(int ii=m_vi_Vertices[i_CurrentVertex]; ii::iterator mii_iter = (*Vertex2ColorCombination)[D1Neighbor].begin(); // !!! could this read from the hash table cause problem if we don't lock it? if( m_vi_VertexColors[D1Neighbor] == _UNKNOWN ) { // Note: the part (m_vi_VertexColors[D1Neighbor] == _UNKNOWN) here is conservative because I assume that if another thread is working on this vertex, it could pick the color D1Colors[i_thread_num][m_vi_VertexColors[D1Neighbor]] and make the whole thing bad // !!! might be able to improve by checking and ?communitation with other threads and see if they works on the vertices around me for(int iii=m_vi_Vertices[D1Neighbor]; iii 1 ) { //forbid all colors that its D1 neighbors have for(; mii_iter != (*Vertex2ColorCombination)[D1Neighbor].end(); mii_iter++) { //mark mii_iter->first as forbidden mip_ForbiddenColors[i_thread_num][mii_iter->first] = true; } } else { // For any color combinations that D1Neighbor is NOT a hub (i.e. a leaf or a non-HUB), forbid the color of the hub (in this color combination) for(; mii_iter != (*Vertex2ColorCombination)[D1Neighbor].end(); mii_iter++) { if(mii_iter->second != -1) { // D1Neighbor is NOT a hub in the combination (m_vi_VertexColors[D1Neighbor], mii_iter->first) //mark mii_iter->first as forbidden mip_ForbiddenColors[i_thread_num][mii_iter->first] = true; } } } } return (_TRUE); } int GraphColoring::StarColoring_serial2() { if(CheckVertexColoring("STAR")) { return(_TRUE); } int i_MaxNumThreads = 1; int i_MaxColor; if(m_i_VertexColorCount>0) i_MaxColor = m_i_VertexColorCount; else i_MaxColor = 3; int i_VertexCount = m_vi_Vertices.size() - 1; m_vi_VertexColors.clear(); m_vi_VertexColors.resize((unsigned) i_VertexCount, _UNKNOWN); /* for(int i=0; i<=i_MaxColor;i++) { if(!omp_test_lock( vl_ColorLock[i] )) { cout<<"Fail to lock color "< vi_VerticesToBeColored; vector* vip_VerticesToBeRecolored_Private = new vector[i_MaxNumThreads]; map* mip_ForbiddenColors = new map[i_MaxNumThreads]; map* D1Colors = new map[i_MaxNumThreads]; vector< map > *Vertex2ColorCombination = new vector< map >; (*Vertex2ColorCombination).resize(i_VertexCount); //Populate (vi_VerticesToBeColored) for(int i=0 ; i< i_VertexCount; i++) { int i_thread_num; i_thread_num = 0; vip_VerticesToBeRecolored_Private[i_thread_num].push_back(m_vi_OrderedVertices[i]); } int* i_StartingIndex = new int[i_MaxNumThreads]; i_StartingIndex[0] = 0; for(int i=1; i < i_MaxNumThreads; i++) { i_StartingIndex[i] = i_StartingIndex[i-1]+vip_VerticesToBeRecolored_Private[i-1].size(); } vi_VerticesToBeColored.resize(i_StartingIndex[i_MaxNumThreads-1]+vip_VerticesToBeRecolored_Private[i_MaxNumThreads-1].size(),_UNKNOWN); for(int i=0 ; i< i_MaxNumThreads; i++) { for(int j=0; j0) { #if COLPACK_DEBUG_LEVEL == 0 i_LoopCount++; //cout<<"(loop "< 10 cout< 10 cout< 10 cout<::iterator mib_itr2 = D1Colors[i_thread_num].begin(); for(;mib_itr2 != D1Colors[i_thread_num].end(); mib_itr2++) { cout< make a function for this so I can improve latter * - if vertex with color appear once and is a LEAF, forbid all of its HUBs color. */ // !!! could to be improved ??? for(int ii=m_vi_Vertices[i_CurrentVertex]; iifirst<<" around v "<first="<first<<" mii_iter->second="<< mii_iter->second <second < -1) { // D1Neighbor is a leaf in the combination (m_vi_VertexColors[D1Neighbor], mii_iter->first) //mark mii_iter->first as forbidden mip_ForbiddenColors[i_thread_num][mii_iter->first] = true; // if(i_CurrentVertex==31) { // cout<<"\t Forbid color "<first<<" of v "<<-(mii_iter->second+2)< 10 cout<<"*After finish marking forbidden color"< i_MaxColor) { //we will need a new color i_MaxColor = i_PotentialColor; } // Now we have a color, i.e. i_PotentialColor m_vi_VertexColors[i_CurrentVertex] = i_PotentialColor; //cout<<"c "< *pii_ConflictColorCombination = new pair; int i_ConflictVertex = CheckStarColoring_OMP(1, pii_ConflictColorCombination); //PrintVertexAndColorAdded(i_MaxNumThreads ,vi_VertexAndColorAdded); //Pause(); // !! find the 2 vertices and find the distance between them if (i_ConflictVertex!=-1) { //PrintVertexAndColorAdded(i_MaxNumThreads ,vi_VertexAndColorAdded); cout<<"t"< > *graph = new map< int, map >; //BuildConnectedSubGraph(graph , i_CurrentVertex, 1); //vector vi_VertexColors; //GetVertexColors(vi_VertexColors); //displayGraph(graph, &vi_VertexColors, true, FDP); //delete graph; //graph = new map< int, map >; //BuildSubGraph(graph , i_CurrentVertex, 0); //displayGraph(graph, &vi_VertexColors, true, FDP); //delete graph; cout<<"i_ConflictVertex="<=0)cout<<" with color "<< m_vi_VertexColors[i_ConflictVertex]; cout< VerticiesWithConflictColors; for(int i=0; i 10 cout<1) { //i_CurrentVertex should be a hub (*Vertex2ColorCombination)[i_CurrentVertex][ m_vi_VertexColors[D1Neighbor] ] = -1; // mark i_CurrentVertex a hub of ( m_vi_VertexColors[i_CurrentVertex] , m_vi_VertexColors[D1Neighbor] ) combination (*Vertex2ColorCombination)[D1Neighbor][m_vi_VertexColors[i_CurrentVertex]] = -(i_CurrentVertex+2); // mark D1Neighbor a leaf of ( m_vi_VertexColors[i_CurrentVertex] , m_vi_VertexColors[D1Neighbor] ) combination } // D1Colors[i_thread_num][ m_vi_VertexColors[D1Neighbor] ] == 1 else if ((*Vertex2ColorCombination)[D1Neighbor].find(m_vi_VertexColors[i_CurrentVertex]) != (*Vertex2ColorCombination)[D1Neighbor].end() ) { int v2 = (*Vertex2ColorCombination)[D1Neighbor][m_vi_VertexColors[i_CurrentVertex]]; if(v2 != -1) { // D1Neighbor is currently connected to a vertice v2 with the same color as i_CurrentVertex (i.e. D1Neighbor and v2 formed a non-HUB) //cout<<"\t v2 "<::iterator mii_iter = (*Vertex2ColorCombination)[i].begin(); for(; mii_iter != (*Vertex2ColorCombination)[i].end(); mii_iter++) { if(mii_iter->second < -1) { // LEAF cout<<"\t is a LEAF of v "<<-(mii_iter->second+2)<<" c "<first<second == -1) { // HUB cout<<"\t is a HUB with c "<first<second<<" c "<first<<" (non-HUB)"< > *Vertex2ColorCombination) { cout<<"PrintVertex2ColorCombination_raw()"<::iterator mii_iter = (*Vertex2ColorCombination)[i].begin(); for(; mii_iter != (*Vertex2ColorCombination)[i].end(); mii_iter++) { cout<<"\t Vertex2ColorCombination["<< i <<"][] "<second<<" c "<first< & vi_VerticesToBeRecolored) { int i, j, k; int i_StarID, i_VertexOne, i_VertexTwo; int i_VertexCount = m_vi_Vertices.size() - 1; int i_EdgeCount = (signed) m_vi_Edges.size(); vector vi_EdgeStarMap; // map an edge to a star. For example vi_EdgeStarMap[edge#1] = star#5 vector vi_StarHubMap; // map a star to its hub (the center of 2-color star. For example vi_StarHubMap[star#5] = edge#7 map< int, map > mimi2_VertexEdgeMap; // map 2 vertices to its edge ID. Note that for mimi2_VertexEdgeMap[vertex#1][vertex#2]= edge#1, the id of vertex#1 must always less than vertex#2 vector vi_FirstSeenOne, vi_FirstSeenTwo; vi_FirstSeenOne.clear(); vi_FirstSeenOne.resize((unsigned) i_VertexCount, _UNKNOWN); vi_FirstSeenTwo.clear(); vi_FirstSeenTwo.resize((unsigned) i_VertexCount, _UNKNOWN); vi_EdgeStarMap.clear(); vi_EdgeStarMap.resize((unsigned) i_EdgeCount/2, _UNKNOWN); vi_StarHubMap.clear(); vi_StarHubMap.resize((unsigned) i_EdgeCount/2, _UNKNOWN); // label each edge //populate mimi2_VertexEdgeMap[][] and vi_EdgeStarMap[] k=0; for(i=0; i& vi_EdgeStarMap, vector& vi_StarHubMap, map< int, map >& mimi2_VertexEdgeMap) { int i, j; int i_VertexCount = m_vi_Vertices.size() - 1; for(i=0; i vi_MemberEdges; vector vi_CandidateColors; vector vi_EdgeStarMap; // map an edge to a star. For example vi_EdgeStarMap[edge#1] = star#5 vector vi_StarHubMap; // map a star to its hub (the center of 2-color star. For example vi_StarHubMap[star#5] = edge#7 vector vi_FirstTreated; // ??? what these structures are for? /* The two vectors vi_FirstSeenOne, vi_FirstSeenTwo are indexed by the color ID * vi_FirstSeenOne[color a] = vertex 1 : means that color a is first seen when we are processing vertex 1 (as colored vertex w) * vi_FirstSeenTwo[color a] = vertex 2 : means that vertex 2 (connected to vertex 1) has color a and this is first seen when we were processing vertex 1 * */ vector vi_FirstSeenOne, vi_FirstSeenTwo; // ??? what these structures are for? map< int, map > mimi2_VertexEdgeMap; // map 2 vertices to its edge ID. Note that for mimi2_VertexEdgeMap[vertex#1][vertex#2]= edge#1, the id of vertex#1 must always less than vertex#2 m_i_VertexColorCount = _UNKNOWN; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); i_EdgeCount = (signed) m_vi_Edges.size(); vi_EdgeStarMap.clear(); vi_EdgeStarMap.resize((unsigned) i_EdgeCount/2, _UNKNOWN); vi_StarHubMap.clear(); vi_StarHubMap.resize((unsigned) i_EdgeCount/2, _UNKNOWN); m_vi_VertexColors.clear(); m_vi_VertexColors.resize((unsigned) i_VertexCount, _UNKNOWN); vi_CandidateColors.clear(); vi_CandidateColors.resize((unsigned) i_VertexCount, _UNKNOWN); vi_FirstSeenOne.clear(); vi_FirstSeenOne.resize((unsigned) i_VertexCount, _UNKNOWN); vi_FirstSeenTwo.clear(); vi_FirstSeenTwo.resize((unsigned) i_VertexCount, _UNKNOWN); // vi_FirstTreated.clear(); // vi_FirstTreated.resize((unsigned) i_EdgeCount, _UNKNOWN); vi_FirstTreated.clear(); vi_FirstTreated.resize((unsigned) i_VertexCount, _UNKNOWN); k = _FALSE; // label each edge //populate mimi2_VertexEdgeMap[][] and vi_EdgeStarMap[] for(i=0; i vi_Hubs; vi_Hubs.resize((unsigned) i_EdgeCount/2, _FALSE); m_i_ColoringUnits = _FALSE; for(i=0; i= vi_Hubs.size() ) { cout<<"Memory violation vi_StarHubMap[i] = "< vi_Hubs; vi_Hubs.resize((unsigned) i_EdgeCount/2, _FALSE); m_i_ColoringUnits = _FALSE; for(i=0; i > &ListOfConflicts) { int i, j, k, l; int i_VertexCount, i_EdgeCount; int i_FirstColor, i_SecondColor, i_ThirdColor, i_FourthColor; int i_ViolationCount; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); i_EdgeCount = (signed) m_vi_Edges.size(); i_ViolationCount = _FALSE; for(i=0; i violation; violation.push_back(i);violation.push_back(m_vi_Edges[j]); ListOfConflicts.push_back(violation); continue; } for(k=m_vi_Vertices[m_vi_Edges[j]]; k violation; violation.push_back(m_vi_Edges[j]);violation.push_back(m_vi_Edges[k]); ListOfConflicts.push_back(violation); continue; } if(i_ThirdColor != i_FirstColor) { continue; } if(i_ThirdColor == i_FirstColor) { for(l=m_vi_Vertices[m_vi_Edges[k]]; l violation; violation.push_back(m_vi_Edges[k]);violation.push_back(m_vi_Edges[l]); ListOfConflicts.push_back(violation); } if(i_FourthColor == i_SecondColor) { i_ViolationCount++; //cout<<"Violation "< violation; violation.push_back(i);violation.push_back(m_vi_Edges[j]);violation.push_back(m_vi_Edges[k]);violation.push_back(m_vi_Edges[l]); ListOfConflicts.push_back(violation); continue; } } } } } } /* if(i_ViolationCount) { cout< vi_CandidateColors; vector vi_FirstSeenOne, vi_FirstSeenTwo, vi_FirstSeenThree; vector vi_FirstVisitedOne, vi_FirstVisitedTwo; #if DISJOINT_SETS == _FALSE int l; int i_MemberCount; int i_SmallerSetID, i_BiggerSetID; vector vi_DisjointSets; vector vi_MemberEdges; vector vi_EdgeSetMap; vector< vector > v2i_SetEdgeMap; #endif #if DISJOINT_SETS == _TRUE int i_SetOneID, i_SetTwoID; #endif i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); k = _FALSE; m_mimi2_VertexEdgeMap.clear(); for(i=0; i vi_CandidateColors; vector vi_FirstSeenOne, vi_FirstSeenTwo, vi_FirstSeenThree; vector vi_FirstVisitedOne, vi_FirstVisitedTwo; //m_mimi2_VertexEdgeMap is populated and used in this function; #if DISJOINT_SETS == _FALSE int l; int i_MemberCount; int i_SmallerSetID, i_BiggerSetID; vector vi_DisjointSets; vector vi_MemberEdges; vector vi_EdgeSetMap; vector< vector > v2i_SetEdgeMap; #endif #if DISJOINT_SETS == _TRUE int i_SetOneID, i_SetTwoID; //DisjointSets ds_DisjointSets; #endif if(m_s_VertexColoringVariant.compare("ALL") != 0) { m_s_VertexColoringVariant = "ACYCLIC"; } i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); k=_FALSE; //populate m_mimi2_VertexEdgeMap //Basically assign a number (k = 1, 2, 3 ...) for each edge of the graph m_mimi2_VertexEdgeMap.clear(); for(i=0; i & vi_Sets, map< int, vector > & mivi_VertexSets) { //#define DEBUG 1462 if(CheckVertexColoring("ACYCLIC")) { return(_TRUE); } int i, j, k; int i_VertexCount, i_EdgeCount; int i_AdjacentEdgeID, i_EdgeID, i_SetID; int i_PresentVertex; vector vi_CandidateColors; vector vi_FirstSeenOne, vi_FirstSeenTwo, vi_FirstSeenThree; vector vi_FirstVisitedOne, vi_FirstVisitedTwo; map< int, map > mimi2_VertexEdgeMap; #if DISJOINT_SETS == _FALSE int l; int i_MemberCount; int i_SmallerSetID, i_BiggerSetID; vector vi_DisjointSets; vector vi_MemberEdges; vector vi_EdgeSetMap; vector< vector > v2i_SetEdgeMap; #endif #if DISJOINT_SETS == _TRUE int i_SetOneID, i_SetTwoID; //DisjointSets ds_DisjointSets; #endif if(m_s_VertexColoringVariant.compare("ALL") != 0) { m_s_VertexColoringVariant = "ACYCLIC"; } i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); k=_FALSE; //populate mimi2_VertexEdgeMap //Basically assign a number (k = 1, 2, 3 ...) for each edge of the graph mimi2_VertexEdgeMap.clear(); for(i=0; i create new set { vi_Sets.push_back(i_SetID); } mivi_VertexSets[i_SetID].push_back(i); mivi_VertexSets[i_SetID].push_back(m_vi_Edges[j]); } } } //cout<<"*Am I here?"< vi_TouchedVertices; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); i_ViolationCount = _FALSE; for(i=0; i vi_VertexHierarchy; vector< vector > v2i_VertexAdjacency; i_VertexCount = (signed) m_vi_OrderedVertices.size(); vi_VertexHierarchy.clear(); vi_VertexHierarchy.resize((unsigned) i_VertexCount); v2i_VertexAdjacency.clear(); v2i_VertexAdjacency.resize((unsigned) i_VertexCount); for(i=0; i vi_VertexHierarchy[i_PresentVertex]) && (vi_VertexHierarchy[m_vi_Edges[j]] > vi_VertexHierarchy[m_vi_Edges[k]])) { _FOUND = _FALSE; for(l=m_vi_Vertices[m_vi_Edges[k]]; l vi_CandidateColors; vector vi_VertexHierarchy; i_VertexCount = (signed) m_vi_OrderedVertices.size(); vi_VertexHierarchy.clear(); vi_VertexHierarchy.resize((unsigned) i_VertexCount); for(i=0; i vi_VertexHierarchy[i_PresentVertex]) && (vi_VertexHierarchy[m_vi_Edges[j]] > vi_VertexHierarchy[m_vi_Edges[k]])) { vi_CandidateColors[m_vi_VertexColors[m_vi_Edges[k]]] = i_PresentVertex; } } } for(j=0; j &output) { output = (m_vi_VertexColors); } //Public Function 1470 int GraphColoring::GetHubCount() { if(CheckVertexColoring("STAR")) { return(m_i_ColoringUnits); } else { return(_UNKNOWN); } } //Public Function 1471 int GraphColoring::GetSetCount() { if(CheckVertexColoring("ACYCLIC")) { return(m_i_ColoringUnits); } else { return(_UNKNOWN); } } //Public Function 1472 double GraphColoring::GetVertexColoringTime() { return(m_d_ColoringTime); } //Public Function 1473 double GraphColoring::GetVertexColoringCheckingTime() { return(m_d_CheckingTime); } //Public Function 1474 int GraphColoring::PrintVertexColors() { int i; int i_VertexCount; string _SLASH("/"); StringTokenizer SlashTokenizer(m_s_InputFile, _SLASH); m_s_InputFile = SlashTokenizer.GetLastToken(); i_VertexCount = (signed) m_vi_VertexColors.size(); cout<. ************************************************************************************/ #ifndef GRAPHCOLORING_H #define GRAPHCOLORING_H using namespace std; namespace ColPack { /** @ingroup group1 * @brief class GraphColoring in @link group1@endlink. Graph coloring is an assignment of consecutive integral numbers (each representing a color) to vertices, edges or faces or a combination of two or more of these objects of a graph such that it satisfes one or more constraints. The present version of ColPack provides methods for vertex coloring only. The minimum number of vertex colors required to color a graph is known as the chromatic number of the graph. The problem of finding the chromatic number for even a planar graph is NP-hard. ColPack features some of the most efficient approximation algorithms available to date for some of the vertex coloring problems. */ class GraphColoring : public GraphOrdering { public: //DOCUMENTED ///Return the Seed matrix based on existing coloring. This Seed matrix is managed and freed by ColPack /** Precondition: - the Graph has been colored Postcondition: - Size of the returned matrix is (*ip1_SeedRowCount) rows x (*ip1_SeedColumnCount) columns. (*ip1_SeedRowCount) == num of columns of the original matrix == GetVertexCount() (*ip1_SeedColumnCount) == num of colors used to color vertices == GetVertexColorCount(). Notes: - This Seed matrix is managed and automatically freed by ColPack when the Graph object is deleted. Therefore, the user should NOT attempt to free the Seed matrix again. */ double** GetSeedMatrix(int* ip1_SeedRowCount, int* ip1_SeedColumnCount); /// Same as GetSeedMatrix(), except that this Seed matrix is NOT managed by ColPack /** Notes: - This Seed matrix is NOT managed by ColPack. Therefore, the user should free the Seed matrix manually when the matrix is no longer needed. */ double** GetSeedMatrix_unmanaged(int* ip1_SeedRowCount, int* ip1_SeedColumnCount); ///Quick check to see if DistanceTwoColoring() ran correctly /** Return value: - 1 when this function detects that DistanceTwoColoring() must have run INcorrectly. - 0 otherwise IMPORTANT: This is the quick check so if CheckQuickDistanceTwoColoring() return 1, then DistanceTwoColoring() definitely ran INcorrectly. However, when CheckQuickDistanceTwoColoring() return 0, it doesn't mean that DistanceTwoColoring() ran correctly (it may, it may not). To be 100% sure, use CheckDistanceTwoColoring() Precondition: DistanceTwoColoring() has been run. Parameter: int Verbose - If Verbose == 0, this function only check and see if m_i_MaximumVertexDegree <= m_i_VertexColorCount + 1. - If Verbose == 1, this function will print out the vertex with m_i_MaximumVertexDegree where the error can be detected. - If Verbose == 2, this function will print out all the errors (violations) and then return. Algorithm: - See if m_i_MaximumVertexDegree <= STEP_UP(m_i_VertexColorCount). If DistanceTwoColoring() ran correctly, this should be the case - If m_i_MaximumVertexDegree > STEP_UP(m_i_VertexColorCount), DistanceTwoColoring() ran INcorrectly and this function will go ahead and find the 2 vertices within distance-2 have the same color */ int CheckQuickDistanceTwoColoring(int Verbose = 0); /// Check to see if DistanceTwoColoring() ran correctly /** 100% accurate but slow. For a quick check, use CheckQuickDistanceTwoColoring(). Return value: - 1 when this function detects that DistanceTwoColoring() must have run INcorrectly. - 0 means DistanceTwoColoring() must have run correctly. Precondition: DistanceTwoColoring() has been run. Parameter: int Verbose - If Verbose == 0, this function will silently return after the first error is detected. - If Verbose == 1, this function will print out the error message and return after the first error is detected. - If Verbose == 2, this function will print out all the errors and then return. */ int CheckDistanceTwoColoring(int Verbose = 0); int CalculateVertexColorClasses(); private: int m_i_ColoringUnits; //Private Function 1401 int FindCycle(int, int, int, int, vector &, vector &, vector &); //Private Function 1402 int UpdateSet(int, int, int, map< int, map > &, vector &, vector &, vector &); //Private Function 1403 int SearchDepthFirst(int, int, int, vector &); //Private Function 1404 int CheckVertexColoring(string s_GraphColoringVariant); protected: int m_i_VertexColorCount; int m_i_LargestColorClass; int m_i_SmallestColorClass; int m_i_LargestColorClassSize; int m_i_SmallestColorClassSize; double m_d_AverageColorClassSize; double m_d_ColoringTime; double m_d_CheckingTime; string m_s_VertexColoringVariant; vector m_vi_VertexColors; vector m_vi_VertexColorFrequency; bool seed_available; int i_seed_rowCount; double** dp2_Seed; void Seed_init(); void Seed_reset(); public: void SetStringVertexColoringVariant(string s); void SetVertexColorCount(int i_VertexColorCount); //Public Constructor 1451 GraphColoring(); //Public Destructor 1452 ~GraphColoring(); //Virtual Function 1453 virtual void Clear(); void ClearColoringONLY(); //Public Function 1454 int DistanceOneColoring(); //Public Function 1455 int DistanceTwoColoring(); //Public Function 1456 int NaiveStarColoring(); //Public Function 1457 /// Star Coloring with an additional restriction /** * The additional restriction: When we try to decide the color of a vertex: * - If D1 neighbor has color id > D2 neighbor's color id, then that D2 neighbor's color is forbidden (the current vertex cannot use that color) * - Else, we can just reuse the color of that D2 neighbor */ int RestrictedStarColoring(); //Public Function 1458 /* * Related paper: A. Gebremedhin, A. Tarafdar, F. Manne and A. Pothen, New Acyclic and Star Coloring Algorithms with Applications to Hessian Computation, SIAM Journal on Scientific Computing, Vol 29, No 3, pp 1042--1072, 2007. * http://www.cs.purdue.edu/homes/agebreme/publications/SISC29-2-2009.pdf * ?This is the algorithm 4.1 in the above paper */ int StarColoring_serial(); int StarColoring_serial2(); // Essentially based on StarColoring_OMP() v1 // TO BE IMPLEMENTED int StarColoring(); /// Build the collection of 2-color star from the coloring result /** * NOTE: At this point, this routine will not work correctly if there are conflicts */ int BuildStarCollection(vector & vi_VerticesToBeRecolored); int PrintStarCollection(vector& vi_EdgeStarMap, vector& vi_StarHubMap, map< int, map >& mimi2_VertexEdgeMap); struct lt_pii { bool operator()(const pair pii_ColorCombination1, const pair pii_ColorCombination2) const { if(pii_ColorCombination1.first < pii_ColorCombination2.first) { return true; } else if (pii_ColorCombination1.first > pii_ColorCombination2.first) { return false; } // pii_ColorCombination1.first == pii_ColorCombination2.first return (pii_ColorCombination1.second < pii_ColorCombination2.second); } }; struct Colors2Edge_Value { Colors2Edge_Value() { visited=false; } vector< pair > value; bool visited; }; /// Build the collection of 2-color star from the coloring result /** * This function also helps us identify a list of vertices need to be recolored if conlict is detected * If vi_VerticesToBeRecolored.size() == 0, then the coloring is a valid star coloring. * The algorithm is done in parallel */ int DetectConflictInColorCombination(int i_MaxNumThreads, int i_thread_num, pair pii_ColorCombination, map< pair, Colors2Edge_Value , lt_pii>* Colors2Edge_Private, map< int, vector< pair > > *Vertex2ColorCombination_Private, map< int, int> * PotentialHub_Private, vector< pair >* ConflictedEdges_Private, vector* ConflictCount_Private); /// This function assume that there is no conflicts in the color assignment int BuildStarFromColorCombination(int i_MaxNumThreads, int i_thread_num, pair pii_ColorCombination, map< pair, Colors2Edge_Value , lt_pii>* Colors2Edge_Private, map< int, vector< pair > > *Vertex2ColorCombination_Private, map< int, int> * PotentialHub_Private); ofstream fout; // !!! int i_ProcessedEdgeCount; // !!! /// Build Vertex2ColorCombination from Vertex2ColorCombination_Private /** * This process is done in parallel * After Vertex2ColorCombination is built, Vertex2ColorCombination_Private will be deallocated */ int BuildVertex2ColorCombination(int i_MaxNumThreads, map< int, vector< pair > > *Vertex2ColorCombination_Private, vector< map > *Vertex2ColorCombination); /* * if(i_Mode==1) : stop at the first failure * else if(i_Mode==0): pause but then continue * * Return values: * - >= 0: Fail. the vertex that causes conflict as this routine progress. Note: this may not be the latest-added vertex that cause coloring conflict in the graph * - -2: Fail. 2 potential hub are connected * - -1: Pass. * * If pii_ConflictColorCombination is provided (i.e. pii_ConflictColorCombination!=NULL) and this Check fail, pii_ConflictColorCombination will contain the 2 problematic colors */ int CheckStarColoring_OMP(int i_Mode, pair *pii_ConflictColorCombination); int BuildStarFromColorCombination_forChecking(int i_Mode, int i_MaxNumThreads, int i_thread_num, pair pii_ColorCombination, map< pair, Colors2Edge_Value , lt_pii>* Colors2Edge_Private, map< int, int> * PotentialHub_Private); int BuildForbiddenColors(int i_MaxNumThreads, int i_thread_num, int i_CurrentVertex, map* mip_ForbiddenColors, map* D1Colors, vector< map > *Vertex2ColorCombination); int PrintVertex2ColorCombination (vector< map > *Vertex2ColorCombination); int PrintVertex2ColorCombination_raw (vector< map > *Vertex2ColorCombination); int PrintVertexAndColorAdded(int i_MaxNumThreads, vector< pair > *vi_VertexAndColorAdded, int i_LastNEntries = 999999999); int PrintForbiddenColors(map* mip_ForbiddenColors,int i_thread_num); int PickVerticesToBeRecolored(int i_MaxNumThreads, vector< pair > *ConflictedEdges_Private, vector &ConflictCount); int PrintAllColorCombination(map< pair, Colors2Edge_Value , lt_pii>* Colors2Edge_Private, int i_MaxNumThreads, int i_MaxNumOfCombination=1000000, int i_MaxElementsOfCombination=100000); int PrintColorCombination(map< pair, Colors2Edge_Value , lt_pii>* Colors2Edge_Private, int i_MaxNumThreads, pair pii_ColorCombination, int i_MaxElementsOfCombination=100000); int PrintPotentialHub(map< int, int> *PotentialHub_Private, int i_thread_num, pair pii_ColorCombination); int PrintConflictEdges(vector< pair > *ConflictedEdges_Private, int i_MaxNumThreads); int PrintConflictCount(vector &ConflictCount); int PrintVertex2ColorCombination(int i_MaxNumThreads, map< int, vector< pair > > *Vertex2ColorCombination_Private); int PrintD1Colors(map* D1Colors, int i_thread_num); int PrintVertexColorCombination(map * VertexColorCombination); /// Note: FDP and CIRCO are the 2 good filters to display this subgraph /** Sample code: map< int, map > *graph = new map< int, map >; map *mib_FilterByColors = new map; (*mib_FilterByColors)[m_vi_VertexColors[i_CurrentVertex]]=true; (*mib_FilterByColors)[color2]=true; (*mib_FilterByColors)[color3]=true; BuildSubGraph(graph, i_CurrentVertex, 2, mib_FilterByColors); vector vi_VertexColors; GetVertexColors(vi_VertexColors); displayGraph(graph, &vi_VertexColors, true, FDP); delete graph; */ int BuildSubGraph(map< int, map > *graph, int i_CenterVertex, int distance=1, map *mib_FilterByColors=NULL); /** Sample code: (see function int BuildSubGraph() ) */ int BuildConnectedSubGraph(map< int, map > *graph, int i_CenterVertex, int distance=1, map *mib_FilterByColors=NULL); /** Sample code: map< int, map > *graph = new map< int, map >; map *mib_Colors = new map; (*mib_Colors)[m_vi_VertexColors[i_CurrentVertex]]=true; (*mib_Colors)[color2]=true; (*mib_Colors)[color3]=true; BuildSubGraph(graph, mib_Colors); vector vi_VertexColors; GetVertexColors(vi_VertexColors); displayGraph(graph, &vi_VertexColors, true, FDP); delete graph; */ int BuildColorsSubGraph(map< int, map > *graph, map *mib_Colors); int PrintSubGraph(map< int, map > *graph); int PrintVertexD1NeighborAndColor(int VertexIndex, int excludedVertex=-1); int FindDistance(int v1, int v2); //Public Function 1459 int StarColoring(vector &, vector &, map< int, map > &); //Public Function 1460 int CheckStarColoring(); int GetStarColoringConflicts(vector > &ListOfConflicts); //Public Function 1461 /** Note: This function can not be used for recovery! */ int AcyclicColoring(); //Public Function 1462 /** Note: Originally created for Hessian Indirect Recovery */ int AcyclicColoring(vector &, map< int, vector > &); /** Note: Currently used for Hessian Indirect Recovery */ int AcyclicColoring_ForIndirectRecovery(); //Public Function 1463 int CheckAcyclicColoring(); //Public Function 1464 int TriangularColoring(); //Public Function 1465 int ModifiedTriangularColoring(); //Public Function 1466 int CheckTriangularColoring(); //Public Function 1467 string GetVertexColoringVariant(); void SetVertexColoringVariant(string s_VertexColoringVariant); //Public Function 1468 int GetVertexColorCount(); //Public Function 1469 void GetVertexColors(vector &output); vector * GetVertexColorsPtr(){ return &m_vi_VertexColors; } //Public Function 1470 int GetHubCount(); //Public Function 1471 int GetSetCount(); //Public Function 1472 double GetVertexColoringTime(); //Public Function 1473 double GetVertexColoringCheckingTime(); //Public Function 1474 int PrintVertexColors(); //Public Function 1475 int FileVertexColors(); //Public Function 1476 int PrintVertexColoringMetrics(); //Public Function 1477 int FileVertexColoringMetrics(); //Public Function 1478 void PrintVertexColorClasses(); }; } #endif ColPack-1.0.10/GraphColoring/GraphColoringInterface.cpp000066400000000000000000000337051266356121500227450ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { GraphColoringInterface::GraphColoringInterface(int i_type, ...) { //cout<<"IN GraphColoringInterface(int i_type, ...)"< &output) { GraphOrdering::GetOrderedVertices(output); } double** GraphColoringInterface::GetSeedMatrix(int* ip1_SeedRowCount, int* ip1_SeedColumnCount) { return GraphColoring::GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); } //Public Destructor 1602 GraphColoringInterface::~GraphColoringInterface() { Clear(); Seed_reset(); } //Virtual Function 1603 void GraphColoringInterface::Clear() { GraphColoring::Clear(); return; } //Public Function 1604 int GraphColoringInterface::DistanceOneColoring(string s_OrderingVariant) { m_T_Timer.Start(); int i_OrderingStatus = OrderVertices(s_OrderingVariant); m_T_Timer.Stop(); m_d_OrderingTime = m_T_Timer.GetWallTime(); if(i_OrderingStatus != _TRUE) { cerr< &vi_Vertices, vector &vi_Edges , map< int, map< int, int> > &mimi2_VertexEdgeMap) { cout< > &vli_GroupedInducedVertexDegrees) { int k; list::iterator lit_ListIterator; cout<. ************************************************************************************/ #ifndef GRAPHCOLORINGINTERFACE_H #define GRAPHCOLORINGINTERFACE_H using namespace std; namespace ColPack { /** @ingroup group1 * @brief class GraphColoringInterface in @link group1@endlink. */ class GraphColoringInterface : public GraphColoring { public: //DOCUMENTED /// Read graph structure and color the adjacency graph /** This function will: - 0. Create initial GraphColoringInterface object - 1. Create the adjacency graph based on the graph structure specified by the input source - 2. Order the vertices based on the requested Ordering Method (s_OrderingVariant) - 3. Color the graph based on the requested Coloring Method (s_ColoringVariant) - Ordering Time and Coloring Time will be recorded. Structure of this variadic function's parameters: GraphColoringInterface(int i_type, [2 or more parameters for input source depending on the value of i_type], [char* s_OrderingVariant], [char* s_ColoringVariant]). Here are some examples: - Just create the GraphColoringInterface object: GraphColoringInterface(SRC_WAIT); - Just get the input from file without ordering and coloring: GraphColoringInterface(SRC_FILE, s_InputFile.c_str() ,"AUTO_DETECTED"); - Get input from ADOLC and color the graph: GraphColoringInterface(SRC_MEM_ADOLC,uip2_SparsityPattern, i_rowCount); About input parameters: - int i_type: specified the input source. i_type can be either: - -1 (SRC_WAIT): only step 0 will be done. - 0 (SRC_FILE): The graph structure will be read from file. The next 2 parameters are: - char* fileName: name of the input file for a symmetric matrix. If the full path is not given, the file is assumed to be in the current directory - char* fileType can be either: - "AUTO_DETECTED" or "". ColPack will decide the format of the file based on the file extension: - ".mtx": MatrixMarket format - ".hb", or any combination of ".": HarwellBoeing format - ".graph": MeTiS format - If the above extensions are not found, MatrixMarket format will be assumed. - "MM" for MatrixMarket format (http://math.nist.gov/MatrixMarket/formats.html#MMformat). Notes: - ColPack only accepts MatrixMarket coordinate format (NO array format) - List of arithmetic fields accepted by ColPack: real, pattern or integer - List of symmetry structures accepted by ColPack: general or symmetric - The first line of the input file should be similar to this: "%%MatrixMarket matrix coordinate real general" - "HB" for HarwellBoeing format (http://math.nist.gov/MatrixMarket/formats.html#hb) - "MeTiS" for MeTiS format (http://people.sc.fsu.edu/~burkardt/data/metis_graph/metis_graph.html) - 1 (SRC_MEM_ADOLC): The graph structure will be read from Row Compressed Structure (used by ADOLC). The next 2 parameters are: - unsigned int **uip2_SparsityPattern: The pattern of Hessian matrix stored in Row Compressed Format - int i_rowCount: number of rows in the Hessian matrix. Number of rows in uip2_SparsityPattern. - 2 (SRC_MEM_ADIC): TO BE IMPLEMENTED so that ColPack can interface with ADIC //*/ GraphColoringInterface(int i_type, ...); /// Color the adjacency graph based on the requested s_ColoringVariant and s_OrderingVariant /** This function will - 1. Order the vertices based on the requested Ordering Method (s_OrderingVariant) - 2. Color the graph based on the requested Coloring Method (s_ColoringVariant) - Ordering Time and Coloring Time will be recorded. About input parameters: - s_OrderingVariant can be either - "NATURAL" (default) - "LARGEST_FIRST" - "DYNAMIC_LARGEST_FIRST" - "DISTANCE_TWO_LARGEST_FIRST" (used primarily for DistanceTwoColoring and various StarColoring) - "SMALLEST_LAST" - "DISTANCE_TWO_SMALLEST_LAST" (used primarily for DistanceTwoColoring and various StarColoring) - "INCIDENCE_DEGREE" - "DISTANCE_TWO_INCIDENCE_DEGREE" (used primarily for DistanceTwoColoring and various StarColoring) - "RANDOM" - s_ColoringVariant can be either - "DISTANCE_ONE" (default) - "ACYCLIC" - "ACYCLIC_FOR_INDIRECT_RECOVERY" - "STAR" - "RESTRICTED_STAR" - "DISTANCE_TWO" Postcondition: - The Graph is colored, i.e., m_vi_VertexColors will be populated. */ int Coloring(string s_OrderingVariant = "NATURAL", string s_ColoringVariant = "DISTANCE_ONE"); /// Generate and return the seed matrix (OpenMP enabled for STAR coloring) /** This function will - 1. Color the graph based on the specified ordering and coloring - 2. Create and return the seed matrix (*dp3_seed) from the coloring information About input parameters: - s_ColoringVariant can be either - "STAR" (default) - "RESTRICTED_STAR" - "ACYCLIC_FOR_INDIRECT_RECOVERY" - s_OrderingVariant can be either - "NATURAL" (default) - "LARGEST_FIRST" - "DYNAMIC_LARGEST_FIRST" - "DISTANCE_TWO_LARGEST_FIRST" - "SMALLEST_LAST" - "DISTANCE_TWO_SMALLEST_LAST" - "INCIDENCE_DEGREE" - "DISTANCE_TWO_INCIDENCE_DEGREE" - "RANDOM" Postcondition: - *dp3_seed: [(*ip1_SeedRowCount) == num of cols of the original matrix == i_RowCount (because Hessian is a square matrix)] [(*ip1_SeedColumnCount) == ColorCount] */ void GenerateSeedHessian(double*** dp3_seed, int *ip1_SeedRowCount, int *ip1_SeedColumnCount, string s_OrderingVariant="NATURAL", string s_ColoringVariant="STAR"); /// Same as GenerateSeedHessian(), except that this Seed matrix is NOT managed by ColPack (OpenMP enabled for STAR coloring) /** Notes: - This Seed matrix is NOT managed by ColPack. Therefore, the user should free the Seed matrix manually when the matrix is no longer needed. */ void GenerateSeedHessian_unmanaged(double*** dp3_seed, int *ip1_SeedRowCount, int *ip1_SeedColumnCount, string s_OrderingVariant="NATURAL", string s_ColoringVariant="STAR"); double** GetSeedMatrix(int* ip1_SeedRowCount, int* ip1_SeedColumnCount); void GetOrderedVertices(vector &output); int CalculateVertexColorClasses(); //Public Destructor 1602 ~GraphColoringInterface(); //Virtual Function 1603 virtual void Clear(); //Public Function 1604 int DistanceOneColoring(string s_OrderingVariant); //Public Function 1605 int DistanceTwoColoring(string s_OrderingVariant); //Public Function 1606 int NaiveStarColoring(string s_OrderingVariant); //Public Function 1607 int RestrictedStarColoring(string s_OrderingVariant); //Public Function 1608 int StarColoring(string s_OrderingVariant); //Public Function 1609 int AcyclicColoring(string s_OrderingVariant); int AcyclicColoring_ForIndirectRecovery(string s_OrderingVariant); //Public Function 1610 int TriangularColoring(string s_OrderingVariant); int GetVertexColorCount(); static void PrintInducedVertexDegrees(int SetID, int i_HighestInducedVertexDegree, vector< list > &vli_GroupedInducedVertexDegrees); static void PrintVertexEdgeMap(vector &vi_Vertices, vector &vi_Edges , map< int, map< int, int> > &mimi2_VertexEdgeMap); private: Timer m_T_Timer; }; } #endif ColPack-1.0.10/GraphColoring/GraphCore.cpp000066400000000000000000000206741266356121500202410ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Virtual Function 1102 void GraphCore::Clear() //!< Reinitialize all variables { m_i_MaximumVertexDegree = _UNKNOWN; m_i_MinimumVertexDegree = _UNKNOWN; m_d_AverageVertexDegree = _UNKNOWN; m_s_InputFile.clear(); m_vi_Vertices.clear(); m_vi_Edges.clear(); m_vd_Values.clear(); return; } //Public Function 1103 int GraphCore::GetVertexCount() { return(STEP_DOWN(m_vi_Vertices.size())); } //Public Function 1104 int GraphCore::GetEdgeCount() { return(m_vi_Edges.size()/2); } //Public Function 1105 int GraphCore::GetMaximumVertexDegree() { return(m_i_MaximumVertexDegree); } //Public Function 1106 int GraphCore::GetMinimumVertexDegree() { return(m_i_MinimumVertexDegree); } //Public Function 1107 double GraphCore::GetAverageVertexDegree() { return(m_d_AverageVertexDegree); } //Public Function 1108 string GraphCore::GetInputFile() { return(m_s_InputFile); } //Public Function 1109 void GraphCore::GetVertices(vector &output) const { output = (m_vi_Vertices); } //Public Function 1110 void GraphCore::GetEdges(vector &output) const { output = (m_vi_Edges); } //Public Function 1111 void GraphCore::GetValues(vector &output) const { output = (m_vd_Values); } void GraphCore::GetVertexEdgeMap(map< int, map< int, int> > &output) { //cerr<<"IN GraphCore::GetVertexEdgeMa()"< &D1Neighbor, int excludedVertex) { if(VertexIndex > (int)m_vi_Vertices.size() - 2) { cout<<"Illegal request. VertexIndex is too large. VertexIndex > m_vi_Vertices.size() - 2"< (int)m_vi_Vertices.size() - 2) { cout<<"Illegal request. VertexIndex is too large. VertexIndex > m_vi_Vertices.size() - 2"< 0 => VertexIndex1 and VertexIndex2 are Distance-2 neighbor */ bool GraphCore::AreD2Neighbor(int VertexIndex1, int VertexIndex2) { set D1_of_VertexIndex1, D1_of_VertexIndex2; vector Intersect_set; for(int i=m_vi_Vertices[VertexIndex1]; i= 1) size--; Intersect_set.resize(size,-1); if(size>0) { //Print printf("%d and %d connected through vertices: ", VertexIndex1, VertexIndex2); copy(Intersect_set.begin(), Intersect_set.end(), ostream_iterator(cout, " ")); cout << endl; return true; } return false; /* //Print printf("%d and %d connected through vertices: ", VertexIndex1, VertexIndex2); set_intersection(D1_of_VertexIndex1.begin(), D1_of_VertexIndex1.end(), D1_of_VertexIndex2.begin(), D1_of_VertexIndex2.end(), ostream_iterator(cout, " ") ); cout << endl; //*/ } bool GraphCore::operator==(const GraphCore &other) const { // Check for self-assignment! if (this == &other) // Same object? return true; // Yes, so the 2 objects are equal //Compare vector m_vi_Vertices; vector m_vi_Edges; vector m_vd_Values; vector other_Vertices, other_Edges; vector other_Values; other.GetVertices(other_Vertices); other.GetEdges(other_Edges); other.GetValues(other_Values); /* if(m_vi_Vertices==other_Vertices) cout<<"m_vi_Vertices==other_Vertices"< m_vi_Vertices; vector m_vi_Edges; vector m_vd_Values; vector other_Vertices, other_Edges; vector other_Values; other.GetVertices(other_Vertices); other.GetEdges(other_Edges); if (!structureOnly) other.GetValues(other_Values); /* if(m_vi_Vertices==other_Vertices) cout<<"m_vi_Vertices==other_Vertices"<. ************************************************************************************/ using namespace std; #ifndef GRAPHCORE_H #define GRAPHCORE_H namespace ColPack { /** @ingroup group1 * @brief class GraphCore in @link group1@endlink. Base class for Graph. Define a Graph: vertices, edges and values (edge's weight - optional); and its statisitcs: max, min and average degree. */ class GraphCore { public: //DOCUMENTED ///Print all the Distance-1 neighbors of VertexIndex (0-based), except the excludedVertex void PrintVertexD1Neighbor(int VertexIndex, int excludedVertex = -1); void GetD1Neighbor(int VertexIndex, vector &D1Neighbor, int excludedVertex = -1); /// Print all the Distance-2 neighbors of VertexIndex void PrintVertexD2Neighbor(int VertexIndex); /// Check and see if VertexIndex1 and VertexIndex2 are Distance-2 neighbor /** Algorithm: - Get the set D1_of_VertexIndex1 of all the Distance-1 neighbors of VertexIndex1 - Get the set D1_of_VertexIndex2 of all the Distance-1 neighbors of VertexIndex2 - Intersect D1_of_VertexIndex1 and D1_of_VertexIndex2 to see which vertices VertexIndex1 and VertexIndex2 have in common. The result is stored in Intersect_set - If the size of Intersect_set > 0 => VertexIndex1 and VertexIndex2 are Distance-2 neighbor */ bool AreD2Neighbor(int VertexIndex1, int VertexIndex2); bool operator==(const GraphCore &other) const; bool areEqual(const GraphCore &other, bool structureOnly = 1) const; protected: int m_i_MaximumVertexDegree; int m_i_MinimumVertexDegree; double m_d_AverageVertexDegree; string m_s_InputFile; vector m_vi_Vertices; vector m_vi_Edges; vector m_vd_Values; //!< Edge's weight /** m_mimi2_VertexEdgeMap is a matrix that has all the non-zero (edge) in the upper triangle marked from 0 to (total number of non-zeros - 1) Populated by GraphColoring::AcyclicColoring() */ map< int, map< int, int> > m_mimi2_VertexEdgeMap; //moved from int GraphColoring::AcyclicColoring() /** m_ds_DisjointSets holds a set of bi-color trees Populated by GraphColoring::AcyclicColoring() */ DisjointSets m_ds_DisjointSets; //moved from int GraphColoring::AcyclicColoring() public: virtual ~GraphCore() {} virtual void Clear(); int GetVertexCount(); int GetEdgeCount(); int GetMaximumVertexDegree(); int GetMinimumVertexDegree(); double GetAverageVertexDegree(); string GetInputFile(); void GetVertices(vector &output) const; vector * GetVerticesPtr(){ return &m_vi_Vertices; } void GetEdges(vector &output) const; vector * GetEdgesPtr(){ return &m_vi_Edges; } void GetValues(vector &output) const; void GetVertexEdgeMap(map< int, map< int, int> > &output); void GetDisjointSets(DisjointSets &output); }; } #endif ColPack-1.0.10/GraphColoring/GraphInputOutput.cpp000066400000000000000000000760051266356121500216700ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Private Function 1201 int GraphInputOutput::ParseWidth(string FortranFormat) { int i; int LetterCount; char PresentLetter; string FieldWidth; boolean FOUND; FieldWidth.clear(); FOUND = FALSE; LetterCount = (signed) FortranFormat.size(); for(i=0; i i_VertexDegree) { m_i_MinimumVertexDegree = i_VertexDegree; } } m_d_AverageVertexDegree = (double)m_vi_Edges.size()/i_VertexCount; return; } //Public Constructor 1251 GraphInputOutput::GraphInputOutput() { Clear(); GraphCore::Clear(); } //Public Destructor 1252 GraphInputOutput::~GraphInputOutput() { Clear(); } //Virtual Function 1254 void GraphInputOutput::Clear() { GraphCore::Clear(); return; } //Public Function 1255 string GraphInputOutput::GetInputFile() { return(m_s_InputFile); } int GraphInputOutput::WriteMatrixMarket(string s_OutputFile, bool b_getStructureOnly) { ofstream out (s_OutputFile.c_str()); if(!out) { cout<<"Error creating file: \""<m_vi_Edges[j]) { i_NumOfLines++; } } } out<m_vi_Edges[j]) { out< > nodeList; map > valueList; //READ IN BANNER MM_typecode matcode; FILE *f; if ((f = fopen(m_s_InputFile.c_str(), "r")) == NULL) { cout<0&&line[0]=='%') {//ignore comment line getline(in,line); } in2.str(line); in2>>row>>col>>num_of_entries; //cout<<"row="<> rowIndex >> colIndex >> value; /*if(value == -999999999 && in2.eof()) { // "value" entry is not specified value_not_specified = true; if(b_getValue) { cerr<<"ERROR: GraphInputOutput::ReadMatrixMarketAdjacencyGraph()"<colIndex) { //cout<<"\t"< > vvi_VertexAdjacency; vector< vector > vvd_Values; vector vi_ColumnStartPointers, vi_RowIndices; vector vd_Values; //ignore the first line, which is the tittle and key getline(in, line); // Get line 2 int TOTCRD; // (ignored) Total number of lines excluding header int PTRCRD; // (ignored) Number of lines for pointers int INDCRD; // (ignored) Number of lines for row (or variable) indices int VALCRD; // Number of lines for numerical values. VALCRD == 0 if no values is presented int RHSCRD; // (ignored) Number of lines for right-hand sides. RHSCRD == 0 if no right-hand side data is presented getline(in, line); iin.clear(); iin.str(line); iin >> TOTCRD >> PTRCRD >> INDCRD >> VALCRD >> RHSCRD; // Get line 3 string MXTYPE; //Matrix type. We only accept: (R | P) (S | U) (A) int NROW; // Number of rows (or left vertices) int NCOL; // Number of columns (or right vertices) int NNZERO; // Number of nonzeros // in case of symmetric matrix, it is the number of nonzeros IN THE UPPER TRIANGULAR including the diagonal int NELTVL; // (ignored) Number of elemental matrix entries (zero in the case of assembled matrices) bool b_symmetric; // true if this matrix is symmetric (MXTYPE[1] == 'S'), false otherwise. getline(in, line); iin.clear(); iin.str(line); iin >> MXTYPE >> NROW >> NCOL >> NNZERO >> NELTVL; // We only accept MXTYPE = (R|P)(S|U)A if(MXTYPE[0] == 'C') { //Complex matrix cerr<<"ERR: Complex matrix format is not supported"<> vi_ColumnStartPointers[i]; } // get the 3rd data block: row (or variable) indices, for(i=0; i> num; vi_RowIndices[i] = num-1; } // get the 4th data block: numerical values if(VALCRD !=0) { for(i=0; i> num_string; ConvertHarwellBoeingDouble(num_string); iin.clear(); iin.str(num_string); iin >> d; vd_Values[i] = d; } } //populate vvi_VertexAdjacency & vvd_Values nnz = 0; counter = 0; for(i=0; i vs_InputTokens; vector vi_EdgeWeights; vector vi_VertexWeights; vector< vector > v2i_VertexAdjacency; vector< vector > v2i_VertexWeights; Clear(); m_s_InputFile = s_InputFile; InputStream.open(m_s_InputFile.c_str()); if(!InputStream) { cout<>i_VertexCount>>i_EdgeCount; i_VertexWeights = _FALSE; i_EdgeWeights = _FALSE; if(!in2.eof()) { int Weights; in2>>Weights; if(Weights == 1) { i_EdgeWeights = _TRUE; } else if(Weights == 10) { i_VertexWeights = _TRUE; } else if(Weights == 11) { i_EdgeWeights = _TRUE; i_VertexWeights = _TRUE; } } if(!in2.eof()) { in2>>i_VertexWeights ; } v2i_VertexAdjacency.clear(); v2i_VertexAdjacency.resize((unsigned) i_VertexCount); i_LineCount++; } else { in2.clear(); //remove trailing space or tab in s_InputLine int input_end= s_InputLine.size() - 1; if(input_end>=0) { while(s_InputLine[input_end] == ' ' || s_InputLine[input_end] == '\t') input_end--; } if(input_end<0) s_InputLine = ""; else s_InputLine = s_InputLine.substr(0, input_end+1); in2.str(s_InputLine); string tokens; vs_InputTokens.clear(); while( !in2.eof() ) { in2>>tokens; vs_InputTokens.push_back(tokens); } i_TokenCount = (signed) vs_InputTokens.size(); vi_VertexWeights.clear(); for(i=0; i vs_InputTokens; vector vi_EdgeWeights; vector vi_VertexWeights; vector< vector > v2i_VertexAdjacency; vector< vector > v2i_VertexWeights; Clear(); m_s_InputFile = s_InputFile; InputStream.open(m_s_InputFile.c_str()); if(!InputStream) { cout< 2) { if(atoi(vs_InputTokens[2].c_str()) == 1) { i_EdgeWeights = _TRUE; } else if(atoi(vs_InputTokens[2].c_str()) == 10) { i_VertexWeights = _TRUE; } else if(atoi(vs_InputTokens[2].c_str()) == 11) { i_EdgeWeights = _TRUE; i_VertexWeights = _TRUE; } } if(vs_InputTokens.size() > 3) { i_VertexWeights = atoi(vs_InputTokens[3].c_str()); } v2i_VertexAdjacency.clear(); v2i_VertexAdjacency.resize((unsigned) i_VertexCount); i_LineCount++; } else { StringTokenizer GapTokenizer(s_InputLine, _GAP); vs_InputTokens.clear(); while(GapTokenizer.HasMoreTokens()) { vs_InputTokens.push_back(GapTokenizer.GetNextToken()); } i_TokenCount = (signed) vs_InputTokens.size(); vi_VertexWeights.clear(); for(i=0; i _FALSE) { cout<. ************************************************************************************/ #ifndef GRAPHINPUTOUTPUT_H #define GRAPHINPUTOUTPUT_H using namespace std; namespace ColPack { /** @ingroup group1 * @brief class GraphInputOutput in @link group1@endlink. This class provides the input methods for reading in matrix or graph files in supported formats for generating general graphs. Three input formats are supported by default - Matrix Market, Harwell Boeing and MeTiS. */ class GraphInputOutput : public GraphCore { public: /// Read the sparsity pattern of Hessian matrix represented in ADOLC format (Compressed Sparse Row format) and build a corresponding adjacency graph. /** Precondition: - The Hessian matrix must be stored in Row Compressed Format Return value: - i_HighestDegree */ int BuildGraphFromRowCompressedFormat(unsigned int ** uip2_HessianSparsityPattern, int i_RowCount); /// Read the sparsity pattern of a symmetric matrix in the specified file format from the specified filename and build an adjacency graph. /** This function will - 1. Read the name of the matrix file and decide which matrix format the file used (based on the file extension). If the file name has no extension, the user will need to pass the 2nd parameter "fileType" explicitly to tell ColPack which matrix format is used - 2. Call the corresponding reading routine to build the graph About input parameters: - fileName: name of the input file for a symmetric matrix. If the full path is not given, the file is assumed to be in the current directory - fileType can be either - "AUTO_DETECTED" (default) or "". ColPack will decide the format of the file based on the file extension: - ".mtx": symmetric MatrixMarket format - ".hb", or any combination of ".": HarwellBoeing format - ".graph": MeTiS format - If the above extensions are not found, MatrixMarket format will be assumed. - "MM" for MatrixMarket format (http://math.nist.gov/MatrixMarket/formats.html#MMformat). Notes: - ColPack only accepts MatrixMarket coordinate format (NO array format) - List of arithmetic fields accepted by ColPack: real, pattern or integer - List of symmetry structures accepted by ColPack: general or symmetric - The first line of the input file should be similar to this: "%%MatrixMarket matrix coordinate real general" - "HB" for HarwellBoeing format (http://math.nist.gov/MatrixMarket/formats.html#hb) - "MeTiS" for MeTiS format (http://people.sc.fsu.edu/~burkardt/data/metis_graph/metis_graph.html) */ int ReadAdjacencyGraph(string s_InputFile, string s_fileFormat="AUTO_DETECTED"); // !!! NEED TO BE FIXED /// Read the entries of a symmetric matrix in Matrix Market format and build the corresponding adjacency graph /** Precondition: - s_InputFile should point to the MatrixMarket-format input file (file name usually ends with .mtx) - If (b_getStructureOnly == true) only the structure of the matrix is read. All the values for the non-zeros in the matrix will be ignored. If the input file contains only the graph structure, the value of b_getStructureOnly will be ignored */ int ReadMatrixMarketAdjacencyGraph(string s_InputFile, bool b_getStructureOnly = false); /// Write the structure of the graph into a file using Matrix Market format /** NOTES: - Because ColPack's internal graph does not have self loop, the output graph will not have any self-loops that exist in the input, i.e., diagonal entries of the input graph will be removed. */ int WriteMatrixMarket(string s_OutputFile = "-ColPack_debug.mtx", bool b_getStructureOnly = false); private: // ??? Wonder if this function is useful any more int ParseWidth(string FortranFormat); void CalculateVertexDegrees(); public: GraphInputOutput(); ~GraphInputOutput(); virtual void Clear(); string GetInputFile(); /// Read the entries of symmetric matrix in Harwell Boeing format and build the corresponding adjacency graph. /** Supported sub-format: MXTYPE[3] = (R | P) (S | U) (A) If MXTYPE[2] = 'U', the matrix structure must still be symmetric for ColPack to work correctly */ int ReadHarwellBoeingAdjacencyGraph(string s_InputFile); /// Read the entries of symmetric matrix in MeTiS format and build the corresponding adjacency graph. int ReadMeTiSAdjacencyGraph(string s_InputFile); // TO BE DOCUMENTED // ??? When do I need ReadMeTiSAdjacencyGraph2() instead of ReadMeTiSAdjacencyGraph() ? // probably need ReadMeTiSAdjacencyGraph2() when I need to read from a variant of MeTiS format int ReadMeTiSAdjacencyGraph2(string s_InputFile); int PrintGraph(); int PrintGraphStructure(); int PrintGraphStructure2(); int PrintMatrix(); int PrintMatrix(vector &, vector &, vector &); void PrintVertexDegrees(); }; } #endif ColPack-1.0.10/GraphColoring/GraphOrdering.cpp000066400000000000000000001440401266356121500211140ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { //Private Function 1501 int GraphOrdering::OrderVertices(string s_OrderingVariant) { s_OrderingVariant = toUpper(s_OrderingVariant); if((s_OrderingVariant.compare("NATURAL") == 0)) { return(NaturalOrdering()); } else if((s_OrderingVariant.compare("LARGEST_FIRST") == 0)) { return(LargestFirstOrdering()); } else if((s_OrderingVariant.compare("DYNAMIC_LARGEST_FIRST") == 0)) { return(DynamicLargestFirstOrdering()); } else if((s_OrderingVariant.compare("DISTANCE_TWO_LARGEST_FIRST") == 0)) { return(DistanceTwoLargestFirstOrdering()); } else if((s_OrderingVariant.compare("SMALLEST_LAST_SERIAL") == 0)) { return(SmallestLastOrdering_serial()); } else if((s_OrderingVariant.substr(0,13).compare("SMALLEST_LAST") == 0)) // match both SMALLEST_LAST_SERIAL and SMALLEST_LAST_OMP { //cout<<"Match "<* listOfPairs = new pair[i_VertexCount]; //populate listOfPairs for(unsigned int i = 0; i &vi_VertexColors) { m_s_VertexOrderingVariant = "COLORING_BASED"; int i, j; int i_VertexCount; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); m_vi_OrderedVertices.clear(); m_vi_OrderedVertices.resize((unsigned) i_VertexCount); vector< vector > vvi_ColorGroups; vvi_ColorGroups.clear(); vvi_ColorGroups.resize((unsigned) i_VertexCount); // reserve memory int i_HighestColor = _FALSE; //Populate ColorGroups for(int i=0; i < vi_VertexColors.size(); i++) { vvi_ColorGroups[vi_VertexColors[i]].push_back(i); if(i_HighestColor < vi_VertexColors[i]) i_HighestColor = vi_VertexColors[i]; } int count = i_VertexCount; for(i = 0; i< STEP_UP(i_HighestColor); i++) { if(vvi_ColorGroups[i].size() > 0) { for(j = vvi_ColorGroups[i].size() - 1; j >= 0; j--) { m_vi_OrderedVertices[count - 1] = vvi_ColorGroups[i][j]; count--; } vvi_ColorGroups[i].clear(); } } if(count!=0) { cout << "TROUBLE!!!"< > vvi_GroupedVertexDegree; m_i_MaximumVertexDegree = _FALSE; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); vvi_GroupedVertexDegree.resize((unsigned) i_VertexCount); for(i=0; i=0; i--) { i_VertexDegreeCount = (signed) vvi_GroupedVertexDegree[i].size(); for(j=0; j > > &vvpii_VertexEdgeMap) { ostringstream oout; string tempS; cout<<"vvpii_VertexEdgeMap.size() = "< *a, const pair< int, int> *b) const { //Compare induced degree of a and b if(a->second < b->second) return true; if(a->second > b->second) return false; //a->second == b->second, now use the vertex ID itself to decide the result // Higher ID will be consider to be smaller. return (a->first > b->first); } }; //Public Function 1356 int GraphOrdering::DynamicLargestFirstOrdering() { if(CheckVertexOrdering("DYNAMIC_LARGEST_FIRST") == _TRUE) { return(_TRUE); } int i, u, l; int i_HighestInducedVertexDegree; int i_VertexCount, i_InducedVertexDegree; int i_InducedVertexDegreeCount; int i_SelectedVertex, i_SelectedVertexCount; vector vi_InducedVertexDegree; vector< vector > vvi_GroupedInducedVertexDegree; vector< int > vi_VertexLocation; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); vi_InducedVertexDegree.clear(); vi_InducedVertexDegree.reserve((unsigned) i_VertexCount); vvi_GroupedInducedVertexDegree.clear(); vvi_GroupedInducedVertexDegree.resize((unsigned) i_VertexCount); vi_VertexLocation.clear(); vi_VertexLocation.reserve((unsigned) i_VertexCount); i_SelectedVertex = _UNKNOWN; i_HighestInducedVertexDegree = _FALSE; for(i=0; i= 0; i--) { i_InducedVertexDegreeCount = (signed) vvi_GroupedInducedVertexDegree[i].size(); if(i_InducedVertexDegreeCount != _FALSE) { i_SelectedVertex = vvi_GroupedInducedVertexDegree[i].back(); //remove the i_SelectedVertex from vvi_GroupedInducedVertexDegree vvi_GroupedInducedVertexDegree[i].pop_back(); break; } else i_HighestInducedVertexDegree--; } //for every D1 neighbor of the i_SelectedVertex, decrease their degree by one and then update their position in vvi_GroupedInducedVertexDegree // and vi_VertexLocation for(i=m_vi_Vertices[i_SelectedVertex]; i 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].pop_back(); // reduce degree of u by 1 vi_InducedVertexDegree[u]--; // move u to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].push_back(u); // update vi_VertexLocation[u] since it has now been changed vi_VertexLocation[u] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].size() - 1; } //Mark the i_SelectedVertex as read (_UNKNOWN), so that we don't look at it again vi_InducedVertexDegree[i_SelectedVertex] = _UNKNOWN; //Select the vertex by pushing it to the end of m_vi_OrderedVertices m_vi_OrderedVertices.push_back(i_SelectedVertex); //increment i_SelectedVertexCount i_SelectedVertexCount = STEP_UP(i_SelectedVertexCount); } // clear the buffers vi_InducedVertexDegree.clear(); vi_VertexLocation.clear(); vvi_GroupedInducedVertexDegree.clear(); return(_TRUE); } /* int GraphOrdering::DynamicLargestFirstOrdering() { if(CheckVertexOrdering("LARGEST FIRST") == _TRUE) { return(_TRUE); } m_vi_OrderedVertices.clear(); int i_VertexCount = m_vi_Vertices.size() - 1; int i_D1Neighbor = _UNKNOWN; cout<<"i_VertexCount = "< p_NeighborAndIndex; p_NeighborAndIndex.first = _UNKNOWN; // The neighbor vertex that the current vertex connected to p_NeighborAndIndex.second = _UNKNOWN; // Index (Place) of the pair where that neighbor point back to the current vertex // vvpii_VertexEdgeMap[1][2] = {4,5} means (1,4) is the edge and vvpii_VertexEdgeMap[4][5] = {1,2}; // Reset the size of vvpii_VertexEdgeMap to be the number of vertices vector< vector< pair< int, int> > > vvpii_VertexEdgeMap(i_VertexCount); //For each edge in the graph, populate vvpii_VertexEdgeMap for(int i=0; i < i_VertexCount; i++) { for(int j = m_vi_Vertices[i]; j < m_vi_Vertices[i+1]; j++) { if(m_vi_Edges[j] > i) { i_D1Neighbor = m_vi_Edges[j]; p_NeighborAndIndex.first = i_D1Neighbor; p_NeighborAndIndex.second = vvpii_VertexEdgeMap[i_D1Neighbor].size(); vvpii_VertexEdgeMap[i].push_back(p_NeighborAndIndex); p_NeighborAndIndex.first = i; p_NeighborAndIndex.second = vvpii_VertexEdgeMap[i].size() - 1; vvpii_VertexEdgeMap[i_D1Neighbor].push_back(p_NeighborAndIndex); } } } printVertexEdgeMap(vvpii_VertexEdgeMap); Pause(); pair< int, int> p_VertexAndInducedDegree; vector< pair< int, int>> vpii_ListOfVertexAndInducedDegree(i_VertexCount); priority_queue< pair< int, int>*, vector< pair< int, int>* >, less_degree_than > hpii_VertexHeap; for(int i = 0; i < i_VertexCount; i++) { p_VertexAndInducedDegree.first = i; p_VertexAndInducedDegree.second = vvpii_VertexEdgeMap[i].size(); vpii_ListOfVertexAndInducedDegree[i] = p_VertexAndInducedDegree; hpii_VertexHeap.push(&vpii_ListOfVertexAndInducedDegree[i]); } cout<<"The order is: "; while(!hpii_VertexHeap.empty()) { p_VertexAndInducedDegree = *hpii_VertexHeap.top(); hpii_VertexHeap.pop(); cout << '(' << setw(4) << p_VertexAndInducedDegree.first << ", " << setw(4) << p_VertexAndInducedDegree.second << ")\t"; } cout< vi_IncludedVertices; vector< vector > v2i_GroupedDistanceTwoVertexDegree; i_HighestDistanceTwoVertexDegree = _FALSE; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); v2i_GroupedDistanceTwoVertexDegree.clear(); v2i_GroupedDistanceTwoVertexDegree.resize((unsigned) i_VertexCount); vi_IncludedVertices.clear(); vi_IncludedVertices.resize((unsigned) i_VertexCount, _UNKNOWN); for(i=0; i=0; i--) { i_DistanceTwoVertexDegreeCount = (signed) v2i_GroupedDistanceTwoVertexDegree[i].size(); for(j=0; j vi_InducedVertexDegree; vector< vector< int > > vvi_GroupedInducedVertexDegree; vector< int > vi_VertexLocation; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); i_VertexCountMinus1 = i_VertexCount - 1; // = i_VertexCount - 1, used when inserting selected vertices into m_vi_OrderedVertices vi_InducedVertexDegree.clear(); vi_InducedVertexDegree.reserve((unsigned) i_VertexCount); vvi_GroupedInducedVertexDegree.clear(); vvi_GroupedInducedVertexDegree.resize((unsigned) i_VertexCount); vi_VertexLocation.clear(); vi_VertexLocation.reserve((unsigned) i_VertexCount); i_SelectedVertex = _UNKNOWN; i_HighestInducedVertexDegree = _FALSE; for(i=0; i 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]][vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].pop_back(); // reduce degree of u by 1 vi_InducedVertexDegree[u]--; // move u to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].push_back(u); // update vi_VertexLocation[u] since it has now been changed vi_VertexLocation[u] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegree[u]].size() - 1; } //Mark the i_SelectedVertex as read, so that we don't look at it again vi_InducedVertexDegree[i_SelectedVertex] = _UNKNOWN; // insert i_SelectedVertex into m_vi_OrderedVertices m_vi_OrderedVertices[i_VertexCountMinus1 - i_SelectedVertexCount] = i_SelectedVertex; //increment i_SelectedVertexCount i_SelectedVertexCount = STEP_UP(i_SelectedVertexCount); } // clear the buffer vi_InducedVertexDegree.clear(); vi_VertexLocation.clear(); vvi_GroupedInducedVertexDegree.clear(); return(_TRUE); } int GraphOrdering::DistanceTwoDynamicLargestFirstOrdering() { if(CheckVertexOrdering("DISTANCE TWO DYNAMIC LARGEST FIRST") == _TRUE) { return(_TRUE); } int i, j, k, l, u, v; int i_HighestInducedVertexDegree; int i_VertexCount, i_InducedVertexDegree; int i_InducedVertexDegreeCount; int i_SelectedVertex, i_SelectedVertexCount; vector < int > vi_IncludedVertices; vector < int > vi_InducedVertexDegrees; vector < vector < int > > vvi_GroupedInducedVertexDegree; vector < int > vi_VertexLocations; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); vi_IncludedVertices.clear(); vi_IncludedVertices.resize((unsigned) i_VertexCount, _UNKNOWN); vi_InducedVertexDegrees.clear(); vi_InducedVertexDegrees.reserve((unsigned) i_VertexCount); vvi_GroupedInducedVertexDegree.clear(); vvi_GroupedInducedVertexDegree.resize((unsigned) i_VertexCount); vi_VertexLocations.clear(); vi_VertexLocations.reserve((unsigned) i_VertexCount); i_SelectedVertex = _UNKNOWN; i_HighestInducedVertexDegree = _FALSE; for(i=0; i= 0; i--) { i_InducedVertexDegreeCount = (signed) vvi_GroupedInducedVertexDegree[i].size(); if(i_InducedVertexDegreeCount != _FALSE) { i_SelectedVertex = vvi_GroupedInducedVertexDegree[i].back(); vvi_GroupedInducedVertexDegree[i].pop_back(); break; } else i_HighestInducedVertexDegree--; } vi_IncludedVertices[i_SelectedVertex] = i_SelectedVertex; for(i=m_vi_Vertices[i_SelectedVertex]; i 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]][vi_VertexLocations[u]] = l; vi_VertexLocations[l] = vi_VertexLocations[u]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].pop_back(); // reduce degree of u by 1 vi_InducedVertexDegrees[u]--; // move u to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].push_back(u); // update vi_VertexLocation[u] since it has now been changed vi_VertexLocations[u] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].size() - 1; // this neighbour has been visited vi_IncludedVertices[u] = i_SelectedVertex; } for(j=m_vi_Vertices[m_vi_Edges[i]]; j 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]][vi_VertexLocations[v]] = l; vi_VertexLocations[l] = vi_VertexLocations[v]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].pop_back(); // reduce degree of v by 1 vi_InducedVertexDegrees[v]--; // move v to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].push_back(v); // update vi_VertexLocation[v] since it has now been changed vi_VertexLocations[v] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].size() - 1; // this neighbour has been visited vi_IncludedVertices[v] = i_SelectedVertex; } } } vi_InducedVertexDegrees[i_SelectedVertex] = _UNKNOWN; m_vi_OrderedVertices.push_back(i_SelectedVertex); i_SelectedVertexCount = STEP_UP(i_SelectedVertexCount); } vi_IncludedVertices.clear(); vi_InducedVertexDegrees.clear(); vvi_GroupedInducedVertexDegree.clear(); vi_VertexLocations.clear(); return(_TRUE); } //Public Function 1359 int GraphOrdering::DistanceTwoSmallestLastOrdering() { if(CheckVertexOrdering("DISTANCE_TWO_SMALLEST_LAST") == _TRUE) { return(_TRUE); } int i, j, k, l, u, v; int i_HighestInducedVertexDegree; int i_VertexCount, i_InducedVertexDegree; int i_VertexCountMinus1; int i_InducedVertexDegreeCount; int i_SelectedVertex, i_SelectedVertexCount; vector < int > vi_IncludedVertices; vector < int > vi_InducedVertexDegrees; vector < vector < int > > vvi_GroupedInducedVertexDegree; vector < int > vi_VertexLocations; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); i_VertexCountMinus1 = i_VertexCount - 1; // = i_VertexCount - 1, used when inserting selected vertices into m_vi_OrderedVertices vi_IncludedVertices.clear(); vi_IncludedVertices.resize((unsigned) i_VertexCount, _UNKNOWN); vi_InducedVertexDegrees.clear(); vi_InducedVertexDegrees.reserve((unsigned) i_VertexCount); vvi_GroupedInducedVertexDegree.clear(); vvi_GroupedInducedVertexDegree.resize((unsigned) i_VertexCount); vi_VertexLocations.clear(); vi_VertexLocations.reserve((unsigned) i_VertexCount); i_SelectedVertex = _UNKNOWN; i_HighestInducedVertexDegree = _FALSE; for(i=0; i 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]][vi_VertexLocations[u]] = l; vi_VertexLocations[l] = vi_VertexLocations[u]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].pop_back(); // reduce degree of u by 1 vi_InducedVertexDegrees[u]--; // move u to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].push_back(u); // update vi_VertexLocation[u] since it has now been changed vi_VertexLocations[u] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].size() - 1; // this neighbour has been visited vi_IncludedVertices[u] = i_SelectedVertex; } for(j=m_vi_Vertices[m_vi_Edges[i]]; j 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]][vi_VertexLocations[v]] = l; vi_VertexLocations[l] = vi_VertexLocations[v]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].pop_back(); // reduce degree of v by 1 vi_InducedVertexDegrees[v]--; // move v to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].push_back(v); // update vi_VertexLocation[v] since it has now been changed vi_VertexLocations[v] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].size() - 1; // this neighbour has been visited vi_IncludedVertices[v] = i_SelectedVertex; } } } vi_InducedVertexDegrees[i_SelectedVertex] = _UNKNOWN; //m_vi_OrderedVertices.push_back(i_SelectedVertex); m_vi_OrderedVertices[i_VertexCountMinus1 - i_SelectedVertexCount] = i_SelectedVertex; i_SelectedVertexCount = STEP_UP(i_SelectedVertexCount); } vi_IncludedVertices.clear(); vi_InducedVertexDegrees.clear(); vvi_GroupedInducedVertexDegree.clear(); vi_VertexLocations.clear(); return(_TRUE); } //Public Function 1360 int GraphOrdering::IncidenceDegreeOrdering() { if(CheckVertexOrdering("INCIDENCE_DEGREE") == _TRUE) { return(_TRUE); } int i, u, v, l; int i_HighestDegreeVertex, i_MaximumVertexDegree; int i_VertexCount, i_VertexDegree; int i_IncidenceVertexDegree, i_IncidenceVertexDegreeCount; int i_SelectedVertex, i_SelectedVertexCount; vector< int > vi_IncidenceVertexDegree; vector< vector< int > > vvi_GroupedIncidenceVertexDegree; vector< int > vi_VertexLocation; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); vi_IncidenceVertexDegree.clear(); vi_IncidenceVertexDegree.reserve((unsigned) i_VertexCount); vvi_GroupedIncidenceVertexDegree.clear(); vvi_GroupedIncidenceVertexDegree.resize((unsigned) i_VertexCount); vi_VertexLocation.clear(); vi_VertexLocation.reserve((unsigned) i_VertexCount); i_HighestDegreeVertex = i_MaximumVertexDegree = _UNKNOWN; i_SelectedVertex = _UNKNOWN; i_IncidenceVertexDegree = _FALSE; // initilly push all the vertices into the first bucket assuming that IncidenceVertexDegree is all 0 vvi_GroupedIncidenceVertexDegree[i_IncidenceVertexDegree].reserve((unsigned) i_VertexCount); // ONLY FOR THE FIRST BUCKET SINCE WE KNOW in THIS case for(i=0; i=0; i--) { i_IncidenceVertexDegreeCount = (signed) vvi_GroupedIncidenceVertexDegree[i].size(); if(i_IncidenceVertexDegreeCount != _FALSE) { i_SelectedVertex = vvi_GroupedIncidenceVertexDegree[i].back(); // remove i_SelectedVertex from vvi_GroupedIncidenceVertexDegree[i] vvi_GroupedIncidenceVertexDegree[i].pop_back(); break; } else iMax--; } //for every D1 neighbor of the i_SelectedVertex, decrease their degree by one and then update their position in vvi_GroupedInducedVertexDegree // and vi_VertexLocation for(i=m_vi_Vertices[i_SelectedVertex]; i 1) { l = vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].back(); vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]][vi_VertexLocation[u]] = l; vi_VertexLocation[l] = vi_VertexLocation[u]; } // remove the last element from vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]] vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].pop_back(); // increase incidence degree of u vi_IncidenceVertexDegree[u]++; // insert u into appropriate bucket vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].push_back(u); // update location of u vi_VertexLocation[u] = vvi_GroupedIncidenceVertexDegree[vi_IncidenceVertexDegree[u]].size() - 1; } //Mark the i_SelectedVertex as read, so that we don't look at it again vi_IncidenceVertexDegree[i_SelectedVertex] = _UNKNOWN; // insert i_SelectedVertex into m_vi_OrderedVertices m_vi_OrderedVertices.push_back(i_SelectedVertex); // increament i_SelectedVertexCount i_SelectedVertexCount = STEP_UP(i_SelectedVertexCount); } // clear the buffer vi_IncidenceVertexDegree.clear(); vi_VertexLocation.clear(); vvi_GroupedIncidenceVertexDegree.clear(); return(_TRUE); } //Public Function 1361 int GraphOrdering::DistanceTwoIncidenceDegreeOrdering() { if(CheckVertexOrdering("DISTANCE_TWO_INCIDENCE_DEGREE") == _TRUE) { return(_TRUE); } int i, j, k, l, u, v; //int i_HighestInducedVertexDegree; int i_DistanceTwoVertexDegree; int i_HighestDistanceTwoDegreeVertex, i_HighestDistanceTwoVertexDegree; int i_VertexCount, i_InducedVertexDegree; int i_InducedVertexDegreeCount; int i_SelectedVertex, i_SelectedVertexCount; vector < int > vi_IncludedVertices; vector < int > vi_InducedVertexDegrees; vector < vector < int > > vvi_GroupedInducedVertexDegree; vector < int > vi_VertexLocations; i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); vi_IncludedVertices.clear(); vi_IncludedVertices.resize((unsigned) i_VertexCount, _UNKNOWN); vi_InducedVertexDegrees.clear(); vi_InducedVertexDegrees.reserve((unsigned) i_VertexCount); vvi_GroupedInducedVertexDegree.clear(); vvi_GroupedInducedVertexDegree.resize((unsigned) i_VertexCount); vi_VertexLocations.clear(); vi_VertexLocations.reserve((unsigned) i_VertexCount); i_SelectedVertex = _UNKNOWN; i_HighestDistanceTwoDegreeVertex = i_HighestDistanceTwoVertexDegree = _UNKNOWN; i_InducedVertexDegree = _FALSE; // initilly push all the vertices into the first bucket assuming that IncidenceVertexDegree is all 0 vvi_GroupedInducedVertexDegree[i_InducedVertexDegree].reserve((unsigned) i_VertexCount); // ONLY FOR THE FIRST BUCKET SINCE WE KNOW in THIS case for(i=0; i= 0; i--) { i_InducedVertexDegreeCount = (signed) vvi_GroupedInducedVertexDegree[i].size(); if(i_InducedVertexDegreeCount != _FALSE) { i_SelectedVertex = vvi_GroupedInducedVertexDegree[i].back(); vvi_GroupedInducedVertexDegree[i].pop_back(); break; } else iMax--; } vi_IncludedVertices[i_SelectedVertex] = i_SelectedVertex; for(i=m_vi_Vertices[i_SelectedVertex]; i 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]][vi_VertexLocations[u]] = l; vi_VertexLocations[l] = vi_VertexLocations[u]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].pop_back(); // reduce degree of u by 1 vi_InducedVertexDegrees[u]++; // move u to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].push_back(u); // update vi_VertexLocation[u] since it has now been changed vi_VertexLocations[u] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[u]].size() - 1; // this neighbour has been visited vi_IncludedVertices[u] = i_SelectedVertex; } for(j=m_vi_Vertices[m_vi_Edges[i]]; j 1) { l = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].back(); vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]][vi_VertexLocations[v]] = l; vi_VertexLocations[l] = vi_VertexLocations[v]; } // remove last element from this bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].pop_back(); // reduce degree of v by 1 vi_InducedVertexDegrees[v]++; // move v to appropriate bucket vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].push_back(v); // update vi_VertexLocation[v] since it has now been changed vi_VertexLocations[v] = vvi_GroupedInducedVertexDegree[vi_InducedVertexDegrees[v]].size() - 1; // this neighbour has been visited vi_IncludedVertices[v] = i_SelectedVertex; } } } vi_InducedVertexDegrees[i_SelectedVertex] = _UNKNOWN; m_vi_OrderedVertices.push_back(i_SelectedVertex); i_SelectedVertexCount = STEP_UP(i_SelectedVertexCount); } vi_IncludedVertices.clear(); vi_InducedVertexDegrees.clear(); vvi_GroupedInducedVertexDegree.clear(); vi_VertexLocations.clear(); return(_TRUE); } //Public Function 1362 string GraphOrdering::GetVertexOrderingVariant() { return(m_s_VertexOrderingVariant); } //Public Function 1363 void GraphOrdering::GetOrderedVertices(vector &output) { output = (m_vi_OrderedVertices); } //Public Function 1364 double GraphOrdering::GetVertexOrderingTime() { return(m_d_OrderingTime); } int GraphOrdering::GetMaxBackDegree() { //create the map from vertexID to orderingID vector vectorID2orderingID; vectorID2orderingID.resize(m_vi_OrderedVertices.size(),-1); for( unsigned int i=0; i < m_vi_OrderedVertices.size(); i++) { vectorID2orderingID[m_vi_OrderedVertices[i]] = i; } //double check for( unsigned int i=0; i < vectorID2orderingID.size(); i++) { if(vectorID2orderingID[i]==-1) { cerr<<"What the hell? There is a vertex missing"<. ************************************************************************************/ #ifndef GRAPHORDERING_H #define GRAPHORDERING_H using namespace std; namespace ColPack { /** @ingroup group1 * @brief class GraphOrdering in @link group1@endlink. This class stores the ordered vertices as a vector of vertex identifiers to be used by coloring methods. */ class GraphOrdering : public GraphInputOutput { public: ///Calculate and return the Maximum Back degree /** Precondition: OrderVertices() has been called, i.e. m_vi_OrderedVertices has been populated Note: Back degree of a vertex is the degree of that vertex in the subgraph consisting of vertices that had been ordered (i.e., the vertices that are ordered before the current vertex). Depend on the ordering style, each vertex in vector m_vi_OrderedVertices may have different Back degree. The Maximum Back degree of all vertices in the graph will be returned. This is the UPPER BOUND for the number of colors needed to D1-color the graph. //*/ int GetMaxBackDegree(); int OrderVertices(string s_OrderingVariant); /// Test and make sure that the ordering is valid. Return 0 if the ordering is invalid, 1 if the ordering is valid. /** This routine will test for: - Duplicated vertices. If there is no duplicated vertex, this ordering is probably ok. - Invalid vertex #. The vertex # should be between 0 and ordering.size() Actually make a call to "bool isValidOrdering(vector & ordering, int offset = 0);" */ int CheckVertexOrdering(); private: /// Get Back Degree of vertex m_vi_OrderedVertices[index] /** Precondition: OrderVertices() has been called, i.e. m_vi_OrderedVertices has been populated Note: This function is written quickly so it is not optimal //*/ int GetBackDegree(int index); //Private Function 1301 int CheckVertexOrdering(string s_VertexOrderingVariant); int printVertexEdgeMap(vector< vector< pair< int, int> > > &vvpii_VertexEdgeMap); protected: double m_d_OrderingTime; string m_s_VertexOrderingVariant; vector m_vi_OrderedVertices; // m_vi_OrderedVertices.size() = m_vi_Vertices.size() - 1 public: //Public Constructor 1351 GraphOrdering(); //Public Destructor 1352 ~GraphOrdering(); //Virtual Function 1353 virtual void Clear(); void ClearOrderingONLY(); //Public Function 1354 int NaturalOrdering(); int RandomOrdering(); int ColoringBasedOrdering(vector &vi_VertexColors); //Public Function 1355 int LargestFirstOrdering(); //Public Function 1357 int DistanceTwoLargestFirstOrdering(); //Public Function 1356 int DynamicLargestFirstOrdering(); int DistanceTwoDynamicLargestFirstOrdering(); //Public Function 1358 int SmallestLastOrdering(); int SmallestLastOrdering_serial(); //Public Function 1359 int DistanceTwoSmallestLastOrdering(); //Public Function 1360 int IncidenceDegreeOrdering(); //Public Function 1361 int DistanceTwoIncidenceDegreeOrdering(); //Public Function 1362 string GetVertexOrderingVariant(); //Public Function 1363 void GetOrderedVertices(vector &output); vector * GetOrderedVerticesPtr(){ return &m_vi_OrderedVertices; } void PrintVertexOrdering(); //Public Function 1364 double GetVertexOrderingTime(); }; } #endif ColPack-1.0.10/Graphs/000077500000000000000000000000001266356121500143405ustar00rootroot00000000000000ColPack-1.0.10/Graphs/bcsstk01.gif000066400000000000000000000153271266356121500164710ustar00rootroot00000000000000GIF87a––õ„‚„DBDÄÂÄ$"$¤¢¤dbdäâä”’”TRTÔÒÔ424´²´trtôòô ŒŠŒLJLÌÊÌ,*,¬ª¬ljlìê윚œ\Z\ÜÚÜ<:<¼º¼|z|üúü„†„DFDÄÆÄ$&$¤¦¤dfdäæä”–”TVTÔÖÔ464´¶´tvtôöô  ŒŽŒLNLÌÎÌ,.,¬®¬lnlìî윞œ\^\ÜÞÜ<><¼¾¼|~|üþü,––þ@€ÅðŠG# €AP I5²„Œ¤¶º5iËKî£s•иðr\-¯«BØìózñý/762*&<}0=€”Ž— +—•˜/:"–Ÿ+ ¦¬ž­Ÿ°¯¦©¸¡É,¤ÐÌ€¶08<È5@Ú ŒÕ,{öAºB¤©³§þOdy[Á4 $ॄ] °Xù£ ¸~îšÁ š @XОZÓ^|qäØƒ.\8ð A‰Nð2ל;`Ú´oGܘë.rë1Cð…ƒªÝ ÔH 0”à! ªÕÀÁàg…4p€ûñB†Õ `àP‚ˆ¯ƒçbËãð 2С–‹j%@8!\× ä£Z$ €ÀЯ:g´=¸ñ DŽ2ÌèQaAÆvTh€ŸjðºÐÅHôåÌ ”°AøgžZæ÷ 4ÀÈ@AÕþä@ T@å wƒŠS"Ô@Ô=¸YPCERrÀRÏDàU=l"™pè˜8@€x(”(ãOA1rA ¬@3”øÓåÄP€6$ |×å9$À¥f»,Ã{ dÀœO^¤QJw<|ôÃð0R. ð`žïˆ €i GÑf9 ´‚" ™çZµHa7ÈUÀË Ïåbg$•ªu*Ã]‘9@ÁWŸÂôØàk?Ü€ £~‚ ÚÓ€G>s‚—ÖøàA_$à@^nsµÖöj[þ(( Ã:h)21¨£Í\`€Ìôt€:xªË!hB*D@o.öj0ª¹ãh”G‘š‘h0ÐQÔà$䛑`ü³1,Ž9(¨`Àèðî. l².˜ ƒÇ³“»D BÇ`rÎ:ðªr8a` 1f”€ Ú Zƒ‡:3­3xàÀ|½4M?<6ÏÏ à@7kå°3óR‹º¬šÞ3 ØèD:ò8¶3à@¦á¤ 7<¹'2”»Ë6ðí)ðà£;H A ˆÐ‚Týw37h @ÊÕ4 €VG\)ÄþpäÁ_þÛåä@¦ìh¾ð@ lÀÇD q3 D«æý‘|¬Ît™ç¯­þ°@*‚Þ@ÁŽÕøHU™ËÈiLÛt¨$±Ÿ¾F£ëBÜ1;pÀ¯È@‡ÏÈ À“ d¡àfóÐÀoÍh D¸^½@4˜ÜèhäüÔ ;À½>Àˆ” ˜~* áç(€ÇVP€¯uyzad8‚,Ï‚F8ÌpS‘£ÀA €ˆA€z£˜ àÐ\™t´í5èIÈ@щc5¨o@( (&ÀÝþ… @‹:À €ƒ§¨,(a䢗ôÀq»8@&°Ô`…‹9½³ŽTf0õ«  Ѓ¥qFA ²ÖŒ€€€Jø«6129(ˆEPÁÒØ’½ •z@HH‰Œ €9@ *€¼ò.@€iù À@€¾x0` (ˆñt±ƒ Äcº8?.°ì  ¸Á 6PÜÑ/ ÐÇN ÎgšëûÄ?ùa.¶Ø"nƒ Ú— ƒ'£±d‚´ýK0T¦pÅÑwû”ØøLs@€¡?pJþ–‹%’`¢E±(/TQ¨˜åžó²?o.²£ÚÁærT 78À`F€»áŒ@18Zæ"ÏHæ#¨ŒR{5 buI…߃I ÀHW P €Ž€˜MmP€›g܈b5Ï1`Äm*QÜFÖ ÄR8e’¾S¥ÍòZ"€pÛH(°ØèµW5˜À2Ђ ÔuÈxA  ö  3û{6ƒ ¬¨eC“O^Ð R!§½í8^øB‰°G¶'à€P. l“Axª‘(ÀC·¢ê{ª¤˜h£À±f «J]€È/ÃFðà…‰ÃŠ( Y ”+BÜDF<þ?dä!ð·à‚äÀ%¨€ |7¨ x <9A|p·ÄÀ/îÕ|Iò" pA zà‚LÀpz(<Ž(ÀTÙ— <õ\720“|P8@É:P@®Çv ¨`PÀwQx  °@ÔÕYþИh¡S{B}ö;“9“@ 8:Ò<4¥ÇCÞûie°A`P;:¨@ tè 50€uà´<ÁGà€uU£:@tà‚èÀÊöÌf6`P–0A `Úš`^x:€Pë²þÀPüÛ°9X ×0A :` ài"³Òp¢{®XŸEè'" ÑÝ"Áp8¼$^ér…q33€¸ 9dÀ"ˆ@DàÌÉ@Y¹´ s‘7»KG‡ªfÈÈÂ_ÿšÏ/`€€;¯‹€¡®?ÐP Cx ¬òzÛð^"@,À0*aÆFôþ@Ý‘ ¤%ÀÐcÀ]¡Aô7*À˜å àt§\ÀI~±9ÐÂsýQ@Cnbj3 <î0 @b2V\Õð‚PYWP€S@˜Ð ÐÕp) 2d*huö sY:ReY¹ i,ÒA^f•'fiL“` Ù6naBP…‘ u,@%  @1fw˜À•a€^h@ @†¡à6@c±^$@- @ иUr± rñ50ƒ‹C,Ø Ð“P K¸;þÄ|Âñ' [á 09€‹ƒ‹îñ=ïWÞ“á#TÑ@Ïð>`K™Ø$ϵ DÑ›@¥„y· 1€<Õ$ € ×”iæ’M~´ ¾” ,°!´öT 0&°ë0ðóê°Öòåô3Ѓ² P00nõsû„±+@C€‹ õˆ¿˜R00Mΰ(PQ¹p „S ^؈ :åg6XDJÕƒQ' *0`6,å 3 ’¼r_ Ç ׸“ºàPEB÷30I%Uþ8C T?± Tú€UþôY rbI–V™H°7°zU@ñYéWU“EîxÁ “â° ,€) tU—Û»ñWõ8G` ÈõaQ”â‚@ l0`™fŸ˜J8@^‡g?ÀZ«8 ŽñŠ0 NT²u7 ƒ¦õÐhV—+(T[‡¡v!]ç6Þ5ˆ¹à$`ϰ4@-°‡5à‡}•šÏP %@0ò8BG:ß^?ñì£ 0 Œ2 WØaˆÊ(žÕÐ_Dq»ÀK®BB/öäi>AþBPÁ§ @Z Ø’90…ð‘íP üÉ<P  U£g°’=ê þgö¶&ÝÇ-àà"ÑkàÏÓ%à!p]rÝ—ðxA¦ s0;oJB—É * Ž†  øW Ð2 ¨õ> îI…j0áp* èx Û$I1ó 9hL²D0ðbYgh•úǰ€þr6`þ”À£œ1&à#`60µ 4º˜ hÈp5‡` ‰Í€«ºš‹¹ èC+y’³ä #zpw—U Ç10i9``싯¹09°cŒðƒ‡ë¯›ŒÐ0¸ÄPô‰ƒÿÂ3È33X%àƒ4¡¡Ùʽ‘ £ÉºÊÚþ0c€´  ˜¾N« À ’ ?ÊÏô&À‡:Ú>B>Ì00Kš€å 622  †ƒ82ÚhÝKz²ž6kz (û79à°Ú×Q/0²#ð%5Àm_2d IÈÇ%3÷=°zŒºx§z¬Cà"p%ˆ•¥wO'ðy¼Ì"@ÆÊ0!~⥗$“…Ðp«3 vÙ©p&j0ÌázZ1OÓÓÚygçØ-& ƒ&`aP®õâ60N/puýÜ0EÀºÀ._c&ÅŸ’rlÃËÒêÀ¼àPþ 9:0/äp`á:s~ €ÂO²_Núš€nûòy¬* w,è{ÊíËvÏö¨:ð·ŸR$­  .ü6 ¼§)2ÀÒÕp& nZQÌnÎØ2kŽü àcÎ]rÐkø6(uê¾÷àû ÆâÆÃ ฆ}Ýå7ÖÕÑ®ŒÂh»rw~Ç p{%}O ' H±Ò=ñÏœ±^6¨O,0Gΰg6“b˜6Àø´&pO ô· Çp¥ ÍÔ5iÄ’+{\= f˜FíÆâ$°Âá\PÔs,@ß2@×:š¤pÈíõËæ…ºd]¸-Í㜼Õn›H§…ÔÃÅîAO—a\pÁœpÒµùµmZ“Ýü1(m"ßs­º YN½‡ëA„LÐ|Ü¢0ªZêv/Ù"(@¯ÏÀLx•'°˜%0-€¿¤§á&€&PŸ8@¸ð+»½ ñ#p`M.دa¼Ôû·ô Upm¢30ƒB=@by9#` 03þð•ÇÝ%,ðÛÂ:Þ ©D (`¿ñÕ€Øí;¥ 5 J®¹åæa0@°™D 0 Ù¹0ÐÖöK6HêPq\@'޲ ¡‘ƒ¡7© ë  ÐþÀÿ`N PÎkNò`-û`NítñŽ|GýGðh MF¾/`MH ÷K@sÎ0P©¹ÇtEem.*à&ðÂÔdK:©¾Œ²(ç9J5IΠY¸^=È.#CLUC\?3ÐÄÐMõ8rqPN® #ЈôÄŠ4OœZƒ¥2‹(,þ8°®ç†Nw$@H5À8ß_ˆ.ÙèšÜœ²ÃÔ$“ðÁ12°ŠÇqXᙹÞ‡Ëg]q3/#£ÎTœô‚™D 14 ‹\¯X ”ß©¸šÌ œ\àâŽÔrÓ蟢V<6ÀL:ž4°À# ?è­ÿ£ .@Øý®,@"´AîõÓ¤É=Ç}•‚ÇVº')}ºà† ö`/ñš40¼SÎá,R,)3!PæŒÎƧ1´c;íÜ% bÏ ²s´Ààq:ß  T=& Æ©³:  Ðà¶(ï  ÞkþùZ¡¤@HýˆE#1 \ŽMçj|0!h @JbJØâùálÑã ^f·û° Ü‹ïñÖÃC¶tÀ&dÄÆcÂÁå$,ŦfïÂÁƒçcÏRÊFãï©AãEÃf@Ç„É,B#ãr•hBôéÅC£è#E#jÃÀ`Ä@…’Õò†D*€!§aÃìCÀ¤ø²åàé ¢H@¥Òi@ºAXûíÁFeÓ©FÁ¥EÅ¢Gà –2ªâé¡ÁÄ'/(°õãC1 ¬Ð c„ÃÚ|ó!¢¾.*Ôðä-•È`EdAïyñáÆë·£ôQbD„ 3"¤ÈSD ›ÚN^pàBU XÙD.ß³ˆn<à!K!¯[½ö $"X a“‚ øENp PC *ðÎ’8 á+3B @‡(¡ xàì=h ƒþ:j€Zpã2Ø „ ³0Ѝá‚x  æjb‚ ˜!ƒ VÈ „ãnñl?Äš:t° ‚¤ ƒìH¡; ²N „ÕžXë<hÈÚ#b)»¤„H B0\À@ƒ% ‡ X€æÌ'& €„/`Gž˜¤"¦–”i‚¸à€(}à†Iw`˜@«N8á HAÒ<¸a€8à„˜N8àTçZa€ 2mqÒW[lõ 0“À(€`ˆ'"… ! 'à‚Tmf”‚("Ââ|bþP¨¡Ió-è`ÈŠà!hˆV` 'Ï Q)8€aˆ @@(F@ƒp€åü … v¨¨‚6¨ …VØ`¿V t…€—{`…Bù€’'¨`(.¨¡j(AÂuã¹¢<"xHÁÞ P àâ(>PTuãpÁ ƒ@q‡nS ¤¯Å›l°Í쉡l±`&†gÀD@å³É~ákt@›ï¶ý¶ð¾Ï~@lT@¤øî@šÜ<¼¾¼üþüüþü,––þ@€ÅðŠG#r©l&ŸL¨3JZ¥Øjöªír¹!Læq¹Êg3z­n§ßl¸;NŸÛåøzþ®ïóï<08>‡ˆ‰Š‹ŒŽ‘’“”•.,26*–¡¢£¤¥¦>E.>(§±²³´©< *("µ¾¿À¢.G " ÁÍÎÎḞ& 8 ÏÙÚ³Ã<«ˆ& Ûåæ¡©Ó>. ëçôõ‡˜ÞŒ$öÿõnÍ;dƒ€–K÷M‘‡1Èx¨°â,<œà‘¢ÇZÝ("JàÁÇ“±¢áʘâF ‘(cFêÖRŒ eê””fþ" lØIô¾šàôYT&ÆI *ÜèØ´*CK¨«Úô)¥pÀ»Z:ÚL.“ÿº•ÀDÖí_hõ”nµ:Ú°/Jë&– ;||R¼‘ æ œY•°«e˜uí_%0@]ü¬6˜ÐB&ãÙðl jQ×¢K櫓’:À# E³vDÖ‘I€¢Æ„²u2 €‚2Ál Èà€ªž|´w:€ArÀõhµBÐÝG7çB-mÁÂÎýž @`äθ,ý–µ5œ%  Õ½Õ—‡8°•ÿ£ö….0@ÄF¯:; ÂþDÿ@ ç #Lšâz0'ØÓô— œpl@‘¿®H;èîLȯïÀˆÓ¨ òŒ$°@çœ:Z¼€q6ùìMŠíØ’¨/ïß›¡@ %T¯Èðí#’¨Ùw’׿Eäl^ ô è ªDûÎõ ‰€Qó…÷(èƒ`€¬EùÚç‚éØ@_F|ÆÁGH@-FX@|M ¡Ù¦h`s²˜Z ¡¼Â6—¢$4€àí:ŸS"$\ €$ÃhÚ a€<œÑáMÀ¬ã­…[ÌH  Î ‰†itÀþh`ŸPð/ú " â1#9ˆÀì´À?2Â7€ó16C6‚$°„™ˆ\Œ”€#%=œ@””İ‚¶hÒ‘Ð^ Z$ÆPŽÄ xÀøéGWJâ|ðI!mɈ÷]Käå#Ï ƒ€"“æ"$ð'­Tæ!r@<Lz“æY¨ƒ4`§Ôfõ&DÜQ›ŽhPÎCS4€¯0;v$ž¡€ÙpL|:†„b¾ü‰ÜtB pAÏ¢À<ÓDÎ` ŠRô¢ͨE5ŠÑz´£ å¨H?:Ò’ô¤&MiÊ&pà [ˆ©d Ó™Ú´¦8¥©N‘ðÒ"¨NA;ColPack-1.0.10/Graphs/bcsstm01.mtx000066400000000000000000000024671266356121500165370ustar00rootroot00000000000000%%MatrixMarket matrix coordinate real symmetric 48 48 48 1 1 1.0000000000000e+02 2 2 1.0000000000000e+02 3 3 1.0000000000000e+02 4 4 0.0000000000000e+00 5 5 0.0000000000000e+00 6 6 0.0000000000000e+00 7 7 1.0000000000000e+02 8 8 1.0000000000000e+02 9 9 1.0000000000000e+02 10 10 0.0000000000000e+00 11 11 0.0000000000000e+00 12 12 0.0000000000000e+00 13 13 1.0000000000000e+02 14 14 1.0000000000000e+02 15 15 1.0000000000000e+02 16 16 0.0000000000000e+00 17 17 0.0000000000000e+00 18 18 0.0000000000000e+00 19 19 1.0000000000000e+02 20 20 1.0000000000000e+02 21 21 1.0000000000000e+02 22 22 0.0000000000000e+00 23 23 0.0000000000000e+00 24 24 0.0000000000000e+00 25 25 2.0000000000000e+02 26 26 2.0000000000000e+02 27 27 2.0000000000000e+02 28 28 0.0000000000000e+00 29 29 0.0000000000000e+00 30 30 0.0000000000000e+00 31 31 2.0000000000000e+02 32 32 2.0000000000000e+02 33 33 2.0000000000000e+02 34 34 0.0000000000000e+00 35 35 0.0000000000000e+00 36 36 0.0000000000000e+00 37 37 2.0000000000000e+02 38 38 2.0000000000000e+02 39 39 2.0000000000000e+02 40 40 0.0000000000000e+00 41 41 0.0000000000000e+00 42 42 0.0000000000000e+00 43 43 2.0000000000000e+02 44 44 2.0000000000000e+02 45 45 2.0000000000000e+02 46 46 0.0000000000000e+00 47 47 0.0000000000000e+00 48 48 0.0000000000000e+00 ColPack-1.0.10/Graphs/bcsstm01.rsa000066400000000000000000000031011266356121500164760ustar00rootroot000000000000001SYMMETRIC MASS MATRIX SMALL GENERALIZED EIGENVALUE PROBLEM, B MATRIX BCSSTM01 19 4 3 12 0 RSA 48 48 48 0 (16I5) (16I5) (4E20.12) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 .100000000000E+03 .100000000000E+03 .100000000000E+03 0. 0. 0. .100000000000E+03 .100000000000E+03 .100000000000E+03 0. 0. 0. .100000000000E+03 .100000000000E+03 .100000000000E+03 0. 0. 0. .100000000000E+03 .100000000000E+03 .100000000000E+03 0. 0. 0. .200000000000E+03 .200000000000E+03 .200000000000E+03 0. 0. 0. .200000000000E+03 .200000000000E+03 .200000000000E+03 0. 0. 0. .200000000000E+03 .200000000000E+03 .200000000000E+03 0. 0. 0. .200000000000E+03 .200000000000E+03 .200000000000E+03 0. 0. 0. ColPack-1.0.10/Graphs/column-compress.jpg000066400000000000000000000550651266356121500202030ustar00rootroot00000000000000ÿØÿàJFIFxxÿÛC      ÿÛC  ÿÀs±"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ý›ø[ð¶ÇâV‡ªêú¾«ãIoeñ·nM¿‹u[H’8u[¨bEŠ„cQ÷}rk¥ÿ†qð÷ý|{ÿ…ƵÿÉt~Î?òOuû=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’뼯(ý¶?hÍcöOýšüUãýÁ7^;›ÂÚmÞ«qc©› 6öÖÒÜÉ,ÓI¹•6ðy1M!y#ýÞÍò$ÊJ*ìºtåRJÕ³oþÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë€øÕûWøÓDñg†|+ðÏáÞ“ã랟ÅwVú׉Ÿ@Ó´ûŒQ„IgtÒ\É4ʱÇäªIYäj‡ôÙ×ãv—ûJüðwÄ«m+Æz=®³k Ê…šž%#€HÜ»°pHÈà‘ÍiÈìßggëy/ž±’Óªf1œd“]Uþôš¿k¦šNͧtVÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿ亳¬þÑ¿|9«\Øj<ðe…õœ†+‹{nÚ)`ppU•œ ö"«ÃT|0ÿ¢à/ü(-?øåIaÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%Ñÿ QðÃþŠ?€¿ð ´ÿã”ÃT|0ÿ¢à/ü(-?øåðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—Gü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã”Ã8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]ðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽPÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%Ñÿ QðÃþŠ?€¿ð ´ÿã”ÃT|0ÿ¢à/ü(-?øåðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—Gü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã”Ã8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]ðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽPÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%Ñÿ QðÃþŠ?€¿ð ´ÿã”ÃT|0ÿ¢à/ü(-?øåðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—Gü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã”Ã8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]ðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽPÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%Ñÿ QðÃþŠ?€¿ð ´ÿã”ÃT|0ÿ¢à/ü(-?øåðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—Gü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã”Ã8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]ðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽPÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%Ñÿ QðÃþŠ?€¿ð ´ÿã”ÃT|0ÿ¢à/ü(-?øåðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—Gü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã”Ã8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]ðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽPÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉuÊügý¾>|ø{}®øwÄë¶ßNÒµH.®nå í@¨ÌTqË€=Nð¯ØWþ ·ÿ ÇâDþñÜZV£¬Þì+‹u+ o?%£çøúoâèyÆ}L6M‹Äa§‹¥ Â;þ¶ïn§Ÿ_4ÃQ¯5IZRþµí~‡ÓÿðÎ>ÿ ð¸Ö¿ù.¹?_ôß| ñ¦¹¥êþ;¶Ôôm úúÎcãMbQÑ[»£m{’­†PpÀƒŒE{EpµGü›Äûõ?ý$–¼³Ð;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š+Êm&ý§¿fO|<ðÇŠt/Oã]2ëD¿ÔµM]i"²¹‚H&CÝ©Y±&QÚFU+Ìož=ZŠ™ÁIrËbéÔ•9)ÃFš/x#Pðø5=#SˆÅ<Ž£ÕXïœ?àž¿°„~^kž.¥Öu¿í­SJÓ§»EݦÚÛ^Ïh6cƒ,‚ZLhnÝõep³ü“ÝGþÆéêú»(æšTg‡§6¡-×ë¯~§-\ •c^qNQÙÿ_Ò;Êàÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zã:ŽòŠ( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ (¢€ (¢€ (¢€8?‹ÿòP¾ÿØÑ?þ™uJï+ƒø¿ÿ% á_ýÿé—T®ò€ (¢€ (¢€ (¢€ àÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuûú%žÞâѰʲ°à‚ZøÏþ +à?‰'øec} ÜµÏ4Õó5:ÕœH•žBï!QŽ,sVø#w€þ$øWá-åçˆî¿µ &дۨØÜ†-–ž2Oîàaœ)y;ÆÑ“'Ð<–Ÿö_ö‡µ\×·/éë×µûRÚRönÖ½ÿ_Nž§ÚQE|ùì…p³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw•ÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$´ÞQEÁþÎ?òOuûl|Σ©ºÏøj†ôQüÿ…§ÿ£âÿü”/…ö4Oÿ¦]R»ÊC8?øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ+¼¢€8?øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ+¼¢€8?øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ+¼¢€8?øj†ôQüÿ…§ÿ®+àí'ðëFð5ü7ž>ðU¬¯â=vuIµËXÙ£“W¼’7¿Ýdee= °#‚+Ükƒýœäžê?ö4x‹ÿOWÔÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9]åÁÿÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9]åÁÿÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9]åÁÿÃT|0ÿ¢à/ü(-?øåq_ÿi?‡ZŽ~MoãïO‡ˆæžåã×-Ymã:F¥w!þUß".OGR+Ükƒø¿ÿ% á_ýÿé—T þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊï( þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊï( þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊï( þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊï( øûIü:Ѽ  ç¼k+ø]RmrÖ6häÕï$À/÷YYOB¬àŠíáª>ÑGðþŸürÙÇþIî£ÿcGˆ¿ôõ}]åpðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽWyEpðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽWyEpðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽWyE|+ûrÿÁQ|;à?‰þ ±ð@Óü_?…5a«jp܇²uk[‹f¶ŽDÈg1ܹ.2¨ÁFî ô‡Ã_Û—áOÄßéúÜ9ðÆ–·Ñ‡k=OT·´»µoâŽHÝÁ Áê ã?·Ÿü×Ã>-xV²—þý_Å×öf­4‚—P¥ÍÓK·þ{m¶(C¼g¥};ð£á>ƒðKÀvðÝ„Zv•§&Øã^YÏñ;·Vv<’z×ÐfÊފ§í~Õÿüö·MÏÁbêÑGðþŸür»Ê(ƒÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür»Ê(ƒÿ†¨øaÿEÀ_øPZñʯû.j¶ºï«‹ë›{Ë+ÏëóÛÜA ’)ãmfõ•цC)AÁ½¸?ÙÇþIî£ÿcGˆ¿ôõ}@åpµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQEÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w”QEQEQEWû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_PyEPEPEP\Åÿù(_ ÿìhŸÿLº¥w•Áü_ÿ’…ð¯þƉÿô˪PyEPEPEPEPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@@ø«L'!Ôl¶M·ÛEž¿i0nÙæùyݳwË»Ï~›‹[‰4ö (¢Îâÿü”/…ö4Oÿ¦]R»Êàþ/ÿÉBøWÿcDÿúeÕ+¼ Š( Š( Š( ¸?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú€;Êàÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zï(¢Šàÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuûiwÿ¢ñuÝ…¦§w~"'„⻸’ÞÚû%Ô—×NðÌLJˆªy“2¨¯¨¨½uµÚù­ÂZK‘ïdþýWàpÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©]åQEQEQEÁþÎ?òOuû;ÈìþÛ>RC@Ñ–©Þ˜Ë£ïâaAè¥×¶±[uݽÖÞc¨¹hJªÝtù7¿ÊÛ=Ïݪ(¢™¿koØ Yý£|aâùt_èþðßÅO Úø?Çzuï…Æ­u¨éðKrÊÖi‰lîLW·1™&†ébeZ3¿ék[u´¶Ž$ÎÈ”"çÐ S覛QåéýK·@—½.gýh—ãe~öÔñ¿ü ©üOø}ssàÏ \\ë^'ueÒ-ÝïÇöF¥.%b™yˆógæE=@5ÖÃ+ü0ÿ¢qà/ü'í?øÝÿä¡|+ÿ±¢ý2ê•ÞRƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê(ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê(ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê(ƒÿ†WøaÿDãÀ_øOÚñºâ¾~ÍŸµŸ_Íyà]Jž#×`W›Cµ‘–8õ{Èã@J}ÕEUQÐ*€8½Æ¸?ÙÇþIî£ÿcGˆ¿ôõ}@ü2¿Ãú'ÿÂ~ÓÿÑÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãuÞQ@ü2¿Ãú'ÿÂ~ÓÿÑÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãuÞQ@ü2¿Ãú'ÿÂ~ÓÿÑÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãuÞQ@ü2¿Ãú'ÿÂ~Óÿ×ñOöløu§xçá´6þðT_øŽh.R=ÕVâ1¤jRpæ]ñ£`ñ¹õ½Æ¸?‹ÿòP¾ÿØÑ?þ™uJ?á•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ®òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ®òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ®òŠàÿá•þÑ8ðþöŸün²²Šþ#Útý*ÞÒêÜöxåD ¬ìzA útêJœ”àìÖÌ™Â3‹„ÕÓ> ýƒÿà˜>ð†µ®ø£Å‚ÇÆ i«ê:Fgwj¯mv·sZ´óDÙV•ŒM…åPä±>£ÿ†WøaÿDãÀ_øOÚñº?gù'ºý"ÿÓÕõw•ÕÌqÚ¾Û.g·ü29°x*8Z~Ê„lŽþ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï(®#¬àÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ®òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ®òŠðgí;Ç? ¡·ð‚ ŠÿÄsAr‘èvª·#R#€Ÿ2ïȧ¨ÚÿÃ+ü0ÿ¢qà/ü'í?øÝÿä¡|+ÿ±¢ý2ê•ÞPÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãtÃ+ü0ÿ¢qà/ü'í?øÝw”Pÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãtÃ+ü0ÿ¢qà/ü'í?øÝw”Pÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãtÃ+ü0ÿ¢qà/ü'í?øÝw”Pÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãu_ö\Ò­t/…W66ÖövV~#×à··‚1PFºÍêª"ŒP€z%p³ü“ÝGþÆéêú€;Êàÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zï(¢Šàÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuû+ð§ÆxCZÔ/¼2'ÓR=]*M+W†ü´&çK¹¹Ža¶YQD¢)'XDªÑ‚µõ}´M´hò¼ìŠÈà÷ŽÐO^Â=i^_4¿ð+~¿ÒÑÊ×ÓúÿƒÓµ‘Ã|_ÿ’…ð¯þƉÿô˪Wy^/ñ·à?µ?‰ÿ®n|áK‹kÄó®£,ºE»½øþÈԥĬS21þlüȧ¨ºÏøe†ôN<ÿ„ý§ÿ¤#¼¢¸?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆè¼¢¸?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆè¼¢¸?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆè¼®öqÿ’{¨ÿØÑâ/ý=_Qÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãuÅ|ý›>k>¿šóÀ> º•'øL·OííwÚÐÕu;Hinöw6ÅY»LVçz¯¢å°ϾÃ+ü0ÿ¢qà/ü'í?øÝ|ûvÿÁ/tüIðuÿ€×Nðߊõa¤_YEŽÅBÚÏr×1¢`#ˆíœP’§å;‹{Y 0Å%˜¶¡gé;koN§—›Ë=ðJòümåÓþöW‹ÆßØx“Ãwñj:V¢›£‘xd?ÄŽ½UÔðAé]yŸØKá_¯Xh‘ø+ÃZËZ&%¾Õ4¸.îîßøÝОOaÀ]ü2¿Ãú'ÿÂ~Óÿ×™‰T•Y* ¸_Kïo3¾ƒ¨éÅÕ·5µ¶×;Ê+ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün°5;Ê+ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün€;Ê+ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün€ÙÇþIî£ÿcGˆ¿ôõ}]åxwÀ/Ù³áÖ³àkù¯<à«©SÄzì óhv²2ǯyh Oº¨ªª:PWkÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãtÞQ\ü2¿Ãú'ÿÂ~ÓÿÑÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãtÞQ\ü2¿Ãú'ÿÂ~ÓÿÑÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãtÞQ\ü2¿Ãú'ÿÂ~ÓÿÑÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãt|_ÿ’…ð¯þƉÿô˪Wy^ñOöløu§xçá´6þðT_øŽh.R=ÕVâ1¤jRpæ]ñ£`ñ¹õ»_øe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ ò¸?ÙÇþIî£ÿcGˆ¿ôõ}Gü2¿Ãú'ÿÂ~ÓÿÕÙsJµÐ¾\XØÛ[ÙÙYø_‚ÞÞÄqAë7ª¨Š0@è•ÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$´ÞQEÁþÎ?òOuûþEœÒÀ:žÒ’Ÿ2¶¿—£êxÙ¾YSÉìê8r»ÿÁõ] ~»Ôµ é³ë6piú´Ö±½í¬3yÑÛLTE| Á[#8ç£EàÉÝßcØJÊÁ\Åÿù(_ ÿìhŸÿLº¥w•Áü_ÿ’…ð¯þƉÿô˪RÞQEQEQEQEÁþÎ?òOuûiÞ9øm ¿€|Wþ#š ”CµU¸Œi”ù—|hØÝ¢Š+Á=p® öp9ø}¨ûx§Ä_úz½¬ïÛ âW‹~~Ïúî»àûs]³‹*œ7Ù#Áßq³¬›;GÔä+óßþ oûJ|Mö—›EÓà½ñf•âëÉ5Á4„-›;f]Cyáóþ³…ûÛ÷²ü‚®/W $¡Ñ½ú¿M6¾ç‘ŒÎ)á±4ðÒ‹n}RÛüþ[ªÔQEx'®gš«­Ý\Øè·“ÙZ}¾òà¶óD_h)+óÂî8< æ¿!»B".ØL=YXŸâ-†p{™.EW2öžÎJ<Šúþ.ï¡ä晽<'<[ævÓúü:Ÿ°´U ßßj¾Ó®µK¥jW6ÑËud'‹IYAx¼Á€ûX‘¸pqš¿^$•™ê§up® ãÇÄ…ö4Ïÿ¦]R»Úü¾ÿ‚´~Ñ?mþ=Øh÷¾м5rš–ƒ%¼¤éW!oD‹üC,¹’$“ëd¹DóGÕá%/wú.§šfPÀÑöÓMëm?Ï¡úƒEy'ìAñWÆ_¿gM^ñ΋ý¬Ü®ðûJ˯/þYïÉùznP”[¯?BT*ÊŒíx»hî´;hVZq«š¾ºWÆ¿ðX?¿~ü.²Ò|5a=—†5åh5mrÌŠNGÙ8æ%eä·ñ‚T` ¾[€ž7 4N]_õ¯¡Ž?- W’m.ß×â}”EñOüËã¯Ä‰_uć…<:‹™®ÎøxÜcý že §p#ýXO €}­O3Ëç‚ÄË 6›Uýiè,28ª¯Ò}ÿ¯Ä(¢¼«öÒø¡ãƒ¿³Æ»¯xEþÚÖíÙÿ³â ïºòÿå§–;}÷ª°<Øz­V4akÉ¥®‹SzÕU*r©-’¾†ÇìàsðûQöñOˆ¿ôõ{]í~WÿÁ+?i‰ƒöŒ›A²†ÿÅš/ŠnäÔ5øî%8²glÉæ7ù?0?ë2ïl#õB½,ï'©–â=„ä¥u{¯Õt8r¬Îê>Úk[kþ}BŠ*ŸˆonôÝúâÂËûJú y$¶´ó–µH•{p›ˆqàg5ä%wcÒnÊåÌóE~<\~Ùfýµˆ‚j+ã5»þÉ_ù/䈼Ì}ƒÈë·?ð-ß>w|Õúõá»ÛÝKöÓ5 ‹x亳 Ŭ¥Ax÷ŒÚÄÌ׹œä5råMÔ’—:¾?ÍyžNW›ÓÇ9¨E®Wm­ü‹´QExG®pÿä¡|+ÿ±¢ý2ê•ÞWå—üSöøŸoûGZèב_xKFðµÒßøx[LÓd%ÿ˜¿yÎX?Õ‚Ë÷·–ûãö-ø¡ãŒ_³Æ…¯xãEþÅÖîÓÙ?´"lºòÿ埘 ;}· +(ö? «…ÁRÆÊI©ôOnÞ¾vØò0yÅàO÷¿°*ÿfÿis+_këm¾ûôßò<íŠ^ú+½·¶þï=³h¢ŠðO\+ƒýœäžê?ö4x‹ÿOWÕûoüUñ—ÁŸÙÓ[×¼ ¢ÿlk6ˆ|þÍ„ƒ¾ëËÿ–›0>^ƒ;˜VáOø$ßíñ6ããõÖi=â™5 {íS,$vËÞ‰8rÇæ_ùiÀûÛH÷p9\N ®62IC£{÷ôò¾ç‘‹Î)ÐÅSÂÊ-¹u¶Ý½|í±ú\íQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K^ëåQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQEQEpÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©]åQEPñG…ôïxv÷IÕ¬íõ 3P‰ ¹¶Ç2È"«xáþð³ÁÚ‡ü=§[éZ6—†ÚÖvƽzœ–bI%‰%‰$’I5±E_´Ÿ/%ôÞÝ/ÜžHósÛ]®QEAA^Iû!ü.ð÷€¼-â}CFÒ,´ëÝwÅzãßK {Z'U»†%ÿe4P¨¸QÉ,ÄúÝp³ü“ÝGþÆéêú®5'¸Å´žþ~¤¸Eµ&µ[yåQPPW//Á_ OñZ/>ƒ§·‹!´6I©˜ÿ|±£Óv>]ØÝ´•ÎÒEuU¤¡~WkéòìL¡[™^Ú…QPPW“~Ó 4‰þ.øSeâ &ËVµ_;ˆî#ÜÍ+P™Tú¯™ LTü­°q^³\Åÿù(_ ÿìhŸÿLº¥]:’„”àì×TLá®Y+£¼Š(¨(+7ÅþÓ<á‹íZ±·Ô´­J#Í´ë¹%CØÿ0G €F­*)ÆN/š.Í ¤Õ™“à_hÿ ¼!a è}¾—£éqm­`\$J>¼’NIbI$’I$šÖ¢Šr““r“»a¨®X«$QEHÏ%ý~x{áÿƒüIy¢èö:eγâ½q¯Þ0†o'U»†%öDUr@Ë}j¸?ÙÇþIî£ÿcGˆ¿ôõ}]å]J“©.y¶ßw©0„`¹`¬‚Š(¨(åÿáJøSþ¿ü'?Ø:ü%¿dûöŸ—ûï+ÓÓv>]øÝ·åÎÞ+¨¢Š¹ÔœíÌïm§bcÆüª×Ô(¢Š‚'ý¥þè¼iðžÛ_Ò,uh"ñ\Ž©sp6éZ„Á}ÔÉ LTü­å®A½b¸?‹ÿòP¾ÿØÑ?þ™uJï*åRn*-è¶]½ PŠnIj÷ (¢ £'Ç^Ñþ&øCPÐuý>ßTÑõHŒ76³®RU?NA0 ‚ ;Á^ Ò~øRÃCÐì-ôÍ'LˆAmmíH”~¤“’IÉ$’I$šÔ¢¯ÚO“ÙÝÚ÷·K÷·ry#ÍÏmv¿[QPP‘^Qû!ü8Ð|àM~MI±ÒßRñVº×&Þ žo•ªÝÃñÑR4UUÉÏ«×û8ÿÉ=Ôìhñþž¯ªÕI(¸'£Ýw·r\"Ú“Z­Žò¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$– £¼¢Š(ƒýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ Š( Š( ý£¿à þýœ¼g­iRø7ÇÞ.µðn•½ãWÃö¶rYx3O™¤ÜÝý¢æd!žS¤w¬p32Ñï÷‹K¸¯í"ž XfA$n‡*êFA¸"¾Ný­ÿdoŠÿ|]ñ_MðD¾ŸÁß<+má]kº•ݦ¡á]±ÜÚÍyi6²¥ùk[œ¬2ÍjHï Èv}Y£iqhzE­” ˆláH#çåU ?ANßžïuÙinúêÒJß>ÛFÖ}ß½~Ö_>3âÿü”/…ö4Oÿ¦]R»Êòг¯Œ<}áMN ¼TÑîKy©˜üW¨Â–жŸ{hP\ó¤…rívp¸;ŸðÎ>ÿ ð¸Ö¿ù.åÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w”Wÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÞQ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%Ðy\ìãÿ$÷Qÿ±£Ä_úz¾£þÇÃßôñïþ×ÿ%×5ð£öZ°Ñ|/u«sãKk§ÖuK„Hÿ ð¸Ö¿ù.€;Êàþ/ÿÉBøWÿcDÿúeÕ(ÿ†qð÷ý|{ÿ…ƵÿÉuÍxëöZ°Ô¼Qàɬn|i5®Ÿ¬Éq¨<ž4Õ™ €é÷‘‡B÷[•¼é!\džÚìÈ\a¢¸?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.€;Ê+ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï(®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èýœäžê?ö4x‹ÿOWÕÞW|(ý–¬4_ ÝCªÜøÒÚéõRájÑ©‚MBâHˆî‚îh^6b~bÌKåËéáœ|=ÿAÿáq­ò]w”Wÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÞQ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÐyEpðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—@Åÿù(_ ÿìhŸÿLº¥w•ãÞ:ý–¬5/x2kŸMk§ë2\j'5fh :}äaнÖåo:HW1á¶»ò¥ÿ†qð÷ý|{ÿ…ƵÿÉtÞQ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÐyEpðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—@åÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w•ÁþÎ?òOuûþ,ø›ÄZ÷Œ<%ãýOã;øóF³Óu{½7Çú†-ŵ­ßÚR)ì@[É-µÊìžygCÝ€C?Ó5¬áÊìc ©+ÿ]×ެדL(¢Š‚Š( Š( Šøþ QûZüPø1ûHͧøSÄÞ3Ñü9¡x{LÕ¥¹ðþƒ§j>Ð¥—P’+‰üW5Í´×VöˆÆtâ&Xâ¾–M‰È¿}G"˺0eaAÈ#ÖœW55Qmv¾í'ËQÓ}~Z«þ{1h¢ŠC (¢€ (¢€ +çø(ÿþ |%øQáïx'ÅÖ¾¶²ñg‡ì5[ìh¯.uX¯uÍ:É¡Y¦f޼›‹€ø…¤fhŠKÆó<ËöÖøÕñFÇÄ?5¿üGºðVû=x*ÛÄöš%Ž•§^Å⫦‚îòHõº·–e¶hí’[È7ÌÆF!$Ó;Ñ]ÅùY)_N–’Úîý #JR’„5nÖ]Ûv·kõÖÊÝo¡ö¥pµGü›Äûõ?ý$–»êrk^±¼–m-ݼs x›Åº7Â}&?_øJêë~‘%¦­e4‘\Y™~ÐöÒÈ LÀÁ4ŠËÈn(ÁFaCûu_|±½Óü­xWÀ¿-üOâM'Äp}¢ÛU°ŽÊî…a1I®^xÈY6®Ù™þÿÁ)þ9~Í^!ð­ç†n>xëJøgiâïø;Bñ&¿¨ÙAká½Z{{‹)%lnX][žÕ¡XÊI—‰Ô‚§(ÎJ3ºÖò·¢ŒÿÀ¤Üzõ“iA©é8ÆðåzZ7ùÊiÿà1Q—þJ“rN?yjŸµÃ-ÓV¸½ø‹àK84{½NIõûHÓN†ù¶ÙK12\7³`JxBÕÑx{â/‡¼]â=sGÒµÝSÕü34vúÅ¥ìS\é2É–8î#V-4l®¡À%XÁÍ~kk?ð@-nOü2ðx£Ãú¿€Gëo|I’\[Ï«>Ÿ$÷z]Åœ ©Þ\?,e"DÁs•?\ÿÁ5¿e¿þÌßõù~'êÖ>'øëÄ7> ñ%þ…$²ÙLû"µ¶Tyb‰Ûe¥µºœÆ¸`Øï¥7RîÉ9[ÎÒJ?|T¤û{½ÎyJIBÊ÷µü¯¿º^éôMQYQ@Q@Q@Q@Q@Q@Q@Q@Q@pµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’ÐyEP'ìßá“yw43x¶Çí·S^Ë—‹u[H<Ù¤ieeŠ+•DÝ#³ªXñGü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉu_Tý—|+®i·W·4½²¼‰ ¸·ŸÆšÌ±O¬Ž­tC)‚ÁƒEè”QEÿÙColPack-1.0.10/Graphs/column-compress.mtx000066400000000000000000000006771266356121500202320ustar00rootroot00000000000000%%MatrixMarket matrix coordinate real general 10 10 19 1 1 .666666666666667 2 1 .27224066696528 2 2 .27224066696528 3 1 .27224066696528 3 3 .577703998805546 4 1 .27224066696528 4 4 .283314888590275 5 1 .27224066696528 5 5 .283314888590275 6 1 .27224066696528 6 6 .283314888590275 7 1 .27224066696528 7 7 .283314888590275 8 1 .27224066696528 8 8 .283314888590275 9 1 .27224066696528 9 9 .283314888590275 10 1 .27224066696528 10 10 .283314888590275 ColPack-1.0.10/Graphs/hess_pat.jpg000066400000000000000000001262101266356121500166520ustar00rootroot00000000000000ÿØÿàJFIFxxÿÛC      ÿÛC  ÿÀZ¡"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ý›ø[ð¶ÇâV‡ªêú¾«ãIoeñ·nM¿‹u[H’8u[¨bEŠ„cQ÷}rk¥ÿ†qð÷ý|{ÿ…ƵÿÉt~Î?òOuû=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼®öŒøãÀ†²kNŸ\Ö/®¡Ò´=).±¨Ü>È-ÃmŠXî’R¤EI# ¨Õ*Fæ—õåæÞÉ-[Ñ E½ŸðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—_>ü\ÿ‚¡jÿc…¿í¼+à(§øáèuÕÑÿ ð¸Ö¿ù.»Ê(ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€8?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»Ê(ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€8?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»Ê(ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€8?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»Ê(ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€8?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»Ê(ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€8?øgÐGÇ¿ø\k_ü—\ŸÇ¯ƒzo>xÓ\ÒõÛjz6…}}g1ñ¦±(Šh­ÝѶ½ÉVÃ(8`AÆ"½¢¸?Ú£þM‡â?ýŠúŸþ’K@åQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEæß´?ìŸàßÚ„h â¡â¨®|-s5Þ•w ø³VðíÕœ²ÂÐÈÂm:æ 1»¦ˆÃ°ÇÌsé4TNœ\e³mj•<;ÿþñÏÂØãÁŸþüTÒ-4]Âòx_^“ƺñRk)$IOË©G%«Þ„…åžÙ@‚¨¢¾‡ø9ðÂÃàÂ/ x3KžöçLðŽ‘i£ZMy ’âXmáHQ¤`g*€’Ï¥t”VÒ©)9I½dîüí{}ÜÎËe} ’M©>—·Î×ûì¯èx¿ÆÏ€þÔ¾'ü>¹¹ðg…..u¿κŒ²iî÷ãû'R—±LÈ<ÄGù³ó"ž ë?á•þÑ8ðþöŸün‹ÿòP¾ÿØÑ?þ™uJï*pðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yExv»û6|:‡öŠð­ŠxÁKeqáÍfymƇj"–Hî´¥GeÙ‚Ê$F@‘±÷v¿ðÊÿ ?èœx ÿ ûOþ7Gˆ¿äç¼ÿb¾¹ÿ¥z=w”ÁÿÃ+ü0ÿ¢qà/ü'í?øÝðÊÿ ?èœx ÿ ûOþ7]åÁÿÃ+ü0ÿ¢qà/ü'í?øÝðÊÿ ?èœx ÿ ûOþ7]åáß ?fχZŽ~$ÃqàO‡ˆá‚Ù$ÐíYmã:F›!D>Uß#¶Rkµÿ†WøaÿDãÀ_øOÚñº>ÉBø©ÿcDúeÒë¼ þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( ý›?fχZïìëàëïø*òöóÚt÷èv²KUß#¶RkÜkƒøAÿ% â§ýé—K þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( þ_á‡ýá?iÿÆëÉÿkÈ>þÌuoÃð£Á:íÕœëcþµx­îr¦á–?Ý Ê“œ¹å«ß?k©>"|,ñõ—ÀýCJñGŽü*<¹­•‹I]$¸¶B6ܲ€ÚXQ_áŸø&‡Š~$xÃö‚Ô4‹WñO‡|LÌ|em«³Ii4H’iYý÷-·‚X’A5õYWJt§‹ÄÙ*vn Ùµ¾½®¶îûn|öa(T†…ÛÒ’Õ'·ÎÏ~ÇGÿéý¢ü9ñ ã)ðgþø;Äð”ݼš}ݯ…íZM:FËeH¿ãÜN嘟—8ýý—tËmá]Å••¼–v^#×ííà†1PFšÍê¢"ŽU@ Åý™¿b_~Ê7úÕç…ìf7úÜÌÏuvþlÖÐÊÛFØÊħ»1±l.:ÙÇþIî£ÿcGˆ¿ôõ}^~}‹Áâ1N¦‘²ò»ïnŸÓ;rŒ>*ŽC>i~KµúÿHï+ƒýª?äØ~#ÿد©ÿé$µÞWûTɰüGÿ±_SÿÒIkÅ=C¼¢Š(ƒýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ Š( Š( Š( âÿü”/…ö4Oÿ¦]R»Êàþ/ÿÉBøWÿcDÿúeÕ+¼ Š( Š( Ä_òsÞÿ±_\ÿÒ½»ÊàüEÿ'=àÿûõÏý+Ñë¼ Š( Š( áü”/ŠŸö4Aÿ¦].»ÊàþÉBø©ÿcDúeÒë¼ Š( Š( öWÿ“aøqÿb¾™ÿ¤‘Wy\ì¯ÿ&ÃðãþÅ}3ÿI"®ò€ (¢€ àÿhïù'ºwýÿÓÕw•ÁþÑßòOtïû<;ÿ§«ï(¢Š(¢Š+ƒñüœ÷ƒÿìW×?ô¯G®ò¸?ÉÏx?þÅ}sÿJôzï(¢Š(¢Š+ƒøAÿ% â§ýé—K®ò¼‚Š:_Áˆ¾6ø£YûQÓ´?Csp¶°´ó0þÅÒ€ ƒ¹$ œ(ä’$\!)ÉB í艜ã¹IÙ#Õ5ízËÂú-Þ¥©]ÛØéö14÷¸HáFY™:×ÅúÿíëáßÛŸþ?„¾×/< ¨k ö_ ës6ÈuÂ1¾ÞAð‰H*¸;™[{÷oãZ7üþâF½á_‰ú"Üü/ñ©K(ll£/w¡aŠdeæmÁY¸'pËoMý›àŽ0øãÍî±ãBÛ[ð¶‹p²è¶¨ ¶¤xe{…þNNw09ùFíhdØ|²žfÜj¤¥ j®­·FÓѧ¥µó_)[3­”a€W§v§}ù¤Ö©­o§“òØ öø¥cûQýºðj¾¶ð5ð]Fÿné¸&Úåe!å¾dù9ܪߧ~ð‰à»½NãHÒtý2mjèÞß½´ ]Î@G |ÌqÉ=É=I­j+ÁÎsÊùUR¢KD¬¿^úë®Ç³•å4pTù ÛÖ÷Öš}á\ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}^)êåpµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEWŽþÚþ Õ>%|1±ðþp²k×ú‚Éi¥ÂÅÔ|ÚÈŽ9Hÿ´tØ&½P‹ûâ(ÞaØG¼7±W)ñà?¿h¯üAðg…±ªø†éVÚtº¦§u%Õî¤ðıµÄòÈÌòK!RÌÌÄ’Ä’iöŸ |-aaá«X<5 Ckà§Ãðǧ±èE`{e6ªb $ˆy{q²ýÒEo×D§¬ÚûR¿—–šÙÝÉ·}n“¿-ÞJ/Ü¿ÙVù½ûiei¦¶²v<_ãn±ã˜þ'ü>[oøR[h¼O?öt’øŠâ7º?ÙĪ,˜B<²íò´Ÿ2ªôbëÖÂCñ?þ„ÿá_wÿÊÊ>/ÿÉBøWÿcDÿúeÕ+¼¬Ë8?øH~'ÿПà/ü+îÿùYGü$?ÿèOðþ÷ü¬®òŠàÿá!øŸÿB€¿ð¯»ÿåeðüOÿ¡?À_øWÝÿò²»Ê(õÝwâ)ý¢¼*ïá_-êøsYDi> =ýÕ¤–Vž+Ú“ØÙê-•TÚÜ2©ÇÎNÒÃ>jëÂ`kâ[Tbß*»ò]ÿ­NlN.•YZú/6u÷í?âè|_­øKJÐ~êž8ÒtÓ¨bAã–¹pA* >žˆ_€v€ÊIPÁ«ó«à§í9ñz_Û>ûT´°º×¼]â»Ï°k>ž7è£Ë6ò¡cEÀf» Iãvl|=ýŒþ3Çûi¶º†âí6ìj—^#iáX™Éûgšy‘\†À<±Ü¤Ò/€Ÿ t}+ãÅ/Ëeisâ§Õ¬ô»WÉ ,Ц‘¦È@Pv i$w!q’FIÚ¸ûIË’BTãË]Õ‡ÝÿÚ½ÕµÓѯ–‚Åæ³Sw¤©Ëïÿí–Ϧ¿'ä??` ¿ƒuiþð3Ü\.›§Oâ릷Ñd9.ÑÿÄ´äçîçîsŒðGÐ_ðüOÿ¡?À_øWÝÿò²»Ê+âqXÊø™©×““JÚöGÕáð´¨G’ŒRO];œü$?ÿèOðþ÷ü¬£þ‰ÿô'ø ÿ û¿þVWyEsœü$?ÿèOðþ÷ü¬ªÿ²ä—S|*¸{èmíï[Äzù¸Š ŒÑE'öÍîåG*…Ô€ÅT‘ÎÑÒ½¸?ÙÇþIî£ÿcGˆ¿ôõ}@åpµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQEÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w”QEQEÁø‹þN{Áÿö+ëŸúW£×y\ˆ¿äç¼ÿb¾¹ÿ¥z=w”QEQEÁü ÿ’…ñSþƈ?ôË¥×y\Âù(_?ìhƒÿLº]w”QEQEÁþÊÿòl??ìWÓ?ô’*ï+ƒý•ÿäØ~د¦é$UÞPEP\íÿ$÷Nÿ±£Ã¿úz±®ò¸?Ú;þIîÿcG‡ôõc@åQ@Q@p~"ÿ“žðýŠúçþ•èõÞWâ/ù9ïÿد®é^@åA©êVú.›qyw4vö¶‘4ÓJç (%˜žÀMex‡â6‹áØh×ZœzÞ¯²iÚsN‰q宿«“Räkò¯ãoüã‡í|u×Kß_xvåì-¼1&æ·HK ÐLƒkI…,ýI P¨TÛîäÙ|ÆRTÚI+ë×µ¾j×Ù~‘šgpQNi»»iÓ×åÓvzßÄÏø,}¦¹ñÖ}&-¯þOºV £t:…ür|¯u­v¦A*NJ±0¼#ÿ€“ÇŸ4ûý'_Ÿµ[xõ{]]\ Ù`|2Úì .ú¡BüÄnýÝ{Ÿ…ÿà˜~ø£ñSAøªhW~µÔíQÔ¼2!† æÃ`²ž#ÎI‹hçû£1¯ -`H¢DŽ(Ô*"Œ*À‚½¬^}‡ÀÆ4ò„âÜm;ë¯9-}奻ôòðÙEl\œó6¤“¼m¦Ÿ¤^š=}:Öðöká]ÇL±¢²Ó­ãµ·F‘¤d*‚ÌK6’IîkøAÿ% â§ýé—K®ò¸?„òP¾*ØÑþ™tºø–ÛwgÕ$’²;Ê(¢ÂŠ( ¸?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú€;Êàÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zï(¢Šàÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuûÿ ð¸Ö¿ù.€;Ê+ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºÿ ð¸Ö¿ù.€;Ê+ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº>ÉBø©ÿcDúeÒ뼯øYð B¾ñÏĘžÿƪ¶~#†Ì~1ÕãfS¤i¯—e¹FË‘¹Ém¡W;U@íáœ|=ÿAÿáq­ò]w”Wÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÞQ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%Ðû+ÿɰü8ÿ±_LÿÒH«¼¯ý›>hZÏìëàɯüj’ÝxsN™ÖêðD¬Ö±’4¹TEÉáT€®×þÇÃßôñïþ×ÿ%ÐyEpðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—@åp´wü“Ý;þÆÿéêÆøgÐGÇ¿ø\k_ü—\WÇ߀Z•àk b¿ñ«3xB„‰¼c«Ì»dÕìшW¹ 0 J°•°ÊC( Üh®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’è¼¢¸?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK ò¾oý ¿lo|ý°¼¥k:ÄQÜRÓ¯™>tÒêk yÏð« g㨠¬@R ùëö«ý»|ð{ãM‡|&|eâ=;Hº)¯Ý7Žõ°%ÆU¡·awÊy.AŒŒ“æŸ?`ÿø_ÿ|7«ü*×dñ…þ&‹­Sí:ÃËu¢y2D.…Ó¹.ût’]‹`î8vúü¯‡`­W5nœ$›‹óó}µIïø5ÎæïO.Js‹IúywWѾŸ‰Ï~Ö¾4j¶]´:œ·ÚÿŠµë•›ÃšŽ—º;yáSº6¶ âŒrFï“‹¼Iüû/éú߃|]ñÇDñÄÿX&ÖmíÌQÉ/gÙ®è8W `å•S!V?†_±‡†~øEÑ¿µüs&l-ÖçþÍR×w÷¶Ç ÂǞʀã'¢ÿ†qð÷ý|{ÿ…ƵÿÉuÍ›ñ LL!F’QPM]+6¶ù&·ŽßÑ–ä°¡)ըܜÚvzÙïóiõ;Ê+ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºù“Ý;ÊàþÉBø©ÿcDúeÒèÿ†qð÷ý|{ÿ…ƵÿÉuÅ|,ø¡_xçâLOãU[?à f?êñ³)Ò4×˲܃#eÈÜä¶Ð«ª {ÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w”Wÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÞWû8ÿÉ=Ôìhñþž¯¨ÿ†qð÷ý|{ÿ…ƵÿÉu_ö\ÓcѾ\YÂׯˆõøQ§ç••u›Ð ÈåÛ–bXžI$æ€=¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–€;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š(¢Š(¢Šàþ/ÿÉBøWÿcDÿúeÕ+¼®âÿü”/…ö4Oÿ¦]R»Ê(¢Š(¢¼³Ç¶wÃφÿtŸ‡º¶»¿ˆudÝŽ lqåÇ;缙ʃØdí »¶¡‡«Y¸Ò‹“Júk¢êeVµ:IJ¤’OM{³_Ä_òsÞÿ±_\ÿÒ½»ÊàüEÿ'=àÿûõÏý+Ñë­ñPÔφ5¢¬ýšO°›ÐÆØO´ù~fß›fìgo8Î+(«»7eqWÄúkx‘´a¨Y]-…ãXùëöb‚_/;¶nwcâ¯Wã_†tŽ×Ÿ·[$M«§Å”Ô —3J~H×€YÈù>Ëåà?vc A¿bôQxº5 ÔZÕõ }©­•–.Ѽ bH]ÙÀ$œc&½ìó$Ž_ìíUO_OëgÑõ<Œ§5xÞ{Óqåv×úߺèY¢‚p+æÿþÛwÆ;Çž ø=¯é“|GÑ-›û=ï6­®¢Tfci!;dt€,î¾d‡•…ÁÕÄ6©­®ú$Ý®ßDzŒU:+ßz½—W仳Ó~ ê6÷_¾,CðÉ4>(·2"¸-:6˜@äd«ø ô®×Hñ6›¯Ý_Aae{6™?Ùo#‚e‘­eÚËv¶ÖSƒƒ‚+ñƒöHñOÅëï‹Zûü9Õîá%¾Ó®îµI'ºOô˜Ô#±”á¤Ür­Ô1ÎG&»ø%†»ñTý­#ºœF+Àn¼L5 ‹Ãshov\îyƒ?ÈWÍÉ^¾ÇÁ^ÂZžÝ{‘OüïÚö|»ÜùŒ7{YÓ‡²~ókþ¾úö?]h¢ŠøCëŠ( öWÿ“aøqÿb¾™ÿ¤‘Wy^Mð‡âV‰ð‡ö*ðGˆ¼E¨A¦ig„´ÙgžSÀÿD‹ VbpŒ’HºO€?´†?io‡6¾&ð­é¹±œì–@K‹)@ù¢•;\dw ‚$NËUÒu”_*v¿Kö¹“­MTöNKš×·[­U×5Ë/ è÷ZŽ¥wmaaeMqsq*Å£,ÌÌ@P$šµ_Áj¡ø–þ ÒÛN9ød»´Å˜o4]nù Ïý1û»1òïûÜì®Ì§±¸¸aœ”yº¿Óϱ͙c*ê.Vè¿­»ŸuÚÝE}mÐÉÐÌ¡ã‘2º‘AGzáÿhïù'ºwýÿÓÕ|ÿÿ·ø—À©‹N< ÛO‡ì7Û\ôƒû¹ç9ÇË×èÚ;þIîÿcG‡ôõcYæX?ªbg‡RRåvºþ·ïÙ—Å}b„kr¸Ýlÿ¯¸ï*޽âm7¶±O©ßÙiÐÏ´a'É^Í­íº]ßüÇk›ÃJRŠæ’¶¯³}—üõ']ñ>›átµmKP²ÓÖúå,íÍÌë¸Î$ÜFçcÑG'ùÁÿÿ‚‰|CðÇí¾ðÚêž ±ðUè”y«¶mbP8’AÈkfRv§*êÛ›$€¿<~Ô^(ø³ªøcáóüGÕ®oln4d¼ðþë¨ä&Ù>Ó)rÏó'#ÐÙÛö[Ú{ö}ø}®üpÓ¬5ßèånô»´“77ZyPÐÅzã"\çy›rw4›¾’ŽS…É”1¸ÇªWVZÙ÷WÑöwµ®xusFhå…Ã'M«;¿Éöî­¹æVŸ°Ž‹ÿÓ|%ñ]´ûφ÷zì¥üQ§¤ËÕ•FMÕ¦OÈe8œ`†-†+™~¥Ð~èß >6|?ðÿ‡ôû}/GÒü#®CmmÂÆ¿kÑÎ}KI,I,I$’I¯R‚µ"‰8£P¨Š0ª: á¼Eÿ'=àÿûõÏý+Ñëäs Ú¾-*roÙÆü±½ìº+îì´Mô>——R÷8¯~[½¯þWßC¼¢Š+Ë;Š( ¸?„òP¾*ØÑþ™tºï+ƒøAÿ% â§ýé—K òŠ( Š( ¸?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú€;Êàÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zï(¢Šàÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuûArìÁîÚ2¿Bðÿ›ÛVµíʶµ·Ó~½ºo~‡Åñ—/³¥{nûþ;õíÔýjø[¤Øh^=øWg¥ë·'Ó­ü«¥¾«<âi/“í:>$.:ç· Àí^Ï_4ü;øãàÛoü5¸Ð¼7ã CƒÁº¢[iéá MžÝeŸIu ±ÀÞját±—L²’Ù‘wz×ü4w‡¿èãßü!õ¯þD¯ƒÄßÛNýÞûïÖÇ×з²»-ŽÅt+ÖßSvƒR’¶k± ùí±a|n(˜…Î$÷«uåþ"ý®<-áí;P—û;ÇwwZu›^µœ^ Õ–w@o·UPÅXvUÈ9#€|#ÿŽñÅ—íyâ-VËí~ ¿×þÈXfÊ'cÄäs8É,LJÉPg«•äX¼Â3ð.¯~ÉVó<ü~o†ÁJ1¬þ'Ó§›þ®~‡~ÕZ•âoÙßÅÖ:ç‰n<¤Üiî·:¼2lkEãñec„(9pÅ,+ñs௄|9âωÿÙÞ"ñü""ÅpÇX’MÊÆÛF¸oœàcßx¯¢¼!ÿ7×þ.|hÕ´ßh_ð•ü=ñÃ&›?†-á3=œe±Zó4êH<`»cHB½ÇÂ?ø'/ï ü`×/¼Rþ?ñƒÑ´ñà­v+‡Þ§&åÖÑy8]‡ç 1ÚCö¹cY¥|Ü\ÕãËgÒÎ×_{ßKjºŸ+¾qZ\SQvwºóWò~ZþÊŸ²Â=+ãgÆ$ðÍ÷ŒÁϨ[O …ëÆÛ/.YvÇnH#h“$žGÊ2X úöÿ‚høûÃ?´skþ)}CÂZ‚/ñ¶Òl—Z”vÄÝíÙHÞýƒÅ5ÿd¿ØãáßÂÿ¾&Öõ´ñ·‰4ÿ êk…i'‚ui “3‰nUmŽ$A0PŒ;D›vºgí¯øhïÐ;Ç¿øCë_ü‰\œAÅîR• ¹¡(¤Û[w·ªvwÙìtäÜ5hƦ.6”eug¿¯Ïk|ÎòŠàÿ᣼=ÿ@ïÿá­ò%ðÑÞÿ wð‡Ö¿ù¿:>Øï(®þ;Ãßôñïþú×ÿ"Qÿ áïúx÷ÿ}kÿ‘(âø(W‡ômCþ éðrþ÷ÅWf«a¡é¿Ùú rñk­!1ŒthÔäHxŠõqUà‡^Òdñ7еAâ¹âÖÖ€øuXÆ“ÁEӃěX•yLœýñš·WÄÏjÿ°o½.o k÷ž&‹FÓíìµ›&êÂÛNÙmšycU¸Wc,§ïî]Ôà¿ü!àø–=KÂÚõ߉LBX5;JºÕDß*´;xÝâ%¹ßŒ7BW7é8U?õZ{îûmË¿[ÞÚXølCúÁºwÞߟáó?Nê¶±£Yø‡J¹°Ô-m¯¬o#hn-î"Ybž6du`C)ƒ\gü4w‡¿èãßü!õ¯þD¨o¿iÏ ivS\ÜÚxÞÞÚÝYe—ÁZÊ$H£%˜›\$“Ò¿7W¾‡Ü;[S¿‚µ"‰8£P¨Š0ª: á¿hïù'ºwýÿÓÕ|£ÿ&ÿ‚‘j¿4‹o øÓÄ:&£¬Aö‹gPÒ®tÙa„±m’â4ră™6áG K¯…|fÿ‚´ø¿â¿ìõ£xelKñ$wP\j:Ü$(¸ki£š !P?vþdjÏŽ_—°>›ÂXüUW‚\³}^Ë»òü|Ę<=YÑ›wŠí»íëøÿà´>Ò4ßÚ6ËPµñ]Ʊ«ßY*ÞèÒ9—û T,!"É–o/ï–èâ¾rø§á?xÀþ »Ñü`Þ$Ô5==åÔôÿ³<Ør ! ÜåŽp[£-}3®xcHÿ‚’ü1µñ{i:׆¾%éwiú¾£§økPÔ4½~0XÚA'—:&3ÂýÒ¥:ðN_‡šÏ|7kà‰<{¥kšiŽ NòûÁëÇ©ÆÍ™&*-ÙUF€~jûœy„ÀR£‚ÅTqœ.¤¬­¢Òí/‡UÊÖ½úŸ%ŠÊqÊ•qXx'jÝ÷é®ú;§§n‡ˆØÄþx'Å_µ_øX6úÆË FÖ1ËáûÆl˜]Xü±.îd8Äp¬¤þþƳ¥Ïì·ðKðî¹u®Þ@Íq<ŽäÁnï‚Ñ[ƒÊħ8Ï$–l ÛG;û;Kðëöcømkᯠhž<а÷7/àmhÏ}6>ido²rOaÐ À®ïþ;Ãßôñïþú×ÿ"WÃg¼G[«§zjM¦ÒMö½»y[Ìúì£#¥„~ÚÖ›I=t]íëçò;ÊàüEÿ'=àÿûõÏý+Ñèÿ†Žð÷ý¼{ÿ„>µÿÈ•Åk¿t)h¯ Þ ˆ ðæ³ )ðv®%,÷ZQc6ÛÙqe”RT1Ô˜=ãÜh®þ;Ãßôñïþú×ÿ"Qÿ áïúx÷ÿ}kÿ‘(¼¢¸?øhïÐ;Ç¿øCë_ü‰Gü4w‡¿èãßü!õ¯þD ò¸?„òP¾*ØÑþ™tº?᣼=ÿ@ïÿá­ò%q_ >>èV>9ø“+ØxÕ–óÄpÍÁÚ¼Œª450ê¶ÄÆÙBv¸ ´«ck) ãEpðÑÞÿ wð‡Ö¿ùøhïÐ;Ç¿øCë_ü‰@åÁÿÃGx{þÞ=ÿÂZÿäJ?᣼=ÿ@ïÿá­ò%w•ÁþÎ?òOuûŸø-5ÐOÙÀxÖÛâÜ>gŒ5ßÚbÛD×$Ô[PŽCªÇá©îÄÒ+HâxmÒ2'CEÃ…»ø³ðûáZü*ÿ‚ŸøŽ4ñü»Ä)¯üe¹ÖÇü$z‰¾ø§¦}£SV6–ìÀõ ùQÛ.h;B¨x=3 Mì“ûù¡Õj´¾Ílº¤vÚ^Ÿ®»ªã_ÿ`߆ÿþq$näî\È~¯2á)Q)á©xóJéôëøü?éóØ#YTŽ&г²Õ}ßðv>7ðçÆÑþÜ-fú…ÏÅIõ°—O“\Ø?5³¦B¯¨UU ÀaÎü*¾ø“gûeAs¡èÐÝüLMjy›5”B!t ™•¢;R5_œ’6ùxÜ ízn“ÿÎø±7íd4n®íÒ)†ª¾3ŸÉXwî[”ÆrzFvîr§|+ÿ‚h|Xÿ†²:Í{¡ å5 ¼U %bß”ž 8/+v®CvݬGݼ~]K–tÿ†ºt×Ïáþîÿyò ”£xOãï×OÇûÛ7ì‰Ä;öа›Ã:5´ÔfkÛÛ%‚ÞÓ,VãÍP [¨ Ã*\áFp+ö’2Ű±È ­cè^Ò<=¯^jööƒ[ÔáŠýH[Æ—Wâ%Ú†VUˆÀvٯ˸‡;ŽeV#MG•[×þè~’åONPsr»¿õçÜ྿>*’@ÅdÿÜK¤øAûNøãο¯ižñž¯yáÙÌi?60<ÈÉÿYì®õÊäuÁR|óâwÁÍ[ãß‚>9øWDñ φµSÄP¤w1p“¢éy‚Raƒåb˜8?Ä2ñ÷üËö øŸ¡~Ó'WÔÆ©à{/^yw·Ãj,0M¼YÊÉ©Ÿ”ÚÙä –å˜:ø*ÕëVåœv_Ö÷ÛMº†;‰£Š¥F•.hËwýmmõÜýB¢Š+çÏd«­kV~Ò.µ Bê +(š{‹‰ÜG1¨Ë31à$šæ> |{ð§íá®xGV‡UÓÒg·…)$N§tl2ä`ŒŽA¼Ëþ 5û6ø§ö™ø6‘áMjâÊúÆ_µ¾—½c·×Œˆdn¡L…¾ðû¬Ÿ>Á"¿cÿ|;ñMçŽ5ëWÂÚD©%˜ÑeË“Ua•ß4l2ˆ’§‹\îú 6Y„©–ÔÅβU"ôéÝߣZ+kÖÞ5|~&øa£JðkY~¿.©êúyýEð¿á>ƒñ·ö%ð?†üIa£¥j>ÓHÛ†CöH¶º7Uu<‚:Sþü*øyÿÿøzaš='DÓPÝjz¥ã¸¼~œ€71ÎÔEHdœô²¿ü›ÃûôÏý$оSÿ‚ßxX]ü0ðÞ­'ŒMŠÚ]¢ðÔ­òjŽzÜFn2F§¿È¸*Çc“Sž.´2ùTq§7v•Þ¾üö[½sIÇ JXØÁ9ÅhÿàþŸ%¹ö7ŠúÆÏØx“ÃZ„Z–“¨¦èäNtuê®§‚§‘_ÿÁjüeñCðn‘§Ø*Ú|9ÔˆŽþâÚCç]]å™a›¦#Ú¡” †`IåTÿ‚{~Ñšìƒð[ÅÞ5ÔüZú…åìŸÙú‚`|=ÍÀ–êMÃä\do^1¸¶Õ®§öºÔऴ¿ˆžÔ/¯„íÄ:÷‚÷oŸK”’MÌJ U‡±’¨1‚®«ôøû?7U%­ÊÜÒZ^Ú/[è¥ðßÏCÀÅæß\Ë\#¥V¯ÊŸKëò¶­oo#çŠ>4ø«âÿÙ;Á â{Y®~Xjú«=º4Ìê¡LqËùj‚ŽØÃ-å•>#ÉñëöUðzÖ‰í/.Î…©%ŒjòÈíûÅyWæÁ*ØÝÛO-°mô?Á4þ-øWöbÒ›ž`°˜uZ“„í7¢ß­íýäÛÙôÝ)Åbk:U£x-_Ê×òÓEºù3¿ÿ‚HÉãxÿe»Koizf‡nùðôŠžMÍÝ»gy# »ˆ*çæ|±#Y¾¤¦Åâ*¢ ª£@ì)Õù&a‹úÎ&xŽUg{/ëïó?HÁa¾¯Bo~Uk³‡øÑûGx3ö|Hok–ºGöåÚÙÚ,„–‘Ž2äDk‘¹Ïʹ<Ší`. Ibt’)2:œ«È Ž¢¿6ਰ÷ÄŸüw‡Åš;êÞ7ÒüI4vVÐ*†—Drp°P`É%dÀ“¼î;Ÿí?Ø·àv½û<~ÏÚ?†|G¯Ï¯êV »!¢°VÑ674iƒ‚Ùäœap©Ë0”p±4«)N[ÇúÕ[g}÷GŸƒÇâjã*P©K–1Ùÿ[ß}6êzµp~"ÿ“žðýŠúçþ•èõÞWâ/ù9ïÿد®é^_>{'yEPEP\Âù(_?ìhƒÿLº]w•Áü ÿ’…ñSþƈ?ôË¥ÐyEPEP\ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}@åpµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”Ä~Ñßÿá> kþ4ÿ„KÆþ;þÁ…fþÁð†—ý©­ê;¤TÙmo¹<Æ·¸aUjü0ð_€õÿÚþ ƒájßi¿x{Zø¡gâd‚ëö5ðæ‡>š´’âyâHîMèŠ7ÙçÝ2³¼k!`Kþ€5FßGÓç»»ž[[XÚi¦™ÂG (Ë31à(’O ü`Õ>6|`Ó?ਞ×bñwíGww㿊–pxbþ-RÉþë~ º`ÐG›„R_I¥«”“#Ü€Wt„ðZfŸ[«vOš6¿«×mdÕìÐñOý†ª{Yß»J.ÿ$®žº¹E=Ó_´´QXÿ>"xá?ƒuø«]Ñü5áí&?:ûTÕoc²²³ o–i ¢.HbH©m%v 6ìŠ+‰ø¹ûK|8ýŸô]/RñçÄø'N×&ÚmÖ¿®Zé°j•Ü#…æuY¯;T“ŽkµV ‚<‚;Õ[ü‰ºÓÏS„ø¿ÿ% á_ýÿé—T®ò¼ö£ø§áï„Þ(øW¨øV³Òlÿá,t2Îø ¿KÔ! {„Mf?*ïˆ×añ/ã§„~¶Œ#I¦4<š@Eû×yȸ)ëܧÝ-‚{ƒî¾3ÀÃÜ—=Ôzß^×êôøÏ!p¾.^ú峕ö¶ž÷O’<ÿ‡¿ð¯Ç‹Hít(ì¾YÁ“i¡CýªÎÚ?•'Vï(ýÞvmzþò¿Kt]^hö—öÆCm{ \Dd‰¢rŽ¡—(À2œÃGB¯ Ó¿à› tÏÚIþ#G¦4âxô‚‹ön÷dÜ*zô!>èl‘Ø^ø¯­ëÞøm­ßø_Jƒ\ñ¥£Éac4ÞR\Ê [õDZŒ®r>#:Äeø©ÒXr»$Ûv×ÎýWY_SêòªÌ<*©­êÎÖšT&'û(”.KÍ áUAÎ܆~‹€—Ä?à™¿ðR[ã׈›Àž9Yo|I/›s§ê–öØK”vŠeA¶2£;[HN ßZüaøΈÿ µ}ÅÖÖw¸·f¼7, EŒ»ÏÜ)Áò6ã5ð7l4ÏÙSö-½×gëâ[O^Ïaâ/£ÄÃI…\„G´4!²ü |­ÖHÊýNOG‰ÀËé~úRIMì¯{kÓ¯»¼ºy|þgSC±*§îâ›qêíkéצ»G¯ŸÜ_²¿?³ÃûôÏý$оDÿ‚ÞÞø*? øf;½*öo\å´ÝF1Áš¶dŽW#l –ùQNå'q*$ù‡á?íañ›Àß²w‰4ÿhIà‹i£µ—WX]ßCós˜c”ݬ„ŒõÚXci~}·þ Ãáý{öÄø/¯ü5ñ¾.³ðçK:n·+ì¸Ðï06ÅnäÄ-·¢ƒƒò¸SêáxzyEg˜V¨œiÊÍ'fÓ_ž«ÝëßkùøŒæ9•%‚¥¥5Õ]'þZ|]?/âÔü>Mjúf¶~ Q^;Ñp¢Ál¶¡Lnß»ür1ƒéÿ³Ïí¥~Ëßµ˜ü%¢ÜÁñO^•­&×® K•ÊÊ \på‡!PÙ<*þ†ÛÿÁ0>Aû77Ããb^wÿHmxÆ¿Úïó·vQÐE»xûÙj›_ÿ‚eü4Öfø>E§›Cg›‹}iMú]NÍüA°!ùJ€ ©…~/ÊëGÙUŒœ\õ¾ÖïþîœTxkJ^Ò›Šj?;öõþñWþ Ëûq¿í{à+«=bÎ[xq#]Bh "Òõ[!eRÔs´îŽA+ÆBú§í Bü<ÓÉ âdÿÜjƬüøá¿Ù·áµŸ…ü/d-lmFéelïe nšVþ'l}|Aÿ£øÉñ MÕ4ÿ t‡÷‹Â^Á!oí©Ð‡Û#6œ#î@rOÊãi`(æ™›£‚ýÜ$ÛWèºÙ~Kñ²¹õ1upWïÉonþoó©ú$ÌdqÍ ÁIg×ã_ÇÚÃãgŽ~x+Jñcê–^pf±Ôü—†M|ÂãcË.xÑ1Œd…vÜØj“öý­¾5øóá_,ü^u=HXVûM¾HžÝõljþK—|üΘ\cÂø%ƒb ˆn7«[O®Ý»½×O¾ÞdøºŠRµ9h“ûûöß~¿qû#Ex§ìñCÇ_fí#Yñö”l59FÛ[—ù$Õm€.Z<|…¹ÿx ÀÃ>×_ŠÃKZT&ÓqvÓT}>¼kRX¦“W×FÁø‹þN{Áÿö+ëŸúW£×y\ˆ¿äç¼ÿb¾¹ÿ¥z=s›åQ@Q@p?ä¡|Tÿ±¢ý2éuÞWðƒþJÅOû ÿÓ.—@åQ@Q@p³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw•ÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$´ÞQEÁþÎ?òOuûøa«|ý“~ø7^œ\ë~𦗣ê‡âÞÒ(¤!‡nSƒÞ½ŠßÚ|im'K9ÊËçRMô¾Ék~HÒIA*·®‘Zü¡¿éoËÿø+gìáñ|m±ñ$÷ú‡‹t]®›¢C@ɧLû™,V$ç µ€%ðwÙ'Àko„>2øâ h^7ñ-¾·«A¢Âc²MA®ßAˆ–)hùá ƒ+†È$`ŸØ/‹ÿòP¾ÿØÑ?þ™uJü«ÿ‚¡Gàˆÿk]}¼=ô÷3xJÅ¡PÜ|Ñ7ÍŒýàx »oË€?Oá î¶*pÁÎ)*qz¥¿Eåý?ƒâ\¦ž3ÅFM¹µ£¯è}á/ÚêÓö\ømðëÃ> øÅâŸßê0E-áðúi—6Þ±uÌJòOi4³:åFÂà…Ï*ùƒö÷·¾OÚNúâïÇÖ¿SR†»=Z9S)o ÌqºÆFʸ;P‚p8OŒ°x×ZÒWÀsø‚æÀé–çR}U#G»|# ÿ,ÁÆ3žs‚F ÆØ|oã %ø?ˆ.t#aln_UDIÅÉ@f ãh?®à \1ú·'£†Ä}fš|ÓRæ¼RëûwÉ-úê™Õ¯CØNܰjÖoµ¿íï^†‡íá­cAø×ökÆÚoŒµVŽÐv×RkÈh“`ó›ŸÝŒé¶½â·ì_ñ‚çö–Ñô«««k¾*Hï´ÏÛݽŭü*©ûñpÜ…ˆÎyi ¤ú‘ÿ±‡ã¾§àï|-צ¹økâxCÞ^j¡VÿDxþY‘ãóXº°]œnà Hߤ¿ þh¿¾éž Ñã¹6—jmcNÏ+†Évgë¹™˜ñ€ à&mÅTðq¦°íJi4Ó­Ó^Í5ðõ]´g­—pôñ2›®œctÓN÷ë§{§ñtóÕ\~Óš?ïÚ ñÆ_êz>u¢ê¾#·´ÒÅìÒÚ0ƒt–¯”Ͷ$’Mì®#˯ïkëeøI¯º_о;*FAº&õÿ}|/ãÿø#ò¿íy¥è:^µö_k¶×:Ágm÷–pÛÉKn¹3¹ˆ#žÄ“’¸oÐ;?…:—Â¥ðRZÉÿâé¿Ùf3ɸÛy~YO3;ó·Œç>õñ9ݶ*”ðuœ•å§ãmÝZZß?ªÊjãÛ©TIÚ:þ½Wžÿ§ÊzíÏámGö”‡éñÇŸb·ÄìÞnÁ„ìÿ¹Ð s´¶F6áÏÒ𨧕迲>øƒªø®ÇÇ,µñ· A}¨G§è‚k„N€Ÿìþ;g-µs«…ð×쑃¼a­xƒKñ׋lu¯2¾£yŸ¢,·eFãýŸøœc'““Ízõâ:õï'ª¶ýËÑYhzª”ÉoŸS矂_³œš'ÄïŠwzg|M¥_Kâ(a»º´Óôd–ü2Æã|„Ø‘»}Äœ U9,Avvi¿jŸÙ«â'ÄOzî‘áoŠ^)ŸT¼„©´Ô Óa‡PøíüØ-b’2ãÛöžU†Ö$z'Âù(_?ìhƒÿLº]w•¥]Ju£^÷”Zzë¶Û‘S Ò•Y;í¦çâÏÂ?Ùƒâu¯~#ëðßÏà-Ã63Øksj2X. àúxÇ.ìp6ž2P .uÿàœ:ËøCâV·âI¾$¼Ñt 9®56„Ã%Þ§8à ÈñÈÛ¶õF*HÀÏO¿?à«ø&OÙ+R4šþ' t1fOšÚŽÇò†>éM»÷ïà.ì|Ûkò£á¤>›Ã^*oO¯C«G§çÃɧ¢4RÝïL[¢môí¸õ[õì³,ßVucʤÔtôÑ;_[{¿#ó\~9n2œ)Êî*ú»k®öÛÓ¯ÌúÓãïí2¿µ§ì›âK'⧈4ëëÌÔü3â§C&¯kæm…á’ÖÚrr¥£;€nÝFo—¾øXÔþøòúÇÆš~‰¤Ù}ûCB—Qh&×ó!ÙåÂ8—Ë?1ÏLÖwÃè< 7€|ZÞ&ŸÄxš;h‡É­e—ïùä ¸Æ;n<÷ÿ±ìíá?ÚŠïľ×/´O][yÞ,´û‡YåŽbl•ŒÇæ !ô(a(e¸j…Ô#$õì´oÍ¥üÛÇäŽ:¸šØêð”¬ç(µ½®õKѾÛ?™Cà7Ào|iø!ãwðv².,´–‚ëRðÄn.µD]ÄN°$ç¿988Ý¿b{?þÉ_5ˆþ,ñ¶½àëˆ?±´[­e¾ñøùeD¹ŠTãp@X|Ä… »Ú¿à•°Jü(Ðt߉þ"œÉ¯k–"m&Ò•ek2$“iÃÈèà rrßsÒà¡ÿ°¬_µï‚`¾ÒîÓÆ N4ÿ2R-îÐÆáI=wàñÊü®gÄx\F*X É:2jòKï^z¥ïîµ·F}$ÄQÃÇý¬S´oøýÍû½zõBþÉ¿#ý®¾G®hüym}o¶=OK– §Óf#îŸø—ÈpJ¸0€Á•Yû[|YöCørÚÖ·ñ[Ç—zÖèôÍ*(4DŸQ”€ÿg¨279(#‚J©Èÿ‚lÿÁ?Ï쥠KâOÈÒxã\¶ÏSf 2Cy)Û#’ªY¹€€Y¢ÿ‚”Á>ßö¨ÑcñG†]“Æú5·‘¼³mƒT€Â˜íŽ@YŠ·’Cu ¿,°ÙWö·±öØ_Òý¯§7o¼ú¬fÙÞÓ‘{[múÛ¿—ü1Û~ÎÞ*öœømkâ_ |^ñä°K„¹¶{]Oc6>h¤_ìþìz‚85Gö«ýžn)øðÐ}“Eÿå}/ü*ÿÑTñïþh¿ü¯®òŠÈÐàÿáPx‡þЧðEÿå}qZïÂÍu?h¯ ÛŸ‰>5yeðæ³"Ü›]#Í…VëJ5ÇfÖ,¤îRÙv•ƒ{p~"ÿ“žðýŠúçþ•èô ñýOÿà&‹ÿÊú?áPx‡þЧðEÿå}w”Pÿ ƒÄ?ôU<{ÿ€š/ÿ+èÿ…Aâú*ž=ÿÀMÿ•õÞQ@ü*ÿÑTñïþh¿ü¯®+ágÂÍvçÇ?Q>$øÖÝ­üG rI®Z鿲4Öóu‰€`Ÿ UÛñ»s7¸×ðƒþJÅOû ÿÓ.—@ü*ÿÑTñïþh¿ü¯£þˆèªx÷ÿ4_þW×yEpð¨0°ŽÍß“jÑ‚OžÅs»Ÿ4.F6”O.ý«fÿžƒÀ‰ãȵMuol¡ÓtT‰ÚìÙ±?-‰ 8›§î‚v?jÈ~§O †”yš{=^šÛ¿÷“Û¦Ç噿֧^º—;Šku§—§•·8Úž)Ö<9-×´ï‹} Ò µ²’ÜjqùnÛ.dÏßç XŒ“öˆñtþ/ø§]ÍàM7Ào—eÓ-me†;¥)[‚®r|ÐC:©\–9výQø û$\x·à¢øÛe¥x³Åž”]Y<¨ZKð6[Í l\êÙ m»›Ôþ þÏ^ ø§ã]ÄZÿ‡ì5-kÃ24û™T–‹9À`CÀ6B·#œø²ã\- ‘¦©ß“™]JëÊ×Ý;nöé~¾¤xZ½X9óÛ›•Ù­|ïmšì·ê~S|aýº~*Ùü[ðÕÂÙKðöOÛÁ›áÛ[g¶¶·V‰s˜[–YŒÈØÀ õ?¬üm­|FøG kž"ÐfðÆµ©Z¬×Zl¬ [±Ï⡆+|Ê È5ù]ûjüøÇ?í•¶¶/|Gâ/Ýðõý„m1#e’!ò‡,¥¾NX±yýRø¡ø£Ã_ t궺׉í­U5 ËxÌqÍ'>¿x€[ÄÂçÍâÕ…x,4¨(&×ÙnöýUïvõ¿ÌïáLjúÕxÕr²}v¿ùÚÛio‘â/ù9ïÿد®é^]åp~"ÿ“žðýŠúçþ•èõÞWÀŸ`W†éðP߆ڷí#'ÃHµaý¢†-@•û ÷y Ú¬™ÿYÓî³eAÝ€}ʺ1JÔU¢ãuu~«¹…M*×t¤»…TW×Ðé–S\Üͽ½º4²Ë+„H‘FK1<$“Ò¹Ò78„òP¾*ØÑþ™tºÈý³~0ø—àOì÷®x“šºþ­dŸu@e°ŒƒºéÓ9t•\žrp¡ˆó¯Ùöàøoñã'Å]:Ó_‚Õ¤Õ¿µíg¼"Þ ÛXtÛ;ydØãÖ²1a Ð6ÞcÇ¿¶D_¶÷Ã?x3àψã+"ÂÑocò$ñ’©ó~È凖ÍÎ Áq»‹'¹ƒÊq0ÄÅâ)Z1qræM$›ënŸ—]™äâ³* Õžô“Qµ®Úíçý#â?‡?¶?ÄmoÀü9¨iÒüEÒ|Kg5þ¡¡ —CH•Ýz¥Õ…$c¡¶1ƒÁ|ñ=߇üã¸mü §xµu É–þæÖI›Ã©æ ûJáHŽ>mœãr¿}û+þÎß|Ocãèü«¢Åie.›®Å+czÀüÖJs7^8  ÀoSÿ‚E|øqñ‡TÔlÕ´¯ÂNñ4±{}P€GÙMÒ®ã–ÿ–aŽrcþ¯‹Äá0´kΞï+iI­tµí³vÒÛõ?:ÃPÄâ*QŒùµºM«÷Úû¥Öût>nøSâ[½ág¬ãð>Ÿâ{]BÊŸWšÒI%ðæ&eIˆ÷·œdí䌫t¿³7í âÿÙ÷áÏŽ¯<#áÈ¥º¿‚ KŸ-«¼ú nÄYV?0ôÎåd×ï†?³¯‚~x7Qðÿ‡¼;§Øèú´’É{lSÍ[¿3;•÷ä²í%Bœ€¼cóíßû&k¾ ý’%ð×Á›+}+ÖóË{¯hö‘³^j±± ¸JIg ŽPä• Â??G‹p˜ÊÏ :VS”u“ÒÊÛöz+-Ÿ^·öªpæ' IWK¸Eé­ü¾ý^ë¡ÁÿÁÿi?øµîü§^k~ÑmüË}U›û–ìÍ÷Ñðv(Ë.AÛú_žðE?†¿´§Õ 辿¸Ö—X‡Å†9­F›‰š+V$5Ì‹ÁTRÚ~rÊÀ.U±í>ñ‡‹ô=SK¼·¿Ó¯âYíî pñÌŒ2Hê*«`«Ò„jUƒIÞͮۓKF¤Ü)É6·³î]®Ä_òsÞÿ±_\ÿÒ½»ÊàüEÿ'=àÿûõÏý+Ñë˜Üï(¢Š(¢Š+ƒøAÿ% â§ýé—K®ò¸?„òP¾*ØÑþ™tºï(¢Š(¢Š+ƒýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯¨¼®ö¨ÿ“aøÿb¾§ÿ¤’×y\íQÿ&ÃñþÅ}OÿI% òŠ( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ (¢€ òÛcöŒÖ?dÿÙ¯Å^?Ñ|uã¹¼-¦Ýê·1êi°Ãomm-Ì’Í4›™Sl;“Ò’?Ýìß"z½yOí±ð#Äß´÷ìÉâñN…àéük¦]h—ú–© K­$VW0IÂ(c»µ+6$Ê;HÊ¥yóÆuy¹_&ÿ×ôü¶Ôß ìý¬}¯Ã}}>]{yœ7í»ûwÞþÉ_ü9â‹=ÀšŒšõ´·Øø“Æëáéµ V‘4í5ÒæmCQ›qX­Ò%Pƒ"’ŠßAøwU}wÃö7ÒÙ]éÒ^[Ç;Ú]Ú–PÆ9’»×88$dÖ¼#â/ìáñ›Æß´ŸÛ|Uøuis6‰u ø•îþK}¦jÐJ¢4–ÞÕµA%¼Éä>mÅÌNX“@=àçà ‚?¼-àÍ.{Û3Â:E¦i5ä‚K‰a·…!F‘€œªHg<•Ñ.[Ô¶ÜÞï§½Ò×Õß[4ïÅ~Z|Ûò¾o_vßûvÚ+u¾žsñËã—,þ&ü=´¼ñ„bŸDñDÒjÍ«[«ØmÒu *—Ìx•ã\¶0Ì£©ÕËûP|,œ¦ÿˆž-·®ízÐí>£÷œÅÿù(_ ÿìhŸÿLº¥w•ͬpðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽWyEp~Ô? D‘þ"x¼Y*Ç^´Êd`àùœq_)|Tÿ‚Ðé>ý¢,ôÍ L‹Zð ‹µ¾§~™ûEÛ›mÈ]©Ž¬årûªi P»i ‚B®2ÞÃ8ú×á¿íâ­7Rý©õíR'†ôèµmÒønã|XØÃÌŽ@¤Ì„Ê„ÜBà_eÁÙVVªÄÁÉ(靯ýžË¯Cæ8›0¯…§MЗ-Þºvý;õyú¡/íQðÓÄ|­Úøû ¥·…õuiäÕ ˆBòÜéOr`cvXä!ýÛñòœu¾-ý þxÏÂÚ–‘wñ+Á‘Zê–²ZLöþ&¶†eGR¤£¬€«`ðGCY u˜üCñ áeì>¸ð”WÕÚ=hÖ7ÓWí:6"Ú¼A€qŒªœ¨öJù:‹ÙÕj:YþOºÓî>Ž›ç¦œµºþ·?"´ŸØ3à ûL¾‘uñcÀkðö/¶ÓÄVBâh·q§™Äü`±T|Üð§ô¿Fý¤þèZ=¥Œ?|ðÙÂFÓx–ÚiYUB‚ÎÒ–vÀ嘒O$“^T ñV™uâK=FÆMZÒ¹žÉgSq NHWdÎऩ‘ƒŠô³Lë˜òýaß‘t_{~oî82ü¯ ‚æö*ÜÏ¯à—¡Âø‹öÅøSá} ïQ¹ø‰àÉ ²‰¦t·Ö-î&pp‘£–v=¨$šø—Ä¿ðTŸ þÓÍãøöÓPð¿€õè èú–œ]ï¬Ú?™Â)Ä‚FQòŽ;NAÞ¿lþÑß4=áŽb}&\èzh“Qðݬ‘ËpñÊ>O53”B2屨̠~6|ñ¦•áOŠï©jž³ñ¦œð]ì6’eHÃFøueË~ès“’“À0únÊ(סV½X78Û•¦“]U¯³ÛW¥¾gƒÄ™•Z5©Ò§$£+Ý4ß“½ºy-oò+|м¯x¿PƒÆÚö±¡h±X]Iiscd.&žåP˜#d,0ã<òp¥"úü­|íI¡^xßÄSxjËLqwep&û<3]!#–l)9=6’3šÍý‡ ÐµßÚOKÒuï·ôï‰tßìøKù¶bQƒqÌb]Ç,p£-•`C?dßø%w…¿fߊú—Šo¯‰§¶¹-áèîbi±ðDÙç• nà³ë¸‡8¡„…Z¥%)Cݵ¼Ö¼ïÓmœÉrʸ‰Ó«I&£-o'¯+|Ïl‹ö øY}Ÿ<žcomºõ Ü}Oï94CûP|,¶R±üDðjX¹ ¯ZI9'ýgRI'ë]ýøÏÕþ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊï( ‘/?à þý™¿b¿µž­£ø‹ÅqønÂÒßF³¼ŽY!¸[XÃ} !&%FûÁ°ÄŒrEߨ›þ …áoŽþ’ÓÇ:¦…áé«™ÝÒZYj)œ "iºnŒœ÷ ãðPŸÙi¿ðN}Ï„¤Õ.oôM7ìšë.#Ñ]m!,”ç|ªØß+'’ƒm/ø!Lj-cñO‹tÅð‹Ï|ð,òx•"Ö<€-±Â†`\ù˜©ÜPSí¨eipüñ’ƒö—Þ룷ÝÝnßÈùJÙ•xç1©.KmgÚÿgµ¾gÜðÕ ?è£ø ÿ Oþ9_"ÁP>øö˜Ñí¼Yáo‰þ ¸ñ6…mäeÉâkS ô‹b dÂJ >Ç@ÏÞôWËeÙ…lxâ(=WãäÏ¡Æàéb¨ºVú¹ñü{Á_d_‡·wzßÅ_Ïâ¬r_ÚÅâ{Si`«’‘$Úò ÇtœõÚ¼eŸ×þ>þÒµŸXCgãï]Jž#Чd‡\µ‘–8õ{9$rýÕEfcÐ*’x½Äž&Ó¼¡Üêz½ýž™¦Ù¦ùXa…sŒ³± 9=ë†ý¨uË-á-®£ywmk§ÛxÃ÷ÜË*¤1F5›&.ÌN€3’qŠ1˜ªøÊïWYIÿIzh\=5%FžŠ+úlð/Ûoþ ·¡üK='áåÖ‡âýzgI®ncœ\ØZD% ÆØyq€ß(9<àWÃß·‡ÅŸ||ø‡¦øç—ZàÕ¼If%×ô»üÈšMÊb1R“ó© Ú£n1¸Ç©ÿÁh¼Eg©þÑQxJMúÎÉLÚÜ‹´ë¨Àl+ƒµ’< ~låN_8üSñv—â/ø"ÒÇÁÞºÓ4׊çR¥'ÄGÎô‚ŽeÈÏ͸d*ª'ë3•P£‡¡Š§§$îë墲Z®½OÎsìµZÕ°õ$œbÕ•ŸGÓÏW{èút ø§¡ø/Fм)'„õÍ[YÔo4Á.½ݘ‚; ½ç÷Q6~uÛõèrÅõþ ÷ñ_à÷Â_Ù{AÓ´ÿ‰0iÃ]^E­êðÚÜÛܰdb $ýÒ8UùOÞËn,|àìáÛ‹ölð^»§è·µ=q¦ê7k’[£fKˆ÷™7ÏÊdåUB~|(øO üð‡†ü7a¥iɶ8×–süNíÕ$žµó¼]œP­‡X8Ê\ñ“ºvé}í£ò·ÏSÛᬲ­:Ï$¹%f¯ÖÛ_o;ü´1¿áª>ÑGðþŸür¸­wö“øu7íá[äñ÷‚šÊßÚÌÜ rÔÅ’]iLˆÍ¿˜G!œ‘cîš÷àüEÿ'=àÿûõÏý+ÑëóÃíCþ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊï( þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊï( þ£á‡ýáAiÿÇ+ŠøYûIü:Ó¼sñ&kx*¯üG öÏ&¹j«qÒ4ØË¡/ó.øÝr8ÜŒ:ƒ^ã\Âù(_?ìhƒÿLº]ðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽWyEpðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽWyEpðÕ ?è£ø ÿ Oþ9UÿeÍV×]øUq}csoyeyâ=~{{ˆ$E¯ƒ5‘©Ib¥`i¾Õ£î*ëŒ ç ëuðßÄ?ø*çôoÛGDH!šÿÂZ%…î‰y­À̹ۗšÑÚhÐ ¼Q›EŽX;*ïûÄ—úOŒ¾_Ü®»ö-SÓ$kW‹Ùàx‰ûDs}ÕÚ§p~ƒ×7,ÅaÜg‰‡"ž«OÂÝ=7:°˜ü=e(PŸ3†úýO1ñwí©á]_âž¹ð¿Â¾ Óâ$6N¶^©m0ßàjÒ)É•H”3·%JüÅøW­|`Ôm6‹EÖe‹âΧ=¥ÅÅÅÜF6•7 RF$Æñ€‡å‚\^ƒàÿ \~ÑqèoãF´ð¨ÕÚñ9¶t"çmÆÌîR@“ÆrN)ÿ | áþÑ–ž¾ñ¡Ò|1&¦öËâQlɘƒ0Žm„ƒò–8MÙ<_«å¹/§R4ß74|Ðo¿ÞŸòn~wŽÍ«c'MÍ[–VV’]¿ïlw_²†½ñJOÛbÍ<5¬F|y¨Í¡5ýà’ÚñU‹\ Ø1óc³|¤±Ú |ÁM~ª|1ý‘¼ð‡ân·ã Aµ²×uüyò ýݾGÎ!N‘‡<°Nùûð7þ ;ãÿøióaª^\èÞðäñ_عF¾MÛ¢û#ÏS·“ÿ,ºœ’¡¿RãO*5\±Ú1’rOÔ×Èq–cJu`°•N6—.—[¤ßUÙtùŸKѧ7‰ƒº•Õõ×goÕõù%û1~Ï~ ø_ñ—âÆ­ è:müšüVk$Kþ¢Ól.Z(Áâ43O#\TtUÛëÈì>(è_n>1øÄz„:n“¦ø–%–CÉ?غ^GVf<’kÈ¿dø*÷‡¿h‹º…u«¼0÷×[|74’åoSe$ág'%qò¶íƒæÌÃŽÆÓž-'5®÷Ûó²û‘ïK„ÂÎ8vÔ\¶_Ö×{>¹¢Š+Ê=¢¼ëö›ý¦ü5û+|5ŸÄ^"Ÿ,sŒlú„Øâ477EøÊ?`Ïø(ö“û[}£CÖ`³Ð¡kÂzŸü%7/â![3™"KbX›µýQ,ÿ¬ÀÇú³Xå™$ªfqÀbÓŽºÙ_m~çßc\~l¡€xÌ5¥Ûúî»ncÁX~1xƒã¼!â/ëÖ7ß u°>ͬž\ÿnU%Öé ÉeÀè¼ð Ë|óñO^ø­yû,x þm^{‡W7  @÷q¹f„ímêò•MùÚ €FyM{ž´ø ¡êöÞ.’÷Ä÷ZŒñ^xxÛ8[B®Ùƒ“´–Àé× ®ßDý‘n>$~ËÖ6ð‡ˆ垤š~µá´Œ¥Ö•%Äë ±I&Q+2 ¨,ÎÇÛú®†ÀáéÓ“J1›I¸ÛºZô}9ö{uG縊ÕñuêN)¹J)ÙKÑíÕwuò>Ïý…¿g;ÏÚ£ö4Òl~.ÇgâÛ]$þ•f?ÚVvèÅd¦S‘ØüÁAcÛôÆOØÿáïÇoèš¿áëVÓ|9$m§%¯ú3Z¢mÌ*É‚"uP¬£¨Á`¬8¿ø'Wìª~É?¥±Öõk›Íc\•onìVmözcíÇ—è\ŒoqÃP23}_“æù•O¯Nxjžê“qåºJû´¼ú¾»õ?DËp0ú¤c^óŠR¾­Ûkþ‹¦Ý úF‘k iVÖ66ÐYÙYİAˆâ†5**Ž€tÅX¯“?mø*Nû2xâÇÃ^±µñ>³mr­!”¬VPçæ„2ÿËr>¡;‚rпþ8xsö‡øscâ ß-î›z0Êp³ZÊÝ «Ÿ•×##ÜH ž,FW‹£B8ª°jÙÿŸ¯KîuÑÇáêV–œ“”w_×n½Žº¸?ÉÏx?þÅ}sÿJôzï+ƒñüœ÷ƒÿìW×?ô¯G¯8í;Ê(¢€ (¢€ àþÉBø©ÿcDúeÒë¼®áü”/ŠŸö4Aÿ¦].€;Ê(¢€ (¢€ àÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuû[oøR[h¼O?öt’øŠâ7º?ÙĪ,˜B<²íò´Ÿ2ªôbëÖÂCñ?þ„ÿá_wÿÊÊï+âïÚ›þ 9ዟt]{FÕì¼)c®Þ0Ö¬îˆF‘šÑq5‚Êxsó‚§é_øH~'ÿПà/ü+îÿùY_˜_ðPŸ|cŸö´€x¦;­TÓ'Wð½¶‘4’[CqåÉk&Õi˜ ϵ\°ÁUÚ~«„¨bªâ¤°µU7ÊïÖÿ.¶zù=ÄupôðñxŠ|êëåóéúŸ«Ÿ ~èŸ|§øwú|f‘¦D"‚‡Õ‰êÌNIc’I$Ö¶¦Ñ&›pf‰®!1’%Ì2.T/;²8Çzù¿¶W>¯¼#ñ Ëáå·|Ij¤ÅqâK‹97¸Ž;cß0‚ùÆ>èé|cûcjÞøÁ¤x SÓþZx£[BÖÖÏ㽪ÇFþÌÂ4™ù[럶íZ”\›»º»ºOY'Õyž¥<^Ù¦šŠVVzY½“]‘ùWñgÅ~¼ý§µ-ZÃÁ·Zo„X?‡e ™¡Wd%€&"øo”gËÝ´g¯o»ÿ‚©x†PÉg ÙÃðÆÞØè£ÁOýš[…*Ë‚<⻂¤ƒçí~*ê·ÅÆ©¡$?æÖ"¹¶±µ²F·yT©„Æ„’-ª§sgp˜’IªºÌ.?möžoˆþ*t]5,cò¾Ò:°NPÇ€ÌÉ~rÇ–¯Ùç‡ÃW§l£+Sº¼ïmµÿí÷?.…zôg/dÜo>‘·}?ûM¯<ÿðgŠ>?YøƒíóÛøþÂ-n? ^ï‡V·iE´ÀË œ‚ÙßÁLäy•½à?ø#W†<1ûHÜë÷×Ë©xØ­Ö£I¹¥3IŠf# `Î_8l`–ùDø‹ñÖÛ£íQ¦­'Åi/þÍ-ƒ¯ÈéÔÂË‚Û`Îs° 5~©Úx‡â§Ùbóü!ðüͰy…<]v¶9ÀþÍ8÷5ðùö34Àr´ó)ÂÚtóóòžïSër|6_Œæ~ÕÂWׯõÖ;#½‚µ"‰8£P¨Š0ª: }x„lmSÇ_õizÃ{¿hˆâÙ|cw†#;Ñû3ñàoUÉ\û6ðÿö½Õþ(üL×ü!¡éß ïµÿ /-ÓÆ7|Ž7Ïöf$ÇkmÎÖàõø™`ñ îPz$Þg³ô}ϪŽ*‹²RZ»-z­×©·oðŸAøÛ/Æ? ø’Â-GJÔ|K Épȱt½®Õ]O Ž•ã_²_ü[Dø ñƒQñ?ˆ¯íüNšuÖï[´gl ÁΤ`̧!@Ê»¹$é?g?Ú_Uøñs↕á«O‡z¾ªšÜw·0/‹n‘v-…©xû8ùñ€‚à 1Æ6ìwöOøH~'ÿПà/ü+îÿùY]”ñøì9ápSJéé¿åu÷£–x<&*qÄ4¤ã³þ·³û™ÞQ\ü$?ÿèOðþ÷ü¬£þ‰ÿô'ø ÿ û¿þVW”z%/Ú“ö[ð×íaðÖoø‚.x÷I§j1 7lÄ}ôõS€ ÃØ…aãÿðOOø'~…û3[KâNÿKñO‹®^X-ï­Ì´Ó¡ ÈVF|Ƈr À ]¿ðPOüsÐÿg Zã@ð÷‡ô»uj·z.·>¡mhAÞèiÕÄêY•I8_šÿà”¿~&øKñ=Ý”zMÏÃ=&'¹Ô§×õ,,lçÀ9†eŠV‚Ê‚1œ„ýŽ žKVt«¥ ü_uå}-µó׿1˜Œ,sZq©I¹Ûâè»?;wè~þÊÿòl??ìWÓ?ô’*ù+þ {®ønÓÁ°ºðÕÕωîäg±ÖÄf8m!SûÈL˜Ä…²—ü9ÝÆpÞ•û4~ÔúŠ~Çšˆm-~7†¼%£[Ø_^]ø²êÞkW·…#+,CNr’Y·]¥ò ðïø(WÇïþÒÿ²&‘¯èZ7…çø}sxUºÒïäÔîôùÓZL%¶…­°X‚Êr£pWNnÂÖ§™Ó•H´”¬ïxÙÙé~ÿÝë·S|÷Jx ¨I6Õլ»yôÜù£à7ínß³ÁéÞÐ#²ñ߈fû;ø¨Ë¾[;"£0B¤~í÷wƒß8Ê¡_zð­·ü7àv§oâHSEø•ðöÄI‹¥ˆÇ§ßÛŒâ+Éžç¨Ã:ŒSó¤6ìu2.‰!ø`uå¼kÿ°ÆYo6y{¼Ìy›1…Ý÷w|¹ÉÁÒ}kâö‘û󯂤ÞXü'¾Õä‘®á¶Xüÿ/¸ùÞ Ëò–K.Ü’Šô¼f I:´cWžÜÜ×kºóÓNM…Ãb§ìë'*|Ÿ ¬½~ýy÷>Ëñ‡üÃwŸ³µ–— êHž?´ÿH}bwqm~ìè™FvÄ1ò §9"½GÂß²?†ÿdOÙ×KÑ´dZ•׊<9&©ªH€O¨J5«.O÷c\¨Ô–cç?ðK|lÔ¾ì¹Ñ4mgÂö®!ЮµÍ^m>àÄ2#)m9– ,o* „ô_Û㟉þü%µÔ¼U¢øK²‹]Òn#ò¼Uu<ó´½ÁTŒéêXb"X‚J¨f ÄoÌóŒVe*ÒË*Uu=îšÝ¾švþ]“ô>ï,ÃàcJ8øSä÷zô_ð{õGÒtWÏßÿlýGàçÃ3ÅzÝÃhô=iã[ àñ…Üæð>>hÕtÂYUNæ p©§ÅÏÛKPøá=\ñ ŸÃX4ßËzl°xÆîãíjûOš4ÂLJ¬œpK(>08‰òòÓo™´´zµº^O^Xº1¿4Ö‰7ªÑ=¾ó†ý¶¿à•ÚWí)ãË/øbúÏÃÅíÒ stE¡¼ˆŸšáUå¸G 'RTä·Ñ_~øoörøoeá Ù M>Ðnwl4×’7M+`nvÀÉè §xËâ>¯§Áwiáo‡·V·Q¬ÐÍŒîž9Q†U•†›‚ ‚8 ÔßðüOÿ¡?À_øWÝÿò²·Äf¸ºØxaj͸Ceþ}íÒûQËðÔ«KN)J[¿ë¿^çy\ˆ¿äç¼ÿb¾¹ÿ¥z=ðüOÿ¡?À_øWÝÿò²¸­w]øŠh¯ »øWÁKz¾ÖDQ]ž3u¥ofìðU€¡H`ÌK.ÐÎ;Oq¢¸?øH~'ÿПà/ü+îÿùYGü$?ÿèOðþ÷ü¬ òŠàÿá!øŸÿB€¿ð¯»ÿåeðüOÿ¡?À_øWÝÿò²€;ÊàþÉBø©ÿcDúeÒèÿ„‡âý þÿ¾ïÿ••Å|,×~"§Ž~$› ø*Y_Äp›•“ÅWQ¬2di *§¶õØ·§s2í†`q¢¸?øH~'ÿПà/ü+îÿùYGü$?ÿèOðþ÷ü¬ òŠàÿá!øŸÿB€¿ð¯»ÿåeðüOÿ¡?À_øWÝÿò²€;Êàÿgù'ºý"ÿÓÕõðüOÿ¡?À_øWÝÿò²«þË’]Mðªáï¡··½oëæâ(&3EŸÛ7»•ªPrRG;GJôJàÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zï(¢Šàÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuû#6Í3L,ªIÙBéGþ}7¾ÝÙï‡_t_‹> ÓüCáíB SGÕ"[ÜBrwuV ©Á@"¾`ý¬¿à£Ÿ >|ðÖy¡Zx¶÷÷Œú†§¤á×e(D$ƒºa]Am;¾çÉúgü°ü ð‚ü9ðƒ@Ñ4]—ÚÚjA.'×.Ù@™dp>áÆ.Öáp(Qâÿ´ïÄüPøÍqâøPðîª$W7º|ó«ºaº' bBƒž„€ „]r® åÅ9b£/fÔ¹uIö÷¬ôvÕZéõìFcÅÃ¥‡k5}.»û·é}ïòîh~Öºn›7í7«5‡Ä¼ka«ÜEtºüÛÙ£Y@m³mO½pÀU ¢ä|mðe¦ñêçGOXx¶Ýî Wñ8id…·…Ý#‘½ÎÌó³Ýã'Š©ñ‹Yð«ñ:;hšæ—á5ŠØIg}x¯tb®…ÜsŒîçœB/×_üÇÃßõ¯ xãÁz–§£ü*×lΡ}iy«Xøx"M¤Ê\‚†GR7»þ¾®:–•)bdâ¹ZÕ-ì´vÚVZ%£ù#æ©á*bçQPŠ“æOFö×kîµÕ½WÞ}yðÛÁ6ºÅO…^n²¾2¾´ð.­xŠuçÔP\i;$/UÄ´ä®rÌY™½qü¤Iâôñiv]ŽÔØ® `_´ˆ o1y˜Ý³w8Î3_—qÿÁOáZ~Ð>ŸÁž·Ó~ø2Ê}ÇFt q=œÒDóJîrDÎðFýN àî,å¿L4Ï‹šF©ð‚/(Ô#ÐåÓ?µþ{9>Ò°y~gú  –ÛØžÙü›8Ê1¸IF¥kÚ¥íó KDü–ѲÌË ‰Œ¡Oxoòê›Ýy½{š‰à½"?¿ˆK°얢ŵý¤Àx‹ÌÆí›¹Æqš£ñ_Á·¿þkz­ßxnûT´{x5;0 ölÃ×?‘Áá”á‡ç•—ü—_ÿ†˜mJ],Ÿ†ÒeýMäqîâè?yû”ο/\I_¤º6­½£Ú_[‰„°¤ñ‰bxd ÊnG”àò¬‚¬s,§—Jœñ uuÖÖèý;lkÌp¸Õ8Ñ{húo×ç÷Ÿ’ÿÿà˜Ÿ5Ú/PðìÒ\øTx|ùÒø’=æVÏ–öî ™ óÀ ¯ÌiS¾ Á/~-kÿµíifðzx~)c—]-'Ùï<ÈÙQ eÁ‘eVÃ÷Q›pÝ„?­ôWµ>:Ç˚ъºKmŸWç}tz/¾þT8K¹nÞ½úvÿ‚µý?*¿aOØâTµ\Ó]ÏàÈ>j*š–¥ óI±\[ܬžlN¤’ äܪߧ¾%hŸ|¨x‹ÄZ„f‘¦DežyOÑ@êÌNQ’IVÂù(_?ìhƒÿLº]MûA|ðçí/ðÎóÂÞ'µûE•Áóa•0&²œh›ø]wb H>NcœË3ÅB¦3ÝŠ²|«[ußú_Ÿ¥ÊÖ8au“»Õé~Ÿ×SÀ~Á^þ|KƒÅâþ:'™sb—2 Sµ.ÌËX†z‚ Ät_±ü›Âÿµ¯‰u-íÃ~ †Y$Óìî&ý¥j2C#`~õW—ÓæÛ~CøÿëðÿìðsÆ>&ø™}{®Ï4­¥øZ:)•hîgb § r‘€À%qáÿ²Ç? þÎÞ3Ô¼U®xjø‡N´ßá”i@³µ½Ý6uûÌNTƒWËO±|5–b°õªà¥²kÛ¥íu¯½}µ±ó =ÇáëÒ§Œq[ów·¶}­ó?b¾>ü{ð×ìßðÖ÷Äþ(¼ÖÃdp®kÙH;a‰‰ÛØI Gç_í ûLx/ö¥ýŒ%µÐ¯í>ßxJýîdðt;VÏ[YdÊ´{u$¶0Ù*ÃÏþ ~ÞþÑŸ5ŸüSÒ%ñ‰ìæ{Ï ëvb;i,%‘Ç™¸0íì'j¯WO!ðN«à{_…^+·×´nëÅ÷Göݵʥ¥®÷¾r‘“‘ÓÏO—ïW^GÂÿT´®Ÿ´ŒÖªÍ[É=Õ›»i5­¶×›6â¬Ë’“^ÍÅïtïæ×[­v}|§ð¯„lµ€¾)ÕåñÍž™wc}i^o7ÎÖ2÷àù`¶ Î2ù(YŸ^ÿÁü iâïÝÜøžmçµû ß„ØKø[é3#‚¬ƒs Û“—`ÅCþû þÏ>ý«4ïx*ñu}7â Ðý¿AÕ“tº|I;á~@ņdb„.m—Öµ/ Áÿ•øgä–ˬ|iñ¥¤‘ÚÞYôßÛdòÙ†ÙfÎ29Ç?Ö÷ç•ã^rÚr~ÖmYYmdïåVw{§§dqå4]ÓÇM/gîî÷ÕZÝõZl×Ìý"Ohqx#þ¥ÒtõðÿÙ~Åýœ _³yvù{1¸ã·ÞÑ5/7‡'Òtét¶gNkuû7’QB€`WÌßðLßÛÚïö¥ðýdž¼Io;x»A¶K}ìú„ …ó¶9r@+Àn«Üà¦ß·Õïì¿£Áá_ A<~-×-¼õ¿–äéð+½7 ²HJ!q“Î~f²\w×ÿ³þÝ゚â¿ã}þgÞja>§õϱkm¯ø­>GÕúvo¤iðZZA ­­¬k 0Â#‰aUTp øþ û&xÃÆz—Ä#RÔ5í"ßÈÓ¤ÑN´×–DŠ6·E8–F@×ÜÃ’¼'¸ÿÁ9n ?k߇÷vº½”¶þ*ðÚFšŒñ@E¥ê¶BJ¬Ôs´îŽA+ÆBú§íÿ$÷Nÿ±£Ã¿úz±¥‡¯ŠÉsä—bŸÿà—ÿ>|=ð† EÏ‹æ5³ŸM²/pú²J̰’ eŸ%Ó $g‚¬ÿ®”W³:Ç®[Æ.Í·¦÷éånëW×­ü¹pŽ óY½R[ín¾wí·n–ñØ7ö{ñìÓû>iþñ&¹>­¨äÛ—”öx›©PrO;w3`c“ìôQ_#ŠÄÏZUêo'wÐúL=ѧPÙ+p~"ÿ“žðýŠúçþ•èõÞWâ/ù9ïÿد®é^XåQ@Q@p?ä¡|Tÿ±¢ý2éuÞWðƒþJÅOû ÿÓ.—@åQ@Q@p³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw•ÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$´ÞQEÁþÎ?òOuûÔ4?^jµìÛ=JÓJ?Ù63k»”Y®¤dFfKÝÁæÈ˜C""ȌާBÕs-¶û·—+å{Ù?“½ŸàÏ"ý©>+xwá/о_øW²Òm[Ån»ç|`>—r:„Mgû«¼ Wç/ü»]ñ>½ûTÜÂAáû=ÎÖÜC£Ïn¡Î«hí¸i°7±ÏÝÿ–w¨$Üÿ‚ÁøsTÐjW¸Ô¼YˆbÔmD¶v;€—D‡?-» ùT–SÕ²Xòr|Kãï‡5OÁàæÕ|m§xÌ^hóÚ-® ÷ŸØÐÛlßwú¶Nrƒšýk…r:XocŒùœâú?]=6wß¡ùÇæÕ+ûL+”ê¿ÒÛu/þÔ:ߌuÏxe¼eáK ^[è6ÙÅm¦ !j«ˆçe30à‘€6ívà;ö¥Öüa®üPÒ§ñ„,|#«Ç¤ØÅ…¶–,Ò⌤1óû»vaBmOÆÙâ…ô_5{?Ä;X[YèWö/y»$X–oõf0ƒ…¿upº´oìñ“Ÿü-¤êé}ã-OÄpÁg¦ÞÁ3ϺF3nÎÿpDªyl.Ä-œ¡¡ŒÂEÒNpNÒòÛ{]ékk}tòg‹W ‰’¨ù$õü Û}ô±õXøð·â~êß,4üI×-TKákfÛêâ1¶:01!T$?ºä®Û–¶±XÛG 1Ç 0¨HãE ¨ `Ú¿j_ëÿþ?Ýè>'ñ…§ŠõûAo Öª—²\,.G–Ò8Ü XÚGQ· <ÙÙßAÕ|3ð?ÃZ߉“ÆZ”6™u˜Èd¾nVV}B•C˸òÆ¿9✽ѡB·¶çR½–¶Iëîߦ©jï·MÛðþ1T­V—²åj×z]½½ï=Þšo×ø‹û ü8ñWíËá¿]èªÏ©é:޳}b0,¯o-§±Hæ’Òq<:YUûµÞâMʦ>÷Bî«e€Îݾ÷Ebq•ñ :Òr²²¿D0Ô¨ÝRŠWwvîQEsœÂù(_?ìhƒÿLº]w„àWðƒþJÅOû ÿÓ.—\—üÃz¯‰¿dïÅ¥x²5½±žêêfÇuƒ¾Ù¤ûÉæd(+Ë'!ˆ­ð´UjФݹšWíCEWJ”ª%{&ìp_¶‡í-gñOöLñú|2‡Dø€Ú\¥ëÈý• {¥ˆßÛ•uÊ‚¥Áacósà¯ã/á÷Ĉ¼5áK/éWº ‹]»ŸL[¦Òm¼ÀÂTsÊ6A¶>½:¼­I¦¬­ç·ë}ú¿µ¯éß¾%[xw–Zî‹}¦Âšî¥6˜·2i C+$‡ýY$ßîoÃ/³Á0|&Ÿí_X™õÝvì­´ºÄŒÑIäuëòg½Ð0ncö{ý…>2|JøAã]GA]CBÒ•M¥Æ—<’[Iâ`—ç€GÀo-•¹~7£Ûy#öpøá_ÙWÅ>2¼ÕŸÂ~¸»‚Íô»Û©-ŸÄ“$¤mŽ’›qù‡ð¾>ãc|e\>"5hB¬Tœ¢®¯tô¶ÏâÓKi¦»3,+Q•:Ó§'=mfµ¿MµÖúë§Cô“þ ƒðÇÀ~ ý—ôMWÁÒÛêÚí¼Rë—ù po%»ð ,LÅU0nwî>«ûA~Ͼý¥þ^xcÄöbâÒãç‚tÀžÆ`Y¢oáaŸ¡‚$WÁßðCÿ ê—ž:ñ6©mâÈ­4«XV+¿«“Pb>IÙÝT'ל§œþ”WåœAJ¦4Ÿ-W)&Ÿ7U×ðòÓò?BɪC€55µktþŸž¿™ç³/ìÉá¯Ù[á´ðí¾XâKëé}£P›»ŸN¡Tp£Ü’bý¨¿e¿ þÖ åðÿˆa1ËdÓõ”}£N˜¾„õS€ bI¢¼®×öÿZç|÷½úÜô¾©GØý_•rZÖécŽøð'ó—Ã{/ ø^ÈZiöƒs»a¦¼”ºi[s¶O@ Ÿ´wü“Ý;þÆÿéêÆ»Êàÿhïù'ºwýÿÓÕcV¬êMÔ¨îÞ­³Ztã¨AY#¼¢Š+2Š( ¸?ÉÏx?þÅ}sÿJôzï+ƒñüœ÷ƒÿìW×?ô¯G òŠ( Š( ¸?„òP¾*ØÑþ™tºï+ƒøAÿ% â§ýé—K òŠ( Š( ¸?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú€;Êàÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zï(¢Šàÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuû\•ø9¥¢ˆé_6þû/É!͹IIôI|“oó“?Cá?Ûÿþ [yñwâ=¯‹>Åo£â@.»kq:Ç&BKßÇ8ÏßE ĶUO"¸¯ŽðDÍOJÿ„]~k?Úž—k®6¦ëçï] òËÖ!¹Ç/“·ô†Šú\7æT! pžÓUºéN‡ƒ_‡05g9Ê:˳ÛÓשâß?`/†~ØèOá?ø’ê¾çRÕ´È.®nå nlº¶Åã„ =NXõ¿ðÊÿ ?èœx ÿ ûOþ7]åóõ«NµGV£¼ž­žÍ*P§N ÉhÎÏðFÝ_ã儞¼¶Óü ­LÒ_yò“A–TRwL­Ñä€7Ÿ¯üû|*øyàÝ?E·ð'…õ´ø„_jÔ´»{»»ƒÔ¼’ºÌI'Ðg©Ez8ü 8‰]Co?7ÝÛOø78°yV RuhÆÎ_‡’ìºÿHñíSöDð<¿4+Ø~ø$hú6£ â ÐF×/=ƒ[“Ï™‚Gs†ÁÚ üô¿ðÊÿ ?èœx ÿ ûOþ7]å䞉ÁÿÃ+ü0ÿ¢qà/ü'í?øÝðÊÿ ?èœx ÿ ûOþ7]åÁÿÃ+ü0ÿ¢qà/ü'í?øÝðÊÿ ?èœx ÿ ûOþ7]åãÞý‘<aâË©|;ðKÙ^ë1ͤ‡Ñ­$T¶}œlv-~Зo–l|Ù5þ7þÀ_ >3|9¾Ð“Â~ðÝÔã}¶¥¤éZÜÚJÚÙE]ëÏ(Nz0öš+Z5§F¢«MÚIÝ3:´¡RœÕÓÜüâøÿK¿Ô ñ8øƒ¬ÿgI™i¡¶˜ë(‘ÇÝ»ùgéÚç'%03×~ßðIðïÅמ ø¥m¥êòé÷A¦ijVæÒuR@¹”†V¬l2ù€?(û¾Šú OfUáRœç¤ôÑl¼»_©ãPáÌ )Âqޱóß×Ó¡ÁÿÃ+ü0ÿ¢qà/ü'í?øÝyoíeÿÙð'Ç߆ÒYø{DÐ|âKÒé×ÚuŒv±;‘Ìs¬j7ÆØ8,‡‘žU¾Ž¢¼,.*®¬kÑv”vg¯ˆÃÓ¯MÒª¯|SûÁ,tÿ…zSxâ~‘¦k$ºVŽ"åb¼´ÓPðKš9%>ÙU2yMÃ+ü0ÿ¢qà/ü'í?øÝw”VÙŽc_]â1íýÉv^FX,,-%Fв_›8?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆë¼¢¸N³ƒÿ†WøaÿDãÀ_øOÚñºæ¾+þÈžÕü/k‰ðïÁ1Þ¦³¥Í!‹F´…´z…¼— ¶Á•6ë(+ü@•ÁΰÑ@ü2¿Ãú'ÿÂ~ÓÿÑÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãuÞQ@ü2¿Ãú'ÿÂ~ÓÿÑÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãuÞQ@ü2¿Ãú'ÿÂ~Óÿ×5ª~Èž—ã…{ÿßFÔa¼A£ZÚåç°krcÙó0HîpØ;Aa‘¿Ÿa¢€8?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆë¼¢€8?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆë¼¢€8?øe†ôN<ÿ„ý§ÿ®kÀ¿²'ì)k:U÷ˆtßê­¥ÚYؽ´Þ1Ö~ŬÃhûíÆ§l.„:™V$î¾IÙ²wšöjq²‡.ú·~¶v²ü6é}Ù›»—7’ûúÿÃõ삊(¤PWϵ§þ |7ý¥¾ÅÖº‚ü_ãáÍ[CF‰çÔCi:µÛ<·r3•@ö¶Û‰”¬¥¤‘\"}^MûA~ľý§üeáÍÅãÆòj^˜\éGñι¡Ce8YÏXlo!ˆÍ²icóYKì‘“vÒVˆéR{&›ôë§[­,ʺäœz¸É/VšNý,ìîµÐùƒãWímñWá7í…$:޳ñÆÖO‰Z…´O CðòYü­èÿb‚Ké5ÁbÂ;õ–æåÂB$Õ"6îNdûâ¼ÒûöEð>±ñÂÛâ£oâ=cÄV «µ?j—ÚF™p!0 ‹]2k†±¶œF]|è`I1,¿7ïw¥Ó§¥Â_{ùrÅ}÷NOÎNÉ+%Wªæ¶ko;É¿•šK­’»oP¢Š) +æk?´Oø(,^¶ø•ªøãÃwN¥«x§BŸGÓ­´¿C$±;y¡…nþÓ(YÃ-ÅÄâE†iB<µ¯¦+Æ~þÀÿ~üU×]WÄÞ.ÕüQ}ª¹[Å>§uq$0—;Ú8™U˜)`J©£Z6¹"º¥¯ÞíøZþwµ•’—w9K£zyh¯øÞÞVë¨QE#2|y§?õ”Ñg{]aìf[’î)Ìmå°ŽGDr+º©èX šù[ö;øƒñkâ—ñÀÚç¼O£xÓ÷ÚuΔ<{áý"ëÄš&™u“%Çö7‘¤Üd‚÷ìín󊩸ó5°ú£ÇþÒ~(x'Uðæ»iöí[µ’Îò1â2DêU€t!Ѱxd!”à‚¼çÁ¿°çÃßxÅ:•`_ÿ‚˜ÁOôÏÙãã—†ü ¥|ZðëßêÞÔüV5[N†ÿR±¾ÖmmZÆ.ò|Ÿ±5íÍÅÄ`4 2‰—¶ý¡¾-üIøYûfü>Ôañ7Œ´ï…~#×ôý&â[/D¸ðuÄWvòCª<]kûF[Ö‡dò,]U‹0 7Ó_>è<9“âí > FÇUH¼é"Ûsewå´›‘”ü“ÁíÎÖÛ†I…Õ¿b/†úïÆø~ ÞéZÍÖ¿¡±´¾$ÔÛE[øâG{ý”n?³þÔ¨'û?˜CÜS¡îò)ëi¶ßx¾_vÛh“K¢vmKšAWXICw—“¶Žþº¾¶vMY[Ö+ƒýª?äØ~#ÿد©ÿé$µÞWûTɰüGÿ±_SÿÒIiÞQEÁþÎ?òOuûñÞ»ªA&‰áO x‹Âú‡‡¦Ó„ñëvúÄ6ñIºS „HH*c}þgUÇ>÷EDéÆZI_u÷§÷¦ÑPœ¢ïm¿šüR?:ü9ÿ4ñ‡„>j^±øómqkã?‡öŸ ³ø‚çÃÖe/µw¶Ï«ÞHí5ÍÛF¶g’I —b7à³O¥ÑE9Iɹ> ••‚Š(©QEQEQEQEQEQEQEQEWûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’ÐyEPû8ÿÉ=Ôìhñþž¯«¼®/Vý›~kú¥Íõÿ€|{{y+Oqq>‰m$³ÈÇ,îÌ„³I$œ’j¿ü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐy\íQÿ&ÃñþÅ}OÿI%£þ_á‡ýá?iÿÆè²Çà ‡t?ØŸün€;Ê(¢€?ÿÙColPack-1.0.10/Graphs/hess_pat.mtx000066400000000000000000000042341266356121500167030ustar00rootroot00000000000000%%MatrixMarket matrix coordinate real general 43 43 230 1 1 1.0 1 2 1.0 1 5 1.0 1 15 1.0 1 16 1.0 1 19 1.0 2 1 1.0 2 2 1.0 2 3 1.0 2 4 1.0 2 5 1.0 2 15 1.0 2 16 1.0 2 17 1.0 2 18 1.0 2 19 1.0 3 2 1.0 3 3 1.0 3 4 1.0 3 16 1.0 3 17 1.0 3 18 1.0 4 2 1.0 4 3 1.0 4 4 1.0 4 5 1.0 4 7 1.0 4 9 1.0 4 16 1.0 4 17 1.0 4 18 1.0 4 19 1.0 4 21 1.0 4 23 1.0 5 1 1.0 5 2 1.0 5 4 1.0 5 5 1.0 5 6 1.0 5 15 1.0 5 16 1.0 5 18 1.0 5 19 1.0 5 20 1.0 6 5 1.0 6 6 1.0 6 11 1.0 6 12 1.0 6 13 1.0 6 19 1.0 6 20 1.0 6 25 1.0 6 26 1.0 6 27 1.0 7 4 1.0 7 7 1.0 7 8 1.0 7 9 1.0 7 18 1.0 7 21 1.0 7 22 1.0 7 23 1.0 8 7 1.0 8 8 1.0 8 21 1.0 8 22 1.0 9 4 1.0 9 7 1.0 9 9 1.0 9 10 1.0 9 14 1.0 9 18 1.0 9 21 1.0 9 23 1.0 9 24 1.0 9 28 1.0 10 9 1.0 10 10 1.0 10 11 1.0 10 23 1.0 10 24 1.0 10 25 1.0 11 6 1.0 11 10 1.0 11 11 1.0 11 20 1.0 11 24 1.0 11 25 1.0 12 6 1.0 12 12 1.0 12 13 1.0 12 20 1.0 12 26 1.0 12 27 1.0 13 6 1.0 13 12 1.0 13 13 1.0 13 14 1.0 13 20 1.0 13 26 1.0 13 27 1.0 13 28 1.0 14 9 1.0 14 13 1.0 14 14 1.0 14 23 1.0 14 27 1.0 14 28 1.0 15 1 1.0 15 2 1.0 15 5 1.0 15 15 1.0 15 16 1.0 15 19 1.0 16 1 1.0 16 2 1.0 16 3 1.0 16 4 1.0 16 5 1.0 16 15 1.0 16 16 1.0 16 17 1.0 16 18 1.0 16 19 1.0 17 2 1.0 17 3 1.0 17 4 1.0 17 16 1.0 17 17 1.0 17 18 1.0 18 2 1.0 18 3 1.0 18 4 1.0 18 5 1.0 18 7 1.0 18 9 1.0 18 16 1.0 18 17 1.0 18 18 1.0 18 19 1.0 18 21 1.0 18 23 1.0 19 1 1.0 19 2 1.0 19 4 1.0 19 5 1.0 19 6 1.0 19 15 1.0 19 16 1.0 19 18 1.0 19 19 1.0 19 20 1.0 20 5 1.0 20 6 1.0 20 11 1.0 20 12 1.0 20 13 1.0 20 19 1.0 20 20 1.0 20 25 1.0 20 26 1.0 20 27 1.0 21 4 1.0 21 7 1.0 21 8 1.0 21 9 1.0 21 18 1.0 21 21 1.0 21 22 1.0 21 23 1.0 22 7 1.0 22 8 1.0 22 21 1.0 22 22 1.0 23 4 1.0 23 7 1.0 23 9 1.0 23 10 1.0 23 14 1.0 23 18 1.0 23 21 1.0 23 23 1.0 23 24 1.0 23 28 1.0 24 9 1.0 24 10 1.0 24 11 1.0 24 23 1.0 24 24 1.0 24 25 1.0 25 6 1.0 25 10 1.0 25 11 1.0 25 20 1.0 25 24 1.0 25 25 1.0 26 6 1.0 26 12 1.0 26 13 1.0 26 20 1.0 26 26 1.0 26 27 1.0 27 6 1.0 27 12 1.0 27 13 1.0 27 14 1.0 27 20 1.0 27 26 1.0 27 27 1.0 27 28 1.0 28 9 1.0 28 13 1.0 28 14 1.0 28 23 1.0 28 27 1.0 28 28 1.0 29 29 1.0 30 30 1.0 31 31 1.0 32 32 1.0 33 33 1.0 34 34 1.0 35 35 1.0 36 36 1.0 37 37 1.0 38 38 1.0 39 39 1.0 40 40 1.0 41 41 1.0 42 42 1.0 ColPack-1.0.10/Graphs/hess_pat_small.jpg000066400000000000000000000741521266356121500200510ustar00rootroot00000000000000ÿØÿàJFIFxxÿÛC      ÿÛC  ÿÀZ¡"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ý›ø[ð¶ÇâV‡ªêú¾«ãIoeñ·nM¿‹u[H’8u[¨bEŠ„cQ÷}rk¥ÿ†qð÷ý|{ÿ…ƵÿÉt~Î?òOuû=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’뼯(ý¶?hÍcöOýšüUãýÁ7^;›ÂÚmÞ«qc©› 6öÖÒÜÉ,ÓI¹•6ðy1M!y#ýÞÍò$ÊJ*ìºtåRJÕ³oþÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë€øÕûWøÓDñg†|+ðÏáÞ“ã랟ÅwVú׉Ÿ@Ó´ûŒQ„IgtÒ\É4ʱÇäªIYäj‡ôÙ×ãv—ûJüðwÄ«m+Æz=®³k Ê…šž%#€HÜ»°pHÈà‘ÍiÈìßggëy/ž±’Óªf1œd“]Uþôš¿k¦šNͧtVÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï(©,àÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»Ê(ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€8?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»Ê(ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€8?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»Ê(ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€8?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»Ê(ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€8?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»Ê(ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºððV|øû§øJÚÜëzU¬Í¿©[>áb瀱Ä…/ùA¯©=ÿÂãZÿ亭ûMþÓ~ý•¾Ïâ/O–9ŽÆÆ6}BlqN››¢|À~÷ö…ûahsZM'‹ì{3ÌÊÍx–yeèuSìA=ÐË1SÃ4Ö%M»º6×¹*Øe 8ÁW´WûTɰüGÿ±_SÿÒIk„ë;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š+Êm&ý§¿fO|<ðÇŠt/Oã]2ëD¿ÔµM]i"²¹‚H&CÝ©Y±&QÚFU+Ìož=ZŠ™ÁIrËbéÔ•9)ÃFšk>¿šóÀ> º•ꢪ¨è@^ã\ìãÿ$÷Qÿ±£Ä_úz¾ þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( þ_á‡ýá?iÿÆëŠø§û6|:Ó¼sðÚø*¯üG4)‡j«qÒ5)8 ó.øÑ°xÜŠz^ã\Åÿù(_ ÿìhŸÿLº¥ðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yExwÀ/Ù³áÖ³àkù¯<à«©SÄzì óhv²2ǯyh Oº¨ªª:PWkÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãt~Î?òOuûÛáׂž 8–iôkyå`2ò:v=Ù‰$òM\ø¿ÿ% á_ýÿé—T®ò½,no‹ÅÓ…*ón0ÛüßwÒïüÎ.[†ÃÔ•J1³–ÿð;#ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê+Í;ý¢?àž ~9|7»Ñìü5 xSṮÕ4­2im¥ÞZ¯™èÈO#‘‚sÿÄý„ôž¹ñ†² Õ|loõ )ftZÛ]Mi ƒ<–ÄÄÈ@;X(nÝõíp³ü“ÝGþÆéêú½*y¾.žX(Íû7Óôô}Wü†ynx…Š”}õ×õõ]ò¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–¼Ó¸ï(¢Šàÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuûÙoïNצԧÓc9ßr-䳄8AþÑÛÅJ«Vøl<«Õ4œµvZ™W¬©S•Yl•ôÕž•û8É=Ôìhñþž¯«½¯Ë_ø%?Ç‹’|[ÕtmÈø¿EÕ^MCXMVþK{{IÜ’nÀŽFIº€Œdî2/èwü$?ÿèOðþ÷ü¬¯C:Ê'—b~¯9)i{¯Õt8²¬Ê8ÚÚ1k¦¿£êw”Wÿ Äÿúüÿ…}ßÿ+(ÿ„‡âý þÿ¾ïÿ••ä|_ÿ’…ð¯þƉÿô˪Wy^ñO]øŠþ9øln<+ਥOÌm–?]H³Iý‘©®Nž»avÜÊ«· Y{_øH~'ÿПà/ü+îÿùY@åÁÿÂCñ?þ„ÿá_wÿÊÊ?á!øŸÿB€¿ð¯»ÿåew•ÁþÎ?òOuû—c¦-犵æ˜[B±‡òõk¸`vXÑ€(½J¸?ÙÇþIî£ÿcGˆ¿ôõ}]å\ç)ÉÊní÷&ŒW,UQEÅÿù(_ ÿìhŸÿLº¥w•Áü_ÿ’…ð¯þƉÿô˪Wy@Q@p³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEåß| £x“â·ÂíCK°½¼²ñ<ËÓÀ®ñìBP#ŒI N=4=@5ê5Áü_ÿ’…ð¯þƉÿô˪UÂrƒæƒ³ò&PŒ•¤®w”QEAAEPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@[ñËÀš6³ñ›á±w¦Y\ê–^"¸·‚æHƒIgIÔ%Ú ì$Š7Œ€Œõ*àþ/ÿÉBøWÿcDÿúeÕ+¼ª”å$”í·‘*M´· (¢¤¢GN·Õôùí.à†êÖê6†hf@ñÊŒ0ÊÊx ‚A‚ y·ìƒàÝ/ÀåÒtk(l4ûk¶ðÃáR=^ò4ž[й$œ(æ½>¸?ÙÇþIî£ÿcGˆ¿ôõ}V§%Dô}:Énkjw•ÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$µåQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQExí#ÿ ð÷ì×ñRЮüãŸCá.Ç\ñN©£&Ÿö? Ø^\Mooqr.nàžef·¸;,â¸,'( o~¯†ÿà¡ðNψ?µ/í <] éŸ5[½;F³³ðO‰µ¯jZV­ð¯PŽé§ŸQ²µ¶´š+÷wKG+,ÖûűØÅ,™û†Ý8d1Õ@gÆ7rqÚœ,é&÷»û¯§oËÑËt§uU¨ü6_}•ïêïk>–ii~âÿü”/…ö4Oÿ¦]R»Êñ¿t}CâÃë‰/ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—@åp³ü“ÝGþÆéêúøgÐGÇ¿ø\k_ü—\WÀ/€Z«àkùe¿ñª²ø]„|c«Â»cÕïIT¹± 1™²ÌK1$Üh®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’è¼®âÿü”/…ö4Oÿ¦]RøgÐGÇ¿ø\k_ü—\WÅ?€ZŽ~D—þ5e¼ñÐÈdñޝ#*#R|£5É1¶P ÈCm,¹Ú̸Ñ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÐyEpðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—@ìãÿ$÷Qÿ±£Ä_úz¾®ò¼;àÀ- Uð5ü²ßøÕY|G®Â>1Õá]±ê÷ˆ¤ª\€X…˜ÌÙf%˜“ÚÿÃ8ø{þ‚>=ÿÂãZÿäºï(®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èø¿ÿ% á_ýÿé—T®ò¼;âŸÀ- ÇÇ? ¢Kÿ²ÞxŽhd2xÇW‘•F‘©>Qšä˜Û(ä!¶–\ífµÿ†qð÷ý|{ÿ…ƵÿÉtÞQ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%Ðy\ìãÿ$÷Qÿ±£Ä_úz¾£þÇÃßôñïþ×ÿ%×ð à…ªøþYoüj¬¾#×aêð®Øõ{ÄRU.@,B‚ÌFæl³ÌI÷+ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï+æÚ×öÛðÁßß ü=«êno4iõU­ÓÍM*4ûËT2àä×(Û@,Y±Ê†õÏøgÐGÇ¿ø\k_ü—_ þ׿ðJ-NOÚ/B—™“BøªI’jwo=Æ™qäËs.÷rd™LpÊÊÄ–Êíc’½Ìƒ €¯]Ç0Ÿ,líÒï×Ëtº¿¹ù9Å|e**X8s;«úz~}¿úE§j6ú¾ŸݤðÝZÝF³C4.9Q†U•‡ApA©«ÈþþÆ>øYðÿJðý¦§ã‰!Ó oꥢÈÙ%˜E ÂF™bNÕP9ük ÿ†qð÷ý|{ÿ…ƵÿÉuãÕPSj›¼o£ÚëÐôé¹8'5gÕåa|Jø•¢|!ðF¡â/jišF™–yå<E«18FI$XðÎ>ÿ ð¸Ö¿ù.¼Ïö®ÿ‚{蟴'Â{"ÇZñEž³lÿjÓ¦Ô¼G¨êV¢`¤’+‰¤P¬ ”o\äde[\(μ#ˆ—,Õ­l¿¯øfgŠXÒ”¨«É-?üïöŸð¯íðïW‡F¹xuK]oUÔ.4ëœ-ÄPÝj71>!—dʤŒá„ý_ÿÁ5?à›ÒøxÞøÓÆwºž£Õæ“ia¥jÓÙIA<–Ó¼“Ûº9ýän¡U¶2sØðÎ>ÿ ð¸Ö¿ù.»³Ê:8¹SÀÏš¯dú¯?øs“)­‰«†Œñqå—õ«]=òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.¼ƒÒ‹ÿòP¾ÿØÑ?þ™uJï+þ)üЬ|sðÚ$¿ñ«-çˆæ†C'ŒuyTi“å®I²€nBieÎÖ`{_øgÐGÇ¿ø\k_ü—@åÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w•ÁþÎ?òOuû ñ5kO xoÚe‡‡n4Éî˜É5Åì¿nÒî.Y`³Žây'PVØ*…gÉú¢5)‚ÅÈ,q–÷ãŠçµ¯„þñÄÍ ÆÖçÄ>µ»³Òîâ]–qÝy^yX·y~cQ|Â¥Õwª°WpÝÒ¯»–Ÿ…þvÙµ—2ì—Ï]~ë/•ï©âÿ~"kŸþE€üWs‡‰ç0MƘRÿ‰F¤˜ˆ5Ø`v±ÞˆþToâÚ­ÖÂßñý¿ÿà^‹ÿË >/ÿÉBøWÿcDÿúeÕ+¼ þÿˆè•ø÷ÿô_þXQÿ Ä?ôJü{ÿz/ÿ,+¼¢€8?ø[þ!ÿ¢Wãßü Ñùa\WÀ/Šzí¯Ò/†Þ5¼Vñ»!’­ *³j÷ŒÑ÷Êw!%nå;K.ûp³ü“ÝGþÆéêú€ø[þ!ÿ¢Wãßü ÑùaGü-ÿÿÑ+ñïþè¿ü°®òŠàÿáoø‡þ‰_ð/Eÿå…q_þ)ë·>9ølïðÛÆ¶íoâ9¤Ž9.´‚×Mý‘©/–›oˆ ùÊ®ØÛÛU½Æ¸?‹ÿòP¾ÿØÑ?þ™uJ?áoø‡þ‰_ð/Eÿå…ð·üCÿD¯Ç¿ø¢ÿò»Ê(ƒÿ…¿âú%~=ÿÀ½ÿ–çµ?í‘â?€u_Eð»ÅðÜÂ'¾“O–ÊÚG8Y'û5Ô²ý Ú»—p5ôAªivÚÞ›qe{oÝÜm ðL‚HæFee< Aàƒ[áªS…Xάy¢ž«k®Æ5á9Ó”iË•µ£ì~kÁ4ÿoïIñ:÷Â:®‘¬øöÓÄww:¢&ž°­ÖŸs,4Ò/˜ñݼŽÅ•™UKeq’­÷§ü-ÿÿÑ+ñïþè¿ü°®+öýžü#ð_Â!¼ðî“•Ö§â=bÚYK$[jw6ð¬Ù!8—ŒòrNM{zyö7 ŠÅ:¸J|‘·¥ß{l¾^§Q…Äaðêž&|Òü¼¯Ôàÿáoø‡þ‰_ð/Eÿå…ð·üCÿD¯Ç¿ø¢ÿò»Ê+Å=Cþ)üS×n|sðÙßá·mÚßÄsIr]i®›û#R_-6ß/ó•]±·;¶«v¿ð·üCÿD¯Ç¿ø¢ÿò‹ÿòP¾ÿØÑ?þ™uJï(ƒÿ…¿âú%~=ÿÀ½ÿ–Âßñý¿ÿà^‹ÿË ï( þÿˆè•ø÷ÿô_þXWð âž»càkô‹á·o¼G®Èd†ëH ¬Ú½ã4g}òÈIFÀÛ¹NÒˆ>ã\ìãÿ$÷Qÿ±£Ä_úz¾ þÿˆè•ø÷ÿô_þXQÿ Ä?ôJü{ÿz/ÿ,+¼¢€8?ø[þ!ÿ¢Wãßü Ñùa_¿¶gü—â ý¦ôæÓ4ëßZü>Ô[]'R‰LÓÌcxîB’§|RH #BU‰;êuxGí?û5x'âÆï…:Ö» Yêç^’Êf‘~[¸SM¾¹Hå‰e·€lŒn!ˆ>îAÁá+ÊxÊ|馗—Éé®ÞG‘œ`ñ8ŠJZœ­5óùï¦þf·ÁïÚ‹]ø¯ðÇDñ üyjÖ©>}.49POy…Ufw)"º_ø[þ!ÿ¢Wãßü Ñùa]à@AExÕeMÊ É½ö]®z”ã(Á);¾ýÎþÿˆè•ø÷ÿô_þXWþÛ¶Ï‹?gï‚wZ¦›ðãÅ:V£xâÒßQÔÚÂ{;`xâÞæc»ûªà)=IÆÖúj¨x£Âúw¼;{¤êÖvú†™¨DÐ\ÛNã™ä[`ªÒ¥^+Cš)ê»™b©Ô©FP¥.Y5£ì~{ÿÁ-?nßêºÿ€õOëþ;WkVÚïOò>ÕjòÊÒÏç¼òGG’F`ìჾߛr…ûoþÿˆè•ø÷ÿô_þXW%û |ðÏÁ?…Z¥·‡´ØíkOpÇ|÷)m©Ý[ÀÏ$$QªÓïe˜Ÿi®Üó†Äâå[ H¿Å÷·Kö9rœ5zhÓÄOšKðò¿Sƒÿ…¿âú%~=ÿÀ½ÿ–Âßñý¿ÿà^‹ÿË ï(¯ ôÊÚ·þ _ñ ïö¥Ó¯ôÛ ¯ XøPÙhZŒC|²xe{µ‚ï’&þí\ìl’í÷÷ÂÿÚ_]ø—ðóF×âøMãèSVµK€†})Ü?„My…UfK) šçÿi/ÙÁ?hO…~'Õô+KÍRMrK ’ëû»Ø“M½¸ŒL½$Ù-¼dg¶Tåxõ_C›æ8F<-IEjÿO=u»×ñ<\·‹£^¬ñy£'¢ý|»Yü-ÿÿÑ+ñïþè¿ü°£þÿˆè•ø÷ÿô_þXWyE|ñíü-ÿÿÑ+ñïþè¿ü°ªÿ²åäšÂ«‹‰­.,%ŸÄzüm9C-»fô˜Ü£2SÁÚ̹9¯D®öqÿ’{¨ÿØÑâ/ý=_Py\íQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K@åQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQ_Åÿ–Ñ5Úšëᆅðö¤ñ<+>ºñ¦“à?„­®’ámç•ïLà­¼2ó$1ð˜$‡½QRÄú|ÒüÚûÂ^ìG²ÿ‚ÿ$þãìj(¢€ +Î>1~ÕÞ øâÝ'@Ö¥ñ-ö»¬Än Ó¼=ámWÄWq@GçÏŸo;[Á½¶‰f !€bTãÑèZ®e·ùo÷ÑÙïþgñþJ¿û'ÿÓ.©]åpÿä¡|+ÿ±¢ý2ê•ÞPEP\ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}@åQ@pÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©@åQ@Q@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEpÿä¡|+ÿ±¢ý2ê•ÞWŠ~Ô|!ð£âŸÂkOëÖ]ľ"’ä¤ÏÌP¶›l%|}ÈüéâMÍÉ9±Ö` ƒÐÖ³¡RŒå”¶}¡œjÂRq‹M­ü½BŠ(¬¸?ÙÇþIî£ÿcGˆ¿ôõ}]®©ª[hšmÅííÄ–v‘´ÓÏ3ˆã…e™˜ðI'€yìMñŸÃ>kRxsW¶ÔþÇâ]fYÑ2²D—ÕÄQ€`¯ŠÀã‘ÕX cF¤ êF-Ånú+ís7V j›jïeÕØöJ(¢²4 àþ/ÿÉBøWÿcDÿúeÕ+¼®âÿü”/…ö4Oÿ¦]R€;Ê(¢€ (¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Šàþ/ÿÉBøWÿcDÿúeÕ+¼®âÿü”/…ö4Oÿ¦]R»Ê(¢Š+ƒýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯¨¼®ö¨ÿ“aøÿb¾§ÿ¤’×y\íQÿ&ÃñþÅ}OÿI% òŠ( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ ü'ñ&û>Ÿø-5ÐOÙÀxÖÛâÜ>gŒ5ßÚbÛD×$Ô[PŽCªÇá©îÄÒ+HâxmÒ2'CEÃ…»ø³ðûáZü*ÿ‚ŸøŽ4ñü»Ä)¯üe¹ÖÇü$z‰¾ø§¦}£SV6–ìÀõ ùQÛ.h;B¨x=3 Mì“ûù¡Õj´¾Ílº¤ñµGŽÚ5•ƒÊª°ÜqɧÑM;ACÍ¿¿ðÿ>· ûÓç~KîIzôêìµµ®ÏøÛðïX»øŸðúXüyâ»hïüO8‚­ôšoüJ5'ÌE­ µJ~ôÉò»Ö^³þˆèªx÷ÿ4_þWÑñþJ¿û'ÿÓ.©]å 8?øT!ÿ¢©ãßüÑù_Gü*ÿÑTñïþh¿ü¯®òŠàÿáPx‡þЧðEÿå}q_¾k·Þ¿x¾$øÖÍWÄzìf8mt‚¬Ë«Þ+HwرÜäl»˜í ¸Qî5ÁþÎ?òOuûÇ—ÂÎÊîèÆ.¡¸òÙü™B*Fˆ±ÆìUP$mÂ…¯·~þ˾,øQðw@ðõÿÅŸIw¥Ú¬R H4Ù-áêDq5Ť’˜Ð«½Ï 0aGcñþJ¿û'ÿÓ.©]å{™†ˆÅáiá*¥hvZ¾‹Ò˱äàòz8lDñ4Û¼¼öïø÷8?øT!ÿ¢©ãßüÑù_Gü*ÿÑTñïþh¿ü¯®òŠðÏXùËöÃý|cñÏàV©¡ip˶FãvÖ_q®âÿü”/…ö4Oÿ¦]R€øT!ÿ¢©ãßüÑù_Gü*ÿÑTñïþh¿ü¯®òŠàÿáPx‡þЧðEÿå}ð¨5¸kÍrIk¤µoìI¼ÄÛbb§ÎvÈÜnÚËÚÿ ñýOÿà&‹ÿÊú>/ÿÉBøWÿcDÿúeÕ+¼ þˆèªx÷ÿ4_þWÑÿ ƒÄ?ôU<{ÿ€š/ÿ+ë¼¢€8?øT!ÿ¢©ãßüÑù_UÿeË94ï…Wó]Ü_ˈõøÞæp‚[†Íè28ET Ç“µUrxq^‰\ìãÿ$÷Qÿ±£Ä_úz¾ ò¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–€;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Êâ?hïðΟ5ÿÂ%ãÿ`³`øCKþÔÖõÒ*l¶·Üžc ÛˆÜ0ªÇµ~x/Àzÿí ÿAðÇŽ5o„?´ß‡<=­|P³ñ2AuûøsCŸM?ÚIq¼ñ$w&ôEìóî™YÞ5°%@Ž£o£éóÝÝÏ ­­¬m4ÓLá#…e™˜ðI'€~0jŸ>0iŸðTOë±x»ö£»»ñßÅK8<1©dÿu¿Ý0h#‚MÂ)/¤ÒÕÊÉ‘î@+ºB x-3 O­Õ»'Í_Õë¶Š2jöhx§þÃU=¬ïÝ¥’WO]\¢žé¯ÚZ(¢‚ŠùOö¼ý¯<|2±×íôÏÁq&a½¶µðÖ¥¨Çi:¾15¼u`ç 2ð=lVI‹ÃáaŒ«B_zí~×èyØ|× [,59{Ñþ½:žãEpðÑÞÿ wð‡Ö¿ùøhïÐ;Ç¿øCë_ü‰^Ièåp³ü“ÝGþÆéêú¹?Ÿ·O„~ |8Ô+ÖÆä˜¼.šÑ´g·—köºÕv5Ãb+N…)^Qü}=`¢¸?øhïÐ;Ç¿øCë_ü‰Gü4w‡¿èãßü!õ¯þD¯$ôNò¸?ÙÇþIî£ÿcGˆ¿ôõ}\íûø[àÃ+­iôÏÜ_±ò4û[ßj:lWSJ©šâ@žK`_>Á:ÿà¦ÑøƒP¾ðwln…þ£¨^êšmÆ“¦ÏxÓIq<·SB`…^NIX)x8ÆO­‡É1uð“ÆÓá½÷k½ºÿÞul× K,åïKúWõè}ùEpðÑÞÿ wð‡Ö¿ùøhïÐ;Ç¿øCë_ü‰^Ièåpÿä¡|+ÿ±¢ý2ê”ÃGx{þÞ=ÿÂZÿäJâ¾)ü}Я¼sðÚT°ñª­ŸˆæšA'ƒµxÙ”é’a­‘²àí@[hfÆÕb=ÆŠàÿ᣼=ÿ@ïÿá­ò%ðÑÞÿ wð‡Ö¿ù€;Ê+ƒÿ†Žð÷ý¼{ÿ„>µÿÈ”ÃGx{þÞ=ÿÂZÿäJ?gù'ºý"ÿÓÕõw•áß¾>èZW¯â–ÃÆ¬Íâ=v`aðv¯2í“W¼u’Ø€À0 ¤îVʰ ¤×þ;Ãßôñïþú×ÿ"PyEpðÑÞÿ wð‡Ö¿ùøhïÐ;Ç¿øCë_ü‰@Åÿù(_ ÿìhŸÿLº¥w•áßþ>èWÞ9øm*XxÕVÏÄsM “ÁÚ¼lÊtI0ŠÖÀÈÙpv -´3cj±¯ü4w‡¿èãßü!õ¯þD òŠàÿ᣼=ÿ@ïÿá­ò%ðÑÞÿ wð‡Ö¿ù€;Êàÿgù'ºý"ÿÓÕõðÑÞÿ wð‡Ö¿ù«þËš”zÏ«‹ÈVá"ºñ¿2,ð<ª¶³z@xÜ+£`ò¬ÁŒP¢WûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’ÐyEPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@ŸÇ¯„íð7Æ^Õ¦¸·Òük¡Þè7’À@–(n x—-ñWö<ªöÝÅ1û%°‘£ŽIL•h®åfÏèÕSýÝOkïóƒn/Ö-¶½u¸T|ôýœ¶÷—ÊI)/ûy$Ÿ¦– (¢€;ð&‘ñ7†ƒ¯iöú¦‘ªDa¹¶™r’)ýA0Á Ö¢ª2qjQvhRŠ’³Øù§þ ùûø?à%†¿â 6¯µ‹oUÓ »»ÚòÚZÚßÜZ¤h@XC3 ŽÅ}-\ìãÿ$÷Qÿ±£Ä_úz¾®ò·Åbëbj:Õäå'Õ˜áðÔ¨AS£$QEsŸ0~Ú°ï¾<|iøs¬jv“YêƶtÍR[Fÿi[Gawt«'|U@ãæØÄs„Ûô—‡<9aá ÏKÒìíì4ë– {x$p¢ŒP: ä>/ÿÉBøWÿcDÿúeÕ+¼®ªØêõiBI·l»ô°´iÎUa¥-ßp¢Š+”è0¾%|5Ñ>/x#Pðø5=#SˆÅ<Ž£ÕXï ÿ‚zþÇþýŸ|5­êúd2ßkwzÖ«¥BïkMµ®¡=´q¦ ¬ØûÌyà(H×û8ÿÉ=Ôìhñþž¯«ªž6¼(Ë µ nº3žxJ3«ÒŠrŽÌï(¢Šå:¸?‹ÿòP¾ÿØÑ?þ™uJï+ƒø¿ÿ% á_ýÿé—T òŠ( Š( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ (¢€8?‹ÿòP¾ÿØÑ?þ™uJï+ƒø¿ÿ% á_ýÿé—T®ò€ (¢€ àÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuûøñËÇß´øcÀþñφ|9«xV?ÛMâÍFËPÓ.ˆ´û›ë¹l¡Òîbue‚ÚãÎ mmË„mï}ÛlÒ=´fdHæ* ª9uVÇ #=ð3è)Ó\Ô½£ßšJÞI+?ßà9+;_Ö¶¶ú?— ñþJ¿û'ÿÓ.©]åx¿ÆÝÇ2|Oø|ÖÞ"ð¤VÒøžìèåðíÄj²5#™X^¨˜ya×åXþfV襬ÿ„{âýÿÂBïÿ–t„w”Wÿ÷Äÿú<ÿ„…ßÿ,èÿ„{âýÿÂBïÿ–tÞW˜þÊÞ0ÒüIàïZX_ÚÝÜé-×Ἂ)5³¾­w*²Ž¬;~µËþÒŸþ7øŸà—ˆ,|1ã lOlDIc O§ÝN¿ÅW{*Æì¹Šu?y>ðø[þ oð“âã||Ô/Â¥Efüß’üý/7Ì'ƒ¡í¡g»×úÜýX¢¼'ökøñ¿Ã¼?câøKûb `%Kí}Bêþå¸KØ–GUÀ,¨ûÏ÷uÿ÷Äÿú<ÿ„…ßÿ,ëËÄRTêÊš’’N×[?4wѨçMM¦®¶{£¼¢¸?øG¾'ÿÐáà/ü$.ÿùg^eû_|4øßã?€:îŸá¿øbâúh¿yk¦h3é÷wàïŠ9žò`¥‡m ·MÃ<¼-V´iJJ)»]ì¼Ø±]:r¨¢äÒ½–ìïe/éž*øw¬6™¨Yj kâ½}&6ó,¢6m^îEã1º0õWR8"½2¿,?à“_ þ-¿ÅÍ[Tð½âxkÃÖ[ìµÉuk).-.§PvÁä #g™äêcäüÁôOþï‰ÿô8x ÿ ¿þY×¥žåpÀbžE5kù¯'çú9Fa™_’?ðRŸƒŸ?á¦m¥ñL³ø¼A*ÛxrãLµxíœg嶆Îcu'”,ÌIݹ³¸þ€þÏþøÝá߃ž²ñ?<&·oj«qöÏÏs]©$é}Ê긠y¾ßC™ä´°¸:8¨VRsè¿OMí©ã`3J˜ŒU\<©¸¨uÿ?]ÕºÛEpð|Oÿ¡ÃÀ_øH]ÿòÎøG¾'ÿÐáà/ü$.ÿùg_<{'y\ìãÿ$÷Qÿ±£Ä_úz¾£þï‰ÿô8x ÿ ¿þY×ð Bø‹/¯ÍŸŠ¼CÄzèe›Â·R±j÷‚Fj …gÜʸʩ Yˆ,@=ÆŠàÿáøŸÿC‡€¿ð»ÿåð|Oÿ¡ÃÀ_øH]ÿò΀;Êó?Ž~+Òô?Š_­/uK«ßNmášuG›þ%Œ(''ç–$ãø¤AÕ€:ð|Oÿ¡ÃÀ_øH]ÿòο1?à ß~07íi ø™î|K¨øŠq†îôØ;i¢ òAoæ12ó!bÀ’Å›vö÷2 ¦ža]Ò©QA$ß›ôôÝù}ëÉÎ3)ਪƒ•Ú^Ÿðû/3õÞŠñ¿‚ÞøÕ ü*ЬüEãoO­[Ú*]5χ./g Ùd™/¢Y\ áH'æ?1ê?áøŸÿC‡€¿ð»ÿåxõ ¡9A4ìíu³óG§NnPRj×è÷GyEpð|Oÿ¡ÃÀ_øH]ÿòÎøG¾'ÿÐáà/ü$.ÿùgY–³ü“ÝGþÆéêú»Êðï€ZÄY| ~lüUà¨"#×C,Þº•ŒƒW¼0#P\+>æUÆUHRÌAcÚÿÂ=ñ?þ‡á!wÿË:ï(®þï‰ÿô8x ÿ ¿þYÑÿ÷Äÿú<ÿ„…ßÿ,è?ãgŠ´Ý;â÷Â-2âúÖBóÄw3Ánò…’T]QF`:X×êê;צWä?í«ðSãTŸ¶m´ÓßxƒÄšýÐ>¿ÓQ¡·š4mȶãqò<®¬¥²œ³3½¿H¾x;ã•àM"ÛZñ·®uh-cK¹Â×3³H9‘o¢Ú¦zíïæÙ5,hVSsWi~k˦¶wüÑGðþŸürøj†ôQüÿ…§ÿ®òŠòÏþÛ? >øFÿX¹ñ÷…/b°ˆÉöm?U·»º¸=’8‘Ë3€;¤€ 9þÁÿðSï ø¿Z×|/âÃcàõ»Õõ_G¼»ºT¶’;«¹®š ¥l*ʦVÃp®0 ÿ\|aø=áÿŽÿïü3âkïô»õÃ)ááq÷d¿…ר#èr å/ø'×üoÃÿ üe«øßZ¹‹Ä7ZV¹¨iÞŠHð–‹iy5·ÚdSÁ˜´$¨T –#gÐeßÙ_Q­õ«û_³oÂÝ7Þý6ðTñXxŽiî^=rÕ–Þ3¤jQ‡rå]ò"äñ¹Ôu"»_øj†ôQüÿ…§ÿ£âÿü”/…ö4Oÿ¦]R»Êàÿáª>ÑGðþŸürøj†ôQüÿ…§ÿ®òŠàÿáª>ÑGðþŸür¸¯€_´ŸÃ­À×ðÞxûÁV²¿ˆõÙÕ&×-cfŽM^òHÜÿu‘•”ô*Àޝq®öqÿ’{¨ÿØÑâ/ý=_Pÿ QðÃþŠ?€¿ð ´ÿã”ÃT|0ÿ¢à/ü(-?øåw”Pÿ QðÃþŠ?€¿ð ´ÿã•Å|Sý¤þj>9øm5¿¼ðU¬¯â=vuIµËXÙ£“W¼’7¿Ýdee= °#‚+µÿ†¨øaÿEÀ_øPZñÊ?gù'ºý"ÿÓÕõw”ÁÿÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9]åáßÿi?‡ZŽ~MoãïO‡ˆæžåã×-Ymã:F¥w!þUß".OGR+µÿ†¨øaÿEÀ_øPZñÊ>/ÿÉBøWÿcDÿúeÕ+¼ þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊï( þ£á‡ýáAiÿÇ*¿ì¹ªÚë¿ ®/¬nmï,¯jAX1_øˆàÿm^ñ]õQEpÿä¡|+ÿ±¢ý2ê•ÞWñ…Â|BøU’|S0=Oö.©]íQEÁþÎ?òOuû[™Ë»¸’7·Dµ"I +˺{«PAAéh¢ì9<ÛòÖÝ=½ÝÞ›%-fåä—žž’謻·ùoÿ|ø‡ñJŽš~­Å&á ~×á–°™š ·^>ÐÒaOÚW8)݆Âä6÷ûöJø…ñÇÅtßxOÂóê2Â6ÜjZôú}åÔ\l’XRÎ`¬ÃŸ¾ êTf»ŸÚºoŒ¼_ð®ËV±µÔm?á-iü›ˆÄˆ^=#R‘Œ«¢°÷Q^™_AŽÎ©â0°q¤¢á×ü½zÞ÷g„ÊçGSê6¥Óüý:yü$?ÿèOðþ÷ü¬£þ‰ÿô'ø ÿ û¿þVWyE|ùìžûJxã㎅ðKÄ~ð‡„WY†Ø˜žÇ_ŸP»‰áì¢Y$ ’~£…s…? Á,~)|\õ? [iš£½ßˆbÕ¯$†Õ‰?hyÂHÉ1lò‹ò8Êþ®×š~Ë^Ó´ø‚æÊÆÖÖãTñn¿5Ü‘F®]u{¸ÕœŽ¤"*Œô +è2üêž[ *JN}_ë麵¬Ï•ξ.ž&5T:—®ÏÈ¿ÿ Äÿúüÿ…}ßÿ+(ÿ„‡âý þÿ¾ïÿ••ÞQ_>{'ÿ Äÿúüÿ…}ßÿ++ó{þ ñKâçü/6×Å6çÃzn”ëyáè´›É&µgÿHIÊFÏ0-y‘g‰dé¤jR# ÷0÷E=…{Yk ¿íêSSVkÍz~^‡—›åóÆPö0Ÿ.·õõþ·9ٛǿŸw2ÿ’À–R¬nË‚@~§î¡ùG{ÿ Äÿúüÿ…}ßÿ++¼¢¼¼EUV¬ª(¨ÝÞËeäŽú4Ý:qƒmÙZïvpðüOÿ¡?À_øWÝÿò²¼Ûöµø…ñÇÂÿuëß øOÂðj1Bw\iºôú…å¬\ï’(^ÎÌ£Ÿ¾Hêâ¾…¢ž²¥V5e$ìö~L+Òu)Êš“Õ®·GåügâOÅßø[Ú½‡…­Ä>»ßy¯G«ÞÉogÌÙ¼ñŒ“» `#äaw§è§ü$?ÿèOðþ÷ü¬ª_²¿†ôÿ|<ÖŸcib.¼Yâ &ò!XüÖ]^î5-Ɉ£ÑQG@+ÒkÒÏsHcñO j Éy¿7çúXàÊ2ù`ðêŒçÌÿ/$pðüOÿ¡?À_øWÝÿò²øH~'ÿПà/ü+îÿùY]åã¡ù)ÿ1ø©ñuÿiKH|S Þ,«sá¸4«©$¶NFÛˆfÚ$„—*¬ÆÕÆ+ïïÙÿÆ¿õ¯ƒžºñOƒ¼ý¹5ªµÉ»ñö/×kKXʱHW”9Á'„û‹ÑüuðÖ¯|HøI%õ…ä–¾*•ái¡Y DiŒ€©#Œ{'ÿ Äÿúüÿ…}ßÿ++Šø®üE‹À×âϾ ž#â=t³M⫨˜Hu{Ã"€4öÊ«îUlå”*¤•ã\ìãÿ$÷Qÿ±£Ä_úz¾ þ‰ÿô'ø ÿ û¿þVQÿ Äÿúüÿ…}ßÿ++¼¢€8?øH~'ÿПà/ü+îÿùY\WÅ=wâ+øçᱸ𯂢•Ô4?^jµìÛ=JÓJ?Ù63k»”Y®¤dFfKÝÁæÈ˜C""ȌާBÕs-¶û·—+å{Ù?“½ŸàÎâÿü”/…ö4Oÿ¦]R»Êùöòý¶¼'û7|@øwovdÕõm#\þÔ¾Óíy¶¶ocwjdbxþ’PãpCÊ‚ }ðÿâñOÁºˆ©šÚæ•‘zcÔ0 ‚¤¤@ Šë«ÄS£EH5 lú?ëñèsSÅÑYQ„“”w]Š(¢¹€®öqÿ’{¨ÿØÑâ/ý=_WQã_é?|)®k—öúf“¦Dg¹¹¶¤J?RIÀd’@’|ßÿÿý¹|ñÊÿÄ´y´Ý^=sUÕ4è®ÈVÕ-.o§º €p$E— IwFí½tp8Š´§^œŒ7}¿¯Ã©ÏSFHÑœ’”¶]Ï©(¢Šä:¸?‹ÿòP¾ÿØÑ?þ™uJï+ƒø¿ÿ% á_ýÿé—T òŠ( Š( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ (¢€8?‹ÿòP¾ÿØÑ?þ™uJï+å¿ÛOöëð?À?ôkû‰¯õ Z:ž«˜ý›o%…ݨ/þÞn•Âv¡']ßJø_Åw¼;g«i7–ú†™¨D³Û\Àáã™àƒ]u°8ŠT¡Z¤Œö}ÿ¯ø'=,]•%Jœ“”w]‹ôQEr\ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}@åQ@pÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©@åQ@Q@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEpÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©]åQEÁþÎ?òOuû/|Pø¯ðQø{á߆ú®ðëÄãÅ7²ø‡Å÷ºEÍÌŸ`¿±6ÑÅ™v»vÞ‰|ÖÆSfñôjä¨È÷ÁÍ-GHòù·÷Ù~ImÊJO¢K䛜›ùú þßÿðJÛÏ‹¿í|Yðæ+xµêuÛ[‰Ö8!2^ø9Æ~ú(f%²ªyïŸÿàŸ? þü5²ÐçðÆâ›èÿ{y©êúd73ÝÌ@ÜÃz·–œaQNå‰cîW­‰Îñuð°ÁÕ•áǵûÛ¡æÐʰÔqÄÓ¥/éÛשÁÿÃ+ü0ÿ¢qà/ü'í?øÝðÊÿ ?èœx ÿ ûOþ7]å䞉ã?ÿ`…ß~ßhcÂ>ðü÷ ºßQÒtÈ-nm%ípQWpç”'zó7ì]ÿ…›ÁßoõÏŠØê%ëŤiªë4: Vùn¦‘傱7ÌOß ­÷ýëa3¼f <-Z3ü;Ûµúžv'*ÃW¯ EHÞQþ•ûØàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ®òŠòODàÿá•þÑ8ðþöŸün¹¯~Èž¿ñGƒ%Ó~ø%,¬µ™&Õ‚hÖ‘«Û>ò5»˜¿h{s·žB¶>\a¢€8?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆë¼¢€8?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆë¼¢€<{áGì‰à}#Â÷Qkü%ëë:¤Ñ™tkI˜[I¨\Ill8QnÑ¿Â\ `t¿ðÊÿ ?èœx ÿ ûOþ7]åÁÿÃ+ü0ÿ¢qà/ü'í?øÝðÊÿ ?èœx ÿ ûOþ7]åùÿû[Á%ñÆ-;Vønö:N…¯]ãW³„FÈ,Ó¹£8Ç”¼«2ãä'gÔ_ aO…Ÿ ü§èià¿ ë-e$¾Õ4È.òÎîêO'°àt½zŠõq™Ö/‡†´¯mçÚýì´G…ʰØzÓ¯J6”¿­;\àÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ®òŠòDàÿá•þÑ8ðþöŸün¹¯…²'ô ÝE­ü;ðL—¯¬ê“FeÑ­&am&¡q%° °áE»Dÿp1ì4Pÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãtÃ+ü0ÿ¢qà/ü'í?øÝw”Pÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãuÍxëöDð=ÿŠ<.›ðïÁ)ee¬É6¬F´^Øé÷‘¨uØ<ÅûCÛ¼ò±òä{ ÁÿÃ+ü0ÿ¢qà/ü'í?øÝðÊÿ ?èœx ÿ ûOþ7]åÁÿÃ+ü0ÿ¢qà/ü'í?øÝðÊÿ ?èœx ÿ ûOþ7]åãß ?dO麋[øwà™/_YÕ&ŒË£ZLÂÚMBâK`a‹vˆþàc¥ÿ†WøaÿDãÀ_øOÚñºï( þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( ñ×ì‰à{ÿx2]7áß‚RÊËY’mX&i½±Óï#Pë°y‹ö‡·;yä+cåÈéá•þÑ8ðþöŸün»Ê(ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê(ƒÿ†WøaÿDãÀ_øOÚñº±ð ÀR|3øvú3XÛéÁ¬êÓZÚÛ„X¡¶›R¹šÜ*§Ê«äÉch8À#ÚQ@pµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQEóÇíiãÿˆ ÿio€‡Eñu®Ÿà¿øÄxsVÐãÑ¢yõÚN­vÏ-ÜŒåP=­¶Ä…"e+)i$WŸCד~Ð_±/€iÿxs_ñxñ¼š—„f:AÑüs®hPÙNDóÖÈb3lšXüÖRû$dÝ´•¯XUÚ  àqÉÍÒŸ+Þíü´¶¾©»t¾ƒªï5(íÊ“õNM»z4¯»¶¢ÑEÎñ†Ÿ©jÞÕ-tmF-W¹´–+ùmEÒYNÈDs4%”Hˆm…—v1‘œ×…~Á^)ñŸˆï~%C¬øçZø›à­#Ä §xWÅ:ÍŽŸk}ªˆ­ã[ð>Áomo-¼W‚X’EIhæU\ûgćúWŇúß…õØn.4_XͦßÅÜÖ’ËÈc‘VhY%Œ•b7#+ äk‘ý›ÿe~Ê—Hðlž2]-á‚Þ+MsÆzψa²Š)v˨]N-‘Tãl;…\ƒµpCII½­eë{ü¬»jï­’ÕOUwwû¿žŠÚjôôŠ(¢…|—ÿ$ø¡ñ;àv§¢xÃÂþ!ñ·‡ü¡µÎ·yi¤è·¾Óí–ú?¶Ë«¬¢]bUkV"%Ó"MŒ¥¥•P—‹ëJòŒŸ±ÃÞ<‡Ä^+ÒµBíÚ+›8|I©ÙiZ²[Êe…/´ø.ÒùQØ.¡”`ã§GJ—DÓ~kµºú]z„¾ %»_Ö½=u=]X:‚ òïKEWûC|vð÷ìÅð?Å?ð–.£{+:§Êƒ„ˆ™¶¨É,2EvTTT‹qj.Ï¿o2¢Òiµsäø%í¥uûXOñvÏYø§àˆÚχBýº~)üIø#ñæÏÅ·:¯Æ- àO‡ôKKÍgPðM¯„î¬ì®öoµË©G©Ç&¢Öëmä4äi6‰vø¯¯#K²œ« ƒê+Êþ3~Åþý ügm­x¾/êâØ@­¤Âe¬Ûø~ðC/›¹Òbº[ ‘¿¼è~Õ ¸(Õh†”Ô÷oïwßË¢è´Ô'wQÉmeø+mø·Õ»èQEy§í™ñÃQýš?dωt)uÍ[Á¾½Õì´÷$%ÜðÂÏ1aKžGäu¯1ÿ‚}üYñ7ˆµïxKÇúŸÆwñæg¦ê÷zoôÿ [‹k[¿´¤SØ>€·’[k•Ù<òΆ»†¡ücàý+â„uM\Óíum[´–ÂþÊê1$–ò¡I"u<2²± šâ¿g¿Ù7Àÿ²ô:·ü"6:ÏÚõÖ„ßê:߈ujWI l†&»Ô'žãɉKl„Iå¡’Bª ±.““}RKïw®·ÛM¦±ŠŽé¿ÓïÓ›M,Úw{ER¯•¿à¢ÑxóA¹ðÉðÆÏˆ> ñ5kO xoÚe‡‡n4Éî˜É5Åì¿nÒî.Y`³Žây'PVØ*…gÉú¦¹Ýká?‡üGñ3Bñ…õ¹ñ†mnìô»‡¸—eœw^WžV-Þ_˜Â_0©u]ê¬Ü0´œeÙ§ënŸ=¼¯}Ð?†KºkÑô'¯žÝN†5)‚ÅÈ,q–÷ãŠZ( IYX+Ïk?k eÿˆ^"ðö¥¡èúþ‹áëëÍ6÷Ytû[”Ú'˜ ,P8\…ž€q^…X?~h¾k^ñN™o¬øwÄVrXjS q ®r¤2žá”†R gV2”c£hÖŒÔjFRWI£æ/ø%¯íã‹ÚŸÄ=/Æú¯ÄæŸEþÊ»°Ñþ&èz^ã >+«gv–ht»xlÚÊF\Bë¾E–¸¥*ñykõÝy¯À/ÙÀÿ³F¥­êµñÚ·ˆÖÞ=KT×üM©øRºŠÜ?‘ ºÔn'œC›)H•Â+K#ØŸJ®Š²Œ¥x«h¿#šŒ%òÉßúþ¾AEVf§Àÿ¿koŠ¿ ¿l)!ÔuŸˆÖ6²|JÐü-¢xR‡’Ïàío@¿û_I® ߬·7.ê 6©·rs'ß暇ìà}kã•¿ÄMJÛÄZLjìgV1j^(Õ/´2àB`ºd× cm8Œº‰¡$Y~oÞ>ïK¢ž”c |IïåË÷Ý9?9;$¬’š½W8ìÖÞw“~V³Iu²Õ·¨QE ùãö´ñÿĆÿ´·ÀC¢øº×Oð_‹üb<9«hqèÑ<úˆm'V»g–îFr¨ÖÛbB‘2•”´’+„O&ø©ñ÷⥇Š|eñ'LøƒymáÿüVÑ~Ãà+]+O›LÕlno4Û)æºíÚùo ê/*n#‰VÄù¿Ðÿ´ìKàÚÆ^×ü^—kžëû·æ‡¼½ïsmO_®ö¨ÿ“aøÿb¾§ÿ¤’×y\íQÿ&ÃñþÅ}OÿI%¤#¼¢Š(ƒýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š+äoø(ßü~Á_>xDé qñNÕõ­xçÇçÂVŸýž¶çÉó…Ù’Y¾Ñ„@«’˜ç¹¢¾Sð÷ü á^‹ðgÁ$ø‘Š>ë¾)ðÄ*Ôü?uáÍOR¸ð•œ’¼ýJK[W[+c.à—buRÜmp½Þ¡ÿ#ø'¤ëX]xîÒÞêZü8‰d°»U—]º¶K«{UcÖI`’7IÁ00uLœVΜ”Ý;j´×^nNŸÞj?âinb§~–¿Ë—šÿø½é®Ç¸Ñ\Á_^ý¡ü7¨ëÕWÓ4­bûA¹¸û$öê/,§{{˜×ÍD2™7¦QЬq]…GDûëòz¯½Õ®×_5£_'£ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ àÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zï(¢Šàÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuûxÂ÷QðA¹¼Ô4[9®–ÐØ°¿E´ºK;¦¶ie[¤sIå)Êž³â÷üHñ߯Oø“@ñÁðÖ“«ønÂ×MÒŸDûki!Ó↠xLn{Åoof ˆÍ‚DË’+îŠ+I·>g'¬¯wÕÝÉホM¯ånêÍ+BŠºvÚÖ쬢´[-#¦éYèy§ìyû:Gû&~Íø|5gñχ¬Ê_jïl-ŸW¼‘Úk›¶Œ3l2Ï$’.ÄoÁf<ŸK¢Šr““r}A++QR0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®ö¨ÿ“aøÿb¾§ÿ¤’×y\íQÿ&ÃñþÅ}OÿI% òŠ( öqÿ’{¨ÿØÑâ/ý=_Wy\^­û6ü:×õK›ëÿø.ööòVžââ}ÚIg‘ŽYÝ™ f$’I9$Õøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ òŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ ò¸?Ú£þM‡â?ýŠúŸþ’KGü2¿Ãú'ÿÂ~ÓÿÐ?e†*A<è°-?øÝw”QEÿÙColPack-1.0.10/Graphs/hess_pat_small.mtx000066400000000000000000000004231266356121500200670ustar00rootroot00000000000000%%MatrixMarket matrix coordinate real general 10 10 36 1 1 1 1 2 1 1 5 1 2 1 1 2 2 1 2 3 1 2 4 1 2 5 1 3 2 1 3 3 1 3 4 1 4 2 1 4 3 1 4 4 1 4 5 1 4 7 1 4 9 1 5 1 1 5 2 1 5 4 1 5 5 1 5 6 1 6 5 1 6 6 1 7 4 1 7 7 1 7 8 1 7 9 1 8 7 1 8 8 1 9 4 1 9 7 1 9 9 1 9 10 1 10 9 1 10 10 1 ColPack-1.0.10/Graphs/jac_pat.jpg000066400000000000000000001124331266356121500164470ustar00rootroot00000000000000ÿØÿàJFIFxxÿÛC      ÿÛC  ÿÀÿ%"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ý›ø[ð¶ÇâV‡ªêú¾«ãIoeñ·nM¿‹u[H’8u[¨bEŠ„cQ÷}rk¥ÿ†qð÷ý|{ÿ…ƵÿÉt~Î?òOuû=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€8?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»yïaµ–åš(ÞåÌp«0V ͵Aêv«ÊOcRÐÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉuÞTO{ w‘Û4Ñ-ĨÒ$E€wU*€ê@. žÛ‡¨ #þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€8?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®Þ Øn¥ž8¦ŠG¶qʬ ‰Š«m`:¬§³ÜT´ÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w••ì:•œ76ÓEqop‚H¥ƒ¤ŠFC)AÈ"€8øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®ò¢»½†Â!$óE3¤a¤` ³°U\žìÄ;’zâ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»Ê(ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºí罆ÖX#–h£{—1¬ÀX+6Õ©Ú¬p;)=K@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%×yQ%ì2^Il³D×"ÈñÑX°V#¨£{í>†€8øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK®òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.»{KØoâ2A4S¢»ÆZ6 #eÈî¬#±v©hƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºíïoaÓlæ¹¹š+{{t2K,Œ#P2Y‰àI5-pðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—]åE=ì6²Á³EܹŽfÊÁY¶¨=NÕcÙIìhˆÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï( 5øa¡/‚¾9ø³C´¿×ntÈ´-"ú8u-bïR1M-Ʀ’2µÄ’2îX"È3š*÷‡äç¼aÿb¾‡ÿ¥zÅ~Î?òOuûè_bð5¼ñW‚§ˆøB °øVê&^ÌFÄA²ªûY—eC)!‡¸×ûGÉ=Ó¿ìhðïþž¬hÿ„{âýÿÂBïÿ–tÂ=ñ?þ‡á!wÿË:ï( ø§¡|EOü6*ðT²¿ˆæÍ…n£XdþÈÔ‰gPmë°:íNæVÝ…*ݯü#ßÿèpðþü³£âÿü”/…ö4Oÿ¦]R»ÊàÿáøŸÿC‡€¿ð»ÿåqZ…ñþÑ^*DñW‚–õ|9£e>º1Å\Åÿù(_ ÿìhŸÿLº¥w”QEp~ÿ“žñ‡ýŠúþ•ëQáßù9ïد¡ÿé^±E³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQEÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w”Wâ/ù9ïÿد®é^]åp~"ÿ“žðýŠúçþ•èôÞQEÁü ÿ’…ñSþƈ?ôË¥×y\Âù(_?ìhƒÿLº]w”Wû+ÿɰü8ÿ±_LÿÒH«¼®öWÿ“aøqÿb¾™ÿ¤‘Py\íÿ$÷Nÿ±£Ã¿úz±®ò¸?Ú;þIîÿcG‡ôõc@åQ@Åÿù(_ ÿìhŸÿLº¥w•Áü_ÿ’…ð¯þƉÿô˪Wy@p~ÿ“žñ‡ýŠúþ•ëÞWáßù9ïد¡ÿé^±@åQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åpµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”WñþJ¿û'ÿÓ.©]åpÿä¡|+ÿ±¢ý2ê”ÞQEÁøwþN{Æö+èúW¬QG‡äç¼aÿb¾‡ÿ¥zÅ~Î?òOuûüS×o¼ `’ü6ñ­š¯ˆô)“]iY—W³eŒl¾c¹È¹w0ÜUrÃÜkƒý£¿äžéßö4xwÿOV4Âßñý¿ÿà^‹ÿË ?áoø‡þ‰_ð/Eÿå…w”P‡|Sø§®Üøç᳿ÃoÛµ¿ˆæ’8äºÒ ]7öF¤¾Zm¾ 0 _ç*»cnwmVíáoø‡þ‰_ð/Eÿå…ÿä¡|+ÿ±¢ý2ê•ÞPÿ Ä?ôJü{ÿz/ÿ,+ŠÐ¾)ë©ûExªà|6ñ«Ë/‡4hÚØ]il*·Z©17Û6±fkÌm¸(*[Ükƒðïüœ÷Œ?ìWÐÿô¯X þÿˆè•ø÷ÿô_þXQÿ Ä?ôJü{ÿz/ÿ,+¼¢€<;àÅ=vÇÀ×éÃoÞ+x]É ÖYµ{ÆhÎûå;’·r¥— {_ø[þ!ÿ¢Wãßü ÑùaGìãÿ$÷Qÿ±£Ä_úz¾®ò€<;ö“ø§®ê?³¯­æømã[§ðæ£ÜÏu¤­ÔÚÈ ŽùœªŽNÕfÀàÅv¿ð·üCÿD¯Ç¿ø¢ÿòÂÚ£þM‡â?ýŠúŸþ’K]åpð·üCÿD¯Ç¿ø¢ÿò¹ŸxïTñGÅ_…ö÷Þ ñ7‡"OÜH.uôù"v6¦<°-î¥}ÄyP¸SÎp±WñþJ¿û'ÿÓ.©@åQ@‡äç¼aÿb¾‡ÿ¥zÅxwþN{Æö+èúW¬Q@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQEQEpÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©]åÁø‹þN{Áÿö+ëŸúW£×y\ˆ¿äç¼ÿb¾¹ÿ¥z=w”QEp?ä¡|Tÿ±¢ý2éuÞWðƒþJÅOû ÿÓ.—]åeø×ƺOß _ëšåý¾™¤é‘îngm©Ô’p$$^oû üOо(þÊÞ›CÔ!¾Ng¥Þ¢œIks ’Fêy‘ž ‚25ÄÁM?e?þÔ?­âðÆ­t—Úx4mámµs€0骀vqó0ãvkÇ¿à²W‹¼ ßuFÿEÑõû@–Z2œ R3Ê\̤|ª3˜ñ†;‰ÈC‡ú 9n Y\ñr­j©ü?§}w¾ËïÖü·ÖÛÛ­‚§?#ö{ô¾×<3ö7ÿ‚x/â÷íã}X§Ð›ÅºÒ_hS^H¡o¶YÚÚy-Ù%o³UÉÌ)Àoû¾ý’à“Úû@x¶óÅ·–¾&Ðüª¥Ž`ñ|—ò5´K%ž ¬w,d3†ÏÊ0ÿ`Ã+ü0ÿ¢qà/ü'í?øÝ{ü2è×K-mÆÊý¯å}}{?¹y™<ñ²¢Þ9%+»z~^žGy\ì¯ÿ&ÃðãþÅ}3ÿI"£þ_á‡ýá?iÿÆëŠý›?fχZïìëàëïø*òöóÚt÷èv²K ‚+ÿÍÊG¡ÚªÜF4J@Ž|˾4l7"ž Wkÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãtÞWáßù9ïد¡ÿé^±Gü2¿Ãú'ÿÂ~Óÿ×øÃ¼Sû_øÇÁöžøuwy§hšti§ Ô¢]G5û]^Ó"¤–ÛöóÀýY ¥:5&›„[²»·EÝ‘:°ƒJM+è¼ÙôårŸ~4øwöøw}âß-Ž™b¾Æ[‰;b‰ÛbI3¿á•þÑ8ðþöŸün¹ÿ°ÂÿŒß¯´4🇼7u0ßk©é:\×6r€v¶QWzóó!8aèpÃL"¢ëEbP¾¶ÞÄb]UJNŠNVÒû\óÏø'?íÙájþxÎ…âOí}OV´³ž`âúÞêö{¿Ý¶^11V\d…Ü27ú¶¾ÿ‚zÿÁ2<;àøõOxê'ź„•þ“ee,{­Ô¶²LÉ"áÝž&*©ï“êøe†ôN<ÿ„ý§ÿ¯C=†8¶²÷x~ën¶õüŽ,¢X¹a“Æ«OôóóÚ£þM‡â?ýŠúŸþ’K]åxwí'û6|:пg__XøÁVw¶~Ôg·¸ƒCµŽX$[Y] *À€A Šíá•þÑ8ðþöŸün¼sÓ;Êàþ/ÿÉBøWÿcDÿúeÕ(ÿ†WøaÿDãÀ_øOÚñºæ|Yð[Áß~*ü/¾ð÷„ü3 ÞËâ;ˆãNÒൕã:6¦Å "‚T•SŒã*=(ب¢Šàü;ÿ'=ãûô?ý+Ö(£Ã¿òsÞ0ÿ±_CÿÒ½bŠ?gù'ºý"ÿÓÕõw•ÁþÎ?òOuû%ÿÁ:>+AûaEát¸ºÖo5é¥Õ­¼O+°ŽXEón¥~J:4ˆr[s ]Ûзë¥p~"ÿ“žðýŠúçþ•èõíäÙí|µÍÑIó+j¾çòí³<¬Ó(¥ŽQU[\®ú~?ðçMàOÝøSÁzV™ªÝk—º}¤vóê*[×U¤`8ˆÏ~¼’y:ÔQ^4¤äÜŸSÔŠIYÂù(_?ìhƒÿLº]w•Áü ÿ’…ñSþƈ?ôË¥×yR0®öWÿ“aøqÿb¾™ÿ¤‘Wy\ì¯ÿ&ÃðãþÅ}3ÿI" ò¸?Ú;þIîÿcG‡ôõc]åp´wü“Ý;þÆÿéêÆ€;Ê(¢€8?‹ÿòP¾ÿØÑ?þ™uJï+ƒø¿ÿ% á_ýÿé—T®ò€0¾'øRûÇ?5LÖï<9¨jV’[ÛêvŠ­5“°ÀuÓØƒŒá”á‡åwÀ_ø'oÅ4ý¯¥ðì³Ýxjë“E¨Ýø†%vò§¸ó ¦7 tpÀm`?[«ƒðïüœ÷Œ?ìWÐÿô¯X¯s)Ïñ}*”¨¤Ô×U³ïç§G§ã'1Éèã*B¥FýÞÏëºÔî¡C(¬í#(»c-îpÏÐS¨¢¼3Ö8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Êàÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zï(®âÿü”/…ö4Oÿ¦]R»Êàþ/ÿÉBøWÿcDÿúeÕ(¼¢Š(ƒðïüœ÷Œ?ìWÐÿô¯X¢ÿÉÏxÃþÅ}ÿJõŠ(ýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ Š( Š( Š( âÿü”/…ö4Oÿ¦]R»Êàþ/ÿÉBøWÿcDÿúeÕ+¼ ¸?ÉÏx?þÅ}sÿJôzï+ƒñüœ÷ƒÿìW×?ô¯G òŠ( áü”/ŠŸö4Aÿ¦].»ÊàþÉBø©ÿcDúeÒë¼ ¸?Ù_þM‡áÇýŠúgþ’EKûDþÑ>ý˜þ]x—Ä·B("Ê[[!{é±òÅ÷'¹èIàW–Á6k |}ø¡øzÎAcâOivÚuö+ƒ#Ç kÜFxÝmã(Çiꥻ#—âe‡x¸Áû4ìßC–XÚ¬°îKëcèêàÿhïù'ºwýÿÓÕw•ÁþÑßòOtïû<;ÿ§«ã:ŽòŠ( âÿü”/…ö4Oÿ¦]R»Êàþ/ÿÉBøWÿcDÿúeÕ+¼ ¸?ÿÉÏxÃþÅ}ÿJõŠï+ƒðïüœ÷Œ?ìWÐÿô¯X òŠ( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€8?Ú£þM‡â?ýŠúŸþ’K]åx'üOöðßÀ¿ÙÇÄš~­rWñf•w¥é–1f™å…£2Ú4ß’Çè9 W[û)þÕžý­~ůh2ùpmRÓdpgÓf#î·÷à•p0À„2ŽÇ—âVënÙÞ×éë®×Ós•ch:ÿVæ\ö½N®âÿü”/…ö4Oÿ¦]R»Êàþ/ÿÉBøWÿcDÿúeÕ+Œê;Ê(¢€8?ÿÉÏxÃþÅ}ÿJõŠ(ðïüœ÷Œ?ìWÐÿô¯X¢€ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š+™ø·ñ§Á¿<7‰ Ñ­µO |,’ÿ^mfyì^ëE¾Òn§´[ æÙ>Ë  Âyñ¤Ê$ûïöq¿ñ–©û>øçâ-­¥î4)#|3ø9=Ö»ã_x>Û^‘ní4+(lä{aõ²‹¨&òÝÆ>D @UÜIùWí*TêüWÖ~×Áÿ¶÷Óâíø-/í–ý‡O‹õí®Ýÿìúàþ/ÿÉBøWÿcDÿúeÕ(ÿ…Aâú*ž=ÿÀMÿ•õÌø³Àš§…þ*ü/¸¾ñ§‰¼GøŽâ1m¨Á§Ç1ѵ3æokîËÃ3‚>,ú“ب¢Šàü;ÿ'=ãûô?ý+Ö(£Ã¿òsÞ0ÿ±_CÿÒ½bŠ?gù'ºý"ÿÓÕõw•ÁþÎ?òOuû{'yEPñþJ¿û'ÿÓ.©]åpÿä¡|+ÿ±¢ý2ê•ÞP\‡äç¼aÿb¾‡ÿ¥zÅw•ÁøwþN{Æö+èúW¬PyEPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Áf¾1|CðW‚4ÿèöØx_ŒÅ©k9g¹çý ð?t¥Fãÿ= +ƒÒÿÁ ¾*|Eø‡ðZæ×ÅVr\ø_H+o¡k.EÅÀ^̑njÈÛ÷>la=çö½Ñí5ßÙ[â=½í´p jˆå@ê-ÝÑ€?Ä®ªÀõAŠî´ËÂú-¦›¦Ú[Øéö1,öð HáFUG:WÐK8¢òµ€TW5ïÍú÷¿NÖü#üLðßÁß_ø—ÅÞ Ñ<+áÍ)—º®±}•š– I¥eD™FXŽHëðš/ŽÞ/øµÿlÒdðgÆß'„µo‹6÷VÓ·íáKÃZ––uEsooá«t†)áýÔVbGeóp¿v~#ü3ð߯/_økÅÞÑо-Að÷OðÍ–‰mkñ~Öä^Gi· +mÖr·JÊ„‡Ü<Âð_ò0¥}^–]ýè-}[ŠZÛW}5OþãW¢êû{²ÛåÌÞµÑþÙÑExÿí»ÿ¤R_x‡Ç.•üfë·z6±â[¢’-¾›o-œ‘]¼’ÈÊËÆÎѨbc󳜹Uÿ¯•µo²êô“ßúþ»ôÜö +áÏÚÀÿ>ÿÁ;~Þx£â7ìø™Ê3®â¨pgíoøH~'ÿПà/ü+îÿùY_ ÿÁ]>=|X´›Jð–±¢[øS·A.Äú^¢÷°k3#ÎÑD@‰‚Ÿ( ;€s¸l#éøCÛiÃØÚúÞýºÛ­û[ò¹àñ/²ú„½­í¥­ß¥ü½;MÿÁ3>xãàìû‡5Iä{éÕŽ tHØP·PÎNâŸuûLÕô]|£ÿüøÿñŸãÀ ;ÝWÂz&§£}žÓZÕõÉ´éux×þZZÎ\©L¤¨sêÁÍ{—ü$?ÿèOðþ÷ü¬¯3:ö¿^«ííÍw~]¾_Õï¾·;ò¯gõJ~Æü¶Òûÿ_‡mâÿü”/…ö4Oÿ¦]R»ÊðïŠzïÄWñÏÃcqá_E*xŽcl±øªêEšOìHrtõØ» ¶àîU]¸bËÚÿÂCñ?þ„ÿá_wÿÊÊòÎó¼®ÿòsÞ0ÿ±_CÿÒ½bøH~'ÿПà/ü+îÿùY\V…®üE´WŠ<+ঽohÂXŠ®„IºÕv2¿öy,Ä™R (U!›q î4Wÿ Äÿúüÿ…}ßÿ+(ÿ„‡âý þÿ¾ïÿ•”~Î?òOuû¾ý‡/ÂïÍÛË®öÛ¦çÍqW±úŸï¯ºµ¿^›w?Aÿc_…¾,ø5û=è^ñž¸uÍjÎ>Xá…ŒD –ÁúÈ#n>¸*­z•yoìkñ'Æ?g½ \ñÖŠ4]zê>@›؀.LxýÑqÎÏlŒz•|æaí>³SÚÛšîöµ¯~–è{˜>Oag{YZûÛÎçáßù9ïد¡ÿé^±Eÿ“žñ‡ýŠúþ•ëWÒ³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”ÆþÑ~ñO‹¿gßé^Ô×Eñ¦§áûû]P$c~öò-¼Ù ²Rœ•ùiàx—öšø»ðBÒÿcï_ h/‡ž#ÐÆßü[áÛxà];MAoª"x¥yõe¹‡| ¥ˆ'2s³Ÿ×Ú(£ûºª®öqvóƒm|Ú’ûJË@«ïÒt¶º’ùM$ýmeËÙÝÙÜ+ŽøÕû;ü?ý¤ü5o¢üEð/ƒ¼£Ú\‹È,V¡k Ç ""Œö`29ȯlý¹¡øq7ìã­ÿÂÐ(<:1ÇÛÖ•ö\ÿË|ç±»wɺ¼_þçkðÙ> Í/†˜?Žâ#t]'?(ŒÏ¿¦:Ÿ½È}VŽ ä•*ÊŒE$¹ºykÑ.««k]U¾z½LJÍaN5Rƒ__=;¾µüïö=yoí‡àm#â/ÁÛm+[Óíõ+ ¯hQÎexžb‰ÈÞAà‚ÍÀ ýoüçöçµý°< 5½ý¹²ñ~…iD‘Ÿ"áOxÏ@õBrLŠçÿà­ü7oÙ®áühU|DŸð‹›|}´Ýí/ý0û¾n~]¸þ=•×Á9mþCû6i‡á±jàj4á~ÜnöâãЗn6ñÍ}Tèàÿ°ãUQ—´æ·7O¿µ´K¹óЩ‰þÖtÝUÉË~^¿w~·ì{ÕyGí#ðãAø‡ã¿„ÑëšE†¨xªFAq}»t­B`¿îùÄÅz1r+Õëƒø¿ÿ% á_ýÿé—T¯˜§RP—4Ÿ‘ïΚ嚺;Ê(¢ £ƒðïüœ÷Œ?ìWÐÿô¯X¢ÿÉÏxÃþÅ}ÿJõŠ(ýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ Š( Š( Š( €à¤?ðMûŸˆtø&uþÖñæ®4Ûë;¹ÈŽ9¼‰§k•vÎEo!d< €çhúÏöNý˜ôÙ7àý§…t«››çó ÕõÜÌsurÁC¸L‹…(èd“’oü_ÿ’…ð¯þƉÿô˪Wy^¶+;Åâ0°ÁÕ•á½ö¿{t<ì>U†£ˆ–&œ}éNÞ½Hu µK í§RÐÜFÑH%X`ŒŒÁêkóâüëF³ý¸ôŸÚx¿O³ðçˆm¦ÖnêPA¨keS÷¤mÇcª’6 Œƒúw}ÓXÌ–ò¬º2Ç#&ñÃÈÎ8ÈÍ~@|Yý’þ4Kûl.‹u6£ªøÓW»þÒ²×ã‘£ŽX‘†.„ƒýRGò‚6aTº»ÁÒ¨§YBº§î½ÿ=t÷w<Ž&Œi9Qs÷º~_3õÇÁ^°ø}á 3BÒ¢x4Ý"Ú;;XÚF¤h¡TbIàI­:Éð—ªhž Ò¬õÍI5bÖÒ8¯o’ ÝÌ árrp+›ý¥|⿈|A¤x+\_xŽöØ¥­á^G÷7XË ®ñ’¹Èä>N0U+rÎkW¬í¾ýüÏ¢rä¥Íì¶Óîìc|ñæ‹âŸŠŸ¬´ÝVÂúîËÄð´ñA:»Ä“§ÂIôC*½ ×©×ä×ü»öeø±gûXK&š×Þo]y!º¹Œ´eN­Y3‰L‹‚q‚®šýe¯W?Êèà+ªTj)¦“ó^½5Ýy}ïÏÉó ¸Ê.¥Xr´ÚõýtÙùþûyþÅv_¶?ÃHmc¼m;ĺ™6‘rÎÞFötR¨ãcíQ¸ Ê@##*ÞIÿ©ý„Sá†4ÿ‰zõÃKâX,Úu´2Ÿ*ÊÒd ðpò:prï}ß´kƒý•ÿäØ~د¦é$U<ï °—¸þÿ5~ϯük<« úþ“õ]?áŽò¸?Ú;þIîÿcG‡ôõc]åp´wü“Ý;þÆÿéêÆ¼“Ñ;Ê(¢€?7¿jø$ÅÍÏí/áãámV;O øûT’ žòFšm"a ×R(ÉÝ*´pÊP“À+ß¾¾ |#Ñþü0Ñü% ­ÂéZ,>L&yL²¹,Y˜÷ffbg€2¾/ÿÉBøWÿcDÿúeÕ+¼¯[âñ”aB¼¯~>o»¶Ÿðny¸<§ …«:´cg/ÃÉv]¤c|Dð›ñKÀÚ¯‡uˆå—LÖmžÖå#•£rŒ0pÃÏ5ùµð_þ £jŸ¶Ö¿àÝSźv£áÿŧ%½µÈ]Bú9¶@Ê9Œ¦Ñæ°åCÇŒ_ÑÿŠZ&·âO‡Z͇†õX´=zîÑ㱿’5me#†+ýyÆsƒŒÉßÙßöQøÍ'í¤úUŒº‡|[áËÁ{ªë“$v‘»ÌÌx˜L7L‘(,˸ áYÔXlO&!S÷vúWé¥Þ»mˆc^‡5=w_—뮚zŸ¯ðİBˆ¹Ú€(É$à{žM+¸ 1 ª2I8RB¬° vàÌç«Äÿà _ ¼uñ‹öpÕ´oj¦ÃQ“纵A²MZܾÙdÏÈ[ÿÆÒ@'?#…£Õ£JrQMÚïeæ}&"¬©Ò•HÇ™¥²Ý›Ÿ²/Ž´oü4ÕgѵKR|S¯ Úe&ýZîTÎ?½ˆãÕ\Á¯R¯Ìïø#çÀ‰:wÅ›ïAqwáÏY4–µ½ÔG´¨Jù3Œé¬¼MàÝ.YÝdv0_ÙÄW‹ÇÎU‡RHn¡—ªÿ‚wþÃþÈ^žóTº{¿kñ'öˆŽRm­r° kO.{ä/·©~Õòl?ÿìWÔÿô’Zï*^w‹x%€r÷/óô¿këÿ¥•a–+ëŠ>ÿáëêÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥y'¢w”QEp~ÿ“žñ‡ýŠúþ•ëQáßù9ïد¡ÿé^±E³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEx×íÿñ“Ç_³Ïìã¯ü>°ðöµá ÿ[”ø†[²Ã­œ×¬0×ÏF#2À‘ŸÌÌb9&sQ\ÌÒ)Tš§Ùì´Wɶíû®|×~xS@'I× ±Ôü9áûit¦Ô$€¦¥xŽË›´ €­R#W¶<€•.6{¼ Ju­‡U}׿O-t÷¶ïò¹äq,¢£Jõ½Ÿ¼¿áô×O¸ý#ð>µâ?éWú¦—&‰©^ÚÇ5ÖŸ$«+YHÊ D]xm§#4¾°¾‰f·¸·ðf³,S# †V[R#¸5ñ'öÓðOŸ_kºÌ>2´²²BÙŸÂ:¥²ÊÿÃy­Ò0ÌpæQ“Éšùz1oò]ó|:ë¯Ãß˹ïÕ’ö óÙ[âÓ¶ý¼ûŸŸðO¿Ûâ½÷í_µÿÈ”ÃGx{þÞ=ÿÂZÿäJ>/ÿÉBøWÿcDÿúeÕ+¼¯Î¿Úwþ é`>?xE¼¦.±ájM}u5Ìr[Ë©HöÓ[:ÆŒ$w`²ä¾ ?_øöÊð_Äߨkš<>3½Óõ÷Ç$ÕnŒ›â·xË+§k0Êœ^®;%Åá(½xZ3ÛËÉöv×úgŸ„Í0Øš“¥FWqßü×uÐî~&xRð‡ÃígTÑ´i¼CªØZI=®›‚7¼‘FBzgÛ'Ѐ)~~ܯlã®ÚÃyâMwÄ× §ßxtÀŒÅ`E9ò|ÎUÏÜË–$3îý*ñOíoàïøzïUÕ£ñ–Ÿ§XÇæOqsàÝb£9wµ 2H‘ɯ„þ ÿÁL<£~ÛÞ%ñ–¥àë þ.Š+í-Ì—ö"6cö™çq”°óV1Ÿ’27”;ýþ§7†Ä¸á•_wý·õÓ]=ˆ'^…ëû=výMt×Ôý6…ÚHQ™ lÀ¤‚TúqÅx§íýñ§Æ?gmO[ðNŠú–¤?u5à×GˆƒºäÇÕÊðA;›ƒ×ÅûJxrx•ÒÃÇnŽ+/‚5¢„²×ûC~Þþ øðÖ÷UÔ´ÿÜO*46V¾Ô4ôÔ¥#ˆ¼Û˜01’Ä’Bƒ€Ç ~g-‹xªiSçw^ï/ëNúö9¥‡›säÓâíçý|“?àŸ´çÄ]_â烧·Ô,é~<ø«ð¾ÎÆ×ÄÐKˆî&-¨øsPÓb*4mL`Iqh[,>Pw“Œ@±QEÁøwþN{Æö+èúW¬QG‡äç¼aÿb¾‡ÿ¥zÅ~Î?òOuû §^q§ìi)ÚK~ŸðV~™ÛÁµºG$qF¡QPª `AŠ«â?Xx¿A¼ÒõK;{ý:þ&‚âÞtÈÃX¢«øÁÖ_<¥h:wŸö Ö;;:V–AjrÍÉ8µkæå•àýǾ•ãi#äßÙ þ ñà_„?´/¼AoúŒžÖ’ÃD‚ïšj½­Ùp‰Á¹(¬yP™åŽGÖUÁü ÿ’…ñSþƈ?ôË¥×y]Ìu|Tý¦"NNÖײþ¿S6Ž”cÊ· àÿeù6‡ö+éŸúIw•ÁþÊÿòl??ìWÓ?ô’*ä:ò¸?Ú;þIîÿcG‡ôõc]åp´wü“Ý;þÆÿéêÆ€;Ê(¢€?9ÿoO|‡öâðˆÖ¯'³–þð¿Œíôð>Ê ¡1<¬§)#ɰJd¡-ò¿-úá{-7NðÝ„4vqi[ƶIh[¬!FÁß—fÜccùËûWÁ'µÿiø[UTð×ÄRX¤šþfš}&&k™T’wL¦8ed$ç+µˆáÛïÿ‚ŸôÏ to hò^M§è°y1Iu1–Y %™˜ŸV$àaFp úÌú®x<4h×”Ú[>Ÿäú[]ÖÖ¿ÎäôñÅWuh¨&÷]Íu¾šßåÑê6–÷ú|ð]Å Ö³FÑÍÊ9Œ2°<Fr¯ÎÙÃÂ?³·ü¦Xl5,=5JŒl‘ÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$µÞW1¸WñþJ¿û'ÿÓ.©]åpÿä¡|+ÿ±¢ý2ê”ÞQEÁøwþN{Æö+èúW¬QG‡äç¼aÿb¾‡ÿ¥zÅ~Î?òOuûÕ4ëíoú ¨’ÓXÈÆ½ÚVcó#`ˆÀË.Ò0Pe=Ê9z™|³µÊž×ÖÝ_ü ßÝ&¦qFØàš|Ï­´òÿ‡Ù}öûê¸?Ú;þIîÿcG‡ôõc]åp´wü“Ý;þÆÿéêÆ¼3Ö;Ê(¢€8?‹ÿòP¾ÿØÑ?þ™uJï+ƒø¿ÿ% á_ýÿé—T®ò€ àü;ÿ'=ãûô?ý+Ö+¼®ÿòsÞ0ÿ±_CÿÒ½b€;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Êàÿjù6ˆÿö+êúI-w•ñ'ü#ö—ñÃZø?EÒ®ì4/[kom;þ]v>´®âÿü”/…ö4Oÿ¦]R»Êàþ/ÿÉBøWÿcDÿúeÕ+Ã=c¼¢Š(ƒðïüœ÷Œ?ìWÐÿô¯X¢ÿÉÏxÃþÅ}ÿJõŠ(ýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ Š( Š+Í¿kÚ{Gýþë^<×4OxƒNÐí§»šÓÃÚ[_]á‚K‰]‰+ (±C!2O$Qä*nÞñ£)IE]—JrQŠ»g¤Ñ^EûB~Ù~ýœ<%á=gUÐ|g«Zx»PÓì!m'J3ŧý²îÖÒ9n§fH!Q5äa“Íp\Ç‚96úí[‹Wo£kæ­uòº3Œ”¢¤¶jëÐàþ/ÿÉBøWÿcDÿúeÕ+¼®âÿü”/…ö4Oÿ¦]R»Ê‘…p~"ÿ“žðýŠúçþ•èõÞWâ/ù9ïÿد®é^@åQ@Âù(_?ìhƒÿLº]w•Áü ÿ’…ñSþƈ?ôË¥×y@û}~Õ>ýš¾ ÝE¯ØÛk÷þ#†[K eÝ÷;Kéî\÷9zÿ‚A~Õ>ñÃko†‘i–^ñN˜¯p vkëÜn$“0oR~ꂸQµ=ßöèð7ÃÏþÏ:Áø‘4V5„fh/Ài³ŸCvrxÙü]¨ñŸø#Ÿ‚~XüŸZðÝÈÔ|oqˆ|A%Ò*]Xäå`rvÀqÀþðŒœŸ[†XOì*ŽPŸ?2Õ_–ý<¬–÷ÖíwVùÊïý¯¥^W§[uó½öéeë²+ƒý£¿äžéßö4xwÿOV5ÞWûGÉ=Ó¿ìhðïþž¬kä£;Ê(¢€8?‹ÿòP¾ÿØÑ?þ™uJï+ƒø¿ÿ% á_ýÿé—T®ò€ àü;ÿ'=ãûô?ý+Ö+¼®ÿòsÞ0ÿ±_CÿÒ½b€;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Êùþ ÉûRxOáÇÁ›ÿ^éöº÷‰|QhM½¬«”ÓîU»cÙÕØ$©'Ž¥ÿ‚iþÕÞøïðfËú6›eák–© Þ‹nˆ&qöˆI$²;±bX;Ää3eÁZ|ðëVýœ®µ?Í—ˆ¬‘×Ó»žçÕ¢'óÂŽG8§ÿ‚køá·„ÿfí:óáÝÊꋪm_P_Mv£æŽuù{7ac¨S[yvúÙ¬'ö _$ùù÷×–ýûZÚw¿ÌùȼGöÃ\ÑååÛ­¿;ß^Ö>‚®âÿü”/…ö4Oÿ¦]R»Êàþ/ÿÉBøWÿcDÿúeÕ+ä£;Ê(¢€8?ÿÉÏxÃþÅ}ÿJõŠ(ðïüœ÷Œ?ìWÐÿô¯X¢€ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š+Æÿoÿ†9øåû xûÀŸ´ÿ _kÞ:Ðï¼:_Ä:ÕÆ•gc ݬ°5Æø-.žGŒº‘ÅÏ￲QQ8)EÅõ4¥VTæªGuªõè|§ûTüøéñ·ö=ðƒ´ |&‡Å–ú®¨ëqÞxëPN³^©i}[Nš;Épg[MŒ^<£&G›·éÿ \jW^°—X´±°Õ¤·¯m¬îÚîÚÞb£zG3ÇH²´hXJ.p.Ñ[J£|×ûRrù´“ü—Ýêa(B0ŽÑV<_ãoÁPøŸðúâKϬš·‰çYÄ^(ÔâDÿ‰F¥'î‘nÀw ˆ/ÊY~ë2ž³þÇÃßôñïþ×ÿ%ÑñþJ¿û'ÿÓ.©]åAgÿ ãáïúø÷ÿ kÿ’ëŠ×~hQ~Ñ^³þ51OáÍffcã\Ê.´ ÈnwªâFÊ© Ä)`J)ã\ˆ¿äç¼ÿb¾¹ÿ¥z=ðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—]åáß >hWÞ9ø“ßøÕVÏÄpÃÆ:¼lÊt5òì· ÈÙr79-´*çj¨¯ü3‡¿è#ãßü.5¯þK£áü”/ŠŸö4Aÿ¦].»Êù“öÐÿ‚wØþÐ Z×AÖ|I¿¥³\Ø&«âýJÒáñƒ-ÌÒ$p@ õȯ,ÿ‚bÁ;O†|Äj:Å­÷‰¬QôÛ'W¹ÓÌ6’m‘dš[iÙœm"=ÛTcp,pŸwWû+ÿɰü8ÿ±_LÿÒH«Ø¥žâéàe—Æ^ãûíÕ_³<Ê™FxµŒ’÷×ÝäýPÃ8ø{þ‚>=ÿÂãZÿäºâ¾>üд¯XKÿY›Äz$Mã^eÛ&¯fŒB½É€bU€Ü­†RAã\íÿ$÷Nÿ±£Ã¿úz±¯ôÃþÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¼¢€<;âŸÀ- ÇÇ? ¢Kÿ²ÞxŽhd2xÇW‘•F‘©>Qšä˜Û(ä!¶–\ífµÿ†qð÷ý|{ÿ…ƵÿÉt|_ÿ’…ð¯þƉÿô˪Wy@ü3‡¿è#ãßü.5¯þK®+Bø¡KûExªÌßøÔE‡4i•‡Œuq)gºÕA ¹ÞËˆ× Äª’Å@.Äûp~ÿ“žñ‡ýŠúþ•ëÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w”P‡|ø¡j¾¿–[ÿ«/ˆõØ@‡Æ:¼+¶=^ñ•K  ³¹›,ij{_øgÐGÇ¿ø\k_ü—Gìãÿ$÷Qÿ±£Ä_úz¾®ò€>(ÿ‚–ÿÁ>m|oð®ëÆ~ÕuÆÕ|c5ÕŶ­­]êIsk´’k™$hÝ@b![¦3ÍtŸ°_ü…>ü6šçÅz¯ˆÄÚÿ—5妑¯ÞiÖö  ìˆ›Ycó¤Žæb@' À,þïûTɰüGÿ±_SÿÒIk¼¯bYî-à³Ü½ÏÆÛÚý¯¯üÌYFbþº—¿øzúØàÿáœ|=ÿAÿáq­ò]s>,øM¥øâ¯Âû˯O,ž#¸„®£â=CRˆ)ѵ3‘Äò l¨ù€ÜFpH>Å\Åÿù(_ ÿìhŸÿLº¥xç¦w”QEp~ÿ“žñ‡ýŠúþ•ëQáßù9ïد¡ÿé^±E³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQEÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w”Wâ/ù9ïÿد®é^]åp~"ÿ“žðýŠúçþ•èôÞQEÁü ÿ’…ñSþƈ?ôË¥×y\Âù(_?ìhƒÿLº]w”Wû+ÿɰü8ÿ±_LÿÒH«¼®öWÿ“aøqÿb¾™ÿ¤‘Py\íÿ$÷Nÿ±£Ã¿úz±®ò¾?ÿ‚›þÞš7ÀýÛÁÚ'Ùõ&¡§ê²Ä[0ikmu Ü~vKHbPv¶âGË»³€¯Œ¬¨aãy?ÃÍöG.3K IÖ¬ì—õ¡öå_²?ímáÏÚóáªkz+}—Q´Û«¦Há¦Ó¦ àï#`”p0À„2U¬qz”*:5•¤·F´kB´JnéìÎâÿü”/…ö4Oÿ¦]R»Êàþ/ÿÉBøWÿcDÿúeÕ+¼¬MB¸?ÿÉÏxÃþÅ}ÿJõŠï+ƒðïüœ÷Œ?ìWÐÿô¯X òŠ( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€8?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–»Ê+ƒø¿ÿ% á_ýÿé—T®ò¾ý¼ÿচ?Â>Ñ|/goâ;ïëM¬He+·Ù®-d´FòÔ%Ä„·!TÇrŽü¿-Äcªû4n÷ôõg7C OÚו‘÷Çü øëáÏÚ7ᵊ|/z.ôëϑрY­%†UÉÛ"ädt ‚ R ì+’­)Ó›§QY­gM:‘œTàî™ÁøwþN{Æö+èúW¬QG‡äç¼aÿb¾‡ÿ¥zÅ™aû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@Q@Q@Åÿù(_ ÿìhŸÿLº¥w•Áü_ÿ’…ð¯þƉÿô˪Wy@p~"ÿ“žðýŠúçþ•èõÞWâ/ù9ïÿد®é^@åQ@Âù(_?ìhƒÿLº]w•Áü ÿ’…ñSþƈ?ôË¥×y@p²¿ü›ÃûôÏý$Š»©eXcgvTD™˜à(Íyç쉫Ú벿Ùìî`»„xoO„É Ô:[¢:äwWVR:‚¤E>Wnkh+«ØôZø›þ ð¿áÅÇÃ;ÄÚÝâhþ4ûL6¶-m’çS·óL­FñlÎ ¹ùÀ¯¶kàïø+7ì3«|HÔ­þ#ørîóQ¿i,ô›&i‹ŒË2[Àm8\É"†A€K–êZ½î©NŒ%V¯³]ûù>‰>·ÿ‚xùü',ãNŸ;íú¯4}9ûü:ðÃÏ€Z,f·¿Ð/â'Q\µÃI)êAS˜ÛŒWª×‚ÿÁ>ÿcùÿd„2éú†©q­kr%æ¡ ÌÍgg \l…:g àeʎʵïUçæŽQÓ›š»÷žìíËÔ– pävÙt8?‹ÿòP¾ÿØÑ?þ™uJï+ƒø¿ÿ% á_ýÿé—T®ò¸À®ÿòsÞ0ÿ±_CÿÒ½b»Êàü;ÿ'=ãûô?ý+Ö(¼¢Š(ƒýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ ö¨ÿ“aøÿb¾§ÿ¤’×y^ûXÝEeû-üH’i(dž5!¹Ø(ɵ“êHS]Ö¨Ûêú|v“ÃukuÍ Ð¸xåFVVAÁŸ+·5´ÕìM_Ÿ?ðU¯„Ÿ-þ2ø/PÖ5–ðæ½¯ê1Çâ°€LçOÃy"ºá¨nKÄ+Áý¯ÍÏø(ü{ľ!ý¡´ßxRòmi>#jÆÑ¢¾¹-.Ÿrb’b77&Šcî,{q÷sô¼'R”1ÜÕk:jÏ^þM½<õ];žB¤ðœ´éóê¾^zkå¡÷ßÁøcáÇÃJðlPørd{&µq$wÀ0—xûåó¸¾Nsšê+ÍÿdÿÙâÙsàŽ—áuKí]¬ËM5ÅÄŒËæ¿."BHŽ<ç8ä“’ÄŸH¯âëÍÆNJïW»óùžÆ?ehò»-O#ƒðïüœ÷Œ?ìWÐÿô¯X¢ÿÉÏxÃþÅ}ÿJõŠ+œØ?gù'ºý"ÿÓÕõw•ÁþÎ?òOuû'ü>koxR+i|O?ötrøvâGµ?Ù‘̬/TL<°ëò¬3+tRÖÂ=ñ?þ‡á!wÿË:øOþ ›ûoøÛAøë¦xSCµÔ|#‚¯“Uµ½u >¥qåº,Êy ’Hy·á_³b_ÚTý§~iž)Ö4 þVkyw.Û{æL<9ò˜äsÑ•—-·'ÚÆd8œ6ž6¥¹g窾ß–ÝO+ œP¯Šžæ–žwü1¿ÿ÷Äÿú<ÿ„…ßÿ,ëŠ×t/ˆ£öŠðª?м×­áÍdÅ(ð­Ð‰#ZVõdþÐ%˜“  À«n}¯Pºk æXf¹hcgÅ2Rv®H=H=E~P|Dÿ‚ |Dƒö¾Å‚ÂM6×Ãí6‘†®P®Ëg‘ ÐË‘¸LÍd¶25ÀÅNO‘â3'5BÞ꾯î_?¸yžmG¢ë_ÞvÓñ/¼ý)ÿ„{âýÿÂBïÿ–tÂ=ñ?þ‡á!wÿË:éüâYPÖtùo¡ººöñ$аÀ]÷í< 1\§ÑŸðRÏÚÃÄ_²ÏÁ¨'ðÖ‘u6£¯HÖqêæ0öºAÆw7¬¬ ØÛò±9Û´ø×üãö¸ñ?ެßᮯ¦^êº^iæXjñ Û§D8[yÉÆTôŒŒ°ÆÜå>ç±_êíNZqä¾ýmÕÛºvIÞöÙl|–%áÿ¶áÍ9s[n—è½ß§žç×ð|Oÿ¡ÃÀ_øH]ÿòθ¯ºÄX¼ `o#Ђ¬>º‰„‡W³±'Plª¾ÖeÆYAPÊHaî5ÁþÑßòOtïû<;ÿ§«øcëCþï‰ÿô8x ÿ ¿þYÑÿ÷Äÿú<ÿ„…ßÿ,ë¼¢€<;âž…ñ½mâǃKŸÃöq–eüˆí‡_1 ²Ÿ¼dlòÙUâqôêT¡kAu{¾ßð^˜g0s…:·¼»-¼ÿ­OÒOøG¾'ÿÐáà/ü$.ÿùgGü#ßÿèpðþü³®ê °£hËJ¶2¾ÇúS«Ä=Sþh_eð5ù³ñW‚ ˆx] ³xVêV2 ^ðHÀAp¬û™WU!K1kÿ÷Äÿú<ÿ„…ßÿ,èýœäžê?ö4x‹ÿOWÕÞPÀ?ðWO üfo…ú}ÍÞ¯¤ë>µ}Ú¢èšdÖw|p<ţ鵃 ~ei=ü·Áÿ,¾ŸZÑ´o \¸—B·×4‰µ ,仯æ,H*¶NYBƒ—±ÿ|ý­Jý¸í9s[n—íémmµúžåÿ÷Äÿú<ÿ„…ßÿ,ë™ñf•㊿ ßÄ:÷†uK#â;€‘iÚ ö¬ŸØÚž»ÞL ãpÛ´w `ûpÿä¡|+ÿ±¢ý2ê•ðÇÖåQ@‡äç¼aÿb¾‡ÿ¥zÅxwþN{Æö+èúW¬Q@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQEQExí…û?øSãÏŠ~Øø—KŽö'ñ3Äî§d¯ é·×&ãŸ-ä·p8 ó^Õ§iÖúFŸ¥¤ÚÚÚÆ°Ã (8‘FUGp®'âÿü”/…ö4Oÿ¦]R»ÊÖuêJ¥)7ìº+ïc8Ñ„fç®÷}ìGwwŸi,óË@†I$‘‚¤jKxrkósâ·í½ðvçþ ¢ø»þ;]WHÑ"{½u–¸ºÜ‚+Õ‹îÉäeV#q¸r‘ãô–X–hÙUÑÁVV c_›¿?dÏCþ 5¤øaüG›¤jh÷Z†‡Ûoþôòì„Àâ%˜31N«³bdMŸK¿Uö•¾°¥ð?†û[[Ûð¾ú}c’—±qø—ÅmúoøÛ^Ç过|EcâíÏTÓ.à¿ÓµV{kˆ\ú&‚âÞtѰÃ+)à‚Jüèøû(| ½ÿ‚†kþ‡Ä‘kz^ˆ©w£è—u½ÕÞç3[™I"uƒj_~áïúnú§Õñ?XS¿/Ù¾×òë{o¥¯æx9ßÖ}µbãnoµmþ}-Û[Øý ŠUš5tetpYNCÜW ûE~Ñ~ý˜þÝx“Ä·b(c-­ƒ=ü¸â(×¹=Ï@9þWÖÞ¿•?#«ˆ©„Œñ2M¾«·´¿§æyWí»ðÿFø‹û)xòÛZ°‚þ=?D¼ÔmLƒæ¶¹†ÞGŠT=U•‡QÔA ÷ ~èŸ|§øwú|f‘¦D"‚‡Õ‰êÌNIc’I$ÖíQÿ&ÃñþÅ}OÿI%®ò¼w^§³ö<Ï–÷·K÷±éûsû[.kZýmØ+ƒø¿ÿ% á_ýÿé—T®ò¸?‹ÿòP¾ÿØÑ?þ™uJÈÐï(¢Šàü;ÿ'=ãûô?ý+Ö(£Ã¿òsÞ0ÿ±_CÿÒ½bŠ?gù'ºý"ÿÓÕõw•ÁþÎ?òOuû&Vrø…Œž fÛáϱ†ÈØùƒùøõ'¨ÆÞÜß°l_!ý›ôQñ@©×±þŽ%ÏÛV×ÊYÿ–Ýsßw|û«è1ÙÃåô±ªª|ýéÞßk³ x€|;kñy¶?`7_wwñmÏËæmÎÍß.í»¸Í|¥ Mbbã$¥Í¿Dï¿§Sèj¨{¥Õ¶ëkmê~{þŸðNGûQê³kúªè¶¿ õ8â¹—L½{éÊ,±¤eN䉣tffá¶cvퟧõùÿè´øÀk©ÿáûtwÑÜ·ü%§Vy"?0ù¢ç?1—ví¿Ç»Ûq¯×Jún5öÿ\Š­QKÝV¶–ïu®ïU®ÇƒÂª—Õ¤éAÇÞ{õí÷-›…p²¿ü›ÃûôÏý$Š»Êàÿeù6‡ö+éŸúI|qôçy\íÿ$÷Nÿ±£Ã¿úz±®ò¸?Ú;þIîÿcG‡ôõc@åQ@wñ—Tµ·ø£ð–ÒK˜êãÄ·2E H’ªhÚfUêB—@Hé½}Ez%~=þÜö_Gíñ)Ô$ñD—iÿËi"A—æ~àYcæoøìîù²kõWà*øÁ>x|xý´öñx´_í#d1™Î3—~Ý»¶ü»·mùq_A›dk†£]URç[/ÓºèßsÆË³gНR‹¦ãÈ÷¯g×ÐÒø›àeø—ðûXÐPÔt¥Õí^ØÝØÌb¸·Ü1¹wöî2;׿'Á/ø%׋.?lKÿ ê:ÚiºoƒZßU¹Ö,.BÝKŽæÜÀ¹Ü’¹‰ùaˆö“ÏÈôóâZøþë§§ˆÍ«ÿg5ð&ÜM—~9Æ ãm•ìðœ±+ ‰ö5cË׿%m/®½/ˆÕoCÚÓ”µéÛ·­õéê~ÅC†@Y‚¹bI8õ'©¯ý¸¿f ÚÃà]߆ìu«PŠAwjDŒ-n¤@q½õê¤ã×àó<„óvvû~î{ã=«Ä?à¡p|I¸ý›ueøfGö–ö‚ÂíÏi´ù‚ÛòÓÔ}â¹Ûó`–ÊÝEŒ¦éÍFWVoeê}=AᦪEÉYè·gËßðIߨwÄ:Ä Ÿˆzæ§.“o¢]]i0XXÝ«Bh¡˜LÈJ˜UÔ€¹ùÙCp ý¯Ìø#âv£&ŽJü<lÞ†04û~Aý7éœpï?§íq‹«ý¥%VjZ+[¢ìüþo‘åp§õéÅÇW{õ}בÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$µÞWÊŸBÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w”QEp~ÿ“žñ‡ýŠúþ•ëQáßù9ïد¡ÿé^±E³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEóÇíiãÿˆ ÿio€‡Eñu®Ÿà¿øÄxsVÐãÑ¢yõÚN­vÏ-ÜŒåP=­¶Ä…"e+)i$WŸCד~Ð_±/€iÿxs_ñxñ¼š—„f:AÑüs®hPÙNDóÖÈb3lšXüÖRû$dÝ´•¯XUÚ  àqÉÍÒŸ+Þíü´¶¾©»t¾ƒªï5(íÊ“õNM»z4¯»¶§æ—üCöÛñD4¯izE߆àð¯³mu}n.¡wá¹L3mÅœ°åW~Ë_¶n¿ûA|ÒüF~xÂk‰ƒCq5Œš|VW¡Ã<æê)2{í Ë¹Š“]‡í!û x'öªM x¶ÆiŸB¼[˜¥¶E,è3ºÞGÁc ä U² ¼çÒ4"×@Ò­¬lm ³²³‰`‚#Å jTUéŠú~c«—ÒÃQ¥ËR;¿ÏÖûë¶Èñ0˜]Í4¹]—Gšd…lñœJ¡YÈs U2—?4Z_åóïº+8Áb±‚ÃTå³MÿŸË¶Ìµáï:ïˆô-B?„ÿâŽöRitˆd@À2=òºžz2‚;Wáoø‡þ‰_ð/Eÿå…w”Wƒ&›m+¼SJÌðŸ„ßµ};âÄÛˆ>xÂYï|GÎ!ŸGY #HÓ”G!kà `oK.%†Ü«ÝÂßñý¿ÿà^‹ÿË é¼;àë_ kõí»NÓxŠýu  ì ¬‹m° €0»-Ðàç’Ç8 jopI-Žþÿˆè•ø÷ÿô_þXWû6|S×tïÙ×À6ðü6ñ­üPxsN.`ºÒW -cD|®‡#r«`òâ½Æ²|àë_‡~Ñ|?bӽޅaŸnÓ0i8cXÔ±ØQ’ç°¤3™ÿ…¿âú%~=ÿÀ½ÿ–Å|}ø§®ßxÁ%ømã[5_èR &ºÒ ³.¯fËÙ|Çsr6îa¸ªå‡¸ÖOŒükã­+Æ!‚þÏPSo2Öæ+˜ÁÈ?)xTÜÌÿÂßñý¿ÿà^‹ÿË ?áoø‡þ‰_ð/Eÿå…w”PåWíwÿ'ñ¦¡ûShÚ–•£Ká˜~_Kö-3VµCrò:4Sý q¾6dÚ…!·|Õ÷ϯÚw[ø£ðçFñ  ü}Zµª\3éq¯#’¢kÈä(O*ÍîR›âßìYð÷ãwÅ}Æ^!ÑRëXÐ_vÑ¢!å0|ÅC†# rüµêÀ`WÐæùކ£K K–PZ¿ÓÎï[¿ó<\·‹£^­Jõ9£'¢ý|´ÒÈó~Кïƒ|)¨j²ü'ø‡4z}»ÎɺLÎÛFp;×sÿV8ìkóËà—üÆ–ß¶÷Šoôc¬ÙxÅ­ô«Â×) nâÝ-ÏV• ¯Ã9r>R¿«•åž ýŒ¾ø ãÆ©ñMÐâ‡Äz¤aOCohçw™4)’I›=w>ã%Ìp8j5¡Š¥Î䬿ËË]nµÐ3L.½ZRÃÔåQwççÚÛjj§Æ/H‡Â¿Ã<Ýh þ_Úïø[þ!ÿ¢Wãßü Ñùa]åóÇ´xOìóñ#WÑ< §ÃÏø“]”µµÆŽˆµk¶(C_)Ü„ìc¹C´²áuÿ Ä?ôJü{ÿz/ÿ,+¦ðgƒ­| £ÍefÓ¼3ßÞj e`Íæ]\Ës å3;$òu©¶Û»I+#ÿi?Šzî£û:øúÞo†Þ5°Šj1½Ì÷ZAŠÝM¬€Èá/™Ê¨äíVl,ñީ⊿ íï¼âoDž#¸\ê3éòE# SX÷R¾â <¨\)ç8Ø«'Ä^µñ>± ÞÜ4ë7‡oÛPµÀ+HÖÓÛù+²áÎ9 s€AÖ¢Š(ƒðïüœ÷Œ?ìWÐÿô¯X¢ÿÉÏxÃþÅ}ÿJõŠ(ýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ Š( Š( Š(  ?üMðß‚üI¡hÚLjt='XñLò[h¶7—ñAs«ËfI#·Ø4α‚ì¨ 5\ÛYü!ñ<—ºN©®Ù.—qö?M±Šþòò#H­ä&r¹Äl¬ü»[;LT—,\»^_š* òH‡àÏÇï~ÑÞ“^øyã_ xóC†á­Qðî±oªZ$Êš#,èRW9‡ŠëkäÏø&¾™«·ÄߌšÔ«ãÝ{Ãþ ¾Ò®-жûíî÷i7öІ’6™Üœ9 W*“qI¯Á]ü–íù-{'±t ¥+7o=—Íô_Ö‡Ô–ðj¶]ZÏ Í­Ìk,3Dáã•eYXpAGš¹‚:еƒ>»ñÍ•Ž™ã[­Òm~ÎÈæÚÒý¡Cqgsü‹)p>và˜õ®¢º*Ã’n £ïǯ©ÏF|ôã;Zé>߇C‰ñ¯í-ðãá·ÄÝ Á^#øàÆ^(Ûý êZå­®§«nr‹ö{iK6\ä‚:×m_žú΋ñcáüÇ—Öþ0I¬øóâ&ƒ{o£¯‚mIødYXA{-ưlKÚKoZŽÈ´ao="+o ¸ýïèEDèÆ£ÝôùEþånÿd¬¬i=*¸t_æ×ãk­6k~‘Ý]Eck$óÉ0Â…ä‘Ø*¢’I<zó?‚ß¶ÿÁoÚKÅ3h_¾/|/ñö·ml׳iþñUŽ«u Ê+E®Á:)b0 ¨ÎH¯P¯ýœ¼3®üFý¤>%|Qñ>™¨é0ÃrÞ ðmì2A$zM£ƒsyåHªÊo/¼ÂIoifêH • jYífÿEäýç4væjö ée½Òûõù{ªNû^ËKžñY>;ñî…ð»Áúˆ¼M­i>ðþ\ßêz¥ävvvQ/Þ’Yd!Gvb­jù×þ  ê¾$ýõ mM×®µ$×4k¨5 G›[¾ðËé[Ìš¼Zt É|ÖmÎ-•Jc‘Ór™œ­o6—Þí}ÒÓÍ¥ÞQWj “zùþ{û“}“zÏð§ã„~;ø"×ÄÞñO‡øþ]~×Å7rê8¾½¶ñ?‰<7qáWÆÉ¶ÝBãKž8šÍÓÔ…†åûž‘"Ì}EZÎ6åóQzNÝ6½µI÷Ièe 7{ôm|“iwéٵٵ©Ìü[øÓà߀ ›Äž<ño†|áÛyu]{TƒM²‰ÜíEi¦e@Ìxœ“Ò¶|5âm7Æž°Ö4}BÇVÒu[xîì¯lçYí¯!‘C$±È„«£)2’ ƒ_<ÿÁFŒ[ÌRÈ#‘Œæ¿5t Ûxûá‡í¡à/‡¿ ¼w¤iÞ%{kÏ h—u iºÖŸm¡éVsÚZIuion ’ÛÜ@°†ÆX)Œï©½Ü•íh¹/Tâ¿&ßË¥aìßt¾þž¯¡÷ÇÁ?Ú7áïí-áë­_áÇ<ãý&ÆàÚ\Þøo[¶Õmíæ ¬by wU}¬§i9ÃŽk³¯—d}@|aý²~$|NÐ|-ã? x+Pð‡|5 øÂ×¾¸Ô5 Iõ9æe´¼ŠÙ!‚òÖ!1‹Ëc¹ØFØúе©WýZ­W“1‹»k}µõI¿¹·柡ÁøwþN{Æö+èúW¬QG‡äç¼aÿb¾‡ÿ¥zÅìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEp~ÿ“žñ‡ýŠúþ•ëQáßù9ïد¡ÿé^±E³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQEQEQEQEQEQEW„ÁQ<_«|?ÿ‚oüv×tSQÑ5½#ÀzÅ冡arö×VS¥œ¬’Å*ÈêÀÊA {½gx»ÂOÄ j:½¥éÚÞ‰«ÛIg§ßÛ%Í­ì¥^)bpUÑ”U¬14J3§fÓWíto†ª©Ö…I+¤Ó·{3ñãà?í·ñGö4ÕO §†ì—Dy<Á.óf#òKy€>vgp ךê¯?häÖ—oä¹âÒõQRWï;$¡#–ŒR×E^Güýæ¿»vÜ¥&|·ÿíÿ‚üVý­~0ø[ÀÞ/ðï‚<=â?xsWÔ¾&ÙXErí¥Þ.¡¾“£4Ì'·óf}þiùkîªçñ¶½â]ÂÞÒ¡$„ iæ@¹‹ïIÏfŠÿÙColPack-1.0.10/Graphs/jac_pat.mtx000066400000000000000000000012031266356121500164670ustar00rootroot00000000000000%%MatrixMarket matrix coordinate real general 10 43 78 1 1 4 1 2 1 1 5 2 1 15 3 1 16 4 1 19 5 2 1 6 2 2 7 2 3 8 2 4 9 2 5 10 2 15 11 2 16 12 2 17 13 2 18 14 2 19 15 2 30 16 3 2 17 3 3 18 3 4 19 3 16 20 3 17 21 3 18 22 3 31 23 4 5 24 4 6 25 4 11 26 4 12 27 4 13 28 4 19 29 4 20 30 4 25 31 4 26 32 4 27 33 4 34 34 5 7 35 5 8 36 5 21 37 5 22 38 6 1 39 6 2 40 6 5 41 6 15 42 6 16 43 6 19 44 7 1 45 7 2 46 7 3 47 7 4 48 7 5 49 7 15 50 7 16 51 7 17 52 7 18 53 7 19 54 7 30 55 8 2 56 8 3 57 8 4 58 8 16 59 8 17 60 8 18 61 8 31 62 9 5 63 9 6 64 9 11 65 9 12 66 9 13 67 9 19 68 9 20 69 9 25 70 9 26 71 9 27 72 9 34 73 10 7 74 10 8 75 10 21 76 10 22 77 ColPack-1.0.10/Graphs/mtx-spear-head.jpg000066400000000000000000000737141266356121500176750ustar00rootroot00000000000000ÿØÿàJFIFxxÿÛC      ÿÛC  ÿÀs±"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ý›ø[ð¶ÇâV‡ªêú¾«ãIoeñ·nM¿‹u[H’8u[¨bEŠ„cQ÷}rk¥ÿ†qð÷ý|{ÿ…ƵÿÉt~Î?òOuû=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’뼯(ý¶?hÍcöOýšüUãýÁ7^;›ÂÚmÞ«qc©› 6öÖÒÜÉ,ÓI¹•6ðy1M!y#ýÞÍò$ÊJ*ìºtåRJÕ³oþÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë€øÕûWøÓDñg†|+ðÏáÞ“ã랟ÅwVú׉Ÿ@Ó´ûŒQ„IgtÒ\É4ʱÇäªIYäj‡ôÙ×ãv—ûJüðwÄ«m+Æz=®³k Ê…šž%#€HÜ»°pHÈà‘ÍiÈìßggëy/ž±’Óªf1œd“]Uþôš¿k¦šNͧtVÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºù‹öñÿ‚¬ž=‹Â^ŽÃVÕô‹µ:åÕ—·‡c|Ö‹‚2ç;òrÍžßðCöþøañ›áÕŽ¸þ,ð÷†î¦.´Í[T‚ÚæÎPåòï^xp0Àö9Qéb2l] 41uahKoÒý¯Ð⡚a«W–œ¯(ÿZw·S®ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ¯,ôþÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºå~3þß ¾|=¾×‹ü;â ‹uÛo§iZ¤W7rv Tf*8åˆÀ§øWì+ÿ[ÿ…ãñ" øî -+QÖoöź•…·Ÿ’Ñóü}·ñt<ã>¦&Åâ0ÓÅÒ…áÿ[w·Sϯša¨×ޤ­)Zö¿CéÿøgÐGÇ¿ø\k_ü—\ŸÇ¯ƒzo>xÓ\ÒõÛjz6…}}g1ñ¦±(Šh­ÝѶ½ÉVÃ(8`AÆ"½¢¸?Ú£þM‡â?ýŠúŸþ’K^YèåQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEå?¶ÇÀ~Óß³'‹¾xcÅ:ƒ§ñ®™u¢_êZ¦.´‘Y\Á$¡ŽîԬؓ(í#*•æ7Ï­ELहe±têJœ”á£GÍ(ý>,ÜËàÏø{â׃t‰ðÝß…5]JOÜ]èšµ”ÒÅ,OžuE– ˆZ+!º•ùwFÁ”'´|ø/¥~Î_¼!à K©´höº5œ·%LóEK¼…UT»Ë Oºú+WRVk»»õ¼Ÿç);-.ÙŒa¤—Eo¹$¯ÞÉ$›»IY)þß°¯…¿h߈¾¾%´=w]Öÿ²µ ûdÝÚ%•Õɽ €[G=`†@ú3áwÂí àÏ´ÿxsO‡MÒtØü¸¢ŒrOvcÕ™%$šÃø¿ÿ% á_ýÿé—T®òºjæš´#†©6á—oë§n†ðT)Õ•xE)KwýL(¢Šã:‚¸?ÿÉÏxÃþÅ}ÿJõŠï+ƒðïüœ÷Œ?ìWÐÿô¯X òŠ( Š( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ (¢€8?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–»Ê(¢Š+ƒø¿ÿ% á_ýÿé—T®ò¸?‹ÿòP¾ÿØÑ?þ™uJï(¢Š(¢ŠàþÉBø©ÿcDúeÒë¼®áü”/ŠŸö4Aÿ¦].»Ê(¢Š+ƒý•ÿäØ~د¦é$UÞWû+ÿɰü8ÿ±_LÿÒH¨¼¢Š(®öŽÿ’{§ØÑáßý=X×y\íÿ$÷Nÿ±£Ã¿úz± òŠ( Š( Ä_òsÞÿ±_\ÿÒ½»ÊàüEÿ'=àÿûõÏý+Ñë¼ Š(  /‰_ tO‹ÞÔ<;â-> OHÔâ1O£ƒèÀõV0Á+çø'¯ìáWšç‹£iuoûkTÒ´éîÑwi¶¶×³Ú ˜àË „–“†Ú·}Y\ìãÿ$÷Qÿ±£Ä_úz¾®Ê9†&•áéͨKußúëß©ËWB¥XלS”v×ôŽò¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–¸Î£¼¢Š(ƒýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ Š( Š( Šøcþ ÿEÖ¿cÿ)ÓO‰¾øKKð?‡4ÿÛè^/’DÖþ&‰æ¹š<Ÿka–¶Ø‚ñžYÑLq¦O¹-æ0$ŠY0ÈÁÁE^<þm}߇ëÞ“´ùö¿äÿU÷œ7Åÿù(_ ÿìhŸÿLº¥w•ùåÿ"ÿ‚jž øÛ£ø_Áv’Ù^|?Õ†¡w}lÈnn<™a0¤n`1O /Ÿp(B€ÏôÏìïûxøsã¯Â½?ÄFñ…¥Ô¹Šî O êZŒ̸Ükxysœ {¼‹‡ÂCV>ì¾õÚþ½?ÍÃæØjø‰ái¿z?{zéEpðÑÞÿ wð‡Ö¿ùøhïÐ;Ç¿øCë_ü‰^9éåp~ÿ“žñ‡ýŠúþ•ëÃGx{þÞ=ÿÂZÿäJâ´/º_´WН ‡LSøsF…Tx;W2†K­T’Ñ‹m긑p̱ ’Œ¸Ñ\ü4w‡¿èãßü!õ¯þD£þ;Ãßôñïþú×ÿ"PyEpðÑÞÿ wð‡Ö¿ùøhïÐ;Ç¿øCë_ü‰@ìãÿ$÷Qÿ±£Ä_úz¾®ò¼;àÇÝ Jð5üRØxÕ™¼G®Ì >Õæ]²j÷Ž ²[”ÊÙV”ÚÿÃGx{þÞ=ÿÂZÿäJï(®þ;Ãßôñïþú×ÿ"Qÿ áïúx÷ÿ}kÿ‘(ýª?äØ~#ÿد©ÿé$µÞW‡~Òt-göuñõœ65In¼9¨Â?ƒµx"VkY/#Û*"äòÌBÉ ×kÿ áïúx÷ÿ}kÿ‘(¼¢¸?øhïÐ;Ç¿øCë_ü‰Gü4w‡¿èãßü!õ¯þD ò¸?‹ÿòP¾ÿØÑ?þ™uJ?᣼=ÿ@ïÿá­ò%q_þ>èWÞ9øm*XxÕVÏÄsM “ÁÚ¼lÊtI0ŠÖÀÈÙpv -´3cj±ãEpðÑÞÿ wð‡Ö¿ùøhïÐ;Ç¿øCë_ü‰@åÁÿÃGx{þÞ=ÿÂZÿäJ?᣼=ÿ@ïÿá­ò%?ä¡|Tÿ±¢ý2éuÞW‡|,øû¡XøçâL¯aãV[ÏÃ4b?jò2¨Ò4ÔêÛe Úà6Ò­¬¤ö¿ðÑÞÿ wð‡Ö¿ù€;Ê+ƒÿ†Žð÷ý¼{ÿ„>µÿÈ”ÃGx{þÞ=ÿÂZÿäJï+ƒý•ÿäØ~د¦é$TÃGx{þÞ=ÿÂZÿäJâ¿fϺû:øÎk¼¶¾Ó¡vƒÁÚ¼ñ3-¬`”‘-™r8e%HähÜh®þ;Ãßôñïþú×ÿ"Qÿ áïúx÷ÿ}kÿ‘(¼®öŽÿ’{§ØÑáßý=XÑÿ áïúx÷ÿ}kÿ‘+Šøûñ÷BÕ| aV5V_èS7ƒµxWlz½›° öÀ!HUs6Af€{ÁÿÃGx{þÞ=ÿÂZÿäJ?᣼=ÿ@ïÿá­ò%w”Wÿ áïúx÷ÿ}kÿ‘)—´·‡-mÞWÓüx5,Çþ}k€OüºÓI·d&í«â/ù9ïÿد®é^]å~`kðWýZïö»±ñ\:0ÿ„'K·ŸGƒLuñ­f’–rݦf·ˆ…ÎÕ ·©g?}hÿµ†uÍ&ÖöÞÃÇoä)1ÉPwåþ®¼E¢¸?øhïÐ;Ç¿øCë_ü‰Gü4w‡¿èãßü!õ¯þD¯ ôŽò¸?ÙÇþIî£ÿcGˆ¿ôõ}Gü4w‡¿èãßü!õ¯þDªÿ²æ¥³ðªâò¸H®¼G¯Ì‹<ª­¬Þ7 èØ<«Àð@#è•ÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$´ÞQEÁþÎ?òOuûÓ7ØÎ¡µ˜ x⻎9622<Šþ³E-*õûÁêî|ãûrþÈžý£ümðÓûbÙ­oïuã§\_Ûan&³K˦€ž„·P ÉMÍŽ¤|ð‡„4ÏxbÇEÑlmôÝ+MˆAmmíHvÌ“É$“’k•ø¿ÿ% á_ýÿé—T®òºjc+Ô¥“qŽË¢¹„0Ô¡RUc¥-ßp¢Š+˜Ü+ƒðïüœ÷Œ?ìWÐÿô¯X®ò¸?ÿÉÏxÃþÅ}ÿJõŠï(¢Š(¢Šàÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuûxÕå—Ú4ml.´6[­T‰›í›X³µ‹f6Ü,î4Wÿ Ä?ôJü{ÿz/ÿ,(ÿ…¿âú%~=ÿÀ½ÿ–ÞQ\ü-ÿÿÑ+ñïþè¿ü°£þÿˆè•ø÷ÿô_þXPû8ÿÉ=Ôìhñþž¯«¼¯øñO]±ð5úEðÛÆ·ŠÞ#×d2Cu¤Vm^ñš3¾ùNä$£`mܧieÃ×þÿˆè•ø÷ÿô_þXPyEpð·üCÿD¯Ç¿ø¢ÿòÂø[þ!ÿ¢Wãßü Ñùa@íQÿ&ÃñþÅ}OÿI%®ò¼;ö“ø§®ê?³¯­æømã[§ðæ£ÜÏu¤­ÔÚÈ ŽùœªŽNÕfÀàÅv¿ð·üCÿD¯Ç¿ø¢ÿò€;Ê+ƒÿ…¿âú%~=ÿÀ½ÿ–Âßñý¿ÿà^‹ÿË ï+ƒø¿ÿ% á_ýÿé—T£þÿˆè•ø÷ÿô_þXWñOâž»s㟆Îÿ ¼knÖþ#šHã’ëH-tßÙ’ùi¶ø€À1œªí¹ÝµXÜh®þÿˆè•ø÷ÿô_þXQÿ Ä?ôJü{ÿz/ÿ,(¼¢¸?ø[þ!ÿ¢Wãßü ÑùaGü-ÿÿÑ+ñïþè¿ü° áü”/ŠŸö4Aÿ¦].»Êðï…ŸõÛoüItømã[†¸ñ2IwZ@kVþÈÓWË}×À!Cü…—l‹Îíʽ¯ü-ÿÿÑ+ñïþè¿ü° òŠàÿáoø‡þ‰_ð/Eÿå…ð·üCÿD¯Ç¿ø¢ÿò€;Êàÿeù6‡ö+éŸúIð·üCÿD¯Ç¿ø¢ÿò¸¯Ù³âž»§~ξ·‡á·oâƒÃštisÖ"¸Qk {åp¬9•[î4Wÿ Ä?ôJü{ÿz/ÿ,(ÿ…¿âú%~=ÿÀ½ÿ–ÞWûGÉ=Ó¿ìhðïþž¬hÿ…¿âú%~=ÿÀ½ÿ–ðïüÛöÿñ®•ã?ÁZFƒ­øt¹íuyäÔÒ¹¼–)Vh ÞXŒ+$jÙWm̘8ÚAôòœª¶aˆXz6OvßDpf9,mWm´êÏÑê+çŸÙ;öÐñíð[Mñ¿ <]stÛ­înlÂ++©†’´ÝDå ÿd…m˹¶“^•ÿ Ä?ôJü{ÿz/ÿ,+‡ ²£UZQvgM ð­N5iìÕÑÞQ\ü-ÿÿÑ+ñïþè¿ü°£þÿˆè•ø÷ÿô_þXVÁâ/ù9ïÿد®é^]åxv»ñO]Ú+·á·RX¼9¬Æ¶ÆëHófVºÒ‰‘H¾ÙµJ¨;˜6d]¡€b½¯ü-ÿÿÑ+ñïþè¿ü° òŠàÿáoø‡þ‰_ð/Eÿå…ð·üCÿD¯Ç¿ø¢ÿò€;Êàÿgù'ºý"ÿÓÕõð·üCÿD¯Ç¿ø¢ÿò«þË—’j? ®.&´¸°–ëò=´å ¶ìu›ÒcrŒÈYOk2äpHæ€=¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–€;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š(¢ŠñŽðOÏ…_´wîüAâÍZ¹¾Õl Óuhl%Ó…ÂKâV‚I¢o.y-ÓN¾¹0ùo%¼{€ÁÆpTœ×·iE®¥[XØÛAgegÁF#ŠÔ¨ª8 ÓÅü_ÿ’…ð¯þƉÿô˪Wy[OVTãJRn1ÙtWÞÆQ£N3u#¤÷}]‚Š(¬MB¸?ÿÉÏxÃþÅ}ÿJõŠï+ƒðïüœ÷Œ?ìWÐÿô¯X òŠ( Š( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ (¢€8?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–»Ê(¢Š+ƒø¿ÿ% á_ýÿé—T®ò¸?‹ÿòP¾ÿØÑ?þ™uJï(¢Š(¢ŠàþÉBø©ÿcDúeÒë¼®áü”/ŠŸö4Aÿ¦].»Ê(¢Š+ƒý•ÿäØ~د¦é$UÞWû+ÿɰü8ÿ±_LÿÒH¨¼¢Š(¯ý¹>øSãWÃí ¼G¤Ã}-‡ˆô{x& c•"¹ÔímçŒ:v¼R0#=pz¨#Ûkƒý£¿äžéßö4xwÿOV5­õ(ÍT¥'-šÜέ(Uƒ…Etú3²Ñt[? éº~Ÿk•”K½¼#ŽÔaUTpZ¢ŠÍ¶ÝÙi$¬‚Š(¤3ƒñüœ÷ƒÿìW×?ô¯G®ò¸?ÉÏx?þÅ}sÿJôzï(¢Š(®öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾ ò¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–€;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š(¢Š(¯‘à¤ÿôÿˆ>(ð>‹£x‹â¦‰ñ#â^«‡ô¹ü=ñÄZ-–“e{«ýAììo"µgŠÕ% òDwÍ-²9 _\Æ‚(ÕFHQ’IüÏ&ˆëùµø'úöµî®Úa-$£åůÍ?=µG ñþJ¿û'ÿÓ.©]å~aÁYÿiÿˆIñÂÇÂæÃQð†‹á{´Õ4yÒ@%Ô¦PÊ—©*°U+–Üd/Ö¿²'íAñâ‡À]Yñ7Ã^ê71áoôù´è!Ôã qå\]Bè_“€»OÞSµ€î7 ­†ÀÓÇNI©ôOU}½|í±äasŠUñsÂE;Ç­¾ÿOžçÑWÿ Ä?ôJü{ÿz/ÿ,(ÿ…¿âú%~=ÿÀ½ÿ–á¹ÞWáßù9ïد¡ÿé^±Gü-ÿÿÑ+ñïþè¿ü°®+Bø§®§íâ«ðÛÆ¯,¾Ñ£kau¤y°ªÝj¤HÄßlÚŘ ¬[1¶à ©`q¢¸?ø[þ!ÿ¢Wãßü ÑùaGü-ÿÿÑ+ñïþè¿ü° òŠàÿáoø‡þ‰_ð/Eÿå…ð·üCÿD¯Ç¿ø¢ÿò€ÙÇþIî£ÿcGˆ¿ôõ}]åxwÀ/Šzí¯Ò/†Þ5¼Vñ»!’­ *³j÷ŒÑ÷Êw!%nå;K.ö¿ð·üCÿD¯Ç¿ø¢ÿò€;Ê+ƒÿ…¿âú%~=ÿÀ½ÿ–Âßñý¿ÿà^‹ÿË ?jù6ˆÿö+êúI-w•áß´ŸÅ=wQý|}o7ÃoØE?‡5Þæ{­ Ån¦Ö@dp—ÌåTrv«6ž+µÿ…¿âú%~=ÿÀ½ÿ–ÞQ\ü-ÿÿÑ+ñïþè¿ü°£þÿˆè•ø÷ÿô_þXPy\Åÿù(_ ÿìhŸÿLº¥ð·üCÿD¯Ç¿ø¢ÿò¸¯ŠõÛŸü6wømã[v·ñÒG—ZAk¦þÈÔ—ËM·Ä‹üåWlmÎíªÀãEpð·üCÿD¯Ç¿ø¢ÿòÂø[þ!ÿ¢Wãßü Ñùa@åÁÿÂßñý¿ÿà^‹ÿË ?áoø‡þ‰_ð/Eÿå…?ä¡|Tÿ±¢ý2éuÞW‡|,ø§®ÛxçâK§ÃoÜ5Ljá’HãºÒZ·öFš¾[î¾± ä,»d^wnUíáoø‡þ‰_ð/Eÿå…w”Wÿ Ä?ôJü{ÿz/ÿ,(ÿ…¿âú%~=ÿÀ½ÿ–ÞWû+ÿɰü8ÿ±_LÿÒH«Àࢿµį†å›Ã~ñ?…£Ô$û%î»{=”­¦£ ,ZÜLQÜ’¢GÚŒe™Jùü[ö¨ø‹©xZûÂsøS^ñ¿†|? ‹+Û9­£›LÉÂÛ¹–$tÆJ€û+¾å,†µLºYŠ’åOkëçÿnþëù53ŠPƬ Níom?¯=—ßoЊ+ƒÿ…¿âú%~=ÿÀ½ÿ–Âßñý¿ÿà^‹ÿË ðÏXï+ƒý£¿äžéßö4xwÿOV4Âßñý¿ÿà^‹ÿË â¾>üS×o¼ `’ü6ñ­š¯ˆô)“]iY—W³eŒl¾c¹È¹w0ÜUrÀÜh®þÿˆè•ø÷ÿô_þXQÿ Ä?ôJü{ÿz/ÿ,(¼¢¸?ø[þ!ÿ¢Wãßü ÑùaGü-ÿÿÑ+ñïþè¿ü° Ä_òsÞÿ±_\ÿÒ½»Êðíw➺ÿ´W…nÃo¤±xsYmÖ‘æÌ­u¥"‘}³j•Pw0lÈ»CÅ{_ø[þ!ÿ¢Wãßü Ñùa@åÁÿÂßñý¿ÿà^‹ÿË ?áoø‡þ‰_ð/Eÿå…w•ÁþÎ?òOuûMïò¶Ïs÷jŠ(¤ ¢¿>?à¡ÿ|o ~Ô>9½¼Òî5…Ÿ¼¥ø¾ïNÒþ-jþÕ&7Z€¹ž(ôø±©¾ËŠ+{«˜!ß•å¦ÜŸ –³‹«hå Ê$PÀ0ÁÁ÷¢*ðSóƒ·ã¯•ºÞé÷gÈû/É?ÁI|úZÍð_îc´ñ÷¦–D‰[År .ÁAfѵEQÏrHw$W Wå§üçâGÅøïc¦kpË¢øON—í~63CxËÇÚZLöœÇîÃar{ýû%|Bøã› 'áyõan5-z}>òê.6I,)g0VaÏßõ*3^þ;!žKê'ÏÑ=¿Ïϳ<|&oøº˜E¹zÿ[yw>…¢¸?øH~'ÿПà/ü+îÿùYGü$?ÿèOðþ÷ü¬¯öò¸?ÿÉÏxÃþÅ}ÿJõŠ?á!øŸÿB€¿ð¯»ÿåeqZ»ñ~Ñ^*t𯂚õ¼9£ b>*º$bëUØÊÿÙä³dJ€¡T†mÄ(¸Ñ\ü$?ÿèOðþ÷ü¬£þ‰ÿô'ø ÿ û¿þVPyEpðüOÿ¡?À_øWÝÿò²øH~'ÿПà/ü+îÿùY@ìãÿ$÷Qÿ±£Ä_úz¾®ò¼;à»ñ/_‹? ø*xˆõÒÍ7Š®¢a!Õï ŠÓÛ*¯¹U³–Pª’Tv¿ðüOÿ¡?À_øWÝÿò²€;Ê+ƒÿ„‡âý þÿ¾ïÿ•”ÂCñ?þ„ÿá_wÿÊÊ?jù6ˆÿö+êúI-w•áß´ž»ñoÙ×ÇÉ}á_[Ù7‡5q,*ºšX£û,›™éè€É YAoÙÊ×ÄZ†¯"걈öx’{y.-¦¹—p2yª-å.ÑìŒG_Ð]~=ø›ö ý²®਱xWÞ%ý©.þŸŠØM§ê³–aáô©pÄFåæ{u´åܘ•åOÊÌ0ðzfŸW§’¼àï}{uŒ•®ÚÑþãQtM?=#>Ÿ>’‹½’ÝŸ°”QE!_ÄÙ»á߯?øwÄ^/ð‚üUâÎ.tOXÑ-¯¯4IC¤že¬²£<¾8ÛteNQOP+´¢Š‹•mþ{ƒÕÝžeûBøKLñŸŒ>YêÖº¨ñkMå\F7ǤêR¡ÁôtFú¨¯M®âÿü”/…ö4Oÿ¦]R»Ê§)4¢ÞˆJ);¥« (¢¤a\‡äç¼aÿb¾‡ÿ¥zÅw•ÁøwþN{Æö+èúW¬PyEPEPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@íQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K]åQEÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w”QEQEy§ÁO éºwÅߋ𕽅¤:…߉-¡žá" ,¨º>œê¥‡$’FÇ«±ï^—\Âù(_?ìhƒÿLº]w•R”¤ï'qF)hQE# àÿeù6‡ö+éŸúIw•ÁþÊÿòl??ìWÓ?ô’*ï(¢Š+ƒý£¿äžéßö4xwÿOV5ÞWûGÉ=Ó¿ìhðïþž¬h¼¢Š(¢Š(ƒñüœ÷ƒÿìW×?ô¯G®ò¸?ÉÏx?þÅ}sÿJôzï(¢Š(®öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾ ò¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–€;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Êâ?hïÙÏÁ¿µ¯ÁMáßÄþxž·ÔôÿµÏiö”YEl’®åX=3_? ?eÙgàíá¢ë>ý‡5­+áo‚þ+ZøMøµÿ júy-øæïÀö÷~:µðýü¾‚tÚŠÛÈm‘ 2„3šü^ð—ÄÙgö¯ý®¾ø«á…uÿ~ÜpxÇÃÒüETð†£gq¦Çn«»wªÚ41éPK™­ã%É…‚  ýþ=à´ošVRVÖÐJ\Î듚2´­ÊÞ/LïÚmvN1½ô¼ÛŠŽ›–QÑÙ¯Ý:(¢ùÝÿO‡áß?jÍ+âÞ¹û7øÓân‡¡i¶º/Âßxnß[ñf¶é¨Í,'D¶$öw3¼­ʶw4(ÅHFôB6-–]¬FHÎp}(‡½MMïv­èìµóZÛ¦Ì&Ò¨à»'÷­tòz'Ö×Gœ|z×ì|7ãO…W:…åµ»x¹ Ï ’iœq¦OgeP;–½zE~YÁat‰ëñ®ÎïÄ’‹ÏK!Ã_a’Ú òcuÉ?i |ÌOÎW 6¯Ø±ÿ†þŠ¢¸?øG¾'ÿÐáà/ü$.ÿùgGü#ßÿèpðþü³¯Ÿ=“¼®ÿòsÞ0ÿ±_CÿÒ½bøG¾'ÿÐáà/ü$.ÿùg\V…¡|E?´WŠ‘…ðËÅ_ µj¶zM—ü%šáöª™4­F'Ñ|ÉcÊ»Á$kÕÁȯËÏø+À_‰ñ¾Ã_Ô/.*ðU½“xsN6ñOá[©¥Š?²Çµ]Æ Ø ÁTÎÑÒ€=ÆŠàÿáøŸÿC‡€¿ð»ÿåð|Oÿ¡ÃÀ_øH]ÿò΀;Êàÿhïù'ºwýÿÓÕð|Oÿ¡ÃÀ_øH]ÿòθ¯ºÄX¼ `o#Ђ¬>º‰„‡W³±'Plª¾ÖeÆYAPÊH`î4Wÿ÷Äÿú<ÿ„…ßÿ,èÿ„{âýÿÂBïÿ–tÞQ\ü#ßÿèpðþü³£þï‰ÿô8x ÿ ¿þYÐâ/ù9ïÿد®é^]åxv»¡|E´W…QüUঽok&)G…n„IºÒ·«'ö,ĘÈ`À(V[p+ÚÿÂ=ñ?þ‡á!wÿË:ï(®þï‰ÿô8x ÿ ¿þYÑÿ÷Äÿú<ÿ„…ßÿ,è¼®öqÿ’{¨ÿØÑâ/ý=_Qÿ÷Äÿú<ÿ„…ßÿ,ê¿ì¹Ô? ®úk{‹Õñ¾.%‚ RÉý³{¹‘ 9E'$)f q¸õ D®ö¨ÿ“aøÿb¾§ÿ¤’×y\íQÿ&ÃñþÅ}OÿI% òŠ( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ (¢€ (¢€ (¢€8/Œ7Ä…yÿÅS7þ™uJïkƒø¿ÿ% á_ýÿé—T®ò€ (¢€ àü;ÿ'=ãûô?ý+Ö+¼®ÿòsÞ0ÿ±_CÿÒ½b€;Ê(¢€ (¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Šàÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zï(¢Š(®âÿü”/…ö4Oÿ¦]R»Êàþ/ÿÉBøWÿcDÿúeÕ(¼¢Š(¢Š(ƒøAÿ% â§ýé—K®ò¸?„òP¾*ØÑþ™tºï(¢Š(®öWÿ“aøqÿb¾™ÿ¤‘Wy\ì¯ÿ&ÃðãþÅ}3ÿI" òŠ( ¸?Ú;þIîÿcG‡ôõc]åp´wü“Ý;þÆÿéêÆ€;Ê(¢€ (¢€8?ÉÏx?þÅ}sÿJôzï+ƒñüœ÷ƒÿìW×?ô¯G®ò€ (¢€ àÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuûgݯ’·ã½õù-…'iòù'÷ÿ]½<_öºøãáÞ%øY¨ø—TƒO·_;0't‹i—Öæ]ƒæòÖIâ Àq¸z^Éc}§e Í´Ñ\[Ü"˱8t•d2‘ÁAkóWþ ûxûYøó¦ø£L½Ô¼gcã+ÄÒôûW*gÒ¦*ò-ªª€¾FÔ‘•Àà+y‡?;ý]û*þȾ-ø%ðCGðþ¡ñGŰ]Û©’Kk´ùm,Ërb‰®me“jÿ¼9!Fkè1ÙfŽ_KJ·4å¼­U¶×~‡„Çâjc*P©K–Ùÿ[ßËn§Ð4Wÿ ƒÄ?ôU<{ÿ€š/ÿ+èÿ…Aâú*ž=ÿÀMÿ•õóç²w•ÁøwþN{Æö+èúW¬Qÿ ƒÄ?ôU<{ÿ€š/ÿ+ëŠÐ¾k¯ûExªÜ|IñªK‡4iäZélÊ×Z¨°6;6©V#j†Ì¸° Üh®þˆèªx÷ÿ4_þWÑÿ ƒÄ?ôU<{ÿ€š/ÿ+輨¯¯¡Ó,¦¹¹š+{{tie–W‘"Œ–bxI'¥qð¨Lmk[ý⹕8ã|-(T­u%Ëõ}¼Ìq' rœ#ÌÒÑw7¿bŸ~ø¹à]~/뺔ºo‰µ™.#BC¤wÕÄm ŠCc‘ÕHÍ_™¿ðLØoâ_oü_y¬kŸôí[%šÑb7Zœñ»E,A%I"1G"ÌèÃzaFàY>öÿ…Aâú*ž=ÿÀMÿ•õég¸6èájsÇò}¯³ùz9F.¾'ªâ!Êÿ?;nŽòŠàÿáPx‡þЧðEÿå}ð¨k·>9ø’‰ñ'ƶíoâ8c’Hít‚×Mý‘¦·˜û¬H ù®Ø×Û™»_øT!ÿ¢©ãßüÑù_@åÁÿ ñýOÿà&‹ÿÊú?áPx‡þЧðEÿå}w•ÁþÊÿòl??ìWÓ?ô’*?áPx‡þЧðEÿå}q_³gÂÍwQý|qÄŸØE?‡4éÚ ] Ån¦Ö2#Bö,åTp736$žhÜh®þˆèªx÷ÿ4_þWÑÿ ƒÄ?ôU<{ÿ€š/ÿ+è¼®öŽÿ’{§ØÑáßý=XÑÿ ƒÄ?ôU<{ÿ€š/ÿ+ëŠøûð³]±ð5ƒËñ'Æ·ŠÞ#УÍk¤Vm^ÍVA²ÅNä$:äíÜ£peÊq¢¸?øT!ÿ¢©ãßüÑù_Gü*ÿÑTñïþh¿ü¯ òŠàÿáPx‡þЧðEÿå}ð¨ $0Áÿ ð¸Ö¿ù.¾xöŽò¾rÒ¿loXþÞš÷„\·7ú¦‹¦é1Nû*ß[Ü_»Ú™:y…n£ÇmÁ“!ð§Òïÿfo_ØOö¯Ä|èÚ=éãgrdc#7Dd{‚=«óÂø$‡‰.k»¯&¨¶PC¬M­ y±ÚK$©ÿžìÐʸéòéÅ{ù /Ä*¿^«Éeuþ~vþ]ÙãfجeOê”ù®õþº_¿CõFŠóÛÙ›ÃÖAý«ño&5{øãYÜøÉÅÐ>Àj›þÇÃßôñïþ×ÿ%ׂí}a^ÚåÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]!‡ìãÿ$÷Qÿ±£Ä_úz¾®ò¼;àÀ- Uð5ü²ßøÕY|G®Â>1Õá]±ê÷ˆ¤ª\€X…˜ÌÙf%˜“ÚÿÃ8ø{þ‚>=ÿÂãZÿäºï(®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èýª?äØ~#ÿد©ÿé$µÞW‡~Ò´-öuñõä7þ5ym|9¨Ì‹?Œuyâf[Yܲ:är¬ ‘ÁWkÿ ãáïúø÷ÿ kÿ’è¼¢¸?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK ò¸?‹ÿòP¾ÿØÑ?þ™uJ?áœ|=ÿAÿáq­ò]q_þhV>9øm_øÕ–óÄsC!“Æ:¼Œª4IòŒ×$ÆÙ@7! ´²çk0 ãEpðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—@åÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]?ä¡|Tÿ±¢ý2éuÞW‡|,ø¡_xçâLOãU[?à f?êñ³)Ò4×˲܃#eÈÜä¶Ð«ª v¿ðÎ>ÿ ð¸Ö¿ù.€;Ê+ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï+ƒý•ÿäØ~د¦é$TÃ8ø{þ‚>=ÿÂãZÿäºâ¿fÏ€Z³û:øòkÿ¤·^Ó¦uƒÆ:¼+5¬d„.UrxU@à(Üh®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’è¼®öŽÿ’{§ØÑáßý=XÑÿ ãáïúø÷ÿ kÿ’ëŠøûð BÒ¼ a,Wþ5foèP‘7Œuy—lš½š1 ÷$‰Vr¶He{ÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w”Wÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtx‹þN{Áÿö+ëŸúW£×y^®üТý¢¼+f/üjbŸÃšÌÌÇÆ:¹”2]i@ÜïUÄ•RˆRÀ”R;_øgÐGÇ¿ø\k_ü—@åÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w•ÁþÎ?òOuû8øÀZ†‡ã ÍCâ¡ý›g©ZiGû&Æcmwr‹5ÔŒˆÌÉcqû¸<ÙdDY›ÔëçÛoáGÅïŠþê?|;ðßUѾxœx¦ö_ø¾÷H¹¹“ìö&Ú8 Ó.×nÛÑ/šÒ˜ÊlÁÞ>\•ø9¢Ó»ÞïîÒÚzß×}‡VÊiGnTßø¯+ëéÊü¯mî|Áûy~Û^ý›¾ |;·»2jú¶‘®j_iöŽ<Û[7±»µ21<ÿI¨q¸!åA¾ˆøñFø§àÝ?ÄÔ-õMTˆMms ÊȽ1êARR E|UûÁ+o¾.|F¶ñgð?´¼C¨…×m¯o?s˜IkÅi°PxhÓ'‘±p¯}øûøCà?Ã[-ÓQñt³§ïon­|K¨éÉ{p@ß/“op‘¯@;UA,A'è1Ø|²9}*˜y·UüKóºénÿ/ [,eHW‚TÖÏü»ß¯oÏÜ(®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ëçÏdï À¯’4oø(ÏÃx?noD’¶—ªéV"k›À±[Ûiï\¦îñ7Ú‰~îä=Tï¯sÕeÏ ëºeÍ•íÏ®ìï"hg‚oë/ÈÀ†VSu‚$zæ¾(_ø"ïü4ÛZÿi¸øZª/En`Xÿ¡mëæ ÞãfÒÞÊWÐdx|²ª«ý¡7—»ýu}—SÆÍ«céºRŠwzÿ]v~Ñ^y¦þËþÑ´ë{;K¯ÛZZF°Ã ^5Ö‘"E*¨XÒ§ÿ†qð÷ý|{ÿ…ƵÿÉuà;_CØW¶§yX¿~"è¿ ¼¨x‡Ä:„^¥Äf¸¸˜à(ìêÌNQ’IMs¿ðÎ>ÿ ð¸Ö¿ù.¸¯¿°?ƒþ<ü7¼Ð¯5EpÃͱ»ºñ.£©-Œà²y7¼mÔ‚ÉV` ’Û R­]µ êÖ­#,C¨©ÉÑW•´O¹ÌÁ=ÿlï|~Ó5ÝO’m?Z·Öµ]R;²«-Õ­Õü÷I"`J¬ÁYA8#<ƒšúb¾ý†¿à“? ¼[yâ?ˆ÷-þ›s$M¶‘©ÍlHV*.Ìð:H¡‡*•€?8åZÃ8ø{þ‚>=ÿÂãZÿäºô³Ú8X·¾\Ðü/äú£‡(«‹©‡RÆFÒý<×C¼¢¸?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¯õþ 'ûGøoà_ìãâM?V¹«ø³J»Òôˈ3LòÂÑ™íoÉcô$ ôOÙ÷ö‚ð×í/ðÚÏÄþ¼—$ð>ö3 C*ÿ ý ‚A¾qý½?à˜VŸü(ußO«?4Øð°êšÕÍðÕ¢ˆ|Û©\Æã§pL’ܽgìyÿÞпg‡+«©k×>)ÔÂÉ©ÜéZõö™ |° ·–=è™8g’Ià£è*áòŕƬ&ý½õ_ð;[gÕþ4+cÞ`éÊ Ù[ë¯uÑ~?LÑ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%×ÏžÉÞWÊ_µ‡üÀ? hï‡þ½»šèøwZ’û[»µlzX{»UF–`×!Ü/*¨x,vqÿ†qð÷ý|{ÿ…ƵÿÉuñ‡í#ÿiºñÇ .ëÀwËeáMràWí· <Ú/šE21yÃc -½†â,=Ü‚†]V¼£˜ÍÆ6võõò躿¹ùÅ\m:Ià£wuOOÍô_zýÒ5{]J¶¾±¹‚òÊò%ž àIѰ]XpT‚#®jÅyOÿØÓÁ¿ <§h:UÏmìtØ„h°ø¿U·V=Yü¸®5,ıª2ÇV×ü3‡¿è#ãßü.5¯þK¯ª‚›TÝã}/¦‡©MÉÅ9«>¾§yPj𥶉¦Ü^ÞÜAigiM<ó8Ž8QFY™@’xWÿ ãáïúø÷ÿ kÿ’ëÇÿ±Çƒ¾%x7Pе[Ÿ\ØêQ¤I¼aªÜ*žªÛ%¸xØ«À:°ÊŒƒÒ•54¦ì¯¯ æä¢ÜßCÈÿeŸø(7€>%þÓ>ð½¥Ü¶ÃÄšÔwºõÈòáÕ XÚZ4J(Å­‹&î\8VŸ¬+ó«àü“PÒ>?j2xÞõn|¡Î²iòZ\g×Ã.v6øz?!· ! ïlÿÃ8ø{þ‚>=ÿÂãZÿäºöóúu*ÑYtÜ••ý}{¾«£û—•“ÖÆÔ¥'ݽ=?'Õ}ï¼¢¸?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¯õË>>xoömøm{â^‹[Q¶(—{ÙH;a‰‰Û@$€ iÿèý¥ü5ñßövðî—¥Üu¯ iVº^¥a+6#K”z7ÛGLàóY?µ÷üƒ@ý¢>µ¾›©kö¾'ÓCK¥Ýjšõþ§b>hn%“j>Y`Bž@*x_Øþ }Á½ø‹ÇSj°xÂþ2‰k¥ëW_Ùqž¨fµ• ŽÝðÅéžµôpùcÊåVs~Þú/ÒÝSêú?ÇÅ©[³Ó„²¶¯úëÙuü¾Ï¢¸?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¯Ÿ=£¼¯š¿à¡_¶?„gý DÑ5e¿Öîu­+TkB­,Ö·ð\¼’ܰ•PHÜO &½gþÇÃßôñïþ×ÿ%×Éß·güvãâgˆ­ÆEGW¡—,? öo¢<ÌÞ®.žËËôò]O´>üJÑ>/x#Oñ‡u5=#SˆKñª‘ÕX‚§A­ÚðŸÙßöðŸÀ/†–š$‹'½?¾¿»³ñ£¦Çy93ù6ó¢(àÁ8Q’O5ÝÃ8ø{þ‚>=ÿÂãZÿäºóñq£ÒŽ· èÞ£·*Ž”]ei[T»åÁÿÃ8ø{þ‚>=ÿÂãZÿ了ÿöbðÆ«c=­Íߎ.-®ch¥ŠOkL’# 2n°A‚+kêjü ñGü[á½·íÍ¡h’j`iÚV•¨h“kA±[Ë™ìP·h×ì…LŸwsŽŠ ×Ö †‚= ~qëðE;ù¿ix­muCÂù¼–ôʦú ?ОL‡6´²²‰`‚|k¬¤pÆ UQt ÷óÌ>YJ4ž_7&×½þo³î¿§ãå5±õ%SëI'§õÕyÿKÑh®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ëçÏdé¼wã½#á—„5 {^Ô-ô½#KˆÍss3a#Qú’NQ’IHó§üóößðwÇyuÿ Ù¼Ún³·ªê–6÷…Uõ+K›éî•ÓoE›™$Ü ÛÚ|výƒ¼!ñÓá½î{¨x¾9%m¥Í׉µ-E,çì—ɸ¸xÛ ‚2U˜¤‚<öÿ‚Têþ'Ëâïˆ/o%ç‡ï˜h––“ïŽfFù/”çiᑟœ m?A€Ãå’ÀU©‰›UW¿+w¿^ÇŒ­Ž2œ(A:owþ}­Ó¹÷epµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-|ùìåQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQEQEWϵ§þ |7ý¥¾ÅÖº‚ü_ãáÍ[CF‰çÔCi:µÛ<·r3•@ö¶Û‰”¬¥¤‘\"}DUãÍæ×Ýgù49®Y(¾©KäÜ—çQE (9ÁÆí_4~ÉÚ×ÄH?j_ˆÕ¾%j¿|áý&Ê=CS¿Ñôët<’É>blመRÙ wŽá®%‹Í…LîÆ@ë>O&þåý.×inÂZEÏÍ/½ÛOÍõ²odϥ袊(¢¸ŸÚ./MðW_ŸÄvÞ +Z·‡àÓfÕ˜Rëhº“¥:£\“± Êàli”¹UÇwc¶¢¼þ Çñ_Å?¾ ë–Þ8Öõ=cÅÞñF¥¢jêö6֚Κ‰ šÚÛPû$qÙIv¶³[³Ëd¦Ù·-åÌ­%Yïtšôi5ø?NÄFWºìÚù¦ÓüPQE%ñGüWþ "Ÿ²«¿ øsâOƒ¾üBÕ|7«x’ÏRÖïìbš,mÙ£ŠÒ °ÑÝ]\ݘ-Ò-Œv=ÀZ5ë߇>8Òþ%øFñ‰«iºî‘­YEyg¨é÷1ÜÚÞÄèeŽHÉGF!”Aâˆ.h:‹kÛúù¦»Ý1Ô\’Œ^òMúZÛú©&¼Íª(¢WÈ?¾+|HøEûv5çuoŒZ? [_Ò´_ Ë£ÚøNãÂSKuk)øxß^Y%Ôô›T¶ÑîqŠŠ•#NsÙ+¿‘Pƒœ”c».Q_Á3k?üqñVuñ5þ0èZ÷Äï·Œ´]\°ðÈð¨µÚ™Ž—6™æß ^Z¦5)ÖGY·ù{ƒþÙ­§NPKY»éÚͦ»]4Óµõ3ŒÔ¯Ë·~÷I¦¼¬ÂŠ(¨((¯)ý²¤ÀÍcÄ÷?|að‡Fðe´ú櫬xzÛHžwµ†g×R²¼n>a±Ë*€Ø%K¿b[?ÚþË>“âv³©ëž7¿´kýF}F8®àóäy¢¶˜Yù’^8Y£‰Ú&lsDuæò·ã{~L%îòÿzÿ…¯ù¯¼õJ(¢€ (¯?ॵ¯Åƒ´ŒÚ…Õ>K¦øcA±´ŽúãO»Òµ°Æ·nÐÙÛïÝ}uæ ¹b‹fØþø¦•áôjÿ×ü ¡7ïÊ¿¯—£³òÕQHaE|ñÿñÿÄ„¿ <=âoøº×Ã6Ö^,ðý†«oýåΫî¹§Y4+4ÌÑÓqp´ŒÍIbØÞg™~Úß¾(Øø‡ãÆ·àÿˆ÷^ Ó¿g¯[xžÓD±Ò´ëؼUtÐ]ÞI¢×Vò̶Í¢B‚ÒKyù˜ÈÄ Dšqçz+¸¿+%+éÒÒ[]ß¡¤iJRP†­ÚË»nÖí~ºÙ[­ô>Ô®ö¨ÿ“aøÿb¾§ÿ¤’×aáÝNMkÃö7’Âm¥»·Žgˆõˆ²‚WœtÎ+ýª?äØ~#ÿد©ÿé$µr‹‹q{£ sSŠœvzåQRYÁþÎ?òOuû+©åOµ/´›{EŠ#åÄ6b4 ë4QTÛi'ЭÉî÷óèQE 9ߊ ü?ñ¯Â  xžÀêš<—V·’Z›‰aI¤·ž;ˆƒùl¥ãó"BѶQÀ*êÊJžŠŠ(¢Š(¯øçÿüøUûGxÞïÄ,Ðõ«›íVÊ 7V†ÃÅ®•aâ XYÚ(5KK˜­ïâ_6EÙuªRFB ’µìôQÕ>¨/¥»‰kjˆ¡UFJZ( I$¬‚Š( gšx#öGð?€~0_xöÚÛÄZŸŠïÂE{®ø£T×KK‡Wž;¯n&ŠÂ9 G¹-R%ajAT@=.Š(Z%²ÛÈ­·» (¢€<Ëö›ýüû_øsNÒ x›Åº7Â}&?_øJêë~‘%¦­e4‘\Y™~ÐöÒÈ LÀÁ4ŠËÈn(ÁFaCûu_|±½Óü­xWÀ¿-üOâM'Äp}¢ÛU°ŽÊî…a1I®^xÈY6®Ù™þÿÁ)þ9~Í^!ð­ç†n>xëJøgiâïø;Bñ&¿¨ÙAká½Z{{‹)%lnX][žÕ¡XÊI—‰Ô‚§(ÎJ3ºÖò·¢ŒÿÀ¤Üzõ“iA©é8ÆðåzZ7ùÊiÿà1Q—þJ“rN?yjŸµÃ-ÓV¸½ø‹àK84{½NIõûHÓN†ù¶ÙK12\7³`JxBÕÑx{â/‡¼]â=sGÒµÝSÕü34vúÅ¥ìS\é2É–8î#V-4l®¡À%XÁÍ~kk?ð@-nOü2ðx£Ãú¿€Gëo|I’\[Ï«>Ÿ$÷z]Åœ ©Þ\?,e"DÁs•?\ÿÁ5¿e¿þÌßõù~'êÖ>'øëÄ7> ñ%þ…$²ÙLû"µ¶Tyb‰Ûe¥µºœÆ¸`Øï¥7RîÉ9[ÎÒJ?|T¤û{½ÎyJIBÊ÷µü¯¿º^éôMQYQ@Q@Q@Q@Q@Q@Q@Q@Q@pµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’ÐyEP'ìßá“yw43x¶Çí·S^Ë—‹u[H<Ù¤ieeŠ+•DÝ#³ªXñGü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉu_Tý—|+®i·W·4½²¼‰ ¸·ŸÆšÌ±O¬Ž­tC)‚ÁƒEè”QEÿÙColPack-1.0.10/Graphs/mtx-spear-head.mtx000066400000000000000000000012101266356121500177030ustar00rootroot00000000000000%%MatrixMarket matrix coordinate real general 10 10 28 1 1 .666666666666667 1 2 -6.310289677458059e-7 1 3 .283314888590275 1 4 .27224066696528 1 5 .666666666666667 1 6 .27224066696528 1 7 .666666666666667 1 8 .27224066696528 1 9 .666666666666667 1 10 .27224066696528 2 1 -6.310289677458059e-7 2 2 .27224066696528 3 1 .283314888590275 3 3 .577703998805546 4 1 .27224066696528 4 4 .283314888590275 5 1 .666666666666667 5 5 .283314888590275 6 1 .27224066696528 6 6 .283314888590275 7 1 .666666666666667 7 7 .283314888590275 8 1 .27224066696528 8 8 .283314888590275 9 1 .666666666666667 9 9 .283314888590275 10 1 .27224066696528 10 10 .283314888590275 ColPack-1.0.10/Graphs/mymatrix.jpg000066400000000000000000000317451266356121500167260ustar00rootroot00000000000000ÿØÿàJFIFxxÿÛC      ÿÛC  ÿÀtå"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ý›ø[ð¶ÇâV‡ªêú¾«ãIoeñ·nM¿‹u[H’8u[¨bEŠ„cQ÷}rk¥ÿ†qð÷ý|{ÿ…ƵÿÉt~Î?òOuû=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’뼯ý»ÿn/þß´ KW»ð®§âýe4ø£ÄqøsEnï5 #”[B°Á)Ü"‘™ö"£3Š™IE]ù/½Ø¨ÅËo7òJïð;_øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK«Ÿ>%Ïñàׇ¼Qq'ƒæ“\µb_ ø€øƒF•m|`ƒí²í;ü”ä&_üxð?µ¹4ÝoÆ~Ñõ‚³Úßjööó a•%à ‚ãkIEŸ½Ñœd¤”–ÌÎÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ©(?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ+Í¿jø(ïÃï€ß ¦Ôtm@ñ~½sº-?OÓu®“~c‘®A9Ánƒ¹ápÕqcFм¥²1¯^n­Wh­ÏIÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºðoø'gü†Ú}¿áñ`·±ñÄJòÛ´I² V%‰Aü2"ƒ•è@ÈîÖµ¶a—×ÁWx|B´—Ü×uägƒÆRÅRU¨»§ýYžkðÃB_|sñf‡i®Üé‘hZEôpêZÅÞ¤bš[M$ek‰$eܰDg4UïÿÉÏxÃþÅ}ÿJõŠ+ˆêÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š+Ê¿j/ÙûZøÒ¾ Õü'âM+Â~4ø­kFÔ5Mµ›ÒZ\YÏ Åª\[Hèð]K.â&WXÛ,¡‘½VŠV{®é¯½XóÙ;ö{OÙ‡à•…U]rüß_ëž¡’XÃyy5õÜ‘[©a&ââ_.-ÎQ6©w ¹¹ûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’ÕJM»²Rÿ?›ÕýçyERQEQEQEÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$µÞPEPEPEP\Gíû>økö—ømyáÙ‹‹Kž Ó{€!f‰¿…†~„ ‘]½¥*³¥5R›³Z¦ˆ©N5"á5tÏ›àšß²?†þü Ñ|Ij‚ÿÄÞ2Òíõ ÝFXÀx¢š5•m£íw ó—a“ÀU_¤«ƒý•ÿäØ~د¦é$UÞV˜¼]lMWZ¼¹¤ú™áðÔèST¨«E‡äç¼aÿb¾‡ÿ¥zÅxwþN{Æö+èúW¬Q\æáû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@Q@pµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEQEQEQEpµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEQEQEQEÁþÊÿòl??ìWÓ?ô’*ï+ƒý•ÿäØ~د¦é$UÞPáßù9ïد¡ÿé^±Eÿ“žñ‡ýŠúþ•ëPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@Q@pµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEQEQEQEpµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEQEQEQEÁþÊÿòl??ìWÓ?ô’*ï+ƒý•ÿäØ~د¦é$UÞPáßù9ïد¡ÿé^±Eÿ“žñ‡ýŠúþ•ëPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@xgíñûdÃü4ðî½äxÿÂCâtµøËÅßðŠèšw™oq7q}ökŸ,£ìÊ;šEîuÅümо!ëÞ´áÇŠ|áMU.7\Üx“Â÷> ·š¬6$Pj,»iÞda€FÌÂ'ÍeËÝ}×W_5§—MJ…µ¿g÷ÙÙüž¾{2÷ÁMñ?á7‡Cÿ+ýŠ<1ñ¿áˆ·g}m½¿­úÛc›í½Œ¾¯n{i}®y—üöéÑ>7|:Ñü©4ŸxgOŠÊÚ ØU¶‚0‹$Y9óoObÃÁ>·¯–ÿà™±w‡þ|#Ѽc Sñ_‹4Ø/šñ“‹(&dX"§ 77V0Òî,-¬#|hf¢k‰Oð¨ vŽ®Ã€Äváðë×úµ(Þwµ¿?¸æÄb©P¤ëVvŠþ¾ÿ#éª+οfOÚoÃ_µOÃXëß²§ìoðãá߉üG/еßh6ºeÝó|½ñĪb„Å #gŒHQTÈY÷1òø*ì¢üið³ñIû>‘âÿ ØI{y.ÜG«ÛAfIp?Öª&ýFãiO¯+ƒýª?äØ~#ÿد©ÿé$µéá³xþ!À?µ‚Mx÷òY%‘¿Ì÷ ; xÙÔ¸/¦eEÇâwK½Üéëø[ç¸ñ?îo²i¿EéúüÞ:(¢‚¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–€;Ê(¢€ (¢€ (¢€ (¢€8?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–»Ê(¢Š(¢Š(¢Š(¢Šàÿeù6‡ö+éŸúIw•ÁþÊÿòl??ìWÓ?ô’*ï(ƒðïüœ÷Œ?ìWÐÿô¯X¢ÿÉÏxÃþÅ}ÿJõŠ(ýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ #öŽø)ÿ ðS_ð_ü%¾7ð'öô+ö÷„5Oì½oNÛ"¾ûk¯å±Û´§*Ì;×ä·Â­7á·ÂÏø(.…áûBÿÁQ|C¦xcÇVÞoëÞ&{¿†z–·è?±î®¼d\âÑТ«;Ý´‡¯ÖïÚ/â±ð›ö}ñÏŠ¼=¢·ˆõÿ x~ÿTÓtXNæ y%ŠßåþñÕWŸ›Šüw¿Õ>|MøŸû;üVðÇé|{ãߊ?ü/®x‡à®…ãy?á}Ví–]CU Ê÷VSÛÌó7²,°pÛðLûô-µàŸ{ÎV‹^‰OÉ>[û·+Lß[M®Þäo/›n6î¹­­Ûª(¢pµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEQEQEQEpµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEQEQEQEÁþÊÿòl??ìWÓ?ô’*ï+ƒý•ÿäØ~د¦é$UÞPáßù9ïد¡ÿé^±Eÿ“žñ‡ýŠúþ•ëPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@yÏ¿cÏ„ >*ê;ð×Âχ>ñ¾¬Ó5÷ˆtÏ YZj·¦fß1–ê8Ä®do™·1Üy95èÔP´w[ƒÕYìÇülø©ðÂßé~ñÄBæåm¡Ò<8¶béòŽí#I{qmmj¨Ä´³ 'j®çuSØW‘~Ùß µo ­´;‡_¾+éòß$šŸ†¾"Jðiwq*±IU³½ ,rùl[8#p ‡ YÕrå÷wþ¿¯ÕnT¾¿×õý_c«ýž¾8èß´¿Á xÿÃÑêèž-ӢԬ㾄CqH¹Úê .G#(ÌŒ«2ƯíQÿ&ÃñþÅ}OÿI%¬ßØÛàþÍžð§ŠõÃâLŽfº¹[™î¢ƒÍžI’Ö)g&i!·IÞL;G £7ö¼øW¦kþ!ks]x‘/!ðÕü‹!Ô ´%-$Ú ²L `p7)BÀä×E^^w˵̩¶â›þ¿/ÉzÁEpðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—Y–w”Wÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÞQ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÐyEpðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—@íÿñ¿Ã¿?eÿ¦¹z°Ýø“I¼ÒtËUÃMy<°4`*ÿuw‚ÍÑG¹Pw?e?Ú³Ã_µ¯ÃXµí_"î ±êZlŽ úlÄ}Öþò®ІQáßðPïø'߇> |ÕüU¦_kxÂt÷É6§­^êkuo4¯ûD²èÅJàn<ä‹¿°ïü/Kø àí^kãMZ .›JÖîôèì"8o³†¶–3' f%r£os}ÃåŸÙ^×û{íú[µµ¾÷ûÛcÿ´=Ÿ"ö6ßþ{ôí÷ŸYQ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%×ÏžÉÞQ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÐyEpðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—@åÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]²¿ü›ÃûôÏý$Š»Êàÿeù6‡ö+éŸúIw”ÁøwþN{Æö+èúW¬QG‡äç¼aÿb¾‡ÿ¥zÅ~Î?òOuûþÍžðý„¼Mà{MÄYÇ£ø†îÎïU·ØÌ ÜÍiqq’Ès+2Lù2pÙQó?üöºø«¤^|Qðõå̺®`[TÓ®nY¡–Ò,dƒqÄlŠ™ ü7çÌû~¸?Ú£þM‡â?ýŠúŸþ’K^¦4¯ƒÄýj†’íѧºô8q˜ Xª[U߯¯©ãß±wü®Ãö}øZ-õÝcÄsx‡Ue¸ÔJñ ö›kÄj¶ÓFnN]²IÎ0+Øáœ|=ÿAÿáq­ò]w”W>3WZUë;Ê[›a°Ôðô£F’´QÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w”W1¹ÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w”Pÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉuÞQ@ûIüдoÙ×Ç×ßøÕåµðæ£2,þ1Õ牙md ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—]åÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w”Pÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉuÞQ@ì¯ÿ&ÃðãþÅ}3ÿI"®ò¸?Ù_þM‡áÇýŠúgþ’E]åp~ÿ“žñ‡ýŠúþ•ëQáßù9ïد¡ÿé^±E³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEWûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’ÐyEPEPEPEPûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’×y@Q@Q@Q@Q@ì¯ÿ&ÃðãþÅ}3ÿI"®ò¸?Ù_þM‡áÇýŠúgþ’E]åp~ÿ“žñ‡ýŠúþ•ëQáßù9ïد¡ÿé^±E³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEWûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’ÐyEPEPEPEPûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’×y@Q@Q@Q@Q@ì¯ÿ&ÃðãþÅ}3ÿI"®ò¸?Ù_þM‡áÇýŠúgþ’E]åp~ÿ“žñ‡ýŠúþ•ëQáßù9ïد¡ÿé^±E³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEW ûE~Óý“~Ýx¿âˆ­|9 Úo̲E$óNÉÌé +Í;¬QK!H‘˜$R9QˆîëÃà¤Ú'мkû|Nð¯‚ü®øïÄž6ðÖ¥áË-?K»Óí^nìæ…'–Kë›x„(ì»ö»Iƒò£sŒêÉÆ-ÇëúòÜß N¬cQÙ7«íçòüv=¯LÔaÖ4Û{»gó-î¢Y¢|¹#‚:×~ßü=ð{ö^ñx×/’ÞišVn¸i®çšB¯ , €{qðXÕ5σžŸ[ðƵàÝUl’VšÎkË6Œlýœ÷Ûw ’·ÊÃ89Qò?üköñOÆ;¯øX¼ÖÎøñFø§àÝ?ÄÔ-õMTˆMms ÊȽ1êARR ElWÊ¿°‡ì%â¯ÙÛá‘©|AñF…¬kR ËÍ3Jû öV-´ƒíó.>û¡PØæûwü*ÿÑTñïþh¿ü¯®,ÂX‰ÓÃÏž èûÿ]úîvàêÕ©B3­Y5ªþ¿¤w”Wÿ ƒÄ?ôU<{ÿ€š/ÿ+èÿ…Aâú*ž=ÿÀMÿ•õÆtåÁÿ ñýOÿà&‹ÿÊú?áPx‡þЧðEÿå}w”Wÿ ƒÄ?ôU<{ÿ€š/ÿ+èÿ…Aâú*ž=ÿÀMÿ•ô~Õòl?ÿìWÔÿô’Zï+ž=üñ>¡ð/Æ[|Añæ·q>ƒ}Zq²ÒX_¹·qŠÈwœ.ƒ|Üpk­ÿ…Aâú*ž=ÿÀMÿ•ôÞQ\ü*ÿÑTñïþh¿ü¯£þˆèªx÷ÿ4_þWÐyEpð¨7×¼ á[»iMÆ¥­x·O¸Ôtý2Æ8¤yeû<7¦FÊ¢ü×1*+;’ÛoGö9ø¹â_²ß|gâ­" _ñ&‘ õå¤ËAœdH‘ËûÈÒEÛ"Ç!.‚@¬I’:ßÊßíù=÷³¶ÀôkÏô=*Š( Š( Š( Š+‰ý¢ü[®øி«øjKXu›HfŸA¿×ÖÞ¢IŸaþ•xËvX!*Ò0 ½.&RåW×õç â®ìvÔWˆþÀ´7ˆi_€÷ߊdðüºæ›¯j:4òiVSéžj[Ü2Ã%Æq,×:mÃÂcw³¹‘¦‹xÞ‰}º´”mo4ŸÉ«¯=º=WRT¯&×Í;?'ê´}ÿòsÞ0ÿ±_CÿÒ½bŠ<;ÿ'=ãûô?ý+Ö(©~Î?òOuû…áÛ +­NûZ¹³·Žu Ä….oT4‚ãˆ;‘¸ˆãDÉ;UF»EMÝÜ”¬¬QE!…Q@Q@Sû_~ʰþØ ,ü/wã_x*ÊÛR‡RžOÿg±ÔÄ[±kuõ­ÔÛ3Í ÄUÊ(lŒƒÜü4ðŽ¡àOXé:§Šuß_Ú+ uf+(¯¯IbÀȶvööà€B.Qœœ“»EÑ4º»üíoÉ jí7Ñ[å¿êŠ( Š( Š( ¹Œ.>*øãG³ñO‰üzòÅ=¾³áù ŽþÊHäWEÄSA"»Z9¢’6V ©íÓÑI«;{û8~ÎzwìÝám^ÎÛZñŠ5jÓkºæ½®IjÍ쪑™¥ñCn›bŠ•!†4T‰p¹É>…EMÞÞV^‰+$»$´K¢Ð”’¿ßÍ»·êÞ¯Ìàü;ÿ'=ãûô?ý+Ö(£Ã¿òsÞ0ÿ±_CÿÒ½bŠCÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+ÍioÚãÀŸ²6áûßêÅ¢ø¯VM G¶Ò¼?¨ë—º•óÅ$«VÖ0O31H¤n/\â½*¾Qÿ‚¢þÈÞ"ý®µ¿ÙöËH°Ö.´o |Mµ×|Is¥x‚M÷MÓ’Âú'ž+˜g†áXI,CýüÏ›ŒÔÉÊñQë(§äœ’oä›wÙnô*<¼²ré5æÔ[KæÒVë²=ãö~ý¢üûQü;_ø#U“UÒåÎ7Ÿcq§ÝY][ÊÐÏoqmssÁ4r) ±«0A=µ~Aøsþ ­ñ_Áºw…¼=ñà(øéðëáåß4¨41©h\x¶îúât¯]Çys]5»\[Ë<ÎoMÒ„o4µ.ÿ‚6|pÕüà‡úÅÆ·§üIøe¤xc∭5¨RMTÐež÷K˜I+­ÅÆd–+a"$‡l°@Až-FVv|¾©56ÛZl¢´ÞóŒ]¥t.V¥(¶´¿£´¢´ï¤›¾—åvM;Ÿ¯”WË¿ðK_‚<ðÃïxëâ׆¢ð§ÅO‹>'—[×t徂õ­!‚l,â2Á$‘‘äZ¬˜YvÎ@úŠ´œ9ZW¾‰»tm&מ—ëc:srMµmZû›WùîQEAaEPEPEPáßù9ïد¡ÿé^±Eÿ“žñ‡ýŠúþ•ëPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@‡äç¼aÿb¾‡ÿ¥zÅxwþN{Æö+èúW¬Q@ì¾_hr^¦“ñ ÆšE•åýÞ¢,àƒJ’($¹¸’âP-“É·Ì•È ì@8Ïcþˆèªx÷ÿ4_þWÑEð¨&Õu›¿kÞ$Ôõ{[k)'Ô–Ñ<¨mÞwm …~õ̤–œŽp(¢ŠÿÙColPack-1.0.10/Graphs/mymatrix.mtx000066400000000000000000000002031266356121500167370ustar00rootroot00000000000000%%MatrixMarket matrix coordinate real general 3 6 8 1 1 2 1 2 1 1 4 -0.9823 1 5 -0.0071 2 3 2.1972 2 4 2.7726 3 5 3.6428 3 6 3.2721ColPack-1.0.10/Graphs/mymatrix1.jpg000066400000000000000000000522171266356121500170040ustar00rootroot00000000000000ÿØÿàJFIFxxÿÛC      ÿÛC  ÿÀs±"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ý›ø[ð¶ÇâV‡ªêú¾«ãIoeñ·nM¿‹u[H’8u[¨bEŠ„cQ÷}rk¥ÿ†qð÷ý|{ÿ…ƵÿÉt~Î?òOuû=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’뼯›¿nÿø(¿‡ÿbïø?Ãê? ì|QãHo/¬ßÇÞ8Áº6–žJÌï|Ö÷ f/q Ç Bìù‘‰UL¤•“ëý~Z¾É6ôE(·{t=WþÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¬ðŽ«>½áM2úétô¹½´ŠyVÂìÞZ+²a ÅËIÚåpÁÚ¹ÀÄñOÇø[“MÖügáMQˆ+=­ö¯oo:RQÜ0È Ž9´”\[‹ÝÆJIIlÌïøgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ’ƒþÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë¿nø)ï†>ø XøWÑ|UâÝV3öylîc»´Ó‘æÈÈJ³õÛ{e¸ÀmØóþ _à¯ÕüU­h^ñNœ«ýµýìv°\žÓ@Ò0Ü­ŽW%ðr0ÇÔy6-`Ö9Ã÷wßõ·n—<õšaž+êŠ^ÿõ§¯‘ëßðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—Gü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã•垀Ã8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]ðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽPÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%Ñÿ QðÃþŠ?€¿ð ´ÿã•ò‡íÿ·øoñ/NÑ>¦™â+-.å_X¿gó-ïTpÖð:ñYFyîô2ܯ«ìpÑ»ßÉz³‹˜PÂSö•Ý–ÇÕÿðÎ>ÿ ð¸Ö¿ù.¹?_ôß| ñ¦¹¥êþ;¶Ôôm úúÎcãMbQÑ[»£m{’­†PpÀƒŒEv³ÇíáïÚgáu—м7;IgrLSC Ķs¨áqýåÜ:pApj?Ú£þM‡â?ýŠúŸþ’K\uiN”Ý:ŠÍhÑÕN¤jANéìw”QEfYÁþÎ?òOuû-ÑômKÓϮøY¼Ecy§ß5´’/—v¬³$¶²9•£Á‘^)7žÝEL ¥¿Ÿâšzm?'b£7uýu_sI¯=NGàÁ+ösøàï‡ú—ShÞ Ñlô+.J™¤†Ú…ʪ®â¨ Ú g Š£ûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’Öµ*Jrs›»z³8AF*+dw”QEAAEPEPEPñþJ¿û'ÿÓ.©]åpÿä¡|+ÿ±¢ý2ê•ÞPEPEPEP\‡äç¼aÿb¾‡ÿ¥zÅw•ÁøwþN{Æö+èúW¬PyEPEPEPEPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@Q@Q@ ÿýœ<7ñÓöqñ&¡«[Õü'¥]êšeô` ¡x¡i d÷ö`©úŽ@5ÖþʲŸ†¿d¯†±h: ^}ÜûdÔµ) õ)€ûÍýÔ!P('©,ÇKö¨ÿ“aøÿb¾§ÿ¤’×y]0ļ7Õß³½íÒÿ×M¯®ç*ÁPUþ³Ê¹ík…Q\gPQEQEWÉÿ·Gì àÿÚâï€uWiô=SÄ:×ö^­sf«›ëxì®®²AãÍŨŒIÎòjõ…pÿä¡|+ÿ±¢ý2ê•׃ÇWÂTöØyrÈçÅa(â!ìëFèé>ü?Ѿx7Oðÿ‡ôû}/GÒâÛ[B0±¯\ú–$’X’X’I$“\ßíQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K\Óœ¥');¶o¨¥«$w”QEHÎöqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ (¢€ (¢€ àÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zï(¢Š(¢Š(¢Š(¢Šàþ/ÿÉBøWÿcDÿúeÕ+¼®âÿü”/…ö4Oÿ¦]R»Ê(¢Š(¢Š(¢Š+ƒðïüœ÷Œ?ìWÐÿô¯X®ò¸?ÿÉÏxÃþÅ}ÿJõŠï(¢Š(¢Š(¢Š(¢Šàÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuû+ð&á5™ñ´z„ƒSø‡ñ þ½&Ûì‚Û÷Kqö+¿6i>Ñ•jñœœb¾’¯,ý§~|Oø© #À^9ð/ƒtÍJÊæËV:ï‚î1øCBøñ Ã÷Þ*ðÝž½?†¯âMŸS†;¹KI<µKdmdäc­w?~i¿þxSÁ4—RéÑí4K'¹pó¼6Ф(ÎÀ\ªHg8¥e~Õòl?ÿìWÔÿô’Z誢¦ÔÕôô9蹺qu•ýz‡ü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã•ÞQYšü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã•ÞQ@ü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã•ÞQ@ü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã•ÞQ@~ÖðUßøoö€ð}—…­-üO¡ø3U{íKP†l¥Ûµ­Å«GlÀíeD¹‘·ò‚òÍõG„¿lï…>2ðÕ–©mñÂðßD%X¯5{{kˆ³ü/¸daЂ+Á?lOø&ǃ>,~Ñ ×àš}x¿Z{zÞÎ5 zVÎæïÎNÑÊÿf(Ç0>7ßõ§‚¼¤ü9𥆇¡Ø[éšN™‚ÚÚÚ‘(ýI'$“’I$’I5ô¤ò·…¢°Iª–÷¯ú÷wÚÝ7{™¾#øÊ·¤}šå´€2pªå˜ú =&¾Bøsÿsðæ¡ûbëWš–šÚo‚uÛ+MßQrLÖÂÚ[—ŽâUé±ÚêMÀr /\ýóªivÚÞ›qe{oÝÜm ðL‚HæFee< Aàƒ_ü5ÿ‚[ü?ðçí©¯]H&¿ð执ØëvÂo†9®f»A±$Éfв©ùаS¿è2Yåq§WûA7+{¶ý<üÞ–ü|lÒ9ƒ?©´•ýëþ¾^šŸLÚ§á{GÄê`´ÿ㔿ðÕ ?è£ø ÿ Oþ9]àWÏžÉÁÿÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9]åÁÿÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9]åÁÿÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9]åáß¿i?‡Z7¯á¼ñ÷‚­e볪M®ZÆÍš½ä‘¸þë#+)èU]¯ü5GÃú(þÿ‚ÓÿŽQû8ÿÉ=Ôìhñþž¯«¼ þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊï( þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊï( þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊï( ’ÿà ðP?ø#à>·áÿëz?‹ußé÷dQi—ÑÜÅg±´o4¯!pí^¬}²k¦ý“¿à¥øûðÞ;¿ëšƒ¼Kd-FÇQ¿ŽÖ7|­¤a¾6Áã%ðsò³Yÿ‚~ËÞøóû>xƒYÔ úÿ„4«­KNÔ"Qæ M)ÿ½íÆ?„œŽàõŸ²ì…áÏÙ áÊiB-Þ­vMWU‘šþP?ñØ×'jgNI$ý§•ÿe¨¤ý½ÿ¯.[tÞþGŒ£˜h6Úö6þ¾wùXÝÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür»Ê+çÏdàÿáª>ÑGðþŸürøj†ôQüÿ…§ÿ®òŠàÿáª>ÑGðþŸürøj†ôQüÿ…§ÿ®òŠàÿáª>ÑGðþŸür¾Pý·¿à©>ð/ÅYx),<^ÞÕ¿µu¸nCYÈÖâÙ­â‘2ü»—;ÆUYTa¾`>ë¯nïø'¯…¾<|^ð6¯k+h¯Š5£¦jó[Æ Ý–w7FM½ÛmŠï¼œsíd2Ë㉾b›…Ÿ¥üí¯ÝÔò³ˆã `]¥u÷y_OøÑß~:øsöømc⟠ދ½:óät`kI@á•rvȹ ‚T‚iþÕòl?ÿìWÔÿô’ZÜø]ð»Bø3àm?ÞÓáÓt6?.(£“ݘõfcÉcÉ&°ÿjù6ˆÿö+êúI-yx‡IÕ—±¿-ô¾öésУí=œ}­¹­­¶¿‘ÞQE‰©ÁþÎ?òOuû;ÈìþÛ>RC@Ñ–©Þ˜Ë£ïâaAè¥×¶±[uݽÖÞc¨¹hJªÝtù7¿ÊÛ=Ïݪùûöåÿ‚tx3öå𖸚¶£âÏø¦ÿÂÚ‡…¬5#Äú¾Ÿœkó ììï-ἋÌ»C8eFªß/O h©i6ŸUþVü›^Œ¨T”ãåø4ÖuIüŒø2×áׂ4Ê}JæÓG´ŽÎu ûBêEE K‹‡’i\ã—‘Ù‰ä’y¯6ý¯>xC]øñ ÄÞðÝæ½†¯åRŸL†K¸Þ;I<¶•. àm ä`c¥{pµGü›Äûõ?ý$–®RrnRݘ„T#²Ð?á•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ®òŠ’Îþ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( ø§û6|:Ó¼sðÚø*¯üG4)‡j«qÒ5)8 ó.øÑ°xÜŠz]¯ü2¿Ãú'ÿÂ~ÓÿÑñþJ¿û'ÿÓ.©]åpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEpðÊÿ ?èœx ÿ ûOþ7\V…û6|:›öŠñU‹øÁMeoáÍx­Î‡jbŠI.µUwUÙ€Ì#ŒHs÷E{p~ÿ“žñ‡ýŠúþ•ëÃ+ü0ÿ¢qà/ü'í?øÝðÊÿ ?èœx ÿ ûOþ7]åÁÿÃ+ü0ÿ¢qà/ü'í?øÝðÊÿ ?èœx ÿ ûOþ7]åÁÿÃ+ü0ÿ¢qà/ü'í?øÝðÊÿ ?èœx ÿ ûOþ7]åÁÿÃ+ü0ÿ¢qà/ü'í?øÝ`üJý†¾üMðN¡¢Oào ik}E¼Ó4»{K»Vê²G" !ÁÇ ô ‚EzÕ¥*³§5R›³Z¦ˆ©N5"á5tÏŒ`oø&§ƒ|§ë:ÿŠm´ïjÚºŽ“iý’Ikm¥äÖ¦O)÷)‘Ì%²s´r~’ÿ†WøaÿDãÀ_øOÚñº?gù'ºý"ÿÓÕõw•ÑŽÇׯUu±¼¿­»á0tpÔÕ*²8?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆë¼¢¸Î“ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê(ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê(ÿi?Ù³áÖ…û:øúúÇÀ> ³½³ðæ£=½Ä¬rÁ"ÚÈÊèÁV9Wkÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãt~Õòl?ÿìWÔÿô’Zï(ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê(ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê(ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê(ƒÿ†WøaÿDãÀ_øOÚñºæ|Yð[Áß~*ü/¾ð÷„ü3 ÞËâ;ˆãNÒൕã:6¦Å "‚T•SŒã*=+Ø«ƒø¿ÿ% á_ýÿé—T ò¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–€;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê+ùôøs⯃š§ü[ʼn®|}øGàAñîæÚÇÀ­û9Zø‹PÕä]V1ÏOo%Å´×2îO5E¼¥Ú=‘ˆëú ¯Ç¿~Ô¶UÏü/ øsÄ¿µ%ßÃóñB; ´ýCörѬ<#‚5 .xˆÜ¼Ïn¶ü»“¼ )ùY†L“êôòWœï¯n±’µÛZ!â?Üj.‰§ç¤gÓçÒQw²[³öŠ(¤ ®ö¨ÿ“aøÿb¾§ÿ¤’×y\íQÿ&ÃñþÅ}OÿI% òŠ( Š( Š( Š( âÿü”/…ö4Oÿ¦]R»Êàþ/ÿÉBøWÿcDÿúeÕ+¼ Š( Š( Š( ¸?ÿÉÏxÃþÅ}ÿJõŠï+ƒðïüœ÷Œ?ìWÐÿô¯X òŠ( Š( Š( Š( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ (¢€ (¢€ (¢€8?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–»Ê(¢Š(¢Š(¢Š+ƒø¿ÿ% á_ýÿé—T®ò¸?‹ÿòP¾ÿØÑ?þ™uJï+ƒýª?äØ~#ÿد©ÿé$µÞWûTɰüGÿ±_SÿÒIh¼¢Š(ƒýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ #öŽýœüûZü×þüAÑ¿á ðw‰á[}OOû\öŸiE‘dQæÀé*áÑNUãÓ5øÓð³öPý–~þÞ.³á¿ØsZÒ¾ø/ⵯtß‹_𶯧’ÓÄÐ^Ço :—+ºŽÈ÷±e)û„f:ý›ý¢õhÿ³ïŽnüoowã«_ßËáØ'@ñM¨­¼†ÙS(@A#9¯Åï |Hý–jÿÚëàоøW_ñíÇŒ|=/ÄXõOj6wlvê°ë·z­£C•±ùšÞ1"\˜Y `¿ßàãÞ ÛFù¥e%mm¥Ìî¹9£+JÜ­âôÁNý¦×dãÙßK͸¨èù¹ešýÓ¢Š(WûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’ÐyEPEPEPEPñþJ¿û'ÿÓ.©]åpÿä¡|+ÿ±¢ý2ê•ÞPEPEPEP\‡äç¼aÿb¾‡ÿ¥zÅw•ÁøwþN{Æö+èúW¬PyEPEPEPEPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@Q@Q@íQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K]åQEQEQEÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w•ÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$´ÞQEÁþÎ?òOuû™ —q¼v’yl%*\ÀÚAÈÀÇJ謠ªISwWvôéÛòG57N.¢³²¿¯SØ(®þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºÌÔï(®þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï(®þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï(®þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñº>/ÿÉBøWÿcDÿúeÕ+¼¯ø§û6|:Ó¼sðÚø*¯üG4)‡j«qÒ5)8 ó.øÑ°xÜŠz]¯ü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐyEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~ÓÿÐi«êöº•s}}s•œM<óÏ Ž(cPK;1à(’OLWÅŸ àª^ñí§®Á2ͧø_\Óìt; ráöDÒÛMvâI€cŠCvT1?/–¥‚†;>˜Ôd…š®Ÿ=´ß< å\FѾÍÚ7Á8e@Ê} Ž ƒ_!|9ÿ‚FxsOý±u«=KRmKÁ:•¦µo§8"k‘s-ÊGo+tØk&â9`W¦N>ƒ%ŽVéÕþÐmJÞí¿O?],xÙ¬³RŸÔ’µõ¿ëåé©ú` ƒÐÑ\ý•¾¨|7ðþ¥ûOþ7Kÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãuóç²w”Wÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãtÃ+ü0ÿ¢qà/ü'í?øÝw”Wÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãtÃ+ü0ÿ¢qà/ü'í?øÝw”Wÿ ¯ðÃþ‰Ç€¿ðŸ´ÿãtÃ+ü0ÿ¢qà/ü'í?øÝ³ü“ÝGþÆéêú»Êðï€_³gígÀ×ó^xÁWR§ˆõØæÐídeŽ=^ò8ПuQUTt  ®×þ_á‡ýá?iÿÆè¼¢¸?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆè¼¢¸?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆè¼¢¸?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆèÌवW†þü×´+éE߈¼c¥\éÚ~Ÿ0,Ñ´Mq'÷c]Ç݈Ú?ˆ¯cû!~×¾ý¯~¦¯¤:ÚjÖcÕt©¬%#ÿ°v¾0@ à‚’Á@ÿàŸžñ¿À}oÄÑ4 k¾Óî58¥Ó,c¶Šò8£iR0d)ÚÝTûdWMû'Á5üð á¼vž!Ðôø–ô,ºö£aÔhøÿUȧdk“Î9äãåUúC*þÊRMýbÿ×—-¾wò x;áÏÅ_…÷ÞðŸ†tÙ|GqÜiÚ\²¼gFÔØ¡dPJ’ªqœeG¥{pµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEWûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’ÐyEPEPEPEPñþJ¿û'ÿÓ.©]åpÿä¡|+ÿ±¢ý2ê•ÞPEPEPEP\‡äç¼aÿb¾‡ÿ¥zÅw•ÁøwþN{Æö+èúW¬PyEPEPEPEPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@Q@Q@íQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K]åQEQEQEÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w•ÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$´ÞQEÁþÎ?òOuû:ðž—®is3Y´ŠúÒRŒžl2 tm¬ «‚äWÁI¿k |ø®xzòA}âOéw:uŽ"G4m\HyÛî8ã.ÃhèÅ{0ø*õë¬=(·6íoóín·Øå­‹£J·œ­^çÑÔW û;~Ñ>ý§>Zø—ÃWBX%Â\Û9{±óE"ö#±èFà×wXÖ£:Stê+In™­:©8;§³ (¢³,(¢Š(¢Šàþ/ÿÉBøWÿcDÿúeÕ+¼¯‘¿kïø(Ÿ¾~Ðþðó´ú«x[Z{ívâу&¾ÊêÐEã‘MÎöü¡6òÄ…ú«Âþ(Ó¼máÛ=[I¼·Ô4ÍB%žÚæÈGìÄeøšáZ´Œö}ÿ¯ËS–Ž6…Z’¥NIÊ;®Åú(¢¸Î ¢Š(¢Š(®ÿòsÞ0ÿ±_CÿÒ½b»Êàü;ÿ'=ãûô?ý+Ö(¼¢Š(¢Š(¢Š(¢Š(ƒýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯«¼ Š( Š( Š( ö¨ÿ“aøÿb¾§ÿ¤’×y^ ÿý£ü7ð/öqñ&Ÿ«\‡ÕüY¥]ézeŒd¦yahÌ„v7ä±úHÖþʵg†¿k_†±kÚ ¾EÜcÔ´ÙôÙˆû­ýä8%\ 0¡ £±åø•†úÛƒöwµú_úëµôÜåXÚ¿Õ¹—=¯cÓ¨¢Šã:‚Š( Š( ¸?‹ÿòP¾ÿØÑ?þ™uJï+ƒø¿ÿ% á_ýÿé—T ò¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–€;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š+ç¿Û÷áwÅÏ~Ðü-à-áö»àRI—Æúwˆå®m-%Ø7E­M$jrŒQ’;8&ÁQ`½+ã‚uˆú)ƒLñg‡¬òü‘ˆõ{h#,C㤨‰…nà+ dÇÜ„H§dk’0[©ì¤ÿÃ+ü0ÿ¢qà/ü'í?øÝw”V¬M\EYV¬ï)nÍhP§Fš¥IZ+cƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê+cƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê(ƒÿ†WøaÿDãÀ_øOÚñº?á•þÑ8ðþöŸün»Ê(óóö¹ÿ‚Mé:ßíá;¿ÞÚxoBñ¾ªöWö>Q)¦Ê¶ÓÝ<–ê8ØÑÛÈg_h+a>±ð/ìOð§À°Ñí¼á[è¬" CJ·»º¸=KÉ+¡fbI'°Î5¾/ÿÉBøWÿcDÿúeÕ+¼¯SœâñTaB¼ïmþo»éý3ƒ –a°õgZŒlå¿üÝÎþ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï(¯,ï8?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆë¼¢€8?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆë¼¢€8?øe†ôN<ÿ„ý§ÿ®+Bý›>MûExªÅüল·ðæ'k ¢hŒÍýØ×q9?xŒä{¿†®5+¯ØK¬ZXØjÒ[Æ×¶Öwmwmo1Q½#™ã‰¤@ÙÚ4,%8&ÁH?àœ ûH,Þ3ðvÿøN"DIìæº"V4Pªªdm‘:€1ªÜ瓺½lžŽxÈÓÇJÐëÛæú/5ÿy™\Lp²ž^×N¯Ëþú?àOÇo þÑ¿ ì¼Qá{Ñw§Ý®…šÎPèe\®¹ ‚T‚{ù»öGÿ‚qø{öuøj–—úŸˆ.¼K¨í›U»Òõûý2p>X‘-åŒ2&XpX–cÀ!WÕáœ|=ÿAÿáq­ò]ræÃÃ8ádåôo·õ÷öGFU¥B2Ä+NÚ¤w”Wÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉuÆtåÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w”Wÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtâßµïíãà/ƒ?¾hä×7´ú†±%ªù«¥Ç%…ݪ‡’Û®•ÊŒˆN2T¦ô]jÏÄšE®¡§ÝA{c{Ïoq‰#š6VVA_þÔðG+¿|nÓußý—úýÑ:Çö…ÓÜM¤œy•¤c$áÈÀRÅ·°ÉÚK/Õ¿ ¿bÿü,ðF éW^5‚ÏNˆ"ˆ|]ªÛ,՟ˆá#RÌKŠ£$à ú Ó–C Fx9¹TkÞ_çÙßDµº×ÍøÙ}l|ñc‰‚P_üë­ûéä½fŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.¾|öNòŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.€;Ê+ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï+ƒðïüœ÷Œ?ìWÐÿô¯X£þÇÃßôñïþ×ÿ%×5¥þËVü`×oå¹ñ¢é:6om:øÓVI=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w”Wÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÞQ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÐyEpðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—@ìãÿ$÷Qÿ±£Ä_úz¾®ò¼{áGìµa¢ø^êVçÆ–×O¬ê—xÓVLj@äGtsBñ³ób_.X×Kÿ ãáïúø÷ÿ kÿ’è¼¢¸?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.€;Ê+ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?jù6ˆÿö+êúI-w•ãß¿e« àÿŠì4{Ÿ]ê÷º5彌4Õ¤†iÞXÑÖ[£)b Nî3]/ü3‡¿è#ãßü.5¯þK òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.€;Ê+ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï(®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’è¼®âÿü”/…ö4Oÿ¦]RøgÐGÇ¿ø\k_ü—Y:Ÿìý‡ñÀº¶/‰n×HÖfžûûGÄ×ú„PÀÚmì!ÄW3ºîóe‰r«¸<íÝ@¥\íQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K@åQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQEQ_<ÁGüñá/Âx›Á>.µð͵—‹(е)õÄZU¶§a4>L·ÐMÉÌ›c:°b»ãhéD=è¹.ŽÏç{|»ÙÛgb~ëŠi6¾V¿ÏU÷®çEEPEPEPEð׉ÿlŸËûox–=m~2øWáW¼q¤x ß ØxfçÚ•Õä.‡U7~n°¾mΡ ¸6QGhcf“-#FA9Õ(îÿÍGÿJ”W{µ K݃¨ö_ŽÙ|“#îZàÿjù6ˆÿö+êúI-w•ÁþÕòl?ÿìWÔÿô’Zï(¢Šàÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuûSý¾ÿàŽ“þÛ¿´¿ÄŸ]ŸÅs©|1±ð÷uk‘!Õü)â;=Bæö øä“AžÏ…ÙDŠP©ù¹{þ UñÃâEÇ‹´_|)›Mø·ã_ |@ñ_‰­µ[æÕô Í. ´Xéö¯e²â&šÄˆ'’æw/˜I\9†÷”cWFÞ¾Ž£áÏåk]º‰@Äû²nžªß³Œ¿ô¶ã¦÷½’ƒrûÇÃÿ´ŸÃ¯M¡Ç¥xûÁZœž&7Ë£­¦¹k3jÆÅŠÞ‹p®|ß³°"]™òˆ!¶Ö÷€þ h?üaâ kzGˆô V/:ËSÒï#¼³¼$oŽXË#®ARGù¯ñgþ½ñy~ |Añ€üÓ?g^ ðqi^ Ñm4[Uv¯—o D=öçñ¢½GÚOI{ºz¦ßÝî¯[ö ÞínHk{_F­÷§‘×ÑEQEQEQEQEQEQEQEQEQEWûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’ÐyEPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@pµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEpr~Íþ7—sC7‹l~Ûu5ì±Yx·U´ƒÍšF–VX¢¹TMÒ;1  eÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK¢Š?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.Š(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’袀øgÐGÇ¿ø\k_ü—UõOÙwºæ›qe{qãKÛ+Èš ‹yüi¬Ëñ°*Èê×D2H ŒH4Q@‰EPÿÙColPack-1.0.10/Graphs/mymatrix1.mtx000066400000000000000000000003031266356121500170210ustar00rootroot00000000000000%%MatrixMarket matrix coordinate real general 6 6 14 1 1 1.0 1 2 5.0 2 1 5.0 2 2 3.5985 2 5 -0.0536 3 3 1.8 3 5 6.0 4 4 -0.1835 5 2 -0.0536 5 3 6.0 5 5 -1.2988 5 6 -1.7023 6 5 -1.7023 6 6 5.9311 ColPack-1.0.10/Graphs/row-compress.jpg000066400000000000000000000553251266356121500175140ustar00rootroot00000000000000ÿØÿàJFIFxxÿÛC      ÿÛC  ÿÀs±"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ý›ø[ð¶ÇâV‡ªêú¾«ãIoeñ·nM¿‹u[H’8u[¨bEŠ„cQ÷}rk¥ÿ†qð÷ý|{ÿ…ƵÿÉt~Î?òOuû=ÿÂãZÿäºï( þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’뼯(ý¶?hÍcöOýšüUãýÁ7^;›ÂÚmÞ«qc©› 6öÖÒÜÉ,ÓI¹•6ðy1M!y#ýÞÍò$ÊJ*ìºtåRJÕ³oþÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë€øÕûWøÓDñg†|+ðÏáÞ“ã랟ÅwVú׉Ÿ@Ó´ûŒQ„IgtÒ\É4ʱÇäªIYäj‡ôÙ×ãv—ûJüðwÄ«m+Æz=®³k Ê…šž%#€HÜ»°pHÈà‘ÍiÈìßggëy/ž±’Óªf1œd“]Uþôš¿k¦šNͧtVÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿ亳¬þÑ¿|9«\Øj<ðe…õœ†+‹{nÚ)`ppU•œ ö"«ÃT|0ÿ¢à/ü(-?øåIaÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÃT|0ÿ¢à/ü(-?øåðÕ ?è£ø ÿ Oþ9@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%×þØðRÿ|øvÏá]kBñ‡Šuhì-¬/cº‚Ø÷švŽÕ\ð¹ ç–°÷ü÷ül|w«è¾ñn•ûD·—1ÚZjiÀócg!Uún=ò¼d/¨²l[Á¼r‡îï¿ënÝ.yï4Ã,WÕ½ÿëO_#Ýáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ+Ë=ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’èÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür€øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK£þ£á‡ýáAiÿÇ(ÿ†¨øaÿEÀ_øPZñÊ?áœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.øj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ(ÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäº?áª>ÑGðþŸürøj†ôQüÿ…§ÿ þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’ë•øÏû||.ø=ðöû\/ðïˆ.-×m¾¥j]\ÝÊAÚQ˜¨ã–#zœá_°¯üoþĉü'ã¸,´­GY¼?ØWêVÞ~KGÏñô ßÅÐóŒú˜l›ˆÃOJ„wýmÞÝO>¾i†£^8j’´¥ýkÚý§ÿáœ|=ÿAÿáq­ò]r¾ é¾øãMsKÕüwm©èÚõõœÇƚĢ)¢·wFÚ÷%[  á ŠöŠàÿjù6ˆÿö+êúI-yg w”QEp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEW”þÛj޵rÖÞÔ—~“§Ý!3I6á™âÉù" F0ä‚1‚OÐG%¦ò·˜{eÍ{rþž½{XñžiQf ìÝ­{þ¾=O·è¢ŠùóÙ àÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuûú%žÞâѰʲ°à‚ZøÏþ +à?‰'øec} ÜµÏ4Õó5:ÕœH•žBï!QŽ,sVø#w€þ$øWá-åçˆî¿µ &дۨØÜ†-–ž2Oîàaœ)y;ÆÑ“'Ð<–Ÿö_ö‡µ\×·/éë×µûRÚRönÖ½ÿ_Nž§ÚQE|ùì…p³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw•ÁþÕòl?ÿìWÔÿô’Zï+ƒýª?äØ~#ÿد©ÿé$´ÞQEÁþÎ?òOuû3ð¥½Î‹âyÛQŠ]^ÝÀdjQfU/˜Ç˜èŸ6>gQÔ]gü5GÃú(þÿ‚ÓÿŽQñþJ¿û'ÿÓ.©]å!œü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã•ÞQ@8þÖ?ðRüøo%߇µÍÆ>%½ c§_Çu>?ÖÎѱÙäqÎxù™s¿cø)§ƒ~=|?ð—k:ƒüU§(KØ/¯#´·»ÿ¦°4Œºd•>£ú7í{û!xsö½ørúF®‹i«Z“JÕc@f°”üz6ÀÜ™Á‚±ìC ~Ç~1BbÔüU©F?µ5R˜/ßÉ‹<¬J{ub7á ô1žUý”âÓúÅÿ¯.[|ïäxÒŽaý škØÛúó½þV;Oøj†ôQüÿ…§ÿ£þ£á‡ýáAiÿÇ+¼¢¾xöNþ£á‡ýáAiÿÇ+ŠøûIü:Ѽ  ç¼k+ø]RmrÖ6häÕï$À/÷YYOB¬àŠ÷àÿgù'ºý"ÿÓÕõðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽWyEpðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽWyEpðÕ ?è£ø ÿ Oþ9Gü5GÃú(þÿ‚ÓÿŽWyEpðÕ ?è£ø ÿ Oþ9\WÅ?ÚOá֣㟆Ó[øûÁSÅaâ9§¹xõËV[xΑ©FÈ•wÈ‹“ÆçQÔŠ÷àþ/ÿÉBøWÿcDÿúeÕ(ÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür»Ê(ƒÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür»Ê(ƒÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür»Ê(ƒÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür»Ê(þ~Ò´o_ÃyãïZÊþ#×gT›\µš95{É#p ýÖFVSЫ8"»_øj†ôQüÿ…§ÿ£öqÿ’{¨ÿØÑâ/ý=_Wy@ü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã•ÞQ@ü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã•ÞQ@ü5GÃú(þÿ‚ÓÿŽQÿ QðÃþŠ?€¿ð ´ÿã•ÞQ@ þÜ¿ðT_øâƒ,|4ÿÏáMXjÚ…Ü7!ìZÖâÙ­£‘2Ìw.KŒª0Q†;‚ý!ð×öåøSñ7Á:~·Ž|1¥­ôaÚÏSÕ-í.í[ø£’7pCÇpz‚AøÏíçÿõðÇÇ‹^Õ¬¥ÿ„WñFµý™«M`¥Ô)gstÒíÿžÛmŠÐïé_Nü(øO üð‡†ü7a¥iɶ8×–süNíÕ$žµô„ò·€¢°©û_µÆÿ=­ÓsÆÁG0Xº׳û?ð?[õØÆÿ†¨øaÿEÀ_øPZñÊ?áª>ÑGðþŸür»Ê+çÏdàÿáª>ÑGðþŸürøj†ôQüÿ…§ÿ®òŠàÿáª>ÑGðþŸürøj†ôQüÿ…§ÿ®òŠàÿáª>ÑGðþŸür«þËš­®»ðªâúÆæÞòÊóÄzüö÷H$ŠxÛY½etaÊApA¯D®öqÿ’{¨ÿØÑâ/ý=_Py\íQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K@åQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQEQEpÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©]åQET:Ž£o¤ióÝÝÏ ­­¬m4ÓLá#‰e™˜ð’O f‹­YøHµÔ4û«{ëØ–{{ˆ$E*Ӊƈuí“möÑcç¯ÚL¶y¾^wlÝòîÆ3Å_¦âÖâM=‚Š(¤3ƒø¿ÿ% á_ýÿé—T®ò¸?‹ÿòP¾ÿØÑ?þ™uJï(¢Š(¢Š(¢Š(®öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾ ò¸?Ú£þM‡â?ýŠúŸþ’K]åpµGü›Äûõ?ý$–€;Ê(¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š(¢Š(¢Šàþ/ÿÉBøWÿcDÿúeÕ+¼®âÿü”/…ö4Oÿ¦]R»Ê(¢ŠøÓþ ¥üK¿ø7jþ}Þ‡æñ6ŠÂé˜6Q¤#­¸ãѹl»qà‹V_àø{©I«6߆ϸèéxÏ7þsoéÞÝž ýÞ|Êû†êÖ+ëi!š8æ†e)$n¡•ÔŒAà‚;S4Í2ÛDÓmìì­à´³´a‚cÇ (¢¨áT€}Ïm•¼»Ù­ïÍýué~Ú3Ê/Xîwµ­ýtòï©=Q_>{!\ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}@åQ@Q@Q@pÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©@åQ@Q@Q@Q@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åOÄ+¨6|4¦³MPÛÉö6»VhÛNà R¦ìg8Î*åÓ³¸šº±øÏ}¡üt_Û FͬŸ‹gPóe#cïþ¯ì¾_oõ~_mâ¿b¼0º’øoOËY>®-£Íf[™ö0Ææ »;wsŒfžt® SìVŸÚBj.ü•óÄ%·y{ñ»fàÜã#5n½ìï<þÐT—³PäVÓúÑv]#*Ê~¤ê>w.g}­û¾¡EW€{ñþJ¿û'ÿÓ.©]åpÿä¡|+ÿ±¢ý2ê•ÞPEPEPEP\ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}@åpµGü›Äûõ?ý$–»Êàÿjù6ˆÿö+êúI-w”QEp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQ_.þÔðRÍàgíC¤|"ÒïþEâë» MNî?üDO#Åwq%½´6+öK©/®á˜˜•Tó&eQ_QQz<ëkµó[„´—#ÞÉýú¯Ààþ/ÿÉBøWÿcDÿúeÕ+¼®âÿü”/…ö4Oÿ¦]R»Ê(¢Š(¯ý²ÿl¿~Èšþý£¾×ï•—JÒ•ñ%Ëãnëž­øk#öýºôOÛÁ%[é^3ÒâTÒÕŽÖ> ’ZHã$¡![9VoAeX§…xÕìïkÿ]:_kèq¼Ã±Ur\ö½¿®¾G½ÑEç\ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}@åQ@Q@Q@pÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©@åQ@Q@Q@W1ñ‡ã‡þ|?¿ñ7‰¯ã°Òì,Ç—™ÏÝŽ5þ'n€©À‹§NS’„ÛÙ9Ær“²FWìãÿ$÷Qÿ±£Ä_úz¾®ò¾0ÿ‚{ÿÁG|;ñ[Åš¿‚u{xü?}©ëz†¥ ¼²å/RîòkŸ³»ÊÓ¸Àq€`}Ÿ]Xü¿ƒ«ìq1å{œøþ&Š]{k·]ÛÝmæ:‹–„ª­×O“{ü­³ÜýÚ¢Š)ù›ö¶ý€µŸÚ7Æ/—EñÎá üTðͯƒüw§^ø\j×ZŽŸ·,­aqö˜–ÎäÅ{s’hnf&XÕ£;þ–µ·[KhâLì‰B.}Å>Šiµ^Ÿ×ô»t {ÒæÖ‰~6WïmOøÛðÀÚŸÄÿ‡×7> ð¥Åεây×Q–]"ÝÞüdjRâV)™˜ˆÿ6~dSÔ]gü2¿Ãú'ÿÂ~ÓÿÑñþJ¿û'ÿÓ.©]å 8?øe†ôN<ÿ„ý§ÿ£þ_á‡ýá?iÿÆë¼¢€>zý¨àœ?~<ü7ŸOѼ? xC_·]?QÓtè­@“rañžùÉ^£¸9ß²üGÁ¾$'Ñtx¢ü,š…åýŒwP@ØÿUn²©Ú‹Ÿ½€Îy8UúZŠôVkŠXO©)¿g{Ûôôëm®q<»ñZq\û_úëæpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEyÇiÁÿÃ+ü0ÿ¢qà/ü'í?øÝq_¿fχZϯæ¼ð‚®¥Oë°+Í¡ÚÈËz½äq %>ꢪ¨è@^ã\ìãÿ$÷Qÿ±£Ä_úz¾ þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( þ_á‡ýá?iÿÆëŠø§û6|:Ó¼sðÚø*¯üG4)‡j«qÒ5)8 ó.øÑ°xÜŠz^ã\Åÿù(_ ÿìhŸÿLº¥ðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEpðÊÿ ?èœx ÿ ûOþ7Y;ý‰¾|@ðþsà YEí:~•oiun{4ƒãÝ͵[örµñ¡«Èº¬b=ž$žÞK‹i®eÜ žj‹yK´{#×ô_~&ý¨?l«Ÿø*,^ðç‰jK¿‡çâ„viú‡ìå£XxF=j@\ñ¹yžÝmùw&%y@Sò³ <™…'Õéä¯8;ß^Ýc%k¶´CĸÔ]OÏHϧϤ¢ïd·gì%QHAEPñþJ¿û'ÿÓ.©]åpÿä¡|+ÿ±¢ý2ê•ÞPEP'-`yetŽ(Ô³»*É$ž‚™§êjÖ]ZÏ Í­Ìk,3Dáã•eYXpAGøïþ â?‰Z'Á»X¼5—à{¬Çâ »Fct„¶9, À, Ë|­€@|_ø"æµñ*ÿáî¥o«Çæü8·ÈÑç»f­Æÿ-ÿ½ÞÝžýÞwŠ÷ÖDÞXó/h··/_ø~¶í©ã¼Ý,Ôy׿õÓϹ÷%Q^ìp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQEÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w”QEÕÔV6ÒM4‘à *^I‚ª($“Àw©+âÏø,·ˆ¾%èß ¬âðô>_€n‡—¯]Ú;•¶9F>[vù~`H,v¶>]Ýù^ã1PÃ)(ó=ßõ¿eÕœxüZÂáå]Å»t_ÖÝÙöuô:”76ÓEqop‹,RÄáÒTaÊGAu©kâOø#»ñ+Tøe¹™ðòÜÑ.nÙ…ÇœçH>hÍ’Nð¹ùñöÝ<Óõ,TðÜÊ\½Wõ£îº0ËñŸZÃÆ¿+Wèÿ­»Q^yØp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQEÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w”QEQEQEWû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Py\íQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K@åQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åq´wìçàßÚ×িðïâÿ ƒ¼O ÛêzÚç´ûJ,‹"6IWŠr¬™¯ÆŸ…Ÿ²‡ì³ð?öðÑuŸ þÚ֕ð·Á­| ¦üZÿ…µ}<–ž&‚ö;xIÐä¼i^ÔvG½‹)OÞ#1×ìßí¨ø»GýŸ|swà {{¿Zø~þ_Á:ŠmEmä6ÈÀ ™B Í~/xKâGì³ûWþ×_üUð¿Âºÿˆ¿n8¹¹ðg…..u¯κŒ²éî÷ãû#R—±LÈ<ÄGù³ó"ž ë?á•þÑ8ðþöŸünŽòŠàÿá•þÑ8ðþöŸünøe†ôN<ÿ„ý§ÿ  oÚãö¸ðßì‰ðÝõeÅÖ¥t=/KÀŸP”ƒû±®Ag# êJ©Êý‹?m_þØ^ûU§—§x“O@5M)Ÿ- éæGžZ&=Px=‰åÿkø&§~>ü8{o 蚃|O`]:÷O±ŽÖ)[ê®5ãlpY#?2¶oìcÿÈð‡À k>¿šóÀ> º•eß6‘OP+µÿ†WøaÿDãÀ_øOÚñºï(®þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï(®þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï(®þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï+ƒýœäžê?ö4x‹ÿOWÔÃ+ü0ÿ¢qà/ü'í?øÝWý—4«] áUŵ½•Ÿˆõø-íàŒG®³zªˆ£T`@‰\íQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K@åQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQEQEpÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©]åQEPHPI ÔÓa™.!I#u’7•”ä0=>”ê(¢€ àÿgù'ºý"ÿÓÕõw•ÁþÎ?òOuû«¡oÂ7z–¡á]6}fÎ ?VšÖ7½µ†o:;iŠ‚è¯¸+dgâ´h¢¼;»ì{ YX+ƒø¿ÿ% á_ýÿé—T®ò¸?‹ÿòP¾ÿØÑ?þ™uJC;Ê(¢€ (¢€ (¢€ (¢€8?ÙÇþIî£ÿcGˆ¿ôõ}]åp³ü“ÝGþÆéêú»Ê(¢Š(¢Š(¢Šàþ/ÿÉBøWÿcDÿúeÕ+¼®âÿü”/…ö4Oÿ¦]R»Ê(¢Š(¢Š(¢Š+ƒýœäžê?ö4x‹ÿOWÕÞWû8ÿÉ=Ôìhñþž¯¨¼®ö¨ÿ“aøÿb¾§ÿ¤’×y\íQÿ&ÃñþÅ}OÿI% òŠ( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ (¢€ (¢€ +ÆÿiOÛ*ÓöaÖí¯à?ˆZdžÀ´m_ÄúU¥›i>K«¡kNf¹ŠyŽþ],á¸xÓk:¨tÝì”-Uÿ¯ëóèGcƒø¿ÿ% á_ýÿé—T®ò¸?‹ÿòP¾ÿØÑ?þ™uJï(¢Š(¢¼Ûö¤ý©<5û'ü5›Ä ›ÌžMÑéÚtnÆ¥0q=dr0 ÷%Tçþȵ÷†ÿk߇K«é ,õ[@©ªiRHk ü7FØ;\ @ìX CÃýo‘û;Úý/ýuÚúÏAVú¿2çµìzÍQ\gHWû8ÿÉ=Ôìhñþž¯«¨ñ¯tŸ‡>¿×5Ëû}3IÓ"3ÜÜÎÛR%©$à2I I¾gý€o/|lÖüAàØLºVª5ÍWSÒRí‚ZÖæö{ W²Ê‚\4y' ¸7m룀ÄU¥:ôàÜa»íý~Nj¸Ê4êFŒä”¥²î}YEW!ÒQEQEÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w”QEQEQEQEp³ü“ÝGþÆéêú»Êàÿgù'ºý"ÿÓÕõw”QEQEQEÁü_ÿ’…ð¯þƉÿô˪Wy\Åÿù(_ ÿìhŸÿLº¥w”QEQEQEWû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Py\íQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K@åQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQE|Õû`|,øÑñ_ãW„cðÿ†~x¯á>€ÖúÅÞ‘®øÆûB¼Ôuˆg2@óˆt»Øæµ·+ÉèËNˆÌvƾ”\•ø9¥¢ˆû±ä]Ûù¿ød»Ù%²V²æôü?«ö»ovÏøÛðÀÚŸÄÿ‡×7> ð¥Åεây×Q–]"ÝÞüdjRâV)™˜ˆÿ6~dSÔ]gü2¿Ãú'ÿÂ~ÓÿÑñþJ¿û'ÿÓ.©]åpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yE|ÁûeÁ3|ñçáëÂ#¢è~ñVš¬ö3XYÇiowÜÃ2Æ {>2§ÔdVGì/ÿÀðçÁKÇú>âjÑ:ÞòÞ;ËM)8>R+­&@Ý'¶Õã%þ¶¢½UbÖ àÿwŸ¥ûu±ç¼¯ ñ_\q÷ÿ­}Nþ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï(¯(ô ø­û |,ø«à;ýOøoFkÄÄwÚ^—¥Õ«ºèè ð{B+åØ?þ [cmãÍ_Äþ;k-wHÐ5‹Ý3H°(Iínd·k‰Ðälßmˆçqo”ÿ õÁþÎ?òOuûꢪ¨è@]¯ü2¿Ãú'ÿÂ~ÓÿÑû8ÿÉ=Ôìhñþž¯«¼ þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( þ_á‡ýá?iÿÆèÿ†WøaÿDãÀ_øOÚñºï( ø§û6|:Ó¼sðÚø*¯üG4)‡j«qÒ5)8 ó.øÑ°xÜŠz]¯ü2¿Ãú'ÿÂ~ÓÿÑñþJ¿û'ÿÓ.©]åpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEpðÊÿ ?èœx ÿ ûOþ7Gü2¿Ãú'ÿÂ~Óÿ×yEpðÊÿ ?èœx ÿ ûOþ7UÿeÍ*×BøUqccmogegâ=~ {x#Åk¬Þª¢(ÀUW¢Wû8ÿÉ=Ôìhñþž¯¨¼®ö¨ÿ“aøÿb¾§ÿ¤’×y\íQÿ&ÃñþÅ}OÿI% òŠ( öqÿ’{¨ÿØÑâ/ý=_Wy\ìãÿ$÷Qÿ±£Ä_úz¾®ò€ (¢€ (¢€ (¢€8?‹ÿòP¾ÿØÑ?þ™uJï+ƒø¿ÿ% á_ýÿé—T®ò€ (¢€ ȯÿà¯þ ü.øGkaák í<=­†·ÕµÈ2ÁœoÌaÇWþ,íç8_ðF¿Ž¿>"xRðî»aq¨øCѬZf¹;á ~?вy•UNàG1€ðȽ‚«Ë^e̬ž×ÖÛ}÷é½!çÖ;ê<®öÞÚÃyì}»EW‚zá\ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}@åQ@Q@Q@pÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©@åQ@Q@Q@Q@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQEQEpÿä¡|+ÿ±¢ý2ê•ÞWñþJ¿û'ÿÓ.©]åQEQEQEÁþÎ?òOuû.ø¯¦ø"_Oàï¶ð¿ˆ.µÝJîÓPð®Øîmf¼´‚YRüµ­ÎVfµ $÷…d;>¬Ñ´¸´="ÖÊD6p¤‚sòª… §‚ï¿Ïwºì´·}u é%oŸm£k>ïÞ¿k/ŸñþJ¿û'ÿÓ.©]åy?Å?ÙÆ×Æ>ð¦§Þ*há×%¼ÔÌ~+ÔaKh[O½Œ4(.ˆùÒB¿¹ v»¸\ÏøgÐGÇ¿ø\k_ü—HòŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.€;Ê+ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï(®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’è¼®öqÿ’{¨ÿØÑâ/ý=_Qÿ ãáïúø÷ÿ kÿ’ëšøQû-Xh¾º‡U¹ñ¥µÓë:¥Â$4Õ£Sš…Ä9ÝÜмlÄüŘ—Ë–4ì4Wÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtÞQ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÐyEpðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—@åpÿä¡|+ÿ±¢ý2ê”Ã8ø{þ‚>=ÿÂãZÿäºæ¼uû-Xj^(ðdÖ7>4š×OÖd¸ÔOjÌÐ@tûÈá{­ÊÞt®cÃmvä.°Ñ\ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÐyEpðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—@åÁÿÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]w”Wÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉt~Î?òOuûÿ ð¸Ö¿ù.€;Ê+ƒÿ†qð÷ý|{ÿ…ƵÿÉtÃ8ø{þ‚>=ÿÂãZÿäºï(®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’è¼¢¸?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK âÿü”/…ö4Oÿ¦]R»Êñï~ËV—Š<5Ï&µÓõ™.5“Æš³4>ò0è^ër·$+˜ðÛ]ù ƒÒÿÃ8ø{þ‚>=ÿÂãZÿäºï(®þÇÃßôñïþ×ÿ%Ñÿ ãáïúø÷ÿ kÿ’è¼¢¸?øgÐGÇ¿ø\k_ü—Gü3‡¿è#ãßü.5¯þK òŠàÿáœ|=ÿAÿáq­ò]ðÎ>ÿ ð¸Ö¿ù.€;Êàÿgù'ºý"ÿÓÕõðÎ>ÿ ð¸Ö¿ù.¬|ð-ÏÇo¤Ý$ñ´Zέ<>uÓ]JðM©\Í ¼¬ÌÎ͈ĻÉ;ŽìÐi\íQÿ&ÃñþÅ}OÿI%®ò¸?Ú£þM‡â?ýŠúŸþ’K@åQ@ìãÿ$÷Qÿ±£Ä_úz¾®ò¸?ÙÇþIî£ÿcGˆ¿ôõ}]åQEQEQEWŶ·Æ¯Š6>!øñ­ø?â=ׂ´ïÙëÁVÞ'´Ñ,t­:ö/]4w’G¨µÕ¼³-³Gh ´’ÞA¾f21ìêrk^±¼–m-ݼs9xoÀšWů|:½ðî­áÍOÅcXÕ´èoõ+ífÖÕ¬a‚ï'Éû^ÜÜ\F@ÀC(‘™HëR–ój+Õ÷ò[þ îɵÓ}¿¯ëïvWgÝÔS-®c½¶ŽhdI¡™C££WR2#‚ïO¦Õ´d¦šº (¢ÂŠ( Š+Í?lÏŽìÑû&|Høƒ¤iK®jÞ ðåî¯e§¹!.ç†xш# X ò8Ï#­LåË+^ÅÓƒœ”WSÒ诙¿àŸ|Mâ-{Æñþ§ñüy£Y麽ޛãý?ÃâÚÖïí)ö ­ä–ÚåvO<³¡€nÀ!ŸéšÖpåv1„Ô•ÿ®ëïVkɦQEAaEPEPE| ÿ(ý­~(|ý¤fÓü)âoèþм=¦jÒÜøAÓµèR˨IÄþ+šæÚk«{ˆDc:q,q_K&ĉd_¾£‘e]2°È äëN+šš¨¶»_v‚“å¨é¾‰?-Uÿ½˜´QE!…Q@Q@óÇüÇÿ>ü(ð÷‰¼âë_ ÛYx³Ãö­¿ö4W—:¬WºædЬÓ3G ^MÅÀ|BÒ34E%‹cyžeûk|jø£câ߃þ#Ýx+Nýž¼mâ{MÇJÓ¯bñUÓAwy$z‹][Ë2Û4v‰ I-äæc#iÇè®âü¬”¯§KImw~†‘¥)IB·k.í»[µúëen·ÐûR¸?Ú£þM‡â?ýŠúŸþ’K]‡‡u95¯ØÞK ¶–îÞ9ž#Ö"Ê ^qÓ8®?ö¨ÿ“aøÿb¾§ÿ¤’ÕÊ.-ÅîŒ)ÍN*qÙêw”QEIgû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@Q@Q@Eñ¿öø_ûEü@ƒÄÞ-Ð5 íU-a°º[]{QÓìõ«Xf3Åm¨ZÛO…ºHÎD7qËó$pì®*„P©h¡iU·ùï÷ƒÖ\ÏòÑQ@Q@Q@¿þé_>ë~×a¸¸Ñ|Ec6›sZK,!ŽEY¡d–2UˆÜŒ¬3A®Göoý”|!û(xr]#Á²xÉt·† x­5Ïë>!†Ê(T¤QÛ.¡u8¶ES°ìRrÕǤQBѶºÚþvÚþ—võ kdúmå{_ï²ûQEQEQEVĆ:ÅÏC¤ø†ÇûCOƒQ±ÕR/:H¶ÜÙ]Åym&äe?$ðDûsµ¶áRAÞ¢…£Mt׿µOäÁ0¢Š(¢Š(¢Š(¬ßø?Jø…áS@×4û][EÖí%°¿²ºŒI弨RHO ¬¬A¨&´¨¥(©+=ŠŒœZ”]š<ãö{ý“|û/C«Â#c¬ý¯]hMþ£­ø‡Qñ¥t¦Èbk½Byî<˜”¶ÈDžZ$* »èôQW)9;ÉÜÎ1QVаQE%Q@Q@1ñÏþ ùð«öŽñ½ßˆcîöº(»¬tÖÿ;Zþ¶Òý´î¬û[å{ÛÒé?]DU ;W ûTɰüGÿ±_SÿÒIk¼®ö¨ÿ“aøÿb¾§ÿ¤’ÐyEPû8ÿÉ=Ôìhñþž¯«¼®öqÿ’{¨ÿØÑâ/ý=_Wy@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@9û`þÙº_ìyiàe»ð—Œ|m«|Eñ$^Ñ4¯ s=ìO:î{Û«h6[¿ÌÒŽqÇ9çÂïø*/Á¯ü “ˆ¯ü%uŽõ?H’ÓV²šH®,Ì¿h{id&``šEeä7?à£?°¡ýº¯¾ XÞéþÖ¼+à_ˆþ'ñ&“â8>ÑmªØGewB°˜¤ŽW/ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—EÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]Pÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtQ@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÑEðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—EÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]Pÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtQ@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÑEðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—EÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]Pÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtQ@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÑEðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—EÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]Pÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtQ@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÑEðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—EÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]Pÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtQ@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÑEðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—EÃ8ø{þ‚>=ÿÂãZÿäº?áœ|=ÿAÿáq­ò]Pÿ ãáïúø÷ÿ kÿ’èÿ†qð÷ý|{ÿ…ƵÿÉtQ@ü3‡¿è#ãßü.5¯þK£þÇÃßôñïþ×ÿ%ÑEðÎ>ÿ ð¸Ö¿ù.øgÐGÇ¿ø\k_ü—EÃ8ø{þ‚>=ÿÂãZÿ亯ª~˾×4Û‹+Û^Ù^DÐ\[ÏãMfX§VGVº!”‚A`‚A¢ŠôJ(¢€?ÿÙColPack-1.0.10/Graphs/row-compress.mtx000066400000000000000000000007111266356121500175310ustar00rootroot00000000000000%%MatrixMarket matrix coordinate real general 10 10 19 1 1 .666666666666667 1 2 -6.310289677458059e-7 1 3 .283314888590275 1 4 .27224066696528 1 5 .666666666666667 1 6 .27224066696528 1 7 .666666666666667 1 8 .27224066696528 1 9 .666666666666667 1 10 .27224066696528 2 2 .27224066696528 3 3 .577703998805546 4 4 .283314888590275 5 5 .283314888590275 6 6 .283314888590275 7 7 .283314888590275 8 8 .283314888590275 9 9 .283314888590275 10 10 .283314888590275 ColPack-1.0.10/Main/000077500000000000000000000000001266356121500140005ustar00rootroot00000000000000ColPack-1.0.10/Main/ColPackHeaders.h000066400000000000000000000050761266356121500167710ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ /************************************************************************************/ /* */ /* Headers.h (Header of header files) */ /* */ /************************************************************************************/ #ifndef HEADER_H #define HEADER_H #include "Definitions.h" #ifdef SYSTEM_TIME #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //for pair #ifdef _OPENMP #include #endif #include "Pause.h" #include "File.h" #include "Timer.h" #include "MatrixDeallocation.h" #include "mmio.h" #include "current_time.h" #include "CoutLock.h" #include "StringTokenizer.h" #include "DisjointSets.h" #include "GraphCore.h" #include "GraphInputOutput.h" #include "GraphOrdering.h" #include "GraphColoring.h" #include "GraphColoringInterface.h" #include "BipartiteGraphCore.h" #include "BipartiteGraphInputOutput.h" #include "BipartiteGraphVertexCover.h" #include "BipartiteGraphPartialOrdering.h" #include "BipartiteGraphOrdering.h" #include "BipartiteGraphBicoloring.h" #include "BipartiteGraphPartialColoring.h" #include "BipartiteGraphBicoloringInterface.h" #include "BipartiteGraphPartialColoringInterface.h" #include "RecoveryCore.h" #include "HessianRecovery.h" #include "JacobianRecovery1D.h" #include "JacobianRecovery2D.h" #include "extra.h" #endif ColPack-1.0.10/Main/Definitions.h000066400000000000000000000110311266356121500164200ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ /******************************************************************************/ /* */ /*DEBUG and ERROR Counter Ranges: (OBSOLETE) */ /* */ /*GraphCore 1100:1199 */ /*GraphInputOutput 1200:1299 */ /*GraphOrdering 1300:1399 */ /*GraphColoring 1400:1499 */ /*GraphColoringInterface 1500:1699 */ /* */ /*BipartiteGraphCore 2100:2199;3100:3199 */ /*BipartiteGraphInputOutput 2200:2299;3200:3299 */ /*BipartiteGraphPartialOrdering 2300:2399 */ /*BipartiteGraphPartialColoring 2400:2499 */ /*BipartiteGraphPartialColoringInterface 2500:2699 */ /* */ /*BipartiteGraphCovering 3300:3399 */ /*BipartiteGraphOrdering 3400:3499 */ /*BipartiteGraphBicoloring 3500:3599 */ /*BipartiteGraphBicoloringInterface 3600:3799 */ /* */ /*StringTokenizer 4100:4199 */ /*DisjointSets 4200:4299 */ /*Timer 4300:4399 */ /* */ /*HessianMatrix 5100:5199 */ /******************************************************************************/ #ifndef DEFINITION_H #define DEFINITION_H #if defined (_WIN32) || defined (__WIN32) || defined (__WIN32__) || defined (WIN32) //Windows OS Predefined Macros #define ____WINDOWS_OS____ #endif #define STEP_DOWN(INPUT) ((INPUT) - 1) #define STEP_UP(INPUT) ((INPUT) + 1) #define _INVALID -2 #define _UNKNOWN -1 #define _FALSE 0 #define _TRUE 1 #define _OFF 0 #define _ON 1 #define DISJOINT_SETS _TRUE #define STATISTICS _TRUE #ifndef ____WINDOWS_OS____ /// UNIX only. Used to measure longer execution time. /** Define SYSTEM_TIME to measure the execution time of a program which may run for more than 30 minutes (35.79 minutes or 2,147 seconds to be accurate) Reason: In UNIX, CLOCKS_PER_SEC is defined to be 1,000,000 (In Windows, CLOCKS_PER_SEC == 1,000). The # of clock-ticks is measured by using variables of type int => max value is 2,147,483,648. Time in seconds = # of clock-ticks / CLOCKS_PER_SEC => max Time in seconds = 2,147,483,648 / 1,000,000 ~= 2,147 */ #define SYSTEM_TIME #else #undef SYSTEM_TIME #endif //define system-dependent directory separator #ifndef ____WINDOWS_OS____ #define DIR_SEPARATOR "/" #else #define DIR_SEPARATOR "\\" #endif //#define DEBUG _UNKNOWN //#define DEBUG 5103 // definition for variadic Graph...Interface() #define SRC_WAIT -1 #define SRC_FILE 0 #define SRC_MEM_ADOLC 1 #define SRC_MEM_ADIC 2 #define SRC_MEM_SSF 3 #define SRC_MEM_CSR 4 enum boolean {FALSE=0, TRUE}; //enum _INPUT_FORMAT {MATRIX_MARKET, METIS, HARWELL_BOEING}; //enum _VERTEX_ORDER {NATURAL, LARGEST_FIRST, DYNAMIC_LARGEST_FIRST, DISTANCE_TWO_LARGEST_FIRST, SMALLEST_LAST, DISTANCE_TWO_SMALLEST_LAST, INCIDENCE_DEGREE, DISTANCE_TWO_INCIDENCE_DEGREE}; //enum _COLORING_STYLE {DISTANCE_ONE, DISTANCE_TWO, NAIVE_STAR, RESTRICTED_STAR, STAR, ACYCLIC, TRIANGULAR}; //enum _BIPARTITE_VERTEX_ORDER{NATURAL, LARGEST_FIRST, SELECTIVE_LARGEST_FIRST, DYNAMIC_LARGEST_FIRST, ROW_LARGEST_FIRST, COLUMN_LARGEST_FIRST, SMALLEST_LAST, SELECTIVE_SMALLEST_LAST, ROW_SMALLEST_LAST, COLUMN_SMALLEST_LAST, INCIDENCE_DEGREE, SELECTIVE_INCIDENCE_DEGREE, ROW_INCIDENCE_DEGREE, COLUMN_INCIDENCE_DEGREE}; //enum _BIPARTITE_COLORING_STYLE{ROW_PARTIAL_DISTANCE_TWO, COLUMN_PARTIAL_DISTANCE_TWO, LEFT_STAR, RIGHT_STAR, MINIMAL_COVER_STAR, MINIMAL_COVER_MODIFIED_STAR, IMPLICIT_COVER_STAR, IMPLICT_COVER_CONSERVATIVE_STAR, IMPLICIT_COVER_RESTRICTED_STAR, IMPLICIT_COVER_GREEDY_STAR, IMPLICIT_COVER_ACYCLIC}; #endif ColPack-1.0.10/Main/Main.cpp000066400000000000000000000023251266356121500153720ustar00rootroot00000000000000/* Notes: * - This code will crash if the matrix only has patterns (no value) //*/ #include "ColPackHeaders.h" using namespace ColPack; using namespace std; #include "extra.h" //This .h file contains functions that are used in the below examples: //ReadMM(), MatrixMultiplication...(), Times2Plus1point5(), displayMatrix() and displayCompressedRowMatrix() #include "stat.h" int main(int argc, const char* argv[]) { vector Orderings; Orderings.push_back("NATURAL"); Orderings.push_back("LARGEST_FIRST"); Orderings.push_back("DYNAMIC_LARGEST_FIRST"); Orderings.push_back("SMALLEST_LAST"); Orderings.push_back("INCIDENCE_DEGREE"); Orderings.push_back("RANDOM"); vector Colorings; Colorings.push_back("EXPLICIT_COVERING__STAR_BICOLORING"); Colorings.push_back("EXPLICIT_COVERING__MODIFIED_STAR_BICOLORING"); Colorings.push_back("IMPLICIT_COVERING__STAR_BICOLORING"); Colorings.push_back("IMPLICIT_COVERING__GREEDY_STAR_BICOLORING"); map stat_flags; stat_flags["output_append"]=true; stat_flags["NumberOfColors"]=true; stat_flags["Time"]=true; toFileBiC("/home/nguyend/Desktop/Duck/Research/Prog/graph/MM_collection/", "test1", Orderings, Colorings, stat_flags ); return 0; } ColPack-1.0.10/Makefile.am000066400000000000000000000133161266356121500151540ustar00rootroot00000000000000ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 COLPACK_COMMON_FLAGS = $(EXTRA_FLAGS) -O3 AM_CPPFLAGS = $(COLPACK_COMMON_FLAGS) \ -I$(top_srcdir)/Main \ -I$(top_srcdir)/Utilities \ -I$(top_srcdir)/BipartiteGraphPartialColoring \ -I$(top_srcdir)/BipartiteGraphBicoloring \ -I$(top_srcdir)/GraphColoring \ -I$(top_srcdir)/Recovery AM_LDFLAGS = $(COLPACK_COMMON_FLAGS) if ENABLE_OPENMP AM_CXXFLAGS = -fopenmp endif LDADD = libColPack.la AM_DEFAULT_SOURCE_EXT = .cpp noinst_PROGRAMS = ColPack lib_LTLIBRARIES = libColPack.la pkginclude_HEADERS = \ Utilities/CoutLock.h Utilities/command_line_parameter_processor.h \ Utilities/File.h Utilities/DisjointSets.h \ Utilities/current_time.h Utilities/mmio.h Utilities/Pause.h \ Utilities/MatrixDeallocation.h Utilities/Timer.h \ Utilities/StringTokenizer.h Utilities/extra.h Utilities/stat.h \ BipartiteGraphPartialColoring/BipartiteGraphPartialColoringInterface.h \ BipartiteGraphPartialColoring/BipartiteGraphPartialOrdering.h \ BipartiteGraphPartialColoring/BipartiteGraphPartialColoring.h \ BipartiteGraphBicoloring/BipartiteGraphBicoloringInterface.h \ BipartiteGraphBicoloring/BipartiteGraphVertexCover.h \ BipartiteGraphBicoloring/BipartiteGraphOrdering.h \ BipartiteGraphBicoloring/BipartiteGraphInputOutput.h \ BipartiteGraphBicoloring/BipartiteGraphBicoloring.h \ BipartiteGraphBicoloring/BipartiteGraphCore.h \ GraphColoring/GraphColoringInterface.h \ GraphColoring/GraphInputOutput.h \ GraphColoring/GraphColoring.h \ GraphColoring/GraphOrdering.h \ GraphColoring/GraphCore.h \ Recovery/JacobianRecovery2D.h \ Recovery/JacobianRecovery1D.h \ Recovery/HessianRecovery.h \ Recovery/RecoveryCore.h \ Main/Definitions.h \ Main/ColPackHeaders.h libColPack_la_SOURCES = \ Utilities/CoutLock.cpp Utilities/command_line_parameter_processor.cpp \ Utilities/File.cpp Utilities/DisjointSets.cpp \ Utilities/current_time.cpp Utilities/mmio.cpp Utilities/Pause.cpp \ Utilities/MatrixDeallocation.cpp Utilities/Timer.cpp \ Utilities/StringTokenizer.cpp Utilities/extra.cpp Utilities/stat.cpp \ BipartiteGraphPartialColoring/BipartiteGraphPartialOrdering.cpp \ BipartiteGraphPartialColoring/BipartiteGraphPartialColoring.cpp \ BipartiteGraphPartialColoring/BipartiteGraphPartialColoringInterface.cpp \ BipartiteGraphBicoloring/BipartiteGraphInputOutput.cpp \ BipartiteGraphBicoloring/BipartiteGraphBicoloring.cpp \ BipartiteGraphBicoloring/BipartiteGraphVertexCover.cpp \ BipartiteGraphBicoloring/BipartiteGraphCore.cpp \ BipartiteGraphBicoloring/BipartiteGraphBicoloringInterface.cpp \ BipartiteGraphBicoloring/BipartiteGraphOrdering.cpp \ GraphColoring/GraphCore.cpp \ GraphColoring/GraphColoringInterface.cpp \ GraphColoring/GraphInputOutput.cpp \ GraphColoring/GraphOrdering.cpp \ GraphColoring/GraphColoring.cpp \ Recovery/JacobianRecovery1D.cpp \ Recovery/RecoveryCore.cpp \ Recovery/JacobianRecovery2D.cpp \ Recovery/HessianRecovery.cpp ColPack_SOURCES = \ Main/Main.cpp examplesdir = ${prefix}/examples basic_examplesdir = ${examplesdir}/Basic basic_examples_PROGRAMS = \ SampleDrivers/Basic/color_bipartite_graph_using_BipartiteGraphBicoloringInterface \ SampleDrivers/Basic/color_bipartite_graph_using_BipartiteGraphPartialColoringInterface \ SampleDrivers/Basic/color_graph_using_GraphColoringInterface \ SampleDrivers/Basic/Generate_seed_matrix_for_Hessian \ SampleDrivers/Basic/Generate_seed_matrix_for_Jacobian TESTS = ${basic_examples_PROGRAMS} if EXAMPLES ADIC_examplesdir = ${examplesdir}/Matrix_Compression_and_Recovery/ADIC ADIC_examples_PROGRAMS = \ SampleDrivers/Matrix_Compression_and_Recovery/ADIC/01_Column_compression_and_recovery_for_Jacobian_return_ADIC_Format ADOLC_examplesdir = ${examplesdir}/Matrix_Compression_and_Recovery/ADOL-C ADOLC_examples_PROGRAMS = \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/01_Column_compression_and_recovery_for_Jacobian_return_Row_Compressed_Format \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/02_Column_compression_and_recovery_for_Jacobian_return_Coordinate_Format \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/03_Column_compression_and_recovery_for_Jacobian_return_Sparse_Solvers_Format \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/04_Row_compression_and_recovery_for_Jacobian_return_Row_Compressed_Format \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/05_Compression_and_direct_recovery_for_Hessian_return_Row_Compressed_Format \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/06_Compression_and_direct_recovery_for_Hessian_return_Coordinate_Format \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/07_Compression_and_direct_recovery_for_Hessian_return_Sparse_Solvers_Format \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/08_Compression_and_indirect_recovery_for_Hessian_return_Row_Compressed_Format \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/09_Bidirectional_compression_and_recovery_for_Jacobian_return_Row_Compressed_Format \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/10_Column_compression_and_recovery_for_Jacobian_return_Row_Compressed_Format__unmanaged_usermem \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/11_Compression_and_direct_recovery_for_Hessian_return_Row_Compressed_Format__unmanaged_usermem \ SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C/12_Bidirectional_compression_and_recovery_for_Jacobian_return_Row_Compressed_Format__unmanaged_usermem CSR_examplesdir = ${examplesdir}/Matrix_Compression_and_Recovery/CSR CSR_examples_PROGRAMS = \ SampleDrivers/Matrix_Compression_and_Recovery/CSR_input/01_Column_compression_and_recovery_for_Jacobian_CSR_input_return_Row_Compressed_Format endif ColPack-1.0.10/NEWS000066400000000000000000000000001266356121500136010ustar00rootroot00000000000000ColPack-1.0.10/README.md000066400000000000000000000010301266356121500143650ustar00rootroot00000000000000[![Build Status](https://travis-ci.org/CSCsw/ColPack.svg?branch=master)](https://travis-ci.org/CSCsw/ColPack) ColPack's Doxygen documentation is available here: http://cscapes.cs.purdue.edu/coloringpage/software.htm ColPack's project home page: http://cscapes.cs.purdue.edu/coloringpage/ Ubuntu Build Instructions ========================= In the `ColPack` directory run the following: autoreconf -vif ./configure --prefix=/path/to/install/ make -j 4 #Where "4" is the number of cores on your machine make install ColPack-1.0.10/Recovery/000077500000000000000000000000001266356121500147125ustar00rootroot00000000000000ColPack-1.0.10/Recovery/HessianRecovery.cpp000066400000000000000000001741031266356121500205350ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; //#define DEBUG 5103 namespace ColPack { int HessianRecovery::DirectRecover_RowCompressedFormat_usermem(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, double*** dp3_HessianValue) { if(g==NULL) { cerr<<"g==NULL"<GetVertexCount(); int colorCount = g->GetVertexColorCount(); //cout<<"colorCount="< vi_VertexColors; g->GetVertexColors(vi_VertexColors); //Do (column-)color statistic for each row, i.e., see how many elements in that row has color 0, color 1 ... int** colorStatistic = new int*[rowCount]; //color statistic for each row. For example, colorStatistic[0] is color statistic for row 0 //If row 0 has 5 columns with color 3 => colorStatistic[0][3] = 5; //Allocate memory for colorStatistic[rowCount][colorCount] and initilize the matrix for(unsigned int i=0; i < (unsigned int)rowCount; i++) { colorStatistic[i] = new int[colorCount]; for(unsigned int j=0; j < (unsigned int)colorCount; j++) colorStatistic[i][j] = 0; } //populate colorStatistic for(unsigned int i=0; i < (unsigned int)rowCount; i++) { int numOfNonZeros = uip2_HessianSparsityPattern[i][0]; for(unsigned int j=1; j <= (unsigned int)numOfNonZeros; j++) { //non-zero in the Hessian: [i][uip2_HessianSparsityPattern[i][j]] //color of that column: vi_VertexColors[uip2_HessianSparsityPattern[i][j]] colorStatistic[i][vi_VertexColors[uip2_HessianSparsityPattern[i][j]]]++; } } //Now, go to the main part, recover the values of non-zero entries in the Hessian for(unsigned int i=0; i < (unsigned int)rowCount; i++) { unsigned int numOfNonZeros = uip2_HessianSparsityPattern[i][0]; for(unsigned int j=1; j <= numOfNonZeros; j++) { if(i == uip2_HessianSparsityPattern[i][j]) { // the non-zero is in the diagonal of the matrix (*dp3_HessianValue)[i][j] = dp2_CompressedMatrix[i][vi_VertexColors[i]]; //printf("Recover diagonal (*dp3_HessianValue)[%d][%d] = %f from dp2_CompressedMatrix[%d][%d] \n", i, j, dp2_CompressedMatrix[i][vi_VertexColors[i]], i, vi_VertexColors[i]); } else {// i != uip2_HessianSparsityPattern[i][j] // the non-zero is NOT in the diagonal of the matrix if(colorStatistic[i][vi_VertexColors[uip2_HessianSparsityPattern[i][j]]]==1) { (*dp3_HessianValue)[i][j] = dp2_CompressedMatrix[i][vi_VertexColors[uip2_HessianSparsityPattern[i][j]]]; //printf("Recover (*dp3_HessianValue)[%d][%d] = %f from dp2_CompressedMatrix[%d][%d] \n", i, j, dp2_CompressedMatrix[i][vi_VertexColors[uip2_HessianSparsityPattern[i][j]]], i, vi_VertexColors[uip2_HessianSparsityPattern[i][j]]); } else { (*dp3_HessianValue)[i][j] = dp2_CompressedMatrix[uip2_HessianSparsityPattern[i][j]][vi_VertexColors[i]]; //printf("Recover (*dp3_HessianValue)[%d][%d] = %f from dp2_CompressedMatrix[%d][%d] \n", i, j, dp2_CompressedMatrix[uip2_HessianSparsityPattern[i][j]][vi_VertexColors[i]], uip2_HessianSparsityPattern[i][j], vi_VertexColors[i]); } } } } free_2DMatrix(colorStatistic, rowCount); colorStatistic = NULL; return (rowCount); } int HessianRecovery::DirectRecover_RowCompressedFormat_unmanaged(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, double*** dp3_HessianValue) { if(g==NULL) { cerr<<"g==NULL"<GetVertexCount(); //allocate memory for *dp3_HessianValue. The dp3_HessianValue and uip2_HessianSparsityPattern matrices should have the same size *dp3_HessianValue = (double**) malloc(rowCount * sizeof(double*)); for(unsigned int i=0; i < (unsigned int)rowCount; i++) { unsigned int numOfNonZeros = uip2_HessianSparsityPattern[i][0]; (*dp3_HessianValue)[i] = (double*) malloc( (numOfNonZeros+1) * sizeof(double) ); (*dp3_HessianValue)[i][0] = numOfNonZeros; //initialize value of the 1st entry for(unsigned int j=1; j <= numOfNonZeros; j++) (*dp3_HessianValue)[i][j] = 0.; //initialize value of other entries } return DirectRecover_RowCompressedFormat_usermem(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, dp3_HessianValue); } int HessianRecovery::DirectRecover_RowCompressedFormat(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, double*** dp3_HessianValue) { int returnValue = DirectRecover_RowCompressedFormat_unmanaged(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, dp3_HessianValue); if(AF_available) reset(); AF_available = true; i_AF_rowCount = g->GetVertexCount(); dp2_AF_Value = *dp3_HessianValue; return (returnValue); } int HessianRecovery::DirectRecover_SparseSolversFormat_usermem(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_HessianValue, unsigned int numOfNonZerosInHessianValue) { if(g==NULL) { cerr<<"g==NULL"<GetVertexCount(); int colorCount = g->GetVertexColorCount(); //cout<<"colorCount="< vi_VertexColors; g->GetVertexColors(vi_VertexColors); //g->PrintGraph(); //Making the array indices to start at 0 instead of 1 for(unsigned int i=0; i <= (unsigned int) rowCount ; i++) { (*ip2_RowIndex)[i]--; } for(unsigned int i=0; i < numOfNonZerosInHessianValue; i++) { (*ip2_ColumnIndex)[i]--; } //Do (column-)color statistic for each row, i.e., see how many elements in that row has color 0, color 1 ... int** colorStatistic = new int*[rowCount]; //color statistic for each row. For example, colorStatistic[0] is color statistic for row 0 //If row 0 has 5 columns with color 3 => colorStatistic[0][3] = 5; //Allocate memory for colorStatistic[rowCount][colorCount] and initilize the matrix for(unsigned int i=0; i < (unsigned int)rowCount; i++) { colorStatistic[i] = new int[colorCount]; for(unsigned int j=0; j < (unsigned int)colorCount; j++) colorStatistic[i][j] = 0; } //populate colorStatistic for(unsigned int i=0; i < (unsigned int)rowCount; i++) { int numOfNonZeros = uip2_HessianSparsityPattern[i][0]; for(unsigned int j=1; j <= (unsigned int)numOfNonZeros; j++) { //non-zero in the Hessian: [i][uip2_HessianSparsityPattern[i][j]] //color of that column: vi_VertexColors[uip2_HessianSparsityPattern[i][j]] colorStatistic[i][vi_VertexColors[uip2_HessianSparsityPattern[i][j]]]++; } } //Now, go to the main part, recover the values of non-zero entries in the Hessian for(unsigned int i=0; i < (unsigned int)rowCount; i++) { unsigned int numOfNonZeros = uip2_HessianSparsityPattern[i][0]; unsigned int offset = 0; //printf("\ti=%d, \t NumOfNonzeros=%d,\t \n",i,numOfNonZeros); for(unsigned int j=1; j <= numOfNonZeros; j++) { if (i > uip2_HessianSparsityPattern[i][j]) { offset++; continue; } else if(i == uip2_HessianSparsityPattern[i][j]) { // the non-zero is in the diagonal of the matrix (*dp2_HessianValue)[(*ip2_RowIndex)[i] + j - offset - 1] = dp2_CompressedMatrix[i][vi_VertexColors[i]]; //printf("DIAGONAL Recover (*dp2_HessianValue)[%d] = %f from dp2_CompressedMatrix[%d][%d] \n", (*ip2_RowIndex)[i] + j - offset - 1, (*dp2_HessianValue)[(*ip2_RowIndex)[i] + j - 1],i,vi_VertexColors[i]); //printf("\t (*ip2_RowIndex)[i = %d] = %d, j = %d, offset = %d \n", i, (*ip2_RowIndex)[i], j, offset); } else {// i != uip2_HessianSparsityPattern[i][j] // the non-zero is NOT in the diagonal of the matrix if(colorStatistic[i][vi_VertexColors[uip2_HessianSparsityPattern[i][j]]]==1) { (*dp2_HessianValue)[(*ip2_RowIndex)[i] + j - offset - 1] = dp2_CompressedMatrix[i][vi_VertexColors[uip2_HessianSparsityPattern[i][j]]]; //printf("Recover (*dp2_HessianValue)[%d] = %f from dp2_CompressedMatrix[%d][%d] \n", (*ip2_RowIndex)[i] + j - offset - 1, (*dp2_HessianValue)[(*ip2_RowIndex)[i] + j - 1], i , vi_VertexColors[uip2_HessianSparsityPattern[i][j]]); } else { (*dp2_HessianValue)[(*ip2_RowIndex)[i] + j - offset - 1] = dp2_CompressedMatrix[uip2_HessianSparsityPattern[i][j]][vi_VertexColors[i]]; //printf("Recover (*dp2_HessianValue)[%d] = %f from dp2_CompressedMatrix[%d][%d] \n", (*ip2_RowIndex)[i] + j - offset - 1, (*dp2_HessianValue)[(*ip2_RowIndex)[i] + j - 1], uip2_HessianSparsityPattern[i][j], vi_VertexColors[i]); } } } } free_2DMatrix(colorStatistic, rowCount); colorStatistic = NULL; //Making the array indices to start at 1 instead of 0 to conform with the Intel MKL sparse storage scheme for the direct sparse solvers for(unsigned int i=0; i <= (unsigned int) rowCount ; i++) { (*ip2_RowIndex)[i]++; } for(unsigned int i=0; i < numOfNonZerosInHessianValue; i++) { (*ip2_ColumnIndex)[i]++; } return (rowCount); } int HessianRecovery::DirectRecover_SparseSolversFormat_unmanaged(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_HessianValue, unsigned int numOfNonZerosInHessianValue) { if(g==NULL) { cerr<<"g==NULL"<GetVertexCount(); if (numOfNonZerosInHessianValue < 1) { numOfNonZerosInHessianValue = ConvertRowCompressedFormat2SparseSolversFormat_StructureOnly(uip2_HessianSparsityPattern, rowCount, ip2_RowIndex, ip2_ColumnIndex); //Making the array indices to start at 1 instead of 0 to conform with the Intel MKL sparse storage scheme for the direct sparse solvers for(unsigned int i=0; i <= (unsigned int) rowCount ; i++) { (*ip2_RowIndex)[i]++; } for(unsigned int i=0; i < numOfNonZerosInHessianValue; i++) { (*ip2_ColumnIndex)[i]++; } } //cout<<"allocate memory for *dp2_HessianValue rowCount="< RowIndex; vector ColumnIndex; vector HessianValue; // int returnValue = DirectRecover_CoordinateFormat_vectors_OMP(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, RowIndex, ColumnIndex, HessianValue); int returnValue = DirectRecover_CoordinateFormat_vectors(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, RowIndex, ColumnIndex, HessianValue); unsigned int numOfNonZeros = RowIndex.size(); // #pragma omp parallel for default(none) schedule(static) shared(numOfNonZeros, ip2_RowIndex, ip2_ColumnIndex, dp2_HessianValue, RowIndex, ColumnIndex, HessianValue) for(int i=0; i < numOfNonZeros; i++) { (*ip2_RowIndex)[i] = RowIndex[i]; (*ip2_ColumnIndex)[i] = ColumnIndex[i]; (*dp2_HessianValue)[i] = HessianValue[i]; } return (returnValue); } /* int HessianRecovery::DirectRecover_CoordinateFormat_usermem_serial(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_HessianValue) { if(g==NULL) { cerr<<"g==NULL"< RowIndex; vector ColumnIndex; vector HessianValue; int returnValue = DirectRecover_CoordinateFormat_vectors(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, RowIndex, ColumnIndex, HessianValue); unsigned int numOfNonZeros = RowIndex.size(); for(int i=0; i < numOfNonZeros; i++) { (*ip2_RowIndex)[i] = RowIndex[i]; (*ip2_ColumnIndex)[i] = ColumnIndex[i]; (*dp2_HessianValue)[i] = HessianValue[i]; } return (returnValue); } */ /* int HessianRecovery::DirectRecover_CoordinateFormat_unmanaged_OMP(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_HessianValue) { if(g==NULL) { cerr<<"g==NULL"< RowIndex; vector ColumnIndex; vector HessianValue; int returnValue = DirectRecover_CoordinateFormat_vectors_OMP(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, RowIndex, ColumnIndex, HessianValue); unsigned int numOfNonZeros = RowIndex.size(); #pragma omp sections { #pragma omp section { (*ip2_RowIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); } #pragma omp section { (*ip2_ColumnIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); } #pragma omp section { (*dp2_HessianValue) = (double*) malloc(numOfNonZeros * sizeof(double)); //allocate memory for *dp2_HessianValue. } } #pragma omp parallel for default(none) schedule(static) shared(numOfNonZeros, ip2_RowIndex, ip2_ColumnIndex, dp2_HessianValue, RowIndex, ColumnIndex, HessianValue) for(int i=0; i < numOfNonZeros; i++) { (*ip2_RowIndex)[i] = RowIndex[i]; (*ip2_ColumnIndex)[i] = ColumnIndex[i]; (*dp2_HessianValue)[i] = HessianValue[i]; } return (returnValue); } */ int HessianRecovery::DirectRecover_CoordinateFormat_unmanaged(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_HessianValue) { if(g==NULL) { cerr<<"g==NULL"< RowIndex; vector ColumnIndex; vector HessianValue; int returnValue = DirectRecover_CoordinateFormat_vectors(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, RowIndex, ColumnIndex, HessianValue); unsigned int numOfNonZeros = RowIndex.size(); (*ip2_RowIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); (*ip2_ColumnIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); (*dp2_HessianValue) = (double*) malloc(numOfNonZeros * sizeof(double)); //allocate memory for *dp2_HessianValue. for(int i=0; i < numOfNonZeros; i++) { (*ip2_RowIndex)[i] = RowIndex[i]; (*ip2_ColumnIndex)[i] = ColumnIndex[i]; (*dp2_HessianValue)[i] = HessianValue[i]; } return (returnValue); } /* int HessianRecovery::DirectRecover_CoordinateFormat_OMP(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_HessianValue) { int numOfNonZeros = DirectRecover_CoordinateFormat_unmanaged_OMP(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, ip2_RowIndex,ip2_ColumnIndex, dp2_HessianValue); if(CF_available) reset(); CF_available = true; i_CF_rowCount = g->GetVertexCount(); ip_CF_RowIndex = *ip2_RowIndex; ip_CF_ColumnIndex = *ip2_ColumnIndex; dp_CF_Value = *dp2_HessianValue; return (numOfNonZeros); } */ int HessianRecovery::DirectRecover_CoordinateFormat(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_HessianValue) { int numOfNonZeros = DirectRecover_CoordinateFormat_unmanaged(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, ip2_RowIndex,ip2_ColumnIndex, dp2_HessianValue); if(CF_available) reset(); CF_available = true; i_CF_rowCount = g->GetVertexCount(); ip_CF_RowIndex = *ip2_RowIndex; ip_CF_ColumnIndex = *ip2_ColumnIndex; dp_CF_Value = *dp2_HessianValue; return (numOfNonZeros); } int HessianRecovery::IndirectRecover_RowCompressedFormat_usermem(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, double*** dp3_HessianValue) { if (g->GetVertexColorCount()==1){ return DirectRecover_RowCompressedFormat_usermem(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, dp3_HessianValue); } if(g==NULL) { cerr<<"g==NULL"< vi_Sets; map< int, vector > mivi_VertexSets; vector vi_Vertices; g->GetVertices(vi_Vertices); vector vi_Edges; g->GetEdges(vi_Edges); vector vi_VertexColors; g->GetVertexColors(vi_VertexColors); map< int, map< int, int> > mimi2_VertexEdgeMap; g->GetVertexEdgeMap(mimi2_VertexEdgeMap); DisjointSets ds_DisjointSets; g->GetDisjointSets(ds_DisjointSets); //populate vi_Sets & mivi_VertexSets vi_Sets.clear(); mivi_VertexSets.clear(); i_VertexCount = g->GetVertexCount(); for(i=0; i create new set { vi_Sets.push_back(i_SetID); } mivi_VertexSets[i_SetID].push_back(i); mivi_VertexSets[i_SetID].push_back(vi_Edges[j]); } } } int i_MaximumVertexDegree; int i_HighestInducedVertexDegree; int i_LeafVertex, i_ParentVertex, i_PresentVertex; int i_VertexDegree; int i_SetCount, i_SetSize; //i_SetCount = vi_Sets.size(); //i_SetSize: size (number of edges?) in a bicolored tree double d_Value; vector vi_EvaluatedDiagonals; vector vi_InducedVertexDegrees; vector vd_IncludedVertices; vector< vector > v2i_VertexAdjacency; vector< vector > v2d_NonzeroAdjacency; vector< list > vli_GroupedInducedVertexDegrees; vector< list::iterator > vlit_VertexLocations; i_MaximumVertexDegree = g->GetMaximumVertexDegree(); #if DEBUG == 5103 cout<GetVertexCount(); v2i_VertexAdjacency.clear(); v2i_VertexAdjacency.resize((unsigned) i_VertexCount); v2d_NonzeroAdjacency.clear(); v2d_NonzeroAdjacency.resize((unsigned) i_VertexCount); vi_EvaluatedDiagonals.clear(); vi_EvaluatedDiagonals.resize((unsigned) i_VertexCount, _FALSE); vi_InducedVertexDegrees.clear(); vi_InducedVertexDegrees.resize((unsigned) i_VertexCount, _FALSE); vd_IncludedVertices.clear(); vd_IncludedVertices.resize((unsigned) i_VertexCount, _UNKNOWN); i_ParentVertex = _UNKNOWN; i_SetCount = (signed) vi_Sets.size(); for(i=0; i::iterator lit_ListIterator; cout<GetVertexCount(); //allocate memory for *dp3_HessianValue. The dp3_HessianValue and uip2_HessianSparsityPattern matrices should have the same size *dp3_HessianValue = (double**) malloc(rowCount * sizeof(double*)); for(unsigned int i=0; i < (unsigned int)rowCount; i++) { unsigned int numOfNonZeros = uip2_HessianSparsityPattern[i][0]; (*dp3_HessianValue)[i] = (double*) malloc( (numOfNonZeros+1) * sizeof(double) ); (*dp3_HessianValue)[i][0] = numOfNonZeros; //initialize value of the 1st entry for(unsigned int j=1; j <= numOfNonZeros; j++) (*dp3_HessianValue)[i][j] = 0.; //initialize value of other entries } return IndirectRecover_RowCompressedFormat_usermem(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, dp3_HessianValue); } int HessianRecovery::IndirectRecover_RowCompressedFormat(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, double*** dp3_HessianValue) { int returnValue = IndirectRecover_RowCompressedFormat_unmanaged( g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, dp3_HessianValue); if(AF_available) reset(); AF_available = true; i_AF_rowCount = g->GetVertexCount(); dp2_AF_Value = *dp3_HessianValue; return (returnValue); } int HessianRecovery::IndirectRecover_SparseSolversFormat_usermem(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_HessianValue, unsigned int numOfNonZerosInHessianValue) { if (g->GetVertexColorCount()==1){ return DirectRecover_SparseSolversFormat_usermem(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_HessianValue,numOfNonZerosInHessianValue); } if(g==NULL) { cerr<<"g==NULL"<GetVertexCount(), ip2_RowIndex, ip2_ColumnIndex); int i_VertexCount = g->GetVertexCount(); //Making the array indices to start at 0 instead of 1 for(unsigned int i=0; i <= (unsigned int) i_VertexCount ; i++) { (*ip2_RowIndex)[i]--; } for(unsigned int i=0; i < numOfNonZerosInHessianValue; i++) { (*ip2_ColumnIndex)[i]--; } int i=0,j=0; int i_EdgeID, i_SetID; vector vi_Sets; map< int, vector > mivi_VertexSets; vector vi_Vertices; g->GetVertices(vi_Vertices); vector vi_Edges; g->GetEdges(vi_Edges); vector vi_VertexColors; g->GetVertexColors(vi_VertexColors); map< int, map< int, int> > mimi2_VertexEdgeMap; g->GetVertexEdgeMap(mimi2_VertexEdgeMap); DisjointSets ds_DisjointSets; g->GetDisjointSets(ds_DisjointSets); //populate vi_Sets & mivi_VertexSets vi_Sets.clear(); mivi_VertexSets.clear(); for(i=0; i create new set { vi_Sets.push_back(i_SetID); } mivi_VertexSets[i_SetID].push_back(i); mivi_VertexSets[i_SetID].push_back(vi_Edges[j]); } } } int i_MaximumVertexDegree; int i_HighestInducedVertexDegree; int i_LeafVertex, i_ParentVertex, i_PresentVertex; int i_VertexDegree; int i_SetCount, i_SetSize; double d_Value; vector vi_EvaluatedDiagonals; vector vi_InducedVertexDegrees; vector vd_IncludedVertices; vector< vector > v2i_VertexAdjacency; vector< vector > v2d_NonzeroAdjacency; vector< list > vli_GroupedInducedVertexDegrees; vector< list::iterator > vlit_VertexLocations; i_MaximumVertexDegree = g->GetMaximumVertexDegree(); #if DEBUG == 5103 cout<GetVertexCount(); v2i_VertexAdjacency.clear(); v2i_VertexAdjacency.resize((unsigned) i_VertexCount); v2d_NonzeroAdjacency.clear(); v2d_NonzeroAdjacency.resize((unsigned) i_VertexCount); vi_EvaluatedDiagonals.clear(); vi_EvaluatedDiagonals.resize((unsigned) i_VertexCount, _FALSE); vi_InducedVertexDegrees.clear(); vi_InducedVertexDegrees.resize((unsigned) i_VertexCount, _FALSE); vd_IncludedVertices.clear(); vd_IncludedVertices.resize((unsigned) i_VertexCount, _UNKNOWN); i_ParentVertex = _UNKNOWN; i_SetCount = (signed) vi_Sets.size(); for(i=0; i::iterator lit_ListIterator; cout< uip2_HessianSparsityPattern[i][j] ) { offset++; continue; } int targetColumnID = uip2_HessianSparsityPattern[i][j]; for (int k=0; kGetVertexCount(); if (numOfNonZerosInHessianValue < 1) { numOfNonZerosInHessianValue = ConvertRowCompressedFormat2SparseSolversFormat_StructureOnly(uip2_HessianSparsityPattern, rowCount, ip2_RowIndex, ip2_ColumnIndex); //Making the array indices to start at 1 instead of 0 to conform with the Intel MKL sparse storage scheme for the direct sparse solvers for(unsigned int i=0; i <= (unsigned int) rowCount ; i++) { (*ip2_RowIndex)[i]++; } for(unsigned int i=0; i < numOfNonZerosInHessianValue; i++) { (*ip2_ColumnIndex)[i]++; } } //cout<<"allocate memory for *dp2_HessianValue rowCount="<GetVertexCount() <<", " << g->GetVertexCount() <<", dp2_CompressedMatrix, " << g->GetVertexCount() <<", " << g->GetVertexColorCount() <GetVertexCount(), g->GetVertexCount() , dp2_CompressedMatrix, g->GetVertexCount(), g->GetVertexColorCount() ); #endif if (g->GetVertexColorCount()==1){ return DirectRecover_CoordinateFormat_unmanaged(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, uip2_RowIndex, uip2_ColumnIndex, dp2_HessianValue); } if(g==NULL) { cerr<<"g==NULL"< RowIndex; vector ColumnIndex; vector HessianValue; int returnValue = IndirectRecover_CoordinateFormat_vectors(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, RowIndex, ColumnIndex, HessianValue); unsigned int numOfNonZeros = returnValue; (*uip2_RowIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); (*uip2_ColumnIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); (*dp2_HessianValue) = (double*) malloc(numOfNonZeros * sizeof(double)); //allocate memory for *dp2_HessianValue. for(int i=0; i < numOfNonZeros; i++) { (*uip2_RowIndex)[i] = RowIndex[i]; (*uip2_ColumnIndex)[i] = ColumnIndex[i]; (*dp2_HessianValue)[i] = HessianValue[i]; } #ifdef _COLPACK_CHECKPOINT_ cout<<"IN 2 HessianRecovery::IndirectRecover_CoordinateFormat_unmanaged()"<GetVertexCount(), numOfNonZeros, dp3_Pattern, dp3_Values ); s_postfix = "-IndirectRecover_CoordinateFormat_vectors"; cout<<"*WriteMatrixMarket_ADOLCInput("<GetVertexCount() <<", " << g->GetVertexCount() <<", dp2_CompressedMatrix, " << g->GetVertexCount() <<", " << g->GetVertexColorCount()<<", dp3_Values" <GetVertexCount(), g->GetVertexCount() , dp2_CompressedMatrix, g->GetVertexCount(), g->GetVertexColorCount(), dp3_Values ); //Deallocate dp3_Pattern & dp3_Values freeMatrix(dp3_Pattern, g->GetVertexCount()); freeMatrix(dp3_Values, g->GetVertexCount()); #endif return (returnValue); } // !!! Note: the speed of this function could be improved by reserve the vectors size for (RowIndex, ColumnIndex, HessianValue) ahead of time int HessianRecovery::IndirectRecover_CoordinateFormat_vectors(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, vector &RowIndex, vector &ColumnIndex, vector &HessianValue) { int i=0,j=0; int i_VertexCount = _UNKNOWN; int i_EdgeID, i_SetID; vector vi_Sets; map< int, vector > mivi_VertexSets; vector vi_Vertices; g->GetVertices(vi_Vertices); vector vi_Edges; g->GetEdges(vi_Edges); vector vi_VertexColors; g->GetVertexColors(vi_VertexColors); map< int, map< int, int> > mimi2_VertexEdgeMap; g->GetVertexEdgeMap(mimi2_VertexEdgeMap); DisjointSets ds_DisjointSets; g->GetDisjointSets(ds_DisjointSets); //populate vi_Sets & mivi_VertexSets vi_Sets.clear(); mivi_VertexSets.clear(); i_VertexCount = g->GetVertexCount(); for(i=0; i create new set { vi_Sets.push_back(i_SetID); } mivi_VertexSets[i_SetID].push_back(i); mivi_VertexSets[i_SetID].push_back(vi_Edges[j]); } } } int i_MaximumVertexDegree; int i_HighestInducedVertexDegree; int i_LeafVertex, i_ParentVertex, i_PresentVertex; int i_VertexDegree; int i_SetCount, i_SetSize; double d_Value; vector vi_EvaluatedDiagonals; vector vi_InducedVertexDegrees; vector vd_IncludedVertices; vector vb_IncludedVertices; vector< vector > v2i_VertexAdjacency; vector< vector > v2d_NonzeroAdjacency; vector< list > vli_GroupedInducedVertexDegrees; vector< list::iterator > vlit_VertexLocations; i_MaximumVertexDegree = g->GetMaximumVertexDegree(); #if DEBUG == 5103 cout<GetVertexCount(); v2i_VertexAdjacency.clear(); v2i_VertexAdjacency.resize((unsigned) i_VertexCount); v2d_NonzeroAdjacency.clear(); v2d_NonzeroAdjacency.resize((unsigned) i_VertexCount); vi_EvaluatedDiagonals.clear(); vi_EvaluatedDiagonals.resize((unsigned) i_VertexCount, _FALSE); vi_InducedVertexDegrees.clear(); vi_InducedVertexDegrees.resize((unsigned) i_VertexCount, _FALSE); vd_IncludedVertices.clear(); vd_IncludedVertices.resize((unsigned) i_VertexCount, 0.); vb_IncludedVertices.clear(); vb_IncludedVertices.resize((unsigned) i_VertexCount, false); i_ParentVertex = _UNKNOWN; i_SetCount = (signed) vi_Sets.size(); for(i=0; i::iterator lit_ListIterator; cout< RowIndex; vector ColumnIndex; vector HessianValue; int returnValue = IndirectRecover_CoordinateFormat_vectors(g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, RowIndex, ColumnIndex, HessianValue); unsigned int numOfNonZeros = returnValue; for(int i=0; i < numOfNonZeros; i++) { (*ip2_RowIndex)[i] = RowIndex[i]; (*ip2_ColumnIndex)[i] = ColumnIndex[i]; (*dp2_HessianValue)[i] = HessianValue[i]; } return (returnValue); } int HessianRecovery::IndirectRecover_CoordinateFormat(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_HessianValue) { //#define DEBUG 5103 int returnValue = IndirectRecover_CoordinateFormat_unmanaged( g, dp2_CompressedMatrix, uip2_HessianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_HessianValue); if(CF_available) reset(); CF_available = true; i_CF_rowCount = returnValue; ip_CF_RowIndex = *ip2_RowIndex; ip_CF_ColumnIndex = *ip2_ColumnIndex; dp_CF_Value = *dp2_HessianValue; return (returnValue); } } ColPack-1.0.10/Recovery/HessianRecovery.h000066400000000000000000000501621266356121500202000ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #ifndef HESSIANRECOVERY_H #define HESSIANRECOVERY_H using namespace std; namespace ColPack { /** @ingroup group5 * @brief class HessianRecovery in @link group5@endlink. */ class HessianRecovery : public RecoveryCore { public: //DOCUMENTED /// A routine for recovering a Hessian from a star-coloring based compressed representation. /** Parameter: - Input: - *g: GraphColoringInterface object, providing the coloring information - dp2_CompressedMatrix: The compressed matrix that contains all computed values - uip2_HessianSparsityPattern. - Output: - dp3_HessianValue Precondition: - Star coloring routine has been called. - uip2_HessianSparsityPattern: The Hessian matrix must be stored in compressed sparse rows format - dp3_HessianValue is just a pointer pointing to a 2D matrix (no memory allocated yet). This matrix will be created (memory will be allocated) by this routine and the pointer will be assigned to dp3_HessianValue Postcondition: - dp3_HessianValue points to a 2d matrix contains the numerical values of the Hessian. Row Compressed Format is used The memory allocated for this output vector is managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. Return value: size of (*dp3_HessianValue) array About input parameters: - This routine doesn't need to take (star) coloring result m_vi_VertexColors of the Hessian as another paramenter because that information is known already (because of the 1st precondition). The cologin result can be retrieved from the first parameter "GraphColoringInterface* g" Row Compressed Format for dp3_HessianValue: - This is a 2D matrix of doubles. - The first element of each row will specify the number of non-zeros in the Hessian => Value of the first element + 1 will be the length of that row. - The value of each element after the 1st element is the value of the non-zero in the Hessian. The value of dp3_HessianValue[col][row] is the value of element [col][uip2_HessianSparsityPattern[col][row]] in the real (uncompressed) Hessian - An example of compressed sparse rows format: - Uncompressed matrix:
1 .5 0
.5 2 3
0 3 -.5
- Corresponding uip2_HessianSparsityPattern:
2 0 1
3 0 1 2
2 1 2
- Corresponding dp3_HessianValue:
2 1 .5
3 .5 2 3
2 3 -.5
Algorithm: optimized version of the algorithm in Figure 2, pg 8, "Efficient Computation of Sparse Hessians using Coloring and Automatic Differentiation" paper. The complexity of this routine is O(|E|) versus O(|E|*average distance-1 neighbour) for DirectRecover1 - Do (column-)color statistic for each row, i.e., see how many elements in that row has color 0, color 1 ... Results are stored in map* colorStatistic. colorStatistic[0] is (column-)color statistic for row 0 If row 0 has 5 columns with color 3 => colorStatistic[0][3] = 5; - Allocate memory for *dp3_HessianValue - (Main part) Recover the values of non-zero entries in the Hessian: For each row, for each entry, see how many entries in that row have the same color by checking colorStatistic[row][column-color of the entry]. If colorStatistic[#][#] == 1 => This entry has unique color (in this row). H[j,i] = B[j,color[hi]] else H[j,i] = B[i,color[hj]] Each non-zero value of the Hessian will be recovered from left to right, top to bottom Note: column-color of entry [row 5][column 3] is m_vi_VertexColors[column 3] */ int DirectRecover_RowCompressedFormat(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, double*** dp3_HessianValue); /// Same as DirectRecover_RowCompressedFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int DirectRecover_RowCompressedFormat_unmanaged(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, double*** dp3_HessianValue); /// Same as DirectRecover_RowCompressedFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). (*dp3_HessianValue) should have the same structure as uip2_HessianSparsityPattern */ int DirectRecover_RowCompressedFormat_usermem(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, double*** dp3_HessianValue); /// A routine for recovering a Hessian from a star-coloring based compressed representation. /** Precondition: - (*uip2_RowIndex), (*uip2_ColumnIndex), and (*dp2_JacobianValue) are equal to NULL, i.e. no memory has been allocated for these 3 vectors yet Return value: size of (*uip2_RowIndex) array Return by recovery routine: three vectors in "Coordinate Format" (zero-based indexing) http://www.intel.com/software/products/mkl/docs/webhelp/appendices/mkl_appA_SMSF.html#mkl_appA_SMSF_5 - unsigned int** uip2_RowIndex - unsigned int** uip2_ColumnIndex - double** dp2_JacobianValue // corresponding non-zero values NOTE: Since we are returning a symmetric matrix, only the upper triangle are stored. The memory allocated for these 3 output vectors are managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. //*/ int DirectRecover_CoordinateFormat(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); // int DirectRecover_CoordinateFormat_OMP(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); /// Same as DirectRecover_CoordinateFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int DirectRecover_CoordinateFormat_unmanaged(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); // int DirectRecover_CoordinateFormat_unmanaged_OMP(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); /// Same as DirectRecover_CoordinateFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. (OpenMP enabled) /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). */ // int DirectRecover_CoordinateFormat_usermem_serial(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); int DirectRecover_CoordinateFormat_usermem(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); //int DirectRecover_CoordinateFormat_usermem_OMP(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); /// A routine for recovering a Hessian from a star-coloring based compressed representation. /** Precondition: - (*uip2_RowIndex), (*uip2_ColumnIndex), and (*dp2_JacobianValue) are equal to NULL, i.e. no memory has been allocated for these 3 vectors yet Return value: size of (*uip2_RowIndex) array Return by recovery routine: three vectors in "Storage Formats for the Direct Sparse Solvers" (zero-based indexing) http://software.intel.com/sites/products/documentation/hpc/mkl/webhelp/appendices/mkl_appA_SMSF.html#mkl_appA_SMSF_1 - unsigned int** uip2_RowIndex - unsigned int** uip2_ColumnIndex - double** dp2_JacobianValue // corresponding non-zero values NOTE: Since we are returning a symmetric matrix, according to format, only the upper triangle are stored. The memory allocated for these 3 output vectors are managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. */ int DirectRecover_SparseSolversFormat(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); /// Same as DirectRecover_SparseSolversFormat(), except that the output is NOT managed by ColPack /** About input parameters: - numOfNonZerosInHessianValue: the size of (*uip2_ColumnIndex) and (*dp2_HessianValue) arrays. The value of numOfNonZerosInHessianValue will be calculated if not provided (i.e. <1). Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int DirectRecover_SparseSolversFormat_unmanaged(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue, unsigned int numOfNonZerosInHessianValue = 0); /// Same as DirectRecover_SparseSolversFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. /** About input parameters: - numOfNonZerosInHessianValue: the size of (*uip2_ColumnIndex) and (*dp2_HessianValue) arrays. Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). */ int DirectRecover_SparseSolversFormat_usermem(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue, unsigned int numOfNonZerosInHessianValue); /// A routine for recovering a Hessian from a acyclic-coloring based compressed representation. /** Parameter: - Input: - *g: GraphColoringInterface object, providing the coloring information - dp2_CompressedMatrix: The compressed matrix that contains all computed values - uip2_HessianSparsityPattern. - Output: - dp3_HessianValue Precondition: - Acyclic coloring routine has been called. - uip2_HessianSparsityPattern: The Hessian matrix must be stored in compressed sparse rows format - dp3_HessianValue is just a pointer pointing to a 2D matrix (no memory allocated yet). This matrix will be created (memory will be allocated) by IndirectRecover2() and the pointer will be assigned to dp3_HessianValue Postcondition: - dp3_HessianValue points to a 2d matrix contains the numerical values of the Hessian. Row Compressed Format is used The memory allocated for this output vector is managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. Return value: size of (*dp3_HessianValue) array About input parameters: - This routine doesn't need to take (acyclic) coloring result m_vi_VertexColors of the Hessian as another paramenter because that information is known already (because of the 1st precondition). Row Compressed Format for dp3_HessianValue: see DirectRecover2() Algorithm: created by Assefaw, 1st implemented by Arijit Tarafdar. This function is just a modification of Arijit's implementation */ int IndirectRecover_RowCompressedFormat(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, double*** dp3_HessianValue); /// Same as IndirectRecover_RowCompressedFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int IndirectRecover_RowCompressedFormat_unmanaged(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, double*** dp3_HessianValue); /// Same as IndirectRecover_RowCompressedFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). */ int IndirectRecover_RowCompressedFormat_usermem(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, double*** dp3_HessianValue); /// A routine for recovering a Hessian from a acyclic-coloring based compressed representation. /** Precondition: - (*uip2_RowIndex), (*uip2_ColumnIndex), and (*dp2_JacobianValue) are equal to NULL, i.e. no memory has been allocated for these 3 vectors yet Return value: size of (*uip2_RowIndex) array Return by recovery routine: three vectors in "Coordinate Format" (zero-based indexing) http://www.intel.com/software/products/mkl/docs/webhelp/appendices/mkl_appA_SMSF.html#mkl_appA_SMSF_5 - unsigned int** uip2_RowIndex - unsigned int** uip2_ColumnIndex - double** dp2_JacobianValue // corresponding non-zero values NOTE: Since we are returning a symmetric matrix, only the upper triangle are stored. The memory allocated for these 3 output vectors are managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. //*/ int IndirectRecover_CoordinateFormat(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); /// Same as IndirectRecover_CoordinateFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int IndirectRecover_CoordinateFormat_unmanaged(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); /// Same as IndirectRecover_CoordinateFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). */ int IndirectRecover_CoordinateFormat_usermem(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); /// A routine for recovering a Hessian from a acyclic-coloring based compressed representation. /** Precondition: - (*uip2_RowIndex), (*uip2_ColumnIndex), and (*dp2_JacobianValue) are equal to NULL, i.e. no memory has been allocated for these 3 vectors yet Return value: size of (*uip2_RowIndex) array Return by recovery routine: three vectors in "Storage Formats for the Direct Sparse Solvers" (zero-based indexing) http://software.intel.com/sites/products/documentation/hpc/mkl/webhelp/appendices/mkl_appA_SMSF.html#mkl_appA_SMSF_1 - unsigned int** uip2_RowIndex - unsigned int** uip2_ColumnIndex - double** dp2_JacobianValue // corresponding non-zero values NOTE: Since we are returning a symmetric matrix, according to format, only the upper triangle are stored. The memory allocated for these 3 output vectors are managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. */ int IndirectRecover_SparseSolversFormat(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue); /// Same as IndirectRecover_SparseSolversFormat(), except that the output is NOT managed by ColPack /** About input parameters: - numOfNonZerosInHessianValue: the size of (*uip2_ColumnIndex) and (*dp2_HessianValue) arrays. The value of numOfNonZerosInHessianValue will be calculated if not provided (i.e. <1). Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int IndirectRecover_SparseSolversFormat_unmanaged(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue, unsigned int numOfNonZerosInHessianValue = 0); /// Same as IndirectRecover_SparseSolversFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. /** About input parameters: - numOfNonZerosInHessianValue: the size of (*uip2_ColumnIndex) and (*dp2_HessianValue) arrays. Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). */ int IndirectRecover_SparseSolversFormat_usermem(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, unsigned int** uip2_RowIndex, unsigned int** uip2_ColumnIndex, double** dp2_HessianValue, unsigned int numOfNonZerosInHessianValue); private: int DirectRecover_CoordinateFormat_vectors(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, vector &RowIndex, vector &ColumnIndex, vector &HessianValue); // int DirectRecover_CoordinateFormat_vectors_OMP(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, vector &RowIndex, vector &ColumnIndex, vector &HessianValue); int IndirectRecover_CoordinateFormat_vectors(GraphColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_HessianSparsityPattern, vector &RowIndex, vector &ColumnIndex, vector &HessianValue); }; } #endif ColPack-1.0.10/Recovery/JacobianRecovery1D.cpp000066400000000000000000000741331266356121500210400ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { int JacobianRecovery1D::RecoverD2Row_RowCompressedFormat_unmanaged(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetRowVertexCount(); unsigned int numOfNonZeros = 0; //allocate memory for *dp3_JacobianValue. The dp3_JacobianValue and uip2_JacobianSparsityPattern matrices should have the same size *dp3_JacobianValue = (double**) malloc(rowCount * sizeof(double*)); for(unsigned int i=0; i < (unsigned int)rowCount; i++) { numOfNonZeros = uip2_JacobianSparsityPattern[i][0]; (*dp3_JacobianValue)[i] = (double*) malloc( (numOfNonZeros+1) * sizeof(double) ); (*dp3_JacobianValue)[i][0] = numOfNonZeros; //initialize value of the 1st entry for(int j=1; j <= numOfNonZeros; j++) (*dp3_JacobianValue)[i][j] = 0.; //initialize value of other entries } return RecoverD2Row_RowCompressedFormat_usermem(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, dp3_JacobianValue); } int JacobianRecovery1D::RecoverD2Row_RowCompressedFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetRowVertexCount(); vector vi_LeftVertexColors; g->GetLeftVertexColors(vi_LeftVertexColors); unsigned int numOfNonZeros = 0; //allocate memory for *dp3_JacobianValue. The dp3_JacobianValue and uip2_JacobianSparsityPattern matrices should have the same size //*dp3_JacobianValue = new double*[rowCount]; //for(unsigned int i=0; i < (unsigned int)rowCount; i++) { // numOfNonZeros = uip2_JacobianSparsityPattern[i][0]; // (*dp3_JacobianValue)[i] = new double[numOfNonZeros+1]; // (*dp3_JacobianValue)[i][0] = numOfNonZeros; //initialize value of the 1st entry // for(int j=1; j <= numOfNonZeros; j++) (*dp3_JacobianValue)[i][j] = 0.; //initialize value of other entries //} //Recover value of the Jacobian for(unsigned int i=0; i < (unsigned int)rowCount; i++) { numOfNonZeros = uip2_JacobianSparsityPattern[i][0]; for(int j=1; j <= numOfNonZeros; j++) { (*dp3_JacobianValue)[i][j] = dp2_CompressedMatrix[vi_LeftVertexColors[i]][uip2_JacobianSparsityPattern[i][j]]; } } return rowCount; } int JacobianRecovery1D::RecoverD2Row_RowCompressedFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue) { int returnValue = RecoverD2Row_RowCompressedFormat_unmanaged(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, dp3_JacobianValue); if(AF_available) reset(); AF_available = true; i_AF_rowCount = g->GetRowVertexCount(); dp2_AF_Value = *dp3_JacobianValue; return returnValue; } int JacobianRecovery1D::RecoverD2Row_SparseSolversFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetRowVertexCount(); vector vi_LeftVertexColors; g->GetLeftVertexColors(vi_LeftVertexColors); unsigned int numOfNonZeros = 0; // Populate ip2_RowIndex and ip2_ColumnIndex //numOfNonZeros = g->GetColumnIndices(ip2_ColumnIndex); numOfNonZeros = g->GetEdgeCount();// !!!! make sure that this line is equivalent to the line above //Making the array indices to start at 0 instead of 1 for(unsigned int i=0; i <= (unsigned int)rowCount; i++) { (*ip2_RowIndex)[i]--; } for(unsigned int i=0; i < numOfNonZeros; i++) { (*ip2_ColumnIndex)[i]--; } //Recover value of the Jacobian unsigned int numOfNonZerosInEachRow = 0; for(unsigned int i=0; i < (unsigned int)rowCount; i++) { numOfNonZerosInEachRow = uip2_JacobianSparsityPattern[i][0]; for(int j=1; j <= numOfNonZerosInEachRow; j++) { (*dp2_JacobianValue)[(*ip2_RowIndex)[i]+j-1] = dp2_CompressedMatrix[vi_LeftVertexColors[i]][uip2_JacobianSparsityPattern[i][j]]; } } //Making the array indices to start at 1 instead of 0 to conform with theIntel MKL sparse storage scheme for the direct sparse solvers for(unsigned int i=0; i <= (unsigned int)rowCount; i++) { (*ip2_RowIndex)[i]++; } for(unsigned int i=0; i < numOfNonZeros; i++) { (*ip2_ColumnIndex)[i]++; } return rowCount; } int JacobianRecovery1D::RecoverD2Row_SparseSolversFormat_unmanaged(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetRowVertexCount(); unsigned int numOfNonZeros = 0; // Allocate memory and populate ip2_RowIndex and ip2_ColumnIndex g->GetRowVertices(ip2_RowIndex); numOfNonZeros = g->GetColumnIndices(ip2_ColumnIndex); //Making the array indices to start at 1 instead of 0 to conform with theIntel MKL sparse storage scheme for the direct sparse solvers for(unsigned int i=0; i <= (unsigned int)rowCount; i++) { (*ip2_RowIndex)[i]++; } for(unsigned int i=0; i < numOfNonZeros; i++) { (*ip2_ColumnIndex)[i]++; } (*dp2_JacobianValue) = (double*) malloc(numOfNonZeros * sizeof(double)); //allocate memory for *dp2_JacobianValue. for(unsigned int i=0; i < numOfNonZeros; i++) (*dp2_JacobianValue)[i] = 0.; //initialize value of other entries return RecoverD2Row_SparseSolversFormat_usermem(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); } int JacobianRecovery1D::RecoverD2Row_SparseSolversFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { int returnValue = RecoverD2Row_SparseSolversFormat_unmanaged(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); if(SSF_available) reset(); SSF_available = true; i_SSF_rowCount = g->GetRowVertexCount(); ip_SSF_RowIndex = *ip2_RowIndex; ip_SSF_ColumnIndex = *ip2_ColumnIndex; dp_SSF_Value = *dp2_JacobianValue; return returnValue; } int JacobianRecovery1D::RecoverD2Row_CoordinateFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetRowVertexCount(); vector vi_LeftVertexColors; g->GetLeftVertexColors(vi_LeftVertexColors); int numOfNonZeros; vector* LeftVerticesPtr = g->GetLeftVerticesPtr(); //Recover value of the Jacobian // #pragma omp parallel for default(none) schedule(static) shared(rowCount,LeftVerticesPtr,dp2_JacobianValue, ip2_RowIndex, ip2_ColumnIndex, uip2_JacobianSparsityPattern, dp2_CompressedMatrix, vi_LeftVertexColors) private(numOfNonZeros) /* for(unsigned int i=0; i < (unsigned int)rowCount; i++) { numOfNonZeros = uip2_JacobianSparsityPattern[i][0]; for(int j=1; j <= numOfNonZeros; j++) { (*dp2_JacobianValue)[(*LeftVerticesPtr)[i]+j-1] = dp2_CompressedMatrix[vi_LeftVertexColors[i]][uip2_JacobianSparsityPattern[i][j]]; (*ip2_RowIndex)[(*LeftVerticesPtr)[i]+j-1] = i; (*ip2_ColumnIndex)[(*LeftVerticesPtr)[i]+j-1] = uip2_JacobianSparsityPattern[i][j]; } } if(numOfNonZeros_count != g->GetEdgeCount()) { cout<<"**Something fishing going on"<GetEdgeCount()) { cout<<"**Something fishing going on"<GetRowVertexCount(); vector vi_LeftVertexColors; g->GetLeftVertexColors(vi_LeftVertexColors); int numOfNonZeros; //Recover value of the Jacobian unsigned int numOfNonZeros_count = 0; for(unsigned int i=0; i < (unsigned int)rowCount; i++) { numOfNonZeros = uip2_JacobianSparsityPattern[i][0]; for(int j=1; j <= numOfNonZeros; j++) { (*dp2_JacobianValue)[numOfNonZeros_count] = dp2_CompressedMatrix[vi_LeftVertexColors[i]][uip2_JacobianSparsityPattern[i][j]]; (*ip2_RowIndex)[numOfNonZeros_count] = i; (*ip2_ColumnIndex)[numOfNonZeros_count] = uip2_JacobianSparsityPattern[i][j]; numOfNonZeros_count++; } } if(numOfNonZeros_count != g->GetEdgeCount()) { cout<<"**Something fishing going on"<GetEdgeCount(); // !!! test the effectiveness of this sections. Will I really get any improvement #pragma omp sections { #pragma omp section { (*ip2_RowIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); } #pragma omp section { (*ip2_ColumnIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); } #pragma omp section { (*dp2_JacobianValue) = (double*) malloc(numOfNonZeros * sizeof(double)); //allocate memory for *dp2_JacobianValue. } } return RecoverD2Row_CoordinateFormat_usermem(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); } */ int JacobianRecovery1D::RecoverD2Row_CoordinateFormat_unmanaged(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetEdgeCount(); (*ip2_RowIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); (*ip2_ColumnIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); (*dp2_JacobianValue) = (double*) malloc(numOfNonZeros * sizeof(double)); //allocate memory for *dp2_JacobianValue. // return RecoverD2Row_CoordinateFormat_usermem_serial(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); return RecoverD2Row_CoordinateFormat_usermem(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); } /* int JacobianRecovery1D::RecoverD2Row_CoordinateFormat_OMP(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { int returnValue = RecoverD2Row_CoordinateFormat_unmanaged_OMP(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); if(CF_available) reset(); CF_available = true; i_CF_rowCount = g->GetRowVertexCount(); ip_CF_RowIndex = *ip2_RowIndex; ip_CF_ColumnIndex = *ip2_ColumnIndex; dp_CF_Value = *dp2_JacobianValue; return returnValue; } */ int JacobianRecovery1D::RecoverD2Row_CoordinateFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { int returnValue = RecoverD2Row_CoordinateFormat_unmanaged(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); if(CF_available) reset(); CF_available = true; i_CF_rowCount = g->GetRowVertexCount(); ip_CF_RowIndex = *ip2_RowIndex; ip_CF_ColumnIndex = *ip2_ColumnIndex; dp_CF_Value = *dp2_JacobianValue; return returnValue; } int JacobianRecovery1D::RecoverD2Cln_ADICFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, std::list >& lsi_SparsityPattern, std::list > &lvd_NewValue) { if(g==NULL) { cerr<<"g==NULL"<GetRowVertexCount(); vector vi_RightVertexColors; g->GetRightVertexColors(vi_RightVertexColors); unsigned int numOfNonZeros = 0; std::list >::iterator lsii_SparsityPattern = lsi_SparsityPattern.begin(); //Recover value of the Jacobian //cout<<"Recover value of the Jacobian"< valset = *lsii_SparsityPattern; std::set::iterator valsetiter = valset.begin(); numOfNonZeros = valset.size(); //(*lsii_SparsityPattern) is equivalent to uip2_JacobianSparsityPattern[i] std::vector valuevector; valuevector.resize(numOfNonZeros); for(unsigned int j=0; j < numOfNonZeros; valsetiter++, j++) { valuevector[j] = dp2_CompressedMatrix[i][vi_RightVertexColors[*valsetiter]]; } lvd_NewValue.push_back(valuevector); } return rowCount; } int JacobianRecovery1D::RecoverD2Cln_RowCompressedFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetRowVertexCount(); vector vi_RightVertexColors; g->GetRightVertexColors(vi_RightVertexColors); unsigned int numOfNonZeros = 0; //Recover value of the Jacobian //cout<<"Recover value of the Jacobian"<GetRowVertexCount(); unsigned int numOfNonZeros = 0; //allocate memory for *dp3_JacobianValue. The dp3_JacobianValue and uip2_JacobianSparsityPattern matrices should have the same size //cout<<"allocate memory for *dp3_JacobianValue rowCount="<GetRowVertexCount(); dp2_AF_Value = *dp3_JacobianValue; return returnValue; } int JacobianRecovery1D::RecoverD2Cln_SparseSolversFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetRowVertexCount(); vector vi_RightVertexColors; g->GetRightVertexColors(vi_RightVertexColors); unsigned int numOfNonZeros = 0; numOfNonZeros = g->GetEdgeCount(); //Making the array indices to start at 0 instead of 1 for(unsigned int i=0; i <= (unsigned int)rowCount; i++) { (*ip2_RowIndex)[i]--; } for(unsigned int i=0; i < numOfNonZeros; i++) { (*ip2_ColumnIndex)[i]--; } //Recover value of the Jacobian //cout<<"Recover value of the Jacobian"<GetRowVertexCount(); unsigned int numOfNonZeros = 0; // Allocate memory and populate ip2_RowIndex and ip2_ColumnIndex g->GetRowVertices(ip2_RowIndex); numOfNonZeros = g->GetColumnIndices(ip2_ColumnIndex); //Making the array indices to start at 1 instead of 0 to conform with theIntel MKL sparse storage scheme for the direct sparse solvers for(unsigned int i=0; i <= (unsigned int)rowCount; i++) { (*ip2_RowIndex)[i]++; } for(unsigned int i=0; i < numOfNonZeros; i++) { (*ip2_ColumnIndex)[i]++; } //cout<<"allocate memory for *dp2_JacobianValue rowCount="<GetRowVertexCount(); ip_SSF_RowIndex = *ip2_RowIndex; ip_SSF_ColumnIndex = *ip2_ColumnIndex; dp_SSF_Value = *dp2_JacobianValue; return returnValue; } int JacobianRecovery1D::RecoverD2Cln_CoordinateFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetRowVertexCount(); vector vi_RightVertexColors; g->GetRightVertexColors(vi_RightVertexColors); unsigned int numOfNonZeros = 0; // vector* LeftVerticesPtr = g->GetLeftVerticesPtr(); //Recover value of the Jacobian //cout<<"Recover value of the Jacobian"<GetRowVertexCount(); vector vi_RightVertexColors; g->GetRightVertexColors(vi_RightVertexColors); unsigned int numOfNonZeros = 0; //Recover value of the Jacobian //cout<<"Recover value of the Jacobian"<GetEdgeCount(); // !!! test the effectiveness of this sections. Will I really get any improvement? #pragma omp sections { #pragma omp section { (*ip2_RowIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); } #pragma omp section { (*ip2_ColumnIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); } #pragma omp section { (*dp2_JacobianValue) = (double*) malloc(numOfNonZeros * sizeof(double)); //allocate memory for *dp2_JacobianValue. } } return RecoverD2Cln_CoordinateFormat_usermem(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); } */ int JacobianRecovery1D::RecoverD2Cln_CoordinateFormat_unmanaged(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetEdgeCount(); (*ip2_RowIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); (*ip2_ColumnIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); (*dp2_JacobianValue) = (double*) malloc(numOfNonZeros * sizeof(double)); //allocate memory for *dp2_JacobianValue. // return RecoverD2Cln_CoordinateFormat_usermem_serial(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); return RecoverD2Cln_CoordinateFormat_usermem(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); } /* int JacobianRecovery1D::RecoverD2Cln_CoordinateFormat_OMP(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { int returnValue = RecoverD2Cln_CoordinateFormat_unmanaged_OMP(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); if(CF_available) reset(); CF_available = true; i_CF_rowCount = g->GetRowVertexCount(); ip_CF_RowIndex = *ip2_RowIndex; ip_CF_ColumnIndex = *ip2_ColumnIndex; dp_CF_Value = *dp2_JacobianValue; return returnValue; } */ int JacobianRecovery1D::RecoverD2Cln_CoordinateFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { int returnValue = RecoverD2Cln_CoordinateFormat_unmanaged(g, dp2_CompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); if(CF_available) reset(); CF_available = true; i_CF_rowCount = g->GetRowVertexCount(); ip_CF_RowIndex = *ip2_RowIndex; ip_CF_ColumnIndex = *ip2_ColumnIndex; dp_CF_Value = *dp2_JacobianValue; return returnValue; } int JacobianRecovery1D::CompareMatrix_CoordinateFormat_vs_CoordinateFormat(int i_rowCount, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue, unsigned int** ip2_RowIndex2, unsigned int** ip2_ColumnIndex2, double** dp2_JacobianValue2) { bool fail_flag=false; for(int i=0;i= rowCount2) { fail_flag = true; break; } int j =0; for(;j<= (*uip3_SparsityPattern)[ (*ip2_RowIndex)[i] ][0];j++) { if((*uip3_SparsityPattern)[ (*ip2_RowIndex)[i] ][j] == (*ip2_ColumnIndex)[i]) break; } if(j>(*uip3_SparsityPattern)[ (*ip2_RowIndex)[i] ][0]) { fail_flag = true; break; } //cout<<"found j = "<. ************************************************************************************/ #ifndef JACOBIANRECOVERY1D_H #define JACOBIANRECOVERY1D_H using namespace std; namespace ColPack { /** @ingroup group5 * @brief class JacobianRecovery1D in @link group5@endlink. */ class JacobianRecovery1D : public RecoveryCore { public: //DOCUMENTED /// A routine for recovering a Jacobian from a "Row-wise Distance 2 coloring"-based compressed representation. /** Return by recovery routine: double*** dp3_JacobianValue Precondition: - Row-wise Distance 2 coloring routine has been called. - uip2_JacobianSparsityPattern (input) The Jacobian matrix must be stored in compressed sparse rows format - dp3_JacobianValue (output) is just a pointer pointing to a 2D matrix (no memory allocated yet). This matrix will be created (memory will be allocated) by DirectRecover() and the pointer will be assigned to dp3_JacobianValue Postcondition: - dp3_JacobianValue points to a 2d matrix contains the numerical values of the Jacobian. Row Compressed Format is used The memory allocated for this output vector is managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. Return value: size of (*dp3_JacobianValue) array About input parameters: - This routine doesn't take (Row-wise Distance 2) coloring result m_vi_LeftVertexColors of the Jacobian as another paramenter because that information is known already (because of the 1st precondition). Row Compressed Format for dp3_JacobianValue: - This is a 2D matrix of doubles. - The first element of each row will specify the number of non-zeros in the Jacobian => Value of the first element + 1 will be the length of that row. - The value of each element after the 1st element is the value of the non-zero in the Jacobian. The value of dp3_JacobianValue[col][row] is the value of element [col][uip2_JacobianSparsityPattern[col][row]] in the real (uncompressed) Jacobian An example of compressed sparse rows format: - Uncompressed matrix:
1 .5 0
.2 2 3
0 6 -.5
- Corresponding uip2_JacobianSparsityPattern:
2 0 1
3 0 1 2
2 1 2
- Corresponding dp3_JacobianValue:
2 1 .5
3 .2 2 3
2 6 -.5
*/ int RecoverD2Row_RowCompressedFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue); /// Same as RecoverD2Row_RowCompressedFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int RecoverD2Row_RowCompressedFormat_unmanaged(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue); /// Same as RecoverD2Row_RowCompressedFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). (*dp3_JacobianValue) should have the same structure as uip2_JacobianSparsityPattern */ int RecoverD2Row_RowCompressedFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue); /// A routine for recovering a Jacobian from a "Row-wise Distance 2 coloring"-based compressed representation. /** Precondition: - (*ip2_RowIndex), (*ip2_ColumnIndex), and (*dp2_JacobianValue) are equal to NULL, i.e. no memory has been allocated for these 3 vectors yet Return value: size of (*ip2_RowIndex) array Return by recovery routine: three vectors in "Storage Formats for the Direct Sparse Solvers" (one-based indexing) http://software.intel.com/sites/products/documentation/hpc/mkl/webhelp/appendices/mkl_appA_SMSF.html#mkl_appA_SMSF_1 - unsigned int** ip2_RowIndex - unsigned int** ip2_ColumnIndex - double** dp2_JacobianValue // corresponding non-zero values Note: In case of Jacobian (non-symmetric matrix), Sparse Solvers Format is equivalent to one-based indexing, 3 array variation CSR format http://software.intel.com/sites/products/documentation/hpc/mkl/webhelp/appendices/mkl_appA_SMSF.html#table_79228E147DA0413086BEFF4EFA0D3F04 The memory allocated for these 3 output vectors are managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. //*/ int RecoverD2Row_SparseSolversFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as RecoverD2Row_SparseSolversFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int RecoverD2Row_SparseSolversFormat_unmanaged(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as RecoverD2Row_SparseSolversFormat_usermem(), except that memory allocation for output vector(s) is done by user. /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). */ int RecoverD2Row_SparseSolversFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// A routine for recovering a Jacobian from a "Row-wise Distance 2 coloring"-based compressed representation. /** Precondition: - (*ip2_RowIndex), (*ip2_ColumnIndex), and (*dp2_JacobianValue) are equal to NULL, i.e. no memory has been allocated for these 3 vectors yet Return value: size of (*ip2_RowIndex) array Return by recovery routine: three vectors in "Coordinate Format" (zero-based indexing) http://www.intel.com/software/products/mkl/docs/webhelp/appendices/mkl_appA_SMSF.html#mkl_appA_SMSF_5 - unsigned int** ip2_RowIndex - unsigned int** ip2_ColumnIndex - double** dp2_JacobianValue // corresponding non-zero values The memory allocated for these 3 output vectors are managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. */ int RecoverD2Row_CoordinateFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); // int RecoverD2Row_CoordinateFormat_OMP(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as RecoverD2Row_CoordinateFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int RecoverD2Row_CoordinateFormat_unmanaged(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); // int RecoverD2Row_CoordinateFormat_unmanaged_OMP(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as RecoverD2Row_CoordinateFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. (OpenMP enabled) /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). */ // int RecoverD2Row_CoordinateFormat_usermem_serial(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); int RecoverD2Row_CoordinateFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); //int RecoverD2Row_CoordinateFormat_usermem_OMP(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// A routine for recovering a Jacobian from a "Column-wise Distance 2 coloring"-based compressed representation. /** Return by recovery routine: double*** dp3_JacobianValue Precondition: - Column-wise Distance 2 coloring routine has been called. - uip2_JacobianSparsityPattern (input) The Jacobian matrix must be stored in compressed sparse rows format - dp3_JacobianValue (output) is just a pointer pointing to a 2D matrix (no memory allocated yet). This matrix will be created (memory will be allocated) by DirectRecover() and the pointer will be assigned to dp3_JacobianValue Postcondition: - dp3_JacobianValue points to a 2d matrix contains the numerical values of the Jacobian. Row Compressed Format is used The memory allocated for this output vector is managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. Return value: size of (*dp3_JacobianValue) array About input parameters: - This routine doesn't take (Column-wise Distance 2) coloring result m_vi_RightVertexColors of the Jacobian as another paramenter because that information is known already (because of the 1st precondition). Row Compressed Format for dp3_JacobianValue: - This is a 2D matrix of doubles. - The first element of each row will specify the number of non-zeros in the Jacobian => Value of the first element + 1 will be the length of that row. - The value of each element after the 1st element is the value of the non-zero in the Jacobian. The value of dp3_JacobianValue[col][row] is the value of element [col][uip2_JacobianSparsityPattern[col][row]] in the real (uncompressed) Jacobian An example of compressed sparse rows format: - Uncompressed matrix:
1 .5 0
.2 2 3
0 6 -.5
- Corresponding uip2_JacobianSparsityPattern:
2 0 1
3 0 1 2
2 1 2
- Corresponding dp3_JacobianValue:
2 1 .5
3 .2 2 3
2 6 -.5
*/ int RecoverD2Cln_RowCompressedFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue); int RecoverD2Cln_ADICFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, std::list >& lsi_SparsityPattern, std::list > &lvd_NewValue); /// Same as RecoverD2Cln_RowCompressedFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int RecoverD2Cln_RowCompressedFormat_unmanaged(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue); /// Same as RecoverD2Cln_RowCompressedFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). (*dp3_JacobianValue) should have the same structure as uip2_JacobianSparsityPattern */ int RecoverD2Cln_RowCompressedFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue); /// A routine for recovering a Jacobian from a "Column-wise Distance 2 coloring"-based compressed representation. /** Precondition: - (*ip2_RowIndex), (*ip2_ColumnIndex), and (*dp2_JacobianValue) are equal to NULL, i.e. no memory has been allocated for these 3 vectors yet Return value: size of (*ip2_RowIndex) array Return by recovery routine: three vectors in "Storage Formats for the Direct Sparse Solvers" (one-based indexing) http://software.intel.com/sites/products/documentation/hpc/mkl/webhelp/appendices/mkl_appA_SMSF.html#mkl_appA_SMSF_1 - unsigned int** ip2_RowIndex - unsigned int** ip2_ColumnIndex - double** dp2_JacobianValue // corresponding non-zero values Note: In case of Jacobian (non-symmetric matrix), Sparse Solvers Format is equivalent to one-based indexing, 3 array variation CSR format http://software.intel.com/sites/products/documentation/hpc/mkl/webhelp/appendices/mkl_appA_SMSF.html#table_79228E147DA0413086BEFF4EFA0D3F04 The memory allocated for these 3 output vectors are managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. //*/ int RecoverD2Cln_SparseSolversFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as RecoverD2Cln_SparseSolversFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int RecoverD2Cln_SparseSolversFormat_unmanaged(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as RecoverD2Cln_SparseSolversFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). */ int RecoverD2Cln_SparseSolversFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// A routine for recovering a Jacobian from a "Column-wise Distance 2 coloring"-based compressed representation. /** Precondition: - (*ip2_RowIndex), (*ip2_ColumnIndex), and (*dp2_JacobianValue) are equal to NULL, i.e. no memory has been allocated for these 3 vectors yet Return value: size of (*ip2_RowIndex) array Return by recovery routine: three vectors in "Coordinate Format" (zero-based indexing) http://www.intel.com/software/products/mkl/docs/webhelp/appendices/mkl_appA_SMSF.html#mkl_appA_SMSF_5 - unsigned int** ip2_RowIndex - unsigned int** ip2_ColumnIndex - double** dp2_JacobianValue // corresponding non-zero values The memory allocated for these 3 output vectors are managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. //*/ int RecoverD2Cln_CoordinateFormat(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); // int RecoverD2Cln_CoordinateFormat_OMP(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as RecoverD2Cln_CoordinateFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int RecoverD2Cln_CoordinateFormat_unmanaged(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); // int RecoverD2Cln_CoordinateFormat_unmanaged_OMP(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as RecoverD2Cln_CoordinateFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. (OpenMP enabled) /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). */ // int RecoverD2Cln_CoordinateFormat_usermem_serial(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); int RecoverD2Cln_CoordinateFormat_usermem(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); //int RecoverD2Cln_CoordinateFormat_usermem_OMP(BipartiteGraphPartialColoringInterface* g, double** dp2_CompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); // Compare 2 matrices in Coordinate Format. Return 1 if they are the same, return 0 if they are different int CompareMatrix_CoordinateFormat_vs_CoordinateFormat(int i_rowCount, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue, unsigned int** ip2_RowIndex2, unsigned int** ip2_ColumnIndex2, double** dp2_JacobianValue2); // Compare 2 matrices (the first one in Coordinate Format and the second one in Row Compressed Format). Return 1 if they are the same, return 0 if they are different // !!! not tested int CompareMatrix_CoordinateFormat_vs_RowCompressedFormat(int i_rowCount, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue, int rowCount2, unsigned int *** uip3_SparsityPattern, double*** dp3_Value); }; } #endif ColPack-1.0.10/Recovery/JacobianRecovery2D.cpp000066400000000000000000000454241266356121500210420ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { int JacobianRecovery2D::DirectRecover_RowCompressedFormat_usermem(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetRowVertexCount(); vector vi_LeftVertexColors; g->GetLeftVertexColors(vi_LeftVertexColors); vector RightVertexColors_Transformed; g->GetRightVertexColors_Transformed(RightVertexColors_Transformed); int i_ColumnColorCount = g->GetRightVertexColorCount(); if (g->GetRightVertexDefaultColor() == 1) i_ColumnColorCount--; //color ID 0 is used, ignore it //Do (column-)color statistic for each row, i.e., see how many elements in that row has color 0, color 1 ... int** colorStatistic = new int*[rowCount]; //color statistic for each row. For example, colorStatistic[0] is color statistic for row 0 //If row 0 has 5 columns with color 3 => colorStatistic[0][3] = 5; //Allocate memory for colorStatistic[rowCount][colorCount] and initilize the matrix for(unsigned int i=0; i < (unsigned int)rowCount; i++) { colorStatistic[i] = new int[i_ColumnColorCount]; for(unsigned int j=0; j < (unsigned int)i_ColumnColorCount; j++) colorStatistic[i][j] = 0; } //populate colorStatistic for right (column) vertices for(unsigned int i=0; i < (unsigned int)rowCount; i++) { int numOfNonZeros = uip2_JacobianSparsityPattern[i][0]; for(unsigned int j=1; j <= (unsigned int)numOfNonZeros; j++) { //non-zero in the Jacobian: [i][uip2_JacobianSparsityPattern[i][j]] //color of that column: RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1 if (RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]] > 0) { colorStatistic[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1]++; } } } //Recover value of the Jacobian from dp2_ColumnCompressedMatrix (priority) and dp2_RowCompressedMatrix //cout<<"Recover value of the Jacobian from dp2_ColumnCompressedMatrix (priority) and dp2_RowCompressedMatrix"< 0 && colorStatistic[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]] - 1]==1 ) { //printf("\t from COLUMN [%d][%d] = %7.2f \n",i, RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1, dp2_ColumnCompressedMatrix[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1]); //printf("\t from COLUMN [%d][%d] \n",i, RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1); (*dp3_JacobianValue)[i][j] = dp2_ColumnCompressedMatrix[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1]; } else { // If not, then use dp2_RowCompressedMatrix //printf("\t from ROW [%d][%d] = %7.2f \n",m_vi_LeftVertexColors[i]-1, uip2_JacobianSparsityPattern[i][j], dp2_RowCompressedMatrix[m_vi_LeftVertexColors[i]-1][uip2_JacobianSparsityPattern[i][j]]); //printf("\t from ROW [%d][%d] \n",m_vi_LeftVertexColors[i]-1, uip2_JacobianSparsityPattern[i][j]); (*dp3_JacobianValue)[i][j] = dp2_RowCompressedMatrix[vi_LeftVertexColors[i]-1][uip2_JacobianSparsityPattern[i][j]]; } } } //cout<<"DONE"<GetRowVertexCount(); //allocate memory for *dp3_JacobianValue. The dp3_JacobianValue and uip2_JacobianSparsityPattern matrices should have the same size //cout<<"allocate memory for *dp3_JacobianValue"<GetRowVertexCount(); //Making the array indices to start at 0 instead of 1 for(unsigned int i=0; i <= (unsigned int) rowCount ; i++) { (*ip2_RowIndex)[i]--; } for(unsigned int i=0; i < (unsigned int)g->GetEdgeCount(); i++) { (*ip2_ColumnIndex)[i]--; } vector vi_LeftVertexColors; g->GetLeftVertexColors(vi_LeftVertexColors); vector RightVertexColors_Transformed; g->GetRightVertexColors_Transformed(RightVertexColors_Transformed); int i_ColumnColorCount = g->GetRightVertexColorCount(); if (g->GetRightVertexDefaultColor() == 1) i_ColumnColorCount--; //color ID 0 is used, ignore it //Do (column-)color statistic for each row, i.e., see how many elements in that row has color 0, color 1 ... int** colorStatistic = new int*[rowCount]; //color statistic for each row. For example, colorStatistic[0] is color statistic for row 0 //If row 0 has 5 columns with color 3 => colorStatistic[0][3] = 5; //Allocate memory for colorStatistic[rowCount][colorCount] and initilize the matrix for(unsigned int i=0; i < (unsigned int)rowCount; i++) { colorStatistic[i] = new int[i_ColumnColorCount]; for(unsigned int j=0; j < (unsigned int)i_ColumnColorCount; j++) colorStatistic[i][j] = 0; } //populate colorStatistic for right (column) vertices unsigned int numOfNonZeros = 0; for(unsigned int i=0; i < (unsigned int)rowCount; i++) { numOfNonZeros = (unsigned int)uip2_JacobianSparsityPattern[i][0]; for(unsigned int j=1; j <= numOfNonZeros; j++) { //non-zero in the Jacobian: [i][uip2_JacobianSparsityPattern[i][j]] //color of that column: RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1 if (RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]] > 0) { colorStatistic[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1]++; } } } //Recover value of the Jacobian from dp2_ColumnCompressedMatrix (priority) and dp2_RowCompressedMatrix //cout<<"Recover value of the Jacobian from dp2_ColumnCompressedMatrix (priority) and dp2_RowCompressedMatrix"< 0 && colorStatistic[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]] - 1]==1 ) { //printf("\t from COLUMN [%d][%d] = %7.2f \n",i, RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1, dp2_ColumnCompressedMatrix[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1]); //printf("\t from COLUMN [%d][%d] \n",i, RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1); (*dp2_JacobianValue)[(*ip2_RowIndex)[i]+j-1] = dp2_ColumnCompressedMatrix[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1]; } else { // If not, then use dp2_RowCompressedMatrix //printf("\t from ROW [%d][%d] = %7.2f \n",m_vi_LeftVertexColors[i]-1, uip2_JacobianSparsityPattern[i][j], dp2_RowCompressedMatrix[m_vi_LeftVertexColors[i]-1][uip2_JacobianSparsityPattern[i][j]]); //printf("\t from ROW [%d][%d] \n",m_vi_LeftVertexColors[i]-1, uip2_JacobianSparsityPattern[i][j]); (*dp2_JacobianValue)[(*ip2_RowIndex)[i]+j-1] = dp2_RowCompressedMatrix[vi_LeftVertexColors[i]-1][uip2_JacobianSparsityPattern[i][j]]; } } } //cout<<"DONE"<GetEdgeCount(); i++) { (*ip2_ColumnIndex)[i]++; } free_2DMatrix(colorStatistic, rowCount); colorStatistic = NULL; return rowCount; } int JacobianRecovery2D::DirectRecover_SparseSolversFormat_unmanaged(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { if(g==NULL) { cerr<<"g==NULL"<GetRowVertexCount(); // Allocate memory and populate ip2_RowIndex and ip2_ColumnIndex g->GetRowVertices(ip2_RowIndex); unsigned int numOfNonZeros = g->GetColumnIndices(ip2_ColumnIndex); //Making the array indices to start at 1 instead of 0 to conform with theIntel MKL sparse storage scheme for the direct sparse solvers for(unsigned int i=0; i <= (unsigned int) rowCount ; i++) { (*ip2_RowIndex)[i]++; } for(unsigned int i=0; i < numOfNonZeros; i++) { (*ip2_ColumnIndex)[i]++; } //cout<<"allocate memory for *dp2_JacobianValue rowCount="<GetRowVertexCount(); vector vi_LeftVertexColors; g->GetLeftVertexColors(vi_LeftVertexColors); vector RightVertexColors_Transformed; g->GetRightVertexColors_Transformed(RightVertexColors_Transformed); int i_ColumnColorCount = g->GetRightVertexColorCount(); if (g->GetRightVertexDefaultColor() == 1) i_ColumnColorCount--; //color ID 0 is used, ignore it //Do (column-)color statistic for each row, i.e., see how many elements in that row has color 0, color 1 ... int** colorStatistic = new int*[rowCount]; //color statistic for each row. For example, colorStatistic[0] is color statistic for row 0 //If row 0 has 5 columns with color 3 => colorStatistic[0][3] = 5; //Allocate memory for colorStatistic[rowCount][colorCount] and initilize the matrix for(unsigned int i=0; i < (unsigned int)rowCount; i++) { colorStatistic[i] = new int[i_ColumnColorCount]; for(unsigned int j=0; j < (unsigned int)i_ColumnColorCount; j++) colorStatistic[i][j] = 0; } //populate colorStatistic for right (column) vertices for(unsigned int i=0; i < (unsigned int)rowCount; i++) { int numOfNonZeros = uip2_JacobianSparsityPattern[i][0]; for(unsigned int j=1; j <= (unsigned int)numOfNonZeros; j++) { //non-zero in the Jacobian: [i][uip2_JacobianSparsityPattern[i][j]] //color of that column: m_vi_RightVertexColors[uip2_JacobianSparsityPattern[i][j]]-1 if (RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]] > 0) { colorStatistic[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1]++; } } } //Recover value of the Jacobian from dp2_ColumnCompressedMatrix (priority) and dp2_RowCompressedMatrix //cout<<"Recover value of the Jacobian from dp2_ColumnCompressedMatrix (priority) and dp2_RowCompressedMatrix"< 0 && colorStatistic[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]] - 1]==1 ) { //printf("\t from COLUMN [%d][%d] = %7.2f \n",i, RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1, dp2_ColumnCompressedMatrix[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1]); //printf("\t from COLUMN [%d][%d] \n",i, RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1); (*dp2_JacobianValue)[numOfNonZeros_count] = dp2_ColumnCompressedMatrix[i][RightVertexColors_Transformed[uip2_JacobianSparsityPattern[i][j]]-1]; } else { // If not, then use dp2_RowCompressedMatrix //printf("\t from ROW [%d][%d] = %7.2f \n",m_vi_LeftVertexColors[i]-1, uip2_JacobianSparsityPattern[i][j], dp2_RowCompressedMatrix[m_vi_LeftVertexColors[i]-1][uip2_JacobianSparsityPattern[i][j]]); //printf("\t from ROW [%d][%d] \n",m_vi_LeftVertexColors[i]-1, uip2_JacobianSparsityPattern[i][j]); (*dp2_JacobianValue)[numOfNonZeros_count] = dp2_RowCompressedMatrix[vi_LeftVertexColors[i]-1][uip2_JacobianSparsityPattern[i][j]]; } (*ip2_RowIndex)[numOfNonZeros_count] = i; (*ip2_ColumnIndex)[numOfNonZeros_count] = uip2_JacobianSparsityPattern[i][j]; numOfNonZeros_count++; } } //cout<<"DONE"<GetEdgeCount(); (*ip2_RowIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); (*ip2_ColumnIndex) = (unsigned int*) malloc(numOfNonZeros * sizeof(unsigned int)); (*dp2_JacobianValue) = (double*) malloc(numOfNonZeros * sizeof(double)); //allocate memory for *dp2_JacobianValue. return DirectRecover_CoordinateFormat_usermem(g, dp2_RowCompressedMatrix, dp2_ColumnCompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); } int JacobianRecovery2D::DirectRecover_CoordinateFormat(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue) { int returnValue = DirectRecover_CoordinateFormat_unmanaged(g, dp2_RowCompressedMatrix, dp2_ColumnCompressedMatrix, uip2_JacobianSparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); if(CF_available) reset(); CF_available = true; i_CF_rowCount = g->GetRowVertexCount(); ip_CF_RowIndex = *ip2_RowIndex; ip_CF_ColumnIndex = *ip2_ColumnIndex; dp_CF_Value = *dp2_JacobianValue; return returnValue; } } ColPack-1.0.10/Recovery/JacobianRecovery2D.h000066400000000000000000000243651266356121500205100ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #ifndef JACOBIANRECOVERY2D_H #define JACOBIANRECOVERY2D_H using namespace std; namespace ColPack { /** @ingroup group5 * @brief class JacobianRecovery2D in @link group5@endlink. */ class JacobianRecovery2D : public RecoveryCore { public: //DOCUMENTED /// A routine for recovering a Jacobian from a Star-Bicoloring based compressed representation. /** Parameter: - Input: - dp2_RowCompressedMatrix: The row compressed matrix that contains all computed values. Row compressed matrix is the matrix where all rows with the same color ID (the values of m_vi_LeftVertexColors[] are equal) are merged together. - dp2_ColumnCompressedMatrix: The column compressed matrix that contains all computed values. Column compressed matrix is the matrix where all columns with the same color ID (the values of m_vi_RightVertexColors[] are equal) are merged together. - uip2_JacobianSparsityPattern. - Output: - dp3_JacobianValue Precondition: - Star Bicoloring routine has been called. - uip2_JacobianSparsityPattern: The Jacobian matrix must be stored in compressed sparse rows format - dp3_JacobianValue is just a pointer pointing to a 2D matrix (no memory allocated yet). This matrix will be created (memory will be allocated) by DirectRecover() and the pointer will be assigned to dp3_JacobianValue Postcondition: - dp3_JacobianValue points to a 2d matrix contains the numerical values of the Jacobian. Row Compressed Format is used. The memory allocated for this output vector is managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. Return value: size of (*dp3_JacobianValue) array About input parameters: - This routine doesn't need to take (Star) Bicoloring results (m_vi_LeftVertexColors and m_vi_RightVertexColors) of the Jacobian as another paramenter because that information is known internally already (because of the 1st precondition). Row Compressed Format for dp3_JacobianValue: - This is a 2D matrix of doubles. - The first element of each row will specify the number of non-zeros in the Jacobian => Value of the first element + 1 will be the length of that row. - The value of each element after the 1st element is the value of the non-zero in the Jacobian. The value of dp3_JacobianValue[col][row] is the value of element [col][uip2_JacobianSparsityPattern[col][row]] in the real (uncompressed) Jacobian - An example of compressed sparse rows format: - Uncompressed matrix:
1 .5 0
.2 2 3
0 6 -.5
- Corresponding uip2_JacobianSparsityPattern:
2 0 1
3 0 1 2
2 1 2
- Corresponding dp3_JacobianValue:
2 1 .5
3 .2 2 3
2 6 -.5
Algorithm: Basically the combination of RecoverForPD2RowWise() (for dp2_RowCompressedMatrix) and RecoverForPD2ColumnWise() (for dp2_ColumnCompressedMatrix) in BipartiteGraphPartialColoringInterface class */ int DirectRecover_RowCompressedFormat(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue); /// Same as DirectRecover_RowCompressedFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int DirectRecover_RowCompressedFormat_unmanaged(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue); /// Same as DirectRecover_RowCompressedFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). (*dp3_JacobianValue) should have the same structure as uip2_JacobianSparsityPattern */ int DirectRecover_RowCompressedFormat_usermem(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, double*** dp3_JacobianValue); /// A routine for recovering a Jacobian from a Star-Bicoloring based compressed representation. /** Precondition: - (*ip2_RowIndex), (*ip2_ColumnIndex), and (*dp2_JacobianValue) are equal to NULL, i.e. no memory has been allocated for these 3 vectors yet Return value: size of (*ip2_RowIndex) array Return by recovery routine: three vectors in "Coordinate Format" (zero-based indexing) http://www.intel.com/software/products/mkl/docs/webhelp/appendices/mkl_appA_SMSF.html#mkl_appA_SMSF_5 - unsigned int** ip2_RowIndex - unsigned int** ip2_ColumnIndex - double** dp2_JacobianValue // corresponding non-zero values The memory allocated for these 3 output vectors are managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. //*/ int DirectRecover_CoordinateFormat(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as DirectRecover_CoordinateFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int DirectRecover_CoordinateFormat_unmanaged(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as DirectRecover_CoordinateFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). */ int DirectRecover_CoordinateFormat_usermem(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// A routine for recovering a Jacobian from a Star-Bicoloring based compressed representation. /** Precondition: - (*ip2_RowIndex), (*ip2_ColumnIndex), and (*dp2_JacobianValue) are equal to NULL, i.e. no memory has been allocated for these 3 vectors yet Return value: size of (*ip2_RowIndex) array Return by recovery routine: three vectors in "Storage Formats for the Direct Sparse Solvers" (one-based indexing) http://software.intel.com/sites/products/documentation/hpc/mkl/webhelp/appendices/mkl_appA_SMSF.html#mkl_appA_SMSF_1 - unsigned int** ip2_RowIndex - unsigned int** ip2_ColumnIndex - double** dp2_JacobianValue // corresponding non-zero values Note: In case of Jacobian (non-symmetric matrix), Sparse Solvers Format is equivalent to one-based indexing, 3 array variation CSR format http://software.intel.com/sites/products/documentation/hpc/mkl/webhelp/appendices/mkl_appA_SMSF.html#table_79228E147DA0413086BEFF4EFA0D3F04 The memory allocated for these 3 output vectors are managed by ColPack. The memory will be deallocated when this function is called again or when the Recovery ojbect is deallocated. //*/ int DirectRecover_SparseSolversFormat(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as DirectRecover_SparseSolversFormat(), except that the output is NOT managed by ColPack /** Notes: - The output is NOT managed by ColPack. Therefore, the user should free the output manually using free() (NOT delete) function when it is no longer needed. */ int DirectRecover_SparseSolversFormat_unmanaged(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); /// Same as DirectRecover_SparseSolversFormat_unmanaged(), except that memory allocation for output vector(s) is done by user. /** Notes: - This function will assume the user has properly allocate memory output vector(s). No checking will be done so if you got a SEGMENTATION FAULT in this function, you should check and see if you have allocated memory properly for the output vector(s). */ int DirectRecover_SparseSolversFormat_usermem(BipartiteGraphBicoloringInterface* g, double** dp2_RowCompressedMatrix, double** dp2_ColumnCompressedMatrix, unsigned int ** uip2_JacobianSparsityPattern, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex, double** dp2_JacobianValue); }; } #endif ColPack-1.0.10/Recovery/RecoveryCore.cpp000066400000000000000000000064201266356121500200270ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "ColPackHeaders.h" using namespace std; namespace ColPack { RecoveryCore::RecoveryCore() { //formatType = "UNKNOWN"; //for ADOL-C Format (AF) AF_available = false; i_AF_rowCount = 0; dp2_AF_Value = NULL; //for Sparse Solvers Format (SSF) SSF_available = false; i_SSF_rowCount = 0; ip_SSF_RowIndex = NULL; ip_SSF_ColumnIndex = NULL; dp_SSF_Value = NULL; //for Coordinate Format (CF) CF_available = false; i_CF_rowCount = 0; ip_CF_RowIndex = NULL; ip_CF_ColumnIndex = NULL; dp_CF_Value = NULL; } void RecoveryCore::reset() { //for ADOL-C Format (AF) if (AF_available) { //free_2DMatrix(dp2_AF_Value, i_AF_rowCount); for( int i=0; i < i_AF_rowCount; i++ ) { free( dp2_AF_Value[i] ); } free( dp2_AF_Value ); dp2_AF_Value = NULL; AF_available = false; i_AF_rowCount = 0; } //for Sparse Solvers Format (SSF) if (SSF_available) { //delete[] ip_SSF_RowIndex; free(ip_SSF_RowIndex); ip_SSF_RowIndex = NULL; //delete[] ip_SSF_ColumnIndex; free(ip_SSF_ColumnIndex); ip_SSF_ColumnIndex = NULL; //delete[] dp_SSF_Value; free(dp_SSF_Value); dp_SSF_Value = NULL; SSF_available = false; i_SSF_rowCount = 0; } //for Coordinate Format (CF) if (CF_available) { //do something //delete[] ip_CF_RowIndex; free(ip_CF_RowIndex); ip_CF_RowIndex = NULL; //delete[] ip_CF_ColumnIndex; free(ip_CF_ColumnIndex); ip_CF_ColumnIndex = NULL; //delete[] dp_CF_Value; free(dp_CF_Value); dp_CF_Value = NULL; CF_available = false; i_CF_rowCount = 0; } //formatType = "UNKNOWN"; } RecoveryCore::~RecoveryCore() { //for ADOL-C Format (AF) if (AF_available) { //do something //free_2DMatrix(dp2_AF_Value, i_AF_rowCount); for( int i=0; i < i_AF_rowCount; i++ ) { free( dp2_AF_Value[i] ); } free( dp2_AF_Value ); } //for Sparse Solvers Format (SSF) if (SSF_available) { //do something //delete[] ip_SSF_RowIndex; free(ip_SSF_RowIndex); //delete[] ip_SSF_ColumnIndex; free(ip_SSF_ColumnIndex); //delete[] dp_SSF_Value; free(dp_SSF_Value); } //for Coordinate Format (CF) if (CF_available) { //do something //delete[] ip_CF_RowIndex; free(ip_CF_RowIndex); //delete[] ip_CF_ColumnIndex; free(ip_CF_ColumnIndex); //delete[] dp_CF_Value; free(dp_CF_Value); } } } ColPack-1.0.10/Recovery/RecoveryCore.h000066400000000000000000000064571266356121500175060ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #ifndef RECOVERYCORE_H #define RECOVERYCORE_H using namespace std; namespace ColPack { /** @ingroup group5 * @brief class RecoveryCore in @link group5@endlink. * * This class will keep track of all the memories allocated and * its destructor will be responsible to destroy the memory allocated for * arrays/matrices of all the Recovery classes. * * This class currently supports matrices in one of the following three formats: * RowCompressedFormat (AF), CoordinateFormat (CF), and SparseSolversFormat (SSF) * * For one graph, you can call the Recovery routine once for each format. * Calling the same recovery function twice will make this class reset() (see the example below): * * Matrix in a particular format is generated when the Recovery routine of the corresponding format is called. * For example, here is one possible sequence: * JacobianRecovery1D jr1d; // create an oject of subclass of RecoveryCore * jr1d.RecoverD2Row_RowCompressedFormat(graph1 , ...); // output matrix in ADOLC Format is generated * jr1d.RecoverD2Row_SparseSolversFormat(graph1 , ...); // output matrix in Sparse Solvers Format is generated * jr1d.RecoverD2Row_CoordinateFormat(graph1 , ...); // output matrix in Coordinate Format is generated * * // Matrices in all 3 formats will be deallocated, a new output matrix in Coordinate Format is generated * // Here, because the user call RecoverD2Row_CoordinateFormat() for the second time, * // we assume that the user have a new graph, so clean up old matrices is necessary. * // Note: DO NOT call the same recovery function twice unless you have a new graph!!! * jr1d.RecoverD2Row_CoordinateFormat(graph2 , ...); */ class RecoveryCore { public: // !!!NEED DOCUMENT RecoveryCore(); ~RecoveryCore(); protected: //string formatType; //At this point, could be either: "RowCompressedFormat," "CoordinateFormat," or "SparseSolversFormat" //for ADOL-C Format (AF) bool AF_available; int i_AF_rowCount; double** dp2_AF_Value; //for Sparse Solvers Format (SSF) bool SSF_available; int i_SSF_rowCount; unsigned int* ip_SSF_RowIndex; unsigned int* ip_SSF_ColumnIndex; double* dp_SSF_Value; //for Coordinate Format (CF) bool CF_available; int i_CF_rowCount; unsigned int* ip_CF_RowIndex; unsigned int* ip_CF_ColumnIndex; double* dp_CF_Value; void reset(); }; } #endifColPack-1.0.10/SampleDrivers/000077500000000000000000000000001266356121500156745ustar00rootroot00000000000000ColPack-1.0.10/SampleDrivers/.gitignore000066400000000000000000000037451266356121500176750ustar00rootroot00000000000000/Basic/Generate_seed_matrix_for_Hessian /Basic/Generate_seed_matrix_for_Jacobian /Basic/color_bipartite_graph_using_BipartiteGraphBicoloringInterface /Basic/color_bipartite_graph_using_BipartiteGraphPartialColoringInterface /Basic/color_graph_using_GraphColoringInterface /Matrix_Compression_and_Recovery/ADIC/01_Column_compression_and_recovery_for_Jacobian_return_ADIC_Format /Matrix_Compression_and_Recovery/ADOL-C/01_Column_compression_and_recovery_for_Jacobian_return_Row_Compressed_Format /Matrix_Compression_and_Recovery/ADOL-C/02_Column_compression_and_recovery_for_Jacobian_return_Coordinate_Format /Matrix_Compression_and_Recovery/ADOL-C/03_Column_compression_and_recovery_for_Jacobian_return_Sparse_Solvers_Format /Matrix_Compression_and_Recovery/ADOL-C/04_Row_compression_and_recovery_for_Jacobian_return_Row_Compressed_Format /Matrix_Compression_and_Recovery/ADOL-C/05_Compression_and_direct_recovery_for_Hessian_return_Row_Compressed_Format /Matrix_Compression_and_Recovery/ADOL-C/06_Compression_and_direct_recovery_for_Hessian_return_Coordinate_Format /Matrix_Compression_and_Recovery/ADOL-C/07_Compression_and_direct_recovery_for_Hessian_return_Sparse_Solvers_Format /Matrix_Compression_and_Recovery/ADOL-C/08_Compression_and_indirect_recovery_for_Hessian_return_Row_Compressed_Format /Matrix_Compression_and_Recovery/ADOL-C/09_Bidirectional_compression_and_recovery_for_Jacobian_return_Row_Compressed_Format /Matrix_Compression_and_Recovery/ADOL-C/10_Column_compression_and_recovery_for_Jacobian_return_Row_Compressed_Format__unmanaged_usermem /Matrix_Compression_and_Recovery/ADOL-C/11_Compression_and_direct_recovery_for_Hessian_return_Row_Compressed_Format__unmanaged_usermem /Matrix_Compression_and_Recovery/ADOL-C/12_Bidirectional_compression_and_recovery_for_Jacobian_return_Row_Compressed_Format__unmanaged_usermem /Matrix_Compression_and_Recovery/CSR_input/01_Column_compression_and_recovery_for_Jacobian_CSR_input_return_Row_Compressed_Format /Matrix_Compression_and_Recovery/SMB/sparse_jac_hess ColPack-1.0.10/SampleDrivers/Basic/000077500000000000000000000000001266356121500167155ustar00rootroot00000000000000ColPack-1.0.10/SampleDrivers/Basic/Generate_seed_matrix_for_Hessian.cpp000066400000000000000000000067011266356121500260630ustar00rootroot00000000000000// An example for using GraphColoringInterface to generate the seed matrix for Hessian /* How to compile this driver manually: To compile the code, replace the Main.cpp file in Main directory with this file and run "make" in ColPack installation directory. Make will generate "ColPack.exe" executable Run "ColPack.exe" //*/ #include "ColPackHeaders.h" using namespace ColPack; using namespace std; int main() { double*** dp3_Seed = new double**; int *ip1_SeedRowCount = new int; int *ip1_SeedColumnCount = new int; int i_RowCount, i_MaxNonZerosInRows; //populate the Hessian. Uncomment one of the 2 matrices below /* 1x1 matrix i_RowCount = 1; i_MaxNonZerosInRows = 1; unsigned int **uip2_HessianSparsityPattern = new unsigned int *[i_RowCount];//[1][1] for(int i=0;i<1;i++) uip2_HessianSparsityPattern[i] = new unsigned int[i_MaxNonZerosInRows + 1]; uip2_HessianSparsityPattern[0][0] = 1; uip2_HessianSparsityPattern[0][1] = 0; //*/ //* 5x5 matrix i_RowCount = 5; i_MaxNonZerosInRows = 2; unsigned int **uip2_HessianSparsityPattern = new unsigned int *[i_RowCount];//[5][5] for(int i=0;i<5;i++) uip2_HessianSparsityPattern[i] = new unsigned int[i_MaxNonZerosInRows + 1]; uip2_HessianSparsityPattern[0][0] = 1; uip2_HessianSparsityPattern[0][1] = 1; uip2_HessianSparsityPattern[1][0] = 2; uip2_HessianSparsityPattern[1][1] = 0; uip2_HessianSparsityPattern[1][2] = 2; uip2_HessianSparsityPattern[2][0] = 2; uip2_HessianSparsityPattern[2][1] = 1; uip2_HessianSparsityPattern[2][2] = 3; uip2_HessianSparsityPattern[3][0] = 2; uip2_HessianSparsityPattern[3][1] = 2; uip2_HessianSparsityPattern[3][2] = 4; uip2_HessianSparsityPattern[4][0] = 1; uip2_HessianSparsityPattern[4][1] = 3; //*/ //Step 1: Read the sparsity pattern of the given Hessian matrix (compressed sparse rows format) //and create the corresponding graph GraphColoringInterface * g = new GraphColoringInterface(SRC_MEM_ADOLC, uip2_HessianSparsityPattern, i_RowCount); //Step 2: Color the bipartite graph with the specified ordering g->Coloring("SMALLEST_LAST", "STAR"); //Step 3: From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: In stead of doing step 1-3, you can just call the bellow function: g->GenerateSeedHessian(uip2_HessianSparsityPattern, i_RowCount, dp3_Seed, ip1_SeedRowCount, ip1_SeedColumnCount, "STAR", "SMALLEST_LAST"); // this function is inside GraphColoringInterface class */ cout<<"Finish GenerateSeed()"<PrintGraphStructure(); g->PrintVertexColors(); g->PrintVertexColoringMetrics(); double **Seed = *dp3_Seed; int rows = g->GetVertexCount(); int cols = g->GetVertexColorCount(); cout<<"Seed matrix: ("<PartialDistanceTwoColoring( "SMALLEST_LAST", "COLUMN_PARTIAL_DISTANCE_TWO"); //Step 3: From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: In stead of doing step 1-3, you can just call the bellow function: g->GenerateSeedJacobian(uip2_JacobianSparsityPattern, i_RowCount,i_ColumnCount, dp3_Seed, ip1_SeedRowCount, ip1_SeedColumnCount, "COLUMN_PARTIAL_DISTANCE_TWO", "SMALLEST_LAST"); // compress columns. This function is inside BipartiteGraphPartialColoringInterface class */ cout<<"Finish GenerateSeed()"<PrintBipartiteGraph(); g->PrintColumnPartialColors(); g->PrintColumnPartialColoringMetrics(); double **RSeed = *dp3_Seed; int rows = g->GetColumnVertexCount(); int cols = g->GetRightVertexColorCount(); cout<<"Right Seed matrix: ("< string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx"; //Generate and color the bipartite graph BipartiteGraphBicoloringInterface *g = new BipartiteGraphBicoloringInterface(SRC_FILE, s_InputFile.c_str(), "AUTO_DETECTED"); //Color the graph based on the specified ordering and (Star) Bicoloring g->Bicoloring( "SMALLEST_LAST", "IMPLICIT_COVERING__STAR_BICOLORING"); /*Done with coloring. Below are possible things that you may want to do after coloring: //*/ //* 1. Check Star Bicoloring Coloring result cout<<"Check Star Bicoloring Coloring result ... "<CheckStarBicoloring(); //*/ //* 2. Print coloring results g->PrintVertexBicoloringMetrics(); //*/ //* 3. Get the list of colorID of colored vertices (in this case, the left side of the bipartite graph) vector vi_LeftVertexColors; g->GetLeftVertexColors(vi_LeftVertexColors); vector vi_RightVertexColors; g->GetRightVertexColors(vi_RightVertexColors); //Print Partial Colors g->PrintVertexBicolors(); //*/ //* 4. Get seed matrix int i_LeftSeedRowCount = 0; int i_LeftSeedColumnCount = 0; double** LeftSeed = g->GetLeftSeedMatrix(&i_LeftSeedRowCount, &i_LeftSeedColumnCount); int i_RightSeedRowCount = 0; int i_RightSeedColumnCount = 0; double** RightSeed = g->GetRightSeedMatrix(&i_RightSeedRowCount, &i_RightSeedColumnCount); //Display Seeds if(i_LeftSeedRowCount>0 && i_LeftSeedColumnCount > 0){ printf("Left Seed matrix %d x %d \n", i_LeftSeedRowCount, i_LeftSeedColumnCount); displayMatrix(LeftSeed, i_LeftSeedRowCount, i_LeftSeedColumnCount, 1); } if(i_RightSeedRowCount>0 && i_RightSeedColumnCount > 0) { printf("Right Seed matrix %d x %d \n", i_RightSeedRowCount, i_RightSeedColumnCount); displayMatrix(RightSeed, i_RightSeedRowCount, i_RightSeedColumnCount, 1); } //*/ delete g; return 0; } //*/ color_bipartite_graph_using_BipartiteGraphPartialColoringInterface.cpp000066400000000000000000000053761266356121500347440ustar00rootroot00000000000000ColPack-1.0.10/SampleDrivers/Basic// An example for using BipartiteGraphPartialColoringInterface to color Bipartite Graph /* How to compile this driver manually: Please make sure that "baseDir" point to the directory (folder) containing the input matrix file, and s_InputFile should point to the input file that you want to use To compile the code, replace the Main.cpp file in Main directory with this file and run "make" in ColPack installation directory. Make will generate "ColPack.exe" executable Run "ColPack.exe" Note: If you got "symbol lookup error ... undefined symbol " Please make sure that your LD_LIBRARY_PATH contains libColPack.so Any time you have trouble understanding what a routine does, how to use a routine, or what are the accepted values for a parameter, please reference the COLPACK's online documentation (temporarily located at http://www.cscapes.org/dox/ColPack/html/ ). For more information, please visit our webpage http://www.cscapes.org/coloringpage/ //*/ #include "ColPackHeaders.h" using namespace ColPack; using namespace std; #ifndef TOP_DIR #define TOP_DIR "." #endif // baseDir should point to the directory (folder) containing the input file string baseDir=TOP_DIR; //* A SHORT VERSION int main(int argc, char ** argv) { // s_InputFile = baseDir + string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx"; //Generate and color the bipartite graph BipartiteGraphPartialColoringInterface *g = new BipartiteGraphPartialColoringInterface(SRC_FILE, s_InputFile.c_str(), "AUTO_DETECTED"); //Do Partial-Distance-Two-Coloring the bipartite graph with the specified ordering g->PartialDistanceTwoColoring("SMALLEST_LAST", "ROW_PARTIAL_DISTANCE_TWO"); /*Done with coloring. Below are possible things that you may want to do after coloring: //*/ /* 1. Check Partial Distance Two Coloring result cout<<"Check Partial Distance Two coloring result ... "<CheckPartialDistanceTwoColoring() == _FALSE) cout<<" FAILED"<PrintPartialColoringMetrics(); //*/ //* 3. Get the list of colorID of colored vertices (in this case, the left side of the bipartite graph) vector vi_VertexPartialColors; g->GetVertexPartialColors(vi_VertexPartialColors); //Print Partial Colors g->PrintPartialColors(); //*/ /* 4. Get seed matrix int i_SeedRowCount = 0; int i_SeedColumnCount = 0; double** Seed = g->GetSeedMatrix(&i_SeedRowCount, &i_SeedColumnCount); //Display Seed printf("Seed matrix %d x %d \n", i_SeedRowCount, i_SeedColumnCount); displayMatrix(Seed, i_SeedRowCount, i_SeedColumnCount, 1); //*/ delete g; return 0; } //*/ ColPack-1.0.10/SampleDrivers/Basic/color_graph_using_GraphColoringInterface.cpp000066400000000000000000000075561266356121500276010ustar00rootroot00000000000000// An example for using GraphColoringInterface to color Graph /* How to compile this driver manually: Please make sure that "baseDir" point to the directory (folder) containing the input matrix file, and s_InputFile should point to the input file that you want to use To compile the code, replace the Main.cpp file in Main directory with this file and run "make" in ColPack installation directory. Make will generate "ColPack.exe" executable Run "ColPack.exe" Note: If you got "symbol lookup error ... undefined symbol " Please make sure that your LD_LIBRARY_PATH contains libColPack.so Any time you have trouble understanding what a routine does, how to use a routine, or what are the accepted values for a parameter, please reference the COLPACK's online documentation (temporarily located at http://www.cscapes.org/dox/ColPack/html/ ). For more information, please visit our webpage http://www.cscapes.org/coloringpage/ //*/ #include "ColPackHeaders.h" using namespace ColPack; using namespace std; #ifndef TOP_DIR #define TOP_DIR "." #endif // baseDir should point to the directory (folder) containing the input file string baseDir=TOP_DIR; //* A SHORT VERSION int main(int argc, char ** argv) { // s_InputFile = baseDir + string s_InputFile; //path of the input file. PICK A SYMMETRIC MATRIX!!! s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "mtx-spear-head.mtx"; //Generate and color the graph GraphColoringInterface * g = new GraphColoringInterface(SRC_FILE, s_InputFile.c_str(), "AUTO_DETECTED"); //Color the bipartite graph with the specified ordering g->Coloring("LARGEST_FIRST", "DISTANCE_TWO"); /*Done with coloring. Below are possible things that you may want to do after coloring: //*/ /* 1. Check DISTANCE_TWO coloring result cout<<"Check DISTANCE_TWO coloring result"<CheckDistanceTwoColoring(); //*/ //* 2. Print coloring results g->PrintVertexColoringMetrics(); //*/ //* 3. Get the list of colorID of vertices vector vi_VertexColors; g->GetVertexColors(vi_VertexColors); //Display vector of VertexColors printf("vector of VertexColors (size %d) \n", (int)vi_VertexColors.size()); displayVector(&vi_VertexColors[0], vi_VertexColors.size(), 1); //*/ /* 4. Get seed matrix int i_SeedRowCount = 0; int i_SeedColumnCount = 0; double** Seed = g->GetSeedMatrix(&i_SeedRowCount, &i_SeedColumnCount); //Display Seed printf("Seed matrix %d x %d \n", i_SeedRowCount, i_SeedColumnCount); displayMatrix(Seed, i_SeedRowCount, i_SeedColumnCount, 1); //*/ delete g; return 0; } //*/ /* A LONGER VERSION showing steps actually executed by the constructor. int main(int argc, char ** argv) { // s_InputFile = baseDir + string s_InputFile; //path of the input file. PICK A SYMMETRIC MATRIX!!! s_InputFile = baseDir + "bcsstk01_symmetric\\bcsstk01_symmetric.mtx"; GraphColoringInterface * g = new GraphColoringInterface(); //Read a matrix from an input file and generate a corresponding graph. //The input format will be determined based on the file extension and a correct reading routine will be used to read the file. //Note: the input matrix MUST be SYMMETRIC in order for a graph to be generated correctly // If you are new to COLPACK, pick either a .graph file (MeTiS format) or a symmetric .mtx (Matrix Market format) if ( g->ReadAdjacencyGraph(s_InputFile) == _FALSE) { cout<<"ReadAdjacencyGraph() Failed!!!"<Coloring("DISTANCE_TWO", "LARGEST_FIRST"); cout<<"Done with Coloring()"<PrintVertexColoringMetrics(); cout<<"Done with PrintVertexColoringMetrics()"< string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx"; //s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "hess_pat.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format and then ADIC format. unsigned int *** uip3_SparsityPattern = new unsigned int **; //uip3_ means triple pointers of type unsigned int double*** dp3_Value = new double**; //dp3_ means triple pointers of type double. Other prefixes follow the same notation int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"< > lsi_SparsityPattern; std::list > lvd_Value; ConvertRowCompressedFormat2ADIC( (*uip3_SparsityPattern) , rowCount, (*dp3_Value), lsi_SparsityPattern, lvd_Value); cout<<"just for debugging purpose, display the matrix in ADIC format rowCount = "<PartialDistanceTwoColoring("SMALLEST_LAST", "COLUMN_PARTIAL_DISTANCE_TWO"); //Step 2.3: From the coloring information, you can get the vector of colorIDs of left or right vertices (depend on the s_ColoringVariant that you choose) vector vi_VertexPartialColors; g->GetVertexPartialColors(vi_VertexPartialColors); *ip1_ColorCount = g->GetRightVertexColorCount(); cout<<"Finish GetVertexPartialColors()"< > lvd_NewValue; JacobianRecovery1D* jr1d = new JacobianRecovery1D; jr1d->RecoverD2Cln_ADICFormat(g, *dp3_CompressedMatrix, lsi_SparsityPattern, lvd_NewValue); cout<<"Finish Recover()"< string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; //uip3_ means triple pointers of type unsigned int double*** dp3_Value = new double**; //dp3_ means triple pointers of type double. Other prefixes follow the same notation int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<PartialDistanceTwoColoring("SMALLEST_LAST", "COLUMN_PARTIAL_DISTANCE_TWO"); //Step 2.3 (Option 1): From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of left or right vertices (depend on the s_ColoringVariant that you choose) vector vi_VertexPartialColors; g->GetVertexPartialColors(vi_VertexPartialColors); */ cout<<"Finish GenerateSeed()"<RecoverD2Cln_RowCompressedFormat(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); cout<<"Finish Recover()"< string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; //uip3_ means triple pointers of type unsigned int double*** dp3_Value = new double**; //dp3_ means triple pointers of type double. Other prefixes follow the same notation int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<PartialDistanceTwoColoring("SMALLEST_LAST", "COLUMN_PARTIAL_DISTANCE_TWO"); //Step 2.3 (Option 1): From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of left or right vertices (depend on the s_ColoringVariant that you choose) vector vi_VertexPartialColors; g->GetVertexPartialColors(vi_VertexPartialColors); */ cout<<"Finish GenerateSeed()"<RecoverD2Cln_CoordinateFormat(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); cout<<"Finish Recover()"<GetEdgeCount()); cout<<"Display *ip2_ColumnIndex"<GetEdgeCount()); cout<<"Display *dp2_JacobianValue"<GetEdgeCount()); Pause(); //Deallocate memory using functions in Utilities/MatrixDeallocation.h free_2DMatrix(uip3_SparsityPattern, rowCount); uip3_SparsityPattern=NULL; free_2DMatrix(dp3_Value, rowCount); dp3_Value=NULL; delete dp3_Seed; dp3_Seed = NULL; delete ip1_SeedRowCount; ip1_SeedRowCount=NULL; delete ip1_SeedColumnCount; ip1_SeedColumnCount = NULL; free_2DMatrix(dp3_CompressedMatrix, rowCount); dp3_CompressedMatrix = NULL; delete ip1_ColorCount; ip1_ColorCount = NULL; delete jr1d; jr1d = NULL; delete ip2_RowIndex; delete ip2_ColumnIndex; delete dp2_JacobianValue; ip2_RowIndex=NULL; ip2_ColumnIndex=NULL; dp2_JacobianValue=NULL; delete g; g=NULL; return 0; } 03_Column_compression_and_recovery_for_Jacobian_return_Sparse_Solvers_Format.cpp000066400000000000000000000143311266356121500450640ustar00rootroot00000000000000ColPack-1.0.10/SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C// An example of Column compression and recovery for Jacobian /* How to compile this driver manually: Please make sure that "baseDir" point to the directory (folder) containing the input matrix file, and s_InputFile should point to the input file that you want to use To compile the code, replace the Main.cpp file in Main directory with this file and run "make" in ColPack installation directory. Make will generate "ColPack.exe" executable Run "ColPack.exe" Note: If you got "symbol lookup error ... undefined symbol " Please make sure that your LD_LIBRARY_PATH contains libColPack.so Return by recovery routine: three vectors in "Storage Formats for the Direct Sparse Solvers" http://www.intel.com/software/products/mkl/docs/webhelp/appendices/mkl_appA_SMSF.html#mkl_appA_SMSF_1 unsigned int** ip2_RowIndex unsigned int** ip2_ColumnIndex double** dp2_JacobianValue // corresponding non-zero values //*/ #include "ColPackHeaders.h" using namespace ColPack; using namespace std; #ifndef TOP_DIR #define TOP_DIR "." #endif // baseDir should point to the directory (folder) containing the input file string baseDir=TOP_DIR; #include "extra.h" //This .h file contains functions that are used in the below examples: //ReadMM(), MatrixMultiplication...(), Times2Plus1point5(), displayMatrix() and displayCompressedRowMatrix() int main() { // s_InputFile = baseDir + string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; //uip3_ means triple pointers of type unsigned int double*** dp3_Value = new double**; //dp3_ means triple pointers of type double. Other prefixes follow the same notation int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<PartialDistanceTwoColoring( "SMALLEST_LAST", "COLUMN_PARTIAL_DISTANCE_TWO"); //Step 2.3 (Option 1): From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of left or right vertices (depend on the s_ColoringVariant that you choose) vector vi_VertexPartialColors; g->GetVertexPartialColors(vi_VertexPartialColors); */ cout<<"Finish GenerateSeed()"<RecoverD2Cln_SparseSolversFormat(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue); cout<<"Finish Recover()"<GetRowVertexCount()+1); cout<<"Display *ip2_ColumnIndex"<GetRowVertexCount()]-1); cout<<"Display *dp2_JacobianValue"<GetRowVertexCount()]-1); Pause(); //Deallocate memory using functions in Utilities/MatrixDeallocation.h free_2DMatrix(uip3_SparsityPattern, rowCount); uip3_SparsityPattern=NULL; free_2DMatrix(dp3_Value, rowCount); dp3_Value=NULL; delete dp3_Seed; dp3_Seed = NULL; delete ip1_SeedRowCount; ip1_SeedRowCount=NULL; delete ip1_SeedColumnCount; ip1_SeedColumnCount = NULL; free_2DMatrix(dp3_CompressedMatrix, rowCount); dp3_CompressedMatrix = NULL; delete ip1_ColorCount; ip1_ColorCount = NULL; delete jr1d; jr1d = NULL; delete ip2_RowIndex; delete ip2_ColumnIndex; delete dp2_JacobianValue; ip2_RowIndex=NULL; ip2_ColumnIndex=NULL; dp2_JacobianValue=NULL; delete g; g=NULL; return 0; } 04_Row_compression_and_recovery_for_Jacobian_return_Row_Compressed_Format.cpp000066400000000000000000000127331266356121500443640ustar00rootroot00000000000000ColPack-1.0.10/SampleDrivers/Matrix_Compression_and_Recovery/ADOL-C// An example of Row compression and recovery for Jacobian /* How to compile this driver manually: Please make sure that "baseDir" point to the directory (folder) containing the input matrix file, and s_InputFile should point to the input file that you want to use To compile the code, replace the Main.cpp file in Main directory with this file and run "make" in ColPack installation directory. Make will generate "ColPack.exe" executable Run "ColPack.exe" Note: If you got "symbol lookup error ... undefined symbol " Please make sure that your LD_LIBRARY_PATH contains libColPack.so Return by recovery routine: a matrix double*** dp3_NewValue //*/ #include "ColPackHeaders.h" using namespace ColPack; using namespace std; #ifndef TOP_DIR #define TOP_DIR "." #endif // baseDir should point to the directory (folder) containing the input file string baseDir=TOP_DIR; #include "extra.h" //This .h file contains functions that are used in the below examples: //ReadMM(), MatrixMultiplication...(), Times2Plus1point5(), displayMatrix() and displayCompressedRowMatrix() int main() { // s_InputFile = baseDir + string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "row-compress.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; double*** dp3_Value = new double**; int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<PartialDistanceTwoColoring("SMALLEST_LAST", "ROW_PARTIAL_DISTANCE_TWO"); //Step 2.3 (Option 1): From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of left or right vertices (depend on the s_ColoringVariant that you choose) vector vi_VertexPartialColors; g->GetVertexPartialColors(vi_VertexPartialColors); */ cout<<"Finish GenerateSeed()"<RecoverD2Row_RowCompressedFormat(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); cout<<"Finish Recover()"< string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "mtx-spear-head.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; double*** dp3_Value = new double**; int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<Coloring("SMALLEST_LAST", "STAR"); //Step 2.3 (Option 1): From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of vertices vector vi_VertexColors; g->GetVertexColors(vi_VertexColors); */ cout<<"Finish GenerateSeed()"<DirectRecover_RowCompressedFormat(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); cout<<"Finish Recover()"< string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "mtx-spear-head.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; double*** dp3_Value = new double**; int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<Coloring("SMALLEST_LAST", "STAR"); //Step 2.3 (Option 1): From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of vertices vector vi_VertexColors; g->GetVertexColors(vi_VertexColors); */ cout<<"Finish GenerateSeed()"<DirectRecover_CoordinateFormat(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_HessianValue); cout<<"Finish Recover()"< string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "mtx-spear-head.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; double*** dp3_Value = new double**; int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<Coloring("SMALLEST_LAST", "STAR"); //Step 2.3 (Option 1): From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of vertices vector vi_VertexColors; g->GetVertexColors(vi_VertexColors); */ cout<<"Finish GenerateSeed()"<DirectRecover_SparseSolversFormat(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_HessianValue); cout<<"Finish Recover()"< string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "mtx-spear-head.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; double*** dp3_Value = new double**; int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<Coloring("SMALLEST_LAST", "ACYCLIC_FOR_INDIRECT_RECOVERY"); //Step 2.3 (Option 1): From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of vertices vector vi_VertexColors; g->GetVertexColors(vi_VertexColors); */ cout<<"Finish GenerateSeed()"<IndirectRecover_RowCompressedFormat(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); cout<<"Finish Indirect Recover()"< string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; //uip3_ means triple pointers of type unsigned int double*** dp3_Value = new double**; //dp3_ means triple pointers of type double. Other prefixes follow the same notation int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<Bicoloring("SMALLEST_LAST", "IMPLICIT_COVERING__STAR_BICOLORING"); //Step 2.3 (Option 1): From the coloring information, create and return the Left and Right seed matrices (*dp3_LeftSeed) = g->GetLeftSeedMatrix(ip1_LeftSeedRowCount, ip1_LeftSeedColumnCount ); (*dp3_RightSeed) = g->GetRightSeedMatrix(ip1_RightSeedRowCount, ip1_RightSeedColumnCount ); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of left and right vertices vector vi_LeftVertexColors; g->GetLeftVertexColors(vi_LeftVertexColors); vector RightVertexColors; g->GetRightVertexColors_Transformed(RightVertexColors); */ cout<<"Finish GenerateSeed()"<DirectRecover_RowCompressedFormat(g, *dp3_LeftCompressedMatrix, *dp3_RightCompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); cout<<"Finish Recover()"< string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; //uip3_ means triple pointers of type unsigned int double*** dp3_Value = new double**; //dp3_ means triple pointers of type double. Other prefixes follow the same notation int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<PartialDistanceTwoColoring("SMALLEST_LAST", "COLUMN_PARTIAL_DISTANCE_TWO"); //Step 2.3 (Option 1): From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of left or right vertices (depend on the s_ColoringVariant that you choose) vector vi_VertexPartialColors; g->GetVertexPartialColors(vi_VertexPartialColors); */ cout<<"Finish GenerateSeed()"<RecoverD2Cln_RowCompressedFormat_unmanaged(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); /* RecoverD2Cln_RowCompressedFormat_unmanaged is called instead of RecoverD2Cln_RowCompressedFormat so that we could manage the memory deallocation for dp3_NewValue by ourselves. This way, we can reuse (*dp3_NewValue) to store new values if RecoverD2Cln_RowCompressedFormat...() need to be called again. //*/ cout<<"Finish Recover()"<RecoverD2Cln_RowCompressedFormat_usermem(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); } //Deallocate memory for 2-dimensional array (*dp3_NewValue) for(int i=0; i string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "mtx-spear-head.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; double*** dp3_Value = new double**; int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<Coloring("SMALLEST_LAST", "STAR"); //Step 2.3 (Option 1): From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of vertices vector vi_VertexColors; g->GetVertexColors(vi_VertexColors); */ cout<<"Finish GenerateSeed()"<DirectRecover_RowCompressedFormat_unmanaged(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); /* RecoverD2Cln_RowCompressedFormat_unmanaged is called instead of RecoverD2Cln_RowCompressedFormat so that we could manage the memory deallocation for dp3_NewValue by ourselves. This way, we can reuse (*dp3_NewValue) to store new values if RecoverD2Cln_RowCompressedFormat...() need to be called again. //*/ cout<<"Finish Recover()"<DirectRecover_RowCompressedFormat_usermem(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); } //Deallocate memory for 2-dimensional array (*dp3_NewValue) for(int i=0; i string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format. unsigned int *** uip3_SparsityPattern = new unsigned int **; //uip3_ means triple pointers of type unsigned int double*** dp3_Value = new double**; //dp3_ means triple pointers of type double. Other prefixes follow the same notation int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<Bicoloring("SMALLEST_LAST", "IMPLICIT_COVERING__STAR_BICOLORING"); //Step 2.3 (Option 1): From the coloring information, create and return the Left and Right seed matrices (*dp3_LeftSeed) = g->GetLeftSeedMatrix(ip1_LeftSeedRowCount, ip1_LeftSeedColumnCount ); (*dp3_RightSeed) = g->GetRightSeedMatrix(ip1_RightSeedRowCount, ip1_RightSeedColumnCount ); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of left and right vertices vector vi_LeftVertexColors; g->GetLeftVertexColors(vi_LeftVertexColors); vector RightVertexColors; g->GetRightVertexColors_Transformed(RightVertexColors); */ cout<<"Finish GenerateSeed()"<DirectRecover_RowCompressedFormat_unmanaged(g, *dp3_LeftCompressedMatrix, *dp3_RightCompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); /* RecoverD2Cln_RowCompressedFormat_unmanaged is called instead of RecoverD2Cln_RowCompressedFormat so that we could manage the memory deallocation for dp3_NewValue by ourselves. This way, we can reuse (*dp3_NewValue) to store new values if RecoverD2Cln_RowCompressedFormat...() need to be called again. //*/ cout<<"Finish Recover()"<DirectRecover_RowCompressedFormat_usermem(g, *dp3_LeftCompressedMatrix, *dp3_RightCompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); } //Deallocate memory for 2-dimensional array (*dp3_NewValue) for(int i=0; i string s_InputFile; //path of the input file s_InputFile = baseDir; s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx"; // Step 1: Determine sparsity structure of the Jacobian. // This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file, // and store the structure in a Compressed Row Format and then CSR format. unsigned int *** uip3_SparsityPattern = new unsigned int **; //uip3_ means triple pointers of type unsigned int double*** dp3_Value = new double**; //dp3_ means double pointers of type double. Other prefixes follow the same notation int rowCount, columnCount; ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount); cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<PartialDistanceTwoColoring("SMALLEST_LAST", "COLUMN_PARTIAL_DISTANCE_TWO"); //Step 2.3 (Option 1): From the coloring information, create and return the seed matrix (*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount); /* Notes: Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of left or right vertices (depend on the s_ColoringVariant that you choose) vector vi_VertexPartialColors; g->GetVertexPartialColors(vi_VertexPartialColors); */ cout<<"Finish GenerateSeed()"<RecoverD2Cln_RowCompressedFormat(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, dp3_NewValue); cout<<"Finish Recover()"< //#define cstr 406 //#define nel 5 //#define ndis 10 // => //#define cstr 4375 //#define ndis 15 // => //#define cstr 12925 //#define ndis 20 // => //#define cstr 8575 //#define ndis 30 // => n = 12780 //#define cstr 12775 //#define ndis 40 // => n = 16980 //#define cstr 16980 //#define ndis 50 // => n = 16980 //#define cstr 21175 //#define ndis 60 // => n = 25380 //#define cstr 25380 //#define nel 10 //#define ndis 10 // => n = 8755 //#define cstr 8750 //#define ndis 15 // => n = 12955 //#define cstr 25845 //#define ndis 20 // => n = 17155 //#define cstr 17150 //#define ndis 30 // => n = 25555 //#define cstr 25550 //#define ndis 40 // => n = 33955 //#define cstr 33950 //#define ndis 50 // => n = 42355 //#define cstr 84645 //#define ndis 60 // => n = 50755 //#define cstr 50750 // ad2008: #define nel 5 // 1 //#define ndis 10 // => //#define cstr 4375 // 2 #define ndis 20 // => #define cstr 8575 // 3 //#define ndis 40 // => n = 16980 //#define cstr 16975 // 4 //#define ndis 60 // => n = 25380 //#define cstr 25375 //#define nel 10 // 11 replaces 3 //#define ndis 20 // => n = 17155 //#define cstr 17150 //12 replaces 4 //#define ndis 30 // => n = 25555 //#define cstr 25550 // 5 //#define ndis 60 // => n = 50755 //#define cstr 50750 // 6 //#define nel 15 //#define ndis 60 // => n = 76115 //#define cstr 76120 // 7 //#define nel 20 //#define ndis 60 // => n = 101505 //#define cstr 101495 // 8 //#define nel 30 //#define ndis 60 // => n = 152255 //#define cstr 152245 // 9 //#define nel 40 //#define ndis 80 // => n = 270205 //#define cstr 270195 // 10 //#define nel 60 //#define ndis 100 // => n = 506105 //#define cstr 506095 #define n1 1 #define n2 2 #define n3 2 #define n4 1 #define ncol 6 #define nex (ndis * n1) #define nfe ((n1 + n2) * ndis) #define nra ((n1 + n2 + n3) * ndis) #define nde ((n1 + n2 + n3 + n4) * ndis) #define pex 0.95 #define pra 0.95 #define kA (2*ndis) #define kB ndis #define cFEA 0.1 #define cFEB 0.1 #define qmax 2 double kk = 0; double omega[3][3]; double h[nel]; //****************************************************************** // Initialize dimensions void init_dim(int *n, int *m) { // cA, cB,cAdot, cBdot cA0 cB0 m*A,m*B,m*Adot,m*Bdot m*A0,m*B0 *n = 5 + 4*(nde*nel*3) + 2*(nde*nel) + 8*(nel*3) + 4*nel + 2*nel*3 + nel; // mfe,mfedot mfe0 *m = cstr-5; } //****************************************************************** // Initialize starting point x void init_startpoint(double *x, int n) { int i,j,l; int index; omega[0][0] = 0.19681547722366; omega[0][1] = 0.39442431473909; omega[0][2] = 0.37640306270047; omega[1][0] =-0.06553542585020; omega[1][1] = 0.29207341166523; omega[1][2] = 0.51248582618842; omega[2][0] = 0.02377097434822; omega[2][1] =-0.04154875212600; omega[2][2] = 0.11111111111111; for(i=0;i colors_C; // colors_C: colors vector (using ColPack?) //string s_InputFile = "test_mat.mtx"; string s_InputFile = "jac_pat.mtx"; unsigned int *rb=NULL; /* dependent variables */ unsigned int *cb=NULL; /* independent variables */ unsigned int **JP=NULL; /* compressed block row storage */ //JP: Jacobian Pattern JP = (unsigned int **) malloc(m*sizeof(unsigned int*)); unsigned int **JP2=NULL; /* compressed block row storage */ //JP2: also Jacobian Pattern JP2 = (unsigned int **) malloc(m*sizeof(unsigned int*)); int ctrl[2]; ctrl[0] = 0; ctrl[1] = 0; //ctrl[2]: for jac_pat(tag_c, m, n, x, JP, ctrl); //control options double tg_C,ts_C; //tg_C: time to read the input file and generate Graph (using ColPack) //ts_C: time to color and generate the seed matrix using ColPack BipartiteGraphPartialColoringInterface * gGraph = new BipartiteGraphPartialColoringInterface(); ColPack-1.0.10/SampleDrivers/Matrix_Compression_and_Recovery/SMB/sparse_jac_hess.cpp000066400000000000000000000220331266356121500305020ustar00rootroot00000000000000#include "math.h" #include "stdlib.h" #include "stdio.h" #include "adolc.h" #include "sparse/sparsedrivers.h" #define repnum 10 //------------------------------------------------------------------------------------ // for time measurements #include #include "ColPackHeaders.h" using namespace ColPack; double k_getTime() { struct timeval v; struct timezone z; gettimeofday(&v, &z); return ((double)v.tv_sec)+((double)v.tv_usec)/1000000; } //------------------------------------------------------------------------------------ // required for second method using namespace std; #include #include #include #include //------------------------------------------------------------------------------------ // as before #define tag_f 1 #define tag_red 2 #define tag_HP 3 #define tag_c 4 // problem definition -> eval_fun.c void init_dim(int *n, int *m); void init_startpoint(double *x, int n); double feval(double *x, int n); adouble feval_ad(double *x, int n); void ceval(double *x, double *c, int n); void ceval_ad(double *x, adouble *c, int n); adouble feval_ad_mod(double *x, int n); adouble feval_ad_modHP(double *x, int n); void printmat(char* kette, int n, int m, double** M); void printmatint(char* kette, int n, int m, int** M); void printmatint_c(char* kette, int m,unsigned int** M); int main() { int i, j, k, l, sum, n, m, nnz, direct = 1, found; double f; double *x, *c; adouble fad, *xad, *cad; //double** Zpp; //double** Zppf; double** J; //double* s; //int p_H_dir, p_H_indir; size_t tape_stats[11]; int num; FILE *fp_JP; double **Seed_J; double **Jc; int p_J; int recover = 1; int jac_vec = 1; int compute_full = 1; int output_sparsity_pattern_J = 0; //int output_sparsity_pattern_H = 1; //int use_direct_method = 1; //int output_direct = 0; //int use_indirect_method = 1; //int output_indirect = 0; double t_f_1, t_f_2, div_f=0, div_c=0, div_JP=0, div_JP2=0, div_Seed=0, div_Seed_C=0, div_Jc=0, div_Jc_C=0, div_rec=0, div_rec_C=0, div_J=0; //double test; unsigned int *rind; unsigned int *cind; double *values; //tring s_InputFile = "test_mat.mtx"; //string s_InputFile = "jac_pat.mtx"; //------------------------------------------------------------------------------------ // problem definition + evaluation init_dim(&n,&m); // initialize n and m printf(" n = %d m = %d\n",n,m); x = (double*) malloc(n*sizeof(double)); // x: vector input for function evaluation c = (double*) malloc(m*sizeof(double)); // c: constraint vector cad = new adouble[m]; init_startpoint(x,n); t_f_1 = k_getTime(); for(i=0;i>= f; trace_off(); trace_on(tag_c); ceval_ad(x, cad, n); //ceval_ad: derivative of ceval for(i=0;i>= f; trace_off(); //return 1; tapestats(tag_c,tape_stats); // reading of tape statistics printf("\n independents %ld\n",(long)tape_stats[0]); printf(" dependents %ld\n",(long)tape_stats[1]); printf(" operations %ld\n",(long)tape_stats[5]); printf(" buffer size %ld\n",(long)tape_stats[4]); printf(" maxlive %ld\n",(long)tape_stats[2]); printf(" valstack size %ld\n\n",(long)tape_stats[3]); //------------------------------------------------------------------------------------ // full Jacobian: div_J = -1; if(compute_full == 1) { J = myalloc2(m,n); t_f_1 = k_getTime(); jacobian(tag_c,m,n,x,J); t_f_2 = k_getTime(); div_J = (t_f_2 - t_f_1); printf("XXX The time needed for full Jacobian: %10.6f \n \n", div_J); printf("XXX runtime ratio: %10.6f \n \n", div_J/div_c); //save the matrix into a file (non-zero entries only) fp_JP = fopen("jac_full.mtx","w"); fprintf(fp_JP,"%d %d\n",m,n); for (i=0;iPrintBipartiteGraph(); t_f_2 = k_getTime(); printf("XXX STEP 2: The time needed for Graph construction: %10.6f \n \n", (t_f_2-t_f_1) ); printf("XXX STEP 2: runtime ratio: %10.6f \n \n", (t_f_2-t_f_1)/div_c); t_f_1 = k_getTime(); //gGraph->GenerateSeedJacobian(&Seed_J, &dummy, &p_J, // "NATURAL", "COLUMN_PARTIAL_DISTANCE_TWO"); gGraph->PartialDistanceTwoColoring("NATURAL", "COLUMN_PARTIAL_DISTANCE_TWO"); t_f_2 = k_getTime(); printf("XXX STEP 2: The time needed for Coloring: %10.6f \n \n", (t_f_2-t_f_1)); printf("XXX STEP 2: runtime ratio: %10.6f \n \n", (t_f_2-t_f_1)/div_c); t_f_1 = k_getTime(); Seed_J = gGraph->GetSeedMatrix(&dummy, &p_J); t_f_2 = k_getTime(); tg_C = t_f_2 - t_f_1; printf("XXX STEP 2: The time needed for Seed generation: %10.6f \n \n", tg_C); printf("XXX STEP 2: runtime ratio: %10.6f \n \n", tg_C/div_c); //*/ //------------------------------------------------------------------------------------ // STEP 3: Jacobian-matrix product: // ADOL-C: //* if (jac_vec == 1) { Jc = myalloc2(m,p_J); t_f_1 = k_getTime(); printf(" hier 1\n"); fov_forward(tag_c,m,n,p_J,x,Seed_J,c,Jc); printf(" hier 2\n"); t_f_2 = k_getTime(); div_Jc = (t_f_2 - t_f_1); printf("XXX STEP 3: The time needed for Jacobian-matrix product: %10.6f \n \n", div_Jc); printf("XXX STEP 3: runtime ratio: %10.6f \n \n", div_Jc/div_c); } //------------------------------------------------------------------------------------ // STEP 4: computed Jacobians/ recovery if (recover == 1) { JacobianRecovery1D jr1d; printf("m = %d, n = %d, p_J = %d \n",m,n,p_J); //printmatint_c("JP Jacobian Pattern",m,JP); //printmat("Jc Jacobian compressed",m,p_J,Jc); t_f_1 = k_getTime(); jr1d.RecoverD2Cln_CoordinateFormat (gGraph, Jc, JP, &rind, &cind, &values); t_f_2 = k_getTime(); div_rec_C = (t_f_2 - t_f_1); printf("XXX STEP 4: The time needed for Recovery: %10.6f \n \n", div_rec_C); printf("XXX STEP 4: runtime ratio: %10.6f \n \n", div_rec_C/div_c); //save recovered matrix into file fp_JP = fopen("jac_recovered.mtx","w"); fprintf(fp_JP,"%d %d %d\n",m,n,nnz); for (i=0;i. ************************************************************************************/ #include "Definitions.h" #include "CoutLock.h" namespace ColPack { #ifdef _OPENMP omp_lock_t CoutLock::coutLock; #endif int CoutLock::unset() { #ifdef _OPENMP omp_unset_lock(&CoutLock::coutLock); #endif return 0; } int CoutLock::set() { #ifdef _OPENMP omp_set_lock(&CoutLock::coutLock); #endif return 0; } } ColPack-1.0.10/Utilities/CoutLock.h000066400000000000000000000027431266356121500167710ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #ifndef COUTLOCK_H #define COUTLOCK_H #ifdef _OPENMP #include #endif namespace ColPack { /** @ingroup group4 * @brief class CoutLock in @link group4@endlink. The CoutLock class is used in a multi-thread environment to support printing strings to standard output in a readable manner. Here is how you do cout: CoutLock::set(); cout<<"blah blah blah"<. ************************************************************************************/ #include #include using namespace std; #include "Definitions.h" #include "DisjointSets.h" namespace ColPack { //Public Constructor 4251 DisjointSets::DisjointSets() { } //Public Constructor 4252 DisjointSets::DisjointSets(int li_SetSize) { p_vi_Nodes.clear(); p_vi_Nodes.resize((unsigned) li_SetSize, _UNKNOWN); } //Public Destructor 4253 DisjointSets::~DisjointSets() { p_vi_Nodes.clear(); } //Public Function 4254 int DisjointSets::SetSize(int li_SetSize) { p_vi_Nodes.clear(); p_vi_Nodes.resize((unsigned) li_SetSize, _UNKNOWN); return(_TRUE); } //Public Function 4255 int DisjointSets::Count() { int i; int li_SetSize, li_HeadCount; li_SetSize = (signed) p_vi_Nodes.size(); li_HeadCount = _FALSE; for(i=0; i. ************************************************************************************/ #ifndef DISJOINTSETS_H #define DISJOINTSETS_H using namespace std; namespace ColPack { /** @ingroup group4 * @brief class DisjointSets in @link group4@endlink. The disjoint set class is used by ColPack to store and operate on disjoint sets of edges identified by integer numbers. A disjoint set class can be instantiated by specifying the maximum number of such sets to be stored. The elements in a set are stored as a tree and the identifier of the set (SetID) is the identifier of the root. The size of the tree is stored in the root and the parent of an element is stored in the element. The tree is implemented simply as a vector of integers the indices being the identifiers of the elements. */ class DisjointSets { private: vector p_vi_Nodes; public: //Public Constructor 4251 DisjointSets(); //Public Constructor 4252 DisjointSets(int); //Public Destructor 4253 ~DisjointSets(); //Public Function 4254 /// Set the size of this DisjointSets object, i.e. resize the vector p_vi_Nodes int SetSize(int); //Public Function 4255 /// Count the number of sets contained by this DisjointSets object int Count(); //Public Function 4256 /// Print out the elements' ID and their values (i.e., p_vi_Nodes's IDs and values) int Print(); //Public Function 4257 /// Find the Set ID of this element int Find(int); //Public Function 4258 /// Find the Set ID of this element, also shorten the tree by updating all elements with its new SetID int FindAndCompress(int); //Public Function 4259 /// Union li_SetOne with li_SetTwo by seting li_SetOne to be the parent of li_SetTwo /** Return the SetID of the new set. In this case, SetID will be li_SetOne */ int Union(int li_SetOne, int li_SetTwo); //Public Function 4260 /// Union li_SetOne with li_SetTwo by their ranks /** Rank: the upper bound on the height of the tree (or set) The root of each set will hold its the negate of its set rank i.e. rank of set 2 is (-p_vi_Nodes[2]) Note: UnionByRank() and UnionBySize() can not be used together to solve the same problem due to the different meaning of the root's value */ int UnionByRank(int li_SetOne, int li_SetTwo); //Public Function 4261 /// Union li_SetOne with li_SetTwo by their sizes /** The root of each set will hold its the negate of its set size i.e. size of set 2 is (-p_vi_Nodes[2]) Note: UnionByRank() and UnionBySize() can not be used together to solve the same problem due to the different meaning of the root's value */ int UnionBySize(int li_SetOne, int li_SetTwo); }; } #endif ColPack-1.0.10/Utilities/File.cpp000066400000000000000000000070131266356121500164530ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include #include "Definitions.h" #include "File.h" using namespace std; namespace ColPack { File::File() { path = ""; name = ""; fileExtension = ""; } File::File(string fileName) { path = ""; name = ""; fileExtension = ""; Parse(fileName); } string File::GetPath() const {return path;} string File::GetName() const {return name;} string File::GetFileExtension() const {return fileExtension;} string File::GetFullName() const {return name+"."+fileExtension;} void File::SetPath(string newPath) {path = newPath;} void File::SetName(string newName) {name = newName;} void File::SetFileExtension(string newFileExtension) {fileExtension = newFileExtension;} void File::Parse(string fileName) { string::size_type result; //1. see if the fileName is given in full path result = fileName.rfind(DIR_SEPARATOR, fileName.size() - 1); if(result != string::npos) {//found the path (file prefix) //get the path, including the last DIR_SEPARATOR path = fileName.substr(0,result+1); //remove the path from the fileName fileName = fileName.substr(result+1); } //2. see if the fileName has file extension. For example ".mtx" result = fileName.rfind('.', fileName.size() - 1); if(result != string::npos) {//found the fileExtension //get the fileExtension excluding the '.' fileExtension = fileName.substr(result+1); //remove the fileExtension from the fileName fileName = fileName.substr(0,result); } //3. get the name of the input file name = fileName; } bool isMatrixMarketFormat(string s_fileExtension) { if (s_fileExtension == "mtx") return true; return false; } bool isHarwellBoeingFormat(string s_fileExtension){ if (s_fileExtension == "hb" || ( s_fileExtension.size()==3 && ( // First Character of the Extension s_fileExtension[0] == 'r' || // Real matrix s_fileExtension[0] == 'c' || // Complex matrix s_fileExtension[0] == 'p' // Pattern only (no numerical values supplied) ) && ( // Second Character of the Extension s_fileExtension[1] == 's' || // Symmetric s_fileExtension[1] == 'u' || // Unsymmetric s_fileExtension[1] == 'h' || // Hermitian s_fileExtension[1] == 'g' || // Skew symmetric s_fileExtension[1] == 'r' // Rectangular ) && ( // Third Character of the Extension s_fileExtension[2] == 'a' || // Assembled s_fileExtension[2] == 'e' // Elemental matrices (unassembled) )) ) return true; return false; } bool isMeTiSFormat(string s_fileExtension){ if (s_fileExtension == "graph") return true; return false; } } ColPack-1.0.10/Utilities/File.h000066400000000000000000000045241266356121500161240ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #ifndef FILE_H #define FILE_H #include using namespace std; //#undef _WIN32 //define system-dependent directory separator #ifdef _WIN32 //Windows #define DIR_SEPARATOR "\\" #else //*nix #define DIR_SEPARATOR "/" #endif namespace ColPack { /** @ingroup group4 * @brief class File in @link group4@endlink. The File class is used to process file name. It should work on both Windows and *nix. A File object will take a file name, parse and separate it into 3 parts: path (name prefix), name, and file extension. */ class File { private: string path; //including the last DIR_SEPARATOR string name; string fileExtension; //excluding the '.' public: File(); File(string fileName); void Parse(string newFileName); string GetPath() const; string GetName() const; ///GetFileExtension excluding the '.' string GetFileExtension() const; string GetFullName() const; void SetPath(string newPath); void SetName(string newName); void SetFileExtension(string newFileExtension); }; ///Tell whether or not the file format is MatrixMarket from its extension bool isMatrixMarketFormat(string s_fileExtension); ///Tell whether or not the file format is HarwellBoeing from its extension bool isHarwellBoeingFormat(string s_fileExtension); ///Tell whether or not the file format is MeTiS from its extension bool isMeTiSFormat(string s_fileExtension); } #endif ColPack-1.0.10/Utilities/MatrixDeallocation.cpp000066400000000000000000000035371266356121500213660ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "MatrixDeallocation.h" int MatrixDeallocation_SparseSolversFormat(unsigned int **ip2_RowIndex, unsigned int **ip2_ColumnIndex, double **dp2_JacobianValue) { //Deallocate the arrays delete[] (*ip2_RowIndex); delete ip2_RowIndex; delete[] (*ip2_ColumnIndex); delete ip2_ColumnIndex; delete[] (*dp2_JacobianValue); delete dp2_JacobianValue; return _TRUE; } int MatrixDeallocation_RowCompressedFormat(double ***dp3_HessianValue, unsigned int i_numOfRows) { //Deallocate the 2D Matrix free_2DMatrix(dp3_HessianValue, i_numOfRows); return _TRUE; } int MatrixDeallocation_CoordinateFormat(unsigned int **ip2_RowIndex, unsigned int **ip2_ColumnIndex, double **dp2_HessianValue) { //Deallocate the arrays delete[] (*ip2_RowIndex); delete ip2_RowIndex; delete[] (*ip2_ColumnIndex); delete ip2_ColumnIndex; delete[] (*dp2_HessianValue); delete dp2_HessianValue; return _TRUE; } ColPack-1.0.10/Utilities/MatrixDeallocation.h000066400000000000000000000051421266356121500210250ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "Definitions.h" #ifndef MATRIXDEALLOCATION_H #define MATRIXDEALLOCATION_H /// Deallocate all the memory reserved for a matrix presented in Sparse Solvers Format /** Postcondition: - ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue become dangling pointers. So for safety reasons, please set ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue to NULL after calling this function. */ int MatrixDeallocation_SparseSolversFormat(unsigned int **ip2_RowIndex, unsigned int **ip2_ColumnIndex, double **dp2_JacobianValue); /// Deallocate all the memory reserved for a matrix presented in ADOLC Format /** Postcondition: - dp3_HessianValue become dangling pointers. So for safety reasons, please set dp3_HessianValue to NULL after calling this function. */ int MatrixDeallocation_RowCompressedFormat(double ***dp3_HessianValue, unsigned int i_numOfRows); /** Deallocate all the memory reserved for a matrix presented in Coordinate Format Postcondition: - ip2_RowIndex, ip2_ColumnIndex, dp2_HessianValue become dangling pointers. So for safety reasons, please set ip2_RowIndex, ip2_ColumnIndex, dp2_HessianValue to NULL after calling this function. */ int MatrixDeallocation_CoordinateFormat(unsigned int **ip2_RowIndex, unsigned int **ip2_ColumnIndex, double **dp2_HessianValue); template int free_2DMatrix(T **dp2_2DMatrix, unsigned int i_numOfRows) { for(unsigned int i=0; i< i_numOfRows; i++) { delete[] (dp2_2DMatrix)[i]; } delete[] (dp2_2DMatrix); return _TRUE; } template int free_2DMatrix(T ***dp3_2DMatrix, unsigned int i_numOfRows) { free_2DMatrix(*dp3_2DMatrix,i_numOfRows); delete dp3_2DMatrix; return _TRUE; } #endif ColPack-1.0.10/Utilities/Pause.cpp000066400000000000000000000021731266356121500166530ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ //Special pause that work on both Windows and UNIX for both C and C++ #include "Pause.h" using namespace std; void Pause() { printf("Press enter to continue ..."); getchar(); } ColPack-1.0.10/Utilities/Pause.h000066400000000000000000000021021266356121500163100ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include #include //Special pause that work on both Windows and UNIX for both C and C++ void Pause(); ColPack-1.0.10/Utilities/StringTokenizer.cpp000066400000000000000000000144161266356121500207420ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include #include using namespace std; #include "Definitions.h" #include "StringTokenizer.h" namespace ColPack { //Public Constructor 4151 StringTokenizer::StringTokenizer() { } //Public Constructor 4152 StringTokenizer::StringTokenizer(char * InputChar) { string TempInputString(InputChar); InputString = TempInputString; TokenString = InputString; } //Public Constructor 4153 StringTokenizer::StringTokenizer(char * InputChar, char * DelimiterChar) { string TempInputString(InputChar); string TempDelimiterString(DelimiterChar); InputString = TempInputString; TokenString = InputString; DelimiterString = TempDelimiterString; } //Public Constructor 4154 StringTokenizer::StringTokenizer(string InputChar, char * DelimiterChar) { string TempDelimiterString(DelimiterChar); InputString = InputChar; TokenString = InputString; DelimiterString = TempDelimiterString; } //Public Constructor 4155 StringTokenizer::StringTokenizer(string InputChar, string DelimiterChar) { InputString = InputChar; TokenString = InputString; DelimiterString = DelimiterChar; } //Public Destructor 4156 StringTokenizer::~StringTokenizer() { } //Public Function 4157 int StringTokenizer::CountTokens() { int TokenCounter = 1; int DelimiterPosition; int LastPosition; int TokenStringLength = TokenString.size(); int DelimiterStringLength = DelimiterString.size(); string DelimiterSubString; if(TokenStringLength == 0) { return(0); } if(DelimiterStringLength == 0) { return(1); } DelimiterPosition = 0; LastPosition = 0; for ( ; ; ) { DelimiterPosition = TokenString.find(DelimiterString, DelimiterPosition); if(DelimiterPosition == 0) { DelimiterPosition += DelimiterStringLength; continue; } if((DelimiterPosition < 0) || (DelimiterPosition == TokenStringLength)) { return(TokenCounter); } if(DelimiterStringLength != (DelimiterPosition - LastPosition)) { // cout<<"Delimiter Position = "<. ************************************************************************************/ #ifndef STRINGTOKENIZER_H #define STRINGTOKENIZER_H using namespace std; namespace ColPack { /** @ingroup group4 * @brief class StringTokenizer in @link group4@endlink. The string tokenizer class is provided as an utility class to assist in reading various matrix and graph format files. As an input file is read line by line as strings, this class is used to tokenize the lines with one or more tokenizing strings which are generally the separators used in the input file. The string tokens are then restored to the intended data format without losing the actual precision of the original data. A string tokenizer class can be instantiated with an input string and an input tokenizer string or character array. */ class StringTokenizer { private: string DelimiterString; string InputString; string TokenString; public: //Public Constructor 4151 StringTokenizer(); //Public Constructor 4152 StringTokenizer(char *); //Public Constructor 4153 StringTokenizer(char *, char *); //Public Constructor 4154 StringTokenizer(string, char *); //Public Constructor 4155 StringTokenizer(string, string); //Public Destructor 4156 ~StringTokenizer(); //Public Function 4157 int CountTokens(); //Public Function 4158 int CountTokens(char *); //Public Function 4159 string GetDelimiterString() const; //Public Function 4160 string GetFirstToken(); //Public Function 4161 string GetInputString() const; //Public Function 4162 string GetLastToken(); //Public Function 4163 string GetNextToken(); //Public Function 4164 string GetNextToken(char *); //Public Function 4165 string GetToken(int); //Public Function 4166 int HasMoreTokens(); //Public Function 4167 int HasMoreTokens(char *); //Public Function 4168 int SetInputString(char *); //Public Function 4169 int SetDelimiterString(char *); }; } #endif ColPack-1.0.10/Utilities/Timer.cpp000066400000000000000000000047461266356121500166660ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ //using namespace std; #include "Definitions.h" #include "Timer.h" namespace ColPack { //Public Constructor 4351 Timer::Timer() { } //Public Destructor 4352 Timer::~Timer() { } //Public Function 4354 void Timer::Start() { #ifdef SYSTEM_TIME ct_BeginTimer = times(&tms_BeginTimer); #else ct_BeginTimer = clock(); #endif } //Public Function 4355 void Timer::Stop() { #ifdef SYSTEM_TIME ct_EndTimer = times(&tms_EndTimer); #else ct_EndTimer = clock(); #endif } //Public Function 4356 double Timer::GetWallTime() { #ifdef SYSTEM_TIME return (double)(ct_EndTimer - ct_BeginTimer) / CLK_TCK; #else return (double)(ct_EndTimer - ct_BeginTimer) / CLOCKS_PER_SEC; #endif } //Public Function 4357 double Timer::GetProcessorTime() { #ifdef SYSTEM_TIME double t_UserTime = (double) (tms_EndTimer.tms_utime - tms_BeginTimer.tms_utime) / CLK_TCK; double t_SystemTime = (double) (tms_EndTimer.tms_stime - tms_BeginTimer.tms_stime) / CLK_TCK; return(t_UserTime + t_SystemTime); #else return(_UNKNOWN); #endif } //Public Function 4358 double Timer::GetUserProcessorTime() { #ifdef SYSTEM_TIME double t_UserTime = (double)(tms_EndTimer.tms_utime - tms_BeginTimer.tms_utime) / CLK_TCK; return(t_UserTime); #else return(_UNKNOWN); #endif } //Public Function 4359 double Timer::GetSystemProcessorTime() { #ifdef SYSTEM_TIME double t_SystemTime = (double)(tms_EndTimer.tms_stime - tms_BeginTimer.tms_stime) / CLK_TCK; return(t_SystemTime); #else return(_UNKNOWN); #endif } } ColPack-1.0.10/Utilities/Timer.h000066400000000000000000000052021266356121500163170ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "Definitions.h" #ifdef SYSTEM_TIME #include #ifndef CLK_TCK #define CLK_TCK 100 #endif #else #include #endif #ifndef TIMER_H #define TIMER_H namespace ColPack { /** @ingroup group4 * @brief class Timer in @link group4@endlink. The timer class is the only class in ColPack which has an optional dependency on the operating system. It offers both system independent C++ timer based on ctime.h or linux/unix dependent timer based on sys/times.h. The sytem independent timer only gives wall clock time while linux/unix dependent timer gives wall, processor, user and system times. */ class Timer { private: /// UNIX only. Used to measure longer execution time. /** Define SYSTEM_TIME to measure the execution time of a program which may run for more than 30 minutes (35.79 minutes or 2,147 seconds to be accurate) Reason: In UNIX, CLOCKS_PER_SEC is defined to be 1,000,000 (In Windows, CLOCKS_PER_SEC == 1,000). The # of clock-ticks is measured by using variables of type int => max value is 2,147,483,648. Time in seconds = # of clock-ticks / CLOCKS_PER_SEC => max Time in seconds = 2,147,483,648 / 1,000,000 ~= 2,147 */ #ifdef SYSTEM_TIME struct tms tms_BeginTimer; struct tms tms_EndTimer; #endif clock_t ct_BeginTimer; clock_t ct_EndTimer; public: //Public Constructor 4351 Timer(); //Public Destructor 4352 ~Timer(); //Public Function 4354 void Start(); //Public Function 4355 void Stop(); //Public Function 4356 double GetWallTime(); //Public Function 4357 double GetProcessorTime(); //Public Function 4358 double GetUserProcessorTime(); //Public Function 4359 double GetSystemProcessorTime(); }; } #endif ColPack-1.0.10/Utilities/command_line_parameter_processor.cpp000066400000000000000000000024011266356121500243540ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include "command_line_parameter_processor.h" void createArgs(int argc, const char* argv[], vector& arg) { for(int i=0;i& arg) { for (unsigned int i=0; i. ************************************************************************************/ #include #include #include using namespace std; /*Convert command line parameters to vector arg for easiness Input: argc, argv Output: arg Precondition: arg is empty */ void createArgs(int argc, const char* argv[], vector& arg); //find argument in vector arg int findArg(string argument, vector& arg); //SAMPLE main.cpp /* #include "command_line_parameter_processor.h" using namespace std; int commandLineProcessing(vector& arg); int main(int argc, const char* argv[] ) { vector arg; //get the list of arguments createArgs(argc, argv, arg); //process those arguments commandLineProcessing(arg); //... return 0; } int commandLineProcessing(vector& arg) { int num=findArg("-r", arg); if (num!=-1) //argument is found, do something { //... } if (findArg("-append", arg) != -1 || findArg("-app", arg) != -1) //append output to the existing file { output_append = true; } //"-suffix" has priority over "-suf", i.e., if both "-suffix" and "-suf" are specified, "-suffix " will be used int result; result = findArg("-suffix", arg); if (result == -1) result = findArg("-suf", arg); if (result != -1) //suffix is specified { output_suffix = arg[result+1]; } return 0; } //*/ ColPack-1.0.10/Utilities/current_time.cpp000066400000000000000000000022001266356121500202650ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #include #include using namespace std; #include "current_time.h" void current_time() { time_t curr=time(0); cout << "Current time is: " << ctime(&curr) <. ************************************************************************************/ #ifndef CURRENT_TIME_H #define CURRENT_TIME_H // Display current time void current_time(); #endif ColPack-1.0.10/Utilities/extra.cpp000066400000000000000000001334751266356121500167330ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ #ifndef EXTRA_CPP #define EXTRA_CPP #include "extra.h" #include "Pause.h" #include "mmio.h" #include int WriteMatrixMarket_ADOLCInput(string s_postfix, int i_mode, ...) { unsigned int ** uip2_SparsityPattern; int i_Matrix_Row; int i_Matrix_Col; double** dp2_CompressedMatrix; int i_CompressedMatrix_Row; int i_CompressedMatrix_Col; double** dp2_Values; string s_BaseName = "-ColPack_debug.mtx"; va_list ap; /*will point to each unnamed argument in turn*/ va_start(ap,i_mode); /* point to first element after i_mode*/ if (i_mode == 0) { uip2_SparsityPattern = va_arg(ap,unsigned int **); i_Matrix_Row = va_arg(ap,int); i_Matrix_Col = va_arg(ap,int); string s_MatrixName = "pattern"+s_postfix+s_BaseName; ofstream out_Matrix (s_MatrixName.c_str()); if(!out_Matrix) { cout<<"Error creating file: \""< > *graph, vector* vi_VertexColors,int i_RunInBackground , int filter ) { static int ranNum = rand(); static int seq = 0; seq++; vector ListOfColors = getListOfColors(""); string fileName = "/tmp/."; fileName = fileName + "ColPack_"+ itoa(ranNum)+"_"+itoa(seq)+".dot"; //build the dot file of the graph if(vi_VertexColors == NULL) { //build dot file represents graph without color info buildDotWithoutColor(graph, ListOfColors, fileName); } else { //build dot file represents graph with color buildDotWithColor(graph, vi_VertexColors, ListOfColors, fileName); } //display the graph using xdot string command; switch (filter) { case NEATO: command="xdot -f neato "; break; case TWOPI: command="xdot -f twopi "; break; case CIRCO: command="xdot -f circo "; break; case FDP: command="xdot -f fdp "; break; default: command="xdot -f dot "; // case DOT } command = command + fileName; if(i_RunInBackground) command = command + " &"; int i_ReturnValue = system(command.c_str()); return i_ReturnValue; } int buildDotWithoutColor(map< int, map > *graph, vector &ListOfColors, string fileName) { cerr<<"IN buildDotWithoutColor"< >::iterator itr = graph->begin(); for(; itr != graph->end(); itr++) { map::iterator itr2 = (itr->second).begin(); for(; itr2 != (itr->second).end(); itr2++) { if(itr2->first<=itr->first) continue; line = ""; line = line + "v"+itoa(itr->first)+" -- v"+ itoa(itr2->first) +" ;"; OutputStream< > *graph, vector* vi_VertexColors, vector &ListOfColors, string fileName) { cerr<<"IN buildDotWithColor"< m_vi_Vertices, m_vi_Edges, m_vi_VertexColors; //g.GetVertices(m_vi_Vertices); //g.GetEdges(m_vi_Edges); //g.GetVertexColors(m_vi_VertexColors); //int i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); int i_NumberOfColors = ListOfColors.size(); string line="", color_str="", colorID_str="", colorID_str2=""; //build header OutputStream<<"graph g {"< >::iterator itr = graph->begin(); for(; itr != graph->end(); itr++) { line=""; if((*vi_VertexColors)[itr->first] != _UNKNOWN) { color_str = ListOfColors[(*vi_VertexColors)[itr->first]%i_NumberOfColors]; colorID_str = itoa((*vi_VertexColors)[itr->first]); } else { color_str="green"; colorID_str = "_"; } //a_1 [color=aliceblue] line = line + "v"+itoa(itr->first)+"_c"+ colorID_str +" [style=filled fillcolor="+color_str+"]"; OutputStream<begin(); for(; itr != graph->end(); itr++) { map::iterator itr2 = (itr->second).begin(); for(; itr2 != (itr->second).end(); itr2++) { if(itr2->first <= itr->first) continue; if((*vi_VertexColors)[itr->first] != _UNKNOWN) { colorID_str = itoa((*vi_VertexColors)[itr->first]); } else { colorID_str = "_"; } if((*vi_VertexColors)[itr2->first] != _UNKNOWN) { colorID_str2 = itoa((*vi_VertexColors)[itr2->first]); } else { colorID_str2 = "_"; } line = ""; line = line + "v"+itoa(itr->first)+"_c"+colorID_str+" -- v"+ itoa(itr2->first)+"_c"+colorID_str2 ; OutputStream<=0; i--) { if(num_string[i] == 'D') { num_string[i]='E'; return 1; } } return 0; } string itoa(int i) { string s; stringstream out; out << i; s = out.str(); return s; } vector getListOfColors(string s_InputFile) { if (s_InputFile.size()==0 || s_InputFile == "" ) s_InputFile="list_of_colors.txt"; ifstream InputStream (s_InputFile.c_str()); if(!InputStream){ cout<<"Not Found File "< ListOfColors; while(!InputStream.eof() && line != "*") { ListOfColors.push_back(line); getline(InputStream, line); } return ListOfColors; } int buildDotWithoutColor(ColPack::BipartiteGraphPartialColoringInterface &g, vector &ListOfColors, string fileName) { cerr<<"IN buildDotWithoutColor - BipartiteGraphPartialColoring"< m_vi_Vertices, m_vi_Edges; g.GetLeftVertices(m_vi_Vertices); g.GetEdges(m_vi_Edges); int i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); string line=""; //build header OutputStream<<"graph g {"< &ListOfColors, string fileName) { cerr<<"IN buildDotWithColor - BipartiteGraphPartialColoringInterface"< m_vi_Vertices, m_vi_Edges, m_vi_LeftVertexColors, m_vi_RightVertexColors; g.GetLeftVertices(m_vi_Vertices); //cout<<"displayVector(m_vi_Vertices);"<0) { color_str = ListOfColors[m_vi_LeftVertexColors[i]%i_NumberOfColors]; //v2_c4 [color=aliceblue] line = line + "v"+itoa(i)+"_c"+itoa(m_vi_LeftVertexColors[i])+" [style=filled fillcolor="+color_str+"]"; } else { color_str = ListOfColors[0]; line = line + "v"+itoa(i)+"_c_"+" [style=filled fillcolor="+color_str+"]"; } OutputStream<0) { color_str = ListOfColors[m_vi_RightVertexColors[i]%i_NumberOfColors]; //v2_c4 [color=aliceblue] line = line + "v"+itoa(i+i_VertexCount)+"_c"+itoa(m_vi_RightVertexColors[i])+" [style=filled fillcolor="+color_str+"]"; } else { color_str = ListOfColors[0]; line = line + "v"+itoa(i+i_VertexCount)+"_c_"+" [style=filled fillcolor="+color_str+"]"; } OutputStream< m_vi_ConflictEdges; /* vector > ListOfConflicts; g.GetStarColoringConflicts(ListOfConflicts); //Mark conflict edge m_vi_ConflictEdges.resize(m_vi_Edges.size(),false); if(ListOfConflicts.size()>0) { for(int i=0; i Vertex2) { //swap order for(int k=m_vi_Vertices[Vertex2]; k < m_vi_Vertices[Vertex2+1]; k++) { if(m_vi_Edges[k] == Vertex1) { m_vi_ConflictEdges[ k ]=true; break; } } } else { for(int k=m_vi_Vertices[Vertex1]; k < m_vi_Vertices[Vertex1+1]; k++) { if(m_vi_Edges[k] == Vertex2) { m_vi_ConflictEdges[ k ]=true; break; } } } } } } //*/ //build body for(int i=0; i < i_VertexCount; i++) { for(int j=m_vi_Vertices[i] ; j< m_vi_Vertices[i + 1]; j++) { line = ""; line = line + "v"+itoa(i)+"_c"; if(m_vi_LeftVertexColors.size() > 0) { line = line + itoa(m_vi_LeftVertexColors[i]); } else { line = line + '_'; } line = line + " -- v"+ itoa(m_vi_Edges[j] + i_VertexCount)+"_c"; if(m_vi_RightVertexColors.size() > 0) { line = line + itoa(m_vi_RightVertexColors[m_vi_Edges[j]]); } else { line = line + '_'; } if(m_vi_ConflictEdges.size()>0 && m_vi_ConflictEdges[j]) { // make the line bolder if the edge is conflict line = line + "[style=\"setlinewidth(3)\"]"; } OutputStream< &ListOfColors, string fileName) { cerr<<"Function to be built! int buildDotWithoutColor(ColPack::BipartiteGraphBicoloringInterface &g, vector &ListOfColors, string fileName)"< &ListOfColors, string fileName) { cerr<<"Function to be built! int buildDotWithColor(ColPack::BipartiteGraphBicoloringInterface &g, vector &ListOfColors, string fileName)"< &ListOfColors, string fileName) { cerr<<"IN buildDotWithoutColor"< m_vi_Vertices, m_vi_Edges; g.GetVertices(m_vi_Vertices); g.GetEdges(m_vi_Edges); int i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); string line=""; //build header OutputStream<<"graph g {"< &ListOfColors, string fileName) { cerr<<"IN buildDotWithColor"< m_vi_Vertices, m_vi_Edges, m_vi_VertexColors; g.GetVertices(m_vi_Vertices); g.GetEdges(m_vi_Edges); g.GetVertexColors(m_vi_VertexColors); int i_VertexCount = STEP_DOWN((signed) m_vi_Vertices.size()); int i_NumberOfColors = ListOfColors.size(); string line="", color_str="", colorID_str="", colorID_str2=""; //build header OutputStream<<"graph g {"< > ListOfConflicts; g.GetStarColoringConflicts(ListOfConflicts); //Mark conflict edge vector m_vi_ConflictEdges; m_vi_ConflictEdges.resize(m_vi_Edges.size(),false); if(ListOfConflicts.size()>0) { for(int i=0; i Vertex2) { //swap order for(int k=m_vi_Vertices[Vertex2]; k < m_vi_Vertices[Vertex2+1]; k++) { if(m_vi_Edges[k] == Vertex1) { m_vi_ConflictEdges[ k ]=true; break; } } } else { for(int k=m_vi_Vertices[Vertex1]; k < m_vi_Vertices[Vertex1+1]; k++) { if(m_vi_Edges[k] == Vertex2) { m_vi_ConflictEdges[ k ]=true; break; } } } } } } //build body for(int i=0; i < i_VertexCount; i++) { for(int j=m_vi_Vertices[i] ; j< m_vi_Vertices[i + 1]; j++) { if(m_vi_Edges[j]<=i) continue; if(m_vi_VertexColors[i] != _UNKNOWN) { colorID_str = itoa(m_vi_VertexColors[i]); } else { colorID_str = "_"; } if(m_vi_VertexColors[m_vi_Edges[j]] != _UNKNOWN) { colorID_str2 = itoa(m_vi_VertexColors[m_vi_Edges[j]]); } else { colorID_str2 = "_"; } line = ""; line = line + "v"+itoa(i)+"_c"+colorID_str+" -- v"+ itoa(m_vi_Edges[j])+"_c"+colorID_str2 ; if(m_vi_ConflictEdges.size()>0 && m_vi_ConflictEdges[j]) { // make the line bolder if the edge is conflict line = line + "[style=\"setlinewidth(3)\"]"; } OutputStream< & ordering, int offset) { vector isExist, index; int orderingNum = 0; isExist.resize(ordering.size(), false); index.resize(ordering.size(), false); for(int i=0; i= ordering.size()) { cerr<<" This vertex # is not in the valid range [0, ordering.size()]. ordering[i]: "<> rowCount >> columnCount >> nonzeros; (*uip3_SparsityPattern) = new unsigned int*[rowCount]; for(int i=0;i < rowCount; i++) { getline(in, line); lineCounter++; if(line!="") { in2.clear(); in2.str(line); in2>>nnz_per_row; (*uip3_SparsityPattern)[i] = new unsigned int[nnz_per_row + 1]; (*uip3_SparsityPattern)[i][0] = nnz_per_row; for(int j=1; j>num; (*uip3_SparsityPattern)[i][j] = num; nz_counter++; } } else { cerr<<"* WARNING: ReadRowCompressedFormat()"< " out< " iin.str(line); iin>>temp>>temp>>temp;out<>temp;out<& ordering) { srand(time(NULL)); int size = ordering.size(); int ran_num = 0; for(int i=0; i < size; i++) { //Get a random number in range [i, size] ran_num = (int)(((float) rand() / RAND_MAX) * (size -1 - i)) + i; swap(ordering[i],ordering[ran_num]); } } string toUpper(string input) { string output = input; for(int i = input.size() - 1; i>=0; i--) { if(input[i]==' ' || input[i]=='\t' || input[i]=='\n') { output[i] = '_'; } else { output[i] = toupper(input[i]); } } return output; } //just manipulate the value of dp2_Values a little bit int Times2Plus1point5(double** dp2_Values, int i_RowCount, int i_ColumnCount) { for(int i=0; i < i_RowCount; i++) { for(int j=0; j < i_ColumnCount; j++) { if(dp2_Values[i][j] != 0.) dp2_Values[i][j] = dp2_Values[i][j]*2 + 1.5; //for each non-zero entry in the matrix, do the manipulation. } } return 0; } int Times2(double** dp2_Values, int i_RowCount, int i_ColumnCount) { for(int i=0; i < i_RowCount; i++) { for(int j=0; j < i_ColumnCount; j++) { if(dp2_Values[i][j] != 0.) dp2_Values[i][j] = dp2_Values[i][j]*2; } } return 0; } int GenerateValues(unsigned int ** uip2_SparsityPattern, int rowCount, double*** dp3_Value) { //srand(time(NULL)); srand(0); (*dp3_Value) = new double*[rowCount]; for(unsigned int i=0; i < (unsigned int)rowCount; i++) { unsigned int numOfNonZeros = uip2_SparsityPattern[i][0]; (*dp3_Value)[i] = new double[numOfNonZeros + 1]; (*dp3_Value)[i][0] = (double)numOfNonZeros; for(unsigned int j=1; j <= numOfNonZeros; j++) { (*dp3_Value)[i][j] = (rand()%2001 - 1000)/1000.0; //printf("(*dp3_Value)[%d][%d] = (%d % 2001 - 1000)/1000.0 = %7.2f \n",i,j,rand(),(*dp3_Value)[i][j]); } } return 0; } int GenerateValuesForSymmetricMatrix(unsigned int ** uip2_SparsityPattern, int rowCount, double*** dp3_Value) { //srand(time(NULL)); srand(0); int * nnzCount = new int[rowCount]; // keep track of the # of non-zeros in each row for(unsigned int i=0; i < (unsigned int)rowCount; i++) nnzCount[i] = 0; (*dp3_Value) = new double*[rowCount]; for(unsigned int i=0; i < (unsigned int)rowCount; i++) { unsigned int numOfNonZeros = uip2_SparsityPattern[i][0]; (*dp3_Value)[i] = new double[numOfNonZeros + 1]; (*dp3_Value)[i][0] = (double)numOfNonZeros; for(unsigned int j=1; j <= numOfNonZeros; j++) { if (uip2_SparsityPattern[i][j] >i) break; (*dp3_Value)[i][j] = (rand()%2001 - 1000)/1000.0; nnzCount[i]++; if (uip2_SparsityPattern[i][j] > &lsi_valsetlist, std::list > &lvd_Value) { for(int i=0; i valset; std::vector valuevector; valuevector.reserve(uip2_SparsityPattern_RowCompressedFormat[i][0]); for(int j= 1; j <= uip2_SparsityPattern_RowCompressedFormat[i][0]; j++) { valset.insert(uip2_SparsityPattern_RowCompressedFormat[i][j]); valuevector.push_back(dp2_Value[i][j]); } (lsi_valsetlist).push_back(valset); (lvd_Value).push_back(valuevector); } return 0; } int ConvertRowCompressedFormat2CSR(unsigned int ** uip2_SparsityPattern_RowCompressedFormat, int i_rowCount, int** ip_RowIndex, int** ip_ColumnIndex) { (*ip_RowIndex) = new int[i_rowCount+1]; int nnz = 0; for(int i=0; i < i_rowCount; i++) { (*ip_RowIndex)[i] = nnz; nnz += uip2_SparsityPattern_RowCompressedFormat[i][0]; //cout<<"Display *ip_RowIndex"< > nodeList; map > valueList; //READ IN BANNER MM_typecode matcode; FILE *f; if ((f = fopen(m_s_InputFile.c_str(), "r")) == NULL) { cout<0&&line[0]=='%') {//ignore comment line getline(in,line); } in2.str(line); in2 >> rowCount >> columnCount >> entries; //cout<<"rowCount="<>value; //cout<<"Value = "<>value; valueList[rowIndex].push_back(value); } } else { //rowIndex < colIndex cerr<<"* WARNING: ConvertMatrixMarketFormatToRowCompressedFormat()"<>value; //cout<<"Value = "< > &lsi_SparsityPattern, std::list > &lvd_Value, int columnCount, vector &vi_VertexPartialColors, int colorCount, double*** dp3_CompressedMatrix) { unsigned int rowCount = lsi_SparsityPattern.size(); //Allocate memory for (*dp3_CompressedMatrix)[rowCount][colorCount] //cout<<"Allocate memory for (*dp3_CompressedMatrix)[rowCount][colorCount]"< >::iterator valsetlistiter = lsi_SparsityPattern.begin(); std::list >::iterator valuelistlistiter = lvd_Value.begin(); for (unsigned int i=0; i< rowCount; valsetlistiter++, valuelistlistiter++, i++){ unsigned int numOfNonZeros = (*valsetlistiter).size(); std::set::iterator valsetiter = (*valsetlistiter).begin(); for(unsigned int j=0; j < numOfNonZeros; valsetiter++, j++) { (*dp3_CompressedMatrix)[i][vi_VertexPartialColors[*valsetiter] ] += (*valuelistlistiter)[j]; } } return 0; } int MatrixMultiplication_VxS(unsigned int ** uip3_SparsityPattern, double** dp3_Value, int rowCount, int columnCount, double** dp2_seed, int colorCount, double*** dp3_CompressedMatrix) { //Allocate memory for (*dp3_CompressedMatrix)[rowCount][colorCount] #if DEBUG == 2 cout<<"Allocate memory for (*dp3_CompressedMatrix)[rowCount][colorCount]"< >& lvd_Value, std::list >& lvd_NewValue, bool compare_exact, bool print_all) { double ratio = 1.; int none_equal_count = 0; int rowCount = lvd_Value.size(); std::list >::iterator lvdi_Value = lvd_Value.begin(), lvdi_NewValue = lvd_NewValue.begin() ; for(unsigned int i=0; i < (unsigned int)rowCount; lvdi_Value++, lvdi_NewValue++, i++) { unsigned int numOfNonZeros = (unsigned int)(*lvdi_Value).size(); if (numOfNonZeros != (unsigned int)(*lvdi_NewValue).size()) { printf("Number of non-zeros in row %d are not equal. (*lvdi_Value).size() = %d; (*lvdi_NewValue).size() = %d; \n",i,(unsigned int)(*lvdi_Value).size(),(unsigned int)(*lvdi_NewValue).size()); if (print_all) { none_equal_count++; continue; } else return false; } for(unsigned int j=0; j < numOfNonZeros; j++) { if (compare_exact) { if ((*lvdi_Value)[j] != (*lvdi_NewValue)[j]) { printf("At row %d, column %d, (*lvdi_Value)[j](%f) != (*lvdi_NewValue)[j](%f) \n",i,j,(*lvdi_Value)[j],(*lvdi_NewValue)[j]); if (print_all) { none_equal_count++; } else { printf("You may want to set the flag \"compare_exact\" to 0 to compare the values approximately\n"); return false; } } } else { if((*lvdi_NewValue)[j] == 0.) { if((*lvdi_Value)[j] != 0.) { printf("At row %d, column %d, (*lvdi_Value)[j](%f) != (*lvdi_NewValue)[j](0) \n",i,j,(*lvdi_Value)[j]); if (print_all) { none_equal_count++; } else return false; } } else { ratio = (*lvdi_Value)[j] / (*lvdi_NewValue)[j]; if( ratio < .99 || ratio > 1.02) { printf("At row %d, column %d, (*lvdi_Value)[j](%f) != (*lvdi_NewValue)[j](%f) ; (*lvdi_Value)[j] / (*lvdi_NewValue)[j]=%f\n",i,j,(*lvdi_Value)[j],(*lvdi_NewValue)[j], ratio); if (print_all) { none_equal_count++; } else return false; } } } } } if(none_equal_count!=0) { printf("Total: %d lines. (The total # of non-equals can be greater)\n",none_equal_count); if (compare_exact) printf("You may want to set the flag \"compare_exact\" to 0 to compare the values approximately\n"); return false; } else return true; } bool CompressedRowMatricesAreEqual(double** dp3_Value, double** dp3_NewValue, int rowCount, bool compare_exact, bool print_all) { double ratio = 1.; int none_equal_count = 0; for(unsigned int i=0; i < (unsigned int)rowCount; i++) { unsigned int numOfNonZeros = (unsigned int)dp3_Value[i][0]; if (numOfNonZeros != (unsigned int)dp3_NewValue[i][0]) { printf("Number of non-zeros in row %d are not equal. dp3_Value[i][0] = %d; dp3_NewValue[i][0] = %d; \n",i,(unsigned int)dp3_Value[i][0],(unsigned int)dp3_NewValue[i][0]); if (print_all) { none_equal_count++; continue; } else return false; } for(unsigned int j=0; j <= numOfNonZeros; j++) { if (compare_exact) { if (dp3_Value[i][j] != dp3_NewValue[i][j]) { printf("At row %d, column %d, dp3_Value[i][j](%f) != dp3_NewValue[i][j](%f) \n",i,j,dp3_Value[i][j],dp3_NewValue[i][j]); if (print_all) { none_equal_count++; } else { printf("You may want to set the flag \"compare_exact\" to 0 to compare the values approximately\n"); return false; } } } else { if(dp3_NewValue[i][j] == 0.) { if(fabs(dp3_Value[i][j]) > 1e-10) { printf("At row %d, column %d, dp3_Value[i][j](%f) != dp3_NewValue[i][j](0) \n",i,j,dp3_Value[i][j]); cout< > &lsi_valsetlist) { int size = (lsi_valsetlist).size(); int rowIndex=-1, colIndex=-1; std::list >::iterator valsetlistiter = (lsi_valsetlist).begin(); unsigned int estimateColumnCount = 20; cout<::iterator valsetiter = (*valsetlistiter).begin(); cout< > &lvd_Value) { int size = (lvd_Value).size(); int rowIndex=-1; double value=0.; std::list >::iterator valsetlistiter = (lvd_Value).begin(); unsigned int estimateColumnCount = 20; cout<::iterator valsetiter = (*valsetlistiter).begin(); cout<. ************************************************************************************/ #ifndef EXTRA_H #define EXTRA_H #include #include #include #include #include #include #include #include // support for variadic functions //#include //for toupper() #include #include #include #include #include #include "ColPackHeaders.h" using namespace std; /* #include "Definitions.h" #include "Pause.h" */ //Definition for dot #define DOT 1 #define NEATO 2 #define TWOPI 3 #define CIRCO 4 #define FDP 5 /// Write out to the file ADOLC Input using Matrix Market format /** Input parameters: - string s_postfix: postfix of the output file name - int i_mode: - i_mode == 0: output the structure of the matrix only. The next 3 parameter(s) are: unsigned int ** uip2_SparsityPattern, int i_Matrix_Row, int i_Matrix_Col - i_mode == 1: output the structure of the matrix and values in the Compressed Matrix The next 6 parameter(s) are: unsigned int ** uip2_SparsityPattern, int i_Matrix_Row, int i_Matrix_Col, double** dp2_CompressedMatrix, int i_CompressedMatrix_Row, int i_CompressedMatrix_Col - i_mode == 2: output the structure and values of the matrix and values in the Compressed Matrix The next 7 parameter(s) are: unsigned int ** uip2_SparsityPattern, int i_Matrix_Row, int i_Matrix_Col, double** dp2_CompressedMatrix, int i_CompressedMatrix_Row, int i_CompressedMatrix_Col, double** dp2_Values */ int WriteMatrixMarket_ADOLCInput(string s_postfix, int i_mode, ...); /// Convert a number string under Harwell-Boeing format to the format that C++ can understand /** For example: -6.310289677458059D-07 to -6.310289677458059E-07 Essentially, this function just search backward for the letter D and replace it with E Return value: - 0 if letter D is not found - 1 if latter D is found and replace by letter E */ int ConvertHarwellBoeingDouble(string & num_string); string itoa(int i); vector getListOfColors(string s_InputFile); int buildDotWithoutColor(ColPack::GraphColoringInterface &g, vector &ListOfColors, string fileName); /// Build dot file with colors, also highlight StarColoringConflicts /** * !!! TO DO: improve this function so that it can detect conflicts of all coloring types */ int buildDotWithColor(ColPack::GraphColoringInterface &g, vector &ListOfColors, string fileName); int buildDotWithoutColor(ColPack::BipartiteGraphPartialColoringInterface &g, vector &ListOfColors, string fileName); // !!! TODO: enable conflict detection int buildDotWithColor(ColPack::BipartiteGraphPartialColoringInterface &g, vector &ListOfColors, string fileName); // !!! TO BE BUILT int buildDotWithoutColor(ColPack::BipartiteGraphBicoloringInterface &g, vector &ListOfColors, string fileName); // !!! TO BE BUILT int buildDotWithColor(ColPack::BipartiteGraphBicoloringInterface &g, vector &ListOfColors, string fileName); /// Read a Row Compressed Format file /** Read a Row Compressed Format file Line 1: <# of rows> <# of columns> <# of non-zeros> Line 2-(# of non-zeros + 1): <# of non-zeros in that row> ... */ int ReadRowCompressedFormat(string s_InputFile, unsigned int *** uip3_SparsityPattern, int& rowCount, int& columnCount); /// Test and make sure that this is a valid ordering. /** This routine will test for: - Duplicated vertices. If there is no duplicated vertex, this ordering is probably ok. - Invalid vertex #. The vertex # should be between 0 and ordering.size() */ bool isValidOrdering(vector & ordering, int offset = 0); //Re-order the values randomly void randomOrdering(vector& ordering); /// Convert all the characters in input to upper case, ' ', '\ t', '\ n' will be converted to '_' string toUpper(string input); /// Build the index struture from Row Compressed Format to Sparse Solvers Format /** ip2_RowIndex and ip2_ColumnIndex will be allocated memory (using malloc) and populated with the matrix structure in Sparse Solvers Format Input: - uip2_HessianSparsityPattern in Row Compressed Format - ui_rowCount Output: - ip2_RowIndex[ui_rowCount + 1] for Sparse Solvers Format - ip2_ColumnIndex[ ip2_RowIndex[ui_rowCount] - 1] for Sparse Solvers Format */ int ConvertRowCompressedFormat2SparseSolversFormat_StructureOnly(unsigned int ** uip2_HessianSparsityPattern, unsigned int ui_rowCount, unsigned int** ip2_RowIndex, unsigned int** ip2_ColumnIndex); /// Convert Coordinate Format to Row Compressed Format /** dp3_Pattern and dp3_Values will be allocated memory (using malloc) and populated with the matrix structure in Row Compressed Format Input: (Coordinate Format) - unsigned int* uip1_RowIndex - unsigned int* uip1_ColumnIndex - double* dp1_HessianValue - int i_RowCount: number of rows of the matrix - int i_ColumnCount: number of columns of the matrix Output: (Row Compressed Format) - unsigned int *** dp3_Pattern - double*** dp3_Values */ int ConvertCoordinateFormat2RowCompressedFormat(unsigned int* uip1_RowIndex, unsigned int* uip1_ColumnIndex, double* dp1_HessianValue, int i_RowCount, int i_NonZeroCount, unsigned int *** dp3_Pattern, double*** dp3_Values ); /// Covert file with DIMACS format to Matrix Market format /** DIMACS graph format: http://www.dis.uniroma1.it/~challenge9/format.shtml#graph Note: DIMACS graph format is for directed graph => the equivalent matrix is squared and non-systemic Read input from file ".gr" (DIMACS graph format) and generate file ".mtx" (Matrix Market format) */ void ConvertFileDIMACSFormat2MatrixMarketFormat(string fileNameNoExt); ///Read the sparse matrix from Matrix-Market-format file and convert to Row Compressed format (used by ADIC) "uip3_SparsityPattern" & "dp3_Value" /** Read in a matrix from matrix-market format file and create a matrix stored in compressed sparse row format The Matrix-Market-format has 3 values in each row, the row index, column index and numerical value of each nonzero. The last 4 parameters of this routine are output parameters (unsigned int *** uip3_SparsityPattern, double*** dp3_Value,int &rowCount, int &columnCount) */ int ConvertMatrixMarketFormat2RowCompressedFormat(string s_InputFile, unsigned int *** uip3_SparsityPattern, double*** dp3_Value, int &rowCount, int &columnCount); /* !!! the documentation here may not be accurate "zero-based indexing, 3-array variation CSR format (used by ADIC)" Does ADIC use zero-based indexing, 3-array variation CSR format any more? //*/ /// Convert Row Compressed format (used by ADOL-C) to zero-based indexing, 3-array variation CSR format (used by ADIC) /** Return 0 upon successful. */ // !!! need to be fixed to accomodate dp2_Value parameter int ConvertRowCompressedFormat2CSR(unsigned int ** uip2_SparsityPattern_RowCompressedFormat, int i_rowCount, int** ip_RowIndex, int** ip_ColumnIndex); int ConvertRowCompressedFormat2ADIC(unsigned int ** uip2_SparsityPattern_RowCompressedFormat, int i_rowCount , double** dp2_Value, std::list > &lsi_SparsityPattern, std::list > &lvd_Value); /// Multiply the original sparse matrix (uip3_SparsityPattern,dp3_Value) (in compress sparse row format) with the seed matrix dp2_seed and store the result in "dp3_CompressedMatrix" /** (*dp3_CompressedMatrix) = (*dp3_Value) * dp2_seed */ int MatrixMultiplication_VxS(unsigned int ** uip3_SparsityPattern, double** dp3_Value, int rowCount, int columnCount, double** dp2_seed, int colorCount, double*** dp3_CompressedMatrix); int MatrixMultiplication_VxS__usingVertexPartialColors(std::list > &lsi_SparsityPattern, std::list > &lvd_Value, int columnCount, vector &vi_VertexPartialColors, int colorCount, double*** dp3_CompressedMatrix); /// Multiply the seed matrix dp2_seed with the original sparse matrix (uip3_SparsityPattern,dp3_Value) (in compress sparse row format) and store the result in "dp3_CompressedMatrix" /** (*dp3_CompressedMatrix) = dp2_seed * (*dp3_Value) */ int MatrixMultiplication_SxV(unsigned int ** uip3_SparsityPattern, double** dp3_Value, int rowCount, int columnCount, double** dp2_seed, int colorCount, double*** dp3_CompressedMatrix); ///Compare dp3_Value with dp3_NewValue and see if all the values are equal. /** If (compare_exact == 0) num1 and num2 are consider equal if 0.99 <= num1/num2 <= 1.02 If (print_all == 1) all cases of non-equal will be print out. Normally (when print_all == 0), this rountine will stop after the first non-equal. */ bool CompressedRowMatricesAreEqual(double** dp3_Value, double** dp3_NewValue, int rowCount, bool compare_exact = 1, bool print_all = 0); bool ADICMatricesAreEqual(std::list >& lvd_Value, std::list >& lvd_NewValue, bool compare_exact = 1, bool print_all = 0); ///just manipulate the value of dp2_Values a little bit. Each non-zero entry in the matrix * 2 + 1.5. int Times2Plus1point5(double** dp2_Values, int i_RowCount, int i_ColumnCount); ///just manipulate the value of dp2_Values a little bit. Each non-zero entry in the matrix * 2. int Times2(double** dp2_Values, int i_RowCount, int i_ColumnCount); ///Allocate memory and generate random values for dp3_Value int GenerateValues(unsigned int ** uip2_SparsityPattern, int rowCount, double*** dp3_Value); ///Allocate memory and generate random values for dp3_Value of a Symmetric Matrix. int GenerateValuesForSymmetricMatrix(unsigned int ** uip2_SparsityPattern, int rowCount, double*** dp3_Value); int DisplayADICFormat_Sparsity(std::list > &lsi_SparsityPattern); int DisplayADICFormat_Value(std::list > &lvd_Value); int displayGraph(map< int, map > *graph, vector* vi_VertexColors=NULL,int i_RunInBackground = false, int filter = DOT); int buildDotWithoutColor(map< int, map > *graph, vector &ListOfColors, string fileName); int buildDotWithColor(map< int, map > *graph, vector* vi_VertexColors, vector &ListOfColors, string fileName); #ifndef EXTRA_H_TEMPLATE_FUNCTIONS #define EXTRA_H_TEMPLATE_FUNCTIONS template int displayGraph(T &g,int i_RunInBackground = false, int filter = DOT) { static int ranNum = rand(); static int seq = 0; seq++; vector ListOfColors = getListOfColors(""); string fileName = "/tmp/."; fileName = fileName + "ColPack_"+ itoa(ranNum)+"_"+itoa(seq)+".dot"; //build the dot file of the graph string m_s_VertexColoringVariant = g.GetVertexColoringVariant(); if(m_s_VertexColoringVariant.empty() || m_s_VertexColoringVariant=="Unknown") { //build dot file represents graph without color info buildDotWithoutColor(g, ListOfColors, fileName); } else { //build dot file represents graph with color buildDotWithColor(g, ListOfColors, fileName); } //display the graph using xdot string command; switch (filter) { case NEATO: command="xdot -f neato "; break; case TWOPI: command="xdot -f twopi "; break; case CIRCO: command="xdot -f circo "; break; case FDP: command="xdot -f fdp "; break; default: command="xdot -f dot "; // case DOT } command = command + fileName; if(i_RunInBackground) command = command + " &"; int i_ReturnValue = system(command.c_str()); return i_ReturnValue; } ///Find the difference between 2 arrays. Return 0 if there is no difference, 1 if there is at least 1 difference template int diffArrays(T* array1, T* array2, int rowCount, bool compare_exact = 1, bool print_all = 0) { double ratio = 0.; int none_equal_count = 0; for(int i = 0; i < rowCount; i++) { if (compare_exact) { if(array1[i]!=array2[i]) { // found a difference cout<<"At index i="< int freeMatrix(T*** xp3_matrix, int rowCount) { //cout<<"IN deleteM 3"< int deleteMatrix(T** xp2_matrix, int rowCount) { //cout<<"IN deleteM 2"< int deleteMatrix(T*** xp3_matrix, int rowCount) { //cout<<"IN deleteM 3"< void displayCompressedRowMatrix(T** xp2_Value, int rowCount, bool structureOnly = false) { unsigned int estimateColumnCount = 20; cout< void displayMatrix(T** xp2_Value, int rowCount, int columnCount, bool structureOnly = false) { cout< void displayVector(T* xp2_Value, int size, bool structureOnly = false) { if(structureOnly) { for(unsigned int i=0; i < (unsigned int)size; i++) { cout< int displayVector(vector v) { for (unsigned int i=0; i < v.size(); i++) { cout< void displayAdjacencyMatrix(vector< vector > &xp2_Value, bool structureOnly = false) { unsigned int estimateColumnCount = 20; cout< #include #include #include #include "mmio.h" int mm_read_unsymmetric_sparse(const char *fname, int *M_, int *N_, int *nz_, double **val_, int **I_, int **J_) { FILE *f; MM_typecode matcode; int M, N, nz; int i; double *val; int *I, *J; if ((f = fopen(fname, "r")) == NULL) return -1; if (mm_read_banner(f, &matcode) != 0) { printf("mm_read_unsymetric: Could not process Matrix Market banner "); printf(" in file [%s]\n", fname); return -1; } if ( !(mm_is_real(matcode) && mm_is_matrix(matcode) && mm_is_sparse(matcode))) { fprintf(stderr, "Sorry, this application does not support "); fprintf(stderr, "Market Market type: [%s]\n", mm_typecode_to_str(matcode)); return -1; } /* find out size of sparse matrix: M, N, nz .... */ if (mm_read_mtx_crd_size(f, &M, &N, &nz) !=0) { fprintf(stderr, "read_unsymmetric_sparse(): could not parse matrix size.\n"); return -1; } *M_ = M; *N_ = N; *nz_ = nz; /* reseve memory for matrices */ I = (int *) malloc(nz * sizeof(int)); J = (int *) malloc(nz * sizeof(int)); val = (double *) malloc(nz * sizeof(double)); *val_ = val; *I_ = I; *J_ = J; /* NOTE: when reading in doubles, ANSI C requires the use of the "l" */ /* specifier as in "%lg", "%lf", "%le", otherwise errors will occur */ /* (ANSI C X3.159-1989, Sec. 4.9.6.2, p. 136 lines 13-15) */ for (i=0; i getListOfGraphs(string location_of_graph_list) { static vector list; string temp; int i=0, max_iteration=1000; //Make sure that this function only run once despite how many times I call toFile...() functions //Help make the statistics data consistent between files. static bool is_run_already = false; if (is_run_already) return list; else is_run_already = true; ifstream input (location_of_graph_list.c_str()); if(!input) {cout<<"**ERR getListOfGraphs: "<>temp; while(temp!="*" && i>temp; i++; } if (i==max_iteration) { cerr<<"**ERR getListOfGraphs(): i==max_iteration. May be you forget to use the \"*\" to terminate the list of graphs?"< listOfGraphs = getListOfGraphs(baseDir+"listOfGraphs.txt"); string s_OrderingVariant = "", s_ColoringVariant = ""; if(stat_output_append) { stat_out1.open((baseDir+"NumberOfColors"+stat_output_suffix+".csv").c_str(),ios::app); stat_out2.open((baseDir+"Time"+stat_output_suffix+".csv").c_str(),ios::app); stat_out3.open((baseDir+"MaxBackDegree"+stat_output_suffix+".csv").c_str(),ios::app); stat_out4.open((baseDir+"Graph_Stat"+stat_output_suffix+".csv").c_str(),ios::app); stat_out1<Reset(); current_time(); switch(k) { case 0: s_OrderingVariant="NATURAL"; cout<<"NATURAL " ;break; case 1: s_OrderingVariant="LARGEST_FIRST"; cout<<"LARGEST_FIRST " ;break; case 2: s_OrderingVariant="SMALLEST_LAST"; cout<<"SMALLEST_LAST " ;break; case 3: s_OrderingVariant="INCIDENCE_DEGREE"; cout<<"INCIDENCE_DEGREE " ;break; case 4: s_OrderingVariant="DISTANCE_TWO_LARGEST_FIRST"; cout<<"DISTANCE_TWO_LARGEST_FIRST " ;break; case 5: s_OrderingVariant="DISTANCE_TWO_SMALLEST_LAST"; cout<<"DISTANCE_TWO_SMALLEST_LAST " ;break; case 6: s_OrderingVariant="DISTANCE_TWO_INCIDENCE_DEGREE"; cout<<"DISTANCE_TWO_INCIDENCE_DEGREE " ;break; case 7: s_OrderingVariant="DYNAMIC_LARGEST_FIRST"; cout<<"DYNAMIC_LARGEST_FIRST " ;break; case 8: s_OrderingVariant="RANDOM"; cout<<"RANDOM " ;break; } cout<<"Ordering "<Coloring(s_OrderingVariant, s_ColoringVariant ); //cout<<"GetVertexColorCount="<GetVertexColorCount()<GetVertexColorCount()<GetVertexOrderingTime()<<","<GetVertexColoringTime()<<","<GetVertexColoringTime()+gGraph->GetVertexOrderingTime()< output; gGraph->GetVertexColors(output); m_T_Timer.Start(); gGraph->ColoringBasedOrdering(output); m_T_Timer.Stop(); double OrderingTime = m_T_Timer.GetWallTime(); gGraph->SetStringVertexColoringVariant(""); // so that DistanceOneColoring() actually does the coloring m_T_Timer.Start(); gGraph->GraphColoring::DistanceOneColoring(); m_T_Timer.Stop(); double ColoringTime = m_T_Timer.GetWallTime(); stat_out1<<","<GetVertexColorCount()<GetMaxBackDegree2()<GetVertexCount(); stat_out4<<","<GetEdgeCount(); stat_out4<<","<GetMaximumVertexDegree(); stat_out4<<","<GetMinimumVertexDegree(); stat_out4<<","<GetAverageVertexDegree(); stat_out4< Orderings, vector Colorings, map stat_flags ) { ofstream out_NumberOfColors, out_Time, out_MaxBackDegree, out_Graph_Stat; vector listOfGraphs = getListOfGraphs(baseDir+"listOfGraphs.txt"); // ****************************************************** // Open appropriate output stream if( stat_flags["output_append"] ) { if(stat_flags["NumberOfColors"]) { cout<<"NumberOfColors: Append to "<<(baseDir+"NumberOfColors"+"-Coloring"+stat_output_suffix+".csv")<Coloring(Orderings[k], Colorings[j] ); /* if(Colorings[j] == "ACYCLIC") { int result = gGraph->CheckAcyclicColoring(); if(result) { cout<<"gGraph->CheckAcyclicColoring() fail. Violation count = "<CheckAcyclicColoring() success. Violation count = "<GraphColoring::CheckStarColoring()) { cout<<"CheckStarColoring(): problem found"<GetVertexColorCount()<GetVertexOrderingTime()<<","<GetVertexColoringTime()<<","<GetVertexColoringTime()+gGraph->GetVertexOrderingTime()<GetVertexCount(); out_Graph_Stat<<","<GetEdgeCount(); out_Graph_Stat<<","<GetMaximumVertexDegree(); out_Graph_Stat<<","<GetMinimumVertexDegree(); out_Graph_Stat<<","<GetAverageVertexDegree(); out_Graph_Stat< stat_flags ) { ofstream out_Graph_Stat; vector listOfGraphs = getListOfGraphs(baseDir+"listOfGraphs.txt"); if(stat_flags["output_append"]) { out_Graph_Stat.open((baseDir+"Graph_Stat"+stat_output_suffix+".csv").c_str(),ios::app); out_Graph_Stat<PrintGraphStructure(); File stat_file_parsor; stat_file_parsor.Parse(listOfGraphs[i]); out_Graph_Stat<GetVertexCount(); out_Graph_Stat<<","<GetEdgeCount(); out_Graph_Stat<<","<GetMaximumVertexDegree(); out_Graph_Stat<<","<GetMinimumVertexDegree(); out_Graph_Stat<<","<GetAverageVertexDegree(); out_Graph_Stat< stat_flags ) { ofstream out_Graph_Stat; vector listOfGraphs = getListOfGraphs(baseDir+"listOfGraphs.txt"); if( stat_flags["output_append"] ) { out_Graph_Stat.open((baseDir+"BiGraph_Stat"+stat_output_suffix+".csv").c_str(),ios::app); out_Graph_Stat<PrintBipartiteGraph(); File stat_file_parsor; stat_file_parsor.Parse(listOfGraphs[i]); out_Graph_Stat<GetEdgeCount(); out_Graph_Stat<<","<<((double)gGraph->GetEdgeCount())/(gGraph->GetColumnVertexCount()*gGraph->GetRowVertexCount()); out_Graph_Stat<<","<GetColumnVertexCount(); out_Graph_Stat<<","<GetMaximumColumnVertexDegree(); out_Graph_Stat<<","<GetMinimumColumnVertexDegree(); out_Graph_Stat<<","<GetAverageColumnVertexDegree(); out_Graph_Stat<<","<GetRowVertexCount(); out_Graph_Stat<<","<GetMaximumRowVertexDegree(); out_Graph_Stat<<","<GetMinimumRowVertexDegree(); out_Graph_Stat<<","<GetAverageRowVertexDegree(); out_Graph_Stat<& listOfGraphs, int selected) { for(int i=0; iGraph: "< Orderings, vector Colorings, map stat_flags ) { ofstream out_NumberOfColors, out_Time; vector listOfGraphs = getListOfGraphs(baseDir+"listOfGraphs.txt"); // ****************************************************** // Open appropriate output stream if( stat_flags["output_append"] ) { if(stat_flags["NumberOfColors"]) { cout<<"NumberOfColors: Append to "<<(baseDir+"NumberOfColors"+"-BiColoring"+stat_output_suffix+".csv")<Bicoloring(Orderings[k], Colorings[j]); if(stat_flags["NumberOfColors"]) out_NumberOfColors<<","<GetLeftVertexColorCount()<<","<GetRightVertexColorCount()<<","<GetVertexColorCount()<GetVertexOrderingTime()<<','<GetVertexColoringTime()<<','<GetVertexOrderingTime() + gGraph->GetVertexColoringTime()< Orderings, vector Colorings, map stat_flags ) { ofstream out_NumberOfColors, out_Time; vector listOfGraphs = getListOfGraphs(baseDir+"listOfGraphs.txt"); // ****************************************************** // Open appropriate output stream if( stat_flags["output_append"] ) { if(stat_flags["NumberOfColors"]) { cout<<"NumberOfColors: Append to "<<(baseDir+"NumberOfColors"+"-PD2Coloring"+stat_output_suffix+".csv")<PartialDistanceTwoColoring(Orderings[k], Colorings[j] ); if(stat_flags["NumberOfColors"]) { //!!! Test the value and see whether or not I will need the +1 if(j==0) out_NumberOfColors<<','<GetRightVertexColorCount(); else out_NumberOfColors<<','<GetLeftVertexColorCount(); } if(stat_flags["Time"]) out_Time<<','<GetVertexOrderingTime()<<','<GetVertexColoringTime()<<','<GetVertexOrderingTime()+gGraph->GetVertexColoringTime(); cout<& listOfGraphs, int selected); vector getListOfGraphs(string location_of_graph_list); void toFileC(string baseDir, string stat_output_suffix, vector Orderings, vector Colorings, map stat_flags ); void toFileC_forColoringBasedOrdering(string baseDir, string stat_output_suffix, bool stat_output_append=1, bool stat_refresh_list = false); void toFileBiC(string baseDir, string stat_output_suffix, vector Orderings, vector Colorings, map stat_flags ); void toFileBiPC(string baseDir, string stat_output_suffix, vector Orderings, vector Colorings, map stat_flags ); /* Note: be careful when you work with MatrixMarket-format. Look inside the file (1st line) to see whether the matrix is: - 'symmetric': use toFileStatisticForGraph() - 'general' (likely to be non-symmetric): use toFileStatisticForBipartiteGraph() //*/ void toFileStatisticForGraph(string baseDir, string stat_output_suffix, map stat_flags); //i.e. Symmetric Matrix, Hessian void toFileStatisticForBipartiteGraph(string baseDir, string stat_output_suffix, map stat_flags); //i.e. Matrix, Jacobian #endif ColPack-1.0.10/autoconf.sh000077500000000000000000000020331266356121500152670ustar00rootroot00000000000000#! /bin/sh -ev autoreconf --force --install ./configure --prefix=$(pwd)/build --exec-prefix=$(pwd)/build --enable-examples if [ -z "$NCPU" ]; then NCPU=$(lscpu --parse | egrep -v '^#' | wc -l || echo 1) fi echo "NCPU=${NCPU}" if [ -z "$MAKEFLAGS" ]; then export MAKEFLAGS=-j${NCPU} fi echo "MAKEFLAGS=${MAKEFLAGS}" make clean make EXTRA_FLAGS="-O5 -DCOLPACK_DEBUG_LEVEL=0" exit 0 # Alternative configuration: # ./configure --prefix=$(pwd)/build --exec-prefix=$(pwd)/build --enable-examples --enable-openmp # Misc commentary. # The sh -e option exits on failure, avoiding the need to guard commands. # The sh -v option echos commands before executing them, avoiding the # need to do so manually. # I'm dubious about # (a) invoking "make" here at all, # (b) using make option -j instead of leaving that to the user, via ${MAKEFLAGS}, # (c) using make option -j instead of -jX where X = #CPUs. # The "if" stanza addresses (c), and partially addresses (b) by avoiding overriding # or augmenting ${MAKEFLAGS} if it is already set. ColPack-1.0.10/configure.ac000066400000000000000000000053051266356121500154050ustar00rootroot00000000000000/************************************************************************************ Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, Alex Pothen This file is part of ColPack. ColPack is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.GraphColoring::GraphColoring() ColPack is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with ColPack. If not, see . ************************************************************************************/ define([COLPACK_VER], [1]) define([COLPACK_SUB], [0]) define([COLPACK_LVL], [10]) AC_INIT([ColPack],[COLPACK_VER.COLPACK_SUB.COLPACK_LVL],[assefaw@eecs.wsu.edu],[ColPack],[http://cscapes.cs.purdue.edu/coloringpage/]) AC_PREREQ([2.57]) AC_CONFIG_SRCDIR([Main/ColPackHeaders.h]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign 1.10 no-define subdir-objects -Wall]) AM_SILENT_RULES([yes]) AC_CONFIG_HEADERS(config.h) AC_PROG_CXX AX_CXXFLAGS_WARN_ALL AC_CONFIG_FILES(Makefile) AM_PROG_AR LT_INIT AC_MSG_CHECKING(Build examples) AC_ARG_ENABLE([examples], [AS_HELP_STRING([--enable-examples],[Build examples])], [case "${enableval}" in yes) examples=true ;; no) examples=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-examples]) ;; esac],[examples=false]) AM_CONDITIONAL([EXAMPLES], [test x$examples = xtrue]) AC_MSG_CHECKING(OpenMP) AC_ARG_ENABLE([openmp], [AS_HELP_STRING([--enable-openmp],[Enable OpenMP])], [case "${enableval}" in yes) openmp=true ;; no) openmp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-openmp]) ;; esac],[openmp=false]) AM_CONDITIONAL([ENABLE_OPENMP], [test x$openmp = xtrue]) AC_OUTPUT # echo configuration echo \ " ----------------------------------------------------------------------------- Configuration: C compiler: ${CC} C++ compiler: ${CXX} Linker: ${LD} Source code location: `pwd` Install path: ${prefix} CFLAGS: ${CFLAGS} CXXFLAGS: ${CXXFLAGS} Use OpenMP: ${openmp} Build examples: ${examples} " ColPack-1.0.10/m4/000077500000000000000000000000001266356121500134345ustar00rootroot00000000000000ColPack-1.0.10/m4/ax_append_flag.m4000066400000000000000000000053311266356121500166300ustar00rootroot00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_append_flag.html # =========================================================================== # # SYNOPSIS # # AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) # # DESCRIPTION # # FLAG is appended to the FLAGS-VARIABLE shell variable, with a space # added in between. # # If FLAGS-VARIABLE is not specified, the current language's flags (e.g. # CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains # FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly # FLAG. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 6 AC_DEFUN([AX_APPEND_FLAG], [dnl AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) AS_VAR_SET_IF(FLAGS,[ AS_CASE([" AS_VAR_GET(FLAGS) "], [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], [ AS_VAR_APPEND(FLAGS,[" $1"]) AC_RUN_LOG([: FLAGS="$FLAGS"]) ]) ], [ AS_VAR_SET(FLAGS,[$1]) AC_RUN_LOG([: FLAGS="$FLAGS"]) ]) AS_VAR_POPDEF([FLAGS])dnl ])dnl AX_APPEND_FLAG ColPack-1.0.10/m4/ax_cflags_warn_all.m4000066400000000000000000000117011266356121500175040ustar00rootroot00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html # =========================================================================== # # SYNOPSIS # # AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # # DESCRIPTION # # Try to find a compiler option that enables most reasonable warnings. # # For the GNU compiler it will be -Wall (and -ansi -pedantic) The result # is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default. # # Currently this macro knows about the GCC, Solaris, Digital Unix, AIX, # HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and # Intel compilers. For a given compiler, the Fortran flags are much more # experimental than their C equivalents. # # - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS # - $2 add-value-if-not-found : nothing # - $3 action-if-found : add value to shellvariable # - $4 action-if-not-found : nothing # # NOTE: These macros depend on AX_APPEND_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2010 Rhys Ulerich # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 15 AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings], VAR,[VAR="no, unknown" ac_save_[]FLAGS="$[]FLAGS" for ac_arg dnl in "-warn all % -warn all" dnl Intel "-pedantic % -Wall" dnl GCC "-xstrconst % -v" dnl Solaris C "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX "-ansi -ansiE % -fullwarn" dnl IRIX "+ESlit % +w1" dnl HP-UX C "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10) "-h conform % -h msglevel 2" dnl Cray C (Unicos) # do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) done FLAGS="$ac_save_[]FLAGS" ]) AS_VAR_POPDEF([FLAGS])dnl AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) case ".$VAR" in .ok|.ok,*) m4_ifvaln($3,$3) ;; .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;; *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;; esac AS_VAR_POPDEF([VAR])dnl ])dnl AX_FLAGS_WARN_ALL dnl implementation tactics: dnl the for-argument contains a list of options. The first part of dnl these does only exist to detect the compiler - usually it is dnl a global option to enable -ansi or -extrawarnings. All other dnl compilers will fail about it. That was needed since a lot of dnl compilers will give false positives for some option-syntax dnl like -Woption or -Xoption as they think of it is a pass-through dnl to later compile stages or something. The "%" is used as a dnl delimiter. A non-option comment can be given after "%%" marks dnl which will be shown but not added to the respective C/CXXFLAGS. AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([C]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([C]) ]) AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([C++]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([C++]) ]) AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([Fortran]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([Fortran]) ]) ColPack-1.0.10/m4/ax_require_defined.m4000066400000000000000000000023011266356121500175140ustar00rootroot00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_require_defined.html # =========================================================================== # # SYNOPSIS # # AX_REQUIRE_DEFINED(MACRO) # # DESCRIPTION # # AX_REQUIRE_DEFINED is a simple helper for making sure other macros have # been defined and thus are available for use. This avoids random issues # where a macro isn't expanded. Instead the configure script emits a # non-fatal: # # ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found # # It's like AC_REQUIRE except it doesn't expand the required macro. # # Here's an example: # # AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) # # LICENSE # # Copyright (c) 2014 Mike Frysinger # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 1 AC_DEFUN([AX_REQUIRE_DEFINED], [dnl m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) ])dnl AX_REQUIRE_DEFINED ColPack-1.0.10/main_page.cpp000066400000000000000000000047071266356121500155500ustar00rootroot00000000000000/*! \mainpage ColPack * *

Assefaw H. Gebremedhin, Duc Nguyen, Arijit Tarafdar, Md. Mostofa Ali Patwary, Alex Pothen

* * \section INTRODUCTION * * ColPack is a package comprising of implementation of algorithms for specialized vertex coloring problems * that arise in sparse derivative computation. It is written in an object-oriented fashion heavily using * the Standard Template Library (STL). It is designed to be simple, modular, extenable and efficient. * * \section SAMPLE_CODES SAMPLE CODES * * Sample codes (with comments) that quickly illustrate how ColPack interface functions are used * are available in the directory SampleDriver.
* Click on "Files" tab and then pick the files you want to look at and click on the [code] link.
*
* To compile all sample drivers on UNIX: make test
* To run all sample drivers on UNIX: make run-test
* Notes:
* - The make command could also be run with parameters: "make EXECUTABLE=(desired name. Optional, default name is ColPack) INSTALL_DIR=(directory where the compiled program will be placed. Optional, default dir is ./)". * - On multi-processors computer, add flag "-j" for faster result. * * \section DOWNLOAD * * ColPack
* Graph Collection in Matrix Market format
* Graph Collection in MeTis format
* To decompress .zip files on UNIX, run "unzip (targeted .zip file)"
* * \section CONTACT * * Email Assefaw Gebremedhin at agebreme [at] purdue [dot] edu or Duc Nguyen at nguyend [at] purdue [dot] edu . * */ /** @defgroup group1 Classes for Graphs Based on functionalities, the general graph coloring part of ColPack is divided into five classes - GraphCore, GraphInputOutput, GraphOrdering, GraphColoring and GraphColoringInterface. In the methods described below if no return type is specifed, it would be an int by default. Most ColPack methods return TRUE on success, which has an integer value of 1. */ /** * @defgroup group2 Classes for Bipartite Graphs */ /** @defgroup group21 Classes for Bipartite Graphs Partial Coloring * @ingroup group2 */ /** @defgroup group22 Classes for Bipartite Graphs BiColoring * @ingroup group2 */ /** @defgroup group5 Recovery Classes */ /** @defgroup group4 Auxiliary Classes */