Просмотр исходного кода

math: allow to divide polynomials by scalars.

undefined
Sam Hocevar 10 лет назад
Родитель
Сommit
ce9daf6899
1 измененных файлов: 51 добавлений и 24 удалений
  1. +51
    -24
      src/lol/math/polynomial.h

+ 51
- 24
src/lol/math/polynomial.h Просмотреть файл

@@ -14,6 +14,9 @@
// The polynomial class
// --------------------
//
// The data structure is a simple dynamic array of scalars, with the
// added guarantee that the leading coefficient is always non-zero.
//

#include <functional>

@@ -105,50 +108,56 @@ struct polynomial

array<T> roots() const
{
ASSERT(degree() >= 0, "roots() called on the null polynomial");
/* For now we can only solve polynomials of degrees 0, 1 or 2. */
ASSERT(degree() >= 0 && degree() <= 2,
"roots() called on polynomial of degree %d", degree());

if (degree() == 0)
{
/* p(x) = a > 0 */
return array<T> {};
/* p(x) = a > 0 */
return array<T> {};
}
else if (degree() == 1)
{
/* p(x) = ax + b */
T const &a = m_coefficients[1];
T const &b = m_coefficients[0];
return array<T> { -b / a };
/* p(x) = ax + b */
T const &a = m_coefficients[1];
T const &b = m_coefficients[0];
return array<T> { -b / a };
}
else if (degree() == 2)
{
/* p(x) = ax² + bx + c */
T const &a = m_coefficients[2];
T const &b = m_coefficients[1];
T const &c = m_coefficients[0];
/* p(x) = ax² + bx + c */
T const &a = m_coefficients[2];
T const &b = m_coefficients[1];
T const &c = m_coefficients[0];

T const k = b / (a + a);
T const delta = k * k - c / a;
T const k = b / (a + a);
T const delta = k * k - c / a;

if (delta < T(0))
{
if (delta < T(0))
{
return array<T> {};
}
else if (delta > T(0))
{
}
else if (delta > T(0))
{
T const sqrt_delta = sqrt(delta);
return array<T> { -k - sqrt_delta, -k + sqrt_delta };
}
else
{
}
else
{
return array<T> { -k };
}
}
}

ASSERT(false, "roots() called on polynomial of degree %d > 2",
degree());
/* It is an error to reach this point. */
ASSERT(false);
return array<T> {};
}

/* Access individual coefficients. This is read-only and returns a
* copy because we cannot let the user mess with the integrity of
* the structure (i.e. the guarantee that the leading coefficient
* remains non-zero). */
inline T operator[](ptrdiff_t n) const
{
if (n < 0 || n > degree())
@@ -157,11 +166,13 @@ struct polynomial
return m_coefficients[n];
}

/* Unary plus */
polynomial<T> operator +() const
{
return *this;
}

/* Unary minus */
polynomial<T> operator -() const
{
polynomial<T> ret;
@@ -170,6 +181,7 @@ struct polynomial
return ret;
}

/* Add two polynomials */
polynomial<T> &operator +=(polynomial<T> const &p)
{
int min_degree = lol::min(p.degree(), degree());
@@ -189,6 +201,7 @@ struct polynomial
return polynomial<T>(*this) += p;
}

/* Subtract two polynomials */
polynomial<T> &operator -=(polynomial<T> const &p)
{
return *this += -p;
@@ -199,6 +212,7 @@ struct polynomial
return polynomial<T>(*this) += -p;
}

/* Multiply polynomial by a scalar */
polynomial<T> &operator *=(T const &k)
{
for (auto &a : m_coefficients)
@@ -212,6 +226,18 @@ struct polynomial
return polynomial<T>(*this) *= k;
}

/* Divide polynomial by a scalar */
polynomial<T> &operator /=(T const &k)
{
return *this *= (T(1) / k);
}

polynomial<T> operator /(T const &k) const
{
return *this * (T(1) / k);
}

/* Multiply polynomial by another polynomial */
polynomial<T> &operator *=(polynomial<T> const &p)
{
return *this = *this * p;
@@ -239,6 +265,7 @@ struct polynomial
}

private:
/* Enforce the non-zero leading coefficient rule. */
void reduce_degree()
{
while (m_coefficients.Count() && m_coefficients.Last() == T(0))


Загрузка…
Отмена
Сохранить