#include <iostream>
#include <fstream>

#include <armadillo>
#include "matReader.h"
#include "Boost.h"
#include "matWriter.h"

using namespace arma;
using namespace std;

fstream logfile;
fstream resultfile;
fstream qfile,
	wfile;

my_param para;
matWriter	writer("result/data.mat");
int	 main(int args, char*argv[])
{
//test
/*	qfile.open("q",std::fstream::out);
	wfile.open("w",std::fstream::out);*/

	para.read("config.xml");
	logfile.open(para.log.c_str(),std::fstream::out);
	if(logfile==false){
		cerr<<"fail to open logfile!\n";exit(-1);
	}
	resultfile.open(para.result.c_str(),std::fstream::out);
	if(resultfile==false){
		cerr<<"fail to open resultfile!\n";exit(-1);
	}
	matReader	reader(para.data);
	Boost		ensemble("softmax");
	mat			data;
	mat			labels;
	mat			pl_labels;
	vector<mat>	tr_idx;
	vector<mat>	te_idx;
	size_t		T = para.T;
	
	reader.read(data, "data"); 
	reader.read(labels,"target");
	reader.read(pl_labels, "partial_target");

	reader.read(tr_idx, "tr_idx"); reader.read(te_idx,"te_idx");
	size_t		n_fold	= tr_idx.size();
	size_t		n_lbl	= labels.n_cols;
	size_t		n_ft	= data.n_cols;
	vector<Boost> boosts(n_fold);
	vec			rate(n_fold);
	vec			transductive(n_fold);
	for (size_t fold = 0; fold < n_fold; fold++)
	{
		size_t	ntr_ins = tr_idx[fold].n_cols;
		size_t	nte_ins = te_idx[fold].n_cols;

		mat		train_data(ntr_ins,n_ft);
		mat		train_pl_labels(ntr_ins,n_lbl);
		mat		train_label(ntr_ins,n_lbl);
		mat		test_data(nte_ins,n_ft);
		mat		test_label(nte_ins,n_lbl);
				
		for (size_t i = 0; i < tr_idx[fold].n_cols; ++i){
			size_t	id = tr_idx[fold](0,i)-1;
			train_data.row(i) = data.row(id);
			train_pl_labels.row(i) = pl_labels.row(id);
			train_label.row(i) = labels.row(id);
		}
		for (size_t i = 0; i < te_idx[fold].n_cols; ++i){
			size_t	id = te_idx[fold](0,i)-1;
			test_data.row(i) = data.row(id);
			test_label.row(i) = labels.row(id);
		}
		//train
		boosts[fold].boosting(train_data, train_pl_labels,train_label,T);

		//predict
		 pair<uvec,double> result = boosts[fold].predict(test_data, test_label,true);
		//transductive
		 double result_trans = boosts[fold].transductive(train_data, train_pl_labels,train_label);
		 printf("####################################################"
			 "\n%dfold correct rate:%f\n",fold,result.second);
		 rate[fold] = result.second;
		 transductive[fold] = result_trans;
	}
	cout << "ÕýÈ·ÂÊ:\n" << rate;
	//record result
	resultfile.close();
	logfile.close();
	return 0;
}

void exc(){
}
