Пример #1
0
void RegionGraph::constructCVM( const FactorGraph &fg, const std::vector<NodeSet> &cl) {
  using std::pair;

  DLOG(INFO) << "constructCVM called (" << fg.nrNodes() << " vars, " << fg.nrFactors() << " facs, " << cl.size() << " clusters)";

  // Retain only maximal clusters
  DLOG(INFO) << "  Constructing ClusterGraph";
  ClusterGraph cg( cl );
  DLOG(INFO) << "  Erasing non-maximal clusters";
  cg.eraseNonMaximal();

  // Create inner regions - first pass
  DLOG(INFO) << "  Creating inner regions (first pass)";
  std::set<NodeSet> betas;
  for( size_t alpha = 0; alpha < cg.nrClusters(); alpha++ )
    for( size_t alpha2 = alpha; (++alpha2) != cg.nrClusters(); ) {
      NodeSet intersection = cg.cluster(alpha) & cg.cluster(alpha2);
      if( intersection.size() > 0 )
        betas.insert( intersection );
    }

  // Create inner regions - subsequent passes
  DLOG(INFO) << "  Creating inner regions (next passes)";
  std::set<NodeSet> new_betas;
  do {
    new_betas.clear();
    for (std::set<NodeSet>::const_iterator gamma = betas.begin(); gamma != betas.end(); gamma++ )
      for (std::set<NodeSet>::const_iterator gamma2 = gamma; (++gamma2) != betas.end(); ) {
        NodeSet 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
  DLOG(INFO) << "  Creating inner regions (final phase)";
  std::vector<Region> irs;
  irs.reserve( betas.size() );
  for (std::set<NodeSet>::const_iterator beta = betas.begin(); beta != betas.end(); beta++ )
    irs.push_back( Region(*beta,0.0) );

  // Create edges
  DLOG(INFO) << "  Creating edges";
  std::vector<std::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
  DLOG(INFO) << "  Constructing region graph";
  construct( fg, cg.clusters(), irs, edges );

  // Calculate counting numbers
  DLOG(INFO) << "  Calculating counting numbers";
  calcCVMCountingNumbers();

  DLOG(INFO) << "Done.";
}
Пример #2
0
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) {
    char *filename;


    // Check for proper number of arguments
    if ((nrhs != NR_IN) || (nlhs != NR_OUT)) {
        mexErrMsgTxt("Usage: [psi] = dai_readfg(filename);\n\n"
        "\n"
        "INPUT:  filename   = filename of a .fg file\n"
        "\n"
        "OUTPUT: psi        = linear cell array containing the factors\n"
        "                     (psi{i} is a structure with a Member field\n"
        "                     and a P field, like a CPTAB).\n");
    }

    // Get input parameters
    size_t buflen;
    buflen = mxGetN( FILENAME_IN ) + 1;
    filename = (char *)mxCalloc( buflen, sizeof(char) );
    mxGetString( FILENAME_IN, filename, buflen );


    // Read factorgraph
    FactorGraph fg;
    try {
        fg.ReadFromFile( filename );
    } catch( std::exception &e ) {
        mexErrMsgTxt( e.what() );
    }


    // Save factors
    vector<Factor> psi;
    for( size_t I = 0; I < fg.nrFactors(); I++ )
        psi.push_back(fg.factor(I));


    // Hand over results to MATLAB
    PSI_OUT = Factors2mx(psi);


    return;
}
Пример #3
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;
    }
}