/*!
\file table.h
\brief Extension of ublas::matrix to store labels
\author Martin Peters
$Date: 2010/03/29 20:35:21 $
$Revision: 1.9 $
----------------------------------------------------------------------------
MTK++ - C++ package of modeling libraries.
Copyright (C) 2005-2006 (see AUTHORS file for a list of contributors)
This file is part of MTK++.
MTK++ 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 3 of the License, or
(at your option) any later version.
MTK++ 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 Lessser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
----------------------------------------------------------------------------
*/
#ifndef TABLE_H
#define TABLE_H
#include
#include
#include
#include
#include
#include
#include
#include
#include "Diagnostics/MTKException.h"
#include
using namespace Eigen;
namespace MTKpp
{
// ============================================================
// Class : table()
// ------------------------------------------------------------
/*!
\class table
\brief Extension of eigen::matrix to store labels
\author Martin Peters
\date 2007
*/
// ============================================================
template class table
{
public:
/*!
\brief table Constructor
*/
table() {
this->itsName = "";
this->nColumns = 0;
this->nRows = 0;
}
//! table Destructor
virtual ~table() {}
/*!
\brief Set the name of the table
\param n table name
*/
void setName(std::string n) {
this->itsName = n;
}
/*!
\brief Get the name of the table
\return table name
*/
std::string getName() {
return this->itsName;
}
/*!
\brief Set the type of the table
\param n table name
*/
void setType(std::string n) {
this->itsType = n;
}
/*!
\brief Get the type of the table
\return table name
*/
std::string getType() {
return this->itsType;
}
/*!
\brief Set the number of columns in the table
\param i number of columns
*/
void setNumColumns(const int& i) {
this->nColumns = i;
}
/*!
\brief Get the number of columns in the table
\return number of columns
*/
int getNumColumns() {
return this->nColumns;
}
/*!
\brief Set a column label in the table
\param i column index
\param s label
*/
void setColumnLabel(const int& i, std::string s) {
if (i > this->nColumns-1) {
std::stringstream ss;
ss << " Out of bounds error: i = " << i+1
<< " > " << this->nColumns << std::endl;
std::cout << ss.str();
throw MTKException(ss.str());
}
this->columnLabels[i] = s;
}
/*!
\brief Set column labels
\param v column labels
*/
void setColumnLabels(std::vector v) {
if (v.size() >= this->columnLabels.size()) {
for (unsigned int i = 0; i < columnLabels.size(); i++) {
this->columnLabels[i] = v[i];
}
}
}
/*!
\brief Get column label
\param i column index
\return column label
*/
std::string getColumnLabel(const int& i) {
if (i < static_cast(this->columnLabels.size())) {
return this->columnLabels[i];
}
return "";
}
/*!
\brief Get column labels
\return column labels
*/
std::vector getColumnLabels() {
return this->columnLabels;
}
/*!
\brief Set row labels
\param v row labels
*/
void setRowLabels(std::vector v) {
if (v.size() == this->rowLabels.size()) {
for (unsigned int i = 0; i < v.size(); i++) {
this->rowLabels[i] = v[i];
}
}
}
/*!
\brief Get row label
\param i row index
\return row labels
*/
std::string getRowLabel(const int& i) {
if (i < static_cast(this->rowLabels.size())) {
return this->rowLabels[i];
}
return "";
}
/*!
\brief Get row labels
\return row labels
*/
std::vector getRowLabels() {
return this->rowLabels;
}
/*!
\brief Set the number of rows in the table
\param i number of rows
*/
void setNumRows(const int& i) {
this->nRows = i;
}
/*!
\brief Get the number of rows in the table
\return number of rows
*/
int getNumRows() {
return this->nRows;
}
/*!
\brief Set a row label in the table
\param i row index
\param s label
*/
void setRowLabel(const int& i, std::string s) {
if (i > this->nRows-1) {
std::stringstream ss;
ss << " Out of bounds error: i = " << i+1
<< " > " << this->nRows << std::endl;
std::cout << ss.str();
throw MTKException(ss.str());
}
this->rowLabels[i] = s;
}
/*!
\brief Set the number of columns and rows in the table
\param i number of rows
\param j number of columns
*/
void setSizes(const int& i, const int& j) {
this->nRows = i;
this->nColumns = j;
this->setSize(i, j);
}
/*!
\brief table setup
*/
void setup() {
if (this->nColumns > 0 and this->nRows > 0) {
this->setSize(this->nRows, this->nColumns);
}
else {
std::cout << " ERROR " << std::endl;
throw MTKException(" table::setup ERROR ");
}
}
/*!
\brief Set the value of a cell in the table
\param i row index
\param j column index
\param v cell value
*/
void setCellValue(const int& i, const int& j, T v) {
if ((i > this->nRows-1) or (j > this->nColumns-1)) {
std::stringstream ss;
ss << " Out of bounds error: i = " << i << " j = " << j << " value = " << v
<< " " << this->nRows << " " << this->nColumns << std::endl;
std::cout << ss.str();
throw MTKException(ss.str());
}
else {
this->itsMatrix(i,j) = v;
}
}
/*!
\brief Get the value of a cell in the table
\param i row index
\param j column index
\return cell value
*/
T getCellValue(const int& i, const int& j) {
if ((i > this->nRows-1) or (j > this->nColumns-1)) {
std::stringstream ss;
ss << " Out of bounds error: i = " << i << " j = " << j
<< " " << this->nRows << " " << this->nColumns << std::endl;
std::cout << ss.str();
throw MTKException(ss.str());
}
else {
return this->itsMatrix(i,j);
}
return 0;
}
/*!
\brief Print table to the screen
*/
void print() {
std::cout << " \n " << this->getName() << std::endl;
std::cout << "- ";
for (unsigned j = 0; j < this->itsMatrix.cols(); ++ j) {
std::cout << this->columnLabels[j] << " ";
}
std::cout << " " << std::endl;
for (unsigned i = 0; i < this->itsMatrix.rows(); ++ i) {
std::cout << this->rowLabels[i] << " ";
for (unsigned j = 0; j < this->itsMatrix.cols(); ++ j) {
std::cout << std::showpoint << this->itsMatrix(i,j) << " ";
}
std::cout << " " << std::endl;
}
}
/*!
\brief Print row of table to the screen
*/
void printRow(const int& r) {
for (unsigned j = 0; j < this->itsMatrix.cols(); ++ j) {
std::cout << this->columnLabels[j] << " ";
}
std::cout << " " << std::endl;
if (r > static_cast(this->itsMatrix.rows())) {
std::cout << " Error in table " << std::endl;
}
std::cout << this->rowLabels[r] << " ";
for (unsigned j = 0; j < this->itsMatrix.cols(); ++ j) {
std::cout << std::showpoint << this->itsMatrix(r,j) << " ";
}
std::cout << " " << std::endl;
}
/*!
\brief Print table matrix to the screen
*/
void printMatrix() {
for (unsigned i = 0; i < this->itsMatrix.rows(); ++ i) {
for (unsigned j = 0; j < this->itsMatrix.cols(); ++ j) {
std::cout << std::showpoint << this->itsMatrix(i,j) << " ";
}
std::cout << " " << std::endl;
}
}
/*!
\brief Get the matrix of type M which the table stores
*/
Eigen::Matrix& getMatrix() {
return this->itsMatrix;
}
/*!
\brief Print table matrix to the screen
\param j column to be sorted
\param order Ascending = 0, Desending = 1
*/
void sortByColumn(int j, int order) {
Eigen::Matrix bkupMatrix;
bkupMatrix.resize(this->nRows, this->nColumns);
for (unsigned i = 0; i < this->itsMatrix.rows(); ++i) {
for (unsigned k = 0; k < this->itsMatrix.cols(); ++k) {
bkupMatrix(i,k) = this->itsMatrix(i,k);
}
}
int size = nRows;
//int size2 = nColumns;
// Eigen::Vector column;
// Eigen::Vector columnIndices;
Eigen::Matrix column;
Eigen::Matrix columnIndices;
column.resize(size,1);
columnIndices.resize(size, 1);
int k = 0;
double p = 0.0;
std::string label = "";
for (int i = 0; i < size; i++) {
column(i, 0) = itsMatrix(i,j);
columnIndices(i, 0) = i;
}
for (int i = 0; i < size; ++i) {
k = i;
p = column(i, 0);
label = rowLabels[i];
for (int j = i+1; j < size; ++j) {
if (!order) { // Ascending
if (column(j, 0) < p) {
k = j;
p = column(j, 0);
label = rowLabels[j];
}
}
else { // Descending
if (column(j,0) > p) {
k = j;
p = column(j,0);
label = rowLabels[j];
}
}
}
if ( k != i ) {
column(k,0) = column(i,0);
column(i,0) = p;
int temK = columnIndices(k,0);
columnIndices(k,0) = columnIndices(i,0);
columnIndices(i,0) = temK;
rowLabels[k] = rowLabels[i];
rowLabels[i] = label;
/*
for (int m = 0; m < size2; ++m) {
p = itsMatrix(i,m);
itsMatrix(i,m) = itsMatrix(k,m);
itsMatrix(k,m) = p;
}
*/
}
}
for (unsigned i = 0; i < this->itsMatrix.rows(); ++i) {
for (unsigned k = 0; k < this->itsMatrix.cols(); ++k) {
this->itsMatrix(i,k) = bkupMatrix(columnIndices(i,0), k);
}
}
}
/*!
\brief Initialize
*/
void initialize(double t) {
for (unsigned i = 0; i < this->itsMatrix.rows(); ++ i) {
for (unsigned j = 0; j < this->itsMatrix.cols(); ++ j) {
this->itsMatrix(i,j) = t;
}
}
}
/*!
\brief Initialize
*/
void initialize(int t) {
for (unsigned i = 0; i < this->itsMatrix.rows(); ++ i) {
for (unsigned j = 0; j < this->itsMatrix.cols(); ++ j) {
this->itsMatrix(i,j) = t;
}
}
}
/*!
\brief Initialize
*/
void initialize(std::string t) {
for (unsigned i = 0; i < this->itsMatrix.rows(); ++ i) {
for (unsigned j = 0; j < this->itsMatrix.cols(); ++ j) {
this->itsMatrix(i,j) = t;
}
}
};
protected: // Functions
/*!
\brief Set the dimensions of the table
*/
void setSize(const int& i, const int& j) {
// try {
this->itsMatrix.resize(i,j);
this->rowLabels.resize(i);
this->columnLabels.resize(j);
this->initializeAll();
/*
}
catch (boost::numeric::ublas::bad_size) {
std::cout << " ERROR IN TABLE ... EXITING " << std::endl;
throw MTKException(" ERROR IN TABLE ... EXITING ");
}
*/
}
void initializeAll() {
for (unsigned i = 0; i < this->itsMatrix.rows(); ++ i) {
this->rowLabels[i] = "";
}
for (unsigned j = 0; j < this->itsMatrix.cols(); ++ j) {
this->columnLabels[j] = "";
}
}
protected: // Data
//! Name
std::string itsName;
//! Type
std::string itsType;
//! Number of columns
int nColumns;
//! Columns labels
std::vector columnLabels;
//! Number of rows
int nRows;
//! Row labels
std::vector rowLabels;
//! matrix of type T
Eigen::Matrix itsMatrix;
};
}
#endif // TABLE_H