[GiNaC-list] legendre and chebyshev polynomials

Jorge Cardona jorgeecardona at gmail.com
Wed Jul 1 02:08:06 CEST 2009


Hi,

i'm working in three classes to generate the legendre polynomial, and
the chebyshev of first and second kind, in chebyshev i define the
derivative in terms of chebyshev polynomials, but it get messy when is
expanded because the polynomials at numerator and denominator are not
factorized, and then the expression is complex that it should.

What do you think is better, to let the derivatives of the polynomials
in terms on the same polynomials, and expaned as like the users, or
always expand at the derivative and return the polynomial expanded at
the derivative (as in the legendre polynomial)?

This is the code:

/ Chebyshev polynomial of first kind
class chebyshev_1 : public basic
{
    GINAC_DECLARE_REGISTERED_CLASS(chebyshev_1, basic)

public:
    // Constructor of chebyshev of first kind
    chebyshev_1(numeric n, symbol x);

    ex derivative(const symbol & s) const;
    ex expand(unsigned options) const;

protected:
    void do_print(const print_context & c, unsigned level = 0) const;

private:

    numeric n;
    symbol x;
};

// Chebyshev polynomial of second kind
class chebyshev_2 : public basic
{
    GINAC_DECLARE_REGISTERED_CLASS(chebyshev_2, basic)

public:
    // Constructor of chebyshev of first kind
    chebyshev_2(numeric n, symbol x);

    ex derivative(const symbol & s) const;
    ex expand(unsigned options) const;

protected:
    void do_print(const print_context & c, unsigned level = 0) const;

private:
    numeric n;
    symbol x;
};

// Legendre polynomial
class legendre : public basic
{
    GINAC_DECLARE_REGISTERED_CLASS(legendre, basic)

public:
    // Constructor of chebyshev of first kind
    legendre(numeric n, symbol x);

    ex derivative(const symbol & s) const;
    ex expand(unsigned options) const;

protected:
    void do_print(const print_context & c, unsigned level = 0) const;

private:
    numeric n;
    symbol x;
};

/***************************************************************
* Chebyshev polynomial of first kind
****************************************************************/

GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(chebyshev_1, basic,
  print_func<print_context>(&chebyshev_1::do_print))

// Default constructor
chebyshev_1::chebyshev_1() {}

// Print the function
void chebyshev_1::do_print(const print_context & c, unsigned level) const
{
    c.s << "Tn(" << n << "," << x << ")";
}

int chebyshev_1::compare_same_type(const basic & other) const
{
    const chebyshev_1 &o = static_cast<const chebyshev_1 &>(other);

    if (x.is_equal(o.x) and (n == o.n))
        return 0;

    return 1;
}

ex chebyshev_1::expand(unsigned options) const
{
    if (n == 0)
        return 1;
    if (n == 1)
        return x;

    exvector e;

    numeric m = n / 2;
    if (n.is_odd())
        m = (n-1)/2;

    e.reserve(m.to_long());

    ex tmp = pow(2 * x,n) / 2;
    e.push_back(tmp);

    for(numeric i = 1; i <= m; i++)
    {
        tmp *= -(n - 2*i + 2) * (n - 2*i + 1);
        tmp /= (4 * i * pow(x,2) * (n-i));
        e.push_back(tmp);
    }

    return add(e);
}

ex chebyshev_1::derivative(const symbol & s) const
{
    if(s.is_equal(x) and (n!=0))
        return n * chebyshev_2(n-1,x);

    return 0;
}

chebyshev_1::chebyshev_1(numeric n, symbol x) : n(n), x(x){}


/***************************************************************
* Chebyshev polynomial of second kind
****************************************************************/

GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(chebyshev_2, basic,
  print_func<print_context>(&chebyshev_2::do_print))

// Default constructor
chebyshev_2::chebyshev_2() {}

// Print the function
void chebyshev_2::do_print(const print_context & c, unsigned level) const
{
    c.s << "Un(" << n << "," << x << ")";
}

int chebyshev_2::compare_same_type(const basic & other) const
{
    const chebyshev_2 &o = static_cast<const chebyshev_2 &>(other);

    if (x.is_equal(o.x) and (n == o.n))
        return 0;

    return 1;
}

ex chebyshev_2::expand(unsigned options) const
{
    if (n == 0)
        return 1;
    if (n == 1)
        return 2*x;

    exvector e;

    numeric m = n / 2;
    if (n.is_odd())
        m = (n-1)/2;

    e.reserve(m.to_long());

    ex tmp = pow(2 * x,n);
    e.push_back(tmp);

    for(numeric i = 1; i <= m; i++)
    {
        tmp *= -(n - 2*i + 2) * (n - 2*i + 1);
        tmp /= (4 * i * pow(x,2) * (n - i + 1));
        e.push_back(tmp);
    }

    return add(e);
}

ex chebyshev_2::derivative(const symbol & s) const
{
    if(s.is_equal(x) and (n!=0))
        return ((n+1) * chebyshev_1(n+1,x) - x * chebyshev_2(n,x)) /
(pow(x,2) - 1);

    return 0;
}

chebyshev_2::chebyshev_2(numeric n, symbol x) : n(n), x(x){}

/***************************************************************
* Legendre polynomial
****************************************************************/

GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(legendre, basic,
  print_func<print_context>(&legendre::do_print))

// Default constructor
legendre::legendre() {}

// Print the function
void legendre::do_print(const print_context & c, unsigned level) const
{
    c.s << "Pn(" << n << "," << x << ")";
}

int legendre::compare_same_type(const basic & other) const
{
    const legendre &o = static_cast<const legendre &>(other);

    if (x.is_equal(o.x) and (n == o.n))
        return 0;

    return 1;
}

ex legendre::expand(unsigned options) const
{
    if (n == 0)
        return 1;
    if (n == 1)
        return x;

    exvector e;

    numeric m = n / 2;
    if (n.is_odd())
        m = (n-1)/2;

    e.reserve(m.to_long());

    ex tmp = factorial(2*n) * pow(x,n) /(pow(2,n) * pow(factorial(n),2));
    e.push_back(tmp);

    for(numeric i = 1; i <= m; i++)
    {
        tmp *= -(n - 2 * i + 1) * (n - 2 * i + 2);
        tmp /= (4 * n -4 * i + 2) * i * pow(x,2);
        e.push_back(tmp);
    }

    return add(e);
}

ex legendre::derivative(const symbol & s) const
{
    return (this->expand(0)).diff(s);
    //if(s.is_equal(x) and (n!=0))

    //    return ((n+1) * chebyshev_1(n+1,x) - x * legendre(n,x)) /
(pow(x,2) - 1);

    //return 0;
}

legendre::legendre(numeric n, symbol x) : n(n), x(x){}


-- 
Jorge Eduardo Cardona
jorgeecardona at gmail.com
jorgeecardona.blogspot.com
------------------------------------------------
Linux registered user  #391186
Registered machine    #291871
------------------------------------------------


More information about the GiNaC-list mailing list