use std::{fmt::Debug, marker::PhantomData};
use derive_getters::{Dissolve, Getters};
use crate::{algebra::matrices::query::{ MatrixOracle}, utilities::{functions::evaluate::EvaluateFunction, iterators::general::MapByTransform}};
use crate::algebra::vectors::entries::{KeyValNew, ReindexEntry};
#[derive(Clone,Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct ReindexSquareMatrix< MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
{
matrix_unreindexed: MatrixUnreindexed,
reindex_function_old_to_new: ReindexFunctionOldToNew,
reindex_function_new_to_old: ReindexFunctionNewToOld,
phantom_indexold: PhantomData< IndexOld >,
phantom_indexnew: PhantomData< IndexNew >,
phantom_entrynew: PhantomData< EntryNew >,
}
impl < MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
ReindexSquareMatrix
< MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
{
pub fn new( matrix_unreindexed: MatrixUnreindexed, reindex_function_old_to_new: ReindexFunctionOldToNew, reindex_function_new_to_old: ReindexFunctionNewToOld )
->
ReindexSquareMatrix
< MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
{
ReindexSquareMatrix{ matrix_unreindexed, reindex_function_old_to_new, reindex_function_new_to_old, phantom_indexnew: PhantomData, phantom_indexold: PhantomData, phantom_entrynew: PhantomData }
}
}
impl < MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
MatrixOracle for
ReindexSquareMatrix
< MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
where
MatrixUnreindexed: MatrixOracle< RowIndex = IndexOld, ColumnIndex = IndexOld >,
ReindexFunctionOldToNew: Clone + EvaluateFunction< IndexOld, IndexNew >,
ReindexFunctionNewToOld: Clone + EvaluateFunction< IndexNew, MatrixUnreindexed::RowIndex >,
EntryNew: Clone + Debug + PartialEq + KeyValNew < Key = IndexNew, Val = MatrixUnreindexed::Coefficient >,
IndexNew: Clone + Debug + Eq,
{
type RowEntry = EntryNew;
type ColumnEntry = EntryNew;
type ColumnIndex = IndexNew;
type RowIndex = IndexNew;
type Coefficient = MatrixUnreindexed::Coefficient;
type Row = MapByTransform<
MatrixUnreindexed::Row,
EntryNew,
ReindexEntry< ReindexFunctionOldToNew >
>;
type RowReverse = MapByTransform<
MatrixUnreindexed::RowReverse,
EntryNew,
ReindexEntry< ReindexFunctionOldToNew >
>;
type Column = MapByTransform<
MatrixUnreindexed::Column,
EntryNew,
ReindexEntry< ReindexFunctionOldToNew >
>;
type ColumnReverse = MapByTransform<
MatrixUnreindexed::ColumnReverse,
EntryNew,
ReindexEntry< ReindexFunctionOldToNew >
>;
fn row( & self, index: & Self::RowIndex ) -> Self::Row {
let selecting_index_new = (self.reindex_function_new_to_old).evaluate_function( index.clone() );
let entry_reindexer = ReindexEntry::new( self.reindex_function_old_to_new.clone() );
MapByTransform::new(
self.matrix_unreindexed.row( & selecting_index_new ),
entry_reindexer,
)
}
fn row_reverse( & self, index: & Self::RowIndex ) -> Self::RowReverse {
let selecting_index_new = (self.reindex_function_new_to_old).evaluate_function( index.clone() );
let entry_reindexer = ReindexEntry::new( self.reindex_function_old_to_new.clone() );
MapByTransform::new(
self.matrix_unreindexed.row_reverse( & selecting_index_new ),
entry_reindexer,
)
}
fn column( & self, index: & Self::ColumnIndex) -> Self::Column {
let selecting_index_new = (self.reindex_function_new_to_old).evaluate_function( index.clone() );
let entry_reindexer = ReindexEntry::new( self.reindex_function_old_to_new.clone() );
MapByTransform::new(
self.matrix_unreindexed.column( & selecting_index_new ),
entry_reindexer,
)
}
fn column_reverse( & self, index: & Self::ColumnIndex) -> Self::ColumnReverse {
let selecting_index_new = (self.reindex_function_new_to_old).evaluate_function( index.clone() );
let entry_reindexer = ReindexEntry::new( self.reindex_function_old_to_new.clone() );
MapByTransform::new(
self.matrix_unreindexed.column_reverse( & selecting_index_new ),
entry_reindexer,
)
}
fn has_row_for_index( & self, index: & Self::RowIndex ) -> bool {
let selecting_index_new = (self.reindex_function_new_to_old).evaluate_function( index.clone() );
return self.matrix_unreindexed.has_row_for_index( & selecting_index_new )
}
fn has_column_for_index( & self, index: & Self::ColumnIndex) -> bool {
let selecting_index_new = (self.reindex_function_new_to_old).evaluate_function( index.clone() );
return self.matrix_unreindexed.has_column_for_index( & selecting_index_new )
}
fn structural_nonzero_entry(& self, row: & Self::RowIndex, column: & Self::ColumnIndex ) -> Option< Self::Coefficient > {
let row = (self.reindex_function_new_to_old).evaluate_function( row.clone() );
let column = (self.reindex_function_new_to_old).evaluate_function( column.clone() );
return self.matrix_unreindexed.structural_nonzero_entry( & row, & column )
}
}
#[derive(Copy,Debug,Dissolve,Eq,PartialEq,Getters,Ord,PartialOrd)]
pub struct ReindexMatrixColumns< MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
{
matrix_unreindexed: MatrixUnreindexed,
reindex_function_old_to_new: ReindexFunctionOldToNew,
reindex_function_new_to_old: ReindexFunctionNewToOld,
phantom_indexold: PhantomData< IndexOld >,
phantom_indexnew: PhantomData< IndexNew >,
phantom_entrynew: PhantomData< EntryNew >,
}
impl < MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
ReindexMatrixColumns
< MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
{
pub fn new( matrix_unreindexed: MatrixUnreindexed, reindex_function_old_to_new: ReindexFunctionOldToNew, reindex_function_new_to_old: ReindexFunctionNewToOld )
->
ReindexMatrixColumns
< MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
{
ReindexMatrixColumns{ matrix_unreindexed, reindex_function_old_to_new, reindex_function_new_to_old, phantom_indexnew: PhantomData, phantom_indexold: PhantomData, phantom_entrynew: PhantomData }
}
}
impl< MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
Clone for
ReindexMatrixColumns
< MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
where
MatrixUnreindexed: Clone,
ReindexFunctionOldToNew: Clone,
ReindexFunctionNewToOld: Clone,
{
fn clone(&self) -> Self {
Self{
matrix_unreindexed: self.matrix_unreindexed.clone(),
reindex_function_old_to_new: self.reindex_function_old_to_new.clone(),
reindex_function_new_to_old: self.reindex_function_new_to_old.clone(),
phantom_indexold: PhantomData,
phantom_indexnew: PhantomData,
phantom_entrynew: PhantomData
}
}
}
impl < MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
MatrixOracle for
ReindexMatrixColumns
< MatrixUnreindexed, ReindexFunctionOldToNew, ReindexFunctionNewToOld, IndexOld, IndexNew, EntryNew >
where
MatrixUnreindexed: MatrixOracle< ColumnIndex = IndexOld >,
ReindexFunctionOldToNew: Clone + EvaluateFunction< IndexOld, IndexNew >,
ReindexFunctionNewToOld: Clone + EvaluateFunction< IndexNew, MatrixUnreindexed::ColumnIndex >,
EntryNew: Clone + Debug + PartialEq + KeyValNew < Key = IndexNew, Val = MatrixUnreindexed::Coefficient >,
IndexNew: Clone + Debug + Eq,
{
type RowEntry = EntryNew;
type ColumnEntry = MatrixUnreindexed::ColumnEntry;
type ColumnIndex = IndexNew;
type RowIndex = MatrixUnreindexed::RowIndex;
type Coefficient = MatrixUnreindexed::Coefficient;
type Row = MapByTransform<
MatrixUnreindexed::Row,
EntryNew,
ReindexEntry< ReindexFunctionOldToNew >
>;
type RowReverse = MapByTransform<
MatrixUnreindexed::RowReverse,
EntryNew,
ReindexEntry< ReindexFunctionOldToNew >
>;
type Column = MatrixUnreindexed::Column;
type ColumnReverse = MatrixUnreindexed::ColumnReverse;
fn row( & self, index: & Self::RowIndex ) -> Self::Row {
let entry_reindexer = ReindexEntry::new( self.reindex_function_old_to_new.clone() );
MapByTransform::new(
self.matrix_unreindexed.row( & index ),
entry_reindexer,
)
}
fn row_reverse( & self, index: & Self::RowIndex ) -> Self::RowReverse {
let entry_reindexer = ReindexEntry::new( self.reindex_function_old_to_new.clone() );
MapByTransform::new(
self.matrix_unreindexed.row_reverse( & index ),
entry_reindexer,
)
}
fn column( & self, index: & Self::ColumnIndex) -> Self::Column {
let selecting_index_new = (self.reindex_function_new_to_old).evaluate_function( index.clone() );
self.matrix_unreindexed.column( & selecting_index_new )
}
fn column_reverse( & self, index: & Self::ColumnIndex) -> Self::ColumnReverse {
let selecting_index_new = (self.reindex_function_new_to_old).evaluate_function( index.clone() );
self.matrix_unreindexed.column_reverse( & selecting_index_new )
}
fn has_row_for_index( & self, index: & Self::RowIndex ) -> bool {
return self.matrix_unreindexed.has_row_for_index( index )
}
fn has_column_for_index( & self, index: & Self::ColumnIndex) -> bool {
let selecting_index_new = (self.reindex_function_new_to_old).evaluate_function( index.clone() );
return self.matrix_unreindexed.has_column_for_index( & selecting_index_new )
}
fn structural_nonzero_entry(& self, row: & Self::RowIndex, column: & Self::ColumnIndex ) -> Option< Self::Coefficient > {
let column = (self.reindex_function_new_to_old).evaluate_function( column.clone() );
return self.matrix_unreindexed.structural_nonzero_entry( row, & column )
}
}
#[cfg(test)]
mod doc_test_drafts {
}