ae0b7202beb2edf0ffa6b6fc2617ff60ec36e032
[libdai.git] / src / alldai.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 <string>
10 #include <fstream>
11 #include <dai/alldai.h>
12 #include <dai/properties.h>
13 #include <dai/exceptions.h>
14
15
16 namespace dai {
17
18
19 using namespace std;
20
21
22 class _builtinInfAlgs : public std::map<std::string, InfAlg *> {
23 public:
24 _builtinInfAlgs() {
25 operator[]( ExactInf().name() ) = new ExactInf;
26 #ifdef DAI_WITH_BP
27 operator[]( BP().name() ) = new BP;
28 #endif
29 #ifdef DAI_WITH_FBP
30 operator[]( FBP().name() ) = new FBP;
31 #endif
32 #ifdef DAI_WITH_TRWBP
33 operator[]( TRWBP().name() ) = new TRWBP;
34 #endif
35 #ifdef DAI_WITH_MF
36 operator[]( MF().name() ) = new MF;
37 #endif
38 #ifdef DAI_WITH_HAK
39 operator[]( HAK().name() ) = new HAK;
40 #endif
41 #ifdef DAI_WITH_LC
42 operator[]( LC().name() ) = new LC;
43 #endif
44 #ifdef DAI_WITH_TREEEP
45 operator[]( TreeEP().name() ) = new TreeEP;
46 #endif
47 #ifdef DAI_WITH_JTREE
48 operator[]( JTree().name() ) = new JTree;
49 #endif
50 #ifdef DAI_WITH_MR
51 operator[]( MR().name() ) = new MR;
52 #endif
53 #ifdef DAI_WITH_GIBBS
54 operator[]( Gibbs().name() ) = new Gibbs;
55 #endif
56 #ifdef DAI_WITH_CBP
57 operator[]( CBP().name() ) = new CBP;
58 #endif
59 #ifdef DAI_WITH_DECMAP
60 operator[]( DecMAP().name() ) = new DecMAP;
61 #endif
62 }
63
64 ~_builtinInfAlgs() {
65 for( iterator it = begin(); it != end(); it++ )
66 delete it->second;
67 }
68 };
69
70
71 static _builtinInfAlgs allBuiltinInfAlgs;
72
73
74 std::map<std::string, InfAlg *>& builtinInfAlgs() {
75 return allBuiltinInfAlgs;
76 }
77
78
79 std::set<std::string> builtinInfAlgNames() {
80 std::set<std::string> algNames;
81 for( _builtinInfAlgs::const_iterator it = allBuiltinInfAlgs.begin(); it != allBuiltinInfAlgs.end(); it++ )
82 algNames.insert( it->first );
83 return algNames;
84 }
85
86
87 InfAlg *newInfAlg( const std::string &name, const FactorGraph &fg, const PropertySet &opts ) {
88 _builtinInfAlgs::const_iterator i = allBuiltinInfAlgs.find( name );
89 if( i == allBuiltinInfAlgs.end() )
90 DAI_THROWE(UNKNOWN_DAI_ALGORITHM, "Unknown inference algorithm: " + name);
91 InfAlg *ia = i->second;
92 return ia->construct( fg, opts );
93 }
94
95
96 InfAlg *newInfAlgFromString( const std::string &nameOpts, const FactorGraph &fg ) {
97 pair<string,PropertySet> no = parseNameProperties( nameOpts );
98 return newInfAlg( no.first, fg, no.second );
99 }
100
101
102 InfAlg *newInfAlgFromString( const std::string &nameOpts, const FactorGraph &fg, const std::map<std::string,std::string> &aliases ) {
103 pair<string,PropertySet> no = parseNameProperties( nameOpts, aliases );
104 return newInfAlg( no.first, fg, no.second );
105 }
106
107
108 std::pair<std::string, PropertySet> parseNameProperties( const std::string &s ) {
109 string::size_type pos = s.find_first_of('[');
110 string name;
111 PropertySet opts;
112 if( pos == string::npos ) {
113 name = s;
114 } else {
115 name = s.substr(0,pos);
116
117 stringstream ss;
118 ss << s.substr(pos,s.length());
119 ss >> opts;
120 }
121 return make_pair(name,opts);
122 }
123
124
125 std::pair<std::string, PropertySet> parseNameProperties( const std::string &s, const std::map<std::string,std::string> &aliases ) {
126 // break string into method[properties]
127 pair<string,PropertySet> ps = parseNameProperties(s);
128 bool looped = false;
129
130 // as long as 'method' is an alias, update:
131 while( aliases.find(ps.first) != aliases.end() && !looped ) {
132 string astr = aliases.find(ps.first)->second;
133 pair<string,PropertySet> aps = parseNameProperties(astr);
134 if( aps.first == ps.first )
135 looped = true;
136 // override aps properties by ps properties
137 aps.second.set( ps.second );
138 // replace ps by aps
139 ps = aps;
140 // repeat until method name == alias name ('looped'), or
141 // there is no longer an alias 'method'
142 }
143
144 return ps;
145 }
146
147
148 std::map<std::string,std::string> readAliasesFile( const std::string &filename ) {
149 // Read aliases
150 map<string,string> result;
151 ifstream infile;
152 infile.open( filename.c_str() );
153 if( infile.is_open() ) {
154 while( true ) {
155 string line;
156 getline( infile,line );
157 if( infile.fail() )
158 break;
159 if( (!line.empty()) && (line[0] != '#') ) {
160 string::size_type pos = line.find(':',0);
161 if( pos == string::npos )
162 DAI_THROWE(INVALID_ALIAS,"Invalid alias '" + line + "'");
163 else {
164 string::size_type posl = line.substr(0, pos).find_last_not_of(" \t");
165 string key = line.substr(0, posl + 1);
166 string::size_type posr = line.substr(pos + 1, line.length()).find_first_not_of(" \t");
167 string val = line.substr(pos + 1 + posr, line.length());
168 result[key] = val;
169 }
170 }
171 }
172 infile.close();
173 } else
174 DAI_THROWE(CANNOT_READ_FILE,"Error opening aliases file " + filename);
175 return result;
176 }
177
178
179 } // end of namespace dai