Write an Eigen Matrix to json file using nlohmann json using to_json method

387 views Asked by At

I have an Eigen matrix defined -

template <typename T>
using Vec3 = Eigen::Matrix<T, 1, 3, Eigen::DontAlign | Eigen::ColMajor>;
using Vec3d = Vec3<double>;

I try to write Vec3d to json file like below -

template <typename T>
void to_json(json& j, const Vec3<T>& v) {
    j = {{"X", v(0)}, {"Y", v(1)}, {"Z", v(2)}};
}

// Usage
Vec3d test(1.f, 2.f, 3.f);
frameJson["Vec3d"] = test;

Output is stored as an array and not like the way specified in to_json, seems like it is not entering the to_json ??

"Vec3d": [
 1.0,
 2.0,
 3.0
]

But I want it like the way specified in to_json like below -

"Vec3d": [
 "X": 1.0,
 "Y": 2.0,
 "Z": 0.0
]

Is something wrong in the way templated to_json is implemented. How do I make this work.

PS : Also how would the templated adl_serializer from_json() look like while reading ?

1

There are 1 answers

3
pptaszni On BEST ANSWER

I failed to find where the default Eigen::Matrix json serializer is implemented, but to have your custom serializer working, just put it inside Eigen namespace:

namespace Eigen
{
    template <typename T>
    void to_json(json& j, const Vec3<T>& v) {
    j = {{"X", v(0)}, {"Y", v(1)}, {"Z", v(2)}};
}

Alternatively, like suggested in the documentation for third-party types serialization, you can write adl_serializer specialization:

namespace nlohmann {
    template <typename T>
    struct adl_serializer<Vec3<T>> {
        static void to_json(json& j, const Vec3<T>& v) {
            j = {{"X", v(0)}, {"Y", v(1)}, {"Z", v(2)}};
        }
        static void from_json(const json& j, Vec3<T>& v) {
            v(0) = j["X"];
            v(1) = j["Y"];
            v(2) = j["Z"];
        }
    };
}

Second option might be preferable in general, as it doesn't pollute your third-party namespace.

Demo