/** 
* @file FPCRandomForestTransfer.h
* @brief implementation of random set forests with a priori knowledge
* @author Erik Rodner
* @date 04/24/2008

*/
#ifndef FPCRandomForestTransferINCLUDE
#define FPCRandomForestTransferINCLUDE

#include "core/vector/VectorT.h"
#include "core/vector/MatrixT.h"

#include "core/basics/Config.h"
#include "vislearning/cbaselib/ClassNames.h"
#include "vislearning/classifier/fpclassifier/randomforest/DTEstimateAPriori.h"

#include "FPCRandomForests.h"


namespace OBJREC {

/** implementation of random set forests */
class FPCRandomForestTransfer : public FPCRandomForests
{
    protected:
	/** set of class numbers which are substituted */
	std::set<int> substituteClasses;

	/** set of class numbers used to estimated  */
	std::set<int> muClasses;

	/** set of new class numbers */
	std::set<int> newClass;
    
	/** whether to reduce to training set randomly */
	bool reduce_training_set;

	/** use only a fraction of original training data */
	double training_ratio;

	/** use only a absolute number of training samples */
	int training_absolute;

	/** extend map tree */
	bool extend_map_tree;

	/** partial ml estimation of lower levels of the tree */
	bool partial_ml_estimation;
	int partial_ml_estimation_depth;
	
	/** extend only leafs with a suitable entropy beyond this threshold */
	double entropy_rejection_threshold;
	bool extend_only_critical_leafs;

	/** variance of gaussian prior 
	    sigmaq \rightarrow 0 : a posteriori = prior 
	    sigmaq \rightarrow \infty : a posteriori = likelihood 
	    (non-informative prior) */
	double sigmaq;

	/** read a-priori decision tree structure from file */
	bool read_cached_prior_structure;

	/** file to store/read a-priori decision tree structure */
	// refactor-nice.pl: check this substitution
	// old: string cached_prior_structure;
	std::string cached_prior_structure;

	/** whether to learn tree structure including the new class examples */
	bool learn_ert_with_newclass;

	/** extend map tree */
	void extendMapTree ( FeaturePool & fp,
			     DecisionTree & tree, 
			     Examples & examples_transfer, 
			     Examples & examples_new, 
			     int newClassNo,
			     const std::set<int> & muClasses );

	/** ML estimation */
	void mlEstimate ( DecisionNode *node,
			  Examples & examples_new,
	        	  int newClassNo );

	/** perform ML estimation at inner nodes of a fixed depth */
	void partialMLEstimate ( DecisionTree & tree,
				  Examples & examples_new,
				  int newClassNo,
				  int mldepth );

	DecisionTreeBuilder *builder_extend;

	DTEstimateAPriori dte;

    public:
  
	/** simple constructor */
	FPCRandomForestTransfer( 
	    const NICE::Config *conf, 	    
	    const ClassNames *classNames, 
	    // refactor-nice.pl: check this substitution
	    // old: string section = "RandomForest"
	    std::string section = "RandomForest"
	);
      
	/** simple destructor */
	virtual ~FPCRandomForestTransfer();

	void train ( FeaturePool & fp,
		     Examples & examples );


	FeaturePoolClassifier *clone () const;
};


} // namespace

#endif