Several changes by Giuseppe Passino
[libdai.git] / TODO
1 TODO:
2
3 - Improve documentation.
4
5 - Adapt http://www.boost.org/development/requirements.html#Design_and_Programming
6
7 - Use "gcc -MM" to generate dependencies for targets.
8 Maybe even better: switch to cmake (see http://lwn.net/Articles/188693/)
9 cross-platform build system.
10
11
12 OPTIMIZATION:
13
14 - BipartiteGraph::isConnected should be optimized using boost::graph
15
16 - Replace VarSets by smallSet<size_t> where appropriate, in order to minimize the use of findVar().
17
18 - A DAIAlg<T> should not inherit from a FactorGraph/RegionGraph, but should
19 store a reference to it. This prevents needless copying of (possibly large)
20 data structures. Disadvantage: the caller must not change the data structure
21 between calls. (Maybe a smart_ptr would help here?)
22 Also, general marginalization functions now copy a complete object. Instead, it
23 would make more sense that they construct a new object without copying the
24 FactorGraph. Or they can simply be made methods of the general InfAlg class.
25
26
27 IDEAS WORTH EXPLORING:
28
29 - Use a PropertySet as output of a DAIAlg, instead of functions like maxDiff and Iterations().
30
31 - Cache second-order neighborhoods (delta's) in BipGraph?
32
33 - If you ever do a rewrite, make sure that the graphical properties are not
34 entangled with the probabilistic properties. E.g., a factor graph really
35 should be represented as a bipartite graph, with a separate array of variable
36 labels and dimensions, and a seperate array of (pointers to) factor tables. In
37 this way, each factor could be implemented differently, e.g., we could have
38 some sparse factors, some noisy-OR factors, some dense factors, some arbitrary
39 precision factors, etc. Or we could make more use of templates to have a more
40 generic factor graph.
41
42 - Use Boost::uBLAS framework to deal with matrices, especially, with
43 2D sparse matrices.
44 See http://www.boost.org/libs/numeric/ublas/doc/matrix_sparse.htm
45 and tests/errorbounds/errorbounds3
46
47 - Introduce naming scheme:
48 all Vars and VarSets should be named v_..., e.g. v_i instead of i
49 all Factors should be named f_..., e.g. f_I instead of I
50 all indices should be named _..., e.g. _k instead of k
51 all iterators should be named i_, e.g. i_i is an iterator to i
52 all const_iterators should be named ci_, e.g. ci_i is an iterator to i
53
54 - Define a better fileformat for .fg files (maybe using XML)?
55
56 - Alternative implementation of undo factor changes: the only things that have to be
57 undone are setting a factor to all ones and setting a factor to a Kronecker delta. This
58 could also be implemented in the factor itself, which could maintain its state
59 (one/delta/full) and act accordingly.
60
61 - Think about the RegionGraph::fac2OR variable: a better implementation of this feature is
62 probably possible.
63
64 - Optimize GBP with precalculated indices.
65
66 - Optimize all indices as follows: keep a cache of all indices that have been
67 computed (use a hash). Then, instead of computing on the fly, use the precomputed ones.
68
69 - Variable elimination should be implemented generically using a function
70 object that tells you which variable to delete.
71
72 - Improve general support for graphs and trees.
73
74 - Add support for sparse potentials.
75
76 - Optimize BP_SEQMAX (it should use a better data structure than a vector for the residuals).
77
78
79 BAD IDEAS:
80
81 - A FactorGraph and a RegionGraph are often equipped with
82 additional properties for nodes and edges. The code to initialize those
83 is often quite similar; maybe this can be abstracted to classes
84 like ExtFactorGraph and ExtRegionGraph (Ext stands for Extended), e.g.
85 template <typename NodeProperties, typename EdgeProperties>
86 class ExtFactorGraph : public FactorGraph {
87 public:
88 std::vector<NodeProperties> nodeProps;
89 std::vector<std::vector<EdgeProperties> > edgeProps;
90 // blabla
91 }
92 A disadvantage of this approach may be worse cachability.
93 A problem is if there are nog properties for nodes (type 1), nodes (type 2)
94 or edges. Maybe this can be solved using specializations, or using variadac
95 template arguments or something similar?
96 Idea: you could define a "class Empty {}", and add some code that checks for
97 the typeid, comparing it with Empty, and doing something special in that case
98 (e.g., not allocating memory).
99 The main disadvantage of this approach seems to be that it leads to even more
100 entanglement.
101
102 - Instead of polymorphism by inheritance, use polymorphism by template
103 parameterization. For example, the real reason you introduced the complicated
104 inheritance scheme was for functions like
105 Factor calcMarginal( const InferenceAlgorithm & obj, const VarSet & ns, bool reInit );
106 Now instead, you could use a template function:
107 template<typename InferenceAlgorithm>
108 Factor calcMarginal( const InferenceAlgorithm &obj, const VarSet &ns, bool reInit );
109 This would assume that InferenceAlgorithm supports certain methods, like
110 clone(), grm(), ...... Ideally, you would use concepts to define different
111 classes of inference algorithms with different capabilities, for example the
112 ability to calculate logZ, the ability to calculate marginals, the ability to
113 calculate bounds, the ability to calculate MAP states, etcetera. Then, use
114 traits classes in order to be able to query the capabilities of the model. For
115 example, you would be able to query whether the inference algorithm supports
116 calculation of logZ. Unfortunately, this is compile-time polymorphism, whereas
117 tests/test needs runtime polymorphism.