use crate::integer::Integer;
use crate::integer_vector::arithmetic::max_bits::vec_max_bits;
use crate::integer_vector::arithmetic::sum_max_bits::vec_sum_max_bits;
use alloc::vec;
use alloc::vec::Vec;
use core::ops::Deref;
use malachite_base::named::Named;
use malachite_base::num::basic::traits::{One, Zero};
use malachite_base::num::conversion::traits::ExactFrom;
use malachite_base::vector::Vector;
pub mod access;
pub mod arithmetic;
pub mod comparison;
pub mod conversion;
pub mod exhaustive;
pub mod extend;
pub mod logic;
#[cfg(feature = "random")]
pub mod random;
pub mod select_coordinates;
#[derive(Clone, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct IntegerVector {
pub elements: Vec<Integer>,
}
impl Vector for IntegerVector {
type Element = Integer;
type ElementOutput<'a>
= &'a Integer
where
Self: 'a;
#[inline]
fn from_elements(xs: &[Integer]) -> Self {
Self {
elements: xs.to_vec(),
}
}
#[inline]
fn from_owned_elements(xs: Vec<Integer>) -> Self {
Self { elements: xs }
}
#[inline]
fn zero(dimension: u64) -> Self {
Self {
elements: vec![Integer::ZERO; usize::exact_from(dimension)],
}
}
fn standard_basis_vector(dimension: u64, index: u64) -> Self {
assert!(
index < dimension,
"the index {index} is not less than the dimension {dimension}"
);
let mut v = Self::zero(dimension);
v.elements[usize::exact_from(index)] = Integer::ONE;
v
}
#[inline]
fn push(&mut self, x: Integer) {
self.elements.push(x);
}
#[inline]
fn set_dimension(&mut self, dimension: u64) {
self.elements
.resize(usize::exact_from(dimension), Integer::ZERO);
}
#[inline]
fn set_zero(&mut self) {
self.elements.fill(Integer::ZERO);
}
#[inline]
fn sort(&mut self) {
self.elements.sort_unstable();
}
#[inline]
fn to_elements(&self) -> Vec<Integer> {
self.elements.clone()
}
#[inline]
fn into_elements(self) -> Vec<Integer> {
self.elements
}
#[inline]
fn elements_ref(&self) -> &[Integer] {
&self.elements
}
#[inline]
fn dimension(&self) -> u64 {
u64::exact_from(self.elements.len())
}
#[inline]
fn pivot(&self) -> Option<&Integer> {
self.elements.iter().find(|x| **x != 0u32)
}
#[inline]
fn pivot_index(&self) -> Option<u64> {
self.elements
.iter()
.position(|x| *x != 0u32)
.map(u64::exact_from)
}
#[inline]
fn height_index(&self) -> Option<u64> {
self.elements
.iter()
.enumerate()
.rev()
.max_by(|(_, x), (_, y)| x.unsigned_abs_ref().cmp(y.unsigned_abs_ref()))
.map(|(i, _)| u64::exact_from(i))
}
#[inline]
fn is_zero(&self) -> bool {
self.elements.iter().all(|x| *x == 0u32)
}
fn standard_basis_index(&self) -> Option<u64> {
let index = self.pivot_index()?;
let i = usize::exact_from(index);
if self.elements[i] == 1u32 && self.elements[i + 1..].iter().all(|x| *x == 0u32) {
Some(index)
} else {
None
}
}
#[inline]
fn max_bits(&self) -> (u64, bool) {
vec_max_bits(&self.elements)
}
#[inline]
fn sum_max_bits(&self) -> (u64, u64) {
vec_sum_max_bits(&self.elements)
}
}
impl_named!(IntegerVector);
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct ShortlexIntegerVector(pub IntegerVector);
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct ShortlexIntegerVectorRef<'a>(pub &'a IntegerVector);
impl ShortlexIntegerVector {
pub const fn as_ref(&self) -> ShortlexIntegerVectorRef<'_> {
ShortlexIntegerVectorRef(&self.0)
}
}
impl Deref for ShortlexIntegerVector {
type Target = IntegerVector;
fn deref(&self) -> &IntegerVector {
&self.0
}
}
impl Deref for ShortlexIntegerVectorRef<'_> {
type Target = IntegerVector;
fn deref(&self) -> &IntegerVector {
self.0
}
}