accumulator.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_FUNCTION_LEVEL_ACCUMULATOR_HXX
00003 #define OPENGM_FUNCTION_LEVEL_ACCUMULATOR_HXX
00004 
00005 #include "opengm/utilities/accumulation.hxx"
00006 #include "opengm/utilities/accessor_iterator.hxx"
00007 #include "opengm/utilities/shape_accessor.hxx"
00008 #include "opengm/utilities/indexing.hxx"
00009 
00010 namespace opengm {
00011 
00013 
00015 template<class A, class B, class ACC>
00016 class AccumulateAllImpl {
00017    typedef typename A::LabelType LabelType;
00018    typedef typename A::ValueType ValueType;
00019 
00020 public:
00021    static void op(const A&, B&);
00022    static void op(const A&, B&, std::vector<LabelType>& state);
00023 };
00024 
00026 template<class A, class B, class ACC>
00027 class AccumulateSomeImpl {
00028    typedef typename A::LabelType LabelType;
00029    typedef typename A::IndexType IndexType;
00030    typedef typename A::ValueType ValueType;
00031    typedef std::vector<IndexType> ViSequenceType;
00032 
00033 public:
00034    template<class Iterator>
00035       static void op(const A&, const ViSequenceType&, Iterator, Iterator, B&, ViSequenceType&);
00036 };
00037 
00039 template<class A, class ACC>
00040 class AccumulateSomeInplaceImpl {
00041    typedef typename A::LabelType LabelType;
00042    typedef typename A::IndexType IndexType;
00043    typedef typename A::ValueType ValueType;
00044    typedef std::vector<IndexType> ViSequenceType;
00045 
00046 public:
00047    template<class Iterator>
00048       static void op(A&, ViSequenceType&, Iterator, Iterator);
00049 };
00050 
00052 template<class A, class B, class ACC>
00053 void AccumulateAllImpl<A, B, ACC>::op
00054 (
00055    const A& a,
00056    B& b
00057 ) {
00058    OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
00059    opengm::Accumulation<ValueType, LabelType, ACC> acc;
00060    const size_t dimA = a.dimension();
00061    const size_t numElement = a.size();
00062    if(dimA != 0) {
00063       typedef opengm::AccessorIterator<opengm::FunctionShapeAccessor<A>, true> ShapeIterType;
00064       ShapeIterType shapeABegin(a, 0);
00065       opengm::ShapeWalker< ShapeIterType> shapeWalker(shapeABegin, dimA);
00066       const opengm::FastSequence<size_t> & coordinate = shapeWalker.coordinateTuple();
00067       for(size_t i=0; i<numElement ; ++i) {
00068          acc(a(coordinate.begin()));
00069          ++shapeWalker;
00070       }
00071    }
00072    else {
00073       size_t indexSequenceToScalar[] = {0};
00074       acc(a(indexSequenceToScalar));
00075    }
00076    b = static_cast<B>(acc.value());
00077 }
00078 
00080 template<class A, class B, class ACC>
00081 void AccumulateAllImpl<A, B, ACC>::op
00082 (
00083    const A& a,
00084    B& b,
00085    std::vector<typename AccumulateAllImpl<A, B, ACC>::LabelType>& state
00086 ) {
00087    OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
00088    opengm::Accumulation<ValueType, LabelType, ACC> acc;
00089    const size_t dimA = a.dimension();
00090    const size_t numElement = a.size();
00091    if(dimA != 0) {
00092       state.resize(dimA);
00093       typedef opengm::AccessorIterator<opengm::FunctionShapeAccessor<A>, true> ShapeIterType;
00094       ShapeIterType shapeABegin(a, 0);
00095       opengm::ShapeWalker< ShapeIterType> shapeWalker(shapeABegin, dimA);
00096       const opengm::FastSequence<size_t> & coordinate = shapeWalker.coordinateTuple();
00097       for(size_t i=0; i<numElement; ++i) {
00098          acc(a(coordinate.begin()), coordinate);
00099          ++shapeWalker;
00100       }
00101       acc.state(state);
00102    }
00103    else {
00104       size_t indexSequenceToScalar[] = {0};
00105       acc(a(indexSequenceToScalar));
00106       state.clear();
00107    }
00108    b = static_cast<B>(acc.value());
00109 }
00110 
00112 template<class A, class B, class ACC>
00113 template<class Iterator>
00114 void AccumulateSomeImpl<A, B, ACC>::op
00115 (
00116    const A& a,
00117    const ViSequenceType& viA,
00118    Iterator viAccBegin,
00119    Iterator viAccEnd,
00120    B& b,
00121    ViSequenceType& viB
00122 ) {
00123    OPENGM_ASSERT(a.dimension() == viA.size());
00124    OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
00125    const size_t dimA = a.dimension();
00126    viB.clear();
00127    b.assign();
00128    if(dimA != 0) {
00129       size_t rawViSize = std::distance(viAccBegin, viAccEnd);
00130       opengm::FastSequence<size_t> viAcc;
00131       opengm::FastSequence<size_t> shapeAcc;
00132       opengm::FastSequence<size_t> shapeNotAcc;
00133       opengm::FastSequence<size_t> notAccPosition;
00134       for(size_t i=0; i <dimA; ++i) {
00135          bool found = false;
00136          for(size_t j=0; j < rawViSize; ++j) {
00137             if(static_cast<opengm::UInt64Type>(viA[i]) == static_cast<opengm::UInt64Type>(viAccBegin[j])) {
00138                viAcc.push_back(viAccBegin[j]);
00139                shapeAcc.push_back(a.shape(i));
00140                found = true;
00141                break;
00142             }
00143          }
00144          if(!found) {
00145             viB.push_back(viA[i]);
00146             shapeNotAcc.push_back(a.shape(i));
00147             notAccPosition.push_back(i);
00148          }
00149       }
00150       if(shapeAcc.size() == dimA) {
00151          // accumulate over all variables ???
00152          ValueType scalarAccResult;
00153          AccumulateAllImpl<A, ValueType, ACC>::op(a, scalarAccResult);
00154          size_t indexSequenceToScalar[] = {0};
00155          size_t shapeToScalarArray[] = {0};
00156          b.resize(shapeToScalarArray, shapeToScalarArray);
00157          b(indexSequenceToScalar) = scalarAccResult;
00158       }
00159       else if(shapeAcc.size() == 0) {
00160          // accumulate over no variable
00161          // ==> copy function
00162          b.resize(shapeNotAcc.begin(), shapeNotAcc.end());
00163          opengm::ShapeWalker< opengm::FastSequence<size_t>::const_iterator> shapeWalker(shapeNotAcc.begin(), dimA);
00164          const opengm::FastSequence<size_t> & coordinate = shapeWalker.coordinateTuple();
00165          for(size_t i=0; i <a.size() ; ++i) {
00166             b(coordinate.begin()) = a(coordinate.begin());
00167             ++shapeWalker;
00168          }
00169          viB.assign(viA.begin(),viA.end());
00170       }
00171       else {
00172          // resize dstFactor
00173          b.resize(shapeNotAcc.begin(), shapeNotAcc.end());
00174          // create a shapeWalker to walk over NOTACC:
00175          opengm::ShapeWalker< opengm::FastSequence<size_t>::const_iterator> walker(shapeNotAcc.begin(), shapeNotAcc.size());
00176          const opengm::FastSequence<size_t> & coordinateNotAcc = walker.coordinateTuple();
00177          // create a subshape walker to walker over ACC
00178          typedef opengm::AccessorIterator<opengm::FunctionShapeAccessor<A>, true> ShapeIterType;
00179          ShapeIterType shapeABegin(a, 0);
00180          SubShapeWalker< ShapeIterType ,opengm::FastSequence<size_t>,opengm::FastSequence<size_t> >
00181          subWalker(shapeABegin, dimA, notAccPosition, coordinateNotAcc);
00182          const size_t subSizeAcc = subWalker.subSize();
00183          // loop over variables we don't want to accumulate over
00184          for(size_t i=0; i<b.size(); ++i) {
00185             // loop over the variables we want to accumulate over
00186             // create an accumulator
00187             Accumulation<ValueType, LabelType, ACC> acc;
00188             subWalker.resetCoordinate();
00189             for(size_t j=0; j < subSizeAcc; ++j) {
00190                acc(a( subWalker.coordinateTuple().begin()));
00191                ++subWalker;
00192             }
00193             b(coordinateNotAcc.begin()) = acc.value();
00194             ++walker;
00195          }
00196       }
00197    }
00198    else {
00199       Accumulation<ValueType, LabelType, ACC> acc;
00200       size_t indexSequenceToScalar[] = {0};
00201       ValueType accRes=static_cast<ValueType>(0.0);
00202       acc(accRes);
00203       size_t shapeToScalarArray[] = {0};
00204       b.resize(shapeToScalarArray, shapeToScalarArray);
00205       b(indexSequenceToScalar) = acc.value();
00206    }
00207    OPENGM_ASSERT(b.dimension() == viB.size());
00208    OPENGM_ASSERT(b.dimension() != 0 || (b.dimension() == 0 && b.size() == 1));
00209 }
00210 
00212 template<class A, class ACC>
00213 template<class Iterator>
00214 void AccumulateSomeInplaceImpl<A, ACC>::op
00215 (
00216    A& a,
00217    ViSequenceType& viA,
00218    Iterator viAccBegin,
00219    Iterator viAccEnd
00220 ) {
00221    OPENGM_ASSERT(a.dimension() == viA.size());
00222    OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
00223    const size_t dimA = a.dimension();
00224    opengm::FastSequence<size_t> viB;
00225    if(dimA != 0) {
00226       const size_t rawViSize = std::distance(viAccBegin, viAccEnd);
00227       opengm::FastSequence<size_t> viAcc;
00228       opengm::FastSequence<size_t> shapeAcc;
00229       opengm::FastSequence<size_t> shapeNotAcc;
00230       opengm::FastSequence<size_t> notAccPosition;
00231       for(size_t i = 0; i <dimA; ++i) {
00232          bool found = false;
00233          for(size_t j=0; j < rawViSize; ++j) {
00234             if( static_cast<UInt64Type>(viA[i]) == static_cast<UInt64Type>(viAccBegin[j])) {
00235                viAcc.push_back(viAccBegin[j]);
00236                shapeAcc.push_back(a.shape(i));
00237                found = true;
00238                break;
00239             }
00240          }
00241          if(!found) {
00242             viB.push_back(viA[i]);
00243             shapeNotAcc.push_back(a.shape(i));
00244             notAccPosition.push_back(i);
00245          }
00246       }
00247       if(shapeAcc.size() == dimA) {
00248          // accumulate over all variables
00249          ValueType scalarAccResult;
00250          AccumulateAllImpl<A, ValueType, ACC>::op(a, scalarAccResult);
00251          a.assign();
00252          size_t shapeToScalarArray[] = {0};
00253          a.resize(shapeToScalarArray, shapeToScalarArray);
00254          a(shapeToScalarArray) = scalarAccResult;
00255          viA.clear();
00256       }
00257       else if(shapeAcc.size() == 0) {
00258          // accumulate over no variable
00259          // do nothing
00260       }
00261       else {
00262          // resize dstFactor
00263          A b;
00264          b.resize(shapeNotAcc.begin(), shapeNotAcc.end());
00265          // create a shapeWalker to walk over NOTACC:
00266          opengm::ShapeWalker< typename opengm::FastSequence<size_t>::const_iterator> walker(shapeNotAcc.begin(), shapeNotAcc.size());
00267          const opengm::FastSequence<size_t> & coordinateNotAcc = walker.coordinateTuple();
00268          // create a subshape walker to walker over ACC
00269          typedef opengm::AccessorIterator<opengm::FunctionShapeAccessor<A>, true> ShapeIterType;
00270          ShapeIterType shapeABegin(a, 0);
00271          SubShapeWalker< ShapeIterType,opengm::FastSequence<size_t> ,opengm::FastSequence<size_t> >
00272          subWalker(shapeABegin, dimA, notAccPosition, coordinateNotAcc);
00273          const size_t subSizeAcc = subWalker.subSize();
00274          // loop over variables  we don't want to accumulate
00275          for(size_t i=0; i < b.size(); ++i) {
00276             // loop over the variables  we want to accumulate
00277             // create an accumulator
00278             Accumulation<ValueType, LabelType, ACC> acc;
00279             subWalker.resetCoordinate();
00280             for(size_t j=0; j<subSizeAcc; ++j) {
00281                acc(a(subWalker.coordinateTuple().begin()));
00282                ++subWalker;
00283             }
00284             b(coordinateNotAcc.begin()) = acc.value();
00285             ++walker;
00286          }
00287          a = b;
00288          viA.assign(viB.begin(),viB.end());
00289       }
00290    }
00291    else {
00292       Accumulation<ValueType, LabelType, ACC> acc;
00293       ValueType accRes=static_cast<ValueType>(0.0);
00294       acc(accRes);
00295       a.assign();
00296       a(0) = acc.value();
00297    }
00298    OPENGM_ASSERT(a.dimension() == viA.size());
00299    OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
00300 }
00301 
00302 } // namespace opengm
00303 
00305 
00306 #endif // OPENGM_FUNCTION_LEVEL_ACCUMULATOR_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:01 2013 for OpenGM by  doxygen 1.6.3