messagepassing_operations.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_MESSAGEPASSING_OPERATIONS_HXX
00003 #define OPENGM_MESSAGEPASSING_OPERATIONS_HXX
00004 
00005 #include <opengm/opengm.hxx>
00006 #include <opengm/operations/adder.hxx>
00007 #include <opengm/operations/multiplier.hxx>
00008 #include <opengm/operations/minimizer.hxx>
00009 #include <opengm/operations/maximizer.hxx>
00010 
00012 
00013 namespace opengm {
00014 namespace messagepassingOperations {
00015 
00016 // out = M(M.shape, OP:neutral)
00018 template<class OP, class M>
00019 inline void clean(M& out) {
00020    for(size_t n=0; n<out.size(); ++n ) {
00021       OP::neutral(out(n));
00022    }
00023 /*
00024    const size_t loopSize= out.size()/2;
00025    for(size_t n=0; n<loopSize;n+=2 ) {
00026       OP::neutral(out(n));
00027       OP::neutral(out(n+1));
00028    }
00029    const size_t loopSize2= loopSize*2;
00030    if(loopSize2!=out.size()) {
00031       OP::neutral(out(loopSize2));
00032    }
00033 */
00034 }
00035       
00036 template<class OP, class ACC, class M>
00037 inline void normalize
00038 (
00039    M& out
00040 ) {
00041    typename M::ValueType v;
00042    ACC::neutral(v);
00043    for(size_t n=0; n<out.size(); ++n)
00044       ACC::op(out(n),v);
00045          
00046    if( opengm::meta::Compare<OP,opengm::Multiplier>::value && v <= 0.00001)
00047       return;
00048    if(opengm::meta::Compare<OP,opengm::Multiplier>::value)
00049       OPENGM_ASSERT(v > 0.00001); // ??? this should be checked in released code   
00050    for(size_t n=0; n<out.size();++n ) {
00051       OP::iop(v,out(n));      
00052    }
00053 /*
00054    const size_t loopSize= out.size()/2;
00055    for(size_t n=0; n<loopSize;n+=2 ) {
00056       OP::iop(v,out(n));
00057       OP::iop(v,out(n+1));
00058    }
00059    const size_t loopSize2= loopSize*2;
00060    if(loopSize2!=out.size()) {
00061       OP::iop(v,out(loopSize2));
00062    }
00063 */
00064 }
00065 
00067 template<class OP, class M, class T>
00068 inline void weightedMean
00069 (
00070    const M& in1,
00071    const M& in2, 
00072    const T alpha, 
00073    M& out
00074 ) { 
00077    T v1,v2;
00078    const T oneMinusAlpha=static_cast<T>(1)-alpha;
00079         
00080    for(size_t n=0; n<out.size();++n ) {
00081       OP::hop(in1(n),alpha,  v1);
00082       OP::hop(in2(n),oneMinusAlpha,v2);
00083       OP::op(v1,v2,out(n));
00084    }
00085    /*
00086    const size_t loopSize= out.size()/2;
00087    for(size_t n=0; n<loopSize;n+=2 ) {
00088       OP::hop(in1(n),alpha,  v1);
00089       OP::hop(in2(n),oneMinusAlpha,v2);
00090       OP::op(v1,v2,out(n));
00091             
00092       OP::hop(in1(n+1),alpha,  v1);
00093       OP::hop(in2(n+1),oneMinusAlpha,v2);
00094       OP::op(v1,v2,out(n+1));
00095    }
00096    const size_t loopSize2= loopSize*2;
00097    if(loopSize2!=out.size()) {
00098       OP::hop(in1(loopSize2),alpha,  v1);
00099       OP::hop(in2(loopSize2),oneMinusAlpha,v2);
00100       OP::op(v1,v2,out(loopSize2));
00101    }
00102    */
00103 }
00104       
00106 template<class OP, class BUFFER, class M>
00107 inline void operate
00108 (
00109    const std::vector<BUFFER>& vec,
00110    M& out
00111 ) {
00114    clean<OP>(out);
00115    for(size_t j = 0; j < vec.size(); ++j) {
00116       const typename BUFFER::ArrayType& b = vec[j].current();
00117       OPENGM_ASSERT(b.size()==out.size());
00118       for(size_t n=0; n<out.size(); ++n) 
00119          OP::op(b(n), out(n));
00120    }
00121 }  
00122       
00124 template<class GM, class BUFFER, class M>
00125 inline void operateW
00126 (
00127    const std::vector<BUFFER>& vec,
00128    const std::vector<typename GM::ValueType>& rho,
00129    M& out
00130 ) {
00131    typedef typename GM::OperatorType OP;
00132    clean<OP>(out);
00136    for(size_t j = 0; j < vec.size(); ++j) {
00137       const typename BUFFER::ArrayType& b = vec[j].current();
00138       typename GM::ValueType e = rho[j];
00139       typename GM::ValueType v;
00140       for(size_t n=0; n<out.size(); ++n) {
00141          OP::hop(b(n),e,v);
00142          OP::op(v,out(n));
00143       }
00144    }
00145 }
00146    
00148 template<class OP, class BUFVEC, class M, class INDEX>
00149 inline void operate
00150 (
00151    const BUFVEC& vec,
00152    const INDEX i, 
00153    M& out
00154 ) {
00155    clean<OP>(out); 
00159    for(size_t j = 0; j < i; ++j) {
00160       const M& f = vec[j].current();
00161       for(size_t n=0; n<out.size(); ++n) 
00162          OP::op(f(n), out(n));
00163    }
00164    for(size_t j = i+1; j < vec.size(); ++j) {
00165       const M& f = vec[j].current();
00166       for(size_t n=0; n<out.size(); ++n) 
00167          OP::op(f(n), out(n));        
00168    }
00169 }
00170  
00172 template<class GM, class BUFVEC, class M, class INDEX>
00173 inline void operateW
00174 (
00175    const BUFVEC& vec, 
00176    const INDEX i, 
00177    const std::vector<typename GM::ValueType>& rho,
00178    M& out
00179 ) {  
00180    typedef typename GM::OperatorType OP;
00181    OPENGM_ASSERT(vec[i].current().size()==out.size());
00182    typename GM::ValueType v;
00183    const typename GM::ValueType e = rho[i]-1;
00184    const M& b = vec[i].current();
00185    for(size_t n=0; n<out.size(); ++n) {
00186       //OP::hop(b(n),e,v);
00187       //OP::op(v,out(n));
00188       OP::hop(b(n),e,out(n));
00189    }
00190          
00191    for(size_t j = 0; j < i; ++j) {
00192       const M& b = vec[j].current();
00193       const typename GM::ValueType e = rho[j];
00194       OPENGM_ASSERT(b.size()==out.size());
00195       for(size_t n=0; n<out.size(); ++n) {
00196          OP::hop(b(n),e,v);
00197          OP::op(v,out(n));
00198       }
00199    } 
00200    for(size_t j = i+1; j < vec.size(); ++j) {
00201       const M& b = vec[j].current();
00202       const typename GM::ValueType e = rho[j];
00203       OPENGM_ASSERT(b.size()==out.size());
00204       for(size_t n=0; n<out.size(); ++n) {
00205          OP::hop(b(n),e,v);
00206          OP::op(v,out(n));
00207       }
00208    }       
00209 }
00210       
00212 template<class GM, class ACC, class BUFVEC, class ARRAY, class INDEX>
00213 inline void operateF
00214 (
00215    const typename GM::FactorType& f, 
00216    const BUFVEC& vec, 
00217    const INDEX i, 
00218    ARRAY& out
00219 ) {  //TODO: Speedup, Inplace
00220    typedef typename GM::OperatorType OP;
00221    if(f.numberOfVariables()==2) {
00222       size_t count[2];
00223       typename GM::ValueType v;
00224       for(size_t n=0; n<out.size(); ++n)
00225          ACC::neutral(out(n));
00226       for(count[0]=0;count[0]<f.numberOfLabels(0);++count[0]) { 
00227          for(count[1]=0;count[1]<f.numberOfLabels(1);++count[1]) {
00228             v = f(count);
00229             if(i==0)
00230                OP::op(vec[1].current()(count[1]), v);
00231             else
00232                OP::op(vec[0].current()(count[0]), v);
00233             /*
00234             for(size_t j = 0; j < i; ++j)
00235                OP::op(vec[j].current()(count[j]), v);
00236             for(size_t j = i+1; j < vec.size(); ++j)
00237                OP::op(vec[j].current()(count[j]), v);
00238             */ 
00239             ACC::op(v,out(count[i]));
00240          }
00241       }
00242    }
00243    else{
00244       // accumulation over all variables except x
00245       typedef typename GM::IndexType IndexType;
00246       typedef typename GM::LabelType LabelType;
00247       // neutral initialization of output
00248       for(size_t n=0; n<f.numberOfLabels(i); ++n)
00249          ACC::neutral(out(n));
00250       // factor shape iterator
00251       typedef typename GM::FactorType::ShapeIteratorType FactorShapeIteratorType;
00252       opengm::ShapeWalker<FactorShapeIteratorType> shapeWalker(f.shapeBegin(),f.numberOfVariables());
00253       for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) {
00254          // loop over the variables
00255          // initialize output value with value of the factor at this coordinate
00256          // operate j=[0,..i-1]
00257          typename GM::ValueType value=f(shapeWalker.coordinateTuple().begin());
00258          for(IndexType j=0;j<static_cast<typename GM::IndexType>(i);++j) {
00259             const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
00260             OP::op(vec[j].current()(label),value);
00261          }
00262          // operate j=[i+1,..,vec.size()]
00263          for(IndexType j=i+1;j< vec.size();++j) {
00264             const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
00265             OP::op(vec[j].current()(label),value);
00266          }
00267          // accumulate 
00268          ACC::op(value,out(shapeWalker.coordinateTuple()[i]));
00269       }
00270       //typename GM::IndependentFactorType temp = f; 
00271       //std::vector<size_t> accVar;
00272       //accVar.reserve(vec.size());
00273       //
00274       //for(size_t j = 0; j < i; ++j) {
00275       //   size_t var = f.variableIndex(j);
00276       //   typename GM::IndependentFactorType dummy(&var, &var+1,vec[j].current().shapeBegin(),vec[j].current().shapeEnd());
00277       //   for(size_t n=0; n<dummy.size();++n)
00278       //      dummy(n) = vec[j].current()(n);
00279       //   OP::op(dummy, temp);
00280       //   accVar.push_back(f.variableIndex(j));
00281       //}
00282       // 
00283       //for(size_t j = i+1; j < vec.size(); ++j) {
00284       //   size_t var = f.variableIndex(j);
00285       //   typename GM::IndependentFactorType dummy(&var, &var+1,vec[j].current().shapeBegin(),vec[j].current().shapeEnd());
00286       //   for(size_t n=0; n<dummy.size();++n)
00287       //      dummy(n) = vec[j].current()(n);
00288       //   OP::op(dummy, temp);
00289       //   accVar.push_back(f.variableIndex(j));
00290       //}
00291       //temp.template accumulate<ACC> (accVar.begin(), accVar.end());
00292       //for(size_t n=0; n<temp.size(); ++n) {
00293       //   out(n) = temp(n);
00294       //}
00295    }  
00296 }
00297 
00299 template<class GM, class ACC, class BUFVEC, class M, class INDEX>
00300 inline void operateWF
00301 (
00302    const typename GM::FactorType& f, 
00303    const typename GM::ValueType rho, 
00304    const BUFVEC& vec, 
00305    const INDEX i, 
00306    M& out
00307 ) {//TODO: Speedup, Inplace   
00308    typedef typename GM::IndexType IndexType;
00309    typedef typename GM::LabelType LabelType;
00310    typedef typename GM::OperatorType OP;
00311    // neutral initialization of output
00312    for(size_t n=0; n<f.numberOfLabels(i); ++n)
00313       ACC::neutral(out(n));
00314    // factor shape iterator
00315    typedef typename GM::FactorType::ShapeIteratorType FactorShapeIteratorType;
00316    opengm::ShapeWalker<FactorShapeIteratorType> shapeWalker(f.shapeBegin(),f.numberOfVariables());
00317    for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) {
00318       // loop over the variables
00319       // initialize output value with value of the factor at this coordinate
00320       // operate j=[0,..i-1]
00321       typename GM::ValueType value;
00322       OP::ihop(f(shapeWalker.coordinateTuple().begin()),rho,value);
00323       for(IndexType j=0;j<static_cast<typename GM::IndexType>(i);++j) {
00324          const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
00325          OP::op(vec[j].current()(label),value);
00326       }
00327       // operate j=[i+1,..,vec.size()]
00328       for(IndexType j=i+1;j< vec.size();++j) {
00329          const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
00330          OP::op(vec[j].current()(label),value);
00331       }
00332       // accumulate 
00333       ACC::op(value,out(shapeWalker.coordinateTuple()[i]));
00334    }
00335 
00336    //typedef typename GM::OperatorType OP;
00337    //typename GM::IndependentFactorType temp = f; 
00338    //OP::ihop(f, rho, temp);
00339    //std::vector<size_t> accVar;
00340    //accVar.reserve(vec.size());      
00341    //for(size_t j = 0; j < i; ++j) {
00342    //   size_t var = f.variableIndex(j);
00343    //   typename GM::IndependentFactorType dummy(&var, &var+1,vec[j].current().shapeBegin(),vec[j].current().shapeEnd());
00344    //   for(size_t n=0; n<dummy.size();++n)
00345    //      dummy(n) = vec[j].current()(n);
00346    //   OP::op(dummy, temp);
00347    //   accVar.push_back(f.variableIndex(j));
00348    //} 
00349    //for(size_t j = i+1; j < vec.size(); ++j) {
00350    //   size_t var = f.variableIndex(j);
00351    //   typename GM::IndependentFactorType dummy(&var, &var+1,vec[j].current().shapeBegin(),vec[j].current().shapeEnd());
00352    //   for(size_t n=0; n<dummy.size();++n)
00353    //      dummy(n) = vec[j].current()(n);
00354    //   OP::op(dummy, temp);
00355    //   accVar.push_back(f.variableIndex(j));
00356    //}
00357    //temp.template accumulate<ACC> (accVar.begin(), accVar.end());
00358    //for(size_t n=0; n<temp.size(); ++n) {
00359    //   out(n) = temp(n);
00360    //}  
00361 }
00362 
00364 template<class GM, class BUFVEC>
00365 inline void operateF
00366 (
00367    const typename GM::FactorType& f, 
00368    const BUFVEC& vec, 
00369    typename GM::IndependentFactorType& out
00370 )
00371 {
00372    OPENGM_ASSERT(out.numberOfVariables()!=0);
00373    //TODO: Speedup
00374    typedef typename GM::IndexType IndexType;
00375    typedef typename GM::LabelType LabelType;
00376    typedef typename GM::OperatorType OP;
00377    // factor shape iterator
00378    typedef typename GM::FactorType::ShapeIteratorType FactorShapeIteratorType;
00379    opengm::ShapeWalker<FactorShapeIteratorType> shapeWalker(f.shapeBegin(),f.numberOfVariables());
00380    for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) {
00381       // loop over the variables
00382       typename GM::ValueType value=f(shapeWalker.coordinateTuple().begin());
00383       for(IndexType j=0;j<static_cast<typename GM::IndexType>(vec.size());++j) {
00384          const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
00385          OP::op(vec[j].current()(label),value);
00386       }
00387       out(scalarIndex)=value;
00388    }
00389    //typedef typename GM::OperatorType OP;
00390    //out = f; 
00391    // accumulation over all variables except x
00392    //for(size_t j = 0; j < vec.size(); ++j) {
00393    //   size_t var = f.variableIndex(j);
00394    //   typename GM::IndependentFactorType dummy(&var, &var+1,vec[j].current().shapeBegin(),vec[j].current().shapeEnd());
00395    //   for(size_t n=0; n<dummy.size();++n)
00396    //      dummy(n) = vec[j].current()(n); 
00397    //   //OPENGM_ASSERT(f.variableIndex(j)==vec[j].current().variableIndex(0));   
00398    //   OP::op(dummy, out);
00399    //}
00400 }
00401 
00402 
00404 template<class GM, class BUFVEC>
00405 inline void operateWF
00406 (
00407    const typename GM::FactorType& f, 
00408    const typename GM::ValueType rho, 
00409    const BUFVEC& vec, 
00410    typename GM::IndependentFactorType& out
00411 ) {//TODO: Speedup
00412    typedef typename GM::OperatorType OP;
00413    typedef typename GM::IndexType IndexType;
00414    typedef typename GM::LabelType LabelType;
00415    typedef typename GM::FactorType::ShapeIteratorType FactorShapeIteratorType;
00416    opengm::ShapeWalker<FactorShapeIteratorType> shapeWalker(f.shapeBegin(),f.numberOfVariables());
00417    for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) {
00418       // loop over the variables
00419       typename GM::ValueType value;
00420       OP::ihop(f(shapeWalker.coordinateTuple().begin()),rho,value);
00421       for(IndexType j=0;j<static_cast<typename GM::IndexType>(vec.size());++j) {
00422          const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
00423          OP::op(vec[j].current()(label),value);
00424       }
00425       out(scalarIndex)=value;
00426    }
00427            
00428    //OP::ihop(f, rho, out);
00429    //for(size_t j = 0; j <  vec.size(); ++j) {
00430    //   size_t var = f.variableIndex(j);
00431    //   typename GM::IndependentFactorType dummy(&var, &var+1,vec[j].current().shapeBegin(),vec[j].current().shapeEnd());
00432    //   for(size_t n=0; n<dummy.size();++n)
00433    //      dummy(n) = vec[j].current()(n); 
00434    //   //OPENGM_ASSERT(f.variableIndex(j)==vec[j].current().variableIndex(0));   
00435    //   OP::op(dummy, out);
00436    //} 
00437 }
00438 /* 
00439 
00440 template<class GM, class BUFVEC> 
00441 void operateFi(
00442    const typename GM::FactorType& myFactor, 
00443    const BUFVEC& vec, 
00444    typename GM::IndependentFactorType& b
00445    )
00446 {//SPEED ME UP
00447    typedef typename GM::OperatorType OP;
00448    b=myFactor;
00449    for(size_t j=0; j<vec.size();++j) {
00450       size_t var = myFactor.variableIndex(j);
00451       typename GM::IndependentFactorType dummy(&var, &var+1,vec[j]->current().shapeBegin(),vec[j]->current().shapeEnd());
00452       for(size_t n=0; n<dummy.size();++n)
00453          dummy(n) = vec[j]->current()(n); 
00454       OP::iop(dummy,b);
00455    }
00456 }
00457 
00458 template<class GM, class BUFVEC> 
00459 void operateFiW(
00460    const typename GM::FactorType& myFactor, 
00461    const BUFVEC& vec, 
00462    const typename GM::ValueType rho, 
00463    typename GM::IndependentFactorType& b
00464    )
00465 {//SPEED ME UP
00466    typedef typename GM::OperatorType OP;
00467    b=myFactor;
00468    for(size_t j=0; j<vec.size();++j) {
00469       size_t var = myFactor.variableIndex(j);
00470       typename GM::IndependentFactorType dummy(&var, &var+1,vec[j]->current().shapeBegin(),vec[j]->current().shapeEnd());
00471       for(size_t n=0; n<dummy.size();++n)
00472          OP::hop(vec[j]->current()(n),rho,dummy(n)); 
00473       OP::iop(dummy,b);
00474    }
00475 }
00476 
00477 template<class A, class B, class T, class OP, class ACC>
00478 T boundOperation(const A& a, const B& b)
00479 { 
00480    T v;
00481          
00482    if(typeid(ACC)==typeid(opengm::Adder) && typeid(OP)==typeid(opengm::Multiplier)) { 
00483       T t;
00484       OP::hop(a(0),b(0),v);
00485       for(size_t n=1; n<a.size(); ++n) {
00486          OP::hop(a(n),b(n),t);
00487          OP::op(t,v);
00488       }
00489    }
00490    else if(typeid(ACC)==typeid(opengm::Minimizer) || typeid(ACC)==typeid(opengm::Maximizer)) {
00491       v = b(0);
00492       for(size_t n=1; n<a.size(); ++n) {
00493          ACC::bop( a(n),v );
00494       }
00495    }
00496    else{
00497       ACC::neutral(v);
00498    }
00499    return v;
00500 }  
00501 */
00502     
00503 } // namespace messagepassingOperations
00504 } // namespace opengm
00505 
00507 
00508 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:04 2013 for OpenGM by  doxygen 1.6.3