9a3e624f9ef7741256cf048ec1e63f0821e4c507
1 /* Copyright (C) 2006-2008 Joris Mooij [j dot mooij at science dot ru dot nl]
2 Radboud University Nijmegen, The Netherlands
4 This file is part of libDAI.
6 libDAI is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 libDAI is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with libDAI; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <dai/regiongraph.h>
25 #include <dai/factorgraph.h>
26 #include <dai/clustergraph.h>
35 RegionGraph::RegionGraph(const FactorGraph
& fg
, const vector
<Region
> & ors
, const vector
<Region
> & irs
, const vector
<R_edge_t
> & edges
) : FactorGraph(fg
), BipRegGraph(), _fac2OR() {
36 // Copy outer regions (giving them counting number 1.0)
37 ORs().reserve( ors
.size() );
38 for( vector
<Region
>::const_iterator alpha
= ors
.begin(); alpha
!= ors
.end(); alpha
++ )
39 ORs().push_back( FRegion(Factor(*alpha
, 1.0), 1.0) );
41 // Incorporate factors into outer regions
42 /* if( !_hasNegatives ) {
43 // For each factor, find the outer regions that subsume that factor.
44 // Then, "divide" the factor over its subsuming outer regions.
45 for( size_t I = 0; I < nrFactors(); I++ ) {
46 vector<size_t> subsuming_alphas;
48 for( size_t alpha = 0; alpha < nr_ORs(); alpha++ ) {
49 if( OR(alpha).vars() >> factor(I).vars() )
50 subsuming_alphas.push_back( alpha );
53 assert( subsuming_alphas.size() >= 1 );
55 for( vector<size_t>::const_iterator alpha = subsuming_alphas.begin(); alpha != subsuming_alphas.end(); alpha++ )
56 OR(*alpha) *= (factor(I) ^ (1.0 / subsuming_alphas.size()));
59 cout << "Careful composition of outer regions" << endl;
61 // For each factor, find an outer regions that subsumes that factor.
62 // Then, multiply the outer region with that factor.
63 for( size_t I
= 0; I
< nrFactors(); I
++ ) {
65 for( alpha
= 0; alpha
< nr_ORs(); alpha
++ )
66 if( OR(alpha
).vars() >> factor(I
).vars() ) {
68 // OR(alpha) *= factor(I);
71 assert( alpha
!= nr_ORs() );
77 IRs().reserve( irs
.size() );
78 for( vector
<Region
>::const_iterator beta
= irs
.begin(); beta
!= irs
.end(); beta
++ )
79 IRs().push_back( *beta
);
82 Redges().reserve( edges
.size() );
83 for( vector
<R_edge_t
>::const_iterator e
= edges
.begin(); e
!= edges
.end(); e
++ )
84 Redges().push_back( *e
);
86 // Regenerate BipartiteGraph internals
87 BipRegGraph::Regenerate();
89 // Check counting numbers
90 Check_Counting_Numbers();
95 RegionGraph::RegionGraph(const FactorGraph
& fg
, const vector
<VarSet
> & cl
) : FactorGraph(fg
), BipRegGraph() {
96 // Retain only maximal clusters
97 ClusterGraph
cg( cl
);
100 // Create outer regions, giving them counting number 1.0
101 ORs().reserve( cg
.size() );
102 for( ClusterGraph::const_iterator alpha
= cg
.begin(); alpha
!= cg
.end(); alpha
++ )
103 ORs().push_back( FRegion(Factor(*alpha
, 1.0), 1.0) );
105 // Incorporate factors into outer regions
106 /* if( !_hasNegatives ) {
107 // For each factor, find the outer regions that subsume that factor.
108 // Then, "divide" the factor over its subsuming outer regions.
109 for( size_t I = 0; I < nrFactors(); I++ ) {
110 vector<size_t> subsuming_alphas;
112 for( size_t alpha = 0; alpha < nr_ORs(); alpha++ ) {
113 if( OR(alpha).vars() >> factor(I).vars() )
114 subsuming_alphas.push_back( alpha );
117 assert( subsuming_alphas.size() >= 1 );
119 for( vector<size_t>::const_iterator alpha = subsuming_alphas.begin(); alpha != subsuming_alphas.end(); alpha++ )
120 OR(*alpha) *= factor(I) ^ (1.0 / subsuming_alphas.size());
123 cout << "Careful composition of outer regions" << endl;
125 // For each factor, find an outer regions that subsumes that factor.
126 // Then, multiply the outer region with that factor.
127 for( size_t I
= 0; I
< nrFactors(); I
++ ) {
129 for( alpha
= 0; alpha
< nr_ORs(); alpha
++ )
130 if( OR(alpha
).vars() >> factor(I
).vars() ) {
132 // OR(alpha) *= factor(I);
135 assert( alpha
!= nr_ORs() );
140 // Create inner regions - first pass
142 for( ClusterGraph::const_iterator alpha
= cg
.begin(); alpha
!= cg
.end(); alpha
++ )
143 for( ClusterGraph::const_iterator alpha2
= alpha
; (++alpha2
) != cg
.end(); ) {
144 VarSet intersect
= (*alpha
) & (*alpha2
);
145 if( intersect
.size() > 0 )
146 betas
.insert( intersect
);
149 // Create inner regions - subsequent passes
150 set
<VarSet
> new_betas
;
153 for( set
<VarSet
>::const_iterator gamma
= betas
.begin(); gamma
!= betas
.end(); gamma
++ )
154 for( set
<VarSet
>::const_iterator gamma2
= gamma
; (++gamma2
) != betas
.end(); ) {
155 VarSet intersect
= (*gamma
) & (*gamma2
);
156 if( (intersect
.size() > 0) && (betas
.count(intersect
) == 0) )
157 new_betas
.insert( intersect
);
159 betas
.insert(new_betas
.begin(), new_betas
.end());
160 } while( new_betas
.size() );
162 // Create inner regions - store them in the bipartite graph
163 IRs().reserve( betas
.size() );
164 for( set
<VarSet
>::const_iterator beta
= betas
.begin(); beta
!= betas
.end(); beta
++ )
165 IRs().push_back( Region(*beta
,NAN
) );
168 for( size_t beta
= 0; beta
< nr_IRs(); beta
++ ) {
169 for( size_t alpha
= 0; alpha
< nr_ORs(); alpha
++ ) {
170 if( OR(alpha
).vars() >> IR(beta
) )
171 Redges().push_back(R_edge_t(alpha
,beta
));
175 // Regenerate BipartiteGraph internals
176 BipRegGraph::Regenerate();
178 // Calculate counting numbers
179 Calc_Counting_Numbers();
181 // Check counting numbers
182 Check_Counting_Numbers();
186 void RegionGraph::Calc_Counting_Numbers() {
187 // Calculates counting numbers of inner regions based upon counting numbers of outer regions
189 vector
<vector
<size_t> > ancestors(nr_IRs());
190 for( size_t beta
= 0; beta
< nr_IRs(); beta
++ ) {
192 for( size_t beta2
= 0; beta2
< nr_IRs(); beta2
++ )
193 if( (beta2
!= beta
) && IR(beta2
) >> IR(beta
) )
194 ancestors
[beta
].push_back(beta2
);
199 new_counting
= false;
200 for( size_t beta
= 0; beta
< nr_IRs(); beta
++ ) {
201 if( isnan( IR(beta
).c() ) ) {
202 bool has_nan_ancestor
= false;
203 for( vector
<size_t>::const_iterator beta2
= ancestors
[beta
].begin(); (beta2
!= ancestors
[beta
].end()) && !has_nan_ancestor
; beta2
++ )
204 if( isnan( IR(*beta2
).c() ) )
205 has_nan_ancestor
= true;
206 if( !has_nan_ancestor
) {
208 for( R_nb_cit alpha
= nbIR(beta
).begin(); alpha
!= nbIR(beta
).end(); alpha
++ )
210 for( vector
<size_t>::const_iterator beta2
= ancestors
[beta
].begin(); beta2
!= ancestors
[beta
].end(); beta2
++ )
217 } while( new_counting
);
221 bool RegionGraph::Check_Counting_Numbers() {
222 // Checks whether the counting numbers satisfy the fundamental relation
224 bool all_valid
= true;
225 for( vector
<Var
>::const_iterator n
= vars().begin(); n
!= vars().end(); n
++ ) {
227 for( size_t alpha
= 0; alpha
< nr_ORs(); alpha
++ )
228 if( OR(alpha
).vars() && *n
)
229 c_n
+= OR(alpha
).c();
230 for( size_t beta
= 0; beta
< nr_IRs(); beta
++ )
233 if( fabs(c_n
- 1.0) > 1e-15 ) {
235 cout
<< "WARNING: counting numbers do not satisfy relation for " << *n
<< "(c_n = " << c_n
<< ")." << endl
;
243 void RegionGraph::RecomputeORs() {
244 for( size_t alpha
= 0; alpha
< nr_ORs(); alpha
++ )
245 OR(alpha
).fill( 1.0 );
246 for( fac2OR_cit I
= _fac2OR
.begin(); I
!= _fac2OR
.end(); I
++ )
247 OR( I
->second
) *= factor( I
->first
);
251 void RegionGraph::RecomputeORs( const VarSet
&ns
) {
252 for( size_t alpha
= 0; alpha
< nr_ORs(); alpha
++ )
253 if( OR(alpha
).vars() && ns
)
254 OR(alpha
).fill( 1.0 );
255 for( fac2OR_cit I
= _fac2OR
.begin(); I
!= _fac2OR
.end(); I
++ )
256 if( OR( I
->second
).vars() && ns
)
257 OR( I
->second
) *= factor( I
->first
);
261 void RegionGraph::RecomputeOR( size_t I
) {
262 if( _fac2OR
.count(I
) ) {
263 size_t alpha
= _fac2OR
[I
];
264 OR(alpha
).fill( 1.0 );
265 for( fac2OR_cit I
= _fac2OR
.begin(); I
!= _fac2OR
.end(); I
++ )
266 if( I
->second
== alpha
)
267 OR(alpha
) *= factor( I
->first
);
272 ostream
& operator << (ostream
& os
, const RegionGraph
& rg
) {
273 os
<< "Outer regions" << endl
;
274 for( size_t alpha
= 0; alpha
< rg
.nr_ORs(); alpha
++ )
275 os
<< rg
.OR(alpha
).vars() << ": c = " << rg
.OR(alpha
).c() << endl
;
277 os
<< "Inner regions" << endl
;
278 for( size_t beta
= 0; beta
< rg
.nr_IRs(); beta
++ )
279 os
<< (VarSet
)rg
.IR(beta
) << ": c = " << rg
.IR(beta
).c() << endl
;
285 } // end of namespace dai