/*
 * library.h
 * This file is part of isoLasso library; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 2.1 of the License.
 *
 *  Created on: 2011-10-14
 *      Author: daniel
 */
#ifndef LIBRARY_H_
#define LIBRARY_H_
#define MAXSTRLEN 10240
const bool testRunningTime = false;

#include <vector>
#include "NewInstance.h"
#include <string>

using namespace std;

const double smalldelta = 1e-20;
extern long begintime;
extern long checkpoint;


template <class T> 
struct MATLAB_SORT_ENTRY{
	T value;
	long idx;
};

template <class T>
bool compareEntry(MATLAB_SORT_ENTRY<T> a, MATLAB_SORT_ENTRY<T> b){
	if (a.value != b.value)
		return a.value < b.value;
	else return a.idx < b.idx;
}


template <class T>
void matlabSortWithIndex(vector<T> &data, vector<MATLAB_SORT_ENTRY<T> > &newdata){
	newdata.clear();
	for (long i = 0; i < data.size(); ++i){
		MATLAB_SORT_ENTRY<T> entry;
		entry.value = data[i];
		entry.idx = i;
		newdata.push_back(entry);
	}
	sort(newdata.begin(), newdata.end(), compareEntry<T>);	
}

template <class T>
void ones(vector<vector<T> > &matrix, long nRow, long nColumn){
	matrix.clear();
	vector<T> zo;
	zo.assign(nColumn, 1);
	matrix.assign(nRow, zo);
}




template <class T>
void ones(vector<T> &matrix, long n){
	matrix.clear();
	matrix.assign(n, 1);
}

bool getBoolenValue(string &a);
template <class T>
void zeros(vector<vector<T> > &matrix, long nRow, long nColumn){
	matrix.clear();
	vector<T> zo;
	zo.assign(nColumn, 0);
	matrix.assign(nRow, zo);
}


template <class T>
void zeros(vector<T> &matrix, long n){
	matrix.clear();
	matrix.assign(n, 0);
}

vector<string> parseVaragin(string varagin);
NewInstance readoneinstance(FILE *fid, long &readcnt, int &success);
bool verifyFieldName(char *fieldname, char *expect_name, int level /*1 means error, 2 means warning*/);
void fillrcount(NewInstance &thisitem);

template <class T>
void repmat(vector<T> &original, long m, long n, vector<vector<T> >&result){
	result.clear();
	for (long i = 0; i < m; ++i){
		vector<T> sub;
		for (long j = 0; j < n; ++j) 
			for (long k = 0; k < original.size(); ++k)
				sub.push_back(original[k]);
		result.push_back(sub);
	}
}

template <class T>
void matrixSum(vector<vector<T> > &matrix, int choice, vector<T> &result){
	result.clear();
	if (choice == 1){
		for (long col = 0; col < matrix[0].size(); ++col){
			result.push_back(0);
			for (long row = 0; row < matrix.size(); ++row)
				result[col] += matrix[row][col];
		}
	}
	if (choice == 2){
		for (long row = 0; row < matrix.size(); ++row){
			result.push_back(0);
			for (long col = 0; col < matrix[row].size(); ++col)
				result[row] += matrix[row][col];
		}
	}
}

void matrixTransposeMulSelf(vector<vector<double> > &matrix, double **result);

/*
template <class T>
void matrixMul(vector<vector<T> > &leftMatrix, vector<vector<T> > &rightMatrix, QuadProgPP::Matrix<T> &result, bool reverseL){
	
	if (!reverseL) {
		result.resize(leftMatrix.size(), rightMatrix[0].size());
		for (long i = 0; i < leftMatrix.size(); ++i)
			for (long j = 0; j < rightMatrix[0].size(); ++j){
				result[i][j] = 0;
				for (long k = 0; k < leftMatrix[0].size(); ++k)
					result[i][j] = result[i][j] + leftMatrix[i][k] * rightMatrix[k][j];
			}
	}
	else {
		result.resize(leftMatrix[0].size(), rightMatrix[0].size());
		for (long i = 0; i < leftMatrix[0].size(); ++i)
			for (long j = 0; j < rightMatrix[0].size(); ++j){
				result[i][j] = 0;
				for (long k = 0; k < leftMatrix.size(); ++k)
					result[i][j] = result[i][j] + leftMatrix[k][i] * rightMatrix[k][j];
			}
	}
}
*/

void writeoneinstance(FILE* fid, NewInstance &oneins, string index, double expcutoff, long mininsrcount);



#endif /* LIBRARY_H_ */
