use super::*;
pub trait SizedSummary {
fn size(self) -> usize;
}
pub trait Keyed<Key>
where
Key: std::cmp::Ord,
{
fn get_key(&self) -> &Key;
}
impl<T: Ord> Keyed<T> for T {
fn get_key(&self) -> &Self {
&self
}
}
pub type PlainData<V> = (V, Unit, Unit);
pub type SizeData<V> = (V, Size, Unit);
pub type StdNum = (I, NumSummary, RevAffineAction);
pub use unit::*;
mod unit {
pub use super::*;
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug, Default, PartialOrd, Ord)]
pub struct Unit {}
impl<V> Acts<V> for Unit {
fn act_inplace(&self, _ref: &mut V) {}
}
impl Add for Unit {
type Output = Unit;
fn add(self, _b: Unit) -> Unit {
Unit {}
}
}
impl Action for Unit {
fn is_identity(self) -> bool {
self == Default::default()
}
}
impl<V> ToSummary<Unit> for V {
fn to_summary(&self) -> Unit {
Unit {}
}
}
}
pub use size::*;
mod size {
use super::*;
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Size {
pub size: usize,
}
impl Add for Size {
type Output = Size;
fn add(self, b: Size) -> Size {
Size {
size: self.size + b.size,
}
}
}
impl Default for Size {
fn default() -> Size {
Size { size: 0 }
}
}
impl SizedSummary for Size {
fn size(self) -> usize {
self.size
}
}
impl<V> ToSummary<Size> for V {
fn to_summary(&self) -> Size {
Size { size: 1 }
}
}
}
pub use rev_action::*;
mod rev_action {
use super::*;
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
pub struct RevAction {
pub to_reverse: bool,
}
impl std::ops::Add for RevAction {
type Output = RevAction;
fn add(self, b: RevAction) -> RevAction {
RevAction {
to_reverse: self.to_reverse != b.to_reverse,
}
}
}
impl Default for RevAction {
fn default() -> Self {
RevAction { to_reverse: false }
}
}
impl Action for RevAction {
fn is_identity(self) -> bool {
self == Default::default()
}
fn to_reverse(self) -> bool {
self.to_reverse
}
}
impl Acts<Unit> for RevAction {
fn act_inplace(&self, _val: &mut Unit) {}
}
impl Acts<I> for RevAction {
fn act_inplace(&self, _val: &mut I) {}
}
impl Acts<Size> for RevAction {
fn act_inplace(&self, _val: &mut Size) {}
}
impl Acts<NumSummary> for RevAction {
fn act_inplace(&self, _val: &mut NumSummary) {}
}
}
pub use add_action::*;
mod add_action {
use super::*;
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
pub struct AddAction {
pub add: I,
}
impl std::ops::Add for AddAction {
type Output = Self;
fn add(self, other: Self) -> Self {
AddAction {
add: self.add + other.add,
}
}
}
impl Default for AddAction {
fn default() -> Self {
AddAction { add: 0 }
}
}
impl Action for AddAction {
fn is_identity(self) -> bool {
self == Default::default()
}
}
impl Acts<Unit> for AddAction {
fn act_inplace(&self, _val: &mut Unit) {}
}
impl Acts<I> for AddAction {
fn act_inplace(&self, val: &mut I) {
*val += self.add;
}
}
impl Acts<NumSummary> for AddAction {
fn act_inplace(&self, summary: &mut NumSummary) {
summary.max = summary.max.map(|max: I| max + self.add);
summary.min = summary.min.map(|max: I| max + self.add);
summary.sum += self.add * summary.size;
}
}
}
type I = i32;
pub use num_summary::*;
mod num_summary {
use super::*;
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
pub struct NumSummary {
pub max: Option<I>,
pub min: Option<I>,
pub size: I,
pub sum: I,
}
impl Add for NumSummary {
type Output = Self;
fn add(self, other: Self) -> Self {
NumSummary {
max: match (self.max, other.max) {
(Some(a), Some(b)) => Some(std::cmp::max(a, b)),
(Some(a), _) => Some(a),
(_, b) => b,
},
min: match (self.min, other.min) {
(Some(a), Some(b)) => Some(std::cmp::min(a, b)),
(Some(a), _) => Some(a),
(_, b) => b,
},
size: self.size + other.size,
sum: self.sum + other.sum,
}
}
}
impl Default for NumSummary {
fn default() -> NumSummary {
NumSummary {
max: None,
min: None,
size: 0,
sum: 0,
}
}
}
impl SizedSummary for NumSummary {
fn size(self) -> usize {
self.size as usize
}
}
impl ToSummary<NumSummary> for I {
fn to_summary(&self) -> NumSummary {
NumSummary {
max: Some(*self),
min: Some(*self),
size: 1,
sum: *self,
}
}
}
}
pub use rev_add_action::*;
mod rev_add_action {
use super::*;
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
pub struct RevAddAction {
pub to_reverse: RevAction,
pub add: AddAction,
}
impl Add for RevAddAction {
type Output = Self;
fn add(self, other: Self) -> Self {
RevAddAction {
to_reverse: self.to_reverse + other.to_reverse,
add: self.add + other.add,
}
}
}
impl Default for RevAddAction {
fn default() -> Self {
RevAddAction {
to_reverse: RevAction::default(),
add: AddAction::default(),
}
}
}
impl Action for RevAddAction {
fn is_identity(self) -> bool {
self == Default::default()
}
fn to_reverse(self) -> bool {
self.to_reverse.to_reverse()
}
}
impl<T> Acts<T> for RevAddAction
where
RevAction: Acts<T>,
AddAction: Acts<T>,
{
fn act_inplace(&self, val: &mut T) {
self.to_reverse.act_inplace(val);
self.add.act_inplace(val);
}
}
}
pub use rev_affine_action::*;
mod rev_affine_action {
use super::*;
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
pub struct RevAffineAction {
pub to_reverse: bool,
pub mul: I,
pub add: I,
}
impl Action for RevAffineAction {
fn is_identity(self) -> bool {
self == Default::default()
}
fn to_reverse(self) -> bool {
self.to_reverse
}
}
impl Add for RevAffineAction {
type Output = Self;
fn add(self, other: Self) -> Self {
RevAffineAction {
to_reverse: self.to_reverse ^ other.to_reverse,
mul: self.mul * other.mul,
add: self.add + self.mul * other.add,
}
}
}
impl Default for RevAffineAction {
fn default() -> Self {
RevAffineAction {
to_reverse: false,
mul: 1,
add: 0,
}
}
}
impl Acts<I> for RevAffineAction {
fn act_inplace(&self, val: &mut I) {
*val *= self.mul;
*val += self.add;
}
}
impl Acts<NumSummary> for RevAffineAction {
fn act_inplace(&self, summary: &mut NumSummary) {
if self.mul < 0 {
std::mem::swap(&mut summary.min, &mut summary.max);
}
summary.max = summary.max.map(|max: I| max * self.mul);
summary.min = summary.min.map(|max: I| max * self.mul);
summary.sum *= self.mul;
summary.max = summary.max.map(|max: I| max + self.add);
summary.min = summary.min.map(|max: I| max + self.add);
summary.sum += self.add * summary.size;
}
}
}
pub use poly_num::*;
mod poly_num {
use super::*;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct PolyNum<const D: usize> {
pub size: usize,
pub moments: [I; D],
}
impl<const D: usize> PolyNum<D> {
pub fn apply_poly(&self, poly: &[I; D]) -> I {
let mut result = 0;
for i in 0..D {
result += poly[i] * self.moments[i];
}
result
}
pub fn shift(&self, shift: I) -> Self {
let mut moments: [I; D] = [0; D];
let mut powers = [0; D];
powers[0] = 1;
for deg in 0..D {
let mut sum: i64 = 0;
for i in 0..=deg {
sum += (powers[i] as i64) * (self.moments[i] as i64);
}
moments[deg] = sum as I;
if deg >= D - 1 {
break; }
for i in (0..=deg).rev() {
powers[i + 1] += powers[i];
powers[i] *= shift;
}
}
PolyNum {
size: self.size,
moments,
}
}
}
impl<const D: usize> Default for PolyNum<D> {
fn default() -> Self {
PolyNum {
size: 0,
moments: [0; D],
}
}
}
impl<const D: usize> SizedSummary for PolyNum<D> {
fn size(self) -> usize {
self.size
}
}
impl<const D: usize> Add for PolyNum<D> {
type Output = PolyNum<D>;
fn add(self, rhs: Self) -> Self::Output {
let mut moments = [0; D];
for (i, m) in rhs.shift(self.size as I).moments.iter().enumerate() {
moments[i] = self.moments[i] + m;
}
PolyNum {
size: self.size + rhs.size,
moments,
}
}
}
impl<const D: usize> ToSummary<PolyNum<D>> for I {
fn to_summary(&self) -> PolyNum<D> {
let mut moments = [0; D];
if D > 0 {
moments[0] = *self;
}
PolyNum { size: 1, moments }
}
}
impl<const D: usize> Acts<PolyNum<D>> for AddAction {
fn act_inplace(&self, summary: &mut PolyNum<D>) {
let singleton: PolyNum<D> = self.add.to_summary();
let mut power_sums_summary = PolyNum::default();
for j in (0..usize::BITS).rev() {
power_sums_summary = power_sums_summary + power_sums_summary;
if (summary.size() >> j) & 1 == 1 {
power_sums_summary = power_sums_summary + singleton;
}
}
for i in 0..D {
summary.moments[i] += power_sums_summary.moments[i];
}
}
}
impl<const D: usize> Acts<PolyNum<D>> for RevAction {
fn act_inplace(&self, summary: &mut PolyNum<D>) {
if !self.to_reverse {
return;
}
summary.moments = summary.shift(1 - (summary.size as I)).moments;
for i in 0..D {
if i % 2 == 1 {
summary.moments[i] *= -1;
}
}
}
}
impl<const D: usize> Acts<PolyNum<D>> for RevAffineAction {
fn act_inplace(&self, summary: &mut PolyNum<D>) {
for i in 0..D {
summary.moments[i] *= self.mul;
}
let action = RevAddAction {
to_reverse: RevAction {
to_reverse: self.to_reverse,
},
add: AddAction { add: self.add },
};
action.act_inplace(summary);
}
}
}