#include <armadillo>
#include <h5cpp/all>
#include <cmath>
#include <iostream>
#include <string>
namespace {
int errors = 0;
template <class A, class B>
void check(const char* tag, const A& expected, const B& got, double tol = 1e-12) {
const double err = std::abs(static_cast<double>(expected - got));
const bool ok = (err <= tol);
if (!ok) ++errors;
<< tag << " (expected=" << expected
<< " got=" << got << ")\n";
}
H5T_conv_ret_t clamp_to_int16(H5T_conv_except_t except_type,
hid_t , hid_t ,
void* , void* dst_buf,
void* ) {
switch (except_type) {
case H5T_CONV_EXCEPT_TRUNCATE: return H5T_CONV_UNHANDLED;
default: return H5T_CONV_UNHANDLED;
}
}
}
int main() {
{
arma::mat M(4, 7); M.ones();
h5::data_transform{"2*x + 5"});
check("write transform 2*x+5 stored as 7", 7.0, back(0, 0));
}
{
h5::data_transform{"x/2 - 1"});
check("read transform x/2-1 of stored 7", 2.5, m(0, 0));
}
{
arma::mat M(3, 3); M.fill(10.0);
h5::data_transform{"x*3 + 2"});
h5::data_transform{"(x-2)/3"});
check("round-trip via (3x+2 write) ∘ ((x-2)/3 read) → identity",
10.0, decoded(0, 0));
}
{
arma::mat celsius(2, 3);
celsius << 0.0 << 25.0 << 100.0 << arma::endr
<< -40.0 << 37.0 << -273.15 << arma::endr;
h5::write(fd,
"/temperature/kelvin", celsius,
h5::data_transform{"x + 273.15"});
check("Celsius 0 → Kelvin 273.15 on disk", 273.15, kelvin(0, 0));
check("Celsius 100 → Kelvin 373.15 on disk", 373.15, kelvin(0, 2));
check("Celsius -273.15 → Kelvin 0 on disk", 0.0, kelvin(1, 2));
h5::data_transform{"x - 273.15"});
check("Kelvin → Celsius round-trip", 25.0, round_trip(0, 1));
}
{
arma::mat wide(1, 4);
wide << 0.0 << 100.0 << 50'000.0 << -50'000.0 << arma::endr;
check(
"int16 in-range value 0",
std::int16_t(0), narrowed(0, 0));
check(
"int16 in-range value 100",
std::int16_t(100), narrowed(0, 1));
check(
"int16 overflow clamped to INT16_MAX",
std::int16_t(32767), narrowed(0, 2));
check(
"int16 underflow clamped to INT16_MIN",
std::int16_t(-32768), narrowed(0, 3));
}
{
arma::mat M(8, 16); M.fill(2.5);
h5::data_transform{"x * 4"});
check("transform composed with chunk + gzip on write", 10.0, back(3, 5));
}
<< (errors == 0 ? "✔ all checks passed"
: "✘ some checks failed")
<< ", errors=" << errors << "\n";
return errors;
}
h5::at_t create(const hid_t &parent, const std::string &path, args_t &&... args)
Create a new attribute of element type T on a parent HDF5 object.
Definition H5Acreate.hpp:100
T aread(const hid_t &ds, const std::string &name, const h5::acpl_t &acpl=h5::default_acpl)
Read an attribute by name and return its value as type T.
Definition H5Aread.hpp:76
h5::gr_t write(const LOC &parent, const std::string &path, const T &src)
Write a sparse matrix or vector as a CSC group.
Definition H5Dsparse.hpp:185