use crate::algebra::matrices::query::{ MatrixAlgebra, MatrixOracle, };
use crate::algebra::matrices::operations::combine_rows_and_columns::{LinearCombinationOfColumns, LinearCombinationOfColumnsReverse, LinearCombinationOfRows, LinearCombinationOfRowsReverse};
use crate::utilities::functions::evaluate::EvaluateFunction;
use crate::utilities::iterators::general::{PeekUnqualified};
use crate::algebra::vectors::entries::{KeyValGet, KeyValSet, KeyValNew};
use crate::algebra::rings::traits::{SemiringOperations, RingOperations};
use crate::utilities::iterators::merge::two_type::MergeTwoIteratorsByOrderOperator;
use crate::utilities::iterators::merge::hit::{IteratorsMergedInSortedOrder, HitMergeByPredicateTrait};
use crate::utilities::order::{JudgeOrder, JudgePartialOrder, ReverseOrder};
use crate::utilities::sets::MapHasKeyOrSequenceHasElement;
use std::collections::HashMap;
use std::fmt::{Debug};
use std::cmp::Ordering;
use std::hash::Hash;
use std::iter::Peekable;
use std::marker::PhantomData;
use derive_getters::{Getters, Dissolve};
use derive_new::new;
pub type LinearCombinationUnsimplified
< SparseVector, RingOperator, OrderOperator >
=
IteratorsMergedInSortedOrder<
Scale<
SparseVector,
RingOperator,
>,
OrderOperator,
>;
pub type LinearCombinationSimplified
< SparseVector, RingOperator, OrderOperator >
=
Simplify<
IteratorsMergedInSortedOrder<
Scale<
SparseVector,
RingOperator,
>,
OrderOperator,
>,
RingOperator,
>;
#[derive(new,Clone,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct DropZeros
< SparseVector, RingOperator >
{
undropped: SparseVector,
ring_operator: RingOperator,
}
impl < SparseVector, RingOperator >
Iterator for
DropZeros
< SparseVector, RingOperator >
where RingOperator: SemiringOperations,
SparseVector: Iterator,
SparseVector::Item: KeyValGet< Val = RingOperator::Element >,
{
type Item = SparseVector::Item;
fn next( &mut self) -> Option< Self::Item >
{
let mut next = self.undropped.next();
while let Some( ref x ) = next {
if self.ring_operator.is_0( x.val() ) { next = self.undropped.next(); }
else {break}
}
next
}
}
#[derive(new,Clone,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct Scale
< SparseVector, RingOperator >
where RingOperator: SemiringOperations,
{
unscaled: SparseVector,
ring_operator: RingOperator,
scaling_coefficient: RingOperator::Element,
}
impl < SparseVector, RingOperator, >
Iterator for
Scale
< SparseVector, RingOperator, >
where SparseVector: Iterator,
SparseVector::Item: KeyValSet< Val = RingOperator::Element >,
RingOperator: SemiringOperations,
{
type Item = SparseVector::Item;
fn next( &mut self) -> Option< Self::Item >
{
if let Some( mut x ) = self.unscaled.next() {
x.set_val(
self.ring_operator.multiply(
x.val(),
self.scaling_coefficient.clone(),
)
);
Some(x)
}
else { None }
}
}
#[derive(new,Clone,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct Gather
< SparseVector, RingOperator >
{
ungathered: SparseVector,
ring_operator: RingOperator,
}
impl < SparseVector, RingOperator >
Iterator for Gather
< SparseVector, RingOperator >
where SparseVector: PeekUnqualified +
Iterator<
Item: KeyValSet<
Key: PartialEq,
Val = RingOperator::Element
>,
>,
RingOperator: SemiringOperations,
{
type Item = SparseVector::Item;
fn next( &mut self) -> Option< Self::Item >
{
if let Some( mut x ) = self.ungathered.next() {
while let Some( peek ) = self.ungathered.peek_unqualified() {
if peek.key() == x.key() {
x.set_val(
self.ring_operator.add(
x.val(),
peek.val()
)
);
let _ = self.ungathered.next(); }
else { break }
}
Some( x )
}
else
{ None }
}
}
#[derive(new,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd,Hash)]
pub struct Simplify
< SparseVector, RingOperator >
{
pub unsimplified: SparseVector,
pub ring_operator: RingOperator,
}
impl < SparseVector, RingOperator >
Iterator for
Simplify
< SparseVector, RingOperator >
where SparseVector: Iterator<
Item: KeyValSet<
Key: PartialEq,
Val = RingOperator::Element,
>
>,
SparseVector: PeekUnqualified,
RingOperator: SemiringOperations,
{
type Item = SparseVector::Item;
fn next( &mut self) -> Option< Self::Item >
{
while let Some( mut x ) = self.unsimplified.next() {
while let Some( peek ) = self.unsimplified.peek_unqualified() {
if peek.key() == x.key() {
x.set_val(
self.ring_operator.add(
x.val(),
peek.val()
)
);
let _ = self.unsimplified.next(); }
else { break }
}
match self.ring_operator.is_0( x.val() ){
false => { return Some( x ) }, true => { continue }, }
}
None
}
}
impl < SparseVector, RingOperator >
Clone for
Simplify
< SparseVector, RingOperator >
where SparseVector: Clone,
RingOperator: Clone,
{
fn clone(&self) -> Self {
Simplify { unsimplified: self.unsimplified.clone(), ring_operator: self.ring_operator.clone() }
}
}
#[derive(new,Clone,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct Negate
< SparseVector, RingOperator >
{
unnegated: SparseVector,
ring_operator: RingOperator,
}
impl < SparseVector, RingOperator >
Iterator for
Negate
< SparseVector, RingOperator >
where SparseVector: Iterator,
SparseVector::Item: PartialEq + KeyValSet< Val = RingOperator::Element >,
RingOperator: RingOperations,
{
type Item = SparseVector::Item;
fn next( &mut self) -> Option< Self::Item >
{
match self.unnegated.next() {
Some( mut next_item ) => {
next_item.set_val(
self.ring_operator.negate( next_item.val() )
);
Some( next_item )
},
None => { None }
}
}
}
#[derive(new,Clone,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct OnlyIndicesInsideCollection
< SparseVector, CollectionToInclude, >
{
entry_iter: SparseVector,
collection_to_include: CollectionToInclude,
}
impl < SparseVector, CollectionToInclude, >
Iterator for
OnlyIndicesInsideCollection
< SparseVector, CollectionToInclude >
where SparseVector: Iterator,
SparseVector::Item: KeyValGet,
CollectionToInclude: MapHasKeyOrSequenceHasElement< <SparseVector::Item as KeyValGet>::Key >,
{
type Item = SparseVector::Item;
fn next( &mut self ) -> Option< Self::Item > {
for entry in self.entry_iter.by_ref() {
match self.collection_to_include.map_has_key_or_sequence_has_element( & entry.key() ) {
true => { return Some( entry ) },
false => { continue },
}
}
None
}
}
#[derive(new,Clone,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct OnlyIndicesOutsideCollection
< SparseVector, CollectionToExclude >
{
entry_iter: SparseVector,
collection_to_exclude: CollectionToExclude,
}
impl < SparseVector, CollectionToExclude >
Iterator for
OnlyIndicesOutsideCollection
< SparseVector, CollectionToExclude >
where SparseVector: Iterator,
SparseVector::Item: KeyValGet,
CollectionToExclude: MapHasKeyOrSequenceHasElement< <SparseVector::Item as KeyValGet>::Key >,
{
type Item = SparseVector::Item;
fn next( &mut self ) -> Option< Self::Item > {
for entry in self.entry_iter.by_ref() {
match self.collection_to_exclude.map_has_key_or_sequence_has_element( & entry.key() ) {
false => return Some( entry ),
true => continue,
}
}
None
}
}
#[derive(Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct RemapEntryTuple< KeyOld, KeyNew, KeyMap, ValOld, ValNew, ValMap, EntryNew > {
pub keymap: KeyMap,
pub valmap: ValMap,
phantom_keyold: PhantomData<KeyOld>,
phantom_keynew: PhantomData<KeyNew>,
phantom_valold: PhantomData<ValOld>,
phantom_valnew: PhantomData<ValNew>,
phantom_entrynew: PhantomData<EntryNew>
}
impl < KeyOld, KeyNew, KeyMap, ValOld, ValNew, ValMap, EntryNew >
RemapEntryTuple
< KeyOld, KeyNew, KeyMap, ValOld, ValNew, ValMap, EntryNew >
{
pub fn new( keymap: KeyMap, valmap: ValMap ) -> Self {
RemapEntryTuple{ keymap, valmap, phantom_entrynew: PhantomData, phantom_keynew: PhantomData, phantom_keyold: PhantomData, phantom_valnew: PhantomData, phantom_valold: PhantomData}
}
}
impl < KeyOld, KeyNew, KeyMap, ValOld, ValNew, ValMap, EntryNew >
EvaluateFunction
< (KeyOld,ValOld), EntryNew > for
RemapEntryTuple
< KeyOld, KeyNew, KeyMap, ValOld, ValNew, ValMap, EntryNew > where
KeyMap: EvaluateFunction< KeyOld, KeyNew >,
ValMap: EvaluateFunction< ValOld, ValNew >,
EntryNew: KeyValNew < Key = KeyNew, Val = ValNew >
{
fn evaluate_function( &self, input: (KeyOld,ValOld) ) -> EntryNew {
EntryNew::new( self.keymap.evaluate_function(input.0), self.valmap.evaluate_function(input.1) )
}
}
impl < KeyOld, KeyNew, KeyMap, ValOld, ValNew, ValMap, EntryNew >
Clone for
RemapEntryTuple
< KeyOld, KeyNew, KeyMap, ValOld, ValNew, ValMap, EntryNew > where
KeyMap: Clone,
ValMap: Clone,
{
fn clone( &self) -> Self {
RemapEntryTuple::new( self.keymap.clone(), self.valmap.clone() )
}
}
#[derive(new,Clone,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct ChangeIndexSimple
< SparseVector, IndexChanger, NewIndex, >
{
entry_iter: SparseVector,
index_changer: IndexChanger,
phantom_indexnew: PhantomData< NewIndex >,
}
impl < SparseVector, IndexChanger, NewIndex, Coefficient >
Iterator for
ChangeIndexSimple
< SparseVector, IndexChanger, NewIndex, >
where
SparseVector: Iterator,
SparseVector::Item: KeyValGet< Val = Coefficient >,
IndexChanger: EvaluateFunction< <SparseVector::Item as KeyValGet>::Key, NewIndex >,
{
type Item = ( NewIndex, Coefficient );
fn next( &mut self ) -> Option< Self::Item > {
match self.entry_iter.next() {
Some( entry ) => {
Some( ( self.index_changer.evaluate_function( entry.key() ), entry.val() ) )
},
None => { None }
}
}
}
#[derive(new,Clone,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct ChangeEntryType
< SparseVector, EntryNew >
{
entry_iter: SparseVector,
phantom_entrynew: PhantomData< EntryNew >,
}
impl < SparseVector, EntryNew, Index, Coefficient >
Iterator for
ChangeEntryType
< SparseVector, EntryNew >
where SparseVector: Iterator,
SparseVector::Item: KeyValGet< Key = Index, Val = Coefficient >,
EntryNew: KeyValNew <
Key = Index,
Val = Coefficient
>,
{
type Item = EntryNew;
fn next( &mut self ) -> Option< Self::Item > {
self.entry_iter.next().map(|entry| EntryNew::new( entry.key(), entry.val() ))
}
}
#[derive(new,Clone,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct FilterChangeIndex
< SparseVector, IndexFilterChanger, IndexNew, >
{
entry_iter: SparseVector,
index_filter_changer: IndexFilterChanger,
phantom_indexnew: PhantomData< IndexNew >,
}
impl < SparseVector, IndexFilterChanger, IndexNew, Coefficient, >
Iterator for
FilterChangeIndex
< SparseVector, IndexFilterChanger, IndexNew, >
where SparseVector: Iterator,
SparseVector::Item: KeyValGet< Val = Coefficient >,
IndexFilterChanger: EvaluateFunction< <SparseVector::Item as KeyValGet>::Key, Option<IndexNew> >,
{
type Item = ( IndexNew, Coefficient );
fn next( &mut self ) -> Option< Self::Item > {
for entry in self.entry_iter.by_ref() {
match self.index_filter_changer.evaluate_function( entry.key() ) {
None => return None,
Some( index_new) => return Some( (index_new, entry.val() ) ),
}
}
None
}
}
#[derive(new,Clone,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct EntrywiseProduct
< VectorA, VectorB, RingOperator, OrderOperator >
where
VectorA: Iterator,
VectorB: Iterator,
{
vec_a: VectorA,
vec_b: VectorB,
next_a: Option< VectorA::Item >,
next_b: Option< VectorB::Item >,
ring_operator: RingOperator,
order_operator: OrderOperator,
}
impl < VectorA, VectorB, RingOperator, OrderOperator, Index >
Iterator for
EntrywiseProduct
< VectorA, VectorB, RingOperator, OrderOperator >
where RingOperator: SemiringOperations,
OrderOperator: JudgeOrder< Index >,
VectorA: Iterator,
VectorB: Iterator,
VectorA::Item: KeyValSet<
Key = Index,
Val = RingOperator::Element,
>,
VectorB::Item: KeyValGet<
Key = Index,
Val = RingOperator::Element,
>,
{
type Item = VectorA::Item;
fn next( &mut self) -> Option< Self::Item >
{
loop {
if self.next_a.is_none() || self.next_b.is_none() { return None }
let a_key = self.next_a.as_ref().unwrap().key();
let b_key = self.next_b.as_ref().unwrap().key();
match self
.order_operator
.judge_cmp(
&a_key,
&b_key
) {
Ordering::Less => {
self.next_a = self.vec_a.next();
}
Ordering::Greater => {
self.next_b = self.vec_b.next();
}
Ordering::Equal => {
let next_a = self.vec_a.next();
let next_b = self.vec_b.next();
let next_a_old = std::mem::replace(&mut self.next_a, next_a).unwrap();
let next_b_old = std::mem::replace(&mut self.next_b, next_b).unwrap();
let mut return_value = next_a_old;
return_value.set_val(
self.ring_operator.multiply(
return_value.val(),
next_b_old.val(),
)
);
return Some( return_value )
}
}
}
}
}
pub fn sort_by_order_operator_on_indices< T, OrderOperator >( vec: &mut Vec< T >, order_operator: OrderOperator )
where
T: KeyValGet,
OrderOperator: JudgeOrder< T::Key >,
{
vec.sort_by(|a,b| order_operator.judge_cmp(& a.key(),& b.key()) )
}
pub fn sort_unstable_by_order_operator_on_indices< T, OrderOperator >( vec: &mut Vec< T >, order_operator: OrderOperator )
where
T: KeyValGet,
OrderOperator: JudgeOrder< T::Key >,
{
vec.sort_unstable_by(|a,b| order_operator.judge_cmp(& a.key(),& b.key()) )
}
pub trait VectorOperations< Index, RingElement>
where Self: IntoIterator,
Self::Item: KeyValGet< Key = Index, Val = RingElement >,
{
fn drop_zeros< RingOperator >
( self, ring_operator: RingOperator )
->
DropZeros< Self::IntoIter, RingOperator >
where Self: Sized,
RingOperator: SemiringOperations< Element = RingElement >,
{
DropZeros{ undropped: self.into_iter(), ring_operator, }
}
fn scale_by
< RingOperator >
( self, scalar: RingElement, ring_operator: RingOperator )
->
Scale < Self::IntoIter, RingOperator >
where Self: Sized,
< Self as IntoIterator>::Item: KeyValSet + PartialEq,
RingOperator: SemiringOperations< Element = RingElement >,
{
Scale{ unscaled: self.into_iter(), scaling_coefficient: scalar, ring_operator, }
}
fn gather < RingOperator > ( self, ring_operator: RingOperator )
-> Gather < Self::IntoIter, RingOperator >
where Self: Sized,
Self::IntoIter: PeekUnqualified,
<Self as IntoIterator>::Item: KeyValGet< Val = RingElement > + KeyValSet < Val = RingOperator::Element > + PartialEq,
RingOperator: SemiringOperations< Element = RingElement >,
Index: PartialEq,
{
Gather{ ungathered: self.into_iter(), ring_operator, }
}
fn simplify < RingOperator > ( self, ring_operator: RingOperator )
-> Simplify < Self::IntoIter, RingOperator >
where Self: Sized,
Self::IntoIter: PeekUnqualified,
<Self as IntoIterator>::Item: KeyValSet < Val = RingElement >,
RingOperator: SemiringOperations< Element = RingElement >,
Index: PartialEq,
{
Simplify{ unsimplified: self.into_iter(), ring_operator, }
}
fn negate < RingOperator > (self, ring_operator: RingOperator )
-> Negate< Self::IntoIter, RingOperator >
where
Self: Sized,
RingOperator: RingOperations< Element = RingElement >,
Self::Item: KeyValSet + PartialEq,
{
Negate::new( self.into_iter(), ring_operator )
}
fn multiply_with_matrix_fnmut_unsimplified < RingOperator, OrderOperator, Matrix, MatrixRowOrColumn, MatrixIndex, > (
self,
mut matrix: Matrix,
ring_operator: RingOperator,
order_operator: OrderOperator,
)
-> IteratorsMergedInSortedOrder<
Scale< MatrixRowOrColumn::IntoIter, RingOperator >,
OrderOperator,
>
where
Self: Sized,
Self::Item: KeyValGet < Val = RingElement >,
Matrix: FnMut( Index ) -> MatrixRowOrColumn,
MatrixRowOrColumn: IntoIterator,
MatrixRowOrColumn::Item: KeyValSet< Key = MatrixIndex, Val = RingElement >,
OrderOperator: JudgePartialOrder< < MatrixRowOrColumn as IntoIterator >::Item >,
MatrixIndex: PartialEq,
RingOperator: Clone + SemiringOperations< Element = RingElement >,
{
self.into_iter()
.map( |x|
( x.val(), matrix(x.key()).into_iter() )
)
.linearly_combine_scalar_vector_pairs_without_symplifying( ring_operator, order_operator )
}
fn multiply_with_matrix_fnmut_unsimplified_result < RingOperator, OrderOperator, Matrix, MatrixView, MatrixIndex, > (
self,
mut matrix: Matrix,
ring_operator: RingOperator,
order_operator: OrderOperator,
)
-> Result<
IteratorsMergedInSortedOrder<
Scale< MatrixView::IntoIter, RingOperator, >,
OrderOperator,
>,
Index,
>
where
Self: Sized,
Self::Item: KeyValGet< Val = RingElement >,
Matrix: FnMut( Index ) -> Result< MatrixView, Index >,
MatrixView: IntoIterator<
Item: KeyValSet<
Key: PartialEq,
Val= RingElement
>
>,
OrderOperator: JudgePartialOrder< < MatrixView as IntoIterator>::Item >, MatrixIndex: PartialEq,
RingOperator: Clone + SemiringOperations< Element = RingElement >,
{
let mut summands = Vec::new();
for x in self.into_iter() {
let slice = matrix( x.key() )?;
summands.push( (x.val(), slice ) );
}
Ok( summands
.linearly_combine_scalar_vector_pairs_without_symplifying(
ring_operator,
order_operator,
)
)
}
fn multiply_matrix_fnmut < RingOperator, OrderOperator, Matrix, MatrixView, MatrixIndex, > (
self,
matrix: Matrix,
ring_operator: RingOperator,
order_operator: OrderOperator,
)
-> Simplify<
IteratorsMergedInSortedOrder<
Scale< MatrixView::IntoIter, RingOperator, >,
OrderOperator,
>,
RingOperator,
>
where
Self: Sized,
Matrix: FnMut( Index ) -> MatrixView,
MatrixView: IntoIterator<
Item: KeyValSet<
Key = MatrixIndex,
Val = RingOperator::Element
>,
>,
OrderOperator: JudgePartialOrder< < MatrixView as IntoIterator >::Item >,
MatrixIndex: PartialEq,
RingOperator: Clone + SemiringOperations< Element = RingElement >,
{
self.multiply_with_matrix_fnmut_unsimplified(matrix, ring_operator.clone(), order_operator)
.simplify( ring_operator )
}
fn multiply_matrix_fnmut_result < RingOperator, OrderOperator, Matrix, MatrixView, MatrixIndex, > (
self,
matrix: Matrix,
ring_operator: RingOperator,
order_operator: OrderOperator,
)
-> Result<
Simplify<
IteratorsMergedInSortedOrder<
Scale< MatrixView::IntoIter, RingOperator, >,
OrderOperator,
>,
RingOperator,
>,
Index,
>
where
Self: Sized,
Matrix: FnMut( Index ) -> Result< MatrixView, Index >,
MatrixView: IntoIterator<
Item: KeyValSet<
Key = MatrixIndex,
Val = RingOperator::Element
>,
>,
OrderOperator: JudgePartialOrder< MatrixView::Item >,
MatrixIndex: PartialEq,
RingOperator: Clone + SemiringOperations< Element = RingElement >,
{
let unsimplified = self.multiply_with_matrix_fnmut_unsimplified_result::<
RingOperator,
OrderOperator,
Matrix,
MatrixView,
MatrixIndex
>
(
matrix,
ring_operator.clone(),
order_operator
)?;
return Ok( unsimplified.simplify( ring_operator ) )
}
fn multiply_self_as_a_row_vector_with_matrix_custom < Matrix, RingOperator, OrderOperatorForRowEntries, > (
self,
matrix: Matrix,
ring_operator: RingOperator,
order_operator_for_row_entries: OrderOperatorForRowEntries,
)
-> Simplify<
IteratorsMergedInSortedOrder<
Scale< Matrix::Row, RingOperator >,
OrderOperatorForRowEntries,
>,
RingOperator,
>
where
Self: Sized,
Matrix: MatrixOracle< RowIndex=Index >,
Matrix::RowEntry: KeyValSet< Key = Matrix::ColumnIndex, Val = RingOperator::Element >,
OrderOperatorForRowEntries: Clone + JudgePartialOrder< Matrix::RowEntry >,
Matrix::ColumnIndex: PartialEq,
RingElement: Clone,
RingOperator: Clone + SemiringOperations< Element = RingElement >,
{
let matrix = |i| { matrix.row(&i) };
self.multiply_matrix_fnmut( matrix, ring_operator, order_operator_for_row_entries )
}
fn multiply_self_as_a_column_vector_with_matrix_and_return_entries_in_reverse_order_custom < Matrix, RingOperator, OrderOperatorForColumnEntries > (
self,
matrix: Matrix,
ring_operator: RingOperator,
order_operator_for_column_entries: OrderOperatorForColumnEntries,
)
-> Simplify<
IteratorsMergedInSortedOrder<
Scale< Matrix::ColumnReverse, RingOperator >,
ReverseOrder< OrderOperatorForColumnEntries >,
>,
RingOperator,
>
where
Self: Sized,
Matrix: MatrixOracle< ColumnIndex = Index >,
Matrix::ColumnEntry: PartialEq + KeyValSet < Key = Matrix::RowIndex, Val = RingOperator::Element >,
OrderOperatorForColumnEntries: Clone + JudgePartialOrder< Matrix::ColumnEntry >,
Matrix::RowIndex: PartialEq,
RingElement: Clone,
RingOperator: Clone + SemiringOperations< Element = RingElement >,
{
let matrix_function = |i| { matrix.column_reverse(&i) };
self.multiply_matrix_fnmut( matrix_function, ring_operator, ReverseOrder::new( order_operator_for_column_entries ) )
}
fn multiply_self_as_a_row_vector_with_matrix< Matrix >(
self,
matrix: Matrix,
)
-> LinearCombinationOfRows< Matrix >
where
Self: Sized,
Matrix: MatrixAlgebra< Coefficient = RingElement, RowIndex = Index >,
Matrix::RowEntry: KeyValSet< Key = Matrix::ColumnIndex, Val = Matrix::Coefficient >,
Matrix::Coefficient: Clone,
Matrix::RingOperator: Clone,
Matrix::ColumnIndex: PartialEq,
{
let matrix_function = |i| { matrix.row(&i) };
let order_operator = matrix.order_operator_for_row_entries();
self.multiply_matrix_fnmut( matrix_function, matrix.ring_operator(), order_operator )
}
fn multiply_self_as_a_row_vector_with_matrix_result< Matrix >(
self,
matrix: Matrix,
)
-> Result<
LinearCombinationOfRows< Matrix >,
Index,
>
where
Self: Sized,
Matrix: MatrixAlgebra< Coefficient = RingElement, RowIndex = Index >,
Matrix::RowEntry: KeyValSet< Key = Matrix::ColumnIndex, Val = Matrix::Coefficient >,
Matrix::Coefficient: Clone,
Matrix::RingOperator: Clone,
Matrix::ColumnIndex: PartialEq,
{
let matrix_function = |i| { matrix.row_result(&i) };
let order_operator = matrix.order_operator_for_row_entries();
self.multiply_matrix_fnmut_result( matrix_function, matrix.ring_operator(), order_operator )
}
fn multiply_self_as_a_row_vector_with_matrix_and_return_entries_in_reverse_order< Matrix >(
self,
matrix: Matrix,
)
-> LinearCombinationOfRowsReverse< Matrix >
where
Self: Sized,
Matrix: MatrixAlgebra< Coefficient = RingElement, RowIndex = Index >,
Matrix::RowEntry: KeyValSet< Key = Matrix::ColumnIndex, Val = Matrix::Coefficient >,
Matrix::Coefficient: Clone,
Matrix::RingOperator: Clone,
Matrix::ColumnIndex: PartialEq,
{
let matrix_function = |i| { matrix.row_reverse(&i) };
let order_operator = ReverseOrder::new(matrix.order_operator_for_row_entries());
self.multiply_matrix_fnmut( matrix_function, matrix.ring_operator(), order_operator )
}
fn multiply_self_as_a_row_vector_with_matrix_and_return_entries_in_reverse_order_result< Matrix >(
self,
matrix: Matrix,
)
-> Result< LinearCombinationOfRowsReverse< Matrix >, Index >
where
Self: Sized,
Matrix: MatrixAlgebra< Coefficient = RingElement, RowIndex = Index >,
Matrix::RowEntry: KeyValSet< Key = Matrix::ColumnIndex, Val = Matrix::Coefficient >,
Matrix::Coefficient: Clone,
Matrix::RingOperator: Clone,
Matrix::ColumnIndex: PartialEq,
{
let matrix_function = |i| { matrix.row_reverse_result(&i) };
let order_operator = ReverseOrder::new(matrix.order_operator_for_row_entries());
self.multiply_matrix_fnmut_result( matrix_function, matrix.ring_operator(), order_operator )
}
fn multiply_self_as_a_column_vector_with_matrix< Matrix >(
self,
matrix: Matrix,
)
-> LinearCombinationOfColumns< Matrix >
where
Self: Sized,
Matrix: MatrixAlgebra< Coefficient=RingElement, ColumnIndex=Index>,
Matrix::ColumnEntry: KeyValSet < Key=Matrix::RowIndex, Val=Matrix::Coefficient >,
Matrix::Coefficient: Clone,
Matrix::RingOperator: Clone,
Matrix::RowIndex: PartialEq,
{
let matrix_function = |i| { matrix.column(&i) };
let order_operator = matrix.order_operator_for_column_entries();
self.multiply_matrix_fnmut( matrix_function, matrix.ring_operator(), order_operator )
}
fn multiply_self_as_a_column_vector_with_matrix_result< Matrix >(
self,
matrix: Matrix,
)
-> Result< LinearCombinationOfColumns< Matrix >, Index >
where
Self: Sized,
Matrix: MatrixAlgebra< Coefficient=RingElement, ColumnIndex=Index>,
Matrix::ColumnEntry: KeyValSet < Key=Matrix::RowIndex, Val=Matrix::Coefficient >,
Matrix::Coefficient: Clone,
Matrix::RingOperator: Clone,
Matrix::RowIndex: PartialEq,
{
let matrix_function = |i| { matrix.column_result(&i) };
let order_operator = matrix.order_operator_for_column_entries();
self.multiply_matrix_fnmut_result( matrix_function, matrix.ring_operator(), order_operator )
}
fn multiply_self_as_a_column_vector_with_matrix_and_return_entries_in_reverse_order_result< Matrix >(
self,
matrix: Matrix,
)
-> Result< LinearCombinationOfColumnsReverse< Matrix >, Index >
where
Self: Sized,
Matrix: MatrixAlgebra< Coefficient=RingElement, ColumnIndex=Index >,
Matrix::ColumnEntry: KeyValSet < Key=Matrix::RowIndex, Val=Matrix::Coefficient >,
Matrix::Coefficient: Clone,
Matrix::RingOperator: Clone,
Matrix::RowIndex: PartialEq,
{
let matrix_function = |i| { matrix.column_reverse_result(&i) };
let order_operator = ReverseOrder::new(matrix.order_operator_for_column_entries());
self.multiply_matrix_fnmut_result( matrix_function, matrix.ring_operator(), order_operator )
}
fn multiply_self_as_a_column_vector_with_matrix_and_return_entries_in_reverse_order< Matrix >(
self,
matrix: Matrix,
)
-> LinearCombinationOfColumnsReverse< Matrix >
where
Self: Sized,
Matrix: MatrixAlgebra< Coefficient=RingElement, ColumnIndex=Index >,
Matrix::ColumnEntry: KeyValSet < Key=Matrix::RowIndex, Val=Matrix::Coefficient >,
Matrix::Coefficient: Clone,
Matrix::RingOperator: Clone,
Matrix::RowIndex: PartialEq,
{
let matrix_function = |i| { matrix.column_reverse(&i) };
let order_operator = ReverseOrder::new(matrix.order_operator_for_column_entries());
self.multiply_matrix_fnmut( matrix_function, matrix.ring_operator(), order_operator )
}
fn multiply_entrywise
< RingOperator, OrderOperator, OtherIterable >
( self, other_iterable: OtherIterable, ring_operator: RingOperator, order_operator: OrderOperator )
->
EntrywiseProduct< Self::IntoIter, OtherIterable::IntoIter, RingOperator, OrderOperator >
where Self: Sized,
OtherIterable: IntoIterator,
OtherIterable::Item: KeyValGet < Key = Index, Val = RingElement >,
RingOperator: SemiringOperations< Element = RingElement >,
OrderOperator: JudgeOrder< Index >,
{
let mut vec_a = self.into_iter();
let mut vec_b = other_iterable.into_iter();
let next_a = vec_a.next();
let next_b = vec_b.next();
EntrywiseProduct{
vec_a,
vec_b,
next_a,
next_b,
ring_operator,
order_operator,
}
}
fn dot
< RingOperator, OrderOperator, OtherIterable >
( self, other_iterable: OtherIterable, ring_operator: RingOperator, order_operator: OrderOperator )
->
RingElement
where Self: Sized,
<Self as IntoIterator>::Item: KeyValSet < Val = RingElement >,
OtherIterable: IntoIterator,
OtherIterable::Item: KeyValGet< Key = Index, Val = RingElement >,
RingOperator: Clone + SemiringOperations< Element = RingElement >,
OrderOperator: JudgeOrder< Index >,
{
self.multiply_entrywise(
other_iterable,
ring_operator.clone(),
order_operator,
)
.sum_coefficients(ring_operator)
}
fn dot_slow
< RingOperator, OtherIterable >
( self, other_iterator: OtherIterable, ring_operator: RingOperator, )
->
RingElement
where Self: Sized,
<Self as IntoIterator>::Item: KeyValSet < Val = RingElement >,
OtherIterable: IntoIterator,
OtherIterable::Item: KeyValGet< Key = Index, Val = RingElement >,
RingOperator: Clone + SemiringOperations< Element= RingElement >,
Index: Hash + std::cmp::Eq,
{
let mut u: HashMap< Index, RingElement > = self.into_iter()
.map(|x| (x.key(), x.val()) )
.collect();
let mut dot = RingOperator::zero();
for entry_a in other_iterator.into_iter() {
if let Some( entry_b_coefficient ) = u.remove( &entry_a.key() ) {
let product = ring_operator.multiply( entry_a.val(), entry_b_coefficient );
dot = < RingOperator as SemiringOperations >::add( & ring_operator, dot, product );
}
}
return dot
}
fn add_unsimplified < OrderOperator, Other > (self, other: Other, order_operator: OrderOperator )
-> MergeTwoIteratorsByOrderOperator< Self::IntoIter, Other::IntoIter, OrderOperator,>
where
Self: Sized,
< Self as IntoIterator>::IntoIter: PeekUnqualified,
Other: IntoIterator< Item = < Self as IntoIterator >::Item >,
Other::IntoIter: PeekUnqualified,
OrderOperator: JudgePartialOrder< < Self as IntoIterator >::Item >,
Index: PartialEq,
{
MergeTwoIteratorsByOrderOperator::new( self.into_iter(), other.into_iter(), order_operator )
}
fn add < RingOperator, OrderOperator, Other > (self, other: Other, ring_operator: RingOperator, order_operator: OrderOperator )
-> Simplify<
MergeTwoIteratorsByOrderOperator<
Self::IntoIter,
Other::IntoIter,
OrderOperator,
>,
RingOperator,
>
where
Self: Sized,
< Self as IntoIterator>::IntoIter: PeekUnqualified,
< Self as IntoIterator >::Item: PartialEq + KeyValSet < Val = RingElement >,
Other: IntoIterator< Item = < Self as IntoIterator >::Item >,
Other::IntoIter: PeekUnqualified,
OrderOperator: JudgePartialOrder< < Self as IntoIterator >::Item >,
RingOperator: SemiringOperations< Element = RingElement >,
Index: PartialEq,
{
MergeTwoIteratorsByOrderOperator::new( self.into_iter(), other.into_iter(), order_operator ).simplify(ring_operator)
}
fn subtract_unsimplified < RingOperator, OrderOperator, Other > (self, other: Other, ring_operator: RingOperator, order_operator: OrderOperator )
-> MergeTwoIteratorsByOrderOperator< Self::IntoIter, Peekable< Negate<Other::IntoIter,RingOperator> >,OrderOperator,>
where
Self: Sized, < Self as IntoIterator>::IntoIter: PeekUnqualified, < Self as IntoIterator >::Item: PartialEq + KeyValSet < Val = RingElement >,
Other: IntoIterator< Item = < Self as IntoIterator >::Item >,
Other::IntoIter: PeekUnqualified,
OrderOperator: JudgePartialOrder< < Self as IntoIterator >::Item >,
RingOperator: Clone + RingOperations< Element = RingElement >,
Index: PartialEq,
{
let pos = self.into_iter();
let neg = Negate::new( other.into_iter(), ring_operator ).peekable();
MergeTwoIteratorsByOrderOperator::new( pos, neg, order_operator )
}
fn subtract < RingOperator, OrderOperator, Other > (self, other: Other, ring_operator: RingOperator, order_operator: OrderOperator )
-> Simplify<
MergeTwoIteratorsByOrderOperator<
Self::IntoIter,
Peekable< Negate< Other::IntoIter,RingOperator > >,
OrderOperator,
>,
RingOperator,
>
where
Self: Sized,
< Self as IntoIterator>::IntoIter: PeekUnqualified,
< Self as IntoIterator >::Item: PartialEq + KeyValSet < Val = RingElement >,
Other: IntoIterator< Item = < Self as IntoIterator >::Item >,
Other::IntoIter: PeekUnqualified,
OrderOperator: JudgePartialOrder< < Self as IntoIterator >::Item >,
RingOperator: Clone + RingOperations< Element = RingElement >,
Index: PartialEq,
{
self.into_iter().subtract_unsimplified(other, ring_operator.clone(), order_operator).simplify(ring_operator)
}
fn include_collection
< CollectionToInclude: MapHasKeyOrSequenceHasElement<Index> >
( self, collection_to_include: CollectionToInclude )
->
OnlyIndicesInsideCollection< Self::IntoIter, CollectionToInclude, >
where
CollectionToInclude: MapHasKeyOrSequenceHasElement<Index>,
Self: Sized,
{
OnlyIndicesInsideCollection::new( self.into_iter(), collection_to_include )
}
fn exclude_collection
< CollectionToExclude: MapHasKeyOrSequenceHasElement<Index> >
( self, collection_to_exclude: CollectionToExclude )
->
OnlyIndicesOutsideCollection< Self::IntoIter, CollectionToExclude, >
where
Self: Sized,
{
OnlyIndicesOutsideCollection::new( self.into_iter(), collection_to_exclude )
}
fn sum_coefficients< RingOperator >( self, ring_operator: RingOperator ) -> RingElement
where
Self: Sized,
< Self as IntoIterator >::Item: KeyValGet< Val = RingElement >,
RingOperator: SemiringOperations< Element = RingElement >,
{
let mut sum = RingOperator::zero();
for entry in self { sum = ring_operator.add( sum, entry.val() ) }
return sum
}
}
impl < T, Index, RingElement >
VectorOperations < Index, RingElement >
for T
where
T: IntoIterator,
T::Item: KeyValGet< Key = Index, Val = RingElement >,
{}
pub trait MultiVectorOperations
{
fn linearly_combine_scalar_vector_pairs_without_symplifying< RingOperator, OrderOperator, Vector, Index, RingElement >(
self,
ring_operator: RingOperator,
order_operator: OrderOperator
)
->
IteratorsMergedInSortedOrder<
Scale< Vector::IntoIter, RingOperator >,
OrderOperator,
>
where
Self: Sized,
Self: IntoIterator< Item = (RingOperator::Element, Vector ) >,
Vector: IntoIterator<
IntoIter: Iterator<
Item: KeyValSet<
Key = Index,
Val = RingElement
>,
>
>,
Index: PartialEq,
OrderOperator: JudgePartialOrder< Vector::Item >,
RingOperator: Clone + SemiringOperations< Element = RingElement >,
{
self.into_iter().map(
| (scale, unscaled) |
Scale{ unscaled: unscaled.into_iter(), scaling_coefficient: scale, ring_operator: ring_operator.clone(), }
)
.hit_merge_by_predicate(order_operator)
}
fn linearly_combine_scalar_vector_pairs< RingOperator, OrderOperator, Vector, RingElement >(
self,
ring_operator: RingOperator,
order_operator: OrderOperator
)
->
Simplify<
IteratorsMergedInSortedOrder<
Scale< Vector::IntoIter, RingOperator, >,
OrderOperator,
>,
RingOperator,
>
where
Self: Sized,
Self: IntoIterator< Item = (RingElement, Vector ) >,
Vector: IntoIterator,
Vector::Item: PartialEq + KeyValSet < Val = RingElement >,
< Vector::Item as KeyValGet >::Key: PartialEq,
OrderOperator: JudgePartialOrder< Vector::Item >,
RingOperator: Clone + SemiringOperations< Element = RingElement >,
{
self.into_iter().map(
| (scale, unscaled) |
Scale{ unscaled: unscaled.into_iter(), scaling_coefficient: scale, ring_operator: ring_operator.clone(), }
)
.hit_merge_by_predicate(order_operator)
.simplify( ring_operator )
}
fn sum_vectors_unsimplified< OrderOperator >( self, order_operator: OrderOperator )
-> IteratorsMergedInSortedOrder< <Self::Item as IntoIterator >::IntoIter, OrderOperator >
where
Self: Sized,
Self: IntoIterator,
Self::Item: IntoIterator,
OrderOperator: JudgePartialOrder<
< <Self as IntoIterator >::Item as IntoIterator >::Item
>,
{
self.hit_merge_by_predicate( order_operator )
}
fn sum_vectors< RingOperator, OrderOperator, RingElement, Index >( self, ring_operator: RingOperator, order_operator: OrderOperator )
->
Simplify<
IteratorsMergedInSortedOrder< <Self::Item as IntoIterator >::IntoIter, OrderOperator >,
RingOperator,
>
where
Self: Sized,
Self: IntoIterator,
Self::Item: IntoIterator,
< Self::Item as IntoIterator >::Item: PartialEq + KeyValSet < Key = Index, Val = RingElement >,
OrderOperator: JudgePartialOrder<
< <Self as IntoIterator >::Item as IntoIterator >::Item
>,
RingOperator: SemiringOperations< Element = RingElement >,
Index: PartialEq,
{
self.hit_merge_by_predicate( order_operator ).simplify( ring_operator )
}
}
impl < T >
MultiVectorOperations for T
{}
#[cfg(test)]
mod tests {
use crate::algebra::vectors::operations::MultiVectorOperations;
#[test]
fn test_subtract_with_trait() {
use crate::algebra::vectors::operations::VectorOperations;
use crate::algebra::rings::types::native::FieldFloat64;
use crate::utilities::order::OrderOperatorAuto;
let order_operator = OrderOperatorAuto::new();
let ring_operator = FieldFloat64::new();
let a = vec![ (1,1.), (2,2.) ].into_iter().peekable();
let b = vec![ (2,2.), (3,3.) ].into_iter().peekable();
let sum = a.subtract( b, ring_operator, order_operator );
assert!( sum.eq( vec![ (1,1.), (3,-3.) ] ) )
}
#[test]
fn test_add_2_with_trait() {
use crate::algebra::vectors::operations::VectorOperations;
use crate::algebra::rings::types::native::FieldFloat64;
use crate::utilities::order::OrderOperatorAuto;
let order_operator = OrderOperatorAuto::new();
let ring_operator = FieldFloat64::new();
let a = vec![ (1,1.), (2,2.) ].into_iter().peekable();
let b = vec![ (2,2.), (3,3.) ].into_iter().peekable();
let sum = a.add( b, ring_operator, order_operator );
assert!( sum.eq( vec![ (1,1.), (2,4.), (3,3.) ] ) )
}
#[test]
fn test_add_k_with_trait() {
use crate::algebra::rings::types::native::FieldFloat64;
use crate::utilities::order::OrderOperatorAuto;
let order_operator = OrderOperatorAuto::new();
let ring_operator = FieldFloat64::new();
let a = vec![ (1,1.), (2,2.) ].into_iter().peekable();
let b = vec![ (2,2.), (3,3.) ].into_iter().peekable();
let c = vec![ (3,3.), (4,4.) ].into_iter().peekable();
let sum = [a,b,c].sum_vectors( ring_operator, order_operator );
assert!( sum.eq( vec![ (1,1.), (2,4.), (3,6.), (4,4.) ] ) )
}
#[test]
fn test_add_2() {
use itertools::Itertools;
use crate::algebra::vectors::operations::VectorOperations;
use crate::algebra::rings::types::native::FieldFloat64;
let sum = vec![ (1,1.), (2,2.) ]
.into_iter() .merge( vec![ (2,2.), (3,3.) ] ) .peekable() .simplify( FieldFloat64::new() );
assert!( sum.eq( vec![ (1,1.), (2,4.), (3,3.) ] ) )
}
#[test]
fn test_add_k() {
use itertools::Itertools;
use crate::algebra::vectors::operations::VectorOperations;
use crate::algebra::rings::types::native::FieldFloat64;
let vectors = vec![ vec![ (1,1.), (2,2.) ], vec![ (2,2.), (3,3.) ], vec![ (3,3.), (4,4.) ] ];
let sum = vectors
.into_iter() .kmerge() .peekable() .simplify( FieldFloat64::new() );
assert!( sum.eq( vec![ (1,1.), (2,4.), (3,6.), (4,4.) ] ) )
}
#[test]
fn test_add_k_with_hit() {
use crate::utilities::iterators::merge::hit::HitMergeByPredicateTrait;
use crate::algebra::vectors::operations::VectorOperations;
use crate::algebra::rings::types::native::FieldFloat64;
use crate::utilities::order::{OrderOperatorAuto, ReverseOrder};
let order_operator = OrderOperatorAuto::new(); let order_operator = ReverseOrder::new( order_operator );
let vectors = vec![ vec![ (2,2.), (1,1.) ], vec![ (3,3.), (2,2.) ], vec![ (4,4.), (3,3.) ] ];
let sum = vectors
.into_iter() .hit_merge_by_predicate(order_operator) .peekable() .simplify( FieldFloat64::new() );
assert!( sum.eq( vec![ (4,4.), (3,6.), (2,4.), (1,1.) ] ) )
}
#[test]
fn test_subtract() {
use itertools::Itertools;
use crate::algebra::vectors::operations::VectorOperations;
use crate::algebra::rings::types::native::FieldFloat64;
let a = vec![ (1,1.), (2,2.) ];
let b = vec![ (2,2.), (3,3.) ];
let sum = a
.into_iter() .merge( b.into_iter() .negate( FieldFloat64::new() ) )
.peekable() .simplify( FieldFloat64::new() );
assert!( sum.eq( vec![ (1,1.), (3,-3.) ] ) )
}
#[test]
fn test_basic_transforms() {
use crate::algebra::rings::types::native::FieldFloat64;
use crate::algebra::vectors::operations::VectorOperations;
let ring_operator = FieldFloat64::new();
let entry_data = vec![ (1, 1.), (2, 2.), (3, 3.), (3, 3.), (4, 0.) ];
let sparse_vec = entry_data.iter().cloned();
let scaled : Vec<_> = sparse_vec
.clone() .scale_by( 2., ring_operator )
.collect(); assert_eq!( scaled, vec![ (1, 2.), (2, 4.), (3, 6.), (3, 6.), (4, 0.) ]);
let dropped : Vec<_> = sparse_vec
.clone() .drop_zeros( ring_operator )
.collect();
assert_eq!( dropped, vec![ (1, 1.), (2, 2.), (3, 3.), (3, 3.) ]);
let gathered : Vec<_> = sparse_vec
.clone() .peekable() .gather( ring_operator )
.collect(); assert_eq!( gathered, vec![ (1, 1.), (2, 2.), (3, 6.), (4, 0.) ]);
let gathered : Vec<_> = sparse_vec
.clone() .peekable() .simplify( ring_operator )
.collect(); assert_eq!( gathered, vec![ (1, 1.), (2, 2.), (3, 6.), ]);
}
#[test]
fn doctest_draft_test_filter_map() {
use std::collections::HashMap;
use crate::algebra::vectors::operations::{FilterChangeIndex, };
let entry_iter_data: Vec< (usize, usize) > = vec![(1,1), (2,2), (3,3)];
let entry_iter = entry_iter_data.iter();
let mut hash = HashMap::new();
hash.insert( 1usize, -1i32 );
hash.insert( 2usize, -2i32 );
let iter_filtermapped_by_index: FilterChangeIndex<
std::slice::Iter<'_, (usize, usize)>,
HashMap<usize,i32>,
i32
>
= FilterChangeIndex::new( entry_iter, hash );
itertools::assert_equal( iter_filtermapped_by_index, vec![(-1,1usize), (-2,2usize)] );
}
#[test]
fn doctest_draft_test_negate() {
use crate::algebra::vectors::operations::Negate;
use crate::algebra::rings::types::field_prime_order::PrimeOrderField;
let vec = vec![ (0, 0usize), (1, 1usize) ];
let ring_operator = PrimeOrderField::new(7);
let negated = Negate::new( vec.iter().cloned(), ring_operator );
itertools::assert_equal( negated, vec![ (0, 0usize), (1, 6usize) ] );
}
#[test]
fn test_multiply_matrix() {
use crate::algebra::rings::types::native::FieldFloat64;
use crate::algebra::vectors::operations::VectorOperations;
use crate::utilities::order::OrderOperatorAuto;
let v = vec![ (0, 1.), (1, 1.) ];
let data = vec![
vec![ (0, 1.), (1, 1.) ],
vec![ (1, 1.) ],
vec![ ],
];
let matrix = |i| { let row: &Vec<_> = &data[i]; row.clone() };
let ring_operator = FieldFloat64::new();
let order_operator = OrderOperatorAuto::new();
let u: Vec<_> = v.multiply_with_matrix_fnmut_unsimplified( matrix, ring_operator, order_operator ).collect();
println!("{:?}", & u );
assert!( u.into_iter().eq( vec![ (0, 1.), (1, 1.), (1, 1.) ] ) );
}
#[test]
fn test_misc_in_operations() {
}
}