/* file EigenUtil.cpp * * author: Roland Conybeare, Sep 2022 */ #include "EigenUtil.hpp" #include "printjson/PrintJson.hpp" #include "reflect/Reflect.hpp" #include #include #include #include namespace xo { using xo::json::PrintJson; using xo::json::JsonPrinter; using xo::reflect::Reflect; using xo::reflect::TypeDescr; using VectorXb = Eigen::Array; using Eigen::VectorXd; using Eigen::MatrixXd; #ifdef NOT_YET namespace reflect { template using EigenVectorX_Tdx = xo::reflect::StlVectorTdx>; /* probably need this to appear before decl for class xo::reflect::Reflect */ template class EstablishTdx> { public: static std::unique_ptr make() { return EigenVectorX_Tdx::make(); } /*make*/ }; /*EstablishTdx*/ } /*reflect*/ #endif namespace eigen { namespace { /* prints a VectorXd as json, in the obvious format, e.g. * [1,2,3] */ template class EigenVectorJsonPrinter : public JsonPrinter { public: EigenVectorJsonPrinter(PrintJson const * pjson) : JsonPrinter(pjson) {} virtual void print_json(TaggedPtr tp, std::ostream * p_os) const override { EigenVectorType * pv = this->check_recover_native(tp, p_os); if (pv) { /* EigenVectorType (VectorXb, VectorXd, ..) * is reflected as atomic for now, out of expedience. * * as soon as we reflect as mt_vector, will not need this helper. */ *p_os << "["; for (std::uint32_t i = 0, n = pv->size(); i < n; ++i) { if (i > 0) *p_os << ","; /* note: need to dispatch via json printer for vector elements, * to get special treatment for non-finite values */ this->pjson()->print((*pv)[i], p_os); //*p_os << jsonp((*pv)[i], this->pjson()); } *p_os << "]"; } } /*print_json*/ }; /*EigenVectorJsonPrinter*/ /* prints a MatrixXd as json, in row-major format, e.g. * [[1,2,3], [4,5,6], [7,8,9]] */ class MatrixXdJsonPrinter : public JsonPrinter { public: MatrixXdJsonPrinter(PrintJson const * pjson) : JsonPrinter(pjson) {} virtual void print_json(TaggedPtr tp, std::ostream * p_os) const override { MatrixXd * pm = this->check_recover_native(tp, p_os); if (pm) { /* MatrixXd is reflected as atomic for now, out of expedience */ *p_os << "["; for(std::uint32_t i=0, m=pm->rows(); i 0) *p_os << ", "; *p_os << "["; for(std::uint32_t j=0, n=pm->cols(); j 0) *p_os << ","; /* note: need to dispatch via json printer for matrix elements, * to get special treatment for non-finite values */ this->pjson()->print((*pm)(i, j), p_os); //*p_os << jsonp((*pm)(i, j), this->pjson()); } *p_os << "]"; } *p_os << "]"; } } /*print_json*/ }; /*MatrixXdJsonPrinter*/ template void provide_eigen_vector_printer(PrintJson * p_pjson) { TypeDescr td = Reflect::require(); std::unique_ptr pr(new EigenVectorJsonPrinter(p_pjson)); p_pjson->provide_printer(td, std::move(pr)); } /*provide_eigen_vector_printer*/ } /*namespace*/ void EigenUtil::reflect_eigen() { #ifdef NOT_YET Reflect::require(); Reflect::require(); #endif } /*reflect_eigen*/ void EigenUtil::provide_json_printers(PrintJson * p_pjson) { assert(p_pjson); provide_eigen_vector_printer(p_pjson); provide_eigen_vector_printer(p_pjson); { TypeDescr td = Reflect::require(); std::unique_ptr pr(new MatrixXdJsonPrinter(p_pjson)); p_pjson->provide_printer(td, std::move(pr)); } } /*provide_json_printers*/ } /*namespace eigen*/ } /*namespace xo*/ /* end EigenUtil.cpp */