Преглед на файлове

math: add derive() method to polynomial and allow to call eval() with

polynomials as arguments so as to compose them together.
undefined
Sam Hocevar преди 11 години
родител
ревизия
3916a44c58
променени са 2 файла, в които са добавени 76 реда и са изтрити 3 реда
  1. +22
    -3
      src/lol/math/polynomial.h
  2. +54
    -0
      src/t/math/polynomial.cpp

+ 22
- 3
src/lol/math/polynomial.h Целия файл

@@ -26,6 +26,13 @@ struct polynomial
/* The zero polynomial */
explicit inline polynomial() {}

/* A constant polynomial */
explicit inline polynomial(T const &a)
{
m_coefficients.Push(a);
reduce_degree();
}

/* Create a polynomial from a list of coefficients */
explicit polynomial(std::initializer_list<T> const &init)
{
@@ -76,11 +83,23 @@ struct polynomial
reduce_degree();
}

T eval(T x) const
/* Evaluate polynomial at a given value. This method can also
* be used to compose polynomials, i.e. using another polynomial
* as the value instead of a scalar. */
template<typename U> U eval(U x) const
{
T ret = this->operator[](degree());
U ret((*this)[degree()]);
for (int i = degree() - 1; i >= 0; --i)
ret = ret * x + m_coefficients[i];
ret = ret * x + U(m_coefficients[i]);
return ret;
}

polynomial<T> derive() const
{
/* No need to reduce the degree after deriving. */
polynomial<T> ret;
for (int i = 1; i <= degree(); ++i)
ret.m_coefficients.Push(m_coefficients[i] * T(i));
return ret;
}



+ 54
- 0
src/t/math/polynomial.cpp Целия файл

@@ -50,6 +50,29 @@ lolunit_declare_fixture(PolynomialTest)
lolunit_assert_equal(s.degree(), -1);
}

lolunit_declare_test(Derive)
{
polynomial<float> p {};
p = p.derive();
lolunit_assert_equal(p.degree(), -1);

polynomial<float> q { 1.f };
q = q.derive();
lolunit_assert_equal(q.degree(), -1);

polynomial<float> r { 1.f, 2.f };
r = r.derive();
lolunit_assert_equal(r.degree(), 0);
lolunit_assert_equal(r[0], 2.f);

polynomial<float> s { 1.f, 2.f, 3.f, 4.f };
s = s.derive();
lolunit_assert_equal(s.degree(), 2);
lolunit_assert_equal(s[0], 2.f);
lolunit_assert_equal(s[1], 6.f);
lolunit_assert_equal(s[2], 12.f);
}

lolunit_declare_test(Eval)
{
/* Special null polynomial */
@@ -160,6 +183,37 @@ lolunit_declare_fixture(PolynomialTest)
lolunit_assert_equal(r[3], 15.f);
}

lolunit_declare_test(Composition1)
{
/* p(x) = 1 + x² */
polynomial<float> p({ 1, 0, 1 });

/* q(x) = (p o p)(x) = 2 + 2x² + x⁴ */
polynomial<float> q = p.eval(p);
lolunit_assert_equal(q.degree(), 4);
lolunit_assert_equal(q[0], 2.f);
lolunit_assert_equal(q[1], 0.f);
lolunit_assert_equal(q[2], 2.f);
lolunit_assert_equal(q[3], 0.f);
lolunit_assert_equal(q[4], 1.f);
}

lolunit_declare_test(Composition2)
{
/* p(x) = 1 + x */
polynomial<float> p({ 1, 1 });

/* q(x) = 1 + x + x² */
polynomial<float> q({ 1, 1, 1 });

/* r(x) = (q o p)(x) = 3 + 3x + x² */
polynomial<float> r = q.eval(p);
lolunit_assert_equal(r.degree(), 2);
lolunit_assert_equal(r[0], 3.f);
lolunit_assert_equal(r[1], 3.f);
lolunit_assert_equal(r[2], 1.f);
}

lolunit_declare_test(Chebyshev)
{
polynomial<float> t0 = polynomial<float>::chebyshev(0);


Зареждане…
Отказ
Запис