Improved documentation of include/dai/cbp.h
[libdai.git] / examples / example_permute.cpp
1 /* This file is part of libDAI - http://www.libdai.org/
2 *
3 * libDAI is licensed under the terms of the GNU General Public License version
4 * 2, or (at your option) any later version. libDAI is distributed without any
5 * warranty. See the file COPYING for more details.
6 *
7 * Copyright (C) 2008-2009 Joris Mooij [joris dot mooij at libdai dot org]
8 */
9
10
11 #include <dai/varset.h>
12 #include <dai/index.h>
13 #include <iostream>
14 #include <iomanip>
15
16 using namespace std;
17 using namespace dai;
18
19 int main() {
20 Var x0(0, 2); // Define binary variable x0 (with label 0)
21 Var x1(1, 3); // Define ternary variable x1 (with label 1)
22 Var x2(2, 2); // Define binary variable x2 (with label 2)
23
24 // Define vector V = (x1, x2, x0)
25 vector<Var> V; // Define a vector of variables
26 V.push_back( x1 ); // V[0] = x1;
27 V.push_back( x2 ); // V[1] = x2;
28 V.push_back( x0 ); // V[2] = x0;
29 cout << "V = " << V << endl; // Note that the elements of X are not necessarily ordered according to their labels
30
31 // Define set X = {x0, x1, x2}
32 VarSet X; // empty
33 X |= x2; // X = {x2}
34 X |= x0; // X = {x0, x2}
35 X |= x1; // X = {x0, x1, x2}
36 cout << "X = " << X << endl; // Note that the elements of X are ordered according to their labels
37
38 cout << "Note that the ordering of the variables in X is the canonical ordering" << endl;
39 cout << "(ascendingly according to their labels) but the ordering in V is different." << endl << endl;
40
41 // N = number of variables in V (and X)
42 size_t N = V.size();
43
44 // Define a Permute object based on the variables in V
45 Permute sigma(V);
46 // Each Var in V corresponds with a dimension in a multi-dimensional array.
47 // The permutation sigma permutes these dimensions from the canonical ordering
48 // (sorted ascendingly on the label of the variable, i.e., the same ordering as
49 // in X) into the ordering these variables have in V.
50 cout << "The permutation between both variable orderings is sigma = " << sigma.sigma() << ", or more verbosely:" << endl;
51 for( size_t n = 0; n < N; n++ )
52 cout << " sigma[" << n << "] = " << sigma[n] << endl;
53 cout << "This means that variable V[sigma[n]] should correspond with the n'th variable in X (for n=0,...," << (N-1) << ")...";
54 // Check whether the permutation works as advertised
55 VarSet::const_iterator X_n = X.begin();
56 for( size_t n = 0; n < N; n++, X_n++ )
57 DAI_ASSERT( V[sigma[n]] == *X_n );
58 cout << "OK. " << endl << endl;
59
60 // Iterate over the joint states of the variables, according to the ordering in V
61 cout << "The states of the variables x0,x1,x2 are, according to the ordering in V:" << endl;
62 cout << "SV: x0: x1: x2:" << endl;
63 std::vector<size_t> ranges;
64 for( size_t i = 0; i < V.size(); i++ )
65 ranges.push_back( V[i].states() );
66 for( multifor SV(ranges); SV.valid(); ++SV )
67 cout << setw(2) << (size_t)SV << " " << SV[sigma[0]] << " " << SV[sigma[1]] << " " << SV[sigma[2]] << endl;
68 cout << endl;
69
70 // Iterate over the joint states of the variables, according to the canonical ordering in X
71 cout << "The states of the variables x0,x1,x2 are, according to the canonical ordering in X:" << endl;
72 cout << "SX: x0: x1: x2:" << endl;
73 for( State SX(X); SX.valid(); SX++ )
74 cout << setw(2) << SX << " " << SX(x0) << " " << SX(x1) << " " << SX(x2) << endl;
75 cout << endl;
76
77 // The main functionality of the Permute object is to calculate the induced permutation of linear indices of joint states
78 cout << "The permutation sigma induces the following permutation of linear indices of joint states:" << endl;
79 cout << "SV: SX:" << endl;
80 for( size_t li = 0; li < X.nrStates(); li++ )
81 cout << setw(2) << li << " " << setw(2) << sigma.convertLinearIndex( li ) << endl;
82
83 return 0;
84 }