Skip to content

Commit

Permalink
Allow negative exponents in polynomials
Browse files Browse the repository at this point in the history
- Improve speed of polynomial multiplication
- Support LaTeX output for series
  • Loading branch information
benruijl committed Nov 24, 2024
1 parent 48d6ade commit a3b97e1
Show file tree
Hide file tree
Showing 14 changed files with 1,296 additions and 654 deletions.
69 changes: 69 additions & 0 deletions src/api/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4941,6 +4941,75 @@ impl PythonSeries {
Ok(format!("{}", self.series))
}

/// Convert the series into a LaTeX string.
pub fn to_latex(&self) -> PyResult<String> {
Ok(format!(
"$${}$$",
self.series
.format_string(&PrintOptions::latex(), PrintState::new())
))
}

/// Convert the expression into a human-readable string, with tunable settings.
///
/// Examples
/// --------
/// >>> a = Expression.parse('128378127123 z^(2/3)*w^2/x/y + y^4 + z^34 + x^(x+2)+3/5+f(x,x^2)')
/// >>> print(a.format(number_thousands_separator='_', multiplication_operator=' '))
#[pyo3(signature =
(terms_on_new_line = false,
color_top_level_sum = true,
color_builtin_symbols = true,
print_finite_field = true,
symmetric_representation_for_finite_field = false,
explicit_rational_polynomial = false,
number_thousands_separator = None,
multiplication_operator = '*',
double_star_for_exponentiation = false,
square_brackets_for_function = false,
num_exp_as_superscript = true,
latex = false,
precision = None)
)]
pub fn format(
&self,
terms_on_new_line: bool,
color_top_level_sum: bool,
color_builtin_symbols: bool,
print_finite_field: bool,
symmetric_representation_for_finite_field: bool,
explicit_rational_polynomial: bool,
number_thousands_separator: Option<char>,
multiplication_operator: char,
double_star_for_exponentiation: bool,
square_brackets_for_function: bool,
num_exp_as_superscript: bool,
latex: bool,
precision: Option<usize>,
) -> PyResult<String> {
Ok(format!(
"{}",
self.series.format_string(
&PrintOptions {
terms_on_new_line,
color_top_level_sum,
color_builtin_symbols,
print_finite_field,
symmetric_representation_for_finite_field,
explicit_rational_polynomial,
number_thousands_separator,
multiplication_operator,
double_star_for_exponentiation,
square_brackets_for_function,
num_exp_as_superscript,
latex,
precision,
},
PrintState::new()
)
))
}

pub fn sin(&self) -> PyResult<Self> {
Ok(Self {
series: self
Expand Down
8 changes: 5 additions & 3 deletions src/domains/algebraic_number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use crate::{
coefficient::ConvertToRing,
combinatorics::CombinationIterator,
poly::{
factor::Factorize, gcd::PolynomialGCD, polynomial::MultivariatePolynomial, Exponent,
Variable,
factor::Factorize, gcd::PolynomialGCD, polynomial::MultivariatePolynomial,
PositiveExponent, Variable,
},
};

Expand Down Expand Up @@ -577,7 +577,9 @@ impl<R: Field + PolynomialGCD<u16>> AlgebraicExtension<R> {
}
}

impl<R: Field + PolynomialGCD<E>, E: Exponent> MultivariatePolynomial<AlgebraicExtension<R>, E> {
impl<R: Field + PolynomialGCD<E>, E: PositiveExponent>
MultivariatePolynomial<AlgebraicExtension<R>, E>
{
/// Get the norm of a non-constant square-free polynomial `f` in the algebraic number field.
pub fn norm(&self) -> MultivariatePolynomial<R, E> {
self.norm_impl().3
Expand Down
54 changes: 28 additions & 26 deletions src/domains/factorized_rational_polynomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use std::{

use crate::{
poly::{
factor::Factorize, gcd::PolynomialGCD, polynomial::MultivariatePolynomial, Exponent,
Variable,
factor::Factorize, gcd::PolynomialGCD, polynomial::MultivariatePolynomial,
PositiveExponent, Variable,
},
printer::{PrintOptions, PrintState},
};
Expand All @@ -23,13 +23,13 @@ use super::{
};

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct FactorizedRationalPolynomialField<R: Ring, E: Exponent> {
pub struct FactorizedRationalPolynomialField<R: Ring, E: PositiveExponent> {
ring: R,
var_map: Arc<Vec<Variable>>,
_phantom_exp: PhantomData<E>,
}

impl<R: Ring, E: Exponent> FactorizedRationalPolynomialField<R, E> {
impl<R: Ring, E: PositiveExponent> FactorizedRationalPolynomialField<R, E> {
pub fn new(
coeff_ring: R,
var_map: Arc<Vec<Variable>>,
Expand All @@ -52,7 +52,7 @@ impl<R: Ring, E: Exponent> FactorizedRationalPolynomialField<R, E> {
}
}

pub trait FromNumeratorAndFactorizedDenominator<R: Ring, OR: Ring, E: Exponent> {
pub trait FromNumeratorAndFactorizedDenominator<R: Ring, OR: Ring, E: PositiveExponent> {
/// Construct a rational polynomial from a numerator and a factorized denominator.
/// An empty denominator means a denominator of 1.
fn from_num_den(
Expand All @@ -64,21 +64,21 @@ pub trait FromNumeratorAndFactorizedDenominator<R: Ring, OR: Ring, E: Exponent>
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct FactorizedRationalPolynomial<R: Ring, E: Exponent> {
pub struct FactorizedRationalPolynomial<R: Ring, E: PositiveExponent> {
pub numerator: MultivariatePolynomial<R, E>,
pub numer_coeff: R::Element,
pub denom_coeff: R::Element,
pub denominators: Vec<(MultivariatePolynomial<R, E>, usize)>, // TODO: sort factors?
}

impl<R: Ring, E: Exponent> InternalOrdering for FactorizedRationalPolynomial<R, E> {
impl<R: Ring, E: PositiveExponent> InternalOrdering for FactorizedRationalPolynomial<R, E> {
/// An ordering of rational polynomials that has no intuitive meaning.
fn internal_cmp(&self, _other: &Self) -> Ordering {
todo!()
}
}

impl<R: Ring, E: Exponent> FactorizedRationalPolynomial<R, E> {
impl<R: Ring, E: PositiveExponent> FactorizedRationalPolynomial<R, E> {
pub fn new(field: &R, var_map: Arc<Vec<Variable>>) -> FactorizedRationalPolynomial<R, E> {
let num = MultivariatePolynomial::new(field, None, var_map);

Expand Down Expand Up @@ -147,7 +147,7 @@ impl<R: Ring, E: Exponent> FactorizedRationalPolynomial<R, E> {
}
}

impl<R: Ring, E: Exponent> SelfRing for FactorizedRationalPolynomial<R, E> {
impl<R: Ring, E: PositiveExponent> SelfRing for FactorizedRationalPolynomial<R, E> {
fn is_zero(&self) -> bool {
self.is_zero()
}
Expand Down Expand Up @@ -385,7 +385,7 @@ impl<R: Ring, E: Exponent> SelfRing for FactorizedRationalPolynomial<R, E> {
}
}

impl<E: Exponent> FromNumeratorAndFactorizedDenominator<RationalField, IntegerRing, E>
impl<E: PositiveExponent> FromNumeratorAndFactorizedDenominator<RationalField, IntegerRing, E>
for FactorizedRationalPolynomial<IntegerRing, E>
{
fn from_num_den(
Expand Down Expand Up @@ -428,7 +428,7 @@ impl<E: Exponent> FromNumeratorAndFactorizedDenominator<RationalField, IntegerRi
}
}

impl<E: Exponent> FromNumeratorAndFactorizedDenominator<IntegerRing, IntegerRing, E>
impl<E: PositiveExponent> FromNumeratorAndFactorizedDenominator<IntegerRing, IntegerRing, E>
for FactorizedRationalPolynomial<IntegerRing, E>
{
fn from_num_den(
Expand Down Expand Up @@ -534,7 +534,7 @@ impl<E: Exponent> FromNumeratorAndFactorizedDenominator<IntegerRing, IntegerRing
}
}

impl<UField: FiniteFieldWorkspace, E: Exponent>
impl<UField: FiniteFieldWorkspace, E: PositiveExponent>
FromNumeratorAndFactorizedDenominator<FiniteField<UField>, FiniteField<UField>, E>
for FactorizedRationalPolynomial<FiniteField<UField>, E>
where
Expand Down Expand Up @@ -618,7 +618,7 @@ where
}
}

impl<R: EuclideanDomain + PolynomialGCD<E>, E: Exponent> FactorizedRationalPolynomial<R, E>
impl<R: EuclideanDomain + PolynomialGCD<E>, E: PositiveExponent> FactorizedRationalPolynomial<R, E>
where
Self: FromNumeratorAndFactorizedDenominator<R, R, E>,
MultivariatePolynomial<R, E>: Factorize,
Expand All @@ -644,7 +644,7 @@ where
}
}

impl<R: EuclideanDomain + PolynomialGCD<E>, E: Exponent> FactorizedRationalPolynomial<R, E>
impl<R: EuclideanDomain + PolynomialGCD<E>, E: PositiveExponent> FactorizedRationalPolynomial<R, E>
where
Self: FromNumeratorAndFactorizedDenominator<R, R, E>,
{
Expand Down Expand Up @@ -727,20 +727,20 @@ where
}
}

impl<R: Ring, E: Exponent> Display for FactorizedRationalPolynomial<R, E> {
impl<R: Ring, E: PositiveExponent> Display for FactorizedRationalPolynomial<R, E> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.format(&PrintOptions::from_fmt(f), PrintState::from_fmt(f), f)
.map(|_| ())
}
}

impl<R: Ring, E: Exponent> Display for FactorizedRationalPolynomialField<R, E> {
impl<R: Ring, E: PositiveExponent> Display for FactorizedRationalPolynomialField<R, E> {
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Ok(())
}
}

impl<R: EuclideanDomain + PolynomialGCD<E>, E: Exponent> Ring
impl<R: EuclideanDomain + PolynomialGCD<E>, E: PositiveExponent> Ring
for FactorizedRationalPolynomialField<R, E>
where
FactorizedRationalPolynomial<R, E>: FromNumeratorAndFactorizedDenominator<R, R, E>,
Expand Down Expand Up @@ -864,7 +864,7 @@ where
}
}

impl<R: EuclideanDomain + PolynomialGCD<E>, E: Exponent> EuclideanDomain
impl<R: EuclideanDomain + PolynomialGCD<E>, E: PositiveExponent> EuclideanDomain
for FactorizedRationalPolynomialField<R, E>
where
FactorizedRationalPolynomial<R, E>: FromNumeratorAndFactorizedDenominator<R, R, E>,
Expand All @@ -888,7 +888,7 @@ where
}
}

impl<R: EuclideanDomain + PolynomialGCD<E>, E: Exponent> Field
impl<R: EuclideanDomain + PolynomialGCD<E>, E: PositiveExponent> Field
for FactorizedRationalPolynomialField<R, E>
where
FactorizedRationalPolynomial<R, E>: FromNumeratorAndFactorizedDenominator<R, R, E>,
Expand All @@ -907,7 +907,7 @@ where
}
}

impl<'a, 'b, R: EuclideanDomain + PolynomialGCD<E> + PolynomialGCD<E>, E: Exponent>
impl<'a, 'b, R: EuclideanDomain + PolynomialGCD<E> + PolynomialGCD<E>, E: PositiveExponent>
Add<&'a FactorizedRationalPolynomial<R, E>> for &'b FactorizedRationalPolynomial<R, E>
where
FactorizedRationalPolynomial<R, E>: FromNumeratorAndFactorizedDenominator<R, R, E>,
Expand Down Expand Up @@ -1014,7 +1014,8 @@ where
}
}

impl<R: EuclideanDomain + PolynomialGCD<E>, E: Exponent> Sub for FactorizedRationalPolynomial<R, E>
impl<R: EuclideanDomain + PolynomialGCD<E>, E: PositiveExponent> Sub
for FactorizedRationalPolynomial<R, E>
where
FactorizedRationalPolynomial<R, E>: FromNumeratorAndFactorizedDenominator<R, R, E>,
{
Expand All @@ -1025,7 +1026,7 @@ where
}
}

impl<'a, 'b, R: EuclideanDomain + PolynomialGCD<E>, E: Exponent>
impl<'a, 'b, R: EuclideanDomain + PolynomialGCD<E>, E: PositiveExponent>
Sub<&'a FactorizedRationalPolynomial<R, E>> for &'b FactorizedRationalPolynomial<R, E>
where
FactorizedRationalPolynomial<R, E>: FromNumeratorAndFactorizedDenominator<R, R, E>,
Expand All @@ -1037,7 +1038,8 @@ where
}
}

impl<R: EuclideanDomain + PolynomialGCD<E>, E: Exponent> Neg for FactorizedRationalPolynomial<R, E>
impl<R: EuclideanDomain + PolynomialGCD<E>, E: PositiveExponent> Neg
for FactorizedRationalPolynomial<R, E>
where
FactorizedRationalPolynomial<R, E>: FromNumeratorAndFactorizedDenominator<R, R, E>,
{
Expand All @@ -1052,7 +1054,7 @@ where
}
}

impl<'a, 'b, R: EuclideanDomain + PolynomialGCD<E>, E: Exponent>
impl<'a, 'b, R: EuclideanDomain + PolynomialGCD<E>, E: PositiveExponent>
Mul<&'a FactorizedRationalPolynomial<R, E>> for &'b FactorizedRationalPolynomial<R, E>
{
type Output = FactorizedRationalPolynomial<R, E>;
Expand Down Expand Up @@ -1145,7 +1147,7 @@ impl<'a, 'b, R: EuclideanDomain + PolynomialGCD<E>, E: Exponent>
}
}

impl<'a, 'b, R: EuclideanDomain + PolynomialGCD<E>, E: Exponent>
impl<'a, 'b, R: EuclideanDomain + PolynomialGCD<E>, E: PositiveExponent>
Div<&'a FactorizedRationalPolynomial<R, E>> for &'b FactorizedRationalPolynomial<R, E>
where
FactorizedRationalPolynomial<R, E>: FromNumeratorAndFactorizedDenominator<R, R, E>,
Expand Down Expand Up @@ -1256,7 +1258,7 @@ where
}
}

impl<R: EuclideanDomain + PolynomialGCD<E>, E: Exponent> FactorizedRationalPolynomial<R, E>
impl<R: EuclideanDomain + PolynomialGCD<E>, E: PositiveExponent> FactorizedRationalPolynomial<R, E>
where
FactorizedRationalPolynomial<R, E>: FromNumeratorAndFactorizedDenominator<R, R, E>,
MultivariatePolynomial<R, E>: Factorize,
Expand Down
Loading

0 comments on commit a3b97e1

Please sign in to comment.