Using a pointer to member function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • cupiemayo

    Using a pointer to member function

    Hello. I'm trying to make a sort of generic integral class, holding
    the boundary values and the integrand. Eventually I'd like to use it
    inside a class, like the example below. I think the problem is that
    in order to pass a member function, I have to qualify the name a bit
    differently, for example:

    typedef double (astro::univers e::*pfn)(double );

    (by the way, I don't think this actually worked...) But doing this
    sort of thing of course doesn't make the integral class generic enough.

    I'd like to get some advices as to how I can make such an integral
    class that even a member function can be passed easily as the
    integrand. How can you do this using C++?

    Thanks in advance...



    ----------------------------------------------------------------

    #include <cmath>
    #include <iostream>
    #include <string>
    #include <vector>

    namespace math {

    typedef double (*pfn)(double);

    class integral
    {
    public:
    integral(double a, double b, pfn f)
    : lower_(a), upper_(b), integrand_(f)
    {}

    double lower_bound() const { return lower_; }
    double upper_bound() const { return upper_; }
    void change_bounds(d ouble a, double b)
    {
    lower_ = a;
    upper_ = b;
    }
    double simpson(unsigne d int const n) const
    {
    double h = (upper_ - lower_) / n;
    double sum = integrand_(lowe r_) * 0.5;
    for (int i = 1; i < n; ++i)
    sum += integrand_(lowe r_ + i * h);
    sum += integrand_(uppe r_) * 0.5;

    double summid = 0.0;
    for (int i = 1; i <= n; ++i)
    summid += integrand_(lowe r_ + (i - 0.5)*h);

    return (sum + 2 * summid) * h / 3.0;
    }

    private:
    double lower_;
    double upper_;
    pfn integrand_;
    };

    } // namespace math

    namespace astro {

    class universe
    {
    public:
    universe(double const omega_matter,
    double const omega_lambda,
    double const hubble_const)
    : omega_matter_(o mega_matter),
    omega_lambda_(o mega_lambda),
    hubble_const_(h ubble_const)
    {}

    double comoving_distan ce(double z)
    {
    //
    // Want to use a generic integral class above with
    // the integrand astro::universe ::inverse_e(dou ble),
    // but does not compile....
    //
    math::integral func(0.0, z, inverse_e);

    double speed_of_light = 3.0e8;
    double c_cgs = speed_of_light * (100.0);
    double H0_cgs = hubble_const_ * (1.0 / 3.0856776e19);

    return (c_cgs / H0_cgs) * func.simpson(10 00);
    }

    private:
    double hubble_const_;
    double omega_matter_;
    double omega_lambda_;

    double inverse_e(doubl e z)
    {
    return 1.0 / std::sqrt(omega _matter_ * std::pow(1 + z, 3)
    + omega_lambda_);
    }
    };

    } // namespace astro

    int main()
    {
    //
    // Create a universe with a particular cosmology.
    //
    astro::universe uni(0.3, 0.7, 70.0);

    //
    // Compute a comoving distance to an object at redshift 0.4.
    //
    std::cout << uni.comoving_di stance(0.4) << '\n';

    return 0;
    }
  • WW

    #2
    Re: Using a pointer to member function

    cupiemayo wrote:[color=blue]
    > Hello. I'm trying to make a sort of generic integral class, holding
    > the boundary values and the integrand. Eventually I'd like to use it
    > inside a class, like the example below. I think the problem is that
    > in order to pass a member function, I have to qualify the name a bit
    > differently, for example:
    >
    > typedef double (astro::univers e::*pfn)(double );
    >
    > (by the way, I don't think this actually worked...) But doing this
    > sort of thing of course doesn't make the integral class generic
    > enough.
    >
    > I'd like to get some advices as to how I can make such an integral
    > class that even a member function can be passed easily as the
    > integrand. How can you do this using C++?[/color]

    Look at boost::function ( http://www.boost.org ). It might provide the
    facility you are looking for. Might I say since you did not care to make
    the smallest compilable code for your posts illiustration purposes, so I did
    not care reading the code with my headache. :-(

    --
    WW aka Attila


    Comment

    • Frank Schmitt

      #3
      Re: Using a pointer to member function

      cupiemayo@yahoo .com (cupiemayo) writes:
      [color=blue]
      > Hello. I'm trying to make a sort of generic integral class, holding
      > the boundary values and the integrand. Eventually I'd like to use it
      > inside a class, like the example below. I think the problem is that
      > in order to pass a member function, I have to qualify the name a bit
      > differently, for example:
      >
      > typedef double (astro::univers e::*pfn)(double );
      >
      > (by the way, I don't think this actually worked...) But doing this
      > sort of thing of course doesn't make the integral class generic enough.[/color]

      No, this won't work. The only solution I can think of is making
      integral a templated class (see below).
      [color=blue]
      >
      > I'd like to get some advices as to how I can make such an integral
      > class that even a member function can be passed easily as the
      > integrand. How can you do this using C++?
      >
      > Thanks in advance...
      >
      >
      >
      > ----------------------------------------------------------------
      >
      > #include <cmath>
      > #include <iostream>
      > #include <string>
      > #include <vector>
      >
      > namespace math {
      >
      > typedef double (*pfn)(double);
      >
      > class integral
      > {
      > public:
      > integral(double a, double b, pfn f)
      > : lower_(a), upper_(b), integrand_(f)
      > {}[/color]

      The following should work (untested code):

      template <class T>
      class integral {
      public:
      typedef double (T::*pfn)(doubl e);
      integral(double a, double b, pfn f)
      : lower_(a), upper_(b), integrand_(f) {}

      ...
      [color=blue]
      > namespace astro {
      >
      > class universe
      > {
      > public:
      > universe(double const omega_matter,
      > double const omega_lambda,
      > double const hubble_const)
      > : omega_matter_(o mega_matter),
      > omega_lambda_(o mega_lambda),
      > hubble_const_(h ubble_const)
      > {}
      >
      > double comoving_distan ce(double z)
      > {
      > //
      > // Want to use a generic integral class above with
      > // the integrand astro::universe ::inverse_e(dou ble),
      > // but does not compile....
      > //
      > math::integral func(0.0, z, inverse_e);[/color]

      math::integral< universe> func(0.0,z,inve rse_e);

      HTH & kind regards
      frank

      --
      Frank Schmitt
      4SC AG phone: +49 89 700763-0
      e-mail: frankNO DOT SPAMschmitt AT 4sc DOT com

      Comment

      Working...