/** \param N1 = number of nodes of type 1 * \param d1 = size of neighborhoods of nodes of type 1 * \param N2 = number of nodes of type 2 * \param d2 = size of neighborhoods of nodes of type 2 * \note asserts that N1 * d1 == N2 * d2 */ BipartiteGraph createRandomBipartiteGraph( size_t N1, size_t N2, size_t d1, size_t d2 ) { BipartiteGraph G; DAI_ASSERT( N1 * d1 == N2 * d2 ); // build lists of degree-repeated vertex numbers std::vector<size_t> stubs1( N1*d1, 0 ); for( size_t n1 = 0; n1 < N1; n1++ ) for( size_t t = 0; t < d1; t++ ) stubs1[n1*d1 + t] = n1; // build lists of degree-repeated vertex numbers std::vector<size_t> stubs2( N2*d2, 0 ); for( size_t n2 = 0; n2 < N2; n2++ ) for( size_t t = 0; t < d2; t++ ) stubs2[n2*d2 + t] = n2; // shuffle lists random_shuffle( stubs1.begin(), stubs1.end() ); random_shuffle( stubs2.begin(), stubs2.end() ); // add edges vector<BipartiteGraph::Edge> edges; edges.reserve( N1*d1 ); for( size_t e = 0; e < N1*d1; e++ ) edges.push_back( BipartiteGraph::Edge(stubs1[e], stubs2[e]) ); // finish construction G.construct( N1, N2, edges.begin(), edges.end() ); return G; }
// N = number of variables // n = size of variable neighborhoods // K = number of factors // k = size of factor neighborhoods // asserts: N * n == K * k BipartiteGraph CreateRandomBipartiteGraph( size_t N, size_t K, size_t n, size_t k ) { BipartiteGraph G; DAI_ASSERT( N * n == K * k ); // build lists of degree-repeated vertex numbers std::vector<size_t> stubs1(N*n,0); for( size_t i = 0; i < N; i++ ) for( size_t t = 0; t < n; t++ ) stubs1[i*n + t] = i; // build lists of degree-repeated vertex numbers std::vector<size_t> stubs2(K*k,0); for( size_t I = 0; I < K; I++ ) for( size_t t = 0; t < k; t++ ) stubs2[I*k + t] = I; // shuffle lists random_shuffle( stubs1.begin(), stubs1.end() ); random_shuffle( stubs2.begin(), stubs2.end() ); // add edges vector<BipartiteGraph::Edge> edges; edges.reserve( N*n ); for( size_t e = 0; e < N*n; e++ ) edges.push_back( BipartiteGraph::Edge(stubs1[e], stubs2[e]) ); // finish construction G.construct( N, K, edges.begin(), edges.end() ); return G; }
/// Constructs a regular LDPC graph with N=6, j=2, K=4, k=3 BipartiteGraph createSmallLDPCGraph() { BipartiteGraph G; size_t N=4, j=3, K=4; // k=3; typedef BipartiteGraph::Edge Edge; vector<Edge> edges; edges.reserve( N*j ); edges.push_back( Edge(0,0) ); edges.push_back( Edge(1,0) ); edges.push_back( Edge(2,0) ); edges.push_back( Edge(0,1) ); edges.push_back( Edge(1,1) ); edges.push_back( Edge(3,1) ); edges.push_back( Edge(0,2) ); edges.push_back( Edge(2,2) ); edges.push_back( Edge(3,2) ); edges.push_back( Edge(1,3) ); edges.push_back( Edge(2,3) ); edges.push_back( Edge(3,3) ); // finish construction G.construct( N, K, edges.begin(), edges.end() ); return G; }
/** Use construction described in "A Class of Group-Structured LDPC Codes" * by R. M. Tanner, D. Sridhara and T. Fuja * Proceedings of ICSTA, 2001 * * Example parameters: (p,j,k) = (31,3,5) * (p,j,k) = (37,3,4) * (p,j,k) = (7,2,4) * (p,j,k) = (29,2,4) * * j and k must be divisors of p-1 */ BipartiteGraph createGroupStructuredLDPCGraph( size_t p, size_t j, size_t k ) { BipartiteGraph G; size_t n = j; size_t N = p * k; size_t K = p * j; size_t a, b; for( a = 2; a < p; a++ ) if( order(a,p) == k ) break; DAI_ASSERT( a != p ); for( b = 2; b < p; b++ ) if( order(b,p) == j ) break; DAI_ASSERT( b != p ); // cout << "# order(a=" << a << ") = " << order(a,p) << endl; // cout << "# order(b=" << b << ") = " << order(b,p) << endl; DAI_ASSERT( N * n == K * k ); typedef BipartiteGraph::Edge Edge; vector<Edge> edges; edges.reserve( N * n ); for( size_t s = 0; s < j; s++ ) for( size_t t = 0; t < k; t++ ) { size_t P = (powmod(b,s,p) * powmod(a,t,p)) % p; for( size_t m = 0; m < p; m++ ) edges.push_back( Edge(t*p + m, s*p + ((m + P) % p)) ); } // finish construction G.construct( N, K, edges.begin(), edges.end() ); return G; }