Page MenuHomec4science

matrices.cpp
No OneTemporary

File Metadata

Created
Tue, Apr 23, 15:43

matrices.cpp

#include <matrices.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
#include <fstream> // ifstream
#include <sstream> // istringstream
#include <stdexcept> // std::runtime_error()
matrix2d_i read_matrix2d_i(const std::string &file_address)
{
matrix2d_i data ;
std::ifstream file(file_address, std::ifstream::in) ;
if(file.fail())
{ char msg[4096] ;
sprintf(msg, "error! cannot open %s", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
std::string buffer_str ;
vector_i buffer_vec ;
int buffer_int ;
// read file
size_t n_line = 0 ;
size_t row_len = 0 ;
while(getline(file, buffer_str))
{ // check stream status and read content
if(file.fail())
{ file.close() ;
char msg[4096] ;
sprintf(msg, "error! while reading %s", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
else if(buffer_str.size() == 0)
{ // this file only contains one eol char and should be considered as empty,
// -> returns empty matrix not an error
if(n_line == 0 and file.peek() == EOF and file.eof())
{ break ; }
file.close() ;
char msg[4096] ;
sprintf(msg, "format error! while reading %s (empty line)", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
// parse line
buffer_vec.clear() ;
std::istringstream buffer_ss(buffer_str) ;
while(buffer_ss >> buffer_int)
{ buffer_vec.push_back(buffer_int) ; }
// check for an error which likely indicates that a value could not be
// casted into a type T (mixed data types in the file)
if(buffer_ss.fail() and not buffer_ss.eof())
{ file.close() ;
char msg[4096] ;
sprintf(msg, "format error! could not read a line in %s (incompatible data types)", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
// check that number of column is constant
if(n_line == 0)
{ row_len = buffer_vec.size() ; }
else if(buffer_vec.size() != row_len)
{ file.close() ;
char msg[4096] ;
sprintf(msg, "format error! variable number of columns in %s", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
// update matrix content
data.push_back(vector_i()) ;
for(auto i : buffer_vec)
{ data.back().push_back(i) ; }
n_line++ ;
}
file.close() ;
return data ;
}
matrix2d_c read_matrix2d_c(const std::string &file_address)
{
matrix2d_c data ;
std::ifstream file(file_address, std::ifstream::in) ;
if(file.fail())
{ char msg[4096] ;
sprintf(msg, "error! cannot open %s", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
std::string buffer_str ;
vector_c buffer_vec ;
char buffer_char ;
// read file
size_t n_line = 0 ;
size_t row_len = 0 ;
while(getline(file, buffer_str))
{ // check stream status and read content
if(file.fail())
{ file.close() ;
char msg[4096] ;
sprintf(msg, "error! while reading %s", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
else if(buffer_str.size() == 0)
{ // this file only contains one eol char and should be considered as empty,
// -> returns empty matrix not an error
if(n_line == 0 and file.peek() == EOF and file.eof())
{ break ; }
file.close() ;
char msg[4096] ;
sprintf(msg, "format error! while reading %s (empty line)", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
// parse line
buffer_vec.clear() ;
std::istringstream buffer_ss(buffer_str) ;
while(buffer_ss >> buffer_char)
{ buffer_vec.push_back(buffer_char) ; }
// check for an error which likely indicates that a value could not be
// casted into a type T (mixed data types in the file)
if(buffer_ss.fail() and not buffer_ss.eof())
{ file.close() ;
char msg[4096] ;
sprintf(msg, "format error! could not read a line in %s (incompatible data types)", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
// check that number of column is constant
if(n_line == 0)
{ row_len = buffer_vec.size() ; }
else if(buffer_vec.size() != row_len)
{ file.close() ;
char msg[4096] ;
sprintf(msg, "format error! variable number of columns in %s", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
// update matrix content
data.push_back(vector_c()) ;
for(auto i : buffer_vec)
{ data.back().push_back(i) ; }
n_line++ ;
}
file.close() ;
return data ;
}
matrix4d_d read_matrix4d_d(const std::string &file_address)
{
std::ifstream file(file_address, std::ifstream::in) ;
if(file.fail())
{ char msg[4096] ;
sprintf(msg, "error! cannot open %s", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
// the data
std::vector<size_t> data_dim(4,0) ;
vector_d data ;
// some buffers
std::string buffer_str ;
vector_d buffer_d ;
std::vector<size_t> dim ;
// read 1st line
getline(file, buffer_str) ;
// empty line
if(buffer_str.size() == 0)
{ // this file only contains one eol char and should be considered as empty,
// -> returns empty matrix not an error
if(file.peek() == EOF and file.eof())
{ file.close() ;
return matrix4d_d() ;
}
file.close() ;
char msg[4096] ;
sprintf(msg, "error! while reading %s (empty line)", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
if(file.fail())
{ file.close() ;
char msg[4096] ;
sprintf(msg, "error! while reading %s", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
bool found_4d_header = is_header_4d(buffer_str) ;
do
{ if(file.fail())
{ file.close() ;
char msg[4096] ;
sprintf(msg, "error! while reading %s", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
// check empty line
if(buffer_str.size() == 0)
{ file.close() ;
char msg[4096] ;
sprintf(msg, "error! while reading %s (empty line)", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
// this is the beginning of a 3D slice -> get it using routine
if(found_4d_header)
{ try
{ // get slice
buffer_d.clear() ;
dim.clear() ;
found_4d_header = get_3d_slice(file_address, file, buffer_d, dim);
// update data
for(const auto& i : buffer_d)
{ data.push_back(i) ; }
// update dim only for the 1st slice (the 1st slice set the dimensions)
if(data_dim[3] == 0)
{ data_dim[0] = dim[0] ;
data_dim[1] = dim[1] ;
data_dim[2] = dim[2] ;
}
// check dimensions of the slice
else
{ if(dim[0] != data_dim[0] or
dim[1] != data_dim[1] or
dim[2] != data_dim[2])
{ char msg[4096] ;
sprintf(msg, "format error! slice have variable dimensions in %s", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
}
data_dim[3]++ ;
}
catch(std::runtime_error& e)
{ file.close() ;
throw e ;
}
}
// this is an error, everything between two ',,,N' header
// should be read at once. The only way out of the loop
// is that no more header has been read because of eof
else if(not found_4d_header and not file.eof())
{ file.close() ;
char msg[4096] ;
sprintf(msg, "error! while reading %s", file_address.c_str()) ;
throw std::runtime_error(msg) ;
}
} while(found_4d_header) ;
file.close() ;
// reformat data
matrix4d_d matrix(data_dim[1],
matrix3d_d(data_dim[0],
matrix2d_d(data_dim[2],
vector_d(data_dim[3])))) ;
size_t n=0 ;
for(size_t l=0; l<matrix[0][0][0].size(); l++)
{ for(size_t k=0; k<matrix[0][0].size(); k++)
{ for(size_t i=0; i<matrix.size(); i++)
{ for(size_t j=0; j<matrix[0].size(); j++)
{ matrix[i][j][k][l] = data[n] ;
n++ ;
}
}
}
}
return matrix ;
}
bool is_header_3d(const std::string &str)
{ if(str[0] == ',' and
str[1] == ',' and
str.find(',', 2) == std::string::npos)
{ return true ; }
return false ;
}
bool is_header_4d(const std::string &str)
{ if(str[0] == ',' and
str[1] == ',' and
str[2] == ',' and
str.find(',', 3) == std::string::npos)
{ return true ; }
return false ;
}
bool get_3d_slice(const std::string& file_name, std::ifstream& file,
vector_d& data, std::vector<size_t>& dim)
{
bool found_4d_header = false ; // the flag to return
dim = {0,0,0} ;
std::string buffer_str ;
vector_d buffer_vec_d ;
double buffer_d ;
size_t n_line = 0, n_line_data = 0 ; // number of line and of data line read
size_t row_len = 0, col_len = 0 ; // length of row and column in nber of values
size_t row_len_cur = 0, col_len_cur = 0 ; // current number of values read in row and col
while(getline(file, buffer_str))
{ if(file.fail())
{ char msg[4096] ;
sprintf(msg, "error! while reading %s", file_name.c_str()) ;
throw std::runtime_error(msg) ;
}
// check empty line
if(buffer_str.size() == 0)
{ char msg[4096] ;
sprintf(msg, "error! while reading %s (empty line)", file_name.c_str()) ;
throw std::runtime_error(msg) ;
}
// check whether this is the beginning of a 4D slice header, if so
// break
if(is_header_4d(buffer_str))
{ found_4d_header = true ;
break ;
}
// check whether it is the beginning of a slice
// 1st line in file should be
if(is_header_3d(buffer_str))
{ // check that slice have a constant number of rows
if(dim[2] == 1)
{ col_len = col_len_cur ;
// dim[0] = row_len ;
// dim[1] = col_len ;
}
else if(col_len_cur != col_len)
{ char msg[4096] ;
sprintf(msg, "format error! slice have variable dimensions in %s", file_name.c_str()) ;
throw std::runtime_error(msg) ;
}
dim[2]++ ;
col_len_cur = 0 ;
n_line++ ;
continue ;
}
// 1st line in file should be a header and entering
// this block is forbidden
if(n_line == 0)
{ char msg[4096] ;
sprintf(msg, "format error! first line is not a slice header in %s", file_name.c_str()) ;
throw std::runtime_error(msg) ;
}
// parse line
row_len_cur = 0 ;
buffer_vec_d.clear() ;
std::istringstream buffer_ss(buffer_str) ;
while(buffer_ss >> buffer_d)
{ buffer_vec_d.push_back(buffer_d) ;
row_len_cur++ ;
}
// check for an error which likely indicates that a value could not be
// casted into a type T (mixed data types in the file)
if(buffer_ss.fail() and not buffer_ss.eof())
{ char msg[4096] ;
sprintf(msg, "format error! could not read a line in %s (incompatible data types)", file_name.c_str()) ;
throw std::runtime_error(msg) ;
}
// check that number of column is constant
if(n_line_data == 0)
{ row_len = row_len_cur ; }
else if(row_len_cur != row_len)
{ char msg[4096] ;
sprintf(msg, "format error! slice have variable dimensions in %s", file_name.c_str()) ;
throw std::runtime_error(msg) ;
}
// update matrix content
for(auto i : buffer_vec_d)
{ data.push_back(i) ; }
col_len_cur++ ;
n_line_data++ ;
n_line++ ;
// update dimension
dim[0] = row_len_cur ;
dim[1] = col_len_cur ;
}
// check dimensions of last slice
if(col_len_cur != dim[1])
{ char msg[4096] ;
sprintf(msg, "format error! slice have variable dimensions 333 in %s", file_name.c_str()) ;
throw std::runtime_error(msg) ;
}
return found_4d_header ;
}
std::ostream& operator << (std::ostream& stream, const vector_d& vector)
{ // set streams
stream.setf(std::ios::left) ;
// display parameters
char sep = ' ' ;
size_t width = 8 ;
for(const auto& x : vector)
{ stream << std::setw(width) << x << sep ; }
return stream ;
}
std::ostream& operator << (std::ostream& stream, const matrix2d_i& matrix)
{
// set streams
stream.setf(std::ios::left) ;
// display parameters
char sep = ' ' ;
size_t width = 8 ;
// other
size_t n = 0 ;
size_t n_tot = matrix.size()*matrix[0].size() ;
for(const auto& row : matrix)
{ for(const auto x : row)
{ stream << std::setw(width) << x << sep ;
n++ ;
}
if(n<n_tot)
{ stream << std::endl ; }
}
return stream ;
}
std::ostream& operator << (std::ostream& stream, const matrix2d_c& matrix)
{
// set streams
stream.setf(std::ios::left) ;
// display parameters
char sep = ' ' ;
size_t width = 8 ;
// other
size_t n = 0 ;
size_t n_tot = matrix.size()*matrix[0].size() ;
for(const auto& row : matrix)
{ for(const auto x : row)
{ stream << std::setw(width) << x << sep ;
n++ ;
}
if(n<n_tot)
{ stream << std::endl ; }
}
return stream ;
}
std::ostream& operator << (std::ostream& stream, const matrix2d_d& matrix)
{
// set streams
stream.setf(std::ios::left) ;
// display parameters
char sep = ' ' ;
size_t width = 8 ;
// other
size_t n = 0 ;
size_t n_tot = matrix.size()*matrix[0].size() ;
for(const auto& row : matrix)
{ for(const auto x : row)
{ stream << std::setw(width) << x << sep ;
n++ ;
}
if(n<n_tot)
{ stream << std::endl ; }
}
return stream ;
}
std::ostream& operator << (std::ostream& stream, const matrix3d_d& matrix)
{
size_t x_dim = matrix.size() ;
size_t y_dim = matrix[0].size() ;
size_t z_dim = matrix[0][0].size() ;
// display parameters
char sep = ' ' ;
size_t width = 8 ;
size_t precision = 4 ;
// set streams
stream.setf(std::ios::left) ;
stream << std::setprecision(precision) << std::fixed ;
// other
size_t n = 0 ;
size_t n_tot = x_dim*y_dim*z_dim ;
// if the matrix has at least one 0 dimension (no data), don't do anything
if(x_dim==0 or y_dim==0 or z_dim==0)
{ return stream ; }
stream.setf(std::ios::left) ;
stream << std::setprecision(precision) << std::fixed ;
for(size_t z=0; z<z_dim; z++)
{ stream << ",," << z << std::endl ;
for(size_t x=0; x<x_dim; x++)
{ for(size_t y=0; y<y_dim; y++, n++)
{ stream << std::setw(width) << matrix[x][y][z] << sep ; }
if(n<n_tot)
{ stream << std::endl ; }
}
}
return stream ;
}
std::ostream& operator << (std::ostream& stream, const matrix4d_d& matrix)
{
size_t dim_0 = matrix.size() ;
size_t dim_1 = matrix[0].size() ;
size_t dim_2 = matrix[0][0].size() ;
size_t dim_3 = matrix[0][0][0].size() ;
// if the matrix has at least one 0 dimension (no data), don't do anything
if(dim_0==0 or dim_1==0 or dim_2==0 or dim_3==0)
{ return stream ; }
// display parameters
char sep = ' ' ;
size_t width = 8 ;
size_t precision = 4 ;
// set streams
stream.setf(std::ios::left) ;
stream << std::setprecision(precision) << std::fixed ;
// other
size_t n = 0 ;
size_t n_tot = dim_0*dim_1*dim_2*dim_3 ;
for(size_t x_3=0; x_3<dim_3; x_3++)
{ stream << ",,," << x_3 << std::endl ;
for(size_t x_2=0; x_2<dim_2; x_2++)
{ stream << ",," << x_2 << std::endl ;
for(size_t x_0=0; x_0<dim_0; x_0++)
{ for(size_t x_1=0; x_1<dim_1; x_1++, n++)
{ stream << std::setw(width) << matrix[x_0][x_1][x_2][x_3] << sep ; }
// avoids terminal eol
if(n < n_tot)
{ stream << std::endl ; }
}
}
}
return stream ;
}

Event Timeline