|
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