Skip to main content

Count

Struct Count 

Source
pub struct Count { /* private fields */ }
Expand description

Closed-form sum of a Poly over given bounds. Counts can themselves be summed, since they are represented by a Poly divided by a constant.

Given the code:

for i from 0 to N:
    for j from 0 to i^2:
        yield 1

The inner for body yields $1$ time, outer for body yields $\sum_{j=0}^{i^2-1} 1 = i^2$ times, and the full program yields $\sum_{i=0}^{N-1} i^2 = N(N-1)(2N - 1)/6$ times.

To count yields in general, we need an algorithm to count lattice points over Poly bounds. Treating other Vars as constants, and summing each term independently, the problem reduces to $\sum_{x=0}^{P-1} x^{n}$ for variable $x$, constant $n$, and polynomial $P$.

We can convert to falling factorials $x_{(k)} = (x)(x-1)(x-2)\dots(x-k+1)$ using Stirling numbers of the second kind and the identity

$$x^{n} = \sum_{k=0}^n {S(n, k)} x_{(k)}$$

Therefore, $$\sum_{x=0}^{P-1} x^n = \sum_{x=0}^{P-1} \left( \sum_{k=0}^n S(n, k) x_{(k)} \right)$$

After the inner sum is expanded, each term will be a falling factorial that can be evaluated with the discrete power rule

$$\sum_{x=0}^{K-1} x_{(k)} = \frac{K_{(k+1)}}{k+1}$$

For example, in the case above, $P=N$ and $n=2$, so $$\sum_{x=0}^{N-1} x^2 = \sum_{x=0}^{N-1} \left( \sum_{k=0}^2 \textcolor{blue}{S(2, k)} \textcolor{red}{x_{(k)}} \right)$$ $$= \textcolor{blue}{0}\sum_{x=0}^{N-1} \textcolor{red}{x_{(0)}} + \textcolor{blue}{1}\sum_{x=0}^{N-1} \textcolor{red}{x_{(1)}} + \textcolor{blue}{1}\sum_{x=0}^{N-1} \textcolor{red}{x_{(2)}}$$ $$= \frac{N_{(2)}}{2} + \frac{N_{(3)}}{3}$$ $$= \frac{N(N-1)}{2} + \frac{N(N-1)(N-2)}{3}$$ $$= \frac{3(N^2-N) + 2(N^3-3N^2+2N)}{6}$$ $$= \frac{2N^3 - 3N^2 + N}{6}$$ $$= \frac{N(N−1)(2N−1)}{6}$$

This algorithm is implemented in Count::sum_below:

use sirius::solver::{poly::poly, count::Count};

let i2 = Count::ratio(poly!(i^2), 1);
let sum = i2.sum_below('i', &poly!(N));
assert_eq!(sum, Count::ratio(poly!(2*N^3 - 3*N^2 + N), 6));

Implementations§

Source§

impl Count

Source

pub fn zero() -> Self

Source

pub fn constant<T: Into<Coef>>(c: T) -> Self

Source

pub fn var<T: Into<Var>>(v: T, p: Pow) -> Self

Source

pub fn ratio<T: Into<Coef>>(num: Poly, den: T) -> Self

Source

pub fn num(&self) -> &Poly

Source

pub fn den(&self) -> Coef

Source

pub fn is_zero(&self) -> bool

Source

pub fn as_poly(&self) -> Option<&Poly>

Source

pub fn as_constant(&self) -> Option<(Coef, Coef)>

Source

pub fn add(&self, rhs: &Self) -> Self

Source

pub fn neg(&self) -> Self

Source

pub fn sub(&self, rhs: &Self) -> Self

Source

pub fn mul(&self, rhs: &Self) -> Self

Source

pub fn mul_scalar<T: Into<Coef>>(&self, c: T) -> Self

Source

pub fn div_scalar<T: Into<Coef>>(&self, d: T) -> Self

Source

pub fn eval(&self, point: impl FnMut(Var) -> i128) -> (Coef, Coef)

Source

pub fn eval_int(&self, point: impl FnMut(Var) -> i128) -> Option<Coef>

Source

pub fn substitute(&self, v: Var, q: &Poly) -> Self

Source

pub fn assert_canonical(&self)

Source

pub fn sum_below<T: Into<Var>>(&self, v: T, hi: &Poly) -> Self

Source

pub fn sum_range(&self, var: Var, lo: &Poly, hi: &Poly) -> Self

Trait Implementations§

Source§

impl Clone for Count

Source§

fn clone(&self) -> Count

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Count

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for Count

Source§

impl Hash for Count

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Count

Source§

fn eq(&self, other: &Count) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for Count

Auto Trait Implementations§

§

impl Freeze for Count

§

impl RefUnwindSafe for Count

§

impl Send for Count

§

impl Sync for Count

§

impl Unpin for Count

§

impl UnsafeUnpin for Count

§

impl UnwindSafe for Count

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more