mirror of
https://github.com/aportelli/LatAnalyze.git
synced 2024-11-10 00:45:36 +00:00
simplification of IO interface
This commit is contained in:
parent
9ce04cd7d6
commit
157fda5445
@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include <latan/Io.hpp>
|
||||
#include <latan/AsciiFile.hpp>
|
||||
#include <latan/Mat.hpp>
|
||||
#include <latan/Math.hpp>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include <latan/Io.hpp>
|
||||
#include <latan/AsciiFile.hpp>
|
||||
#include <latan/RandGen.hpp>
|
||||
|
||||
using namespace std;
|
||||
@ -11,7 +11,7 @@ const string stateFileName = "exRand.seed";
|
||||
|
||||
int main(void)
|
||||
{
|
||||
RandGen::State state;
|
||||
RandGenState state;
|
||||
RandGen gen[2];
|
||||
AsciiFile stateFile(stateFileName, File::Mode::write|File::Mode::read);
|
||||
|
||||
@ -31,7 +31,7 @@ int main(void)
|
||||
}
|
||||
cout << "-- setting up another generator from '" << stateFileName << "'..."
|
||||
<< endl;
|
||||
gen[1].setState(stateFile.read<RandGen::State>("exRand"));
|
||||
gen[1].setState(stateFile.read<RandGenState>("exRand"));
|
||||
cout << "-- generating a " << seqLength << " steps random sequence..."
|
||||
<< endl;
|
||||
for (int i = 0; i < seqLength; ++i)
|
||||
|
193
latan/AsciiFile.cpp
Normal file
193
latan/AsciiFile.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* AsciiFile.cpp, part of LatAnalyze 3
|
||||
*
|
||||
* Copyright (C) 2013 - 2014 Antonin Portelli
|
||||
*
|
||||
* LatAnalyze 3 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LatAnalyze 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <latan/AsciiFile.hpp>
|
||||
#include <latan/includes.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace Latan;
|
||||
|
||||
/******************************************************************************
|
||||
* AsciiFile implementation *
|
||||
******************************************************************************/
|
||||
// AsciiParserState constructor ////////////////////////////////////////////////
|
||||
AsciiFile::AsciiParserState::AsciiParserState(istream *stream, string *name,
|
||||
IoDataTable *data)
|
||||
: ParserState<IoDataTable>(stream, name, data)
|
||||
{
|
||||
initScanner();
|
||||
}
|
||||
|
||||
// AsciiParserState destructor /////////////////////////////////////////////////
|
||||
AsciiFile::AsciiParserState::~AsciiParserState(void)
|
||||
{
|
||||
destroyScanner();
|
||||
}
|
||||
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
AsciiFile::AsciiFile(void)
|
||||
: File(), fileStream_()
|
||||
, isParsed_(false)
|
||||
, state_(nullptr)
|
||||
{}
|
||||
|
||||
AsciiFile::AsciiFile(const string &name, const unsigned int mode)
|
||||
{
|
||||
open(name, mode);
|
||||
}
|
||||
|
||||
// destructor //////////////////////////////////////////////////////////////////
|
||||
AsciiFile::~AsciiFile(void)
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
// access //////////////////////////////////////////////////////////////////////
|
||||
void AsciiFile::save(const DMat &m, const std::string &name)
|
||||
{
|
||||
checkWritability();
|
||||
isParsed_ = false;
|
||||
fileStream_ << "#L latan_begin mat " << name << endl;
|
||||
fileStream_ << m.cols() << endl;
|
||||
fileStream_ << scientific << m << endl;
|
||||
fileStream_ << "#L latan_end mat " << endl;
|
||||
}
|
||||
|
||||
void AsciiFile::save(const DMatSample &s, const std::string &name)
|
||||
{
|
||||
checkWritability();
|
||||
isParsed_ = false;
|
||||
fileStream_ << "#L latan_begin rs_sample " << name << endl;
|
||||
fileStream_ << s.size() << endl;
|
||||
save(s[central], name + "_C");
|
||||
for (int i = 0; i < static_cast<int>(s.size()); ++i)
|
||||
{
|
||||
save(s[i], name + "_S_" + strFrom(i));
|
||||
}
|
||||
fileStream_ << "#L latan_end rs_sample " << endl;
|
||||
}
|
||||
|
||||
void AsciiFile::save(const RandGenState &state, const std::string &name)
|
||||
{
|
||||
checkWritability();
|
||||
isParsed_ = false;
|
||||
fileStream_ << "#L latan_begin rg_state " << name << endl;
|
||||
fileStream_ << state << endl;
|
||||
fileStream_ << "#L latan_end rg_state " << endl;
|
||||
}
|
||||
|
||||
// tests ///////////////////////////////////////////////////////////////////////
|
||||
bool AsciiFile::isOpen() const
|
||||
{
|
||||
return fileStream_.is_open();
|
||||
}
|
||||
|
||||
// IO //////////////////////////////////////////////////////////////////////////
|
||||
void AsciiFile::close(void)
|
||||
{
|
||||
state_.reset();
|
||||
if (isOpen())
|
||||
{
|
||||
fileStream_.close();
|
||||
}
|
||||
name_ = "";
|
||||
mode_ = Mode::null;
|
||||
isParsed_ = false;
|
||||
deleteData();
|
||||
}
|
||||
|
||||
void AsciiFile::open(const string &name, const unsigned int mode)
|
||||
{
|
||||
if (isOpen())
|
||||
{
|
||||
LATAN_ERROR(Io, "file already opened with name '" + name_ + "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
ios_base::openmode stdMode = static_cast<ios_base::openmode>(0);
|
||||
|
||||
if (mode & Mode::write)
|
||||
{
|
||||
stdMode |= ios::out|ios::trunc;
|
||||
}
|
||||
if (mode & Mode::read)
|
||||
{
|
||||
stdMode |= ios::in;
|
||||
}
|
||||
if (mode & Mode::append)
|
||||
{
|
||||
stdMode |= ios::out|ios::app;
|
||||
}
|
||||
name_ = name;
|
||||
mode_ = mode;
|
||||
isParsed_ = false;
|
||||
fileStream_.open(name_.c_str(), stdMode);
|
||||
if (mode_ & Mode::read)
|
||||
{
|
||||
state_.reset(new AsciiParserState(&fileStream_, &name_, &data_));
|
||||
}
|
||||
else
|
||||
{
|
||||
state_.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string AsciiFile::load(const string &name)
|
||||
{
|
||||
if ((mode_ & Mode::read)&&(isOpen()))
|
||||
{
|
||||
if (!isParsed_)
|
||||
{
|
||||
state_->isFirst = true;
|
||||
parse();
|
||||
}
|
||||
if (name.empty())
|
||||
{
|
||||
return state_->first;
|
||||
}
|
||||
else
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isOpen())
|
||||
{
|
||||
LATAN_ERROR(Io, "file '" + name_ + "' is not opened in read mode");
|
||||
}
|
||||
else
|
||||
{
|
||||
LATAN_ERROR(Io, "file not opened");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parser //////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// Bison/Flex parser declaration
|
||||
int _Ascii_parse(AsciiFile::AsciiParserState *state);
|
||||
|
||||
void AsciiFile::parse()
|
||||
{
|
||||
fileStream_.seekg(0);
|
||||
_Ascii_parse(state_.get());
|
||||
isParsed_ = true;
|
||||
}
|
87
latan/AsciiFile.hpp
Normal file
87
latan/AsciiFile.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* AsciiFile.hpp, part of LatAnalyze 3
|
||||
*
|
||||
* Copyright (C) 2013 - 2014 Antonin Portelli
|
||||
*
|
||||
* LatAnalyze 3 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LatAnalyze 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef Latan_AsciiFile_hpp_
|
||||
#define Latan_AsciiFile_hpp_
|
||||
|
||||
#include <latan/Global.hpp>
|
||||
#include <latan/File.hpp>
|
||||
#include <latan/Mat.hpp>
|
||||
#include <latan/RandGen.hpp>
|
||||
#include <latan/Sample.hpp>
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* ASCII datafile class *
|
||||
******************************************************************************/
|
||||
class AsciiFile: public File
|
||||
{
|
||||
public:
|
||||
class AsciiParserState: public ParserState<IoDataTable>
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
explicit AsciiParserState(std::istream *stream, std::string *name,
|
||||
IoDataTable *data);
|
||||
// destructor
|
||||
virtual ~AsciiParserState(void);
|
||||
// first element reference
|
||||
bool isFirst;
|
||||
std::string first;
|
||||
// parsing buffers
|
||||
RandGenState stateBuf;
|
||||
DMatSample dMatSampleBuf;
|
||||
std::queue<DMat> dMatQueue;
|
||||
std::queue<double> doubleQueue;
|
||||
std::queue<int> intQueue;
|
||||
private:
|
||||
// allocation/deallocation functions defined in IoAsciiLexer.lpp
|
||||
virtual void initScanner(void);
|
||||
virtual void destroyScanner(void);
|
||||
};
|
||||
public:
|
||||
// constructors
|
||||
AsciiFile(void);
|
||||
AsciiFile(const std::string &name, const unsigned int mode);
|
||||
// destructor
|
||||
virtual ~AsciiFile(void);
|
||||
// access
|
||||
virtual void save(const DMat &m, const std::string &name);
|
||||
virtual void save(const DMatSample &s, const std::string &name);
|
||||
virtual void save(const RandGenState &state, const std::string &name);
|
||||
// tests
|
||||
virtual bool isOpen(void) const;
|
||||
// IO
|
||||
virtual void close(void);
|
||||
virtual void open(const std::string &name, const unsigned int mode);
|
||||
private:
|
||||
// IO
|
||||
virtual std::string load(const std::string &name = "");
|
||||
// parser
|
||||
void parse(void);
|
||||
private:
|
||||
std::fstream fileStream_;
|
||||
bool isParsed_;
|
||||
std::unique_ptr<AsciiParserState> state_;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif // Latan_AsciiFile_hpp_
|
95
latan/AsciiLexer.lpp
Normal file
95
latan/AsciiLexer.lpp
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* IoAsciiLexer.lpp, part of LatAnalyze 3
|
||||
*
|
||||
* Copyright (C) 2013 - 2014 Antonin Portelli
|
||||
*
|
||||
* LatAnalyze 3 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LatAnalyze 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
%option reentrant
|
||||
%option prefix="_Ascii_"
|
||||
%option bison-bridge
|
||||
%option bison-locations
|
||||
%option noyywrap
|
||||
%option yylineno
|
||||
|
||||
%{
|
||||
#include <iostream>
|
||||
#include <latan/AsciiFile.hpp>
|
||||
#include <latan/IOASCIIParser.hpp>
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
using namespace std;
|
||||
using namespace Latan;
|
||||
|
||||
#define YY_EXTRA_TYPE AsciiFile::AsciiParserState*
|
||||
#define YY_USER_ACTION \
|
||||
yylloc->first_line = yylloc->last_line = yylineno;\
|
||||
yylloc->first_column = yylloc->last_column + 1;\
|
||||
yylloc->last_column = yylloc->first_column + yyleng - 1;
|
||||
|
||||
#define YY_INPUT(buf, result, max_size) \
|
||||
{ \
|
||||
(*yyextra->stream).read(buf,max_size);\
|
||||
result = (*yyextra->stream).gcount();\
|
||||
}
|
||||
|
||||
#define YY_DEBUG 0
|
||||
#if (YY_DEBUG == 1)
|
||||
#define RETTOK(tok) cout << #tok << "(" << yytext << ")" << endl; return tok
|
||||
#else
|
||||
#define RETTOK(tok) return tok
|
||||
#endif
|
||||
%}
|
||||
|
||||
DIGIT [0-9]
|
||||
ALPHA [a-zA-Z_\-]
|
||||
SIGN \+|-
|
||||
EXP e|E
|
||||
INT {SIGN}?{DIGIT}+
|
||||
FLOAT {SIGN}?(({DIGIT}+\.{DIGIT}*)|({DIGIT}*\.{DIGIT}+))({EXP}{SIGN}?{INT}+)?
|
||||
LMARK #L
|
||||
BLANK [ \t]
|
||||
|
||||
%x MARK TYPE
|
||||
|
||||
%%
|
||||
|
||||
{LMARK} {BEGIN(MARK);}
|
||||
{INT} {yylval->val_int = strTo<int>(yytext); RETTOK(INT);}
|
||||
{FLOAT} {yylval->val_double = strTo<double>(yytext); RETTOK(FLOAT);}
|
||||
({ALPHA}|{DIGIT})+ {strcpy(yylval->val_str,yytext); RETTOK(ID);}
|
||||
<MARK>latan_begin {BEGIN(TYPE); RETTOK(OPEN);}
|
||||
<MARK>latan_end {BEGIN(TYPE); RETTOK(CLOSE);}
|
||||
<TYPE>mat {BEGIN(INITIAL); RETTOK(MAT);}
|
||||
<TYPE>rs_sample {BEGIN(INITIAL); RETTOK(SAMPLE);}
|
||||
<TYPE>rg_state {BEGIN(INITIAL); RETTOK(RG_STATE);}
|
||||
<*>\n {yylloc->last_column = 0;}
|
||||
<*>[ \t]
|
||||
<*>. {yylval->val_char = yytext[0]; RETTOK(ERR);}
|
||||
|
||||
%%
|
||||
|
||||
void AsciiFile::AsciiParserState::initScanner()
|
||||
{
|
||||
yylex_init(&scanner);
|
||||
yyset_extra(this, scanner);
|
||||
}
|
||||
|
||||
void AsciiFile::AsciiParserState::destroyScanner()
|
||||
{
|
||||
yylex_destroy(scanner);
|
||||
}
|
188
latan/AsciiParser.ypp
Normal file
188
latan/AsciiParser.ypp
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* IoAsciiParser.ypp, part of LatAnalyze 3
|
||||
*
|
||||
* Copyright (C) 2013 - 2014 Antonin Portelli
|
||||
*
|
||||
* LatAnalyze 3 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LatAnalyze 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
%{
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <cstring>
|
||||
#include <latan/Global.hpp>
|
||||
#include <latan/AsciiFile.hpp>
|
||||
#include <latan/Mat.hpp>
|
||||
#include <latan/RandGen.hpp>
|
||||
#include <latan/Sample.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace Latan;
|
||||
|
||||
#define TEST_FIRST(name) \
|
||||
if (state->isFirst)\
|
||||
{\
|
||||
state->first = (name);\
|
||||
state->isFirst = false;\
|
||||
}
|
||||
%}
|
||||
|
||||
%pure-parser
|
||||
%name-prefix="_Ascii_"
|
||||
%locations
|
||||
%defines
|
||||
%error-verbose
|
||||
%parse-param { Latan::AsciiFile::AsciiParserState* state }
|
||||
%initial-action {yylloc.last_column = 0;}
|
||||
%lex-param { void* scanner }
|
||||
|
||||
%union
|
||||
{
|
||||
int val_int;
|
||||
double val_double;
|
||||
char val_char;
|
||||
char val_str[256];
|
||||
}
|
||||
|
||||
%token <val_char> ERR
|
||||
%token <val_double> FLOAT
|
||||
%token <val_int> INT
|
||||
%token <val_str> ID
|
||||
%token OPEN CLOSE MAT SAMPLE RG_STATE
|
||||
|
||||
%type <val_str> mat sample rg_state
|
||||
|
||||
%{
|
||||
int _Ascii_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner);
|
||||
|
||||
void _Ascii_error(YYLTYPE* locp, AsciiFile::AsciiParserState* state,
|
||||
const char* err)
|
||||
{
|
||||
stringstream buf;
|
||||
|
||||
buf << *state->streamName << ":" << locp->first_line << ":"\
|
||||
<< locp->first_column << ": " << err;
|
||||
LATAN_ERROR(Parsing, buf.str());
|
||||
}
|
||||
|
||||
#define scanner state->scanner
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
datas:
|
||||
/* empty string */
|
||||
| datas data
|
||||
;
|
||||
|
||||
data:
|
||||
mat
|
||||
{
|
||||
TEST_FIRST($1);
|
||||
(*state->data)[$1].reset(new DMat(state->dMatQueue.front()));
|
||||
state->dMatQueue.pop();
|
||||
}
|
||||
| sample
|
||||
{
|
||||
TEST_FIRST($1);
|
||||
(*state->data)[$1].reset(new DMatSample(state->dMatSampleBuf));
|
||||
}
|
||||
| rg_state
|
||||
{
|
||||
TEST_FIRST($1);
|
||||
(*state->data)[$1].reset(new RandGenState(state->stateBuf));
|
||||
}
|
||||
;
|
||||
|
||||
mat:
|
||||
OPEN MAT ID INT floats CLOSE MAT
|
||||
{
|
||||
const unsigned int nRow = state->doubleQueue.size()/$INT, nCol = $INT;
|
||||
int i, j, r = 0;
|
||||
|
||||
if (state->doubleQueue.size() != nRow*nCol)
|
||||
{
|
||||
LATAN_ERROR(Size, "matrix '" + *state->streamName + ":" + $ID +
|
||||
"' has a wrong size");
|
||||
}
|
||||
|
||||
state->dMatQueue.push(DMat(nRow, nCol));
|
||||
while (!state->doubleQueue.empty())
|
||||
{
|
||||
j = r % nCol;
|
||||
i = (r - j)/nCol;
|
||||
state->dMatQueue.back()(i, j) = state->doubleQueue.front();
|
||||
state->doubleQueue.pop();
|
||||
r++;
|
||||
}
|
||||
strcpy($$, $ID);
|
||||
}
|
||||
;
|
||||
|
||||
sample:
|
||||
OPEN SAMPLE ID INT mats CLOSE SAMPLE
|
||||
{
|
||||
const unsigned int nSample = $INT + 1;
|
||||
|
||||
if (state->dMatQueue.size() != nSample)
|
||||
{
|
||||
LATAN_ERROR(Size, "sample '" + *state->streamName + ":" + $ID +
|
||||
"' has a wrong size");
|
||||
}
|
||||
state->dMatSampleBuf.resize(nSample);
|
||||
state->dMatSampleBuf[central] = state->dMatQueue.front();
|
||||
state->dMatQueue.pop();
|
||||
for (int i = 0; i < $INT; ++i)
|
||||
{
|
||||
state->dMatSampleBuf[i] = state->dMatQueue.front();
|
||||
state->dMatQueue.pop();
|
||||
}
|
||||
strcpy($$, $ID);
|
||||
}
|
||||
|
||||
rg_state:
|
||||
OPEN RG_STATE ID ints CLOSE RG_STATE
|
||||
{
|
||||
if (state->intQueue.size() != RLXG_STATE_SIZE)
|
||||
{
|
||||
LATAN_ERROR(Size, "random generator state '" + *state->streamName
|
||||
+ ":" + $ID + "' has a wrong size");
|
||||
}
|
||||
for (unsigned int i = 0; i < RLXG_STATE_SIZE; ++i)
|
||||
{
|
||||
state->stateBuf[i] = state->intQueue.front();
|
||||
state->intQueue.pop();
|
||||
}
|
||||
strcpy($$, $ID);
|
||||
}
|
||||
;
|
||||
|
||||
mats:
|
||||
mats mat
|
||||
| mat
|
||||
;
|
||||
|
||||
floats:
|
||||
floats FLOAT {state->doubleQueue.push($FLOAT);}
|
||||
| floats INT {state->doubleQueue.push(static_cast<double>($INT));}
|
||||
| FLOAT {state->doubleQueue.push($FLOAT);}
|
||||
| INT {state->doubleQueue.push(static_cast<double>($INT));}
|
||||
;
|
||||
|
||||
ints:
|
||||
ints INT {state->intQueue.push($INT);}
|
||||
| INT {state->intQueue.push($INT);}
|
||||
;
|
@ -21,7 +21,7 @@
|
||||
#define Latan_Dataset_hpp_
|
||||
|
||||
#include <latan/Global.hpp>
|
||||
#include <latan/Io.hpp>
|
||||
#include <latan/File.hpp>
|
||||
#include <latan/Sample.hpp>
|
||||
#include <latan/RandGen.hpp>
|
||||
#include <fstream>
|
||||
@ -32,7 +32,7 @@ BEGIN_NAMESPACE
|
||||
/******************************************************************************
|
||||
* Dataset class *
|
||||
******************************************************************************/
|
||||
template <typename T, typename FileType>
|
||||
template <typename T>
|
||||
class Dataset: public StatArray<T>
|
||||
{
|
||||
private:
|
||||
@ -41,40 +41,43 @@ public:
|
||||
// constructors
|
||||
using Base::Base;
|
||||
Dataset(void);
|
||||
template <typename FileType>
|
||||
Dataset(const std::string &listFileName, const std::string &dataName);
|
||||
// destructor
|
||||
virtual ~Dataset(void) = default;
|
||||
// IO
|
||||
template <typename FileType>
|
||||
void load(const std::string &listFileName, const std::string &dataName);
|
||||
// resampling
|
||||
Sample<T> bootstrapMean(const unsigned int nSample, RandGen& generator);
|
||||
private:
|
||||
// mean from pointer vector for resampling
|
||||
void ptVectorMean(T &m, const std::vector<const T *> &v);
|
||||
private:
|
||||
FileType file_;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Dataset template implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename FileType>
|
||||
Dataset<T, FileType>::Dataset(void)
|
||||
template <typename T>
|
||||
Dataset<T>::Dataset(void)
|
||||
{}
|
||||
|
||||
template <typename T, typename FileType>
|
||||
Dataset<T, FileType>::Dataset(const std::string &listFileName,
|
||||
template <typename T>
|
||||
template <typename FileType>
|
||||
Dataset<T>::Dataset(const std::string &listFileName,
|
||||
const std::string &dataName)
|
||||
{
|
||||
load(listFileName, dataName);
|
||||
load<FileType>(listFileName, dataName);
|
||||
}
|
||||
|
||||
// IO //////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename FileType>
|
||||
void Dataset<T, FileType>::load(const std::string &listFileName,
|
||||
template <typename T>
|
||||
template <typename FileType>
|
||||
void Dataset<T>::load(const std::string &listFileName,
|
||||
const std::string &dataName)
|
||||
{
|
||||
FileType file;
|
||||
std::ifstream listFile;
|
||||
char dataFileNameBuf[MAX_PATH_LENGTH];
|
||||
std::vector<std::string> dataFileName;
|
||||
@ -92,15 +95,15 @@ void Dataset<T, FileType>::load(const std::string &listFileName,
|
||||
this->resize(dataFileName.size());
|
||||
for (unsigned int i = 0; i < dataFileName.size(); ++i)
|
||||
{
|
||||
file_.open(dataFileName[i], File::Mode::read);
|
||||
(*this)[i] = file_.template read<T>(dataName);
|
||||
file_.close();
|
||||
file.open(dataFileName[i], File::Mode::read);
|
||||
(*this)[i] = file.template read<T>(dataName);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
// resampling //////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename FileType>
|
||||
Sample<T> Dataset<T, FileType>::bootstrapMean(const unsigned int nSample,
|
||||
template <typename T>
|
||||
Sample<T> Dataset<T>::bootstrapMean(const unsigned int nSample,
|
||||
RandGen& generator)
|
||||
{
|
||||
unsigned int nData = this->size();
|
||||
@ -124,8 +127,8 @@ Sample<T> Dataset<T, FileType>::bootstrapMean(const unsigned int nSample,
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename T, typename FileType>
|
||||
void Dataset<T, FileType>::ptVectorMean(T &m, const std::vector<const T *> &v)
|
||||
template <typename T>
|
||||
void Dataset<T>::ptVectorMean(T &m, const std::vector<const T *> &v)
|
||||
{
|
||||
if (v.size())
|
||||
{
|
||||
|
75
latan/File.cpp
Normal file
75
latan/File.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* File.cpp, part of LatAnalyze 3
|
||||
*
|
||||
* Copyright (C) 2013 - 2014 Antonin Portelli
|
||||
*
|
||||
* LatAnalyze 3 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LatAnalyze 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <latan/File.hpp>
|
||||
#include <latan/includes.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace Latan;
|
||||
|
||||
/******************************************************************************
|
||||
* File implementation *
|
||||
******************************************************************************/
|
||||
// constructors ////////////////////////////////////////////////////////////////
|
||||
File::File(void)
|
||||
: name_("")
|
||||
, mode_(Mode::null)
|
||||
, data_()
|
||||
{}
|
||||
|
||||
File::File(const string &name, const unsigned int mode)
|
||||
: name_(name)
|
||||
, mode_(mode)
|
||||
, data_()
|
||||
{}
|
||||
|
||||
// destructor //////////////////////////////////////////////////////////////////
|
||||
File::~File(void)
|
||||
{
|
||||
deleteData();
|
||||
}
|
||||
|
||||
// access //////////////////////////////////////////////////////////////////////
|
||||
const string & File::getName(void) const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
unsigned int File::getMode(void) const
|
||||
{
|
||||
return mode_;
|
||||
}
|
||||
|
||||
// internal functions //////////////////////////////////////////////////////////
|
||||
void File::deleteData(void)
|
||||
{
|
||||
for (auto &i : data_)
|
||||
{
|
||||
i.second.reset();
|
||||
}
|
||||
data_.clear();
|
||||
}
|
||||
|
||||
void File::checkWritability(void)
|
||||
{
|
||||
if (!((mode_ & Mode::write)||(mode_ & Mode::append))||!isOpen())
|
||||
{
|
||||
LATAN_ERROR(Io, "file '" + name_ + "' is not writable");
|
||||
}
|
||||
}
|
161
latan/File.hpp
Normal file
161
latan/File.hpp
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* File.hpp, part of LatAnalyze 3
|
||||
*
|
||||
* Copyright (C) 2013 - 2014 Antonin Portelli
|
||||
*
|
||||
* LatAnalyze 3 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LatAnalyze 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef Latan_Io_hpp_
|
||||
#define Latan_Io_hpp_
|
||||
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <latan/Global.hpp>
|
||||
#include <latan/IoObject.hpp>
|
||||
#include <latan/ParserState.hpp>
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
// forward declaration of IO types
|
||||
class DMat;
|
||||
class DMatSample;
|
||||
class RandGen;
|
||||
class RandGenState;
|
||||
|
||||
/******************************************************************************
|
||||
* Abstract datafile class *
|
||||
******************************************************************************/
|
||||
typedef std::unordered_map<std::string, std::unique_ptr<IoObject>> IoDataTable;
|
||||
|
||||
class File
|
||||
{
|
||||
public:
|
||||
class Mode
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
null = 0,
|
||||
write = 1 << 0,
|
||||
read = 1 << 1,
|
||||
append = 1 << 2
|
||||
};
|
||||
};
|
||||
public:
|
||||
// constructors
|
||||
File(void);
|
||||
File(const std::string &name, const unsigned int mode);
|
||||
// destructor
|
||||
virtual ~File(void);
|
||||
// access
|
||||
const std::string & getName(void) const;
|
||||
unsigned int getMode(void) const;
|
||||
template <typename IoT>
|
||||
const IoT & read(const std::string &name = "");
|
||||
virtual void save(const DMat &m, const std::string &name) = 0;
|
||||
virtual void save(const DMatSample &state, const std::string &name) = 0;
|
||||
virtual void save(const RandGenState &state, const std::string &name) = 0;
|
||||
// tests
|
||||
virtual bool isOpen(void) const = 0;
|
||||
// IO
|
||||
virtual void close(void) = 0;
|
||||
virtual void open(const std::string &name, const unsigned int mode) = 0;
|
||||
// static IO functions
|
||||
|
||||
protected:
|
||||
// access
|
||||
void setName(const std::string &name);
|
||||
void setMode(const unsigned int mode);
|
||||
// data access
|
||||
void deleteData(void);
|
||||
// error checking
|
||||
void checkWritability(void);
|
||||
private:
|
||||
// data access
|
||||
template <typename IoT>
|
||||
const IoT& getData(const std::string &name = "") const;
|
||||
// IO
|
||||
virtual std::string load(const std::string &name = "") = 0;
|
||||
protected:
|
||||
std::string name_;
|
||||
unsigned int mode_;
|
||||
IoDataTable data_;
|
||||
};
|
||||
|
||||
// Template implementations
|
||||
template <typename IoT>
|
||||
const IoT& File::read(const std::string &name)
|
||||
{
|
||||
std::string dataName;
|
||||
|
||||
dataName = load(name);
|
||||
|
||||
return getData<IoT>(dataName);
|
||||
}
|
||||
|
||||
template <typename IoT>
|
||||
const IoT& File::getData(const std::string &name) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return dynamic_cast<const IoT &>(*(data_.at(name)));
|
||||
}
|
||||
catch(std::out_of_range)
|
||||
{
|
||||
LATAN_ERROR(Definition, "no data with name '" + name + "' in file "
|
||||
+ name_);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Static IO functions *
|
||||
******************************************************************************/
|
||||
class Io
|
||||
{
|
||||
public:
|
||||
template <typename IoT, typename FileType>
|
||||
static IoT load(const std::string &fileName, const std::string &name = "");
|
||||
template <typename IoT, typename FileType>
|
||||
static void save(const IoT &data, const std::string &fileName,
|
||||
const unsigned int mode = File::Mode::append,
|
||||
const std::string &name = "");
|
||||
};
|
||||
|
||||
// template implementation /////////////////////////////////////////////////////
|
||||
template <typename IoT, typename FileType>
|
||||
IoT Io::load(const std::string &fileName, const std::string &name)
|
||||
{
|
||||
FileType file(fileName, File::Mode::read);
|
||||
|
||||
return file.template read<IoT>(name);
|
||||
}
|
||||
|
||||
template <typename IoT, typename FileType>
|
||||
void Io::save(const IoT &data, const std::string &fileName,
|
||||
const unsigned int mode, const std::string &name)
|
||||
{
|
||||
FileType file(fileName, mode);
|
||||
std::string realName = (name.empty()) ? fileName : name;
|
||||
|
||||
file.template save(data, realName);
|
||||
}
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif
|
@ -24,7 +24,9 @@
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
// Abstract base for IO objects
|
||||
/******************************************************************************
|
||||
* Abstract class for IO objects *
|
||||
******************************************************************************/
|
||||
class IoObject
|
||||
{
|
||||
public:
|
||||
|
@ -20,19 +20,20 @@ AM_YFLAGS = -d
|
||||
include eigen_files.mk
|
||||
nobase_dist_pkginclude_HEADERS = $(eigen_files)
|
||||
|
||||
BUILT_SOURCES = IoAsciiParser.hpp MathParser.hpp
|
||||
BUILT_SOURCES = AsciiParser.hpp MathParser.hpp
|
||||
|
||||
lib_LTLIBRARIES = liblatan.la
|
||||
|
||||
liblatan_la_SOURCES = \
|
||||
AsciiFile.cpp \
|
||||
AsciiParser.ypp \
|
||||
AsciiLexer.lpp \
|
||||
CompiledFunction.cpp\
|
||||
Exceptions.cpp \
|
||||
Function.cpp \
|
||||
Global.cpp \
|
||||
includes.hpp \
|
||||
Io.cpp \
|
||||
IoAsciiParser.ypp \
|
||||
IoAsciiLexer.lpp \
|
||||
File.cpp \
|
||||
Mat.cpp \
|
||||
Math.cpp \
|
||||
MathInterpreter.cpp \
|
||||
@ -45,11 +46,12 @@ liblatan_la_SOURCES = \
|
||||
../config.h
|
||||
liblatan_ladir = $(pkgincludedir)
|
||||
liblatan_la_HEADERS = \
|
||||
AsciiFile.hpp \
|
||||
CompiledFunction.hpp\
|
||||
Dataset.hpp \
|
||||
Function.hpp \
|
||||
Global.hpp \
|
||||
Io.hpp \
|
||||
File.hpp \
|
||||
IoObject.hpp \
|
||||
Mat.hpp \
|
||||
Math.hpp \
|
||||
|
@ -28,18 +28,17 @@ using namespace std;
|
||||
using namespace Latan;
|
||||
|
||||
/******************************************************************************
|
||||
* RandGen implementation *
|
||||
* RandGenState implementation *
|
||||
******************************************************************************/
|
||||
// State constructor ///////////////////////////////////////////////////////////
|
||||
RandGen::State::State(void)
|
||||
{}
|
||||
|
||||
// State IO type ///////////////////////////////////////////////////////////////
|
||||
IoObject::IoType RandGen::State::getType(void) const
|
||||
// IO type ///////////////////////////////////////////////////////////////
|
||||
IoObject::IoType RandGenState::getType(void) const
|
||||
{
|
||||
return IoType::rgState;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RandGen implementation *
|
||||
******************************************************************************/
|
||||
// RanLxd implementation ///////////////////////////////////////////////////////
|
||||
RandGen::RanLxd::RanLxd(void)
|
||||
: init(0)
|
||||
@ -640,22 +639,22 @@ RandGen::RandGen(const int seed)
|
||||
generator_.rlxd_init(RLXD_LEVEL, seed);
|
||||
}
|
||||
|
||||
RandGen::RandGen(const State &state)
|
||||
RandGen::RandGen(const RandGenState &state)
|
||||
{
|
||||
setState(state);
|
||||
}
|
||||
|
||||
// state management ////////////////////////////////////////////////////////////
|
||||
RandGen::State RandGen::getState(void) const
|
||||
RandGenState RandGen::getState(void) const
|
||||
{
|
||||
State state;
|
||||
RandGenState state;
|
||||
|
||||
generator_.rlxd_get(state.data());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void RandGen::setState(const State &state)
|
||||
void RandGen::setState(const RandGenState &state)
|
||||
{
|
||||
generator_.rlxd_reset(state.data());
|
||||
}
|
||||
|
@ -27,25 +27,24 @@
|
||||
|
||||
BEGIN_NAMESPACE
|
||||
|
||||
class RandGenState: public Eigen::Array<int, RLXG_STATE_SIZE, 1>,
|
||||
public IoObject
|
||||
{
|
||||
private:
|
||||
typedef Eigen::Array<int, RLXG_STATE_SIZE, 1> Base;
|
||||
public:
|
||||
// destructor
|
||||
virtual ~RandGenState(void) = default;
|
||||
// IO type
|
||||
IoType getType(void) const;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Random generator class *
|
||||
******************************************************************************/
|
||||
|
||||
class RandGen
|
||||
{
|
||||
public:
|
||||
class State: public Eigen::Array<int, RLXG_STATE_SIZE, 1>, public IoObject
|
||||
{
|
||||
private:
|
||||
typedef Eigen::Array<int, RLXG_STATE_SIZE, 1> Base;
|
||||
public:
|
||||
// constructor
|
||||
State(void);
|
||||
// destructor
|
||||
virtual ~State(void) = default;
|
||||
// IO type
|
||||
IoType getType(void) const;
|
||||
};
|
||||
private:
|
||||
// Martin Luescher's ranlxd generator interface
|
||||
class RanLxd
|
||||
@ -85,12 +84,12 @@ public:
|
||||
// constructors
|
||||
RandGen(void);
|
||||
RandGen(const int seed);
|
||||
RandGen(const State &state);
|
||||
RandGen(const RandGenState &state);
|
||||
// destructor
|
||||
virtual ~RandGen(void) = default;
|
||||
// state management
|
||||
State getState(void) const;
|
||||
void setState(const State &state);
|
||||
RandGenState getState(void) const;
|
||||
void setState(const RandGenState &state);
|
||||
// generators
|
||||
double uniform(const double a = 0.0, const double b = 1.0);
|
||||
double discreteUniform(const unsigned int n);
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include <iostream>
|
||||
#include <libgen.h>
|
||||
#include <unistd.h>
|
||||
#include <latan/AsciiFile.hpp>
|
||||
#include <latan/Dataset.hpp>
|
||||
#include <latan/Io.hpp>
|
||||
|
||||
#ifndef DEF_NSAMPLE
|
||||
#define DEF_NSAMPLE 100u
|
||||
@ -60,25 +60,25 @@ int main(int argc, char *argv[])
|
||||
usage(cmdName);
|
||||
}
|
||||
|
||||
Dataset<DMat, AsciiFile> dataset;
|
||||
Dataset<DMat> dataset;
|
||||
DMatSample s;
|
||||
RandGen g;
|
||||
|
||||
if (!stateFileName.empty())
|
||||
{
|
||||
AsciiFile f(stateFileName, File::Mode::read);
|
||||
g.setState(f.read<RandGen::State>());
|
||||
g.setState(f.read<RandGenState>());
|
||||
}
|
||||
cout << "-- loading data from manifest '" << manFileName << "'..." << endl;
|
||||
dataset.load(manFileName, name);
|
||||
dataset.load<AsciiFile>(manFileName, name);
|
||||
s = dataset.bootstrapMean(nSample, g);
|
||||
cout << scientific;
|
||||
cout << "central value:\n" << s[central] << endl;
|
||||
cout << "standard deviation:\n" << s.variance().cwiseSqrt() << endl;
|
||||
if (!outFileName.empty())
|
||||
{
|
||||
AsciiFile f(outFileName, File::Mode::write);
|
||||
f.save(s, manFileName + "_" + name);
|
||||
Io::save<DMatSample, AsciiFile>(s, outFileName, File::Mode::write,
|
||||
manFileName + "_" + name);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include <latan/Io.hpp>
|
||||
#include <latan/AsciiFile.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace Latan;
|
||||
@ -13,10 +13,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
string fileName = argv[1];
|
||||
AsciiFile f(fileName, File::Mode::read);
|
||||
|
||||
cout << "-- loading sample from '" << fileName << "'..." << endl;
|
||||
const DMatSample &s = f.read<DMatSample>();
|
||||
const DMatSample &s = Io::load<DMatSample, AsciiFile>(fileName);
|
||||
cout << scientific;
|
||||
cout << "central value:\n" << s[central] << endl;
|
||||
cout << "standard deviation:\n" << s.variance().cwiseSqrt() << endl;
|
||||
|
Loading…
Reference in New Issue
Block a user