Menu

LocalCartesian::Forward interface

Anonymous
2018-09-12
2018-09-12
  • Anonymous

    Anonymous - 2018-09-12

    Dear dr. Karney,

    I have been using GeographicLib inside a real-time positioning project. Thanks for providing the source under very lenient terms. Although I can understand the philosophy behind the LocalCartesian::Forward (and Reverse) interface in terms of safety, it has struck me as cumbersome and less performant. In order to obtain the orientation matrix at the surface I need to perform the following:

    Matrix3x3 basis;
    std::vector<double> M(9);
    m_cartesian.Forward(latitude, longitude, altitudeEllipsoid, pos.x, pos.y, pos.z, M);
    std::copy(M.begin(), m_M.end(), &basis[0][0]);</double>

    The procedure involves: a dynamic memory allocation (9 doubles) and two copies (one inside Forward). In order to avoid this I've added an overloaded inline Forward member function to LocalCartesian.hpp:

    void Forward(real lat, real lon, real h, real& x, real& y, real& z, real* pM) const {
    IntForward(lat, lon, h, x, y, z, pM);
    }

    In fact, it would be sufficient to make IntForward public, but I didn't want to break the binary lib. With the newly added Forward the code looks like

    Matrix3x3 basis;
    m_cartesian.Forward(latitude, longitude, altitudeEllipsoid, pos.x, pos.y, pos.z, &basis[0][0]);

    This code has zero dynamic memory allocations and zero copies. The responsibility to provide a double array holding at least 9 doubles lies entirely by the client code and cannot be verified by the library, but as with many constructs in C++ this is a risk many are willing to take in favor of performance and usability. Would it be possible to add this Forward overload in future updates of LocalCartesian? You could even call it UnsafeForward, if you feel it is breaking the philosophy of the library. Thanks again for the great library.

    Kind regards,

    Gino

     
  • Charles Karney

    Charles Karney - 2018-09-12

    I understand that there's a cost to dynamic memory allocation (in
    creating the vector M). However, you can amortize this cost by
    declaring the vector M just once (e.g., before entering any loops).
    Then you are just left with the overhead of the copies. I assumed
    that this cost would be negligible in any realistic application. But
    perhaps you run some benchmarks to quantify this cost? Then I can see
    whether it's worth opening up access to the internal version.

     

Anonymous
Anonymous

Add attachments
Cancel