[opengm] 377/386: merging changes from learning-branch into master

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Wed Aug 31 08:38:37 UTC 2016


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to branch debian/master
in repository opengm.

commit ef1a4dc93b78846b5ed72750df07c53053d2b346
Author: Joerg Kappes <kappes at math.uni-heidelberg.de>
Date:   Thu Aug 4 22:47:12 2016 +0200

    merging changes from learning-branch into master
---
 include/opengm/python/numpyview.hxx                |  22 +-
 include/opengm/python/opengmpython.hxx             |  63 +++---
 src/interfaces/python/opengm/__init__.py           |   2 +-
 .../opengm/_inference_interface_generator.py       |  59 +++++
 src/interfaces/python/opengm/functionhelper.py     |   4 +-
 .../python/opengm/opengmcore/CMakeLists.txt        |   9 +-
 .../python/opengm/opengmcore/__init__.py           |  19 +-
 .../python/opengm/opengmcore/function_injector.py  |  11 +-
 .../python/opengm/opengmcore/opengmcore.cpp        |  40 +++-
 .../python/opengm/opengmcore/pyFunctionGen.cxx     |  57 +++++
 .../python/opengm/opengmcore/pyFunctionTypes.cxx   | 241 ++++++++++++++++++---
 src/interfaces/python/opengm/opengmcore/pyGm.cxx   |  25 ++-
 src/interfaces/python/test.py                      |   3 +-
 13 files changed, 456 insertions(+), 99 deletions(-)

diff --git a/include/opengm/python/numpyview.hxx b/include/opengm/python/numpyview.hxx
index bf0eb21..1be7c44 100644
--- a/include/opengm/python/numpyview.hxx
+++ b/include/opengm/python/numpyview.hxx
@@ -31,7 +31,8 @@ public:
    typedef typename marray::View< V ,false >::const_iterator ConstIteratorType;
    typedef size_t const *  ShapeIteratorType;
    
-   NumpyView( ):allocFromCpp_(false){
+   NumpyView():allocFromCpp_(false){
+
    }
    NumpyView( boost::python::object  obj):allocFromCpp_(false){
       boost::python::numeric::array array = boost::python::extract<boost::python::numeric::array > (obj);
@@ -174,6 +175,25 @@ public:
       return view_.end();   
    }
 
+   marray::View< V, false > getSliceView(size_t dimension, size_t sliceIndex) {
+      // create base coordinate
+      std::vector<size_t> baseIterator(view_.dimension(), 0);
+      baseIterator[dimension] = sliceIndex;
+
+      // create expected shape
+      std::vector<size_t> shapeIterator(view_.shapeBegin(), view_.shapeEnd());
+      shapeIterator[dimension] = 1;
+
+      // return sub view of slice with reduced dimensions
+      marray::View< V, false > new_view = view_.view(baseIterator.begin(), shapeIterator.begin());
+      new_view.squeeze();
+      return new_view;
+   }
+
+   marray::View< V ,false > view()const{
+        return view_;
+   }
+
    //boost::python::object arrayObject()const{
    //   return arrayObj_;
    //};
diff --git a/include/opengm/python/opengmpython.hxx b/include/opengm/python/opengmpython.hxx
index dc7588c..0db4882 100644
--- a/include/opengm/python/opengmpython.hxx
+++ b/include/opengm/python/opengmpython.hxx
@@ -18,6 +18,9 @@
 #include "opengm/functions/truncated_squared_difference.hxx"
 #include "opengm/functions/sparsemarray.hxx"
 
+#include "opengm/functions/learnable/lpotts.hxx"
+#include "opengm/functions/learnable/lunary.hxx"
+
 #include <opengm/python/opengmpython.hxx>
 #include <opengm/python/converter.hxx>
 #include <opengm/python/numpyview.hxx>
@@ -45,31 +48,34 @@ namespace python{
       typedef opengm::ExplicitFunction<V ,I,I> type;
    };
 
-   template<class V,class I>
-   struct FTLGen{
-
-      typedef V ValueType;
-      typedef I IndexType;
-      typedef I LabelType;
-      typedef opengm::ExplicitFunction                      <ValueType,IndexType,LabelType> PyExplicitFunction;
-      typedef opengm::PottsFunction                         <ValueType,IndexType,LabelType> PyPottsFunction;
-      typedef opengm::PottsNFunction                        <ValueType,IndexType,LabelType> PyPottsNFunction;
-      typedef opengm::PottsGFunction                        <ValueType,IndexType,LabelType> PyPottsGFunction;
-      typedef opengm::TruncatedAbsoluteDifferenceFunction   <ValueType,IndexType,LabelType> PyTruncatedAbsoluteDifferenceFunction;
-      typedef opengm::TruncatedSquaredDifferenceFunction    <ValueType,IndexType,LabelType> PyTruncatedSquaredDifferenceFunction;
-      typedef opengm::SparseFunction                        <ValueType,IndexType,LabelType> PySparseFunction; 
-      typedef PythonFunction                                <ValueType,IndexType,LabelType> PyPythonFunction; 
-
-      typedef typename opengm::meta::TypeListGenerator<
-         PyExplicitFunction,
-         PyPottsFunction,
-         PyPottsNFunction,
-         PyPottsGFunction,
-         PyTruncatedAbsoluteDifferenceFunction,
-         PyTruncatedSquaredDifferenceFunction,
-         PySparseFunction,
-         PyPythonFunction
-      >::type type;
+    template<class V,class I>
+    struct FTLGen{
+
+        typedef V ValueType;
+        typedef I IndexType;
+        typedef I LabelType;
+        typedef opengm::ExplicitFunction                      <ValueType,IndexType,LabelType> PyExplicitFunction;
+        typedef opengm::PottsFunction                         <ValueType,IndexType,LabelType> PyPottsFunction;
+        typedef opengm::PottsNFunction                        <ValueType,IndexType,LabelType> PyPottsNFunction;
+        typedef opengm::PottsGFunction                        <ValueType,IndexType,LabelType> PyPottsGFunction;
+        typedef opengm::TruncatedAbsoluteDifferenceFunction   <ValueType,IndexType,LabelType> PyTruncatedAbsoluteDifferenceFunction;
+        typedef opengm::TruncatedSquaredDifferenceFunction    <ValueType,IndexType,LabelType> PyTruncatedSquaredDifferenceFunction;
+        typedef opengm::SparseFunction                        <ValueType,IndexType,LabelType> PySparseFunction; 
+        typedef opengm::functions::learnable::LPotts          <ValueType,IndexType,LabelType> PyLPottsFunction;
+        typedef opengm::functions::learnable::LUnary          <ValueType,IndexType,LabelType> PyLUnaryFunction;
+
+
+        typedef typename opengm::meta::TypeListGenerator<
+            PyExplicitFunction,
+            PyPottsFunction,
+            PyPottsNFunction,
+            PyPottsGFunction,
+            PyTruncatedAbsoluteDifferenceFunction,
+            PyTruncatedSquaredDifferenceFunction,
+            PySparseFunction,
+            PyLPottsFunction,
+            PyLUnaryFunction
+        >::type type;
    };
 
 
@@ -79,6 +85,8 @@ namespace python{
    typedef GmIndexType GmLabelType;
 
 
+   typedef opengm::learning::Weights<GmValueType> PyWeights;
+
 
    // different function types
    typedef opengm::ExplicitFunction                      <GmValueType,GmIndexType,GmLabelType> GmExplicitFunction;
@@ -90,8 +98,9 @@ namespace python{
    typedef opengm::SquaredDifferenceFunction             <GmValueType,GmIndexType,GmLabelType> GmSquaredDifferenceFunction;
    typedef opengm::TruncatedSquaredDifferenceFunction    <GmValueType,GmIndexType,GmLabelType> GmTruncatedSquaredDifferenceFunction;
    typedef opengm::SparseFunction                        <GmValueType,GmIndexType,GmLabelType> GmSparseFunction; 
-   typedef opengm::python::PythonFunction                <GmValueType,GmIndexType,GmLabelType> GmPythonFunction; 
-
+   typedef opengm::functions::learnable::LPotts          <GmValueType,GmIndexType,GmLabelType> PyLPottsFunction;
+   typedef opengm::functions::learnable::LUnary          <GmValueType,GmIndexType,GmLabelType> PyLUnaryFunction;
+   
    typedef std::vector<GmIndexType> IndexVectorType;
    typedef std::vector<IndexVectorType> IndexVectorVectorType;
 
diff --git a/src/interfaces/python/opengm/__init__.py b/src/interfaces/python/opengm/__init__.py
index 8258c93..a479397 100644
--- a/src/interfaces/python/opengm/__init__.py
+++ b/src/interfaces/python/opengm/__init__.py
@@ -14,7 +14,7 @@ from _inference_interface_generator import _inject_interface , InferenceBase
 import inference
 import hdf5
 import benchmark
-
+from _to_native_converter import to_native_boost_python_enum_converter
 # initialize solver/ inference dictionaries
 _solverDicts=[
    (inference.adder.minimizer.solver.__dict__ ,     'adder',       'minimizer' ),
diff --git a/src/interfaces/python/opengm/_inference_interface_generator.py b/src/interfaces/python/opengm/_inference_interface_generator.py
index 887d26a..15aa072 100644
--- a/src/interfaces/python/opengm/_inference_interface_generator.py
+++ b/src/interfaces/python/opengm/_inference_interface_generator.py
@@ -211,6 +211,60 @@ def classGenerator(
 
         self.inference = self._selectedInfClass(self.gm, self.parameter)
 
+    @classmethod
+    def get_cpp_parameter(cls, operator, accumulator, parameter):
+        _meta_parameter = parameter
+        # get hyper parameter (as minStCut for graphcut, or the subsolver for
+        # dualdec.)
+        hyperParamKeywords = inferenceClasses.hyperParameterKeywords
+        numHyperParams = len(hyperParamKeywords)
+        userHyperParams = [None]*numHyperParams
+        collectedHyperParameters = 0
+        # get the users hyper parameter ( if given)
+
+        if(_meta_parameter is not None):
+            for hpIndex, hyperParamKeyword in enumerate(hyperParamKeywords):
+                if hyperParamKeyword in _meta_parameter.kwargs:
+                    userHyperParams[hpIndex] = _meta_parameter.kwargs.pop(
+                        hyperParamKeyword)
+                    collectedHyperParameters += 1
+
+            # check if ZERO or ALL hyperParamerts have been collected
+            if collectedHyperParameters != 0 and collectedHyperParameters != numHyperParams:
+                raise RuntimeError("All or none hyper-parameter must be given")
+
+        # check if the WHOLE tuple of hyperParameters is allowed
+        if collectedHyperParameters != 0:
+            if tuple(str(x) for x in userHyperParams) not in inferenceClasses.implDict:
+                raise RuntimeError("%s is not an allowed hyperParameter\nAllowed hyperParameters are %s" % (
+                    repr(userHyperParams), repr(inferenceClasses.implDict.keys())))
+        else:
+            userHyperParams = defaultHyperParams
+
+        #try:
+        # get the selected inference class and the parameter
+        if(numHyperParams == 0):
+            
+            _selectedInfClass, _selectedInfParamClass = inferenceClasses.implDict[
+                    "__NONE__"][(operator, accumulator)]
+        else:
+            hp = tuple(str(x) for x in userHyperParams)
+            _selectedInfClass, _selectedInfParamClass = inferenceClasses.implDict[
+                hp][(operator, accumulator)]
+        #except:
+        #    dictStr=str(inferenceClasses.implDict)
+        #    raise RuntimeError("given seminring (operator = %s ,accumulator = %s) is not implemented for this solver\n %s" % \
+        #        (operator, accumulator,dictStr))
+
+        if _meta_parameter is None:
+            cppParam = self._selectedInfClass._parameter()
+            cppParam.set()
+        else:
+            cppParam = to_native_class_converter(
+                givenValue=_meta_parameter, nativeClass=_selectedInfParamClass)
+            assert cppParam is not None
+
+        return cppParam
     def verboseVisitor(self, printNth=1, multiline=True):
         """ factory function to get a verboseVisitor:
 
@@ -572,6 +626,11 @@ def classGenerator(
     infClass = type(classname, (InferenceBase,), memberDict)
 
     infClass.__init__ = inference_init
+
+
+    infClass.get_cpp_parameter = get_cpp_parameter
+
+
     # print to string!!!
     old_stdout = sys.stdout
     sys.stdout = mystdout = StringIO()
diff --git a/src/interfaces/python/opengm/functionhelper.py b/src/interfaces/python/opengm/functionhelper.py
index cf424cb..c8833e8 100644
--- a/src/interfaces/python/opengm/functionhelper.py
+++ b/src/interfaces/python/opengm/functionhelper.py
@@ -4,12 +4,12 @@ from opengmcore._opengmcore import (SparseFunction,
                                     TruncatedAbsoluteDifferenceFunction,
                                     TruncatedSquaredDifferenceFunction,
                                     PottsFunction, PottsNFunction,
-                                    PottsGFunction , PythonFunction,
+                                    PottsGFunction ,
                                     SparseFunctionVector, 
                                     TruncatedAbsoluteDifferenceFunctionVector,
                                     TruncatedSquaredDifferenceFunctionVector,
                                     PottsFunctionVector, PottsNFunctionVector,
-                                    PottsGFunctionVector , PythonFunctionVector,
+                                    PottsGFunctionVector ,
                                     
                                     )
 
diff --git a/src/interfaces/python/opengm/opengmcore/CMakeLists.txt b/src/interfaces/python/opengm/opengmcore/CMakeLists.txt
index b0e8ad0..fedb09a 100644
--- a/src/interfaces/python/opengm/opengmcore/CMakeLists.txt
+++ b/src/interfaces/python/opengm/opengmcore/CMakeLists.txt
@@ -81,7 +81,7 @@ if(LINK_RT)
     find_library(RT rt)
     target_link_libraries(_opengmcore ${Boost_PYTHON_LIBRARIES} rt)
 else()
-    target_link_libraries(_opengmcore ${Boost_PYTHON_LIBRARIES})
+    target_link_libraries(_opengmcore ${PYTHON_LIBRARY} ${Boost_PYTHON_LIBRARIES})
 endif(LINK_RT)
 
 IF(WITH_MAXFLOW)
@@ -100,8 +100,11 @@ ELSE()
     SET_TARGET_PROPERTIES(_opengmcore PROPERTIES OUTPUT_NAME "opengmcore"   PREFIX "_")
 ENDIF()
 
-
-
+IF(WIN32)
+    INSTALL(TARGETS _opengmcore RUNTIME DESTINATION ${PYTHON_INSTALL_DIR}/opengmcore)
+ELSE()
+    INSTALL(TARGETS _opengmcore LIBRARY DESTINATION ${PYTHON_INSTALL_DIR}/opengmcore)
+ENDIF()
 
 #--------------------------------------------------------------
 # Copy from src to build
diff --git a/src/interfaces/python/opengm/opengmcore/__init__.py b/src/interfaces/python/opengm/opengmcore/__init__.py
index ab17277..15f6ad7 100644
--- a/src/interfaces/python/opengm/opengmcore/__init__.py
+++ b/src/interfaces/python/opengm/opengmcore/__init__.py
@@ -1,4 +1,5 @@
 from _opengmcore import *
+from _opengmcore import _gridVis2d
 from factorSubset import FactorSubset
 from gm_injector import _extend_gm_classes
 from factor_injector import _extend_factor_classes
@@ -193,14 +194,15 @@ class Multiplier:
    def neutral(self):
       return float(1.0)
 
- 
-def modelViewFunction(factor):
-  class _ModelViewFunction:
-    def __init__(self,factor):
-      self.factor=factor
-    def __call__(self,labeling):
-      return self.factor[labeling]
-  return PythonFunction( _ModelViewFunction(factor) ,factor.shape.__tuple__())
+
+def gridVis(shape, numpyOrder=True):
+    assert len(shape) == 2
+    nFac = (shape[0]-1)*shape[1] + (shape[1]-1)*shape[0]
+    out = numpy.ones([nFac,2], dtype=index_type)
+    _gridVis2d(shape[0],shape[1],numpyOrder, out)
+    return out
+
+
 
 #Model generators
 def grid2d2Order(unaries,regularizer,order='numpy',operator='adder'):
@@ -351,7 +353,6 @@ _TruncatedSquaredDifferenceFunction  = TruncatedSquaredDifferenceFunction
 _PottsFunction                       = PottsFunction
 _PottsNFunction                      = PottsNFunction
 _PottsGFunction                      = PottsGFunction
-_PythonFunction                      = PythonFunction
 _FactorSubset                        = FactorSubset
 
 
diff --git a/src/interfaces/python/opengm/opengmcore/function_injector.py b/src/interfaces/python/opengm/opengmcore/function_injector.py
index bf0f832..f31c565 100644
--- a/src/interfaces/python/opengm/opengmcore/function_injector.py
+++ b/src/interfaces/python/opengm/opengmcore/function_injector.py
@@ -1,11 +1,11 @@
 from _opengmcore import ExplicitFunction,SparseFunction, \
                         TruncatedAbsoluteDifferenceFunction, \
                         TruncatedSquaredDifferenceFunction,PottsFunction,PottsNFunction, \
-                        PottsGFunction,PythonFunction,\
+                        PottsGFunction,\
                         ExplicitFunctionVector,SparseFunctionVector, \
                         TruncatedAbsoluteDifferenceFunctionVector, \
                         TruncatedSquaredDifferenceFunctionVector,PottsFunctionVector,PottsNFunctionVector, \
-                        PottsGFunctionVector,PythonFunctionVector
+                        PottsGFunctionVector
 import numpy
 
 
@@ -25,8 +25,8 @@ def _extend_function_vector_classes():
     function_vector_classes=[   ExplicitFunctionVector,SparseFunctionVector,
                                 TruncatedAbsoluteDifferenceFunctionVector,
                                 TruncatedSquaredDifferenceFunctionVector,PottsFunctionVector,
-                                PottsNFunctionVector,PottsGFunctionVector,
-                                PythonFunctionVector ]  
+                                PottsNFunctionVector,PottsGFunctionVector
+                                 ]  
 
     for function_vector in function_vector_classes:
         class InjectorGenericFunctionVector(object):
@@ -50,8 +50,7 @@ def _extend_function_type_classes():
   function_classes=[ExplicitFunction,SparseFunction,
                     TruncatedAbsoluteDifferenceFunction,
                     TruncatedSquaredDifferenceFunction,PottsFunction,
-                    PottsNFunction,PottsGFunction,
-                    PythonFunction]
+                    PottsNFunction,PottsGFunction]
 
 
 
diff --git a/src/interfaces/python/opengm/opengmcore/opengmcore.cpp b/src/interfaces/python/opengm/opengmcore/opengmcore.cpp
index c63aae1..eda42fd 100644
--- a/src/interfaces/python/opengm/opengmcore/opengmcore.cpp
+++ b/src/interfaces/python/opengm/opengmcore/opengmcore.cpp
@@ -276,6 +276,37 @@ GM *  pyPottsModel3d(
 
 }
 
+
+
+void gridVis2d(
+    const size_t dx,
+    const size_t dy,
+    const bool numpyOrder,
+    opengm::python::NumpyView< opengm::python::GmIndexType, 2> visarray
+){
+    size_t shape[2]={dx,dy};
+    CoordToVi toVi(shape,shape+2,numpyOrder);
+
+    size_t c=0;
+
+    for(size_t x=0; x<dx;++x)
+    for(size_t y=0; y<dy;++y){
+
+        if(x+1<dx){
+            visarray(c,0) = toVi(x,y);
+            visarray(c,1) = toVi(x+1,y);
+            ++c;
+        }
+        if(y+1<dy){
+            visarray(c,0) = toVi(x,y);
+            visarray(c,1) = toVi(x,y+1);
+            ++c;
+        }
+    }
+}
+
+
+
 void  makeMaskedState(
     opengm::python::NumpyView< opengm::UInt32Type, 3> mask,
     opengm::python::NumpyView< opengm::UInt64Type, 1> arg,
@@ -636,13 +667,15 @@ BOOST_PYTHON_MODULE_INIT(_opengmcore) {
 
 
       typedef std::deque<opengm::UInt64Type>  DequeUInt64;
+      typedef void (DequeUInt64::*DequePush)(opengm::UInt64Type const &);
+
       boost::python::class_<DequeUInt64>("DequeUInt64" ,init<>())
       .def("pop_front",&DequeUInt64::pop_front)
       .def("pop_back",&DequeUInt64::pop_back)
       .def("front",&dequeFront<DequeUInt64>)
       .def("back",&dequeBack<DequeUInt64>)
-      .def("push_front",&DequeUInt64::push_front)
-      .def("push_back",&DequeUInt64::push_back)
+      .def("push_front",(DequePush)&DequeUInt64::push_front)
+      .def("push_back",(DequePush)&DequeUInt64::push_back)
       .def("push_back",&dequePushBack<DequeUInt64>)
       .def("__len__",&DequeUInt64::size)
       .def("empty",&DequeUInt64::empty)
@@ -652,7 +685,7 @@ BOOST_PYTHON_MODULE_INIT(_opengmcore) {
    }
 
 
-
+   boost::python::def("_gridVis2d",&gridVis2d);
 
    //export_rag();
    export_config();
@@ -681,7 +714,6 @@ BOOST_PYTHON_MODULE_INIT(_opengmcore) {
 
       export_potts_model_3d<opengm::python::GmAdder>();
       export_potts_model_3d_masked<opengm::python::GmAdder>();
-
    }
    //multiplier
    {
diff --git a/src/interfaces/python/opengm/opengmcore/pyFunctionGen.cxx b/src/interfaces/python/opengm/opengmcore/pyFunctionGen.cxx
index c9f9d3a..2d138f6 100644
--- a/src/interfaces/python/opengm/opengmcore/pyFunctionGen.cxx
+++ b/src/interfaces/python/opengm/opengmcore/pyFunctionGen.cxx
@@ -117,6 +117,63 @@ private:
 };
 
 
+template<class GM_ADDER,class GM_MULT,class FUNCTION_TYPE>
+class LPottsFunctionGen :
+public FunctionGeneratorBase<GM_ADDER,GM_MULT>
+{
+public:
+    typedef FUNCTION_TYPE FunctionType;
+    typedef typename FUNCTION_TYPE::ValueType ValueType;
+    typedef typename FUNCTION_TYPE::IndexType IndexType;
+    typedef typename FUNCTION_TYPE::LabelType LabelType;
+    LPottsFunctionGen(
+
+        size_t numberOfLabels,
+        opengm::python::NumpyView<LabelType,2> numLabels1Array,
+        opengm::python::NumpyView<LabelType,1> numLabels2Array,
+        opengm::python::NumpyView<ValueType,1> valEqualArray,
+        opengm::python::NumpyView<ValueType,1> valNotEqualArray
+    ):FunctionGeneratorBase<GM_ADDER,GM_MULT>(),
+    numLabels1Array_(numLabels1Array),
+    numLabels2Array_(numLabels2Array),
+    valEqualArray_(valEqualArray),
+    valNotEqualArray_(valNotEqualArray)
+    {
+        numFunctions_=std::max( 
+            std::max(numLabels1Array_.shape(0),numLabels2Array_.shape(0)) , 
+            std::max(valEqualArray_.shape(0),valNotEqualArray_.shape(0))
+        );
+    }  
+
+   template<class GM>
+   std::vector< typename GM::FunctionIdentifier > * addFunctionsGeneric(GM & gm)const{
+      std::vector< typename GM::FunctionIdentifier > * fidVector = new std::vector< typename GM::FunctionIdentifier > (numFunctions_);
+      for(size_t  i=0;i<numFunctions_;++i){
+         const LabelType numL1=i<numLabels1Array_.size() ? numLabels1Array_(i) : numLabels1Array_(numLabels1Array_.size()-1);
+         const LabelType numL2=i<numLabels2Array_.size() ? numLabels2Array_(i) : numLabels2Array_(numLabels2Array_.size()-1);
+         const ValueType veq=i<valEqualArray_.size() ? valEqualArray_(i) : valEqualArray_(valEqualArray_.size()-1);
+         const ValueType vneq=i<valNotEqualArray_.size() ? valNotEqualArray_(i) : valNotEqualArray_(valNotEqualArray_.size()-1);
+         (*fidVector)[i]=gm.addFunction(FunctionType(numL1,numL2,veq,vneq));
+      }
+      return fidVector;
+   }
+    
+   virtual std::vector< typename GM_ADDER::FunctionIdentifier > * addFunctions(GM_ADDER & gm)const{
+      return this-> template addFunctionsGeneric<GM_ADDER>(gm);
+   }
+   virtual std::vector< typename GM_MULT::FunctionIdentifier >  * addFunctions(GM_MULT & gm)const{
+      return this-> template addFunctionsGeneric<GM_MULT>(gm);
+   }
+private:
+   opengm::python::NumpyView<LabelType,1>  numLabels1Array_;
+   opengm::python::NumpyView<LabelType,1>  numLabels2Array_;
+   opengm::python::NumpyView<ValueType,1>  valEqualArray_;
+   opengm::python::NumpyView<ValueType,1>  valNotEqualArray_;
+   size_t numFunctions_;
+};
+
+
+
 template<class GM_ADDER,class GM_MULT,class FUNCTION>
 inline FunctionGeneratorBase<GM_ADDER,GM_MULT> * pottsFunctionGen(
     opengm::python::NumpyView<typename GM_ADDER::LabelType,1> numLabels1Array,
diff --git a/src/interfaces/python/opengm/opengmcore/pyFunctionTypes.cxx b/src/interfaces/python/opengm/opengmcore/pyFunctionTypes.cxx
index 6571b3d..f5a343a 100644
--- a/src/interfaces/python/opengm/opengmcore/pyFunctionTypes.cxx
+++ b/src/interfaces/python/opengm/opengmcore/pyFunctionTypes.cxx
@@ -8,10 +8,10 @@
 #include <map>
 
 #include "nifty_iterator.hxx"
-#include <opengm/python/opengmpython.hxx>
-#include <opengm/python/converter.hxx>
-#include <opengm/python/numpyview.hxx>
-#include <opengm/python/pythonfunction.hxx>
+#include "opengm/python/opengmpython.hxx"
+#include "opengm/python/converter.hxx"
+#include "opengm/python/numpyview.hxx"
+#include "opengm/python/pythonfunction.hxx"
 
 #include "copyhelper.hxx"
 
@@ -26,7 +26,9 @@
 #include "opengm/functions/truncated_squared_difference.hxx"
 #include "opengm/functions/sparsemarray.hxx"
 
-
+#include "opengm/functions/learnable/lpotts.hxx"
+#include "opengm/functions/learnable/lunary.hxx"
+#include "opengm/functions/learnable/lweightedsum_of_functions.hxx"
 
 
 using namespace boost::python;
@@ -169,6 +171,146 @@ namespace pyfunction{
       return f;
    }
 
+
+
+
+   template<class FUNCTION>
+   FUNCTION * lPottsConstructor(
+        opengm::python::PyWeights & pyWeights,
+        const opengm::python::GmLabelType numberOfLabels,
+        opengm::python::NumpyView<opengm::python::GmIndexType,1> weightIds,
+        opengm::python::NumpyView<opengm::python::GmValueType,1> features
+
+    ){
+      FUNCTION * f = NULL;
+      
+      std::vector<size_t>      weightIdVec(weightIds.begin(), weightIds.end());
+      std::vector<opengm::python::GmValueType> featureVec(features.begin(), features.end());
+
+      f = new FUNCTION(pyWeights, numberOfLabels, weightIdVec, featureVec);
+      return f;
+   }
+
+
+    template<class FUNCTION>
+    FUNCTION * lUnaryConstructor(
+        opengm::python::PyWeights & pyWeights,
+        const opengm::python::GmLabelType numberOfLabels,
+        opengm::python::NumpyView<opengm::python::GmIndexType,2> weightIds,
+        opengm::python::NumpyView<opengm::python::GmValueType,2> features
+    ){
+        FUNCTION * f = NULL;
+        typedef opengm::functions::learnable::FeaturesAndIndices<
+            opengm::python::GmValueType,
+            opengm::python::GmIndexType
+        > FI;
+        typedef std::vector<FI> FI_VEC;
+
+        size_t fPerL = weightIds.shape(1);
+
+        OPENGM_CHECK_OP(weightIds.shape(0), <=, numberOfLabels,   "wrong shapes");
+        OPENGM_CHECK_OP(weightIds.shape(0), >=, numberOfLabels-1,   "wrong shapes");
+        OPENGM_CHECK_OP(weightIds.shape(0), ==, features.shape(0),"wrong shapes");
+        OPENGM_CHECK_OP(weightIds.shape(1), ==, features.shape(1),"wrong shapes");
+
+        FI_VEC fiVec(numberOfLabels);
+
+        const size_t weightShape0 =  weightIds.shape(0);
+        for(size_t l=0; l<weightShape0; ++l){
+            fiVec[l].weightIds.resize(fPerL);
+            fiVec[l].features.resize(fPerL);
+            for(size_t i=0; i<fPerL; ++i){
+                fiVec[l].weightIds[i] = weightIds(l, i);
+                fiVec[l].features[i] = features(l, i);
+            }
+        }
+        //std::cout<<"done on python side\n";
+        f = new FUNCTION(pyWeights, fiVec);
+        return f;
+    }
+
+    template<class FUNCTION>
+    FUNCTION * lUnaryConstructorList(
+        opengm::python::PyWeights & pyWeights,
+        const opengm::python::GmLabelType numberOfLabels,
+        boost::python::list weightIds,
+        boost::python::list features
+    ){
+
+        typedef opengm::python::NumpyView<opengm::python::GmIndexType,1> IndexArray;
+        typedef opengm::python::NumpyView<opengm::python::GmValueType,1> ValueArray;
+
+
+        OPENGM_CHECK_OP(boost::python::len(weightIds), == ,numberOfLabels ,"length of weightIds must be numberOfLabels");
+        OPENGM_CHECK_OP(boost::python::len(weightIds), == ,boost::python::len(features) ,"weightIds must be as long as features");
+
+
+        FUNCTION * f = NULL;
+        typedef opengm::functions::learnable::FeaturesAndIndices<
+            opengm::python::GmValueType,
+            opengm::python::GmIndexType
+        > FI;
+        typedef std::vector<FI> FI_VEC;
+
+        FI_VEC fiVec(numberOfLabels);
+
+        for(size_t l=0; l<numberOfLabels; ++l){
+
+            std::cout<<"extr. l "<<l<<"\n";
+            boost::python::extract<boost::python::numeric::array> eW(weightIds[l]);
+            boost::python::extract<boost::python::numeric::array> eF(features[l]);
+
+            IndexArray wId = eW();
+            ValueArray fs = eF();
+
+            std::cout<<"done\n";
+
+            OPENGM_CHECK_OP(wId.shape(0), ==, fs.shape(0), 
+                "for one label the number of features and the number of weights must be the same");
+
+            const size_t fPerL = wId.shape(0);
+            fiVec[l].weightIds.resize(fPerL);
+            fiVec[l].features.resize(fPerL);
+
+            for(size_t i=0; i<fPerL; ++i){
+                fiVec[l].weightIds[i] = wId(i);
+                fiVec[l].features[i] = fs(i);
+            }
+        }
+        f = new FUNCTION(pyWeights, fiVec);
+        return f;
+   }
+
+    template<class FUNCTION>
+    FUNCTION * weightedSumOfFunctionsConstructor(
+        boost::python::object pyShape,
+        opengm::python::PyWeights& pyWeights,
+        opengm::python::NumpyView<opengm::python::GmIndexType,1> weightIds,
+        opengm::python::NumpyView<opengm::python::GmValueType,3> features
+    ){
+        stl_input_iterator<int> begin(pyShape), end;
+        std::vector<opengm::python::GmLabelType> shape(begin, end);
+        std::vector<size_t> weightIdVec(weightIds.begin(), weightIds.end());
+        std::vector<marray::Marray<opengm::python::GmValueType> > featureVec;
+        for(size_t i = 0; i < features.shape(0); i++)
+        {
+            featureVec.push_back(marray::Marray<opengm::python::GmValueType>(features.getSliceView(0, i)));
+        }
+
+        FUNCTION * f = NULL;
+
+        OPENGM_CHECK_OP(weightIdVec.size(), ==, featureVec.size(),"wrong shapes");
+        if(weightIdVec.size() > 0)
+        {
+            OPENGM_CHECK_OP(shape[0], ==, featureVec[0].shape(0),"wrong feature array shapes");
+            OPENGM_CHECK_OP(shape[1], ==, featureVec[0].shape(1),"wrong feature array shapes");
+        }
+
+        f = new FUNCTION(shape, pyWeights, weightIdVec, featureVec);
+        return f;
+    }
+
+
    ////////////////////////////////////////
    // EXPLICIT FUNCTION
    ////////////////////////////////////////
@@ -325,17 +467,19 @@ void export_functiontypes(){
    typedef IndexType LabelType;
 
    // different function types
-   typedef opengm::ExplicitFunction                      <ValueType,IndexType,LabelType> PyExplicitFunction;
-   typedef opengm::PottsFunction                         <ValueType,IndexType,LabelType> PyPottsFunction;
-   typedef opengm::PottsNFunction                        <ValueType,IndexType,LabelType> PyPottsNFunction;
-   typedef opengm::PottsGFunction                        <ValueType,IndexType,LabelType> PyPottsGFunction;
-   typedef opengm::AbsoluteDifferenceFunction            <ValueType,IndexType,LabelType> PyAbsoluteDifferenceFunction;
-   typedef opengm::TruncatedAbsoluteDifferenceFunction   <ValueType,IndexType,LabelType> PyTruncatedAbsoluteDifferenceFunction;
-   typedef opengm::SquaredDifferenceFunction             <ValueType,IndexType,LabelType> PySquaredDifferenceFunction;
-   typedef opengm::TruncatedSquaredDifferenceFunction    <ValueType,IndexType,LabelType> PyTruncatedSquaredDifferenceFunction;
-   typedef opengm::SparseFunction                        <ValueType,IndexType,LabelType> PySparseFunction; 
-   typedef opengm::python::PythonFunction                <ValueType,IndexType,LabelType> PyPythonFunction; 
-    
+   typedef opengm::ExplicitFunction                                <ValueType,IndexType,LabelType> PyExplicitFunction;
+   typedef opengm::PottsFunction                                   <ValueType,IndexType,LabelType> PyPottsFunction;
+   typedef opengm::PottsNFunction                                  <ValueType,IndexType,LabelType> PyPottsNFunction;
+   typedef opengm::PottsGFunction                                  <ValueType,IndexType,LabelType> PyPottsGFunction;
+   typedef opengm::AbsoluteDifferenceFunction                      <ValueType,IndexType,LabelType> PyAbsoluteDifferenceFunction;
+   typedef opengm::TruncatedAbsoluteDifferenceFunction             <ValueType,IndexType,LabelType> PyTruncatedAbsoluteDifferenceFunction;
+   typedef opengm::SquaredDifferenceFunction                       <ValueType,IndexType,LabelType> PySquaredDifferenceFunction;
+   typedef opengm::TruncatedSquaredDifferenceFunction              <ValueType,IndexType,LabelType> PyTruncatedSquaredDifferenceFunction;
+   typedef opengm::SparseFunction                                  <ValueType,IndexType,LabelType> PySparseFunction; 
+   typedef opengm::functions::learnable::LPotts                    <ValueType,IndexType,LabelType> PyLPottsFunction;
+   typedef opengm::functions::learnable::LUnary                    <ValueType,IndexType,LabelType> PyLUnaryFunction;
+   typedef opengm::functions::learnable::LWeightedSumOfFunctions   <ValueType,IndexType,LabelType> PyLSumOfWeightedFunction;
+
    // vector exporters
    export_function_type_vector<PyExplicitFunction>("ExplicitFunctionVector");
    
@@ -359,7 +503,6 @@ void export_functiontypes(){
    //export_function_type_vector<PySquaredDifferenceFunction>("SquaredDifferenceFunctionVector");
    export_function_type_vector<PyTruncatedSquaredDifferenceFunction>("TruncatedSquaredDifferenceFunctionVector");
    export_function_type_vector<PySparseFunction>("SparseFunctionVector");
-   export_function_type_vector<PyPythonFunction>("PythonFunctionVector");
 
    typedef typename PySparseFunction::ContainerType PySparseFunctionMapType;
    //export std::map for sparsefunction
@@ -582,23 +725,55 @@ void export_functiontypes(){
    )
    ;
    
-   FUNCTION_TYPE_EXPORTER_HELPER(PyPythonFunction,                       "PythonFunction")
-   .def(init<boost::python::object,boost::python::object,const bool>(
-         (arg("function"),arg("shape"),arg("ensureGilState")=true),
-         "Examples: ::\n\n"
-         "   >>> import opengm\n"
-         "   >>> import numpy\n" 
-         "   >>> def labelSumFunction(labels):\n"
-         "   ...    s=0\n"
-         "   ...    for l in labels:\n"
-         "   ...       s+=l\n"
-         "   ...    return s\n"
-         "   >>> f=opengm.PythonFunction(function=labelSumFunction,shape=[2,2])\n"
-         "\n\n"
-      )
-   )
-   ;
 
+
+   FUNCTION_TYPE_EXPORTER_HELPER(PyLPottsFunction,"LPottsFunction")
+    .def("__init__", make_constructor(&pyfunction::lPottsConstructor<PyLPottsFunction> ,default_call_policies(),
+         (
+            boost::python::arg("weights"),
+            boost::python::arg("numberOfLabels"),
+            boost::python::arg("weightIds"),
+            boost::python::arg("features")
+         )
+      ),
+   "todo"
+   );
+
+    FUNCTION_TYPE_EXPORTER_HELPER(PyLUnaryFunction,"LUnaryFunction")
+    .def("__init__", make_constructor(&pyfunction::lUnaryConstructor<PyLUnaryFunction> ,default_call_policies(),
+         (
+            boost::python::arg("weights"),
+            boost::python::arg("numberOfLabels"),
+            boost::python::arg("weightIds"),
+            boost::python::arg("features")
+         )
+      ),
+   "todo"
+    )
+    .def("__init__", make_constructor(&pyfunction::lUnaryConstructorList<PyLUnaryFunction> ,default_call_policies(),
+         (
+            boost::python::arg("weights"),
+            boost::python::arg("numberOfLabels"),
+            boost::python::arg("weightIds"),
+            boost::python::arg("features")
+         )
+      ),
+   "todo"
+    )
+    ;
+
+    FUNCTION_TYPE_EXPORTER_HELPER(PyLSumOfWeightedFunction,"SumOfExpertsFunction")
+    .def("__init__", make_constructor(&pyfunction::weightedSumOfFunctionsConstructor<PyLSumOfWeightedFunction> ,default_call_policies(),
+         (
+            boost::python::arg("shape"),
+            boost::python::arg("weight"),
+            boost::python::arg("weightIds"),
+            boost::python::arg("features")
+         )
+      ),
+   "todo"
+    )
+    ;
 }
 
 template void export_functiontypes<opengm::python::GmValueType,opengm::python::GmIndexType>();
diff --git a/src/interfaces/python/opengm/opengmcore/pyGm.cxx b/src/interfaces/python/opengm/opengmcore/pyGm.cxx
index 0fe3cc9..1b2c6cf 100644
--- a/src/interfaces/python/opengm/opengmcore/pyGm.cxx
+++ b/src/interfaces/python/opengm/opengmcore/pyGm.cxx
@@ -682,7 +682,8 @@ namespace pygm {
          typedef opengm::SquaredDifferenceFunction             <ValueType,IndexType,LabelType> PySquaredDifferenceFunction;
          typedef opengm::TruncatedSquaredDifferenceFunction    <ValueType,IndexType,LabelType> PyTruncatedSquaredDifferenceFunction;
          typedef opengm::SparseFunction                        <ValueType,IndexType,LabelType> PySparseFunction; 
-         typedef opengm::python::PythonFunction                <ValueType,IndexType,LabelType> PyPythonFunction; 
+         typedef opengm::functions::learnable::LPotts          <ValueType,IndexType,LabelType> PyLPottsFunction;
+         typedef opengm::functions::learnable::LUnary          <ValueType,IndexType,LabelType> PyLUnaryFunction;
 
          if(fname==std::string("explicit")){
             return gm. template  reserveFunctions<PyExplicitFunction>(size);
@@ -705,8 +706,11 @@ namespace pygm {
          else if(fname==std::string("sparse")){
             return gm. template  reserveFunctions<PySparseFunction>(size);
          }
-         else if(fname==std::string("python")){
-            return gm. template  reserveFunctions<PyPythonFunction>(size);
+         else if(fname==std::string("lpotts")){
+            return gm. template  reserveFunctions<PyLPottsFunction>(size);
+         }
+         else if(fname==std::string("lunary")){
+            return gm. template  reserveFunctions<PyLUnaryFunction>(size);
          }
          else{
             throw opengm::RuntimeError(fname + std::string(" is an unknown function type name"));
@@ -1457,9 +1461,8 @@ void export_gm() {
    typedef opengm::SquaredDifferenceFunction             <ValueType,IndexType,LabelType> PySquaredDifferenceFunction;
    typedef opengm::TruncatedSquaredDifferenceFunction    <ValueType,IndexType,LabelType> PyTruncatedSquaredDifferenceFunction;
    typedef opengm::SparseFunction                        <ValueType,IndexType,LabelType> PySparseFunction; 
-   typedef opengm::python::PythonFunction                <ValueType,IndexType,LabelType> PyPythonFunction; 
-
-
+   typedef opengm::functions::learnable::LPotts          <ValueType,IndexType,LabelType> PyLPottsFunction;
+   typedef opengm::functions::learnable::LUnary          <ValueType,IndexType,LabelType> PyLUnaryFunction;
 
    typedef typename PyGm::FunctionIdentifier PyFid;
    typedef typename PyGm::FactorType PyFactor;
@@ -1837,10 +1840,9 @@ void export_gm() {
    //.def("_addFunctions_vector",&pygm::addFunctionsGenericVectorPy<PyGm,PySquaredDifferenceFunction>,return_value_policy<manage_new_object>(),args("functions"),"todo")
    .def("_addFunctions_vector",&pygm::addFunctionsGenericVectorPy<PyGm,PyTruncatedSquaredDifferenceFunction>,return_value_policy<manage_new_object>(),args("functions"),"todo")
    .def("_addFunctions_vector",&pygm::addFunctionsGenericVectorPy<PyGm,PySparseFunction>,return_value_policy<manage_new_object>(),args("functions"),"todo")
-   .def("_addFunctions_vector",&pygm::addFunctionsGenericVectorPy<PyGm,PyPythonFunction>,return_value_policy<manage_new_object>(),args("functions"),"todo")
 
-
-   .def("_addFunction",&pygm::addFunctionGenericPy<PyGm,PyPottsFunction>,args("function"))
+   .def("_addFunction",&pygm::addFunctionGenericPy<PyGm,PyLUnaryFunction>,args("function"))
+   .def("_addFunction",&pygm::addFunctionGenericPy<PyGm,PyLPottsFunction>,args("function"))
    .def("_addFunction",&pygm::addFunctionGenericPy<PyGm,PyPottsFunction>,args("function"))
    .def("_addFunction",&pygm::addFunctionGenericPy<PyGm,PyPottsNFunction>,args("function"))
    .def("_addFunction",&pygm::addFunctionGenericPy<PyGm,PyPottsGFunction>,args("function"))
@@ -1849,10 +1851,9 @@ void export_gm() {
    //.def("_addFunction",&pygm::addFunctionGenericPy<PyGm,PySquaredDifferenceFunction>,args("function"))
    .def("_addFunction",&pygm::addFunctionGenericPy<PyGm,PyTruncatedSquaredDifferenceFunction>,args("function"))
    .def("_addFunction",&pygm::addFunctionGenericPy<PyGm,PySparseFunction>,args("function"))
-   .def("_addFunction",&pygm::addFunctionGenericPy<PyGm,PyPythonFunction>,args("function"))
-	.def("_addFunction", &pygm::addFunctionNpPy<PyGm>,args("function"))
+   .def("_addFunction", &pygm::addFunctionNpPy<PyGm>,args("function"))
    .def("_addFactor", &pygm::addFactor_Any<PyGm,int>, (arg("fid"),arg("variableIndices"),arg("finalize")))
-	.def("_addFactor", &pygm::addFactor_Numpy<PyGm>, (arg("fid"),arg("variableIndices"),arg("finalize")))
+   .def("_addFactor", &pygm::addFactor_Numpy<PyGm>, (arg("fid"),arg("variableIndices"),arg("finalize")))
    .def("_addFactor", &pygm::addFactor_Vector<PyGm>, (arg("fid"),arg("variableIndices"),arg("finalize")))
    .def("_addUnaryFactors_vector_numpy", &pygm::addUnaryFactors_Vector_Numpy<PyGm>, (arg("fid"),arg("variableIndices"),arg("finalize")))
    .def("_addFactors_vector_numpy", &pygm::addFactors_Vector_Numpy<PyGm>, (arg("fid"),arg("variableIndices"),arg("finalize")))
diff --git a/src/interfaces/python/test.py b/src/interfaces/python/test.py
index b0db546..55a8256 100644
--- a/src/interfaces/python/test.py
+++ b/src/interfaces/python/test.py
@@ -1047,6 +1047,7 @@ class Test_Inference():
                                gms=[self.mcGm],
                                semiRings=self.minSum,testPythonVisitor=False)
 
+    """
     def test_lpcplex(self):
         if opengm.configuration.withCplex:
             solverClass = opengm.inference.LpCplex
@@ -1057,7 +1058,7 @@ class Test_Inference():
                                gms=[self.gridGm, self.chainGm, self.gridGm3,
                                     self.chainGm3],
                                semiRings=self.minSum,testPythonVisitor=False,testLpInterface=True)
-    """
+    
     def test_lpcplex2(self):
         if False and opengm.configuration.withCplex:
             solverClass = opengm.inference.LpCplex2

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/opengm.git



More information about the debian-science-commits mailing list