//============================================================================
// Name        : GetFreqAndRare.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <string>
#include <vector>

#include <matrices/SuperMatrix.h>
#include <matrices/io/SuperMatrixWriter.h>
#include <matrices/io/SuperMatrixReader.h>

using namespace std;

typedef std::pair<size_t, size_t> PairSizeT;

size_t getFreq(Matrices::Feature const& pFeature){
	return pFeature.GetGlobalTermFrequency();
}


int main() {

	std::string dir = "/home/michalw/Dokumenty/macierze/";
	std::string name = "BNC_entropy1p";

	Matrices::SuperMatrixPtr mtx = Matrices::IO::LoadSuperMatrix(dir, name, false, true);
	Matrices::FeatureVector const& rowFeatures = *mtx->GetRowFeatures();

	//ranks
	std::vector<size_t> sorted(rowFeatures.size());
	for(size_t i=0; i<sorted.size(); ++i)
		sorted[i] = getFreq(rowFeatures[i]);
	std::sort(sorted.begin(), sorted.end(), std::greater<int>());

	//margins
	PairSizeT highMargins(sorted[999], sorted[0]);
	PairSizeT lowMargins(sorted[3999], sorted[3000]);
	std::cout << lowMargins.first << " " << lowMargins.second << " | "
		<< highMargins.first << " " << highMargins.second << std::endl;


	Matrices::FeatureVectorPtr newCols(new Matrices::FeatureVector(*mtx->GetColumnFeatures()));
	Matrices::FeatureVectorPtr newRows(new Matrices::FeatureVector(2000));
	{
		size_t counter = 0;
		for(size_t i=0; i<rowFeatures.size(); ++i){
			size_t fr = getFreq(rowFeatures[i]);
			if(fr >= highMargins.first && fr <= highMargins.second)
				(*newRows)[counter++] = rowFeatures[i];
			if(counter == 1000)
				break;
		}
		for(size_t i=0; i<rowFeatures.size(); ++i){
			size_t fr = getFreq(rowFeatures[i]);
			if (fr >= lowMargins.first && fr <= lowMargins.second)
				(*newRows)[counter++] = rowFeatures[i];
			if(counter == 2000)
				break;
		}
	}

	std::cout << "creating CRS" << std::endl;

	Matrices::CRSMatrixPtr crs(new Matrices::CRSMatrix("BNC_mini_crs", 2000, newCols->size()));
	for(size_t i=0; i<newRows->size(); ++i){
		size_t ridx = mtx->GetRowIndex((*newRows)[i].GetLabel());
		crs->SetCompressedRow(i, mtx->GetCRS()->GetCompressedRow(ridx));
	}

	std::cout << "creating MTX" << std::endl;

	Matrices::SuperMatrixPtr lowBNC(new Matrices::SuperMatrix(
		"BNC_entropy1p_mini",
		Matrices::CCSMatrixPtr(), crs,
		newRows, newCols,
		mtx->GetTokenCount(), mtx->GetCorpusInfo()));

	lowBNC->SyncCRSToCCS();

	std::cout << "writing" << std::endl;

	Matrices::IO::WriteSuperMatrix(lowBNC, dir);

	std::cout << "done" << std::endl;

	return 0;
}
