A job for lambda expressions?

Discussion in 'C++' started by Rune Allnor, Mar 8, 2010.

  1. Rune Allnor

    Rune Allnor Guest

    Hi all.

    I am working on an application to process geometric (x,y,z) data
    measured in a physical world. The application relies heavily on
    the user interacting with the data through a GUI.

    In particular, both the 'world data' and the 'screen data' require
    much the same types of operations:

    - Select bounding polygons.
    - Preprocess / regularize the polygons.
    - Identify whether data points are enclosed or not, by the polygon.

    The algorithms in both cases are the same. The semantics differ.
    For instance, my xyzpoint<T> class addresses the x coordinate
    of the individual point p as

    xyzpoint<float> p;
    float x = p.x();

    whereas the Qt GUI library addresses the x coordinate of a point
    on the screen as something like

    QGraphicsItem *item = new SomeGraphicsItem;
    item->pos().x();

    So I would save a lot of duplicate work if I could somehow introduce
    the exact semantics of addressing the individual coordinates of the
    data points as variables.

    Could lambda expressions be used for this?
    Or are there other ways to achieve the same end?

    Rune
     
    Rune Allnor, Mar 8, 2010
    #1
    1. Advertising

  2. Hi,

    Rune Allnor wrote:
    > So I would save a lot of duplicate work if I could somehow introduce
    > the exact semantics of addressing the individual coordinates of the
    > data points as variables.
    >
    > Could lambda expressions be used for this?
    > Or are there other ways to achieve the same end?


    there are a several possibilities, since the number of different cases
    are limited.

    - Use a function pointer to retrieve the desired information.
    (Only if you are context free.)

    - Use an interface with the desired methods.
    The implementing class could carry the context.

    - Use templates and functors.
    This has the advantage of almost no runtime overhead and is in fact
    the base of lambda expressions.


    If I had the choice, I would prefer the second solution unless the
    performance becomes undesirable.


    Marcel
     
    Marcel Müller, Mar 8, 2010
    #2
    1. Advertising

  3. Rune Allnor

    Rune Allnor Guest

    On 8 Mar, 15:44, Marcel Müller <> wrote:
    > Hi,
    >
    > Rune Allnor wrote:
    > > So I would save a lot of duplicate work if I could somehow introduce
    > > the exact semantics of addressing the individual coordinates of the
    > > data points as variables.

    >
    > > Could lambda expressions be used for this?
    > > Or are there other ways to achieve the same end?

    >
    > there are a several possibilities, since the number of different cases
    > are limited.
    >
    > - Use a function pointer to retrieve the desired information.
    >    (Only if you are context free.)
    >
    > - Use an interface with the desired methods.
    >    The implementing class could carry the context.
    >
    > - Use templates and functors.
    >    This has the advantage of almost no runtime overhead and is in fact
    >    the base of lambda expressions.
    >
    > If I had the choice, I would prefer the second solution unless the
    > performance becomes undesirable.


    While performance questions might be more or less irrelevant
    in the case of GUI interaction, they *are* an issue when
    processing the measured data.

    Rune
     
    Rune Allnor, Mar 8, 2010
    #3
  4. Rune Allnor wrote:
    > While performance questions might be more or less irrelevant
    > in the case of GUI interaction, they *are* an issue when
    > processing the measured data.


    Sure, but it depends on what you are doing with the returned data. If
    there are several dozen math operations with each data point in avarage,
    then the additional function call will not harm significantly.

    On the other side, if you call these functions over and over, the
    overhead may be harmful.


    Marcel
     
    Marcel Müller, Mar 8, 2010
    #4
  5. On Mar 8, 10:57 pm, Rune Allnor <> wrote:
    > ...
    > The algorithms in both cases are the same. The semantics differ.
    > For instance, my xyzpoint<T> class addresses the x coordinate
    > of the individual point p as
    >
    > xyzpoint<float> p;
    > float x = p.x();
    >
    > whereas the Qt GUI library addresses the x coordinate of a point
    > on the screen as something like
    >
    > QGraphicsItem *item = new SomeGraphicsItem;
    > item->pos().x();
    >
    > So I would save a lot of duplicate work if I could somehow introduce
    > the exact semantics of addressing the individual coordinates of the
    > data points as variables.
    >
    > Could lambda expressions be used for this?
    > Or are there other ways to achieve the same end?


    Perhaps I'm missing something... what's wrong with the obvious?

    inline float get_x(QGraphicsItem* p) { return p->pos().x(); }
    inline float get_x(xyzpoint<float>& xyz) { return xyz.x(); }

    Cheers,
    Tony
     
    Anthony Delroy, Mar 9, 2010
    #5
  6. Rune Allnor

    Rune Allnor Guest

    On 9 Mar, 02:27, Anthony Delroy <> wrote:
    > On Mar 8, 10:57 pm, Rune Allnor <> wrote:
    > > ...
    > > The algorithms in both cases are the same. The semantics differ.
    > > For instance, my xyzpoint<T> class addresses the x coordinate
    > > of the individual point p as

    >
    > > xyzpoint<float> p;
    > > float x = p.x();

    >
    > > whereas the Qt GUI library addresses the x coordinate of a point
    > > on the screen as something like

    >
    > > QGraphicsItem *item = new SomeGraphicsItem;
    > > item->pos().x();

    >
    > > So I would save a lot of duplicate work if I could somehow introduce
    > > the exact semantics of addressing the individual coordinates of the
    > > data points as variables.

    >
    > > Could lambda expressions be used for this?
    > > Or are there other ways to achieve the same end?

    >
    > Perhaps I'm missing something... what's wrong with the obvious?
    >
    >     inline float get_x(QGraphicsItem* p) { return p->pos().x(); }
    >     inline float get_x(xyzpoint<float>& xyz) { return xyz.x(); }


    First of all that my algorithm library needs to be aware
    of the various types of points it might have to work on.
    I'd prefer it not to.

    Second, an issue I have not mentioned here - that in the
    data analysis application the algorithms might have to
    work along different dimensions. Some times one needs to
    work in the (x,y) plane. At other times one needs to work
    in the (y,z) or (x,z) planes. There are too many possible
    uses to individually implement each one specifically. And
    once one have done it for the data analysis application,
    one really would like to benefit from all that hard work
    when one needs the same functionality in a 'mere' GUI.

    A nifty way of parametrizing the coordinate access methods,
    that did not introduce additional run-time overhead, would
    work wonders.

    After having browsed a few books and pages, it seems that
    I need much the same functionality that boost::bind offers.
    Or am I wrong?

    Rune
     
    Rune Allnor, Mar 9, 2010
    #6
  7. On Mar 9, 6:10 pm, Rune Allnor <> wrote:
    > On 9 Mar, 02:27, Anthony Delroy <> wrote:
    >
    >
    >
    > > On Mar 8, 10:57 pm, Rune Allnor <> wrote:
    > > > ...
    > > > The algorithms in both cases are the same. The semantics differ.
    > > > For instance, my xyzpoint<T> class addresses the x coordinate
    > > > of the individual point p as

    >
    > > > xyzpoint<float> p;
    > > > float x = p.x();

    >
    > > > whereas the Qt GUI library addresses the x coordinate of a point
    > > > on the screen as something like

    >
    > > > QGraphicsItem *item = new SomeGraphicsItem;
    > > > item->pos().x();

    >
    > > > So I would save a lot of duplicate work if I could somehow introduce
    > > > the exact semantics of addressing the individual coordinates of the
    > > > data points as variables.

    >
    > > > Could lambda expressions be used for this?
    > > > Or are there other ways to achieve the same end?

    >
    > > Perhaps I'm missing something... what's wrong with the obvious?

    >
    > >     inline float get_x(QGraphicsItem* p) { return p->pos().x(); }
    > >     inline float get_x(xyzpoint<float>& xyz) { return xyz.x(); }

    >
    > First of all that my algorithm library needs to be aware
    > of the various types of points it might have to work on.
    > I'd prefer it not to.


    Your algorithms don't have to be aware. Consider:

    #include <iostream>

    class Point1
    {
    public:
    Point1(int x, int y) : x_(x), y_(y) { }

    int x() const { return x_; }
    int y() const { return y_; }

    friend std::eek:stream& operator<<(std::eek:stream& os, const Point1& p)
    {
    return os << '(' << p.x_ << ',' << p.y_ << ')';
    }

    private:
    int x_, y_;
    };

    class Point2
    {
    public:
    Point2(int x, int y) : x_(x), y_(y) { }

    int get_x() const { return x_; }
    int get_y() const { return y_; }

    private:
    int x_, y_;
    };

    inline int get_x(const Point1& p1) { return p1.x(); }
    inline int get_x(const Point2* p_p2) { return p_p2->get_x(); }
    inline int get_y(const Point1& p1) { return p1.y(); }
    inline int get_y(const Point2* p_p2) { return p_p2->get_y(); }

    template <typename PointA, typename PointB>
    Point1 mid(const PointA& a, const PointB& b)
    {
    return Point1((get_x(a) + get_x(b)) / 2, (get_y(a) + get_y(b)) /
    2);
    }

    int main()
    {
    Point1 p1(1, 3);
    Point2* p2 = new Point2(5, 9);
    std::cout << mid(p1, p2) << '\n';
    }

    Another alternative is to template the algorithm with a policy
    specifying how to access the points:

    template <class Point, class Access>
    void algo(...)
    {
    ... Access::get_x(my_point) ...
    }

    (Good idea to read Modern C++ Design by Andrei Alexandrescu if you
    haven't already.)

    These are all compile time adaptations.

    > Second, an issue I have not mentioned here - that in the
    > data analysis application the algorithms might have to
    > work along different dimensions. Some times one needs to
    > work in the (x,y) plane. At other times one needs to work
    > in the (y,z) or (x,z) planes. There are too many possible
    > uses to individually implement each one specifically. And
    > once one have done it for the data analysis application,
    > one really would like to benefit from all that hard work
    > when one needs the same functionality in a 'mere' GUI.
    >
    > A nifty way of parametrizing the coordinate access methods,
    > that did not introduce additional run-time overhead, would
    > work wonders.
    >
    > After having browsed a few books and pages, it seems that
    > I need much the same functionality that boost::bind offers.
    > Or am I wrong?


    I haven't got my head around how you might want to access these
    planes, so am not sure.

    Cheers,
    Tony
     
    Anthony Delroy, Mar 10, 2010
    #7
  8. Rune Allnor

    Rune Allnor Guest

    On 10 Mar, 03:43, Anthony Delroy <> wrote:
    > On Mar 9, 6:10 pm, Rune Allnor <> wrote:


    > > Second, an issue I have not mentioned here - that in the
    > > data analysis application the algorithms might have to
    > > work along different dimensions. Some times one needs to
    > > work in the (x,y) plane. At other times one needs to work
    > > in the (y,z) or (x,z) planes. There are too many possible
    > > uses to individually implement each one specifically. And
    > > once one have done it for the data analysis application,
    > > one really would like to benefit from all that hard work
    > > when one needs the same functionality in a 'mere' GUI.

    >
    > > A nifty way of parametrizing the coordinate access methods,
    > > that did not introduce additional run-time overhead, would
    > > work wonders.

    >
    > > After having browsed a few books and pages, it seems that
    > > I need much the same functionality that boost::bind offers.
    > > Or am I wrong?

    >
    > I haven't got my head around how you might want to access these
    > planes, so am not sure.


    All you need to do is to decide which of the coordinates
    is the ordinate and which is the abscissa. In the (x,y)
    case you use x as the ordinate and y as the abscissa.
    In the (y,z) case you use y as the ordinate and z as the
    abscissa, and so on. Apart from that, all the algorithms
    are the same.

    What one needs is the internal functions

    T ordinate(const point_t&);
    T abscissa(const point_t&);

    that can be called on each element (preferably with the
    element staying oblivious to the context), and a way to
    overload the implementations of those functions. And an
    as loose way as possible to couple the implementation to
    the point classes in question.

    As far as I can tell - which isn't very far - it's the
    same mechanism (whichever mechanism that might be) that
    is required to flip the ordinate-abscissa pair for a given
    class of points, as is needed to specify the implementation
    of the ordinate/abscissa access functions for some other
    class of points.

    Coming to think of it, it seems an interface along the
    lines of

    template<class T, class point_t, class result_t>
    result_t& process_data(std::vector<point_t>,
    T ordinate(const point_t&),
    T abscissa(const point_t&));

    where one could use boost::bind to specify the ordinate
    and abscissa access functions, might be what I am looking
    for...

    Rune
     
    Rune Allnor, Mar 10, 2010
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roman Suzi
    Replies:
    13
    Views:
    614
    Bengt Richter
    Jan 7, 2005
  2. Paul Miller
    Replies:
    12
    Views:
    467
    Paul Miller
    Apr 28, 2005
  3. Casey Hawthorne
    Replies:
    6
    Views:
    379
    Dennis Lee Bieber
    Jul 21, 2006
  4. Steve Dogers

    lambda vs non-lambda proc

    Steve Dogers, Mar 30, 2009, in forum: Ruby
    Replies:
    1
    Views:
    187
    Sean O'Halpin
    Mar 30, 2009
  5. Haochen Xie
    Replies:
    4
    Views:
    251
    Haochen Xie
    Mar 17, 2013
Loading...

Share This Page