Пример #1
0
Factor LC::NewPancake (size_t i, size_t _I, bool & hasNaNs) {
    size_t I = nbV(i)[_I];
    Factor piet = _pancakes[i];

    // recalculate _pancake[i]
    VarSet Ivars = factor(I).vars();
    Factor A_I;
    for( VarSet::const_iterator k = Ivars.begin(); k != Ivars.end(); k++ )
        if( var(i) != *k )
            A_I *= (_pancakes[findVar(*k)] * factor(I).inverse()).marginal( Ivars / var(i), false );
    if( Ivars.size() > 1 )
        A_I ^= (1.0 / (Ivars.size() - 1));
    Factor A_Ii = (_pancakes[i] * factor(I).inverse() * _phis[i][_I].inverse()).marginal( Ivars / var(i), false );
    Factor quot = A_I / A_Ii;
    if( props.damping != 0.0 )
        quot = (quot^(1.0 - props.damping)) * (_phis[i][_I]^props.damping);

    piet *= quot / _phis[i][_I].normalized();
    _phis[i][_I] = quot.normalized();

    piet.normalize();

    if( piet.hasNaNs() ) {
        cerr << name() << "::NewPancake(" << i << ", " << _I << "):  has NaNs!" << endl;
        hasNaNs = true;
    }

    return piet;
}
Пример #2
0
Factor LC::belief (const VarSet &ns) const {
    if( ns.size() == 0 )
        return Factor();
    else if( ns.size() == 1 )
        return beliefV( findVar( *(ns.begin()) ) );
    else {
        DAI_THROW(BELIEF_NOT_AVAILABLE);
        return Factor();
    }
}
Factor ExactInf::belief( const VarSet &ns ) const {
    if( ns.size() == 0 )
        return Factor();
    else if( ns.size() == 1 ) {
        return beliefV( findVar( *(ns.begin()) ) );
    } else {
        size_t I;
        for( I = 0; I < nrFactors(); I++ )
            if( factor(I).vars() >> ns )
                break;
        if( I == nrFactors() )
            DAI_THROW(BELIEF_NOT_AVAILABLE);
        return beliefF(I).marginal(ns);
    }
}
/** \param N number of variables
 *  \param M number of factors
 *  \param k number of variables that each factor depends on
 *  \param beta standard-deviation of Gaussian log-factor entries
 */
FactorGraph createHOIFG( size_t N, size_t M, size_t k, Real beta ) {
    vector<Var> vars;
    vector<Factor> factors;

    vars.reserve(N);
    for( size_t i = 0; i < N; i++ )
        vars.push_back(Var(i,2));

    for( size_t I = 0; I < M; I++ ) {
        VarSet vars;
        while( vars.size() < k ) {
            do {
                size_t newind = (size_t)(N * rnd_uniform());
                Var newvar = Var(newind, 2);
                if( !vars.contains( newvar ) ) {
                    vars |= newvar;
                    break;
                }
            } while( 1 );
        }
        factors.push_back( createFactorExpGauss( vars, beta ) );
    }

    return FactorGraph( factors.begin(), factors.end(), vars.begin(), vars.end(), factors.size(), vars.size() );
}
Пример #5
0
void MakeHOIFG( size_t N, size_t M, size_t k, Real sigma, FactorGraph &fg ) {
    vector<Var> vars;
    vector<Factor> factors;

    vars.reserve(N);
    for( size_t i = 0; i < N; i++ )
        vars.push_back(Var(i,2));

    for( size_t I = 0; I < M; I++ ) {
        VarSet vars;
        while( vars.size() < k ) {
            do {
                size_t newind = (size_t)(N * rnd_uniform());
                Var newvar = Var(newind, 2);
                if( !vars.contains( newvar ) ) {
                    vars |= newvar;
                    break;
                }
            } while( 1 );
        }
        factors.push_back( RandomFactor( vars, sigma ) );
    }

    fg = FactorGraph( factors.begin(), factors.end(), vars.begin(), vars.end(), factors.size(), vars.size() );
}
Пример #6
0
void findLoopClusters( const FactorGraph & fg, std::set<VarSet> &allcl, VarSet newcl, const Var & root, size_t length, VarSet vars ) {
    for( VarSet::const_iterator in = vars.begin(); in != vars.end(); in++ ) {
        VarSet ind = fg.delta( *in );
        if( (newcl.size()) >= 2 && ind.contains( root ) ) {
            allcl.insert( newcl | *in );
        }
        else if( length > 1 )
            findLoopClusters( fg, allcl, newcl | *in, root, length - 1, ind / newcl );
    }
}
Пример #7
0
/* Convert cell vector of Matlab sets to vector<VarSet> */
vector<VarSet> mx2VarSets(const mxArray *vs, const FactorGraph &fg, long verbose, vector<Permute> &perms) {
    vector<VarSet> varsets;

    int n1 = mxGetM(vs);
    int n2 = mxGetN(vs);
    if( n2 != 1 && n1 != 1 )
        mexErrMsgTxt("varsets should be a Nx1 or 1xN cell matrix.");
    size_t nr_vs = n1;
    if( n1 == 1 )
        nr_vs = n2;

    // interpret vs, linear cell array of varsets
    varsets.reserve( nr_vs );
    perms.clear();
    perms.reserve( nr_vs );
    for( size_t cellind = 0; cellind < nr_vs; cellind++ ) {
        if( verbose >= 3 )
            cerr << "reading varset " << cellind << ": " << endl;
        mxArray *cell = mxGetCell(vs, cellind);
        if( verbose >= 3 )
            cerr << "  got cell " << endl;
        size_t nr_mem = mxGetN(cell);
        if( verbose >= 3 )
            cerr << "  number members: " << nr_mem << endl;
        double *members = mxGetPr(cell);
        if( verbose >= 3 )
            cerr << "  got them! " << endl;

        // add variables
        VarSet vsvars;
        if( verbose >= 3 )
            cerr << "  vars: ";
        vector<long> labels(nr_mem,0);
        vector<size_t> dims(nr_mem,0);
        for( size_t mi = 0; mi < nr_mem; mi++ ) {
            labels[mi] = (long)members[mi];
            dims[mi] = fg.var(labels[mi]).states();
            if( verbose >= 3 )
                cerr << labels[mi] << " ";
            vsvars.insert( fg.var(labels[mi]) );
        }
        if( verbose >= 3 )
            cerr << endl;
        DAI_ASSERT( nr_mem == vsvars.size() );
        varsets.push_back(vsvars);

        // calculate permutation matrix
        vector<size_t> perm(nr_mem,0);
        VarSet::iterator j = vsvars.begin();
        for( size_t mi = 0; mi < nr_mem; mi++,j++ ) {
            long gezocht = j->label();
            vector<long>::iterator piet = find(labels.begin(),labels.end(),gezocht);
            perm[mi] = piet - labels.begin();
        }
        if( verbose >= 3 ) {
            cerr << endl << "  perm: ";
            for( vector<size_t>::iterator r=perm.begin(); r!=perm.end(); r++ )
                cerr << *r << " ";
            cerr << endl;
        }
        // create Permute object
        vector<size_t> di(nr_mem,0);
        size_t prod = 1;
        for( size_t k = 0; k < nr_mem; k++ ) {
            di[k] = dims[k];
            prod *= dims[k];
        }
        Permute permindex( di, perm );
        perms.push_back( permindex );
    }

    if( verbose >= 3 ) {
        for(vector<VarSet>::const_iterator I=varsets.begin(); I!=varsets.end(); I++ )
            cerr << *I << endl;
    }

    return( varsets );
}
Пример #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;
}
Пример #9
0
void CobwebGraph::setCountingNumbers( bool debugging ) {
    // should handle the case when one region in the msg-region graph is subset of another or even to top regions are the same
    _cn.reserve( nrCWs() );
    for( size_t R = 0; R < _INRs.size(); R++ ) {
        vector<VarSet> topR;
        // finding the intersection of messages
        SmallSet<VarSet> betas;
        for( size_t m1 = 0; m1 < M(R).size(); m1++ ) {
            topR.push_back( M(R,m1).msg.vars() );
            for( size_t m2 = 0; m2 < M(R).size(); m2++ ) {
                if( m1 == m2 )
                    continue;
                VarSet b = M(R,m1).msg.vars() & M(R,m2).msg.vars();
                if( b.size() == 0 )
                    continue;
                betas.insert( b );
            }
        }
        if( debugging )
            cerr << "topR: " << topR << endl;

        // finding the intersections of intersections
        bool somechange = true;
        while( somechange ) {
            SmallSet<VarSet> newbetas;
            somechange = false;
            bforeach( const VarSet &b1, betas ) {
                bforeach( const VarSet &b2, betas ) {
                    if( b1 == b2 )
                        continue;
                    VarSet b3 = b1 & b2;
                    if( betas.contains(b3) || b3.size() == 0 )
                        continue;
                    newbetas |= b3;
                    somechange = true;
                }
            }
            betas |= newbetas;
        }
        if( debugging )
            cerr << "betas: " << betas << endl;

        // set the counting number
        _cn.push_back( map<VarSet, pair<int, vector<size_t> > >() );
        // adding sub-regions of every message
        for( size_t i = 0; i < topR.size(); i++ ) {
            M(R,i).subregions.clear();
            bforeach( const VarSet& b, betas )
                if( b << topR[i] )
                    M(R,i).subregions.push_back( b );
        }
        SmallSet<VarSet> subVisited;
        SmallSet<VarSet> topRSet( topR.begin(), topR.end(), topR.size() );
        // looks to see if all parents of a sub-region got their counting number
        while( !betas.empty() ) {
            bforeach( const VarSet &beta, betas ) {
                bool allparentsset = true;
                bforeach( const VarSet &beta2, betas )
                    if( beta2 >> beta && beta2 != beta ) {
                        allparentsset = false;
                        break;
                    }
                if( allparentsset ) {
                    // the first in the pair is cn and the second the index of top regions containing it
                    _cn[R][beta] = make_pair( 1, vector<size_t>() );
                    for( size_t TR = 0; TR < topR.size(); TR++ ) {
                        if( topR[TR] >> beta ) {
                            _cn[R][beta].first--;
                            _cn[R][beta].second.push_back( TR );
                        }
                    }
                    bforeach( const VarSet& possibleparent, subVisited )
                        if( possibleparent >> beta )
                            _cn[R][beta].first -= _cn[R][possibleparent].first;

                    if( debugging )
                        cerr << "cn[" << R << "][" << beta << "] <- " << _cn[R][beta] << endl;
                    subVisited.insert( beta );
                    betas /= beta;
                    break; // since betas has changed we need to enter the loop again
                }
            }
        }
Пример #10
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;
    }
}