Esempio n. 1
0
TreeEP::TreeEP( const FactorGraph &fg, const PropertySet &opts ) : JTree(fg, opts("updates",string("HUGIN")), false), _maxdiff(0.0), _iters(0), props(), _Q() {
    setProperties( opts );

    if( opts.hasKey("tree") ) {
        construct( fg, opts.getAs<RootedTree>("tree") );
    } else {
        if( props.type == Properties::TypeType::ORG || props.type == Properties::TypeType::ALT ) {
            // ORG: construct weighted graph with as weights a crude estimate of the
            // mutual information between the nodes
            // ALT: construct weighted graph with as weights an upper bound on the
            // effective interaction strength between pairs of nodes

            WeightedGraph<Real> wg;
            // in order to get a connected weighted graph, we start
            // by connecting every variable to the zero'th variable with weight 0
            for( size_t i = 1; i < fg.nrVars(); i++ )
                wg[UEdge(i,0)] = 0.0;
            for( size_t i = 0; i < fg.nrVars(); i++ ) {
                SmallSet<size_t> delta_i = fg.bipGraph().delta1( i, false );
                const Var& v_i = fg.var(i);
                foreach( size_t j, delta_i ) 
                    if( i < j ) {
                        const Var& v_j = fg.var(j);
                        VarSet v_ij( v_i, v_j );
                        SmallSet<size_t> nb_ij = fg.bipGraph().nb1Set( i ) | fg.bipGraph().nb1Set( j );
                        Factor piet;
                        foreach( size_t I, nb_ij ) {
                            const VarSet& Ivars = fg.factor(I).vars();
                            if( props.type == Properties::TypeType::ORG ) {
                                if( (Ivars == v_i) || (Ivars == v_j) )
                                    piet *= fg.factor(I);
                                else if( Ivars >> v_ij )
                                    piet *= fg.factor(I).marginal( v_ij );
                            } else {
                                if( Ivars >> v_ij )
                                    piet *= fg.factor(I);
                            }
                        }
                        if( props.type == Properties::TypeType::ORG ) {
                            if( piet.vars() >> v_ij ) {
                                piet = piet.marginal( v_ij );
                                Factor pietf = piet.marginal(v_i) * piet.marginal(v_j);
                                wg[UEdge(i,j)] = dist( piet, pietf, DISTKL );
                            } else {
                                // this should never happen...
                                DAI_ASSERT( 0 == 1 );
                                wg[UEdge(i,j)] = 0;
                            }
                        } else
                            wg[UEdge(i,j)] = piet.strength(v_i, v_j);
                    }
Esempio n. 2
0
 TestDAI( const FactorGraph &fg, const string &_name, const PropertySet &opts ) : obj(NULL), name(_name), err(), q(), logZ(0.0), maxdiff(0.0), time(0), iters(0U), has_logZ(false), has_maxdiff(false), has_iters(false) {
     double tic = toc();
     if( name == "LDPC" ) {
         double zero[2] = {1.0, 0.0};
         q.clear();
         for( size_t i = 0; i < fg.nrVars(); i++ )
             q.push_back( Factor(Var(i,2), zero) );
         logZ = 0.0;
         maxdiff = 0.0;
         iters = 1;
         has_logZ = false;
         has_maxdiff = false;
         has_iters = false;
     } else
         obj = newInfAlg( name, fg, opts );
     time += toc() - tic;
 }
Esempio n. 3
0
        /// Construct from factor graph \a fg, name \a _name, and set of properties \a opts
        TestDAI( const FactorGraph &fg, const string &_name, const PropertySet &opts ) : obj(NULL), name(_name), varErr(), facErr(), varMarginals(), facMarginals(), allMarginals(), logZ(0.0), maxdiff(0.0), time(0), iters(0U), has_logZ(false), has_maxdiff(false), has_iters(false) {
            double tic = toc();

            if( name == "LDPC" ) {
                // special case: simulating a Low Density Parity Check code
                Real zero[2] = {1.0, 0.0};
                for( size_t i = 0; i < fg.nrVars(); i++ )
                    varMarginals.push_back( Factor(fg.var(i), zero) );
                allMarginals = varMarginals;
                logZ = 0.0;
                maxdiff = 0.0;
                iters = 1;
                has_logZ = false;
                has_maxdiff = false;
                has_iters = false;
            } else
                // create a corresponding InfAlg object
                obj = newInfAlg( name, fg, opts );

            // Add the time needed to create the object
            time += toc() - tic;
        }
Esempio n. 4
0
int main( int argc, char *argv[] ) {
    if ( argc != 2 ) {
        cout << "Usage: " << argv[0] << " <filename.fg>" << endl << endl;
        cout << "Reads factor graph <filename.fg> and verifies" << endl;
        cout << "whether BBP works correctly on it." << endl << endl;
        return 1;
    } else {
        // Read FactorGraph from the file specified by the first command line argument
        FactorGraph fg;
        fg.ReadFromFile(argv[1]);

        // Set some constants
        size_t verbose = 0;
        Real   tol = 1.0e-9;
        size_t maxiter = 10000;
        Real   damping = 0.0;

        // Store the constants in a PropertySet object
        PropertySet opts;
        opts.set("verbose",verbose);  // Verbosity (amount of output generated)
        opts.set("tol",tol);          // Tolerance for convergence
        opts.set("maxiter",maxiter);  // Maximum number of iterations
        opts.set("damping",damping);  // Amount of damping applied

        // Construct a BP (belief propagation) object from the FactorGraph fg
        BP bp(fg, opts("updates",string("SEQFIX"))("logdomain",false));
        bp.recordSentMessages = true;
        bp.init();
        bp.run();

        vector<size_t> state( fg.nrVars(), 0 );

        for( size_t t = 0; t < 45; t++ ) {
            BBP::Properties::UpdateType updates;
            switch( t % 5 ) {
                case BBP::Properties::UpdateType::SEQ_FIX:
                    updates = BBP::Properties::UpdateType::SEQ_FIX;
                    break;
                case BBP::Properties::UpdateType::SEQ_MAX:
                    updates = BBP::Properties::UpdateType::SEQ_MAX;
                    break;
                case BBP::Properties::UpdateType::SEQ_BP_REV:
                    updates = BBP::Properties::UpdateType::SEQ_BP_REV;
                    break;
                case BBP::Properties::UpdateType::SEQ_BP_FWD:
                    updates = BBP::Properties::UpdateType::SEQ_BP_FWD;
                    break;
                case BBP::Properties::UpdateType::PAR:
                    updates = BBP::Properties::UpdateType::PAR;
                    break;
            }
            BBPCostFunction cfn;
            switch( (t / 5) % 9 ) {
                case 0:
                    cfn = BBPCostFunction::CFN_GIBBS_B;
                    break;
                case 1:
                    cfn = BBPCostFunction::CFN_GIBBS_B2;
                    break;
                case 2:
                    cfn = BBPCostFunction::CFN_GIBBS_EXP;
                    break;
                case 3:
                    cfn = BBPCostFunction::CFN_GIBBS_B_FACTOR;
                    break;
                case 4:
                    cfn = BBPCostFunction::CFN_GIBBS_B2_FACTOR;
                    break;
                case 5:
                    cfn = BBPCostFunction::CFN_GIBBS_EXP_FACTOR;
                    break;
                case 6:
                    cfn = BBPCostFunction::CFN_VAR_ENT;
                    break;
                case 7:
                    cfn = BBPCostFunction::CFN_FACTOR_ENT;
                    break;
                case 8:
                    cfn = BBPCostFunction::CFN_BETHE_ENT;
                    break;
            }

            Real h = 1e-4;
            Real result = numericBBPTest( bp, &state, opts("updates",updates), cfn, h );
            cout << "result: " << result << ",\tupdates=" << updates << ", cfn=" << cfn << endl;
        }
    }

    return 0;
}
Esempio n. 5
0
int main( int argc, char *argv[] ) {
	int i;

	char* myString = (char*) malloc (50);

    if ( argc < 3 ) {
        cout << "Usage: Filename and then Number of Nodes in the One Loop Graph. " << endl;
        cout << "Reads filename, it creates the fg file and then runs inference algorithms" << endl;
        return 1;
    } else {


    	strcpy(myString,"Results");
    	strcat(myString,argv[1]);
    	ofstream file( myString,ios::out);


        FactorGraph fg;
        vector<Var> vars;
        vector<Factor> factors;

        //Number of variables.
        size_t dimx=atoi(argv[2]);
        double J=0.5;
        size_t N=dimx;
        vars.reserve( N );
        for( size_t i = 0; i < N; i++ )
            vars.push_back( Var( i, 2 ) );

        factors.reserve( N );
 
        for( size_t i = 0; i < dimx; i++ ){
            // Add a pairwise interaction with the next neighboring pixel
            	   if (i!=dimx-1)
            	    factors.push_back( createFactorIsing( vars[i], vars[i+1], J ) );
            	   else if (i==dimx-1)
            		   factors.push_back( createFactorIsing( vars[i], vars[0], J ) );
            // Add a single-variable interaction with strength th.
            	    double th=0.1;
            	    factors.push_back( createFactorIsing( vars[i], th) );
            }

        fg=FactorGraph( factors.begin(), factors.end(), vars.begin(), vars.end(), factors.size(), vars.size() );
        fg.WriteToFile( strcat(myString,".fg") );

        cout << "1" << endl;

        // Set some constants
        size_t maxiter = 10000;
        Real   tol = 1e-9;
        size_t verb = 1;

        // Store the constants in a PropertySet object
        PropertySet opts,cavaiopts;
        opts.set("maxiter",maxiter);  // Maximum number of iterations
        opts.set("tol",tol);          // Tolerance for convergence
        opts.set("verbose",verb);     // Verbosity (amount of output generated)

        cavaiopts.set("maxiter",maxiter);  // Maximum number of iterations
        cavaiopts.set("tol",tol);          // Tolerance for convergence
        cavaiopts.set("verbose",verb);     // Verbosity (amount of output generated)
        cavaiopts.set("updates",string("HUGIN"));

        printf("Doing Juction Tree\n");
        JTree jt( fg, opts("updates",string("HUGIN")) );
        jt.init();
        jt.run();

        printf("Doing BP\n");
        BP bp(fg, opts("updates",string("SEQRND"))("logdomain",false));
        bp.init();
        bp.run();


        printf("Doing LC\n");
        LC lc(fg, opts("updates",string("SEQRND"))("logdomain",false)("cavity",string("PAIR"))("cavainame",string("BP"))("cavaiopts",string("[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0]")));
        //LC lc(fg, opts("updates",string("SEQRND"))("logdomain",false)("cavity",string("UNIFORM")));
        //LC lc(fg, opts("updates",string("SEQRND"))("logdomain",false)("cavity",string("FULL")));
        lc.init();
        lc.run();

        printf("Doing MR\n");
        MR mr(fg, opts("updates",string("LINEAR"))("logdomain",false)("inits",string("CLAMPING")));
        mr.init();
        mr.run();

        // Report variable marginals for fg, calculated by the junction tree algorithm
        file << "Exact variable marginals:" << endl;
        for( size_t i = 0; i < fg.nrVars(); i++ ) // iterate over all variables in fg
        	file << jt.belief(fg.var(i)) << endl; // display the "belief" of jt for that variable
        file << "\n" << endl;


        // Report variable marginals for fg, calculated by the belief propagation algorithm
        file << "Approximate (LBF) variable marginals:" << endl;
        for( size_t i = 0; i < fg.nrVars(); i++ ) // iterate over all variables in fg
        	file << bp.belief(fg.var(i)) << endl; // display the belief of bp for that variable

        file << "\n" << endl;

        // Report variable marginals for fg, calculated by the MoK07
        file << "Approximate (Loop Corrected MoK07) variable marginals:" << endl;
        for( size_t i = 0; i < fg.nrVars(); i++ ) // iterate over all variables in fg
        	file << lc.belief(fg.var(i)) << endl; // display the belief of bp for that variable

        file << "\n" << endl;

        // Report variable marginals for fg, calculated by the MR05
        file << "Approximate (Loop Corrected MR05) variable marginals:" << endl;
        for( size_t i = 0; i < fg.nrVars(); i++ ) // iterate over all variables in fg
        	file << mr.belief(fg.var(i)) << endl; // display the belief of bp for that variable

        file << "\n" << endl;

        file.close();
    	}

    return 0;
}
int main( int argc, char *argv[] ) {
    if ( argc != 3 ) {
        cout << "Usage: " << argv[0] << " <filename.fg> [map|pd]" << endl << endl;
        cout << "Reads factor graph <filename.fg> and runs" << endl;
        cout << "map: Junction tree MAP" << endl;
        cout << "pd : LBP and posterior decoding" << endl << endl;
        return 1;
    } else {
        // Redirect cerr to inf.log
        ofstream errlog("inf.log");
        //streambuf* orig_cerr = cerr.rdbuf();
        cerr.rdbuf(errlog.rdbuf());

        // Read FactorGraph from the file specified by the first command line argument
        FactorGraph fg;
        fg.ReadFromFile(argv[1]);

        // Set some constants
        size_t maxiter = 10000;
        Real   tol = 1e-9;
        size_t verb = 1;

        // Store the constants in a PropertySet object
        PropertySet opts;
        opts.set("maxiter",maxiter);  // Maximum number of iterations
        opts.set("tol",tol);          // Tolerance for convergence
        opts.set("verbose",verb);     // Verbosity (amount of output generated)

        if (strcmp(argv[2], "map") == 0) {
            // Construct another JTree (junction tree) object that is used to calculate
            // the joint configuration of variables that has maximum probability (MAP state)
            JTree jtmap( fg, opts("updates",string("HUGIN"))("inference",string("MAXPROD")) );
            // Initialize junction tree algorithm
            jtmap.init();
            // Run junction tree algorithm
            jtmap.run();
            // Calculate joint state of all variables that has maximum probability
            vector<size_t> jtmapstate = jtmap.findMaximum();

            /*
            // Report exact MAP variable marginals
            cout << "Exact MAP variable marginals:" << endl;
            for( size_t i = 0; i < fg.nrVars(); i++ )
                cout << jtmap.belief(fg.var(i)) << endl;
            */

            // Report exact MAP joint state
            cerr << "Exact MAP state (log score = " << fg.logScore( jtmapstate ) << "):" << endl;
            cout << fg.nrVars() << endl;
            for( size_t i = 0; i < jtmapstate.size(); i++ )
                cout << fg.var(i).label() << " " << jtmapstate[i] + 1 << endl; // +1 because in MATLAB assignments start at 1
        } else if (strcmp(argv[2], "pd") == 0) {

            // Construct a BP (belief propagation) object from the FactorGraph fg
            // using the parameters specified by opts and two additional properties,
            // specifying the type of updates the BP algorithm should perform and
            // whether they should be done in the real or in the logdomain
            BP bp(fg, opts("updates",string("SEQMAX"))("logdomain",true));
            // Initialize belief propagation algorithm
            bp.init();
            // Run belief propagation algorithm
            bp.run();

            // Report variable marginals for fg, calculated by the belief propagation algorithm
            cerr << "LBP posterior decoding (highest prob assignment in marginal):" << endl;
            cout << fg.nrVars() << endl;
            for( size_t i = 0; i < fg.nrVars(); i++ ) {// iterate over all variables in fg
                //cout << bp.belief(fg.var(i)) << endl; // display the belief of bp for that variable
                Factor marginal = bp.belief(fg.var(i));
                Real maxprob = marginal.max();
                for (size_t j = 0; j < marginal.nrStates(); j++) {
                    if (marginal[j] == maxprob) {
                        cout << fg.var(i).label() << " " << j + 1 << endl; // +1 because in MATLAB assignments start at 1
                    }
                }
            }
        } else {
            cerr << "Invalid inference algorithm specified." << endl;
            return 1;
        }
    }

    return 0;
}
/// Main function
int main( int argc, char *argv[] ) {
    try {
        // Variables for storing command line arguments
        size_t seed;
        size_t states = 2;
        string type;
        size_t d, N, K, k, j, n1, n2, n3, prime;
        bool periodic = false;
        FactorType ft;
        LDPCType ldpc;
        Real beta, sigma_w, sigma_th, mean_w, mean_th, noise;

        // Declare the supported options.
        po::options_description opts("General command line options");
        opts.add_options()
            ("help",     "produce help message")
            ("seed",     po::value<size_t>(&seed),   "random number seed (tries to read from /dev/urandom if not specified)")
            ("states",   po::value<size_t>(&states), "number of states of each variable (default=2 for binary variables)")
        ;

        // Graph structure options
        po::options_description opts_graph("Options for specifying graph structure");
        opts_graph.add_options()
            ("type",     po::value<string>(&type),   "factor graph type (one of 'FULL', 'DREG', 'LOOP', 'TREE', 'GRID', 'GRID3D', 'HOI', 'LDPC')")
            ("d",        po::value<size_t>(&d),      "variable connectivity (only for type=='DREG');\n\t<d><N> should be even")
            ("N",        po::value<size_t>(&N),      "number of variables (not for type=='GRID','GRID3D')")
            ("n1",       po::value<size_t>(&n1),     "width of grid (only for type=='GRID','GRID3D')")
            ("n2",       po::value<size_t>(&n2),     "height of grid (only for type=='GRID','GRID3D')")
            ("n3",       po::value<size_t>(&n3),     "length of grid (only for type=='GRID3D')")
            ("periodic", po::value<bool>(&periodic), "periodic grid? (only for type=='GRID','GRID3D'; default=0)")
            ("K",        po::value<size_t>(&K),      "number of factors (only for type=='HOI','LDPC')")
            ("k",        po::value<size_t>(&k),      "number of variables per factor (only for type=='HOI','LDPC')")
        ;

        // Factor options
        po::options_description opts_factors("Options for specifying factors");
        opts_factors.add_options()
            ("factors",  po::value<FactorType>(&ft), "factor type (one of 'EXPGAUSS','POTTS','ISING')")
            ("beta",     po::value<Real>(&beta),     "inverse temperature (ignored for factors=='ISING')")
            ("mean_w",   po::value<Real>(&mean_w),   "mean of pairwise interactions w_{ij} (only for factors=='ISING')")
            ("mean_th",  po::value<Real>(&mean_th),  "mean of unary interactions th_i (only for factors=='ISING')")
            ("sigma_w",  po::value<Real>(&sigma_w),  "stddev of pairwise interactions w_{ij} (only for factors=='ISING')")
            ("sigma_th", po::value<Real>(&sigma_th), "stddev of unary interactions th_i (only for factors=='ISING'")
        ;

        // LDPC options
        po::options_description opts_ldpc("Options for specifying LDPC code factor graphs");
        opts_ldpc.add_options()
            ("ldpc",     po::value<LDPCType>(&ldpc), "type of LDPC code (one of 'SMALL','GROUP','RANDOM')")
            ("j",        po::value<size_t>(&j),      "number of parity checks per bit (only for type=='LDPC')")
            ("noise",    po::value<Real>(&noise),    "bitflip probability for binary symmetric channel (only for type=='LDPC')")
            ("prime",    po::value<size_t>(&prime),  "prime number for construction of LDPC code (only for type=='LDPC' with ldpc='GROUP'))")
        ;

        // All options
        opts.add(opts_graph).add(opts_factors).add(opts_ldpc);

        // Parse command line arguments
        po::variables_map vm;
        po::store(po::parse_command_line(argc, argv, opts), vm);
        po::notify(vm);

        // Display help message if necessary
        if( vm.count("help") || !vm.count("type") ) {
            cout << "This program is part of libDAI - http://www.libdai.org/" << endl << endl;
            cout << "Usage: ./createfg [options]" << endl << endl;
            cout << "Creates a factor graph according to the specified options." << endl << endl;
            
            cout << endl << opts << endl;
            
            cout << "The following factor graph types with pairwise interactions can be created:" << endl;
            cout << "\t'FULL':   fully connected graph of <N> variables" << endl;
            cout << "\t'DREG':   random regular graph of <N> variables where each variable is connected with <d> others" << endl;
            cout << "\t'LOOP':   a single loop of <N> variables" << endl;
            cout << "\t'TREE':   random tree-structured (acyclic, connected) graph of <N> variables" << endl;
            cout << "\t'GRID':   2D grid of <n1>x<n2> variables" << endl;
            cout << "\t'GRID3D': 3D grid of <n1>x<n2>x<n3> variables" << endl;
            cout << "The following higher-order interactions factor graphs can be created:" << endl;
            cout << "\t'HOI':    random factor graph consisting of <N> variables and <K> factors," << endl;
            cout << "\t          each factor being an interaction of <k> variables." << endl;
            cout << "The following LDPC code factor graphs can be created:" << endl;
            cout << "\t'LDPC':   simulates LDPC decoding problem, using an LDPC code of <N> bits and <K>" << endl;
            cout << "\t          parity checks, with <k> bits per check and <j> checks per bit, transmitted" << endl;
            cout << "\t          on a binary symmetric channel with probability <noise> of flipping a bit." << endl;
            cout << "\t          The transmitted codeword has all bits set to zero. The argument 'ldpc'" << endl;
            cout << "\t          determines how the LDPC code is constructed: either using a group structure," << endl;
            cout << "\t          or randomly, or a fixed small code with (N,K,k,j) = (4,4,3,3)." << endl << endl;

            cout << "For all types except type=='LDPC', the factors have to be specified as well." << endl << endl;

            cout << "EXPGAUSS factors (the default) are created by drawing all log-factor entries" << endl;
            cout << "independently from a Gaussian with mean 0 and standard deviation <beta>." << endl << endl;
            
            cout << "In case of pairwise interactions, one can also choose POTTS factors, for which" << endl;
            cout << "the log-factors are simply delta functions multiplied by the strength <beta>." << endl << endl;

            cout << "For pairwise interactions and binary variables, one can also use ISING factors." << endl;
            cout << "Here variables x1...xN are assumed to be +1/-1--valued, and unary interactions" << endl;
            cout << "are of the form exp(th*xi) with th drawn from a Gaussian distribution with mean" << endl;
            cout << "<mean_th> and standard deviation <sigma_th>, and pairwise interactions are of the" << endl;
            cout << "form exp(w*xi*xj) with w drawn from a Gaussian distribution with mean <mean_w>" << endl;
            cout << "and standard deviation <sigma_w>." << endl;
            return 1;
        }

        // Set default number of states
        if( !vm.count("states") )
            states = 2;

        // Set default factor type
        if( !vm.count("factors") )
            ft = FactorType::EXPGAUSS;
        // Check validness of factor type
        if( ft == FactorType::POTTS )
            if( type == HOI_TYPE )
                throw "For factors=='POTTS', interactions should be pairwise (type!='HOI')";
        if( ft == FactorType::ISING )
            if( ((states != 2) || (type == HOI_TYPE)) )
                throw "For factors=='ISING', variables should be binary (states==2) and interactions should be pairwise (type!='HOI')";

        // Read random seed
        if( !vm.count("seed") ) {
            ifstream infile;
            bool success;
            infile.open( "/dev/urandom" );
            success = infile.is_open();
            if( success ) {
                infile.read( (char *)&seed, sizeof(size_t) / sizeof(char) );
                success = infile.good();
                infile.close();
            }
            if( !success )
                throw "Please specify random number seed.";
        }
        rnd_seed( seed );

        // Set default periodicity
        if( !vm.count("periodic") )
            periodic = false;

        // Store some options in a PropertySet object
        PropertySet options;
        if( vm.count("mean_th") )
            options.Set("mean_th", mean_th);
        if( vm.count("sigma_th") )
            options.Set("sigma_th", sigma_th);
        if( vm.count("mean_w") )
            options.Set("mean_w", mean_w);
        if( vm.count("sigma_w") )
            options.Set("sigma_w", sigma_w);
        if( vm.count("beta") )
            options.Set("beta", beta);

        // Output some comments
        cout << "# Factor graph made by " << argv[0] << endl;
        cout << "# type = " << type << endl;
        cout << "# states = " << states << endl;

        // The factor graph to be constructed
        FactorGraph fg;

#define NEED_ARG(name, desc) do { if(!vm.count(name)) throw "Please specify " desc " with --" name; } while(0);

        if( type == FULL_TYPE || type == DREG_TYPE || type == LOOP_TYPE || type == TREE_TYPE || type == GRID_TYPE || type == GRID3D_TYPE ) {
            // Pairwise interactions

            // Check command line options
            if( type == GRID_TYPE ) {
                NEED_ARG("n1", "width of grid");
                NEED_ARG("n2", "height of grid");
                N = n1 * n2;
            } else if( type == GRID3D_TYPE ) {
                NEED_ARG("n1", "width of grid");
                NEED_ARG("n2", "height of grid");
                NEED_ARG("n3", "depth of grid");
                N = n1 * n2 * n3;
            } else
                NEED_ARG("N", "number of variables");

            if( states > 2 || ft == FactorType::POTTS ) {
                NEED_ARG("beta", "stddev of log-factor entries");
            } else {
                NEED_ARG("mean_w", "mean of pairwise interactions");
                NEED_ARG("mean_th", "mean of unary interactions");
                NEED_ARG("sigma_w", "stddev of pairwise interactions");
                NEED_ARG("sigma_th", "stddev of unary interactions");
            }

            if( type == DREG_TYPE )
                NEED_ARG("d", "connectivity (number of neighboring variables of each variable)");

            // Build pairwise interaction graph
            GraphAL G;
            if( type == FULL_TYPE )
                G = createGraphFull( N );
            else if( type == DREG_TYPE )
                G = createGraphRegular( N, d );
            else if( type == LOOP_TYPE )
                G = createGraphLoop( N );
            else if( type == TREE_TYPE )
                G = createGraphTree( N );
            else if( type == GRID_TYPE )
                G = createGraphGrid( n1, n2, periodic );
            else if( type == GRID3D_TYPE )
                G = createGraphGrid3D( n1, n2, n3, periodic );

            // Construct factor graph from pairwise interaction graph
            fg = createFG( G, ft, states, options );

            // Output some additional comments
            if( type == GRID_TYPE || type == GRID3D_TYPE ) {
                cout << "# n1 = " << n1 << endl;
                cout << "# n2 = " << n2 << endl;
                if( type == GRID3D_TYPE )
                    cout << "# n3 = " << n3 << endl;
            }
            if( type == DREG_TYPE )
                cout << "# d = " << d << endl;
            cout << "# options = " << options << endl;
        } else if( type == HOI_TYPE ) {
            // Higher order interactions

            // Check command line arguments
            NEED_ARG("N", "number of variables");
            NEED_ARG("K", "number of factors");
            NEED_ARG("k", "number of variables per factor");
            NEED_ARG("beta", "stddev of log-factor entries");

            // Create higher-order interactions factor graph
            do {
                fg = createHOIFG( N, K, k, beta );
            } while( !fg.isConnected() );

            // Output some additional comments
            cout << "# K = " << K << endl;
            cout << "# k = " << k << endl;
            cout << "# beta = " << beta << endl;
        } else if( type == LDPC_TYPE ) {
            // LDPC codes

            // Check command line arguments
            NEED_ARG("ldpc", "type of LDPC code");
            NEED_ARG("noise", "bitflip probability for binary symmetric channel");

            // Check more command line arguments (seperately for each LDPC type)
            if( ldpc == LDPCType::RANDOM ) {
                NEED_ARG("N", "number of variables");
                NEED_ARG("K", "number of factors");
                NEED_ARG("k", "number of variables per factor");
                NEED_ARG("j", "number of parity checks per bit");
                if( N * j != K * k )
                    throw "Parameters should satisfy N * j == K * k";
            } else if( ldpc == LDPCType::GROUP ) {
                NEED_ARG("prime", "prime number");
                NEED_ARG("k", "number of variables per factor");
                NEED_ARG("j", "number of parity checks per bit");

                if( !isPrime(prime) )
                    throw "Parameter <prime> should be prime";
                if( !((prime-1) % j == 0 ) )
                    throw "Parameters should satisfy (prime-1) % j == 0";
                if( !((prime-1) % k == 0 ) )
                    throw "Parameters should satisfy (prime-1) % k == 0";

                N = prime * k;
                K = prime * j;
            } else if( ldpc == LDPCType::SMALL ) {
                N = 4;
                K = 4;
                j = 3;
                k = 3;
            }

            // Output some additional comments
            cout << "# N = " << N << endl;
            cout << "# K = " << K << endl;
            cout << "# j = " << j << endl;
            cout << "# k = " << k << endl;
            if( ldpc == LDPCType::GROUP )
                cout << "# prime = " << prime << endl;
            cout << "# noise = " << noise << endl;

            // Construct likelihood and paritycheck factors
            Real likelihood[4] = {1.0 - noise, noise, noise, 1.0 - noise};
            Real *paritycheck = new Real[1 << k];
            createParityCheck(paritycheck, k, 0.0);

            // Create LDPC structure
            BipartiteGraph ldpcG;
            bool regular;
            do {
                if( ldpc == LDPCType::GROUP )
                    ldpcG = createGroupStructuredLDPCGraph( prime, j, k );
                else if( ldpc == LDPCType::RANDOM )
                    ldpcG = createRandomBipartiteGraph( N, K, j, k );
                else if( ldpc == LDPCType::SMALL )
                    ldpcG = createSmallLDPCGraph();

                regular = true;
                for( size_t i = 0; i < N; i++ )
                    if( ldpcG.nb1(i).size() != j )
                        regular = false;
                for( size_t I = 0; I < K; I++ )
                    if( ldpcG.nb2(I).size() != k )
                        regular = false;
            } while( !regular && !ldpcG.isConnected() );

            // Convert to FactorGraph
            vector<Factor> factors;
            for( size_t I = 0; I < K; I++ ) {
                VarSet vs;
                for( size_t _i = 0; _i < k; _i++ ) {
                    size_t i = ldpcG.nb2(I)[_i];
                    vs |= Var( i, 2 );
                }
                factors.push_back( Factor( vs, paritycheck ) );
            }
            delete paritycheck;

            // Generate noise vector
            vector<char> noisebits(N,0);
            size_t bitflips = 0;
            for( size_t i = 0; i < N; i++ ) {
                if( rnd_uniform() < noise ) {
                    noisebits[i] = 1;
                    bitflips++;
                }
            }
            cout << "# bitflips = " << bitflips << endl;

            // Simulate transmission of all-zero codeword
            vector<char> input(N,0);
            vector<char> output(N,0);
            for( size_t i = 0; i < N; i++ )
                output[i] = (input[i] + noisebits[i]) & 1;

            // Add likelihoods
            for( size_t i = 0; i < N; i++ )
               factors.push_back( Factor(Var(i,2), likelihood + output[i]*2) );

            // Construct Factor Graph
            fg = FactorGraph( factors );
        } else
            throw "Invalid type";

        // Output additional comments
        cout << "# N = " << fg.nrVars() << endl;
        cout << "# seed = " << seed << endl;

        // Output factor graph
        cout << fg;
    } catch( const char *e ) {
        /// Display error message
        cerr << "Error: " << e << endl;
        return 1;
    }

    return 0;
}
Esempio n. 8
0
void RegionGraph::constructCVM( const FactorGraph &fg, const std::vector<VarSet> &cl, size_t verbose ) {
    if( verbose )
        cerr << "constructCVM called (" << fg.nrVars() << " vars, " << fg.nrFactors() << " facs, " << cl.size() << " clusters)" << endl;

    // Retain only maximal clusters
    if( verbose )
        cerr << "  Constructing ClusterGraph" << endl;
    ClusterGraph cg( cl );
    if( verbose )
        cerr << "  Erasing non-maximal clusters" << endl;
    cg.eraseNonMaximal();

    // Create inner regions - first pass
    if( verbose )
        cerr << "  Creating inner regions (first pass)" << endl;
    set<VarSet> betas;
    for( size_t alpha = 0; alpha < cg.nrClusters(); alpha++ )
        for( size_t alpha2 = alpha; (++alpha2) != cg.nrClusters(); ) {
            VarSet intersection = cg.cluster(alpha) & cg.cluster(alpha2);
            if( intersection.size() > 0 )
                betas.insert( intersection );
        }

    // Create inner regions - subsequent passes
    if( verbose )
        cerr << "  Creating inner regions (next passes)" << endl;
    set<VarSet> new_betas;
    do {
        new_betas.clear();
        for( set<VarSet>::const_iterator gamma = betas.begin(); gamma != betas.end(); gamma++ )
            for( set<VarSet>::const_iterator gamma2 = gamma; (++gamma2) != betas.end(); ) {
                VarSet intersection = (*gamma) & (*gamma2);
                if( (intersection.size() > 0) && (betas.count(intersection) == 0) )
                    new_betas.insert( intersection );
            }
        betas.insert(new_betas.begin(), new_betas.end());
    } while( new_betas.size() );

    // Create inner regions - final phase
    if( verbose )
        cerr << "  Creating inner regions (final phase)" << endl;
    vector<Region> irs;
    irs.reserve( betas.size() );
    for( set<VarSet>::const_iterator beta = betas.begin(); beta != betas.end(); beta++ )
        irs.push_back( Region(*beta,0.0) );

    // Create edges
    if( verbose )
        cerr << "  Creating edges" << endl;
    vector<pair<size_t,size_t> > edges;
    for( size_t beta = 0; beta < irs.size(); beta++ )
        for( size_t alpha = 0; alpha < cg.nrClusters(); alpha++ )
            if( cg.cluster(alpha) >> irs[beta] )
                edges.push_back( pair<size_t,size_t>(alpha,beta) );

    // Construct region graph
    if( verbose )
        cerr << "  Constructing region graph" << endl;
    construct( fg, cg.clusters(), irs, edges );

    // Calculate counting numbers
    if( verbose )
        cerr << "  Calculating counting numbers" << endl;
    calcCVMCountingNumbers();
    
    if( verbose )
        cerr << "Done." << endl;
}
Esempio n. 9
0
int main( int argc, char *argv[] ) {
    if( argc != 3 ) {
        cout << "Usage: " << argv[0] << " <in.fg> <tw>" << endl << endl;
        cout << "Reports some characteristics of the .fg network." << endl;
        cout << "Also calculates treewidth (which may take some time) unless <tw> == 0." << endl;
        return 1;
    } else {
        // Read factorgraph
        FactorGraph fg;
        char *infile = argv[1];
        int calc_tw = atoi(argv[2]);
        fg.ReadFromFile( infile );

        cout << "Number of variables:   " << fg.nrVars() << endl;
        cout << "Number of factors:     " << fg.nrFactors() << endl;
        cout << "Connected:             " << fg.isConnected() << endl;
        cout << "Tree:                  " << fg.isTree() << endl;
        cout << "Has short loops:       " << hasShortLoops(fg.factors()) << endl;
        cout << "Has negatives:         " << hasNegatives(fg.factors()) << endl;
        cout << "Binary variables?      " << fg.isBinary() << endl;
        cout << "Pairwise interactions? " << fg.isPairwise() << endl;
        if( calc_tw ) {
            std::pair<size_t,size_t> tw = treewidth(fg);
            cout << "Treewidth:           " << tw.first << endl;
            cout << "Largest cluster for JTree has " << tw.second << " states " << endl;
        }
        double stsp = 1.0;
        for( size_t i = 0; i < fg.nrVars(); i++ )
            stsp *= fg.var(i).states();
        cout << "Total state space:   " << stsp << endl;

        double cavsum_lcbp = 0.0;
        double cavsum_lcbp2 = 0.0;
        size_t max_Delta_size = 0;
        map<size_t,size_t> cavsizes;
        for( size_t i = 0; i < fg.nrVars(); i++ ) {
            VarSet di = fg.delta(i);
            if( cavsizes.count(di.size()) )
                cavsizes[di.size()]++;
            else
                cavsizes[di.size()] = 1;
            size_t Ds = fg.Delta(i).nrStates();
            if( Ds > max_Delta_size )
                max_Delta_size = Ds;
            cavsum_lcbp += di.nrStates();
            for( VarSet::const_iterator j = di.begin(); j != di.end(); j++ )
                cavsum_lcbp2 += j->states();
        }
        cout << "Maximum pancake has " << max_Delta_size << " states" << endl;
        cout << "LCBP with full cavities needs " << cavsum_lcbp << " BP runs" << endl;
        cout << "LCBP with only pairinteractions needs " << cavsum_lcbp2 << " BP runs" << endl;
        cout << "Cavity sizes: ";
        for( map<size_t,size_t>::const_iterator it = cavsizes.begin(); it != cavsizes.end(); it++ ) 
            cout << it->first << "(" << it->second << ") ";
        cout << endl;

        cout << "Type: " << (fg.isPairwise() ? "pairwise" : "higher order") << " interactions, " << (fg.isBinary() ? "binary" : "nonbinary") << " variables" << endl;

        if( fg.isPairwise() ) {
            bool girth_reached = false;
            size_t loopdepth;
            for( loopdepth = 2; loopdepth <= fg.nrVars() && !girth_reached; loopdepth++ ) {
                size_t nr_loops = countLoops( fg, loopdepth );
                cout << "Loops up to " << loopdepth << " variables: " << nr_loops << endl;
                if( nr_loops > 0 )
                    girth_reached = true;
            }
            if( girth_reached )
                cout << "Girth: " << loopdepth-1 << endl;
            else
                cout << "Girth: infinity" << endl;
        }

        return 0;
    }
}