void testPotts() { MRFEnergy<TypePotts>* mrf; MRFEnergy<TypePotts>::NodeId* nodes; MRFEnergy<TypePotts>::Options options; TypePotts::REAL energy, lowerBound; const int nodeNum = 2; // number of nodes const int K = 3; // number of labels TypePotts::REAL D[K]; int x, y; mrf = new MRFEnergy<TypePotts>(TypePotts::GlobalSize(K)); nodes = new MRFEnergy<TypePotts>::NodeId[nodeNum]; // construct energy D[0] = 0; D[1] = 1; D[2] = 2; nodes[0] = mrf->AddNode(TypePotts::LocalSize(), TypePotts::NodeData(D)); D[0] = 3; D[1] = 4; D[2] = 5; nodes[1] = mrf->AddNode(TypePotts::LocalSize(), TypePotts::NodeData(D)); mrf->AddEdge(nodes[0], nodes[1], TypePotts::EdgeData(6)); // Function below is optional - it may help if, for example, nodes are added in a random order // mrf->SetAutomaticOrdering(); /////////////////////// TRW-S algorithm ////////////////////// options.m_iterMax = 30; // maximum number of iterations mrf->Minimize_TRW_S(options, lowerBound, energy); // read solution x = mrf->GetSolution(nodes[0]); y = mrf->GetSolution(nodes[1]); printf("Solution: %d %d\n", x, y); //////////////////////// BP algorithm //////////////////////// mrf->ZeroMessages(); // in general not necessary - it may be faster to start // with messages computed in previous iterations. // NOTE: in most cases, immediately after creating the energy // all messages are zero. EXCEPTION: typeBinary and typeBinaryFast. // So calling ZeroMessages for these types will NOT transform // the energy to the original state. options.m_iterMax = 30; // maximum number of iterations mrf->Minimize_BP(options, energy); // read solution x = mrf->GetSolution(nodes[0]); y = mrf->GetSolution(nodes[1]); printf("Solution: %d %d\n", x, y); // done delete nodes; delete mrf; }
py::object add_grid_nodes(MRFEnergy<T>& mrfenergy, const PyArrayObject* unaryterms, int axis=0) { typedef typename T::REAL REAL; typedef typename T::LocalSize LocalSize; typedef typename T::NodeData NodeData; int ndim = PyArray_NDIM(unaryterms); npy_intp* shape = PyArray_DIMS(unaryterms); if(-axis > ndim || axis >= ndim) throw std::runtime_error("axis is out of bounds"); if(axis < 0) axis = ndim + axis; int num_labels = shape[axis]; npy_intp* nodeids_shape = new npy_intp[ndim-1]; // Copy the shape except for the axis given. std::copy(shape, shape+axis, nodeids_shape); std::copy(shape+axis+1, shape+ndim, nodeids_shape+axis); PyArrayObject* nodeids = reinterpret_cast<PyArrayObject*>( PyArray_SimpleNew(ndim-1, nodeids_shape, NPY_ULONG)); std::vector<REAL> d(num_labels); pyarray_index unaryterms_idx(ndim); for(pyarray_iterator it(nodeids); !it.atEnd(); ++it) { const pyarray_index& nodeids_idx = it.getIndex(); // Extract unary terms for this node. std::copy(nodeids_idx.idx, nodeids_idx.idx+axis, &unaryterms_idx[0]); std::copy(nodeids_idx.idx+axis, nodeids_idx.idx+nodeids_idx.ndim, &unaryterms_idx[axis+1]); // std::copy(nodeids_idx.idx, nodeids_idx.idx+nodeids_idx.ndim, &unaryterms_idx[1]); for(int j=0; j<num_labels; ++j) { unaryterms_idx[axis] = j; d[j] = PyArray_SafeGet<REAL>(unaryterms, unaryterms_idx); } // Create the node. typename MRFEnergy<T>::NodeId id = mrfenergy.AddNode(LocalSize(num_labels), NodeData(d)); // Store the node. PyArray_SafeSet<numeric_pointer>(nodeids, nodeids_idx, reinterpret_cast<numeric_pointer>(id)); } delete [] nodeids_shape; return py::object(nodeids); }
///----------------------------------------------------------------------------- //extern __declspec(dllexport) double trw_potts( int nnodes, // number of nodes int nlabels, // number of labels double const* unary, // unary potentials int npairs, // number of pairs int const *pairs, // pairs (ith pair = pairs[2*i], pairs[2*i+1]) double const *wpairs, // binary potentials int* solution, // return array int max_iter, // max number of iterations bool randomize_order, // bool use_bp, // belief propagation bool verbose // print debug info ) { MRFEnergy<TypePotts>* mrf; MRFEnergy<TypePotts>::NodeId* nodes; MRFEnergy<TypePotts>::Options options; TypePotts::REAL energy, lowerBound; mrf = new MRFEnergy<TypePotts>(TypePotts::GlobalSize(nlabels)); nodes = new MRFEnergy<TypePotts>::NodeId[nnodes]; // construct energy TypePotts::REAL * U = new TypePotts::REAL[nlabels]; for (int i=0; i < nnodes; i++) { for (int l=0; l < nlabels; l++) { U[l] = unary[i*nlabels + l]; } nodes[i] = mrf->AddNode( TypePotts::LocalSize(), TypePotts::NodeData(U) ); } delete[] U; /// pairs for (int i = 0; i < npairs; ++i) { mrf->AddEdge( nodes[pairs[i*2]], nodes[pairs[i*2+1]], TypePotts::EdgeData(wpairs[i]) ); } // TypeGeneral::REAL * E = new TypeGeneral::REAL[nlabels*nlabels]; // for (int i=0; i < npairs; i++) // { // for (int l1 = 0; l1 < nlabels; l1++) // for (int l2 = 0; l2 < nlabels; l2++) // {{ // E[l1 + l2*nlabels] = wpairs[i*nlabels*nlabels + l1 + l2*nlabels]; // }} // mrf->AddEdge( // nodes[pairs[i*2]], // nodes[pairs[i*2+1]], // TypeGeneral::EdgeData(TypeGeneral::GENERAL, E) // ); // } // Function below is optional - it may help if, for example, nodes are added in a random order if (randomize_order) mrf->SetAutomaticOrdering(); /////////////////////// TRW-S algorithm ////////////////////// if (verbose) options.m_printMinIter = 0; else options.m_printMinIter = max_iter+1; options.m_iterMax = max_iter; // maximum number of iterations if (use_bp) mrf->Minimize_BP(options, energy); else mrf->Minimize_TRW_S(options, lowerBound, energy); // read solution for (int i = 0; i<nnodes; i++) { solution[i] = mrf->GetSolution(nodes[i]); } delete mrf; delete[] nodes; return energy; }