Boost logo

Boost :

From: Peder Holt (peder.holt_at_[hidden])
Date: 2005-11-08 01:49:24


On 11/7/05, Cromwell Enage <sponage_at_[hidden]> wrote:
> > --- Cromwell Enage wrote:
> > > What I'll do is:
> > > 1) Create an internal metafunction in the
> > > double_::aux namespace that does what
> > > fractional_part does now.
> > > 2) Change fractional_part so that it returns a
> > > double.
> > > 3) Implement numerator and denominator
> > > specializations that use the metafunction in 1).
> > >
> > > Then, with fractional_power as a template nested
> > > within power_impl, we can return:
> > >
> > > times<
> > > integral_power<z,integral_part<a> >
> > > , fractional_power<z, fractional_part<a> >
> > > >
>
> Done.
>
> --- Peder Holt wrote:
> > The series:
> > z^a == Sum[(Log[z]^k/k!) a^k, {k, 0, Infinity}]
> > requires 27 recursions, but the code is very simple:
>
> The series looks exactly like e^(a log z), which is
> what we have right now.
>

Ok :)
I have implemented the compile-time inverse_sine and inverse_tangent
(the latter only for x<=1)
but have a bit of a problem with arcus_cosine, which is defined as
pi/2-inverse_sine.
Also, inverse_tangent for x>=1 is defined as pi/2+something.

So far, all implementations of math metafunctions should work with
both double_ and your mixed_number etc. types, but once we introduce a
constant, the result type is given, unless there is some clever way of
defining the constant several times for all the different input types.

Also, I have managed to squeeze more performance out of the compiler
by replacing integral operations in the metafunctions with
BOOST_STATIC_CONSTANT.
e.g.

    template <typename NumericTag>
    struct logarithm_impl
    {
        /*
         * Continued fraction representation
(http://functions.wolfram.com/ElementaryFunctions/Tan/10)
         */
        template <
            typename Arg
          , typename I
          , typename FractionCount
>
        struct fraction
        {
         private:
            typedef typename eval_if<
                        less<I,FractionCount>
                        , fraction<Arg,typename I::next,FractionCount>
                      , I
>::type
                    next_term;
            BOOST_STATIC_CONSTANT(int,coefficient=(((I::value)+1)/2)*(((I::value)+1)/2));
         public:
            typedef typename plus<
                        I,
                        divides<
                            times<
                                int_<coefficient>,
                                Arg
>,
                            next_term
>
>::type
                    type;
        };

        template <
            typename Arg
          , typename SeriesCount
>
        struct apply
#if !defined BOOST_MPL_CFG_NO_NESTED_FORWARDING
        : divides<Arg,typename fraction<Arg,int_<1>,SeriesCount>::type>
        {
#else
        {
            /*
             * Metafunction class return type.
             */
            typedef typename divides<
                        Arg
                      , typename fraction<Arg,int_<1>,SeriesCount>::type
>::type
                    type;
#endif /* BOOST_MPL_CFG_NO_NESTED_FORWARDING */
        };
    };

I think it should be possible to only use 4 arithmetic meta-operation per term,
typically (a+b*x*next)/c
where a,b and c are calculated using BOOST_STATIC_CONSTANT

Regards,
Peder


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk