|
|
@ -1,10 +1,8 @@ |
|
|
|
/*! read_tra_file.cpp
|
|
|
|
* Provides functions for reading a *.tra file describing the transition |
|
|
|
* system of a Markov chain (DTMC) and saving it into a corresponding |
|
|
|
* matrix. |
|
|
|
/*!
|
|
|
|
* readTraFile.cpp |
|
|
|
* |
|
|
|
* Created on: 20.11.2012 |
|
|
|
* Author: Gereon Kremer |
|
|
|
* Created on: 20.11.2012 |
|
|
|
* Author: Gereon Kremer |
|
|
|
*/ |
|
|
|
|
|
|
|
#include "parser.h"
|
|
|
@ -30,9 +28,13 @@ |
|
|
|
#include <pantheios/inserters/real.hpp>
|
|
|
|
|
|
|
|
namespace mrmc { |
|
|
|
|
|
|
|
namespace parser{ |
|
|
|
|
|
|
|
/*!
|
|
|
|
* Skips all whitespaces and returns new pointer. |
|
|
|
* |
|
|
|
* @todo should probably be replaced by strspn et.al. |
|
|
|
*/ |
|
|
|
char* skipWS(char* buf) |
|
|
|
{ |
|
|
|
while(1) |
|
|
@ -43,20 +45,25 @@ char* skipWS(char* buf) |
|
|
|
} |
|
|
|
|
|
|
|
/*!
|
|
|
|
* This method does the first pass through the .tra file and computes |
|
|
|
* the number of non-zero elements that are not diagonal elements, |
|
|
|
* which correspondents to the number of transitions that are not |
|
|
|
* self-loops. |
|
|
|
* (Diagonal elements are treated in a special way). |
|
|
|
* @brief Perform first pass through the file and obtain number of |
|
|
|
* non-zero cells and maximum node id. |
|
|
|
* |
|
|
|
* This method does the first pass through the .tra file and computes |
|
|
|
* the number of non-zero elements that are not diagonal elements, |
|
|
|
* which correspondents to the number of transitions that are not |
|
|
|
* self-loops. |
|
|
|
* (Diagonal elements are treated in a special way). |
|
|
|
* It also calculates the maximum node id and stores it in maxnode. |
|
|
|
* |
|
|
|
* @return The number of non-zero elements that are not on the diagonal |
|
|
|
* @param buf Data to scan. Is expected to be some char array. |
|
|
|
* @return The number of non-zero elements that are not on the diagonal |
|
|
|
* @param buf Data to scan. Is expected to be some char array. |
|
|
|
* @param maxnode Is set to highest id of all nodes. |
|
|
|
*/ |
|
|
|
static uint_fast32_t makeFirstPass(char* buf, uint_fast32_t &maxnode) |
|
|
|
{ |
|
|
|
uint_fast32_t non_zero = 0; |
|
|
|
|
|
|
|
/*!
|
|
|
|
/*
|
|
|
|
* check file header and extract number of transitions |
|
|
|
*/ |
|
|
|
if (strncmp(buf, "STATES ", 7) != 0) return 0; |
|
|
@ -67,7 +74,7 @@ static uint_fast32_t makeFirstPass(char* buf, uint_fast32_t &maxnode) |
|
|
|
buf += 12; // skip "TRANSITIONS "
|
|
|
|
if ((non_zero = strtol(buf, &buf, 10)) == 0) return 0; |
|
|
|
|
|
|
|
/*!
|
|
|
|
/*
|
|
|
|
* check all transitions for non-zero diagonal entrys |
|
|
|
*/ |
|
|
|
uint_fast32_t row, col; |
|
|
@ -75,10 +82,20 @@ static uint_fast32_t makeFirstPass(char* buf, uint_fast32_t &maxnode) |
|
|
|
maxnode = 0; |
|
|
|
while (1) |
|
|
|
{ |
|
|
|
/*
|
|
|
|
* read row and column |
|
|
|
*/ |
|
|
|
row = strtol(buf, &buf, 10); |
|
|
|
if (row > maxnode) maxnode = row; |
|
|
|
col = strtol(buf, &buf, 10); |
|
|
|
/*
|
|
|
|
* check if one is larger than the current maximum id |
|
|
|
*/ |
|
|
|
if (row > maxnode) maxnode = row; |
|
|
|
if (col > maxnode) maxnode = col; |
|
|
|
/*
|
|
|
|
* read value. if value is zero, we have reached the end of the file. |
|
|
|
* if row == col, we have a diagonal element which is treated seperately and this non_zero must be decreased. |
|
|
|
*/ |
|
|
|
val = strtod(buf, &buf); |
|
|
|
if (val == 0.0) break; |
|
|
|
if (row == col) non_zero--; |
|
|
@ -89,44 +106,44 @@ static uint_fast32_t makeFirstPass(char* buf, uint_fast32_t &maxnode) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!Reads a .tra file and produces a sparse matrix representing the described Markov Chain.
|
|
|
|
/*!
|
|
|
|
* Reads a .tra file and produces a sparse matrix representing the described Markov Chain. |
|
|
|
* |
|
|
|
* Matrices created with this method have to be freed with the delete operator. |
|
|
|
* @param filename input .tra file's name. |
|
|
|
* @return a pointer to the created sparse matrix. |
|
|
|
* Matrices created with this method have to be freed with the delete operator. |
|
|
|
* @param filename input .tra file's name. |
|
|
|
* @return a pointer to the created sparse matrix. |
|
|
|
*/ |
|
|
|
|
|
|
|
sparse::StaticSparseMatrix<double> * readTraFile(const char * filename) { |
|
|
|
/*!
|
|
|
|
/*
|
|
|
|
* enforce locale where decimal point is '.' |
|
|
|
*/ |
|
|
|
setlocale( LC_NUMERIC, "C" ); |
|
|
|
|
|
|
|
/*
|
|
|
|
* open file |
|
|
|
*/ |
|
|
|
MappedFile file(filename); |
|
|
|
char* buf = file.data; |
|
|
|
|
|
|
|
/*!
|
|
|
|
/*
|
|
|
|
* perform first pass, i.e. count entries that are not zero and not on the diagonal |
|
|
|
*/ |
|
|
|
uint_fast32_t maxnode; |
|
|
|
uint_fast32_t non_zero = makeFirstPass(file.data, maxnode); |
|
|
|
if (non_zero == 0) |
|
|
|
{ |
|
|
|
/*!
|
|
|
|
* first pass returned zero, this means the file format was wrong |
|
|
|
*/ |
|
|
|
throw mrmc::exceptions::wrong_file_format(); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
/*
|
|
|
|
* if first pass returned zer, the file format was wrong |
|
|
|
*/ |
|
|
|
if (non_zero == 0) throw mrmc::exceptions::wrong_file_format(); |
|
|
|
|
|
|
|
/*!
|
|
|
|
/*
|
|
|
|
* perform second pass |
|
|
|
* |
|
|
|
* from here on, we already know that the file header is correct |
|
|
|
*/ |
|
|
|
char* buf = file.data; |
|
|
|
sparse::StaticSparseMatrix<double> *sp = NULL; |
|
|
|
|
|
|
|
/*!
|
|
|
|
/*
|
|
|
|
* read file header, extract number of states |
|
|
|
*/ |
|
|
|
buf += 7; // skip "STATES "
|
|
|
@ -139,29 +156,27 @@ sparse::StaticSparseMatrix<double> * readTraFile(const char * filename) { |
|
|
|
pantheios::integer(maxnode + 1), " maxnodes and ", |
|
|
|
pantheios::integer(non_zero), " Non-Zero-Elements"); |
|
|
|
|
|
|
|
/*!
|
|
|
|
/*
|
|
|
|
* Creating matrix |
|
|
|
* Memory for diagonal elements is automatically allocated, hence only the number of non-diagonal |
|
|
|
* non-zero elements has to be specified (which is non_zero, computed by make_first_pass) |
|
|
|
*/ |
|
|
|
sp = new sparse::StaticSparseMatrix<double>(maxnode + 1); |
|
|
|
if (sp == NULL) |
|
|
|
{ |
|
|
|
/*!
|
|
|
|
* creating the matrix failed |
|
|
|
*/ |
|
|
|
throw std::bad_alloc(); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
if (sp == NULL) throw std::bad_alloc(); |
|
|
|
sp->initialize(non_zero); |
|
|
|
|
|
|
|
uint_fast64_t row, col; |
|
|
|
double val; |
|
|
|
/*!
|
|
|
|
|
|
|
|
/*
|
|
|
|
* read all transitions from file |
|
|
|
*/ |
|
|
|
while (1) |
|
|
|
{ |
|
|
|
/*
|
|
|
|
* read row, col and value. if value == 0.0, we have reached the |
|
|
|
* end of the file. |
|
|
|
*/ |
|
|
|
row = strtol(buf, &buf, 10); |
|
|
|
col = strtol(buf, &buf, 10); |
|
|
|
val = strtod(buf, &buf); |
|
|
@ -174,7 +189,7 @@ sparse::StaticSparseMatrix<double> * readTraFile(const char * filename) { |
|
|
|
sp->addNextValue(row,col,val); |
|
|
|
} |
|
|
|
|
|
|
|
/*!
|
|
|
|
/*
|
|
|
|
* clean up |
|
|
|
*/ |
|
|
|
pantheios::log_DEBUG("Finalizing Matrix"); |
|
|
@ -183,5 +198,4 @@ sparse::StaticSparseMatrix<double> * readTraFile(const char * filename) { |
|
|
|
} |
|
|
|
|
|
|
|
} //namespace parser
|
|
|
|
|
|
|
|
} //namespace mrmc
|