design choice

Discussion in 'C++' started by Hicham Mouline, May 27, 2008.

  1. Hello,
    i am writing a curve class that is supposed to represent a mathematic
    function from n tabbulated data (xi,yi) , 0<= i < n
    the curve will be used internally to my library by its templated derived
    classes only, these templated derived classes are user-visible though,
    and so are the template argument types

    template <typename Interpolator, typename Extrapolator, typename Integrator>
    class Curve {
    virtual ~Curve() {} //
    double& operator()(double x); // To set a
    tabbulated point, might resize/sort the data container
    double operator()(double x) const; // To
    interpolate a point
    double integral( double xmin, double xmax ) const; // returns the
    integral based on the Integrator
    // tabbulated private data container

    1) I have 4 interpolators
    1.1 Constant => assumes the function is a stair-like function constant
    discontinuous segments in [xi, xi+1]
    1.2 Linear => the function is continuous linear segments over [xi, xi+1]
    1.3 Polynomial => the interpolated function is a (n-1) order polynomial
    that passes through the n data points,
    or m-order polynomial that interpolates over
    the m closest points to the desired x
    1.4 Cubic splines => a collection of local cubic polynomials over
    individual intervals that provides f'' continuity

    2) I have tested these data holders for performance
    2.0 double xarr[], double yarr[]
    2.1 double data[][2]
    2.2 std::map<double, double>
    2.3 std::vector<double> xarr std::vector<double> yarr
    2.4 std::vector< std::pair<double, double> >
    2.5 boost::multi_array<double, 2>

    In most cases, calls to operator() const are have the highest performance
    requirements, but in other cases,
    calls to operator() (non-const) have that.

    3) here are the various inter/extrapolators:
    class Constant {
    static interpolate( // <dataholder> , double x);

    class Linear {
    static interpolate( // <dataholder> , double x);

    class Polynomial {
    static interpolate( // <dataholder> , double x);

    Unfortunately, where map works well for Constant /Linear, it doesn't for
    Polynomial which requires random access to the container for the
    interpolation. so 2.2 doesn't work for that. However, inserting data points
    in the container doesn't work well for all the 2) that are not 2.2, as it
    requires reallocation and resorting.

    Should i write partial template spec of Curve to have an appropriate private
    data container for the relevant interpolator?
    The static function signatures in the various interpolators will be
    different. Is there a way to use iterators in order to have an identical
    How can I/should I hide the need to choose different containers for
    performance reasons?

    Hicham Mouline, May 27, 2008
    1. Advertisements

  2. Hello,

    "Stuart Golodetz" <> wrote in message
    > As far as the first question goes (and just off the top of my head), you
    > may be able to avoid partially specializing Curve if you define a
    > templated DataContainer type and partially specialize that instead. In
    > other words, something like:
    > template <typename Interpolator> struct DataContainer;
    > template <> struct DataContainer<Constant>
    > {
    > typedef std::map<double,double> type;
    > };
    > etc.
    > template <typename Interpolator, typename Extrapolator, typename
    > Integrator>
    > class Curve
    > {
    > // can use (typename) DataContainer<Interpolator>::type here
    > };
    > Just a thought anyway...
    > Note that this provides one possible solution to your problem with the
    > function signatures: for example, Constant::interpolate now takes a
    > DataContainer<Constant>& as its first argument, etc.

    this works well, thank you.

    i have 1 more question:
    I would do this:
    template <> struct DataContainer<Constant>
    typedef std::map<double,double> type;

    template <> struct DataContainer<Ploynomial>
    typedef struct {
    double* data[2];
    size_t size;
    } type;

    However, in Curve<Polynomial>, i have
    double& operator(double x); // to insert a new x in the tabulated data

    for Constant with map, this is trivial {
    return map[x];

    for Polynomial, with double*[2]
    i have to manage it myself, the sorting/inserting into the array,
    it seems like redundant work thatt can be done better by stdlib c++

    is there a way to get double*[2] frm map<double, double> (i cuold write it)
    should i keep both map<double, double> and the double*[2] for the case of
    using the map for inserting, and then using the double*[2] to do the
    (because it requires random access iterators)

    Hicham Mouline, May 29, 2008
    1. Advertisements

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. Mickey Segal
    Mickey Segal
    Feb 2, 2004
  2. Replies:
    John C. Bollinger
    Jun 6, 2005
  3. deancoo
    Ioannis Vranos
    Feb 17, 2005
  4. Divick
    Daniel T.
    Mar 18, 2006
  5. miles.jg
    Alf P. Steinbach
    Nov 14, 2007

Share This Page