New git HEAD version
[libdai.git] / utils / uai2fg.cpp
1 /* This file is part of libDAI - http://www.libdai.org/
2 *
3 * Copyright (c) 2006-2011, The libDAI authors. All rights reserved.
4 *
5 * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
6 */
7
8
9 #include <iostream>
10 #include <fstream>
11 #include <cstdlib>
12 #include <dai/alldai.h>
13 #include <dai/io.h>
14
15
16 using namespace std;
17 using namespace dai;
18
19
20 int main( int argc, char *argv[] ) {
21 if ( argc != 4 ) {
22 cout << "This program is part of libDAI - http://www.libdai.org/" << endl << endl;
23 cout << "Usage: ./uai2fg <basename> <surgery> <verbose>" << endl << endl;
24 cout << "Converts input files in the UAI 2006/2008/2010 approximate inference evaluation format" << endl;
25 cout << "(see http://graphmod.ics.uci.edu/uai08/ and http://www.cs.huji.ac.il/project/UAI10/)" << endl;
26 cout << "to the libDAI factor graph format." << endl << endl;
27 cout << "Reads factor graph <basename.uai> and evidence <basename.uai.evid>" << endl;
28 cout << "and writes the resulting clamped factor graphs to <basename.X.fg>," << endl;
29 cout << "where X=0,1,2,... enumerates the different evidence cases." << endl << endl;
30 cout << "If surgery!=0, uses surgery on the factor graph (recommended)," << endl;
31 cout << "otherwise, just adds delta factors to the factor graph." << endl;
32 return 1;
33 } else {
34 string basename( argv[1] );
35 bool surgery = fromString<size_t>( argv[2] );
36 size_t verbose = fromString<size_t>( argv[3] );
37 string uainame = basename + ".uai";
38 string evidname = uainame + ".evid";
39
40 // output command line options
41 if( verbose ) {
42 cout << "Factorgraph filename: " << uainame << endl;
43 cout << "Evidence filename: " << evidname << endl;
44 cout << "Output basename: " << basename << endl;
45 cout << "Surgery: " << surgery << endl;
46 }
47
48 // read factor graph
49 vector<Var> vars;
50 vector<Factor> facs0;
51 vector<Permute> permutations;
52 if( verbose )
53 cout << "Reading factor graph..." << endl;
54 ReadUaiAieFactorGraphFile( uainame.c_str(), verbose, vars, facs0, permutations );
55 if( verbose )
56 cout << "Successfully read factor graph" << endl;
57
58 // read evidence
59 if( verbose )
60 cout << "Reading evidence..." << endl;
61 vector<map<size_t,size_t> > evid = ReadUaiAieEvidenceFile( evidname.c_str(), verbose );
62 if( verbose )
63 cout << "Successfully read " << evid.size() << " evidence cases" << endl;
64
65 // build output file names
66 vector<string> fgnames;
67 fgnames.reserve( evid.size() );
68 for( size_t ev = 0; ev < evid.size(); ev++ )
69 fgnames.push_back( basename + '.' + toString(ev) + ".fg" );
70
71 // construct clamped factor graphs which reflect observed evidence cases
72 if( verbose )
73 cout << "Constructing clamped factor graphs..." << endl;
74 vector<FactorGraph> fgs;
75 fgs.reserve( evid.size() );
76 for( size_t ev = 0; ev < evid.size(); ev++ ) {
77 if( verbose )
78 cout << " Evidence case " << ev << "..." << endl;
79 // copy vector of factors
80 vector<Factor> facs( facs0 );
81
82 // change factor graph to reflect observed evidence
83 if( verbose )
84 cout << " Applying evidence..." << endl;
85 if( surgery ) {
86 // replace factors with clamped variables with slices
87 for( size_t I = 0; I < facs.size(); I++ ) {
88 for( map<size_t,size_t>::const_iterator e = evid[ev].begin(); e != evid[ev].end(); e++ ) {
89 if( facs[I].vars() >> vars[e->first] ) {
90 if( verbose >= 2 )
91 cout << " Clamping " << e->first << " to value " << e->second << " in factor " << I << " = " << facs[I].vars() << endl;
92 facs[I] = facs[I].slice( vars[e->first], e->second );
93 if( verbose >= 2 )
94 cout << " ...remaining vars: " << facs[I].vars() << endl;
95 }
96 }
97 }
98 // remove empty factors
99 Real logZcorr = 0.0;
100 for( vector<Factor>::iterator I = facs.begin(); I != facs.end(); )
101 if( I->vars().size() == 0 ) {
102 logZcorr += std::log( (Real)(*I)[0] );
103 I = facs.erase( I );
104 } else
105 I++;
106 // multiply with logZcorr constant
107 if( facs.size() == 0 )
108 facs.push_back( Factor( VarSet(), std::exp(logZcorr) ) );
109 else
110 facs.front() *= std::exp(logZcorr);
111 }
112 // add delta factors corresponding to observed variable values
113 for( map<size_t,size_t>::const_iterator e = evid[ev].begin(); e != evid[ev].end(); e++ )
114 facs.push_back( createFactorDelta( vars[e->first], e->second ) );
115
116 // construct clamped factor graph
117 if( verbose )
118 cout << " Constructing factor graph..." << endl;
119 fgs.push_back( FactorGraph( facs.begin(), facs.end(), vars.begin(), vars.end(), facs.size(), vars.size() ) );
120
121 // write it to a file
122 if( verbose )
123 cout << " Saving factor graph as " << fgnames[ev] << "..." << endl;
124 fgs[ev].WriteToFile( fgnames[ev].c_str() );
125 }
126
127 if( verbose )
128 cout << "Done!" << endl;
129 }
130
131 return 0;
132 }