/** \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;
}
Example #2
0
// 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;
}