1
0
mirror of https://github.com/aportelli/LatAnalyze.git synced 2025-04-05 09:35:54 +01:00

I/O for DSample type

This commit is contained in:
Antonin Portelli 2016-04-05 15:57:19 +01:00
parent 7f8eacc95d
commit 257c430745
15 changed files with 270 additions and 103 deletions

View File

@ -71,7 +71,22 @@ void AsciiFile::save(const DMat &m, const std::string &name)
fileStream_.precision(defaultPrec);
}
void AsciiFile::save(const DMatSample &s, const std::string &name)
void AsciiFile::save(const DSample &ds, const std::string &name)
{
if (name.empty())
{
LATAN_ERROR(Io, "trying to save data with an empty name");
}
checkWritability();
isParsed_ = false;
fileStream_ << "#L latan_begin rs_sample " << name << endl;
fileStream_ << ds.size() << endl;
save(ds.matrix(), name + "_data");
fileStream_ << "#L latan_end rs_sample " << endl;
}
void AsciiFile::save(const DMatSample &ms, const std::string &name)
{
if (name.empty())
{
@ -81,11 +96,11 @@ 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 (Index i = 0; i < s.size(); ++i)
fileStream_ << ms.size() << endl;
save(ms[central], name + "_C");
for (Index i = 0; i < ms.size(); ++i)
{
save(s[i], name + "_S_" + strFrom(i));
save(ms[i], name + "_S_" + strFrom(i));
}
fileStream_ << "#L latan_end rs_sample " << endl;
}

View File

@ -49,6 +49,7 @@ public:
std::string first;
// parsing buffers
RandGenState stateBuf;
DSample dSampleBuf;
DMatSample dMatSampleBuf;
std::queue<DMat> dMatQueue;
std::queue<double> doubleQueue;
@ -66,7 +67,8 @@ public:
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 DSample &ds, const std::string &name);
virtual void save(const DMatSample &ms, const std::string &name);
virtual void save(const RandGenState &state, const std::string &name);
// read first name
virtual std::string getFirstName(void);

View File

@ -69,7 +69,7 @@
%token <val_str> ID
%token OPEN CLOSE MAT SAMPLE RG_STATE
%type <val_str> mat sample rg_state
%type <val_str> mat matsample dsample rg_state
%{
int _Ascii_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner);
@ -101,7 +101,12 @@ data:
(*state->data)[$1].reset(new DMat(state->dMatQueue.front()));
state->dMatQueue.pop();
}
| sample
| dsample
{
TEST_FIRST($1);
(*state->data)[$1].reset(new DSample(state->dSampleBuf));
}
| matsample
{
TEST_FIRST($1);
(*state->data)[$1].reset(new DMatSample(state->dMatSampleBuf));
@ -138,15 +143,37 @@ mat:
}
;
sample:
OPEN SAMPLE ID INT mats CLOSE SAMPLE
dsample:
OPEN SAMPLE ID INT mat CLOSE SAMPLE
{
const unsigned int nSample = $4, os = DMatSample::offset;
DMat &m = state->dMatQueue.front();
if (m.rows() != nSample + os)
{
LATAN_ERROR(Size, "double sample '" + *state->streamName + ":"
+ $3 + "' has a wrong size");
}
if (m.cols() != 1)
{
LATAN_ERROR(Size, "double sample '" + *state->streamName + ":"
+ $3 + "' is not stored as a column vector");
}
state->dSampleBuf = m.array();
state->dMatQueue.pop();
strcpy($$, $3);
}
;
matsample:
OPEN SAMPLE ID INT mat mats CLOSE SAMPLE
{
const unsigned int nSample = $4, os = DMatSample::offset;
if (state->dMatQueue.size() != nSample + os)
{
LATAN_ERROR(Size, "sample '" + *state->streamName + ":" + $3 +
"' has a wrong size");
LATAN_ERROR(Size, "matrix sample '" + *state->streamName + ":"
+ $3 + "' has a wrong size");
}
state->dMatSampleBuf.resize(nSample);
state->dMatSampleBuf[central] = state->dMatQueue.front();
@ -158,6 +185,7 @@ sample:
}
strcpy($$, $3);
}
;
rg_state:
OPEN RG_STATE ID ints CLOSE RG_STATE

View File

@ -52,10 +52,6 @@ unsigned int File::getMode(void) const
// internal functions //////////////////////////////////////////////////////////
void File::deleteData(void)
{
for (auto &i : data_)
{
i.second.reset();
}
data_.clear();
}

View File

@ -61,7 +61,8 @@ public:
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 DSample &ds, const std::string &name) = 0;
virtual void save(const DMatSample &ms, const std::string &name) = 0;
virtual void save(const RandGenState &state, const std::string &name) = 0;
// read first name
virtual std::string getFirstName(void) = 0;

View File

@ -30,6 +30,7 @@ using namespace H5NS;
constexpr unsigned int maxGroupNameSize = 1024u;
const short dMatType = static_cast<short>(IoObject::IoType::dMat);
const short dSampleType = static_cast<short>(IoObject::IoType::dSample);
const short dMatSampleType = static_cast<short>(IoObject::IoType::dMatSample);
const short rgStateType = static_cast<short>(IoObject::IoType::rgState);
@ -65,7 +66,6 @@ void Hdf5File::save(const DMat &m, const string &name)
hsize_t dim[2] = {static_cast<hsize_t>(m.rows()),
static_cast<hsize_t>(m.cols())};
hsize_t attrDim = 1;
DataSpace dataSpace(2, dim), attrSpace(1, &attrDim);
group = h5File_->createGroup(name.c_str() + nameOffset(name));
@ -75,7 +75,31 @@ void Hdf5File::save(const DMat &m, const string &name)
dataset.write(m.data(), PredType::NATIVE_DOUBLE);
}
void Hdf5File::save(const DMatSample &sample, const string &name)
void Hdf5File::save(const DSample &ds, const string &name)
{
if (name.empty())
{
LATAN_ERROR(Io, "trying to save data with an empty name");
}
Group group;
Attribute attr;
DataSet dataset;
hsize_t dim = static_cast<hsize_t>(ds.size() + 1);
hsize_t attrDim = 1;
DataSpace dataSpace(1, &dim), attrSpace(1, &attrDim);
const long int nSample = ds.size();
group = h5File_->createGroup(name.c_str() + nameOffset(name));
attr = group.createAttribute("type", PredType::NATIVE_SHORT, attrSpace);
attr.write(PredType::NATIVE_SHORT, &dSampleType);
attr = group.createAttribute("nSample", PredType::NATIVE_LONG, attrSpace);
attr.write(PredType::NATIVE_LONG, &nSample);
dataset = group.createDataSet("data", PredType::NATIVE_DOUBLE, dataSpace);
dataset.write(ds.data(), PredType::NATIVE_DOUBLE);
}
void Hdf5File::save(const DMatSample &ms, const string &name)
{
if (name.empty())
{
@ -85,11 +109,11 @@ void Hdf5File::save(const DMatSample &sample, const string &name)
Group group;
Attribute attr;
DataSet dataset;
hsize_t dim[2] = {static_cast<hsize_t>(sample[central].rows()),
static_cast<hsize_t>(sample[central].cols())};
hsize_t dim[2] = {static_cast<hsize_t>(ms[central].rows()),
static_cast<hsize_t>(ms[central].cols())};
hsize_t attrDim = 1;
DataSpace dataSpace(2, dim), attrSpace(1, &attrDim);
const long int nSample = sample.size();
const long int nSample = ms.size();
string datasetName;
group = h5File_->createGroup(name.c_str() + nameOffset(name));
@ -97,13 +121,13 @@ void Hdf5File::save(const DMatSample &sample, const string &name)
attr.write(PredType::NATIVE_SHORT, &dMatSampleType);
attr = group.createAttribute("nSample", PredType::NATIVE_LONG, attrSpace);
attr.write(PredType::NATIVE_LONG, &nSample);
FOR_STAT_ARRAY(sample, s)
FOR_STAT_ARRAY(ms, s)
{
datasetName = (s == central) ? "data_C" : ("data_S_" + strFrom(s));
dataset = group.createDataSet(datasetName.c_str(),
PredType::NATIVE_DOUBLE,
dataSpace);
dataset.write(sample[s].data(), PredType::NATIVE_DOUBLE);
dataset.write(ms[s].data(), PredType::NATIVE_DOUBLE);
}
}
@ -253,6 +277,17 @@ void Hdf5File::load(DMat &m, const DataSet &d)
d.read(m.data(), PredType::NATIVE_DOUBLE);
}
void Hdf5File::load(DSample &ds, const DataSet &d)
{
DataSpace dataspace;
hsize_t dim[1];
dataspace = d.getSpace();
dataspace.getSimpleExtentDims(dim);
ds.resize(dim[0] - 1);
d.read(ds.data(), PredType::NATIVE_DOUBLE);
}
void Hdf5File::load(RandGenState &state, const DataSet &d)
{
DataSpace dataspace;
@ -296,6 +331,15 @@ string Hdf5File::load(const string &name)
load(*pt, dataset);
break;
}
case IoObject::IoType::dSample:
{
DSample *pt = new DSample;
data_[groupName].reset(pt);
dataset = group.openDataSet("data");
load(*pt, dataset);
break;
}
case IoObject::IoType::dMatSample:
{
DMatSample *pt = new DMatSample;

View File

@ -46,7 +46,8 @@ public:
virtual ~Hdf5File(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 DSample &ds, const std::string &name);
virtual void save(const DMatSample &ms, const std::string &name);
virtual void save(const RandGenState &state, const std::string &name);
// read first name
virtual std::string getFirstName(void);
@ -60,6 +61,7 @@ private:
std::string getFirstGroupName(void);
virtual std::string load(const std::string &name = "");
void load(DMat &m, const H5NS::DataSet &d);
void load(DSample &ds, const H5NS::DataSet &d);
void load(DMatSample &s, const H5NS::DataSet &d);
void load(RandGenState &state, const H5NS::DataSet &d);
// check name for forbidden characters

View File

@ -30,12 +30,14 @@ BEGIN_LATAN_NAMESPACE
class IoObject
{
public:
// conserve order for datafile retro-compatibility!
enum class IoType: short int
{
noType = 0,
dMat = 1,
dMatSample = 2,
rgState = 3
rgState = 3,
dSample = 4
};
public:
// destructor

View File

@ -38,13 +38,13 @@ libLatAnalyze_la_SOURCES = \
MathInterpreter.cpp \
MathParser.ypp \
MathLexer.lpp \
MatSample.cpp \
Minimizer.cpp \
Model.cpp \
Plot.cpp \
RandGen.cpp \
RootFinder.cpp \
Solver.cpp \
StatArray.cpp \
TabFunction.cpp \
XYSampleData.cpp \
XYStatData.cpp \

View File

@ -35,7 +35,7 @@ BEGIN_LATAN_NAMESPACE
std::placeholders::_1, x))
template <typename T>
class MatSample: public Sample<Mat<T>>, public IoObject
class MatSample: public Sample<Mat<T>>
{
public:
// block type template
@ -104,9 +104,6 @@ public:
const Index nCol);
// resize all matrices
void resizeMat(const Index nRow, const Index nCol);
// IO type
virtual IoType getType(void) const;
};
// non-member operators
@ -383,12 +380,6 @@ void MatSample<T>::resizeMat(const Index nRow, const Index nCol)
}
}
// IO type /////////////////////////////////////////////////////////////////////
template <typename T>
IoObject::IoType MatSample<T>::getType(void) const
{
return IoType::noType;
}
END_LATAN_NAMESPACE

View File

@ -1,5 +1,5 @@
/*
* MatSample.cpp, part of LatAnalyze 3
* StatArray.cpp, part of LatAnalyze 3
*
* Copyright (C) 2013 - 2015 Antonin Portelli
*
@ -17,7 +17,7 @@
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LatAnalyze/MatSample.hpp>
#include <LatAnalyze/StatArray.hpp>
#include <LatAnalyze/includes.hpp>
using namespace std;
@ -25,7 +25,7 @@ using namespace std;
namespace Latan
{
template <>
IoObject::IoType MatSample<double>::getType(void) const
IoObject::IoType StatArray<Mat<double>, -1>::getType(void) const
{
return IoType::dMatSample;
}

View File

@ -33,7 +33,7 @@ BEGIN_LATAN_NAMESPACE
* Array class with statistics *
******************************************************************************/
template <typename T, Index os = 0>
class StatArray: public Array<T, dynamic, 1>
class StatArray: public Array<T, dynamic, 1>, public IoObject
{
protected:
typedef Array<T, dynamic, 1> Base;
@ -60,8 +60,10 @@ public:
T variance(const Index pos = 0, const Index n = -1) const;
T varianceMatrix(const Index pos = 0, const Index n = -1) const;
T correlationMatrix(const Index pos = 0, const Index n = -1) const;
// IO type
virtual IoType getType(void) const;
public:
static const Index offset = os;
static constexpr Index offset = os;
};
// reduction operations
@ -77,12 +79,10 @@ namespace ReducOp
}
// Sample types
#define SAMPLE_OFFSET 1
const int central = -SAMPLE_OFFSET;
const int central = -1;
template <typename T>
using Sample = StatArray<T, SAMPLE_OFFSET>;
using Sample = StatArray<T, 1>;
typedef Sample<double> DSample;
typedef Sample<std::complex<double>> CSample;
@ -273,6 +273,13 @@ namespace ReducOp
}
}
// IO type /////////////////////////////////////////////////////////////////////
template <typename T, Index os>
IoObject::IoType StatArray<T, os>::getType(void) const
{
return IoType::noType;
}
END_LATAN_NAMESPACE
#endif // Latan_StatArray_hpp_

View File

@ -42,21 +42,21 @@ int main(int argc, char *argv[])
nSample = strTo<Index>(argv[3]);
outFileName = argv[4];
RandGen gen;
DMatSample res(nSample, 1, 1);
RandGen gen;
DSample res(nSample);
FOR_STAT_ARRAY(res, s)
{
if (s == central)
{
res[s](0, 0) = val;
res[s] = val;
}
else
{
res[s](0, 0) = gen.gaussian(val, err);
res[s] = gen.gaussian(val, err);
}
}
Io::save<DMatSample>(res, outFileName);
Io::save<DSample>(res, outFileName);
return EXIT_SUCCESS;
}

View File

@ -35,6 +35,108 @@ static void usage(const string &cmdName)
exit(EXIT_FAILURE);
}
template <typename T>
static void loadAndCheck(vector<T> &sample, const vector<string> &fileName)
{
const unsigned int n = sample.size();
Index nSample = 0;
cout << "-- loading data..." << endl;
for (unsigned int i = 0; i < n; ++i)
{
sample[i] = Io::load<T>(fileName[i]);
if (i == 0)
{
nSample = sample[i].size();
}
else if (sample[i].size() != nSample)
{
cerr << "error: number of sample mismatch (between '";
cerr << fileName[0] << "' and '" << fileName[i] << "')" << endl;
abort();
}
}
}
template <typename T>
static void combine(const string &outFileName __dumb,
const vector<T> &sample __dumb, const string &code __dumb)
{
abort();
}
template <>
void combine(const string &outFileName, const vector<DSample> &sample,
const string &code)
{
const unsigned int n = sample.size();
DoubleFunction f = compile(code, n);
DSample result(sample[0]);
DVec buf(n);
cout << "-- combining data..." << endl;
result = sample[0];
FOR_STAT_ARRAY(result, s)
{
for (unsigned int k = 0; k < n; ++k)
{
buf[k] = sample[k][s];
}
result[s] = f(buf);
}
cout << scientific;
cout << "central value:\n" << result[central];
cout << endl;
cout << "standard deviation:\n" << sqrt(result.variance());
cout << endl;
if (!outFileName.empty())
{
Io::save<DSample>(result, outFileName);
}
}
template <>
void combine(const string &outFileName, const vector<DMatSample> &sample,
const string &code)
{
const unsigned int n = sample.size();
DoubleFunction f = compile(code, n);
DVec buf(n);
DMatSample result(sample[0]);
cout << "-- combining data..." << endl;
FOR_STAT_ARRAY(result, s)
{
FOR_MAT(result[s], i, j)
{
for (unsigned int k = 0; k < n; ++k)
{
buf[k] = sample[k][s](i,j);
}
result[s](i, j) = f(buf);
}
}
cout << scientific;
cout << "central value:\n" << result[central];
cout << endl;
cout << "standard deviation:\n" << result.variance().cwiseSqrt();
cout << endl;
if (!outFileName.empty())
{
Io::save<DMatSample>(result, outFileName);
}
}
template <typename T>
void process(const string &outFileName, const vector<string> &fileName,
const string &code)
{
vector<T> sample(fileName.size());
loadAndCheck(sample, fileName);
combine(outFileName, sample, code);
}
int main(int argc, char *argv[])
{
// argument parsing ////////////////////////////////////////////////////////
@ -82,54 +184,16 @@ int main(int argc, char *argv[])
{
usage(cmdName);
}
// data loading ////////////////////////////////////////////////////////////
vector<DMatSample> sample(n);
Index nSample = 0;
cout << "-- loading data..." << endl;
for (unsigned int i = 0; i < n; ++i)
// process data ////////////////////////////////////////////////////////////
try
{
sample[i] = Io::load<DMatSample>(fileName[i]);
if (i == 0)
{
nSample = sample[i].size();
}
else if (sample[i].size() != nSample)
{
cerr << "error: number of sample mismatch (between '";
cerr << fileName[0] << "' and '" << fileName[i] << "')" << endl;
return EXIT_FAILURE;
}
process<DSample>(outFileName, fileName, code);
}
// combine data ////////////////////////////////////////////////////////////
DoubleFunction f = compile(code, n);
DVec buf(n);
DMatSample result(sample[0]);
cout << "-- combining data..." << endl;
FOR_STAT_ARRAY(result, s)
catch (bad_cast &e)
{
FOR_MAT(result[s], i, j)
{
for (unsigned int k = 0; k < n; ++k)
{
buf[k] = sample[k][s](i,j);
}
result[s](i, j) = f(buf);
}
process<DMatSample>(outFileName, fileName, code);
}
// output //////////////////////////////////////////////////////////////////
cout << scientific;
cout << "central value:\n" << result[central] << endl;
cout << "standard deviation:\n" << result.variance().cwiseSqrt() << endl;
if (!outFileName.empty())
{
Io::save<DMatSample>(result, outFileName);
}
return EXIT_SUCCESS;
}

View File

@ -35,14 +35,29 @@ int main(int argc, char *argv[])
string fileName = argv[1], copy = (argc >= 3) ? argv[2] : "";
cout << "-- loading sample from '" << fileName << "'..." << endl;
DMatSample s = Io::load<DMatSample>(fileName);
string name = Io::getFirstName(fileName);
cout << scientific;
cout << "central value:\n" << s[central] << endl;
cout << "standard deviation:\n" << s.variance().cwiseSqrt() << endl;
if (!copy.empty())
try
{
Io::save(s, copy, File::Mode::write, name);
DMatSample s = Io::load<DMatSample>(fileName);
string name = Io::getFirstName(fileName);
cout << scientific;
cout << "central value:\n" << s[central] << endl;
cout << "standard deviation:\n" << s.variance().cwiseSqrt() << endl;
if (!copy.empty())
{
Io::save(s, copy, File::Mode::write, name);
}
}
catch (bad_cast &e)
{
DSample s = Io::load<DSample>(fileName);
string name = Io::getFirstName(fileName);
cout << scientific;
cout << "central value:\n" << s[central] << endl;
cout << "standard deviation:\n" << sqrt(s.variance()) << endl;
if (!copy.empty())
{
Io::save(s, copy, File::Mode::write, name);
}
}
return EXIT_SUCCESS;