<commit_before>#ifndef TRWS_DECOMPOSITION_HXX_
#define TRWS_DECOMPOSITION_HXX_
#include <iostream>
#include <list>
#include <vector>
#include <utility>
#include <stdexcept>
#include <algorithm>
#include <opengm/graphicalmodel/decomposition/graphicalmodeldecomposition.hxx>
#include <opengm/inference/trws/utilities2.hxx>

#ifdef TRWS_DEBUG_OUTPUT
#include <opengm/inference/trws/output_debug_utils.hxx>
#endif

namespace opengm {
namespace trws_base{

#ifdef TRWS_DEBUG_OUTPUT
using OUT::operator <<;
#endif

template<class GM>
class Decomposition
{
public:
	typedef typename GM::IndexType IndexType;
	typedef typename GM::LabelType LabelType;
	typedef std::vector<IndexType> IndexList;
	typedef opengm::GraphicalModelDecomposition::SubVariable SubVariable;
	typedef opengm::GraphicalModelDecomposition::SubVariableListType SubVariableListType;
	Decomposition(const GM& gm,IndexType numSubModels=0)//!< numSubModels - ESTIMATED number of submodels to optimize memory allocation
	:_numberOfModels(0),_gm(gm)
	{	// Reserve memory
		_variableLists.reserve(numSubModels);
		_pwFactorLists.reserve(numSubModels);
	};
	virtual ~Decomposition()=0;

	virtual IndexType 		 getNumberOfSubModels()const{return _numberOfModels;}
	virtual const IndexList& getVariableList(IndexType subModelId)const {return _variableLists[subModelId];}
	virtual const IndexList& getFactorList(IndexType subModelId)const {return _pwFactorLists[subModelId];}

#ifdef TRWS_DEBUG_OUTPUT
	virtual void PrintTestData(std::ostream& fout);
#endif

	virtual void ComputeVariableDecomposition(std::vector<SubVariableListType>* plist)const;

	static void CheckUnaryFactors(const GM& gm);//!< checks whether all variables have corresp. unary factor with the same index and vice versa
	static void CheckDuplicateUnaryFactors(const GM& gm);
	/*static*/ void CheckForIsolatedNodes(const GM& gm);
protected:
	typedef std::pair<IndexType,IndexType> Edge;//first=factorId, second=neighborNodeId
	typedef std::list<Edge> EdgeList;
	typedef std::vector<EdgeList> NodeList;

	IndexType _numberOfModels;
	std::vector<IndexList> _variableLists;
	std::vector<IndexList> _pwFactorLists;
	const GM& _gm;

	IndexType _addSubModel();
	void _addSubFactor(const IndexType& factorId);
	void _addSubVariable(const IndexType& variableId);
	static void _CreateNodeList(const GM& gm,NodeList* pnodeList);
};

/*
 * So far oriented to 2-nd order factors only!
 */
template<class GM>
class MonotoneChainsDecomposition : public Decomposition<GM>
{
public:
	typedef Decomposition<GM> parent;
	typedef typename parent::IndexType IndexType;
	typedef typename parent::LabelType LabelType;
	typedef typename parent::IndexList IndexList;
	typedef typename parent::SubVariable SubVariable;
	typedef typename parent::SubVariableListType SubVariableListType;

	MonotoneChainsDecomposition(const GM& gm,IndexType numSubModels=0);//!< numSubModels - ESTIMATED number of submodels to optimize memory allocation
protected:
	void _GetMaximalMonotoneSequence(typename parent::NodeList* pnodesList,IndexType start);
};

template<class GM>
class GridDecomposition : public Decomposition<GM>
{
public:
	typedef Decomposition<GM> parent;
	typedef typename parent::IndexType IndexType;
	typedef typename parent::LabelType LabelType;
	typedef typename parent::IndexList IndexList;
	typedef typename parent::SubVariable SubVariable;
	typedef typename parent::SubVariableListType SubVariableListType;

	GridDecomposition(const GM& gm,IndexType numSubModels=0);//!< numSubModels - ESTIMATED number of submodels to optimize memory allocation
	IndexType xsize()const{return _xsize;}
	IndexType ysize()const{return _ysize;}
private:
	IndexType _xsize, _ysize;
protected:
	void _computeGridSizes();
	void _CheckGridModel();
	void _initDecompositionLists();

	IndexType _xysize()const{return _xsize*_ysize;}
	IndexType _pwrowsize()const{return 2*_xsize-1;}
	IndexType _pwIndexRow(IndexType x,IndexType y)const;//!> returns an index of a row pairwise factor places to the right to var (x,y)
	IndexType _pwIndexCol(IndexType x,IndexType y)const;//!> returns an index of a column pairwise factor places to the down to var (x,y)
	IndexType _varIndex(IndexType x,IndexType y)const{return x+_xsize*y;}
	void _getRow(IndexType y,IndexList* plist)const;//!> returns indexes of variables in the row <y>
	void _getCol(IndexType x,IndexList* plist)const;//!> returns indexes of variables in the column <y>
	void _getPWRow(IndexType y, IndexList* plist)const;//!> return indexes of pairwise factors in the row <y>
	void _getPWCol(IndexType x,IndexList* plist)const;//!> return indexes of pairwise factors in the column <x>
};

template<class GM>
class EdgeDecomposition : public Decomposition<GM>
{
public:
	typedef Decomposition<GM> parent;
	typedef typename parent::IndexType IndexType;
	typedef typename parent::LabelType LabelType;
	typedef typename parent::IndexList IndexList;
	typedef typename parent::SubVariable SubVariable;
	typedef typename parent::SubVariableListType SubVariableListType;

	EdgeDecomposition(const GM& gm):parent(gm)
	 {
		parent::CheckUnaryFactors(gm);
		parent::CheckDuplicateUnaryFactors(gm);
		parent::_numberOfModels=gm.numberOfFactors()-gm.numberOfVariables();//!> this should be a number of pairwise factors
		//bild variable and factor lists
		parent::_variableLists.resize(parent::_numberOfModels,IndexList(2,(IndexType)0));
		parent::_pwFactorLists.resize(parent::_numberOfModels,IndexList(1,(IndexType)0));

		IndexType pwFid=0;
		for (IndexType fId=0;fId<gm.numberOfFactors();++fId)
		{
			if (gm[fId].numberOfVariables()==1) continue;
			if ((gm[fId].numberOfVariables()>2) || (gm[fId].numberOfVariables()==0))
				std::runtime_error("EdgeDecomposition<GM>::EdgeDecomposition(): Only factors of order 1 or 2 are supported!");

			//factor of order 2:
			parent::_variableLists[pwFid][0]=gm[fId].variableIndex(0);
			parent::_variableLists[pwFid][1]=gm[fId].variableIndex(1);
			parent::_pwFactorLists[pwFid][0]=fId;
			++pwFid;
		}
	}
};


#ifdef TRWS_DEBUG_OUTPUT
template <class SubFactor><commit_msg>edge decomposition: removed unary factor check in for TRWSi-based algorithms<commit_after>#ifndef TRWS_DECOMPOSITION_HXX_
#define TRWS_DECOMPOSITION_HXX_
#include <iostream>
#include <list>
#include <vector>
#include <utility>
#include <stdexcept>
#include <algorithm>
#include <opengm/graphicalmodel/decomposition/graphicalmodeldecomposition.hxx>
#include <opengm/inference/trws/utilities2.hxx>

#ifdef TRWS_DEBUG_OUTPUT
#include <opengm/inference/trws/output_debug_utils.hxx>
#endif

namespace opengm {
namespace trws_base{

#ifdef TRWS_DEBUG_OUTPUT
using OUT::operator <<;
#endif

template<class GM>
class Decomposition
{
public:
	typedef typename GM::IndexType IndexType;
	typedef typename GM::LabelType LabelType;
	typedef std::vector<IndexType> IndexList;
	typedef opengm::GraphicalModelDecomposition::SubVariable SubVariable;
	typedef opengm::GraphicalModelDecomposition::SubVariableListType SubVariableListType;
	Decomposition(const GM& gm,IndexType numSubModels=0)//!< numSubModels - ESTIMATED number of submodels to optimize memory allocation
	:_numberOfModels(0),_gm(gm)
	{	// Reserve memory
		_variableLists.reserve(numSubModels);
		_pwFactorLists.reserve(numSubModels);
	};
	virtual ~Decomposition()=0;

	virtual IndexType 		 getNumberOfSubModels()const{return _numberOfModels;}
	virtual const IndexList& getVariableList(IndexType subModelId)const {return _variableLists[subModelId];}
	virtual const IndexList& getFactorList(IndexType subModelId)const {return _pwFactorLists[subModelId];}

#ifdef TRWS_DEBUG_OUTPUT
	virtual void PrintTestData(std::ostream& fout);
#endif

	virtual void ComputeVariableDecomposition(std::vector<SubVariableListType>* plist)const;

	static void CheckUnaryFactors(const GM& gm);//!< checks whether all variables have corresp. unary factor with the same index and vice versa
	static void CheckDuplicateUnaryFactors(const GM& gm);
	/*static*/ void CheckForIsolatedNodes(const GM& gm);
protected:
	typedef std::pair<IndexType,IndexType> Edge;//first=factorId, second=neighborNodeId
	typedef std::list<Edge> EdgeList;
	typedef std::vector<EdgeList> NodeList;

	IndexType _numberOfModels;
	std::vector<IndexList> _variableLists;
	std::vector<IndexList> _pwFactorLists;
	const GM& _gm;

	IndexType _addSubModel();
	void _addSubFactor(const IndexType& factorId);
	void _addSubVariable(const IndexType& variableId);
	static void _CreateNodeList(const GM& gm,NodeList* pnodeList);
};

/*
 * So far oriented to 2-nd order factors only!
 */
template<class GM>
class MonotoneChainsDecomposition : public Decomposition<GM>
{
public:
	typedef Decomposition<GM> parent;
	typedef typename parent::IndexType IndexType;
	typedef typename parent::LabelType LabelType;
	typedef typename parent::IndexList IndexList;
	typedef typename parent::SubVariable SubVariable;
	typedef typename parent::SubVariableListType SubVariableListType;

	MonotoneChainsDecomposition(const GM& gm,IndexType numSubModels=0);//!< numSubModels - ESTIMATED number of submodels to optimize memory allocation
protected:
	void _GetMaximalMonotoneSequence(typename parent::NodeList* pnodesList,IndexType start);
};

template<class GM>
class GridDecomposition : public Decomposition<GM>
{
public:
	typedef Decomposition<GM> parent;
	typedef typename parent::IndexType IndexType;
	typedef typename parent::LabelType LabelType;
	typedef typename parent::IndexList IndexList;
	typedef typename parent::SubVariable SubVariable;
	typedef typename parent::SubVariableListType SubVariableListType;

	GridDecomposition(const GM& gm,IndexType numSubModels=0);//!< numSubModels - ESTIMATED number of submodels to optimize memory allocation
	IndexType xsize()const{return _xsize;}
	IndexType ysize()const{return _ysize;}
private:
	IndexType _xsize, _ysize;
protected:
	void _computeGridSizes();
	void _CheckGridModel();
	void _initDecompositionLists();

	IndexType _xysize()const{return _xsize*_ysize;}
	IndexType _pwrowsize()const{return 2*_xsize-1;}
	IndexType _pwIndexRow(IndexType x,IndexType y)const;//!> returns an index of a row pairwise factor places to the right to var (x,y)
	IndexType _pwIndexCol(IndexType x,IndexType y)const;//!> returns an index of a column pairwise factor places to the down to var (x,y)
	IndexType _varIndex(IndexType x,IndexType y)const{return x+_xsize*y;}
	void _getRow(IndexType y,IndexList* plist)const;//!> returns indexes of variables in the row <y>
	void _getCol(IndexType x,IndexList* plist)const;//!> returns indexes of variables in the column <y>
	void _getPWRow(IndexType y, IndexList* plist)const;//!> return indexes of pairwise factors in the row <y>
	void _getPWCol(IndexType x,IndexList* plist)const;//!> return indexes of pairwise factors in the column <x>
};

template<class GM>
class EdgeDecomposition : public Decomposition<GM>
{
public:
	typedef Decomposition<GM> parent;
	typedef typename parent::IndexType IndexType;
	typedef typename parent::LabelType LabelType;
	typedef typename parent::IndexList IndexList;
	typedef typename parent::SubVariable SubVariable;
	typedef typename parent::SubVariableListType SubVariableListType;

	EdgeDecomposition(const GM& gm):parent(gm)
	 {
		//parent::CheckUnaryFactors(gm);
		parent::CheckDuplicateUnaryFactors(gm);
		parent::_numberOfModels=gm.numberOfFactors()-gm.numberOfVariables();//!> this should be a number of pairwise factors
		//bild variable and factor lists
		parent::_variableLists.resize(parent::_numberOfModels,IndexList(2,(IndexType)0));
		parent::_pwFactorLists.resize(parent::_numberOfModels,IndexList(1,(IndexType)0));

		IndexType pwFid=0;
		for (IndexType fId=0;fId<gm.numberOfFactors();++fId)
		{
			if (gm[fId].numberOfVariables()==1) continue;
			if ((gm[fId].numberOfVariables()>2) || (gm[fId].numberOfVariables()==0))
				std::runtime_error("EdgeDecomposition<GM>::EdgeDecomposition(): Only factors of order 1 or 2 are supported!");

			//factor of order 2:
			parent::_variableLists[pwFid][0]=gm[fId].variableIndex(0);
			parent::_variableLists[pwFid][1]=gm[fId].variableIndex(1);
			parent::_pwFactorLists[pwFid][0]=fId;
			++pwFid;
		}
	}
};


#ifdef TRWS_DEBUG_OUTPUT
template <class SubFactor>
{'fraction_non_alphanumeric': 0.10266128367800939, 'fraction_numerical': 0.004284419543544533, 'mean_word_length': 7.494051784464661, 'pattern_counts': {'":': 0, '<': 81, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3950114', 'n_tokens_mistral': 4120, 'n_tokens_neox': 3745, 'n_words': 954}