Merged bp.h and bp.cpp from SVN head
authorJoris Mooij <jorism@marvin.jorismooij.nl>
Fri, 26 Sep 2008 17:12:49 +0000 (19:12 +0200)
committerJoris Mooij <jorism@marvin.jorismooij.nl>
Fri, 26 Sep 2008 17:12:49 +0000 (19:12 +0200)
STATUS
include/dai/bp.h
src/bp.cpp
tests/aliases.conf

diff --git a/STATUS b/STATUS
index eb8efce..ffad5f0 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -97,14 +97,14 @@ tests/
        test.cpp
 mf.h
 mf.cpp
+bp.h
+bp.cpp
 
 FILES IN SVN HEAD THAT ARE STILL RELEVANT:
 ChangeLog
 README
 TODO
 
-bp.h
-bp.cpp
 hak.h
 hak.cpp
 jtree.h
index 5d6b456..8853c94 100644 (file)
@@ -34,7 +34,7 @@ namespace dai {
 
 
 class BP : public DAIAlgFG {
-    protected:
+    private:
         typedef std::vector<size_t> ind_t;
         struct EdgeProp {
             ind_t  index;
@@ -42,7 +42,11 @@ class BP : public DAIAlgFG {
             Prob   newMessage;
             double residual;
         };
-        std::vector<std::vector<EdgeProp> > edges;
+        std::vector<std::vector<EdgeProp> > _edges;
+        /// Maximum difference encountered so far
+        double _maxdiff;
+        /// Number of iterations needed
+        size_t _iters;
     
     public:
         struct Properties {
@@ -50,70 +54,100 @@ class BP : public DAIAlgFG {
             size_t maxiter;
             double tol;
             bool logdomain;
+            double damping;
             DAI_ENUM(UpdateType,SEQFIX,SEQRND,SEQMAX,PARALL)
             UpdateType updates;
         } props;
-        double maxdiff;
+        static const char *Name;
 
     public:
         /// Default constructor
-        BP() : DAIAlgFG(), edges(), props(), maxdiff(0.0) {};
-        /// Copy constructor
-        BP( const BP & x ) : DAIAlgFG(x), edges(x.edges), props(x.props), maxdiff(x.maxdiff) {};
-        /// Clone *this (virtual copy constructor)
-        BP* clone() const { return new BP(*this); }
-        /// Create (virtual constructor)
-        virtual BP* create() const { return new BP; }
+        BP() : DAIAlgFG(), _edges(), _maxdiff(0.0), _iters(0U), props() {}
+
         /// Construct from FactorGraph fg and PropertySet opts
-        BP( const FactorGraph & fg, const PropertySet &opts ) : DAIAlgFG(fg), edges(), props(), maxdiff(0.0) {
+        BP( const FactorGraph & fg, const PropertySet &opts ) : DAIAlgFG(fg), _edges(), _maxdiff(0.0), _iters(0U), props() {
             setProperties( opts );
             construct();
         }
+
+        /// Copy constructor
+        BP( const BP & x ) : DAIAlgFG(x), _edges(x._edges), _maxdiff(x._maxdiff), _iters(x._iters), props(x.props) {}
+
+        /// Clone *this (virtual copy constructor)
+        virtual BP* clone() const { return new BP(*this); }
+
+        /// Create (virtual constructor)
+        virtual BP* create() const { return new BP(); }
+
         /// Assignment operator
         BP& operator=( const BP & x ) {
             if( this != &x ) {
                 DAIAlgFG::operator=( x );
-                edges = x.edges;
+                _edges = x._edges;
+                _maxdiff = x._maxdiff;
+                _iters = x._iters;
                 props = x.props;
-                maxdiff = x.maxdiff;
             }
             return *this;
         }
 
-        static const char *Name;
+        /// Return number of passes over the factorgraph
+        size_t Iterations() const { return _iters; }
 
-        Prob & message(size_t i, size_t _I) { return edges[i][_I].message; }
-        const Prob & message(size_t i, size_t _I) const { return edges[i][_I].message; }
-        Prob & newMessage(size_t i, size_t _I) { return edges[i][_I].newMessage; }
-        const Prob & newMessage(size_t i, size_t _I) const { return edges[i][_I].newMessage; }
-        ind_t & index(size_t i, size_t _I) { return edges[i][_I].index; }
-        const ind_t & index(size_t i, size_t _I) const { return edges[i][_I].index; }
-        double & residual(size_t i, size_t _I) { return edges[i][_I].residual; }
-        const double & residual(size_t i, size_t _I) const { return edges[i][_I].residual; }
+        /// Return maximum difference between single node beliefs for two consecutive iterations
+        double maxDiff() const { return _maxdiff; }
 
+        /// Identifies itself for logging purposes
         std::string identify() const;
-        void construct();
+
+        /// Get single node belief
+        Factor belief( const Var &n ) const;
+
+        /// Get general belief
+        Factor belief( const VarSet &n ) const;
+
+        /// Get all beliefs
+        std::vector<Factor> beliefs() const;
+
+        /// Get log partition sum
+        Real logZ() const;
+
+        /// Clear messages and beliefs
         void init();
+
         /// Clear messages and beliefs corresponding to the nodes in ns
         virtual void init( const VarSet &ns );
+
+        /// The actual approximate inference algorithm
         double run();
 
-        void findMaxResidual( size_t &i, size_t &_I );
-        void calcNewMessage( size_t i, size_t _I );
-        Factor beliefV (size_t i) const;
-        Factor beliefF (size_t I) const;
-        Factor belief (const Var &n) const;
-        Factor belief (const VarSet &n) const;
-        std::vector<Factor> beliefs() const;
-        Real logZ() const;
+        Factor beliefV( size_t i ) const;
+        Factor beliefF( size_t I ) const;
+
+    private:
+        const Prob & message(size_t i, size_t _I) const { return _edges[i][_I].message; }
+        Prob & message(size_t i, size_t _I) { return _edges[i][_I].message; }
+        Prob & newMessage(size_t i, size_t _I) { return _edges[i][_I].newMessage; }
+        const Prob & newMessage(size_t i, size_t _I) const { return _edges[i][_I].newMessage; }
+        ind_t & index(size_t i, size_t _I) { return _edges[i][_I].index; }
+        const ind_t & index(size_t i, size_t _I) const { return _edges[i][_I].index; }
+        double & residual(size_t i, size_t _I) { return _edges[i][_I].residual; }
+        const double & residual(size_t i, size_t _I) const { return _edges[i][_I].residual; }
 
-        void restoreFactors( const VarSet &ns ) { FactorGraph::restoreFactors(ns); init(ns); }
+        void calcNewMessage( size_t i, size_t _I );
+        void updateMessage( size_t i, size_t _I ) {
+            if( props.damping == 0.0 )
+                message(i,_I) = newMessage(i,_I);
+            else
+                message(i,_I) = (message(i,_I) ^ props.damping) * (newMessage(i,_I) ^ (1.0 - props.damping));
+        }
+        void findMaxResidual( size_t &i, size_t &_I );
 
         /// Set Props according to the PropertySet opts, where the values can be stored as std::strings or as the type of the corresponding Props member
+        void construct();
         void setProperties( const PropertySet &opts );
         PropertySet getProperties() const;
         std::string printProperties() const;
-        double maxDiff() const { return maxdiff; }
 };
 
 
index aeaeaae..8162bf7 100644 (file)
@@ -42,15 +42,22 @@ const char *BP::Name = "BP";
 void BP::setProperties( const PropertySet &opts ) {
     assert( opts.hasKey("tol") );
     assert( opts.hasKey("maxiter") );
-    assert( opts.hasKey("verbose") );
     assert( opts.hasKey("logdomain") );
     assert( opts.hasKey("updates") );
     
     props.tol = opts.getStringAs<double>("tol");
     props.maxiter = opts.getStringAs<size_t>("maxiter");
-    props.verbose = opts.getStringAs<size_t>("verbose");
     props.logdomain = opts.getStringAs<bool>("logdomain");
     props.updates = opts.getStringAs<Properties::UpdateType>("updates");
+
+    if( opts.hasKey("verbose") )
+        props.verbose = opts.getStringAs<size_t>("verbose");
+    else
+        props.verbose = 0;
+    if( opts.hasKey("damping") )
+        props.damping = opts.getStringAs<double>("damping");
+    else
+        props.damping = 0.0;
 }
 
 
@@ -61,6 +68,7 @@ PropertySet BP::getProperties() const {
     opts.Set( "verbose", props.verbose );
     opts.Set( "logdomain", props.logdomain );
     opts.Set( "updates", props.updates );
+    opts.Set( "damping", props.damping );
     return opts;
 }
 
@@ -72,18 +80,19 @@ string BP::printProperties() const {
     s << "maxiter=" << props.maxiter << ",";
     s << "verbose=" << props.verbose << ",";
     s << "logdomain=" << props.logdomain << ",";
-    s << "updates=" << props.updates << "]";
+    s << "updates=" << props.updates << ",";
+    s << "damping=" << props.damping << "]";
     return s.str();
 }
 
 
 void BP::construct() {
     // create edge properties
-    edges.clear();
-    edges.reserve( nrVars() );
+    _edges.clear();
+    _edges.reserve( nrVars() );
     for( size_t i = 0; i < nrVars(); ++i ) {
-        edges.push_back( vector<EdgeProp>() );
-        edges[i].reserve( nbV(i).size() ); 
+        _edges.push_back( vector<EdgeProp>() );
+        _edges[i].reserve( nbV(i).size() ); 
         foreach( const Neighbor &I, nbV(i) ) {
             EdgeProp newEP;
             newEP.message = Prob( var(i).states() );
@@ -94,22 +103,18 @@ void BP::construct() {
                 newEP.index.push_back( k );
 
             newEP.residual = 0.0;
-            edges[i].push_back( newEP );
+            _edges[i].push_back( newEP );
         }
     }
 }
 
 
 void BP::init() {
+    double c = props.logdomain ? 0.0 : 1.0;
     for( size_t i = 0; i < nrVars(); ++i ) {
         foreach( const Neighbor &I, nbV(i) ) {
-            if( props.logdomain ) {
-                message( i, I.iter ).fill( 0.0 );
-                newMessage( i, I.iter ).fill( 0.0 );
-            } else {
-                message( i, I.iter ).fill( 1.0 );
-                newMessage( i, I.iter ).fill( 1.0 );
-            }
+            message( i, I.iter ).fill( c );
+            newMessage( i, I.iter ).fill( c );
         }
     }
 }
@@ -133,64 +138,67 @@ void BP::calcNewMessage( size_t i, size_t _I ) {
     // calculate updated message I->i
     size_t I = nbV(i,_I);
 
-/*  UNOPTIMIZED (SIMPLE TO READ, BUT SLOW) VERSION
-
-    Factor prod( factor( I ) );
-    for( _nb_cit j = nb2(I).begin(); j != nb2(I).end(); j++ )
-        if( *j != i ) {     // for all j in I \ i
-            for( _nb_cit J = nb1(*j).begin(); J != nb1(*j).end(); J++ ) 
-                if( *J != I ) {     // for all J in nb(j) \ I 
-                    prod *= Factor( *j, message(*j,*J) );
-    Factor marg = prod.marginal(var(i));
-*/
-    
-    Prob prod( factor(I).p() );
-    if( props.logdomain ) 
-        prod.takeLog();
-
-    // Calculate product of incoming messages and factor I
-    foreach( const Neighbor &j, nbF(I) ) {
-        if( j != i ) {     // for all j in I \ i
-            size_t _I = j.dual;
-            // ind is the precalculated IndexFor(j,I) i.e. to x_I == k corresponds x_j == ind[k]
-            const ind_t & ind = index(j, _I);
+    if( 0 == 1 ) {
+        /* UNOPTIMIZED (SIMPLE TO READ, BUT SLOW) VERSION */
+        Factor prod( factor( I ) );
+        foreach( const Neighbor &j, nbF(I) )
+            if( j != i ) {     // for all j in I \ i
+                foreach( const Neighbor &J, nbV(j) )
+                    if( J != I ) {     // for all J in nb(j) \ I 
+                        prod *= Factor( var(j), message(j, J.iter) );
+                    }
+            }
+        newMessage(i,_I) = prod.marginal( var(i) ).p();
+    } else {
+        /* OPTIMIZED VERSION */
+        Prob prod( factor(I).p() );
+        if( props.logdomain ) 
+            prod.takeLog();
+
+        // Calculate product of incoming messages and factor I
+        foreach( const Neighbor &j, nbF(I) ) {
+            if( j != i ) {     // for all j in I \ i
+                size_t _I = j.dual;
+                // ind is the precalculated IndexFor(j,I) i.e. to x_I == k corresponds x_j == ind[k]
+                const ind_t &ind = index(j, _I);
+
+                // prod_j will be the product of messages coming into j
+                Prob prod_j( var(j).states(), props.logdomain ? 0.0 : 1.0 ); 
+                foreach( const Neighbor &J, nbV(j) )
+                    if( J != I ) { // for all J in nb(j) \ I 
+                        if( props.logdomain )
+                            prod_j += message( j, J.iter );
+                        else
+                            prod_j *= message( j, J.iter );
+                    }
 
-            // prod_j will be the product of messages coming into j
-            Prob prod_j( var(j).states(), props.logdomain ? 0.0 : 1.0 ); 
-            foreach( const Neighbor &J, nbV(j) )
-                if( J != I ) { // for all J in nb(j) \ I 
+                // multiply prod with prod_j
+                for( size_t r = 0; r < prod.size(); ++r )
                     if( props.logdomain )
-                        prod_j += message( j, J.iter );
+                        prod[r] += prod_j[ind[r]];
                     else
-                        prod_j *= message( j, J.iter );
-                }
-
-            // multiply prod with prod_j
-            for( size_t r = 0; r < prod.size(); ++r )
-                if( props.logdomain )
-                    prod[r] += prod_j[ind[r]];
-                else
-                    prod[r] *= prod_j[ind[r]];
+                        prod[r] *= prod_j[ind[r]];
+            }
+        }
+        if( props.logdomain ) {
+            prod -= prod.maxVal();
+            prod.takeExp();
         }
-    }
-    if( props.logdomain ) {
-        prod -= prod.maxVal();
-        prod.takeExp();
-    }
 
-    // Marginalize onto i
-    Prob marg( var(i).states(), 0.0 );
-    // ind is the precalculated IndexFor(i,I) i.e. to x_I == k corresponds x_i == ind[k]
-    const ind_t ind = index(i,_I);
-    for( size_t r = 0; r < prod.size(); ++r )
-        marg[ind[r]] += prod[r];
-    marg.normalize( Prob::NORMPROB );
-    
-    // Store result
-    if( props.logdomain )
-        newMessage(i,_I) = marg.log();
-    else
-        newMessage(i,_I) = marg;
+        // Marginalize onto i
+        Prob marg( var(i).states(), 0.0 );
+        // ind is the precalculated IndexFor(i,I) i.e. to x_I == k corresponds x_i == ind[k]
+        const ind_t ind = index(i,_I);
+        for( size_t r = 0; r < prod.size(); ++r )
+            marg[ind[r]] += prod[r];
+        marg.normalize();
+
+        // Store result
+        if( props.logdomain )
+            newMessage(i,_I) = marg.log();
+        else
+            newMessage(i,_I) = marg;
+    }
 }
 
 
@@ -212,7 +220,6 @@ double BP::run() {
     for( size_t i = 0; i < nrVars(); ++i )
         old_beliefs.push_back( beliefV(i) );
 
-    size_t iter = 0;
     size_t nredges = nrEdges();
 
     if( props.updates == Properties::UpdateType::SEQMAX ) {
@@ -232,15 +239,14 @@ double BP::run() {
 
     // do several passes over the network until maximum number of iterations has
     // been reached or until the maximum belief difference is smaller than tolerance
-    for( iter=0; iter < props.maxiter && diffs.maxDiff() > props.tol; ++iter ) {
+    for( _iters=0; _iters < props.maxiter && diffs.maxDiff() > props.tol; ++_iters ) {
         if( props.updates == Properties::UpdateType::SEQMAX ) {
             // Residuals-BP by Koller et al.
             for( size_t t = 0; t < nredges; ++t ) {
                 // update the message with the largest residual
-
                 size_t i, _I;
                 findMaxResidual( i, _I );
-                message( i, _I ) = newMessage( i, _I );
+                updateMessage( i, _I );
                 residual( i, _I ) = 0.0;
 
                 // I->i has been updated, which means that residuals for all
@@ -265,7 +271,7 @@ double BP::run() {
 
             for( size_t i = 0; i < nrVars(); ++i )
                 foreach( const Neighbor &I, nbV(i) )
-                    message( i, I.iter ) = newMessage( i, I.iter );
+                    updateMessage( i, I.iter );
         } else {
             // Sequential updates
             if( props.updates == Properties::UpdateType::SEQRND )
@@ -273,7 +279,7 @@ double BP::run() {
             
             foreach( const Edge &e, update_seq ) {
                 calcNewMessage( e.first, e.second );
-                message( e.first, e.second ) = newMessage( e.first, e.second );
+                updateMessage( e.first, e.second );
             }
         }
 
@@ -285,11 +291,11 @@ double BP::run() {
         }
 
         if( props.verbose >= 3 )
-            cout << "BP::run:  maxdiff " << diffs.maxDiff() << " after " << iter+1 << " passes" << endl;
+            cout << "BP::run:  maxdiff " << diffs.maxDiff() << " after " << _iters+1 << " passes" << endl;
     }
 
-    if( diffs.maxDiff() > maxdiff )
-        maxdiff = diffs.maxDiff();
+    if( diffs.maxDiff() > _maxdiff )
+        _maxdiff = diffs.maxDiff();
 
     if( props.verbose >= 1 ) {
         if( diffs.maxDiff() > props.tol ) {
@@ -299,7 +305,7 @@ double BP::run() {
         } else {
             if( props.verbose >= 3 )
                 cout << "BP::run:  ";
-                cout << "converged in " << iter << " passes (" << toc() - tic << " clocks)." << endl;
+                cout << "converged in " << _iters << " passes (" << toc() - tic << " clocks)." << endl;
         }
     }
 
@@ -319,7 +325,7 @@ Factor BP::beliefV( size_t i ) const {
         prod.takeExp();
     }
 
-    prod.normalize( Prob::NORMPROB );
+    prod.normalize();
     return( Factor( var(i), prod ) );
 }
 
@@ -354,54 +360,58 @@ Factor BP::belief( const VarSet &ns ) const {
 
 
 Factor BP::beliefF (size_t I) const {
-    Prob prod( factor(I).p() );
-    if( props.logdomain )
-        prod.takeLog();
-
-    foreach( const Neighbor &j, nbF(I) ) {
-        size_t _I = j.dual;
-        // ind is the precalculated IndexFor(j,I) i.e. to x_I == k corresponds x_j == ind[k]
-        const ind_t & ind = index(j, _I);
-
-        // prod_j will be the product of messages coming into j
-        Prob prod_j( var(j).states(), props.logdomain ? 0.0 : 1.0 ); 
-        foreach( const Neighbor &J, nbV(j) ) {
-            if( J != I ) { // for all J in nb(j) \ I 
+    if( 0 == 1 ) {
+        /*  UNOPTIMIZED (SIMPLE TO READ, BUT SLOW) VERSION */
+
+        Factor prod( factor(I) );
+        foreach( const Neighbor &j, nbF(I) ) {
+            foreach( const Neighbor &J, nbV(j) ) {
+                if( J != I )  // for all J in nb(j) \ I
+                    prod *= Factor( var(j), newMessage(j, J.iter) );
+            }
+        }
+        return prod.normalized();
+    } else {
+        /* OPTIMIZED VERSION */
+        Prob prod( factor(I).p() );
+        if( props.logdomain )
+            prod.takeLog();
+
+        foreach( const Neighbor &j, nbF(I) ) {
+            size_t _I = j.dual;
+            // ind is the precalculated IndexFor(j,I) i.e. to x_I == k corresponds x_j == ind[k]
+            const ind_t & ind = index(j, _I);
+
+            // prod_j will be the product of messages coming into j
+            Prob prod_j( var(j).states(), props.logdomain ? 0.0 : 1.0 ); 
+            foreach( const Neighbor &J, nbV(j) ) {
+                if( J != I ) { // for all J in nb(j) \ I 
+                    if( props.logdomain )
+                        prod_j += newMessage( j, J.iter );
+                    else
+                        prod_j *= newMessage( j, J.iter );
+                }
+            }
+
+            // multiply prod with prod_j
+            for( size_t r = 0; r < prod.size(); ++r ) {
                 if( props.logdomain )
-                    prod_j += newMessage( j, J.iter );
+                    prod[r] += prod_j[ind[r]];
                 else
-                    prod_j *= newMessage( j, J.iter );
+                    prod[r] *= prod_j[ind[r]];
             }
         }
 
-        // multiply prod with prod_j
-        for( size_t r = 0; r < prod.size(); ++r ) {
-            if( props.logdomain )
-                prod[r] += prod_j[ind[r]];
-            else
-                prod[r] *= prod_j[ind[r]];
+        if( props.logdomain ) {
+            prod -= prod.maxVal();
+            prod.takeExp();
         }
-    }
-
-    if( props.logdomain ) {
-        prod -= prod.maxVal();
-        prod.takeExp();
-    }
-
-    Factor result( factor(I).vars(), prod );
-    result.normalize( Prob::NORMPROB );
 
-    return( result );
+        Factor result( factor(I).vars(), prod );
+        result.normalize();
 
-/*  UNOPTIMIZED VERSION
-    Factor prod( factor(I) );
-    for( _nb_cit i = nb2(I).begin(); i != nb2(I).end(); i++ ) {
-        for( _nb_cit J = nb1(*i).begin(); J != nb1(*i).end(); J++ )
-            if( *J != I )
-                prod *= Factor( var(*i), newMessage(*i,*J)) );
+        return( result );
     }
-    return prod.normalize( Prob::NORMPROB );*/
 }
 
 
index 0c0d5c5..b3fd1da 100644 (file)
@@ -1,13 +1,13 @@
 # --- BP ----------------------
 
-BP_SEQFIX:                      BP[updates=SEQFIX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0]
-BP_SEQRND:                      BP[updates=SEQRND,tol=1e-9,maxiter=10000,verbose=0,logdomain=0]
-BP_SEQMAX:                      BP[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0]
-BP_PARALL:                      BP[updates=PARALL,tol=1e-9,maxiter=10000,verbose=0,logdomain=0]
-BP_SEQFIX_LOG:                  BP[updates=SEQFIX,tol=1e-9,maxiter=10000,verbose=0,logdomain=1]
-BP_SEQRND_LOG:                  BP[updates=SEQRND,tol=1e-9,maxiter=10000,verbose=0,logdomain=1]
-BP_SEQMAX_LOG:                  BP[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=1]
-BP_PARALL_LOG:                  BP[updates=PARALL,tol=1e-9,maxiter=10000,verbose=0,logdomain=1]
+BP_SEQFIX:                      BP[updates=SEQFIX,tol=1e-9,maxiter=10000,logdomain=0]
+BP_SEQRND:                      BP[updates=SEQRND,tol=1e-9,maxiter=10000,logdomain=0]
+BP_SEQMAX:                      BP[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0]
+BP_PARALL:                      BP[updates=PARALL,tol=1e-9,maxiter=10000,logdomain=0]
+BP_SEQFIX_LOG:                  BP[updates=SEQFIX,tol=1e-9,maxiter=10000,logdomain=1]
+BP_SEQRND_LOG:                  BP[updates=SEQRND,tol=1e-9,maxiter=10000,logdomain=1]
+BP_SEQMAX_LOG:                  BP[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=1]
+BP_PARALL_LOG:                  BP[updates=PARALL,tol=1e-9,maxiter=10000,logdomain=1]
 
 # --- JTREE -------------------
 
@@ -55,26 +55,25 @@ HAK_LOOP8:                      HAK[doubleloop=1,clusters=LOOP,loopdepth=8,tol=1
 
 # --- LC ----------------------
 
-LCBP_FULLCAVin_SEQFIX:          LC[cavity=FULL,reinit=1,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_FULLCAVin_SEQRND:          LC[cavity=FULL,reinit=1,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_FULLCAVin_NONE:            LC[cavity=FULL,reinit=1,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_FULLCAV_SEQFIX:            LC[cavity=FULL,reinit=0,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_FULLCAV_SEQRND:            LC[cavity=FULL,reinit=0,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_FULLCAV_NONE:              LC[cavity=FULL,reinit=0,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIRCAVin_SEQFIX:          LC[cavity=PAIR,reinit=1,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIRCAVin_SEQRND:          LC[cavity=PAIR,reinit=1,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIRCAVin_NONE:            LC[cavity=PAIR,reinit=1,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIRCAV_SEQFIX:            LC[cavity=PAIR,reinit=0,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIRCAV_SEQRND:            LC[cavity=PAIR,reinit=0,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIRCAV_NONE:              LC[cavity=PAIR,reinit=0,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIR2CAVin_SEQFIX:         LC[cavity=PAIR2,reinit=1,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIR2CAVin_SEQRND:         LC[cavity=PAIR2,reinit=1,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIR2CAVin_NONE:           LC[cavity=PAIR2,reinit=1,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIR2CAV_SEQFIX:           LC[cavity=PAIR2,reinit=0,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIR2CAV_SEQRND:           LC[cavity=PAIR2,reinit=0,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
-LCBP_PAIR2CAV_NONE:             LC[cavity=PAIR2,reinit=0,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,verbose=0,logdomain=0],tol=1e-9,verbose=0]
+LCBP_FULLCAVin_SEQFIX:          LC[cavity=FULL,reinit=1,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_FULLCAVin_SEQRND:          LC[cavity=FULL,reinit=1,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_FULLCAVin_NONE:            LC[cavity=FULL,reinit=1,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_FULLCAV_SEQFIX:            LC[cavity=FULL,reinit=0,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_FULLCAV_SEQRND:            LC[cavity=FULL,reinit=0,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_FULLCAV_NONE:              LC[cavity=FULL,reinit=0,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIRCAVin_SEQFIX:          LC[cavity=PAIR,reinit=1,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIRCAVin_SEQRND:          LC[cavity=PAIR,reinit=1,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIRCAVin_NONE:            LC[cavity=PAIR,reinit=1,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIRCAV_SEQFIX:            LC[cavity=PAIR,reinit=0,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIRCAV_SEQRND:            LC[cavity=PAIR,reinit=0,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIRCAV_NONE:              LC[cavity=PAIR,reinit=0,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIR2CAVin_SEQFIX:         LC[cavity=PAIR2,reinit=1,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIR2CAVin_SEQRND:         LC[cavity=PAIR2,reinit=1,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIR2CAVin_NONE:           LC[cavity=PAIR2,reinit=1,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIR2CAV_SEQFIX:           LC[cavity=PAIR2,reinit=0,updates=SEQFIX,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIR2CAV_SEQRND:           LC[cavity=PAIR2,reinit=0,updates=SEQRND,maxiter=10000,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
+LCBP_PAIR2CAV_NONE:             LC[cavity=PAIR2,reinit=0,updates=SEQFIX,maxiter=0,cavainame=BP,cavaiopts=[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0],tol=1e-9,verbose=0]
 LCBP_UNICAV_SEQFIX:             LC[cavity=UNIFORM,updates=SEQFIX,maxiter=10000,tol=1e-9,verbose=0,cavaiopts=[],cavainame=NONE]
 LCBP_UNICAV_SEQRND:             LC[cavity=UNIFORM,updates=SEQRND,maxiter=10000,tol=1e-9,verbose=0,cavaiopts=[],cavainame=NONE]
 LCTREEEP:                       LC[cavity=FULL,reinit=1,updates=SEQFIX,maxiter=10000,cavainame=TREEEP,cavaiopts=[type=ORG,tol=1e-9,maxiter=10000,verbose=0],tol=1e-9,verbose=0]
 LCMF:                           LC[cavity=FULL,reinit=1,updates=SEQFIX,maxiter=10000,cavainame=MF,cavaiopts=[tol=1e-9,maxiter=10000,verbose=0],tol=1e-9,verbose=0]
-