curve and curve with error objects : sorting , friend

Discussion in 'C++' started by Hicham Mouline, Sep 14, 2009.

  1. Hello,

    I have a Curve class that holds variable data
    x f(x)
    ------ ---------
    0.5 7.8
    0.9 6.7
    -5.4 6.6
    0.0 6.6
    1.5 7.8

    and a CurveWithError object that holds data as
    x f(x) error
    ------ --------- ----------
    0.5 7.8 0.1
    0.9 6.7 0.2
    -5.4 6.6 0.05
    0.0 6.6 0.1
    1.5 7.8 0.05

    I maintain the Curve object sorted at all times. In particular, the last
    thing done by Curve::Curve(...) is to sort the data based on x.

    I implemented CurveWithError with the help of Curve so that

    class CurveWithError {
    private:
    Curve mCurve;
    ContainerType mErrors;
    };

    I am trying to implement CurveWithError ctor in a way that I maintain the
    invariant of sorted Curve.

    in pseudo-code:
    // xbegin is the iterator that points to the beginning of the sequence of
    x's
    // xend is the iterator that points to the end of the sequence of f(x)'s
    // fbegin is the iterator that points to the beginning of the sequence of
    f(x)'s
    // ferrbegin is the iterator that points to the beginning of the sequence of
    errors
    CurveWithError::CurveWithError(... xbegin, .... xend, .... fbegin,
    ....ferrbegin )
    : mCurve( xbegin, xend, fbegin), // the Curve ctor finished by sorting its
    internal container based on the x's
    mErrors(xend-xbegin)
    {
    // I should sort mErrors as well in the same order Curve sorted its
    container
    }

    Ideas to implement this are welcome.

    regards,
     
    Hicham Mouline, Sep 14, 2009
    #1
    1. Advertising

  2. Hicham Mouline wrote:
    > I have a Curve class that holds variable data
    > x f(x)
    > ------ ---------
    > 0.5 7.8
    > 0.9 6.7
    > -5.4 6.6
    > 0.0 6.6
    > 1.5 7.8
    >
    > and a CurveWithError object that holds data as
    > x f(x) error
    > ------ --------- ----------
    > 0.5 7.8 0.1
    > 0.9 6.7 0.2
    > -5.4 6.6 0.05
    > 0.0 6.6 0.1
    > 1.5 7.8 0.05
    >
    > I maintain the Curve object sorted at all times. In particular, the last
    > thing done by Curve::Curve(...) is to sort the data based on x.
    >
    > I implemented CurveWithError with the help of Curve so that
    >
    > class CurveWithError {
    > private:
    > Curve mCurve;
    > ContainerType mErrors;
    > };
    >
    > I am trying to implement CurveWithError ctor in a way that I maintain the
    > invariant of sorted Curve.
    >
    > in pseudo-code:
    > // xbegin is the iterator that points to the beginning of the sequence of
    > x's
    > // xend is the iterator that points to the end of the sequence of f(x)'s
    > // fbegin is the iterator that points to the beginning of the sequence of
    > f(x)'s
    > // ferrbegin is the iterator that points to the beginning of the sequence of
    > errors
    > CurveWithError::CurveWithError(... xbegin, .... xend, .... fbegin,
    > ...ferrbegin )
    > : mCurve( xbegin, xend, fbegin), // the Curve ctor finished by sorting its
    > internal container based on the x's
    > mErrors(xend-xbegin)
    > {
    > // I should sort mErrors as well in the same order Curve sorted its
    > container
    > }
    >
    > Ideas to implement this are welcome.


    What seemed like a good idea at the time (to use inheritance) perhaps
    isn't so hot, at the second look. The 'Curve' type has a closed design,
    it keeps and sorts its own data, and without it providing some interface
    to expose the sorting order your attempts aren't going to be successful.

    I would probably consider two approaches: one is that a Curve should
    keep the sorting order in a separate array (basically a permutation
    vector) which you could later use to rearrange whatever else you need.
    Just ask the curve what the new arrangement is, then move your objects
    (in your case the 'error' values) around according to it. Another is to
    make your 'Curve' a template and tell to to store (and sort) whatever
    you need stored and sorted. Here is a mock-up:

    template<class T> class CurveT {
    std::vector<double> internal_container_of_x;
    public:
    template<class ItX, class ItData> CurveT(It xbegin, It xend,
    ItData dbegin, ItData dend);
    }; // the c-tor does the sorting

    class Curve : public CurveT<double> {
    std::vector<double> eff_of_ex; // your f(x)
    public:
    Curve(...) : CurveT<double>(...,
    eff_of_ex.begin(), eff_of_ex(end)) { ... }
    };

    class CurveWithError : public CurveT<std::pair<double,double> >
    std::deque<std::pair<double,double> > eff_and_error;
    public:
    CurveWithError(...) : CurveT<std::pair<double,double> >(...,
    eff_and_error.begin(), eff_and_error(end)) { ... }
    };

    (here I use ... as omitted code, not the variable number of args).

    Of course, in this implementation, 'Curve' and 'CurveWithError' are not
    related. You can make them related if you extract the data storage
    mechanism into a separate type (abstract in case of 'Curve', for
    example, and concrete in case of 'CurveWithError'). That's essentially
    a third way (a bit more convoluted) to design this. It would allow you
    to both keep the classes related (and use run-time polymorphism if you
    need to), and make it generic enough so you can later extend the whole
    thing to store more than just pairs of doubles.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 14, 2009
    #2
    1. Advertising

  3. Hicham Mouline

    Jerry Coffin Guest

    In article <4aae3687$0$286$>,
    says...
    >
    > Hello,
    >
    > I have a Curve class that holds variable data


    [ examples elided ]

    > I maintain the Curve object sorted at all times. In particular, the
    > last thing done by Curve::Curve(...) is to sort the data based on
    > x.


    [ ... ]

    > I am trying to implement CurveWithError ctor in a way that I
    > maintain the invariant of sorted Curve.


    It seems to me that you're combining a couple of rather different
    concerns. I'd have one class for data about a point, and a completely
    separate class for storing that data:

    struct Point {
    double x, f_x;

    bool operator<(Point const &other) {
    return x < other.x;
    }
    };

    struct PointWithError : public Point {
    double error;
    };

    Template <class Point>
    class SortedVector {
    std::vector<Point> points;
    public:
    SortedVector(/* ... */) {
    // ...
    std::sort(points.begin(), points.end());
    }
    };

    typedef SortedVector<Point> Curve;
    typedef SortedVector<PointWithError> CurveWithError;

    --
    Later,
    Jerry.
     
    Jerry Coffin, Sep 14, 2009
    #3
    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. Jeremy S.

    Learning Curve on 2.0

    Jeremy S., Sep 9, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    399
    clintonG
    Sep 10, 2005
  2. =?Utf-8?B?ZGF2aWQ=?=
    Replies:
    0
    Views:
    359
    =?Utf-8?B?ZGF2aWQ=?=
    Feb 16, 2006
  3. 7stud
    Replies:
    11
    Views:
    717
    Dennis Lee Bieber
    Mar 20, 2007
  4. Jason
    Replies:
    0
    Views:
    399
    Jason
    Oct 4, 2006
  5. Peter
    Replies:
    2
    Views:
    288
    Öö Tiib
    Jun 6, 2013
Loading...

Share This Page