<commit_before>#include <iostream>
#include <algorithm>
#include <time.h>
#include "../Eigen/Dense"

using namespace Eigen;

// My own implementation of LU decomposition with partial pivoting
bool LU(const MatrixXf &a, MatrixXf &l, MatrixXf &u, MatrixXf &p) {
	// 'a' should be a square matrix, so does 'l', 'u', and 'p'
	assert(a.rows() == a.cols());
	int size = a.rows();

	// no pivoting upper triangular matrix 'nu' elimination begin with 'a'
	MatrixXf nu = a;

	// row_indexes has row order of 'nu'
	ArrayXi row_indexes(size);
	for (int r = 0; r < size; r++) {
		row_indexes(r) = r;
	}

	// lower triangular matrix
	l = MatrixXf::Identity(size, size);

	// 'i' is diagonal index of the matrix
	for (int i = 0; i < size; i++) {
		// find real pivot index
		int pivot_index = row_indexes[i];
		float maximum = abs(nu(pivot_index, i));
		for (int r = i + 1; r < size; r++) {
			float value = abs(nu(row_indexes[r], i));

			if (value > maximum) {
				pivot_index = row_indexes[r];
				maximum = value;
			}
		}

		// if row exchange is required
		if (pivot_index > i) {
			// swap pivot index with current row index
			std::swap(row_indexes[i], row_indexes[pivot_index]);

			// swap rows in L
			for (int c = 0; c < i; c++) {
				std::swap(l(i, c), l(pivot_index, c));
			}
		}

		// get pivot value
		float pivot = nu(row_indexes[i], i);
		if (pivot == 0.0f) {
			// abandon decomposition if pivot does not exist
			return false;
		}

		for (int r = i + 1; r < size; r++) {
			// scaler for subtract a row
			float scaler = nu(row_indexes[r], i) / pivot;

			// subtract a row from scaled pivot row
			for (int c = i; c < size; c++) {
				nu(row_indexes[r], c) -= scaler * nu(row_indexes[i], c);
			}

			// scaler matches with L component
			l(r, i) = scaler;
		}
	}

	// generate permutation matrix P with 'row_indexes'
	p = MatrixXf::Zero(size, size);
	for (int r = 0; r < size; r++) {
		p.row(r)[row_indexes[r]] = 1.0f;
	}

	// permutate matrix U using P
#if 0
	u = p * u;
#else
	for (int r = 0; r < size; r++) {
		u.row(r) = nu.row(row_indexes[r]);
	}
#endif

	return true;
}

// Example code for my own LU decomposition
void TestLU() {
	const int DIMENSION = 5;

	MatrixXf a(DIMENSION, DIMENSION);
	a << MatrixXf::Random(DIMENSION, DIMENSION);

	VectorXf b(DIMENSION);
	b << VectorXf::Random(DIMENSION);

	MatrixXf l(DIMENSION, DIMENSION);
	MatrixXf u(DIMENSION, DIMENSION);
	MatrixXf p(DIMENSION, DIMENSION);
	bool invertible = ::LU(a, l, u, p);

	if (!invertible) {
		std::cout << "ERROR: A is not invertible !!\n";
		return;
	}

	std::cout << "A =\n";
	std::cout << a << "\n\n";

	std::cout << "b =\n";
	std::cout << b << "\n\n";

	std::cout << "A * b =\n";
	std::cout << a * b << "\n\n";

	// PA = LU
	// A = P^T LU
	std::cout << "P^T * L * U * b =\n";
	std::cout << p.transpose() * l * u * b << "\n\n";;
}

int main() {
	srand((unsigned int)time(0));

	TestLU();

	getchar();

	return 0;
}
<commit_msg>Minor fix<commit_after>#include <iostream>
#include <algorithm>
#include <time.h>
#include "../Eigen/Dense"

using namespace Eigen;

// My own implementation of LU decomposition with partial pivoting
bool LU(const MatrixXf &a, MatrixXf &l, MatrixXf &u, MatrixXf &p) {
	// 'a' should be a square matrix, so does 'l', 'u', and 'p'
	assert(a.rows() == a.cols());
	int size = a.rows();

	// no pivoting upper triangular matrix 'nu' elimination begin with 'a'
	MatrixXf nu = a;

	// row_indexes has row order of 'nu'
	ArrayXi row_indexes(size);
	for (int r = 0; r < size; r++) {
		row_indexes(r) = r;
	}

	// lower triangular matrix
	l = MatrixXf::Identity(size, size);

	// 'i' is diagonal index of the matrix
	for (int i = 0; i < size; i++) {
		// find real pivot index
		int pivot_index = row_indexes[i];
		float maximum = abs(nu(pivot_index, i));
		for (int r = i + 1; r < size; r++) {
			float value = abs(nu(row_indexes[r], i));

			if (value > maximum) {
				pivot_index = row_indexes[r];
				maximum = value;
			}
		}

		// if row exchange is required
		if (pivot_index > i) {
			// swap pivot index with current row index
			std::swap(row_indexes[i], row_indexes[pivot_index]);

			// swap rows in L
			for (int c = 0; c < i; c++) {
				std::swap(l(i, c), l(pivot_index, c));
			}
		}

		// get pivot value
		float pivot = nu(row_indexes[i], i);
		if (pivot == 0.0f) {
			// abandon decomposition if pivot does not exist
			return false;
		}

		for (int r = i + 1; r < size; r++) {
			// scaler for subtract a row
			float scaler = nu(row_indexes[r], i) / pivot;

			// subtract a row from scaled pivot row
			for (int c = i; c < size; c++) {
				nu(row_indexes[r], c) -= scaler * nu(row_indexes[i], c);
			}

			// scaler matches with L component
			l(r, i) = scaler;
		}
	}

	// generate permutation matrix P with 'row_indexes'
	p = MatrixXf::Zero(size, size);
	for (int r = 0; r < size; r++) {
		p.row(r)[row_indexes[r]] = 1.0f;
	}

	// permutate matrix U using P
#if 0
	u = p * nu;
#else
	for (int r = 0; r < size; r++) {
		u.row(r) = nu.row(row_indexes[r]);
	}
#endif

	return true;
}

// Example code for my own LU decomposition
void TestLU() {
	const int DIMENSION = 5;

	MatrixXf a(DIMENSION, DIMENSION);
	a << MatrixXf::Random(DIMENSION, DIMENSION);

	VectorXf b(DIMENSION);
	b << VectorXf::Random(DIMENSION);

	MatrixXf l(DIMENSION, DIMENSION);
	MatrixXf u(DIMENSION, DIMENSION);
	MatrixXf p(DIMENSION, DIMENSION);
	bool invertible = ::LU(a, l, u, p);

	if (!invertible) {
		std::cout << "ERROR: A is not invertible !!\n";
		return;
	}

	std::cout << "A =\n";
	std::cout << a << "\n\n";

	std::cout << "b =\n";
	std::cout << b << "\n\n";

	std::cout << "A * b =\n";
	std::cout << a * b << "\n\n";

	// PA = LU
	// A = P^T LU
	std::cout << "P^T * L * U * b =\n";
	std::cout << p.transpose() * l * u * b << "\n\n";;
}

int main() {
	srand((unsigned int)time(0));

	TestLU();

	getchar();

	return 0;
}
<|endoftext|>


<commit_before>/*	library based on jeelabs RTClib [original library at https://github.com/jcw/rtclib ] altered to support Microchip MCP7940M RTC, used in Arduino
	based embedded environments. To use this library, add #include <MCP7940.h> to the top of your program.*/

#include <Wire.h>
#ifndef ENERGIA
#include <avr/pgmspace.h>
#else
#define pgm_read_word(data) *data
#define pgm_read_byte(data) *data
#define PROGMEM
#endif
#include <MCP7940.h>
#include <Arduino.h>

#define RTC_ADD           0x6F
#define RTC_CONREG        0x07
#define RTC_ALARM         0x0D
#define SECONDS_PER_DAY   86400L

/*	THIS SECTION COPIED DIRECTLY FROM RTClib [ https://github.com/jcw/rtclib ]
	USE PER http://opensource.org/licenses/mit-license.php */

static const uint8_t daysInMonth [] PROGMEM = {
  31,28,31,30,31,30,31,31,30,31,30,31
};

static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) {
  if(y >= 2000)
    y -= 2000;
  uint16_t days = d;
  for(uint8_t i = 1; i<m; ++i)
    days += pgm_read_byte(daysInMonth + i - 1);
  if(m>2 && y%4 ==0)
    ++days;
  return days + 365 * y + (y + 3) / 4 - 1;
}

static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) {
  return ((days * 24L + h) * 60 + m) * 60 + s;
}

DateTime::DateTime(long t) {
  ss=t%60;
  t/=60;
  mm=t%60;
  t/=60;
  hh=t%24;
  uint16_t days = t/24;
  uint8_t leap;
  for (yOff = 0; ;++yOff) {
    leap = yOff%4==0;
    if(days<365+leap)
      break;
    days -= 365 + leap;
  }
  for(m=1; ;++m){
    uint8_t daysPerMonth=pgm_read_byte(daysInMonth + m - 1);
    if(leap && m == 2)
      ++daysPerMonth;
    if(days<daysPerMonth)
      break;
    days -= daysPerMonth;
  }
  d=days+1;
}

DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) {
  if(year >= 2000)
    year -= 2000;
  yOff = year;
  m = month;
  d = day;
  hh = hour;
  mm = min;
  ss = sec;
}

static uint8_t conv2d(const char* p) {
  uint8_t v=0;
  if('0' <= *p && *p <= '9')
    v = *p - '0';
  return 10 * v + *++p - '0';
}

DateTime::DateTime (const char* date, const char* time) {
  yOff = conv2d(date + 9);
  switch(date[0]) {
    case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break;
    case 'F': m = 2; break;
    case 'A': m = date[2] == 'r' ? 4 : 8; break;
    case 'M': m = date[2] == 'r' ? 3 : 5; break;
    case 'S': m = 9; break;
    case 'O': m = 10; break;
    case 'N': m = 11; break;
    case 'D': m = 12; break;
  }
  d=conv2d(date+4);
  hh=conv2d(time);
  mm=conv2d(time+3);
  ss=conv2d(time+6);
}

uint8_t DateTime::DayOfWeek() const{
  uint16_t day = get()/SECONDS_PER_DAY;
  return (day+6)%7;
}

long DateTime::get()const{
  uint16_t days=date2days(yOff, m ,d);
  return time2long(days, hh, mm, ss);
}

/*	END SECTION COPIED FROM RTClib */

/*	THIS SECTION BASED ON RTClib
	It has been adjusted to support the Microchip MCP7940M

	Version:	Initial
	Author:		C.Koiter
	Date:		August 2014
*/

void RTC_MCP7940::begin(){
  Wire.begin();
}

void RTC_MCP7940::adjust(const DateTime& dt) {	//change date and time registers based on user input
  Wire.beginTransmission(RTC_ADD);
  Wire.write((byte) 0);
  Wire.write(bin2bcd((byte) 10000000));
  Wire.write(bin2bcd(dt.minute()));
  Wire.write(bin2bcd(dt.hour()));
  Wire.write(bin2bcd(0x8)); //enable RTC battery backup function
  Wire.write(bin2bcd(dt.day()));
  Wire.write(bin2bcd(dt.month()));
  Wire.write(bin2bcd(dt.year()-2000));
  Wire.write((byte) 0);
  Wire.endTransmission();
}

bool RTC_MCP7940::isset(){		//check whether clock is set
  Wire.beginTransmission(RTC_ADD);
  Wire.write((byte) 0);
  Wire.endTransmission();
  Wire.requestFrom(RTC_ADD,1);
  return ((Wire.read()&(1<<7))==(1<<7));
}

DateTime RTC_MCP7940::now(){					//current date and time
  Wire.beginTransmission(RTC_ADD);
  Wire.write((byte) 0);
  Wire.endTransmission();
  Wire.requestFrom(RTC_ADD, 7);
  uint8_t ss = bcd2bin(Wire.read())-80;
  uint8_t mm = bcd2bin(Wire.read());
  uint8_t hh = bcd2bin(Wire.read());
  Wire.read();
  uint8_t d = bcd2bin(Wire.read());
  uint8_t m = bcd2bin(Wire.read());
  uint16_t y = bcd2bin(Wire.read()) + 2000;

  return DateTime (y, m, d, hh, mm, ss);
}

void RTC_MCP7940::configure(uint8_t value){		//enable and disable alarms, external oscillator, sqw output
  Wire.beginTransmission(RTC_ADD);
  Wire.write(RTC_CONREG);
  Wire.write(value);
  Wire.endTransmission();
}

void RTC_MCP7940::setAlarm(uint8_t value){		//set Alarm 0 interval, interrupt flag, MFP state when triggered
  Wire.beginTransmission(RTC_ADD);
  Wire.write(RTC_ALARM);
  Wire.write(value);
  Wire.endTransmission();
}

uint8_t RTC_MCP7940::ordinalDate(uint8_t toDay, uint8_t toMonth){	//convert user date to ordinal (julian) date
	Wire.beginTransmission(RTC_ADD);
	Wire.write(0x05);
	Wire.endTransmission();
	Wire.requestFrom(RTC_ADD, 1);
	uint8_t leap = Wire.read();
	uint8_t ordinal = 0;
	if(leap>=32){
		switch(toMonth){
			case 1: ordinal = toDay; break;
			case 2: ordinal = toDay + 31; break;
			case 3: ordinal = toDay + 60; break;
			case 4: ordinal = toDay + 91; break;
			case 5: ordinal = toDay + 121; break;
			case 6: ordinal = toDay + 152; break;
			case 7: ordinal = toDay + 182; break;
			case 8: ordinal = toDay + 213; break;
			case 9: ordinal = toDay + 244; break;
			case 10: ordinal = toDay + 274; break;
			case 11: ordinal = toDay + 305; break;
			case 12: ordinal = toDay + 335; break;
		}
	}
	else if(leap<32){												//leap year support
		switch(toMonth){
			case 1: ordinal = toDay; break;
			case 2: ordinal = toDay + 31; break;
			case 3: ordinal = toDay + 59; break;
			case 4: ordinal = toDay + 90; break;
			case 5: ordinal = toDay + 120; break;
			case 6: ordinal = toDay + 151; break;
			case 7: ordinal = toDay + 181; break;
			case 8: ordinal = toDay + 212; break;
			case 9: ordinal = toDay + 243; break;
			case 10: ordinal = toDay + 273; break;
			case 11: ordinal = toDay + 304; break;
			case 12: ordinal = toDay + 334; break;
		}
	}
	return ordinal;
}
<commit_msg>Correct leap year handling<commit_after>/*	library based on jeelabs RTClib [original library at https://github.com/jcw/rtclib ] altered to support Microchip MCP7940M RTC, used in Arduino
	based embedded environments. To use this library, add #include <MCP7940.h> to the top of your program.*/

#include <Wire.h>
#ifndef ENERGIA
#include <avr/pgmspace.h>
#else
#define pgm_read_word(data) *data
#define pgm_read_byte(data) *data
#define PROGMEM
#endif
#include <MCP7940.h>
#include <Arduino.h>

#define RTC_ADD           0x6F
#define RTC_CONREG        0x07
#define RTC_ALARM         0x0D
#define SECONDS_PER_DAY   86400L

/*	THIS SECTION COPIED DIRECTLY FROM RTClib [ https://github.com/jcw/rtclib ]
	USE PER http://opensource.org/licenses/mit-license.php */

static const uint8_t daysInMonth [] PROGMEM = {
  31,28,31,30,31,30,31,31,30,31,30,31
};

static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) {
  if(y >= 2000)
    y -= 2000;
  uint16_t days = d;
  for(uint8_t i = 1; i<m; ++i)
    days += pgm_read_byte(daysInMonth + i - 1);
  if(m>2 && y%4 ==0)
    ++days;
  return days + 365 * y + (y + 3) / 4 - 1;
}

static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) {
  return ((days * 24L + h) * 60 + m) * 60 + s;
}

DateTime::DateTime(long t) {
  ss=t%60;
  t/=60;
  mm=t%60;
  t/=60;
  hh=t%24;
  uint16_t days = t/24;
  uint8_t leap;
  for (yOff = 0; ;++yOff) {
    leap = yOff%4==0;
    if(days<365+leap)
      break;
    days -= 365 + leap;
  }
  for(m=1; ;++m){
    uint8_t daysPerMonth=pgm_read_byte(daysInMonth + m - 1);
    if(leap && m == 2)
      ++daysPerMonth;
    if(days<daysPerMonth)
      break;
    days -= daysPerMonth;
  }
  d=days+1;
}

DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) {
  if(year >= 2000)
    year -= 2000;
  yOff = year;
  m = month;
  d = day;
  hh = hour;
  mm = min;
  ss = sec;
}

static uint8_t conv2d(const char* p) {
  uint8_t v=0;
  if('0' <= *p && *p <= '9')
    v = *p - '0';
  return 10 * v + *++p - '0';
}

DateTime::DateTime (const char* date, const char* time) {
  yOff = conv2d(date + 9);
  switch(date[0]) {
    case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break;
    case 'F': m = 2; break;
    case 'A': m = date[2] == 'r' ? 4 : 8; break;
    case 'M': m = date[2] == 'r' ? 3 : 5; break;
    case 'S': m = 9; break;
    case 'O': m = 10; break;
    case 'N': m = 11; break;
    case 'D': m = 12; break;
  }
  d=conv2d(date+4);
  hh=conv2d(time);
  mm=conv2d(time+3);
  ss=conv2d(time+6);
}

uint8_t DateTime::DayOfWeek() const{
  uint16_t day = get()/SECONDS_PER_DAY;
  return (day+6)%7;
}

long DateTime::get()const{
  uint16_t days=date2days(yOff, m ,d);
  return time2long(days, hh, mm, ss);
}

/*	END SECTION COPIED FROM RTClib */

/*	THIS SECTION BASED ON RTClib
	It has been adjusted to support the Microchip MCP7940M

	Version:	Initial
	Author:		C.Koiter
	Date:		August 2014
*/

void RTC_MCP7940::begin(){
  Wire.begin();
}

void RTC_MCP7940::adjust(const DateTime& dt) {	//change date and time registers based on user input
  Wire.beginTransmission(RTC_ADD);
  Wire.write((byte) 0);
  Wire.write(bin2bcd((byte) 10000000));
  Wire.write(bin2bcd(dt.minute()));
  Wire.write(bin2bcd(dt.hour()));
  Wire.write(bin2bcd(0x8)); //enable RTC battery backup function
  Wire.write(bin2bcd(dt.day()));
  Wire.write(bin2bcd(dt.month()));
  Wire.write(bin2bcd(dt.year()-2000));
  Wire.write((byte) 0);
  Wire.endTransmission();
}

bool RTC_MCP7940::isset(){		//check whether clock is set
  Wire.beginTransmission(RTC_ADD);
  Wire.write((byte) 0);
  Wire.endTransmission();
  Wire.requestFrom(RTC_ADD,1);
  return ((Wire.read()&(1<<7))==(1<<7));
}

DateTime RTC_MCP7940::now(){					//current date and time
  Wire.beginTransmission(RTC_ADD);
  Wire.write((byte) 0);
  Wire.endTransmission();
  Wire.requestFrom(RTC_ADD, 7);
  uint8_t ss = bcd2bin(Wire.read())-80;
  uint8_t mm = bcd2bin(Wire.read());
  uint8_t hh = bcd2bin(Wire.read());
  Wire.read();
  uint8_t d = bcd2bin(Wire.read());
  uint8_t m = bcd2bin(Wire.read() & 0x1F);
  uint16_t y = bcd2bin(Wire.read()) + 2000;

  return DateTime (y, m, d, hh, mm, ss);
}

void RTC_MCP7940::configure(uint8_t value){		//enable and disable alarms, external oscillator, sqw output
  Wire.beginTransmission(RTC_ADD);
  Wire.write(RTC_CONREG);
  Wire.write(value);
  Wire.endTransmission();
}

void RTC_MCP7940::setAlarm(uint8_t value){		//set Alarm 0 interval, interrupt flag, MFP state when triggered
  Wire.beginTransmission(RTC_ADD);
  Wire.write(RTC_ALARM);
  Wire.write(value);
  Wire.endTransmission();
}

uint8_t RTC_MCP7940::ordinalDate(uint8_t toDay, uint8_t toMonth){	//convert user date to ordinal (julian) date
	Wire.beginTransmission(RTC_ADD);
	Wire.write(0x05);
	Wire.endTransmission();
	Wire.requestFrom(RTC_ADD, 1);
	uint8_t leap = Wire.read();
	uint8_t ordinal = 0;
	if(leap>=32){
		switch(toMonth){
			case 1: ordinal = toDay; break;
			case 2: ordinal = toDay + 31; break;
			case 3: ordinal = toDay + 60; break;
			case 4: ordinal = toDay + 91; break;
			case 5: ordinal = toDay + 121; break;
			case 6: ordinal = toDay + 152; break;
			case 7: ordinal = toDay + 182; break;
			case 8: ordinal = toDay + 213; break;
			case 9: ordinal = toDay + 244; break;
			case 10: ordinal = toDay + 274; break;
			case 11: ordinal = toDay + 305; break;
			case 12: ordinal = toDay + 335; break;
		}
	}
	else if(leap<32){												//leap year support
		switch(toMonth){
			case 1: ordinal = toDay; break;
			case 2: ordinal = toDay + 31; break;
			case 3: ordinal = toDay + 59; break;
			case 4: ordinal = toDay + 90; break;
			case 5: ordinal = toDay + 120; break;
			case 6: ordinal = toDay + 151; break;
			case 7: ordinal = toDay + 181; break;
			case 8: ordinal = toDay + 212; break;
			case 9: ordinal = toDay + 243; break;
			case 10: ordinal = toDay + 273; break;
			case 11: ordinal = toDay + 304; break;
			case 12: ordinal = toDay + 334; break;
		}
	}
	return ordinal;
}
<|endoftext|>


<commit_before>#include <vector>
#include <iostream>
#include <fstream>
#include <math.h>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <algorithm>
#include "mpi.h"

bool fillMatrixFromFile(std::string path, std::vector< std::vector<unsigned short> > &matrix, std::string &cols, std::string &lines);
void createMatrix(unsigned short l, unsigned short c, std::vector< std::vector<unsigned short> > &matrix);
void processMatrix(std::vector< std::vector<unsigned short> > &matrix, std::string &cols, std::string &lines);
void backtrack(std::vector< std::vector<unsigned short> > &matrix, std::string &cols, std::string &lines, unsigned short i, unsigned short j, std::stringstream &ss);
void printMatrix(std::vector< std::vector<unsigned short> > &matrix);
unsigned short cost(unsigned short cols);

int main(int argc, char* argv[]) {

  MPI_Init(&argc, &argv);

  if(argc != 2){
    std::cout << "Exactly one input parameter is allowed. This should be the name of the input file present in public-instances." << std::endl;
    exit(EXIT_FAILURE);
  }

  std::string path = argv[1];

  std::vector< std::vector<unsigned short> > matrix;
  std::string lines = "";
  std::string cols = "";

  std::stringstream ss;

  if(fillMatrixFromFile(path, matrix, lines, cols)) {
    backtrack(matrix, lines, cols, lines.size(), cols.size(), ss);
    std::string result = ss.str();
    std::reverse(result.begin(), result.end());
    std::cout << result.size() << std::endl;
    std::cout << result << std::endl;
  }
  else {
    std::cout << "Error opening file" << std::endl;
    exit(EXIT_FAILURE);
  }

  return 0;
}

bool fillMatrixFromFile(std::string path, std::vector< std::vector<unsigned short> > &matrix, std::string &lines, std::string &cols) {
  std::ios_base::sync_with_stdio (false);

  std::stringstream ss;
  std::ifstream file (path.c_str(), std::ifstream::in);

  if (file.is_open()) {
    std::string line;
    std::getline(file, line);

    ss << line;
    unsigned short nLines, nCols;
    ss >> nLines >> nCols;

    std::getline(file, lines);
    std::getline(file, cols);

    createMatrix(lines.size()+1, cols.size()+1, matrix);
    processMatrix(matrix, cols, lines);

    return true;
  } else {
    return false;
  }
}

void createMatrix(unsigned short l, unsigned short c, std::vector< std::vector<unsigned short> > &matrix) {
  for (unsigned short i = 0; i < l; i++) {
    std::vector<unsigned short> column(c, 0);
    matrix.push_back(column);
  }
}

void processMatrix(std::vector< std::vector<unsigned short> > &matrix, std::string &cols, std::string &lines) {
  unsigned short nLines = matrix.size();
  unsigned short nCols = matrix[0].size();

  int id, p;
  MPI_Comm_rank (MPI_COMM_WORLD, &id);
  MPI_Comm_size (MPI_COMM_WORLD, &p);

  float division = nCols/p;
  size_t remainder = nCols % p;

  std::cout << "Cols" << nCols << "Remainder: " << remainder << std::endl;

  unsigned short startCol = id * division;
  unsigned short endCol = (id+1) * division - 1;

  if (id == (p-1)) {
    endCol += remainder;
  }

  std::cout << "ID: " << id << "Start Col: " << startCol << " endCol:" << endCol << std::endl;

  MPI_Finalize();
}

void backtrack(std::vector< std::vector<unsigned short> > &matrix, std::string &lines, std::string &cols, unsigned short i, unsigned short j, std::stringstream &ss) {
  while(i!=0 && j!=0){
    if(cols[j-1] == lines[i-1]) {
      ss << std::string(1, cols[j-1]);
      i--;
      j--;
    }
    else{
      if(matrix[i][j-1] < matrix[i-1][j]){
        i--;
      }
      else{
        j--;
      }
    }
  }
}

void printMatrix(std::vector< std::vector<unsigned short> > &matrix) {
  for (unsigned short i = 0; i < matrix.size(); i++) {
    for (unsigned short j = 0; j < matrix[i].size(); j++) {
      std::cout << matrix[i][j] << " ";
    }
    std::cout << std::endl;
  }
}

unsigned short cost(unsigned short cols) {
  unsigned short i, n_iter = 20;
  double dcost = 0;
  for(i = 0; i < n_iter; i++)
    dcost += pow(sin((double) cols),2) + pow(cos((double) cols),2);
  return (unsigned short) (dcost / n_iter + 0.1);
}
<commit_msg>commit super fixe todo super awesome projecto feito mas não funciona<commit_after>#include <vector>
#include <iostream>
#include <fstream>
#include <math.h>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <algorithm>
#include "mpi.h"

bool fillMatrixFromFile(std::string path, std::vector< std::vector<unsigned short> > &matrix, std::string &cols, std::string &lines);
void createMatrix(unsigned short l, unsigned short c, std::vector< std::vector<unsigned short> > &matrix);
void processMatrix(std::vector< std::vector<unsigned short> > &matrix, std::string &cols, std::string &lines);
void backtrack(std::vector< std::vector<unsigned short> > &matrix, std::string &cols, std::string &lines, unsigned short i, unsigned short j, std::stringstream &ss);
void printMatrix(std::vector< std::vector<unsigned short> > &matrix);
unsigned short cost(unsigned short cols);

int main(int argc, char* argv[]) {

  MPI_Init(&argc, &argv);

  if(argc != 2){
    std::cout << "Exactly one input parameter is allowed. This should be the name of the input file present in public-instances." << std::endl;
    exit(EXIT_FAILURE);
  }

  std::string path = argv[1];

  std::vector< std::vector<unsigned short> > matrix;
  std::string lines = "";
  std::string cols = "";

  std::stringstream ss;

  if(fillMatrixFromFile(path, matrix, lines, cols)) {
    backtrack(matrix, lines, cols, lines.size(), cols.size(), ss);
    std::string result = ss.str();
    std::reverse(result.begin(), result.end());
    std::cout << result.size() << std::endl;
    std::cout << result << std::endl;
  }
  else {
    std::cout << "Error opening file" << std::endl;
    exit(EXIT_FAILURE);
  }

  return 0;
}

bool fillMatrixFromFile(std::string path, std::vector< std::vector<unsigned short> > &matrix, std::string &lines, std::string &cols) {
  std::ios_base::sync_with_stdio (false);

  std::stringstream ss;
  std::ifstream file (path.c_str(), std::ifstream::in);

  if (file.is_open()) {
    std::string line;
    std::getline(file, line);

    ss << line;
    unsigned short nLines, nCols;
    ss >> nLines >> nCols;

    std::getline(file, lines);
    std::getline(file, cols);

    createMatrix(lines.size()+1, cols.size()+1, matrix);
    processMatrix(matrix, cols, lines);

    return true;
  } else {
    return false;
  }
}

void createMatrix(unsigned short l, unsigned short c, std::vector< std::vector<unsigned short> > &matrix) {
  for (unsigned short i = 0; i < l; i++) {
    std::vector<unsigned short> column(c, 0);
    matrix.push_back(column);
  }
}

void processMatrix(std::vector< std::vector<unsigned short> > &matrix, std::string &cols, std::string &lines) {
  unsigned short nLines = matrix.size();
  unsigned short nCols = matrix[0].size();

  int id, p;
  MPI_Comm_rank (MPI_COMM_WORLD, &id);
  MPI_Comm_size (MPI_COMM_WORLD, &p);

  float division = nCols/p;
  size_t remainder = nCols % p;

  unsigned short startCol = id * division;
  unsigned short endCol = (id+1) * division - 1;

  int blockLines = 10;

  if (id == (p-1)) {
    endCol += remainder;
  }

  short i=0;
  MPI_Status status;

  if(i == id && id == 0){
    unsigned short currentLine = 1;
    while(currentLine != nLines){
      if((nLines-currentLine) < blockLines)
        blockLines = (nLines-currentLine);
      #define TAG 123

      //process block
      short pos = 0;
      unsigned short send[blockLines];

      for(unsigned short i = currentLine; i < (currentLine + blockLines); i++) {
        currentLine++;
        for (unsigned short j = startCol; j < endCol; j++) {
          if(cols[i-1] == lines[j-1]) {
            matrix[i][j] = matrix[i-1][j-1] + cost(i);
          } else {
            matrix[i][j] = std::max(matrix[i][j-1], matrix[i-1][j]);
          }
        }
        send[pos] = matrix[currentLine][endCol];
        pos++;
      }

      MPI_Send(send,blockLines,MPI_UNSIGNED_SHORT,1,TAG,MPI_COMM_WORLD);
    }
  }

  if(i == id && id != 0 && id!= p){
    unsigned short currentLine = 1;
   while(currentLine != nLines){
      if((nLines-currentLine) < blockLines)
        blockLines = (nLines-currentLine);
      #define TAG 123

      unsigned short input[blockLines];
      MPI_Recv(input,blockLines,MPI_UNSIGNED_SHORT,(id-1),TAG,MPI_COMM_WORLD,&status);

      //save input to matrix
      short pos = 0;
      short col = startCol -1 ;
      for(unsigned short i = currentLine; i < (currentLine + blockLines); i++){
          matrix[i][col] = input[pos];
          pos++;
        }

      //process block
      unsigned short send[blockLines];

      pos = 0;
      for(unsigned short i = currentLine; i < (currentLine + blockLines); i++) {
        currentLine++;
        for (unsigned short j = startCol; j < endCol; j++) {
          if(cols[i-1] == lines[j-1]) {
            matrix[i][j] = matrix[i-1][j-1] + cost(i);
          } else {
            matrix[i][j] = std::max(matrix[i][j-1], matrix[i-1][j]);
          }
         }
        send[pos] = matrix[currentLine][endCol];
        pos++;
      }

      MPI_Send(send,blockLines,MPI_UNSIGNED_SHORT,(id+1),TAG,MPI_COMM_WORLD);
    }
  }

  if(i == id && id!= p){
    unsigned short currentLine = 1;
   while(currentLine != nLines){
      if((nLines-currentLine) < blockLines)
        blockLines = (nLines-currentLine);
      #define TAG 123

      unsigned short input[blockLines];
      MPI_Recv(input,blockLines,MPI_UNSIGNED_SHORT,(id-1),TAG,MPI_COMM_WORLD,&status);

      //save input to matrix
      short pos = 0;
      short col = startCol -1 ;
      for(unsigned short i = currentLine; i < (currentLine + blockLines); i++){
          matrix[i][col] = input[pos];
          pos++;
      }

      //process block
      for(unsigned short i = currentLine; i < (currentLine + blockLines); i++) {
        currentLine++;
        for (unsigned short j = startCol; j < endCol; j++) {
          if(cols[i-1] == lines[j-1]) {
            matrix[i][j] = matrix[i-1][j-1] + cost(i);
          } else {
            matrix[i][j] = std::max(matrix[i][j-1], matrix[i-1][j]);
          }
        }
      }
    }
  }

  std::cout << "ID: " << id << "Start Col: " << startCol << " endCol:" << endCol << std::endl;

  MPI_Finalize();
}

void backtrack(std::vector< std::vector<unsigned short> > &matrix, std::string &lines, std::string &cols, unsigned short i, unsigned short j, std::stringstream &ss) {
  while(i!=0 && j!=0){
    if(cols[j-1] == lines[i-1]) {
      ss << std::string(1, cols[j-1]);
      i--;
      j--;
    }
    else{
      if(matrix[i][j-1] < matrix[i-1][j]){
        i--;
      }
      else{
        j--;
      }
    }
  }
}

void printMatrix(std::vector< std::vector<unsigned short> > &matrix) {
  for (unsigned short i = 0; i < matrix.size(); i++) {
    for (unsigned short j = 0; j < matrix[i].size(); j++) {
      std::cout << matrix[i][j] << " ";
    }
    std::cout << std::endl;
  }
}

unsigned short cost(unsigned short cols) {
  unsigned short i, n_iter = 20;
  double dcost = 0;
  for(i = 0; i < n_iter; i++)
    dcost += pow(sin((double) cols),2) + pow(cos((double) cols),2);
  return (unsigned short) (dcost / n_iter + 0.1);
}
<|endoftext|>


<commit_before>/*
    Copyright (C) 2009-2011 qiuu
    Copyright (C) 2016 Clownacy

    This library is free software; 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; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
    USA
*/

#include <cstring>
#include <fstream>
#include <unistd.h>

#include <SDL2/SDL.h>

#include "PrjHndl.h"
#include "TxtRead.h"
#include "Resource.h"
#include "WinAPI.h"

ProjectData::ProjectData(const char* const prjtxt) {
    tileOffset = 0;
    letterOffset = numberOffset = 0;

    // Make working directory from project path
    char prjdir[strlen(prjtxt)+1];
    strcpy(prjdir, prjtxt);
    // Find last path separator
    char* posix_seperator = strrchr(prjdir, '/');	// First, POSIX
    char* windows_seperator = strrchr(prjdir, '\\');	// Then whatever Windows uses
    if (posix_seperator != NULL || windows_seperator != NULL)
    {
        if (posix_seperator != NULL)
            (*posix_seperator) = '\0';
        else if (windows_seperator != NULL)
            (*windows_seperator) = '\0';

        chdir(prjdir);
    }

    std::ifstream prjfile(prjtxt, std::ios::in);

    while (!prjfile.eof()) {
        char line[256];
        prjfile.getline(line, 256);
	infoType info_type = readInfoType(line);
	AssignInfo(info_type, line+strcspn(line, ":")+1);
    }
}

void ProjectData::AssignInfo(const infoType type, char* content) {
    switch(type) {
        case infoType::PALETTE_FILE:
		strcpy(pal.name, trimString(content));
		break;
        case infoType::MAPPING_FILE:
		strcpy(map.name, trimString(content));
		break;
        case infoType::ART_FILE:
		strcpy(art.name, trimString(content));
		break;
        case infoType::PALETTE_OFFSET:
		pal.offset = strtol(content, NULL, 0);
		break;
        case infoType::MAPPING_OFFSET:
		map.offset = strtol(content, NULL, 0);
		break;
        case infoType::ART_OFFSET:
		art.offset = strtol(content, NULL, 0);
		break;
        case infoType::PALETTE_LENGTH:
		pal.length = strtol(content, NULL, 0);
		break;
        case infoType::MAPPING_LENGTH:
		map.length = strtol(content, NULL, 0);
		break;
        case infoType::ART_LENGTH:
		art.length = strtol(content, NULL, 0);
		break;
        case infoType::PALETTE_COMPRESSION:
		pal.compression = readComprType(trimString(content));
		break;
        case infoType::MAPPING_COMPRESSION:
		map.compression = readComprType(trimString(content));
		break;
        case infoType::ART_COMPRESSION:
		art.compression = readComprType(trimString(content));
		break;
        case infoType::PALETTE_DESTINATION_OFFSET:
		pal.destination_offset = strtol(content, NULL, 0);
		break;
        case infoType::X_SIZE:
		map.xSize = strtol(content, NULL, 0);
		break;
        case infoType::Y_SIZE:
		map.ySize = strtol(content, NULL, 0);
		break;
        case infoType::TILE_OFFSET:
		tileOffset = strtol(content, NULL, 0);
		break;
        case infoType::LETTER_OFFSET:
		letterOffset = strtol(content, NULL, 0);
		break;
        case infoType::NUMBER_OFFSET:
		numberOffset = strtol(content, NULL, 0);
		break;
        case infoType::SAVE_FILE:
		strcpy(map.saveName, trimString(content));
		break;
        case infoType::KOSINSKI_MODULE_SIZE:
		art.kosinski_module_size = strtol(content, NULL, 0);
		break;
    }
}
<commit_msg>Flagging error if Palette Destination Offset is too high<commit_after>/*
    Copyright (C) 2009-2011 qiuu
    Copyright (C) 2016 Clownacy

    This library is free software; 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; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
    USA
*/

#include <cstring>
#include <fstream>
#include <unistd.h>

#include <SDL2/SDL.h>

#include "PrjHndl.h"
#include "TxtRead.h"
#include "Resource.h"
#include "WinAPI.h"

ProjectData::ProjectData(const char* const prjtxt) {
    tileOffset = 0;
    letterOffset = numberOffset = 0;

    // Make working directory from project path
    char prjdir[strlen(prjtxt)+1];
    strcpy(prjdir, prjtxt);
    // Find last path separator
    char* posix_seperator = strrchr(prjdir, '/');	// First, POSIX
    char* windows_seperator = strrchr(prjdir, '\\');	// Then whatever Windows uses
    if (posix_seperator != NULL || windows_seperator != NULL)
    {
        if (posix_seperator != NULL)
            (*posix_seperator) = '\0';
        else if (windows_seperator != NULL)
            (*windows_seperator) = '\0';

        chdir(prjdir);
    }

    std::ifstream prjfile(prjtxt, std::ios::in);

    while (!prjfile.eof()) {
        char line[256];
        prjfile.getline(line, 256);
	infoType info_type = readInfoType(line);
	AssignInfo(info_type, line+strcspn(line, ":")+1);
    }
}

void ProjectData::AssignInfo(const infoType type, char* content) {
    switch(type) {
        case infoType::PALETTE_FILE:
		strcpy(pal.name, trimString(content));
		break;
        case infoType::MAPPING_FILE:
		strcpy(map.name, trimString(content));
		break;
        case infoType::ART_FILE:
		strcpy(art.name, trimString(content));
		break;
        case infoType::PALETTE_OFFSET:
		pal.offset = strtol(content, NULL, 0);
		break;
        case infoType::MAPPING_OFFSET:
		map.offset = strtol(content, NULL, 0);
		break;
        case infoType::ART_OFFSET:
		art.offset = strtol(content, NULL, 0);
		break;
        case infoType::PALETTE_LENGTH:
		pal.length = strtol(content, NULL, 0);
		break;
        case infoType::MAPPING_LENGTH:
		map.length = strtol(content, NULL, 0);
		break;
        case infoType::ART_LENGTH:
		art.length = strtol(content, NULL, 0);
		break;
        case infoType::PALETTE_COMPRESSION:
		pal.compression = readComprType(trimString(content));
		break;
        case infoType::MAPPING_COMPRESSION:
		map.compression = readComprType(trimString(content));
		break;
        case infoType::ART_COMPRESSION:
		art.compression = readComprType(trimString(content));
		break;
        case infoType::PALETTE_DESTINATION_OFFSET:
		pal.destination_offset = strtol(content, NULL, 0);
		if (pal.destination_offset >= 0x80)
		{
			SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Palette Destination Offset cannot be higher than 0x7F (16th entry of 4th palette line; the last palette entry)", NULL);
			exit(1);
		}
		break;
        case infoType::X_SIZE:
		map.xSize = strtol(content, NULL, 0);
		break;
        case infoType::Y_SIZE:
		map.ySize = strtol(content, NULL, 0);
		break;
        case infoType::TILE_OFFSET:
		tileOffset = strtol(content, NULL, 0);
		break;
        case infoType::LETTER_OFFSET:
		letterOffset = strtol(content, NULL, 0);
		break;
        case infoType::NUMBER_OFFSET:
		numberOffset = strtol(content, NULL, 0);
		break;
        case infoType::SAVE_FILE:
		strcpy(map.saveName, trimString(content));
		break;
        case infoType::KOSINSKI_MODULE_SIZE:
		art.kosinski_module_size = strtol(content, NULL, 0);
		break;
    }
}
<|endoftext|>


<commit_before>#include <fstream>
#include <algorithm>
#include <regex>
#include "ProcNet.h"

unordered_map<string, NetData> ProcNet::getInodesIpMap() {
    auto inodeIpMapList = retrieveInodeIpMapping();

    return inodeIpMapList;
}

unordered_map<string, NetData> ProcNet::retrieveInodeIpMapping() {
    string filename = "/proc/net/" + ipType;

    ifstream file(filename);
    string store;
    unordered_map<string, NetData> inodesIpMap;
    inodesIpMap.reserve(100);

    while (getline(file, store)) {
        string header("sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode");
        if (store.find(header) == string::npos) {
            auto first = store.find_first_not_of(" ");
            auto last = store.find_last_not_of(" ");

            string ipTypeData = store.substr(first, last - first + 1);

            inodesIpMap.insert(extractInodeIpMapping(ipTypeData));
        }
    }

    return inodesIpMap;
}

pair<string, NetData> ProcNet::extractInodeIpMapping(string ipTypeData) {
    regex ipTypeDataRegex("\\d++:\\s([0-9A-Z]{8}):([0-9A-Z]{4})\\s([0-9A-Z]{8}):([0-9A-Z]{4})(?:\\s++[0-9A-Z:]++){6}\\s([0-9]++)");
    smatch match;

    struct NetData netData;
    if (regex_search(ipTypeData, match, ipTypeDataRegex)) {

        netData = {
            match[1].str().c_str(),
            match[2].str().c_str(),
            match[3].str().c_str(),
            match[4].str().c_str()
        };
    }

    return pair<string, NetData>(match[5].str().c_str(), netData);
}
<commit_msg>Refactor proc net<commit_after>#include <fstream>
#include <algorithm>
#include <regex>
#include "ProcNet.h"

unordered_map<string, NetData> ProcNet::getInodesIpMap() {
    auto inodeIpMapList = retrieveInodeIpMapping();

    return inodeIpMapList;
}

unordered_map<string, NetData> ProcNet::retrieveInodeIpMapping() {
    string filename = "/proc/net/" + ipType;

    ifstream file(filename);
    string store;
    unordered_map<string, NetData> inodesIpMap;
    inodesIpMap.reserve(100);

    bool firstLine = true;
    while (getline(file, store)) {
        if (firstLine) {
            firstLine = false;
            continue;
        }

        auto first = store.find_first_not_of(" ");
        auto last = store.find_last_not_of(" ");

        string ipTypeData = store.substr(first, last - first + 1);

        inodesIpMap.insert(extractInodeIpMapping(ipTypeData));
    }

    return inodesIpMap;
}

pair<string, NetData> ProcNet::extractInodeIpMapping(string ipTypeData) {
    regex ipTypeDataRegex("\\d++:\\s([0-9A-Z]{8}):([0-9A-Z]{4})\\s([0-9A-Z]{8}):([0-9A-Z]{4})(?:\\s++[0-9A-Z:]++){6}\\s([0-9]++)");
    smatch match;

    struct NetData netData;
    if (regex_search(ipTypeData, match, ipTypeDataRegex)) {

        netData = {
            match[1].str().c_str(),
            match[2].str().c_str(),
            match[3].str().c_str(),
            match[4].str().c_str()
        };
    }

    return pair<string, NetData>(match[5].str().c_str(), netData);
}
<|endoftext|>


<commit_before>#include <string.h>

#include "SelRect.h"

Graphics* SelRect::GfxStuff = NULL;
LevMap* SelRect::LevelMap = NULL;

/* constructor */
SelRect::SelRect(Graphics* GfxStuff, LevMap* LevelMap) {
    this->GfxStuff = GfxStuff;
    this->LevelMap = LevelMap;
    MapData = NULL;
}

/* copy constructor */
SelRect::SelRect(SelRect* const sr) {
    xStart = sr->xStart;
    yStart = sr->yStart;
    xSize = sr->xSize;
    ySize = sr->ySize;
    if (sr->MapData != NULL) {
        MapData = new Tile**[ySize];
        for (int y=0; y < ySize; ++y) MapData[y] = new Tile*[xSize];
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                MapData[y][x] = new Tile(sr->MapData[y][x]);
            }
        }
    } else MapData = NULL;
}

/* destructor */
SelRect::~SelRect() {
    Kill();
}

/* returns true if the selected rectangle contains some data, false otherwise */
bool SelRect::isActive() {
    if (MapData == NULL) return false;
    else return true;
}

/* write selected content to map */
void SelRect::AssignSection() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    //condition to prevent weird crash
                    if (xStart != 0) delete &LevelMap->MapData[y+yStart][x+xStart];
                    LevelMap->MapData[y+yStart][x+xStart] = *MapData[y][x];
                }
            }
        }
    }
}

/* write selected content to current position map */
void SelRect::PasteSection() {
    xStart = LevelMap->CurX;
    yStart = LevelMap->CurY;
    AssignSection();
}

/* reads content within rectangle from map */
void SelRect::TakeSection() {
    Kill();
    MapData = new Tile**[ySize];
    for (int y=0; y < ySize; ++y) MapData[y] = new Tile*[xSize];
    for (int y=0; y < ySize; ++y) {
        for (int x=0; x < xSize; ++x) {
            if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize))
                MapData[y][x] = new Tile(LevelMap->MapData[y+yStart][x+xStart]);
        }
    }
}

/* Sets the start position of the rectangle
   parameters: the cursor position */
void SelRect::SelInit(int x, int y) {
    if (MapData != NULL) SelClearRect();
    GfxStuff->PosScreenToTileRound(&x, &y);
    xStart = x;
    yStart = y;
    AdaptStartBounds();
}

/* Sets the ending position of the rectangle and grabs data from the map
   parameters: the cursor position */
void SelRect::SelFinalize(int x, int y) {
    GfxStuff->PosScreenToTileRound(&x, &y);
    if (x < xStart) {int temp = x; x = xStart; xStart = temp;}
    if (y < yStart) {int temp = y; y = yStart; yStart = temp;}
    xSize = x - xStart;
    ySize = y - yStart;
    AdaptBounds();
    if (xSize > 0 && ySize > 0) {
        TakeSection();
        SelDrawRect();
    }
}

/* draws the rectangle on screen */
void SelRect::SelDrawRect() {
    if (isActive())
        GfxStuff->DrawFreeRect(xStart, yStart, xSize, ySize);
}

/* re-draws the section on the map that was previously covered by the selection
   rectangle to remove its graphics */
void SelRect::SelClearRect() {
    LevelMap->DrawMapSection(xStart, yStart, xSize, ySize);
}

/* unselects the currently selected area */
void SelRect::Unselect() {
    if (isActive()) SelClearRect();
    Kill();
}

/* clears the memory occupied by the mapdata within the object */
void SelRect::Kill() {
    if (MapData != NULL) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                delete MapData[y][x];
            }
        }
        for (int y=0; y < ySize; ++y) delete MapData[y];
        delete MapData;
        MapData = NULL;
    }
}

/* Checks if rectangle needs to be redrawn, and does if necessary
 * parameters are tile coords of possibly overlapping tile */
void SelRect::CheckRedraw(int x, int y) {
    //add code to check whether rectangle has been overwritten
}

/* fills the selected rectangle with empty tiles */
void SelRect::clear() {
    for (int y=0; y < ySize; ++y) {
        for (int x=0; x < xSize; ++x) {
            delete MapData[y][x];
            MapData[y][x] = new Tile;
        }
    }
}

void SelRect::AdaptBounds() {
    if (xStart + xSize > LevelMap->xSize) xSize = LevelMap->xSize - xStart;
    if (yStart + ySize > LevelMap->ySize) ySize = LevelMap->ySize - yStart;
}

void SelRect::AdaptStartBounds() {
    if (xStart > LevelMap->xSize) xStart = LevelMap->xSize - 1;
    if (yStart > LevelMap->ySize) yStart = LevelMap->ySize - 1;
    if (xStart < 0) xStart = 0;
    if (yStart < 0) yStart = 0;
}

/* xFlip selected content */
void SelRect::FlipX() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    //condition to prevent weird crash
                    if (xStart != 0) delete &LevelMap->MapData[y+yStart][x+xStart];
                    LevelMap->MapData[y+yStart][x+xStart] = *MapData[y][xSize-x-1];
                    LevelMap->MapData[y+yStart][x+xStart].FlipX();
                }
            }
        }
        TakeSection();
    }
}

/* yFlip selected content */
void SelRect::FlipY() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    //condition to prevent weird crash
                    if (xStart != 0) delete &LevelMap->MapData[y+yStart][x+xStart];
                    LevelMap->MapData[y+yStart][x+xStart] = *MapData[ySize-y-1][x];
                    LevelMap->MapData[y+yStart][x+xStart].FlipY();
                }
            }
        }
        TakeSection();
    }
}

void SelRect::SwapPriority() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    MapData[y][x]->SwapPriority();
                }
            }
        }
        AssignSection();
    }
}

void SelRect::IncrID() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    if (MapData[y][x]->tileID == 0 && GfxStuff->GetTileOffset() != 0) MapData[y][x]->tileID = GfxStuff->GetTileOffset();
                    else if (MapData[y][x]->tileID + 1 < GfxStuff->GetTileAmount() + GfxStuff->GetTileOffset())
                        ++MapData[y][x]->tileID;
                }
            }
        }
        AssignSection();
    }
}

void SelRect::DecrID() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    if (MapData[y][x]->tileID > GfxStuff->GetTileOffset()) --MapData[y][x]->tileID;
                    else MapData[y][x]->tileID = 0;
                }
            }
        }
        AssignSection();
    }
}
<commit_msg>This fix *causes* a weird crash<commit_after>#include <string.h>

#include "SelRect.h"

Graphics* SelRect::GfxStuff = NULL;
LevMap* SelRect::LevelMap = NULL;

/* constructor */
SelRect::SelRect(Graphics* GfxStuff, LevMap* LevelMap) {
    this->GfxStuff = GfxStuff;
    this->LevelMap = LevelMap;
    MapData = NULL;
}

/* copy constructor */
SelRect::SelRect(SelRect* const sr) {
    xStart = sr->xStart;
    yStart = sr->yStart;
    xSize = sr->xSize;
    ySize = sr->ySize;
    if (sr->MapData != NULL) {
        MapData = new Tile**[ySize];
        for (int y=0; y < ySize; ++y) MapData[y] = new Tile*[xSize];
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                MapData[y][x] = new Tile(sr->MapData[y][x]);
            }
        }
    } else MapData = NULL;
}

/* destructor */
SelRect::~SelRect() {
    Kill();
}

/* returns true if the selected rectangle contains some data, false otherwise */
bool SelRect::isActive() {
    if (MapData == NULL) return false;
    else return true;
}

/* write selected content to map */
void SelRect::AssignSection() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    LevelMap->MapData[y+yStart][x+xStart] = *MapData[y][x];
                }
            }
        }
    }
}

/* write selected content to current position map */
void SelRect::PasteSection() {
    xStart = LevelMap->CurX;
    yStart = LevelMap->CurY;
    AssignSection();
}

/* reads content within rectangle from map */
void SelRect::TakeSection() {
    Kill();
    MapData = new Tile**[ySize];
    for (int y=0; y < ySize; ++y) MapData[y] = new Tile*[xSize];
    for (int y=0; y < ySize; ++y) {
        for (int x=0; x < xSize; ++x) {
            if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize))
                MapData[y][x] = new Tile(LevelMap->MapData[y+yStart][x+xStart]);
        }
    }
}

/* Sets the start position of the rectangle
   parameters: the cursor position */
void SelRect::SelInit(int x, int y) {
    if (MapData != NULL) SelClearRect();
    GfxStuff->PosScreenToTileRound(&x, &y);
    xStart = x;
    yStart = y;
    AdaptStartBounds();
}

/* Sets the ending position of the rectangle and grabs data from the map
   parameters: the cursor position */
void SelRect::SelFinalize(int x, int y) {
    GfxStuff->PosScreenToTileRound(&x, &y);
    if (x < xStart) {int temp = x; x = xStart; xStart = temp;}
    if (y < yStart) {int temp = y; y = yStart; yStart = temp;}
    xSize = x - xStart;
    ySize = y - yStart;
    AdaptBounds();
    if (xSize > 0 && ySize > 0) {
        TakeSection();
        SelDrawRect();
    }
}

/* draws the rectangle on screen */
void SelRect::SelDrawRect() {
    if (isActive())
        GfxStuff->DrawFreeRect(xStart, yStart, xSize, ySize);
}

/* re-draws the section on the map that was previously covered by the selection
   rectangle to remove its graphics */
void SelRect::SelClearRect() {
    LevelMap->DrawMapSection(xStart, yStart, xSize, ySize);
}

/* unselects the currently selected area */
void SelRect::Unselect() {
    if (isActive()) SelClearRect();
    Kill();
}

/* clears the memory occupied by the mapdata within the object */
void SelRect::Kill() {
    if (MapData != NULL) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                delete MapData[y][x];
            }
        }
        for (int y=0; y < ySize; ++y) delete MapData[y];
        delete MapData;
        MapData = NULL;
    }
}

/* Checks if rectangle needs to be redrawn, and does if necessary
 * parameters are tile coords of possibly overlapping tile */
void SelRect::CheckRedraw(int x, int y) {
    //add code to check whether rectangle has been overwritten
}

/* fills the selected rectangle with empty tiles */
void SelRect::clear() {
    for (int y=0; y < ySize; ++y) {
        for (int x=0; x < xSize; ++x) {
            delete MapData[y][x];
            MapData[y][x] = new Tile;
        }
    }
}

void SelRect::AdaptBounds() {
    if (xStart + xSize > LevelMap->xSize) xSize = LevelMap->xSize - xStart;
    if (yStart + ySize > LevelMap->ySize) ySize = LevelMap->ySize - yStart;
}

void SelRect::AdaptStartBounds() {
    if (xStart > LevelMap->xSize) xStart = LevelMap->xSize - 1;
    if (yStart > LevelMap->ySize) yStart = LevelMap->ySize - 1;
    if (xStart < 0) xStart = 0;
    if (yStart < 0) yStart = 0;
}

/* xFlip selected content */
void SelRect::FlipX() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    //condition to prevent weird crash
                    if (xStart != 0) delete &LevelMap->MapData[y+yStart][x+xStart];
                    LevelMap->MapData[y+yStart][x+xStart] = *MapData[y][xSize-x-1];
                    LevelMap->MapData[y+yStart][x+xStart].FlipX();
                }
            }
        }
        TakeSection();
    }
}

/* yFlip selected content */
void SelRect::FlipY() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    //condition to prevent weird crash
                    if (xStart != 0) delete &LevelMap->MapData[y+yStart][x+xStart];
                    LevelMap->MapData[y+yStart][x+xStart] = *MapData[ySize-y-1][x];
                    LevelMap->MapData[y+yStart][x+xStart].FlipY();
                }
            }
        }
        TakeSection();
    }
}

void SelRect::SwapPriority() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    MapData[y][x]->SwapPriority();
                }
            }
        }
        AssignSection();
    }
}

void SelRect::IncrID() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    if (MapData[y][x]->tileID == 0 && GfxStuff->GetTileOffset() != 0) MapData[y][x]->tileID = GfxStuff->GetTileOffset();
                    else if (MapData[y][x]->tileID + 1 < GfxStuff->GetTileAmount() + GfxStuff->GetTileOffset())
                        ++MapData[y][x]->tileID;
                }
            }
        }
        AssignSection();
    }
}

void SelRect::DecrID() {
    if (isActive()) {
        for (int y=0; y < ySize; ++y) {
            for (int x=0; x < xSize; ++x) {
                if ((x+xStart < LevelMap->xSize) && (y+yStart < LevelMap->ySize)) {
                    if (MapData[y][x]->tileID > GfxStuff->GetTileOffset()) --MapData[y][x]->tileID;
                    else MapData[y][x]->tileID = 0;
                }
            }
        }
        AssignSection();
    }
}
<|endoftext|>


<commit_before><commit_msg>Added -infer functionality.  Cleaned up flag descriptions.<commit_after><|endoftext|>


<commit_before>#pragma once

#include <iterator>
#include <stdexcept>
#include <limits>
#include <functional>

#include "acmacs-base/throw.hh"
#include "acmacs-base/stream.hh"

// ----------------------------------------------------------------------

namespace _acmacs_base_internal
{
    template <typename T, typename Increment> class input_iterator : public std::iterator<std::input_iterator_tag, T>
    {
     public:
        constexpr static const T End{std::numeric_limits<T>::max()};

        inline input_iterator() : current(End) {}
        inline input_iterator(T aFirst, const Increment& aIncrement) : current(aFirst), increment(aIncrement) { increment.find_valid(current); }
        inline input_iterator(T aFirst, Increment&& aIncrement) : current(aFirst), increment(std::move(aIncrement)) { increment.find_valid(current); }

        inline input_iterator& operator++() { increment(current); return *this;}
          // inline input_iterator operator++(int) { input_iterator result = *this; ++(*this); return result; }
        inline bool operator==(const input_iterator& other) const { return current == other.current; }
        inline bool operator!=(const input_iterator& other) const { return !(*this == other); }
        inline const T& operator*() const { return current; }
        inline T& operator*() { return current; }

     private:
        T current;
        Increment increment;

    }; // input_iterator<>

} // namespace _acmacs_base_internal

// ----------------------------------------------------------------------

// template <typename T> class Range
// {
//  private:
//     class increment
//     {
//      public:
//         inline increment() {}
//         inline increment(T aStep, T aLast) : step(aStep), last(aLast) { if (step == T{0}) THROW_OR_VOID(std::runtime_error("Invalid range with step 0")); }
//         inline void operator()(T& current)
//             {
//                 if (current != _acmacs_base_internal::input_iterator<T, increment>::End) {
//                     current += step;
//                     if (step > 0) {
//                         if (current >= last)
//                             current = _acmacs_base_internal::input_iterator<T, increment>::End;
//                     }
//                     else {
//                         if (current <= last)
//                             current = _acmacs_base_internal::input_iterator<T, increment>::End;
//                     }
//                 }
//             }

//         inline void find_valid(T&) {}

//      private:
//         T step;
//         T last;
//     };

//     class iterator : public _acmacs_base_internal::input_iterator<T, increment>
//     {
//      public:
//         inline iterator() : _acmacs_base_internal::input_iterator<T, increment>() {}
//         inline iterator(T aFirst, T aLast, T aStep) : _acmacs_base_internal::input_iterator<T, increment>(aFirst, {aStep, aLast}) {}
//     };

//  public:
//     static inline iterator begin(T first, T last, T step = T{1})
//         {
//             return {first, last, step};
//         }

//     static inline iterator begin(T last)
//         {
//             return {T{0}, last, T{1}};
//         }

//     static inline iterator end()
//         {
//             return {};
//         }

// }; // class Range

// ----------------------------------------------------------------------

class IndexGenerator
{
 public:
    using Validator = std::function<bool (size_t)>;

 private:
    class increment
    {
     public:
        inline increment() {}
        inline increment(size_t aLast, Validator aValidator) : last(aLast), valid(aValidator) {}
        inline bool end(size_t current) const { return current == _acmacs_base_internal::input_iterator<size_t, increment>::End; }
        inline size_t end() const { return _acmacs_base_internal::input_iterator<size_t, increment>::End; }

        inline void operator()(size_t& current)
            {
                if (!end(current)) {
                    ++current;
                    while (current < last && !valid(current))
                        ++current;
                    if (current >= last)
                        current = end();
                }
            }

        inline void find_valid(size_t& current)
            {
                while (!end(current) && !valid(current))
                    operator()(current);
            }

        size_t last;
        Validator valid;
    };

 public:
    inline IndexGenerator(size_t aFirst, size_t aLast, Validator aValidator) : mFirst(aFirst), mIncrement(aLast, aValidator) {}
    inline IndexGenerator(size_t aLast, Validator aValidator) : mFirst(0), mIncrement(aLast, aValidator) {}

    using iterator = _acmacs_base_internal::input_iterator<size_t, IndexGenerator::increment>;

    inline iterator begin() const { return {mFirst, mIncrement}; }
    inline iterator end() const { return {}; }

 private:
    size_t mFirst;
    increment mIncrement;

}; // class IndexGenerator

#ifdef ACMACS_TARGET_OS
inline std::ostream& operator << (std::ostream& out, const IndexGenerator& aGen)
{
    return stream_internal::write_to_stream(out, aGen, "<", ">", ", ");
}
#endif

// ----------------------------------------------------------------------

template <typename Index> class incrementer
{
 public:
    class iterator
    {
     public:
        using difference_type = long;
        using value_type = Index;
        using pointer = Index*;
        using reference = Index&;
        using iterator_category = std::random_access_iterator_tag;

        inline iterator& operator++() { ++value; return *this;}
        inline iterator operator++(int) { iterator retval = *this; ++(*this); return retval;}
        inline bool operator==(iterator other) const { return value == other.value; }
        inline bool operator!=(iterator other) const { return !(*this == other); }
        inline value_type operator*() { return value; }
        inline difference_type operator-(iterator other) const { return static_cast<difference_type>(value) - static_cast<difference_type>(other.value); }

     private:
        value_type value;
        inline iterator(value_type aValue) : value(aValue) {}

        friend class incrementer<Index>;
    };

    inline incrementer(Index aBegin, Index aEnd) : mBegin{aBegin}, mEnd{aEnd} {}

    static inline iterator begin(Index aValue) { return iterator(aValue); }
    static inline iterator end(Index aValue) { return iterator(aValue); }

    inline iterator begin() { return begin(mBegin); }
    inline iterator end() { return end(mBegin); }

 private:
    Index mBegin, mEnd;

}; // class incrementer<>

template <typename Index> inline void fill_with_indexes(std::vector<Index>& aToFill, Index aBegin, Index aEnd)
{
    aToFill.resize(aEnd - aBegin);
    std::copy(incrementer<Index>::begin(aBegin), incrementer<Index>::end(aEnd), aToFill.begin());
}

template <typename Index> inline void fill_with_indexes(std::vector<Index>& aToFill, Index aSize)
{
    aToFill.resize(aSize);
    std::copy(incrementer<Index>::begin(0), incrementer<Index>::end(aSize), aToFill.begin());
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>filled_with_indexes<commit_after>#pragma once

#include <iterator>
#include <stdexcept>
#include <limits>
#include <functional>

#include "acmacs-base/throw.hh"
#include "acmacs-base/stream.hh"

// ----------------------------------------------------------------------

namespace _acmacs_base_internal
{
    template <typename T, typename Increment> class input_iterator : public std::iterator<std::input_iterator_tag, T>
    {
     public:
        constexpr static const T End{std::numeric_limits<T>::max()};

        inline input_iterator() : current(End) {}
        inline input_iterator(T aFirst, const Increment& aIncrement) : current(aFirst), increment(aIncrement) { increment.find_valid(current); }
        inline input_iterator(T aFirst, Increment&& aIncrement) : current(aFirst), increment(std::move(aIncrement)) { increment.find_valid(current); }

        inline input_iterator& operator++() { increment(current); return *this;}
          // inline input_iterator operator++(int) { input_iterator result = *this; ++(*this); return result; }
        inline bool operator==(const input_iterator& other) const { return current == other.current; }
        inline bool operator!=(const input_iterator& other) const { return !(*this == other); }
        inline const T& operator*() const { return current; }
        inline T& operator*() { return current; }

     private:
        T current;
        Increment increment;

    }; // input_iterator<>

} // namespace _acmacs_base_internal

// ----------------------------------------------------------------------

// template <typename T> class Range
// {
//  private:
//     class increment
//     {
//      public:
//         inline increment() {}
//         inline increment(T aStep, T aLast) : step(aStep), last(aLast) { if (step == T{0}) THROW_OR_VOID(std::runtime_error("Invalid range with step 0")); }
//         inline void operator()(T& current)
//             {
//                 if (current != _acmacs_base_internal::input_iterator<T, increment>::End) {
//                     current += step;
//                     if (step > 0) {
//                         if (current >= last)
//                             current = _acmacs_base_internal::input_iterator<T, increment>::End;
//                     }
//                     else {
//                         if (current <= last)
//                             current = _acmacs_base_internal::input_iterator<T, increment>::End;
//                     }
//                 }
//             }

//         inline void find_valid(T&) {}

//      private:
//         T step;
//         T last;
//     };

//     class iterator : public _acmacs_base_internal::input_iterator<T, increment>
//     {
//      public:
//         inline iterator() : _acmacs_base_internal::input_iterator<T, increment>() {}
//         inline iterator(T aFirst, T aLast, T aStep) : _acmacs_base_internal::input_iterator<T, increment>(aFirst, {aStep, aLast}) {}
//     };

//  public:
//     static inline iterator begin(T first, T last, T step = T{1})
//         {
//             return {first, last, step};
//         }

//     static inline iterator begin(T last)
//         {
//             return {T{0}, last, T{1}};
//         }

//     static inline iterator end()
//         {
//             return {};
//         }

// }; // class Range

// ----------------------------------------------------------------------

class IndexGenerator
{
 public:
    using Validator = std::function<bool (size_t)>;

 private:
    class increment
    {
     public:
        inline increment() {}
        inline increment(size_t aLast, Validator aValidator) : last(aLast), valid(aValidator) {}
        inline bool end(size_t current) const { return current == _acmacs_base_internal::input_iterator<size_t, increment>::End; }
        inline size_t end() const { return _acmacs_base_internal::input_iterator<size_t, increment>::End; }

        inline void operator()(size_t& current)
            {
                if (!end(current)) {
                    ++current;
                    while (current < last && !valid(current))
                        ++current;
                    if (current >= last)
                        current = end();
                }
            }

        inline void find_valid(size_t& current)
            {
                while (!end(current) && !valid(current))
                    operator()(current);
            }

        size_t last;
        Validator valid;
    };

 public:
    inline IndexGenerator(size_t aFirst, size_t aLast, Validator aValidator) : mFirst(aFirst), mIncrement(aLast, aValidator) {}
    inline IndexGenerator(size_t aLast, Validator aValidator) : mFirst(0), mIncrement(aLast, aValidator) {}

    using iterator = _acmacs_base_internal::input_iterator<size_t, IndexGenerator::increment>;

    inline iterator begin() const { return {mFirst, mIncrement}; }
    inline iterator end() const { return {}; }

 private:
    size_t mFirst;
    increment mIncrement;

}; // class IndexGenerator

#ifdef ACMACS_TARGET_OS
inline std::ostream& operator << (std::ostream& out, const IndexGenerator& aGen)
{
    return stream_internal::write_to_stream(out, aGen, "<", ">", ", ");
}
#endif

// ----------------------------------------------------------------------

template <typename Index> class incrementer
{
 public:
    class iterator
    {
     public:
        using difference_type = long;
        using value_type = Index;
        using pointer = Index*;
        using reference = Index&;
        using iterator_category = std::random_access_iterator_tag;

        inline iterator& operator++() { ++value; return *this;}
        inline iterator operator++(int) { iterator retval = *this; ++(*this); return retval;}
        inline bool operator==(iterator other) const { return value == other.value; }
        inline bool operator!=(iterator other) const { return !(*this == other); }
        inline value_type operator*() { return value; }
        inline difference_type operator-(iterator other) const { return static_cast<difference_type>(value) - static_cast<difference_type>(other.value); }

     private:
        value_type value;
        inline iterator(value_type aValue) : value(aValue) {}

        friend class incrementer<Index>;
    };

    inline incrementer(Index aBegin, Index aEnd) : mBegin{aBegin}, mEnd{aEnd} {}

    static inline iterator begin(Index aValue) { return iterator(aValue); }
    static inline iterator end(Index aValue) { return iterator(aValue); }

    inline iterator begin() { return begin(mBegin); }
    inline iterator end() { return end(mBegin); }

 private:
    Index mBegin, mEnd;

}; // class incrementer<>

template <typename Index> inline void fill_with_indexes(std::vector<Index>& aToFill, Index aBegin, Index aEnd)
{
    aToFill.resize(aEnd - aBegin);
    std::copy(incrementer<Index>::begin(aBegin), incrementer<Index>::end(aEnd), aToFill.begin());
}

template <typename Index> inline void fill_with_indexes(std::vector<Index>& aToFill, Index aSize)
{
    aToFill.resize(aSize);
    std::copy(incrementer<Index>::begin(0), incrementer<Index>::end(aSize), aToFill.begin());
}

template <typename Index> inline std::vector<Index> filled_with_indexes(Index aSize)
{
    std::vector<Index> result(aSize);
    std::copy(incrementer<Index>::begin(0), incrementer<Index>::end(aSize), result.begin());
    return result;
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>
#include <boost/program_options.hpp>
#include <omp.h>

#include "tools.hpp"
#include "density_clustering.hpp"
#include "mpp.hpp"
#include "logger.hpp"

int main(int argc, char* argv[]) {
  namespace b_po = boost::program_options;
  using namespace Clustering::Density;
  b_po::variables_map args;
  // density options
  b_po::options_description desc_dens (std::string(argv[0]).append(
    "\n\n"
    "perform clustering of MD data based on phase space densities.\n"
    "densities are approximated by counting neighboring frames inside\n"
    "a n-dimensional hypersphere of specified radius.\n"
    "distances are measured with n-dim P2-norm.\n"
    "\n"
    "options"));
  desc_dens.add_options()
    ("help,h", b_po::bool_switch()->default_value(false), "show this help.")
    ("file,f", b_po::value<std::string>(), "input (required): phase space coordinates (space separated ASCII).")
    ("radius,r", b_po::value<float>(), "parameter (required): hypersphere radius.")
    // optional
    ("threshold,t", b_po::value<float>(), "parameter: Free Energy threshold for clustering (FEL is normalized to zero).")
    ("output,o", b_po::value<std::string>(), "output (optional): clustering information.")
    ("input,i", b_po::value<std::string>(), "input (optional): initial state definition.")
    ("population,p", b_po::value<std::string>(), "output (optional): population per frame.")
    ("free-energy,d", b_po::value<std::string>(), "output (optional): free energies per frame.")
    ("free-energy-input,D", b_po::value<std::string>(), "input (optional): reuse free energy info.")
    ("nearest-neighbors,b", b_po::value<std::string>(), "output (optional): nearest neighbor info.")
    ("nearest-neighbors-input,B", b_po::value<std::string>(), "input (optional): reuse nearest neighbor info.")
    // defaults
    ("only-initial,I", b_po::bool_switch()->default_value(false),
                      "only assign initial (i.e. low free energy / high density) frames to clusters. "
                      "leave unclustered frames as state '0'.")
    ("nthreads,n", b_po::value<int>()->default_value(0),
                      "number of OpenMP threads. default: 0; i.e. use OMP_NUM_THREADS env-variable.")
    ("verbose,v", b_po::bool_switch()->default_value(false), "verbose mode: print runtime information to STDOUT.")
  ;
  // MPP options
  b_po::options_description desc_mpp (std::string(argv[1]).append(
    "\n\n"
    "TODO: description for MPP"
    "\n"
    "options"));
  desc_mpp.add_options()
    ("help,h", b_po::bool_switch()->default_value(false), "show this help.")
    ("qmin-from", b_po::value<float>()->default_value(0.01), "initial Qmin value (default: 0.01).")
    ("qmin-to", b_po::value<float>()->default_value(1.0), "final Qmin value (default: 1.0).")
    ("qmin-step", b_po::value<float>()->default_value(0.01), "Qmin stepping (default: 0.01).")
    ("lagtime", b_po::value<std::size_t>(), "lagtime (in units of frame numbers).")
  ;
  // parse cmd arguments
  try {
    b_po::store(b_po::command_line_parser(argc, argv).options(desc_dens).run(), args);
    b_po::notify(args);
  } catch (b_po::error& e) {
    if ( ! args["help"].as<bool>()) {
      std::cout << "\n" << e.what() << "\n\n" << std::endl;
    }
    std::cout << desc_dens << std::endl;
    return EXIT_FAILURE;
  }
  if (args["help"].as<bool>()) {
    std::cout << desc_dens << std::endl;
    return EXIT_SUCCESS;
  }
  // setup general flags / options
  verbose = args["verbose"].as<bool>();
  const std::string input_file = args["file"].as<std::string>();
  const float radius = args["radius"].as<float>();
  // setup OpenMP
  const int n_threads = args["nthreads"].as<int>();
  if (n_threads > 0) {
    omp_set_num_threads(n_threads);
  }
  // setup coords
  float* coords;
  std::size_t n_rows;
  std::size_t n_cols;
  logger(std::cout) << "reading coords" << std::endl;
  std::tie(coords, n_rows, n_cols) = read_coords<float>(input_file);
  #ifdef DC_USE_OPENCL
  DC_OpenCL::setup(coords, n_rows, n_cols);
  #endif
  //// free energies
  std::vector<float> free_energies;
  if (args.count("free-energy-input")) {
    logger(std::cout) << "re-using free energy data." << std::endl;
    std::ifstream ifs(args["free-energy-input"].as<std::string>());
    if (ifs.fail()) {
      std::cerr << "error: cannot open file '" << args["free-energy-input"].as<std::string>() << "'" << std::endl;
      exit(EXIT_FAILURE);
    } else {
      while(ifs.good()) {
        float buf;
        ifs >> buf;
        if ( ! ifs.fail()) {
          free_energies.push_back(buf);
        }
      }
    }
  } else if (args.count("free-energy") || args.count("output")) {
    logger(std::cout) << "calculating free energies" << std::endl;
    #ifdef DC_USE_OPENCL
    free_energies = calculate_free_energies(
                      DC_OpenCL::calculate_populations(radius));
    #else
    free_energies = calculate_free_energies(
                      calculate_populations(coords, n_rows, n_cols, radius));
    #endif
    if (args.count("free-energy")) {
      std::ofstream ofs(args["free-energy"].as<std::string>());
      ofs << std::scientific;
      for (float f: free_energies) {
        ofs << f << "\n";
      }
    }
  }
  //// nearest neighbors
  Neighborhood nh;
  Neighborhood nh_high_dens;
  if (args.count("nearest-neighbors-input")) {
    logger(std::cout) << "re-using nearest neighbor data." << std::endl;
    std::ifstream ifs(args["nearest-neighbors-input"].as<std::string>());
    if (ifs.fail()) {
      std::cerr << "error: cannot open file '" << args["nearest-neighbors-input"].as<std::string>() << "'" << std::endl;
      exit(EXIT_FAILURE);
    } else {
      std::size_t i=0;
      while (ifs.good()) {
        std::size_t buf1;
        float buf2;
        std::size_t buf3;
        float buf4;
        ifs >> buf1;
        ifs >> buf2;
        ifs >> buf3;
        ifs >> buf4;
        if ( ! ifs.fail()) {
          nh[i] = std::pair<std::size_t, float>(buf1, buf2);
          nh_high_dens[i] = std::pair<std::size_t, float>(buf3, buf4);
          ++i;
        }
      }
    }
  } else if (args.count("nearest-neighbors") || args.count("output")) {
    logger(std::cout) << "calculating nearest neighbors" << std::endl;
    auto nh_tuple = nearest_neighbors(coords, n_rows, n_cols, free_energies);
    nh = std::get<0>(nh_tuple);
    nh_high_dens = std::get<1>(nh_tuple);
    if (args.count("nearest-neighbors")) {
      std::ofstream ofs(args["nearest-neighbors"].as<std::string>());
      auto p = nh.begin();
      auto p_hd = nh_high_dens.begin();
      while (p != nh.end() && p_hd != nh_high_dens.end()) {
        // first: key (not used)
        // second: neighbor
        // second.first: id; second.second: squared dist
        ofs << p->second.first    << " " << p->second.second    << " "
            << p_hd->second.first << " " << p_hd->second.second << "\n";
        ++p;
        ++p_hd;
      }
    }
  }
  //// clustering
  if (args.count("output")) {
    const std::string output_file = args["output"].as<std::string>();
    std::vector<std::size_t> clustering;
    if (args.count("input")) {
      logger(std::cout) << "reading initial clusters from file." << std::endl;
      std::ifstream ifs(args["input"].as<std::string>());
      if (ifs.fail()) {
        std::cerr << "error: cannot open file '" << args["input"].as<std::string>() << "'" << std::endl;
        exit(EXIT_FAILURE);
      } else {
        while (ifs.good()) {
          std::size_t buf;
          ifs >> buf;
          if ( ! ifs.fail()) {
            clustering.push_back(buf);
          }
        }
      }
    } else {
      logger(std::cout) << "calculating initial clusters" << std::endl;
      if (args.count("threshold") == 0) {
        std::cerr << "error: need threshold value for initial clustering" << std::endl;
        exit(EXIT_FAILURE);
      }
      float threshold = args["threshold"].as<float>();
      clustering = initial_density_clustering(free_energies, nh, threshold, coords, n_rows, n_cols);
    }
    if ( ! args["only-initial"].as<bool>()) {
      logger(std::cout) << "assigning low density states to initial clusters" << std::endl;
      clustering = assign_low_density_frames(clustering, nh_high_dens, free_energies);
    }
    // write clusters to file
    {
      logger(std::cout) << "writing clusters to file " << output_file << std::endl;
      std::ofstream ofs(output_file);
      if (ofs.fail()) {
        std::cerr << "error: cannot open file '" << output_file << "' for writing." << std::endl;
        exit(EXIT_FAILURE);
      }
      for (std::size_t i: clustering) {
        ofs << i << "\n";
      }
    }
  }
  logger(std::cout) << "freeing coords" << std::endl;
  free_coords(coords);
  return EXIT_SUCCESS;
}

<commit_msg>new menu structure<commit_after>
#include <boost/program_options.hpp>
#include <omp.h>

#include "tools.hpp"
#include "density_clustering.hpp"
#include "mpp.hpp"
#include "logger.hpp"

int main(int argc, char* argv[]) {
  namespace b_po = boost::program_options;
  using namespace Clustering::Density;
  std::string general_help =
    "clustering - a classification framework for MD data\n"
    "\n"
    "modes:\n"
    "  density: run density clustering\n"
    "  mpp:     run MPP (Most Probable Path) clustering\n"
    "           (based on density-results)\n"
    "\n"
    "usage:\n"
    "  clustering MODE --option1 --option2 ...\n"
    "\n"
    "for a list of available options per mode, run with '-h' option, e.g.\n"
    "  clustering density -h\n"
  ;
  enum {DENSITY, MPP} mode;
  if (argc <= 2) {
    std::cerr << general_help;
    return EXIT_FAILURE;
  } else {
    std::string str_mode(argv[1]);
    if (str_mode.compare("density") == 0) {
      mode = DENSITY;
    } else if (str_mode.compare("mpp") == 0) {
      mode = MPP;
    } else {
      std::cerr << "\nerror: unrecognized mode '" << str_mode << "'\n\n";
      std::cerr << general_help;
      return EXIT_FAILURE;
    }
  }
  b_po::variables_map args;
  // density options
  b_po::options_description desc_dens (std::string(argv[1]).append(
    "\n\n"
    "perform clustering of MD data based on phase space densities.\n"
    "densities are approximated by counting neighboring frames inside\n"
    "a n-dimensional hypersphere of specified radius.\n"
    "distances are measured with n-dim P2-norm.\n"
    "\n"
    "options"));
  desc_dens.add_options()
    ("help,h", b_po::bool_switch()->default_value(false), "show this help.")
    ("file,f", b_po::value<std::string>(), "input (required): phase space coordinates (space separated ASCII).")
    ("radius,r", b_po::value<float>(), "parameter (required): hypersphere radius.")
    // optional
    ("threshold,t", b_po::value<float>(), "parameter: Free Energy threshold for clustering (FEL is normalized to zero).")
    ("output,o", b_po::value<std::string>(), "output (optional): clustering information.")
    ("input,i", b_po::value<std::string>(), "input (optional): initial state definition.")
    ("population,p", b_po::value<std::string>(), "output (optional): population per frame.")
    ("free-energy,d", b_po::value<std::string>(), "output (optional): free energies per frame.")
    ("free-energy-input,D", b_po::value<std::string>(), "input (optional): reuse free energy info.")
    ("nearest-neighbors,b", b_po::value<std::string>(), "output (optional): nearest neighbor info.")
    ("nearest-neighbors-input,B", b_po::value<std::string>(), "input (optional): reuse nearest neighbor info.")
    // defaults
    ("only-initial,I", b_po::bool_switch()->default_value(false),
                      "only assign initial (i.e. low free energy / high density) frames to clusters. "
                      "leave unclustered frames as state '0'.")
    ("nthreads,n", b_po::value<int>()->default_value(0),
                      "number of OpenMP threads. default: 0; i.e. use OMP_NUM_THREADS env-variable.")
    ("verbose,v", b_po::bool_switch()->default_value(false), "verbose mode: print runtime information to STDOUT.")
  ;
  // MPP options
  b_po::options_description desc_mpp (std::string(argv[1]).append(
    "\n\n"
    "TODO: description for MPP"
    "\n"
    "options"));
  desc_mpp.add_options()
    ("help,h", b_po::bool_switch()->default_value(false), "show this help.")
    ("qmin-from", b_po::value<float>()->default_value(0.01, "0.01"), "initial Qmin value (default: 0.01).")
    ("qmin-to", b_po::value<float>()->default_value(1.0, "1.00"), "final Qmin value (default: 1.00).")
    ("qmin-step", b_po::value<float>()->default_value(0.01, "0.01"), "Qmin stepping (default: 0.01).")
    ("lagtime", b_po::value<std::size_t>(), "lagtime (in units of frame numbers).")
  ;
  // parse cmd arguments
  b_po::options_description desc;
  if (mode == DENSITY) {
    desc.add(desc_dens);
  } else {
    desc.add(desc_mpp);
  }
  try {
    b_po::store(b_po::command_line_parser(argc, argv).options(desc).run(), args);
    b_po::notify(args);
  } catch (b_po::error& e) {
    if ( ! args["help"].as<bool>()) {
      std::cout << "\n" << e.what() << "\n\n" << std::endl;
    }
    std::cout << desc << std::endl;
    return EXIT_FAILURE;
  }
  if (args["help"].as<bool>()) {
    std::cout << desc << std::endl;
    return EXIT_SUCCESS;
  }
  // setup general flags / options
  verbose = args["verbose"].as<bool>();
  const std::string input_file = args["file"].as<std::string>();
  const float radius = args["radius"].as<float>();
  // setup OpenMP
  const int n_threads = args["nthreads"].as<int>();
  if (n_threads > 0) {
    omp_set_num_threads(n_threads);
  }
  // setup coords
  float* coords;
  std::size_t n_rows;
  std::size_t n_cols;
  logger(std::cout) << "reading coords" << std::endl;
  std::tie(coords, n_rows, n_cols) = read_coords<float>(input_file);
  #ifdef DC_USE_OPENCL
  DC_OpenCL::setup(coords, n_rows, n_cols);
  #endif
  //// free energies
  std::vector<float> free_energies;
  if (args.count("free-energy-input")) {
    logger(std::cout) << "re-using free energy data." << std::endl;
    std::ifstream ifs(args["free-energy-input"].as<std::string>());
    if (ifs.fail()) {
      std::cerr << "error: cannot open file '" << args["free-energy-input"].as<std::string>() << "'" << std::endl;
      exit(EXIT_FAILURE);
    } else {
      while(ifs.good()) {
        float buf;
        ifs >> buf;
        if ( ! ifs.fail()) {
          free_energies.push_back(buf);
        }
      }
    }
  } else if (args.count("free-energy") || args.count("output")) {
    logger(std::cout) << "calculating free energies" << std::endl;
    #ifdef DC_USE_OPENCL
    free_energies = calculate_free_energies(
                      DC_OpenCL::calculate_populations(radius));
    #else
    free_energies = calculate_free_energies(
                      calculate_populations(coords, n_rows, n_cols, radius));
    #endif
    if (args.count("free-energy")) {
      std::ofstream ofs(args["free-energy"].as<std::string>());
      ofs << std::scientific;
      for (float f: free_energies) {
        ofs << f << "\n";
      }
    }
  }
  //// nearest neighbors
  Neighborhood nh;
  Neighborhood nh_high_dens;
  if (args.count("nearest-neighbors-input")) {
    logger(std::cout) << "re-using nearest neighbor data." << std::endl;
    std::ifstream ifs(args["nearest-neighbors-input"].as<std::string>());
    if (ifs.fail()) {
      std::cerr << "error: cannot open file '" << args["nearest-neighbors-input"].as<std::string>() << "'" << std::endl;
      exit(EXIT_FAILURE);
    } else {
      std::size_t i=0;
      while (ifs.good()) {
        std::size_t buf1;
        float buf2;
        std::size_t buf3;
        float buf4;
        ifs >> buf1;
        ifs >> buf2;
        ifs >> buf3;
        ifs >> buf4;
        if ( ! ifs.fail()) {
          nh[i] = std::pair<std::size_t, float>(buf1, buf2);
          nh_high_dens[i] = std::pair<std::size_t, float>(buf3, buf4);
          ++i;
        }
      }
    }
  } else if (args.count("nearest-neighbors") || args.count("output")) {
    logger(std::cout) << "calculating nearest neighbors" << std::endl;
    auto nh_tuple = nearest_neighbors(coords, n_rows, n_cols, free_energies);
    nh = std::get<0>(nh_tuple);
    nh_high_dens = std::get<1>(nh_tuple);
    if (args.count("nearest-neighbors")) {
      std::ofstream ofs(args["nearest-neighbors"].as<std::string>());
      auto p = nh.begin();
      auto p_hd = nh_high_dens.begin();
      while (p != nh.end() && p_hd != nh_high_dens.end()) {
        // first: key (not used)
        // second: neighbor
        // second.first: id; second.second: squared dist
        ofs << p->second.first    << " " << p->second.second    << " "
            << p_hd->second.first << " " << p_hd->second.second << "\n";
        ++p;
        ++p_hd;
      }
    }
  }
  //// clustering
  if (args.count("output")) {
    const std::string output_file = args["output"].as<std::string>();
    std::vector<std::size_t> clustering;
    if (args.count("input")) {
      logger(std::cout) << "reading initial clusters from file." << std::endl;
      std::ifstream ifs(args["input"].as<std::string>());
      if (ifs.fail()) {
        std::cerr << "error: cannot open file '" << args["input"].as<std::string>() << "'" << std::endl;
        exit(EXIT_FAILURE);
      } else {
        while (ifs.good()) {
          std::size_t buf;
          ifs >> buf;
          if ( ! ifs.fail()) {
            clustering.push_back(buf);
          }
        }
      }
    } else {
      logger(std::cout) << "calculating initial clusters" << std::endl;
      if (args.count("threshold") == 0) {
        std::cerr << "error: need threshold value for initial clustering" << std::endl;
        exit(EXIT_FAILURE);
      }
      float threshold = args["threshold"].as<float>();
      clustering = initial_density_clustering(free_energies, nh, threshold, coords, n_rows, n_cols);
    }
    if ( ! args["only-initial"].as<bool>()) {
      logger(std::cout) << "assigning low density states to initial clusters" << std::endl;
      clustering = assign_low_density_frames(clustering, nh_high_dens, free_energies);
    }
    // write clusters to file
    {
      logger(std::cout) << "writing clusters to file " << output_file << std::endl;
      std::ofstream ofs(output_file);
      if (ofs.fail()) {
        std::cerr << "error: cannot open file '" << output_file << "' for writing." << std::endl;
        exit(EXIT_FAILURE);
      }
      for (std::size_t i: clustering) {
        ofs << i << "\n";
      }
    }
  }
  logger(std::cout) << "freeing coords" << std::endl;
  free_coords(coords);
  return EXIT_SUCCESS;
}

<|endoftext|>