pub struct DualRing<T> { /* private fields */ }Expand description
Dual Ring Structure for IRCP/RCP
Represents the same episodes in two different orderings:
- Temporal Ring (RCP): Ordered by causal/temporal flow
- Influence Ring (IRCP): Ordered by influence/attention weight
This enables efficient traversal in both directions:
- Forward (RCP): “What context led to this response?”
- Inverse (IRCP): “What did this response influence?”
§Example
use rag_plusplus_core::trajectory::{DualRing, DualRingNode};
// Create nodes with temporal order and influence weights
let nodes = vec![
DualRingNode::new(0, "episode_a", 0.8), // temporal_idx=0, influence=0.8
DualRingNode::new(1, "episode_b", 0.3), // temporal_idx=1, influence=0.3
DualRingNode::new(2, "episode_c", 0.9), // temporal_idx=2, influence=0.9
DualRingNode::new(3, "episode_d", 0.5), // temporal_idx=3, influence=0.5
];
let dual = DualRing::new(nodes);
// Traverse temporally (RCP direction)
let temporal_order: Vec<_> = dual.iter_temporal().map(|n| n.value).collect();
// ["episode_a", "episode_b", "episode_c", "episode_d"]
// Traverse by influence (IRCP direction)
let influence_order: Vec<_> = dual.iter_by_influence().map(|n| n.value).collect();
// ["episode_c", "episode_a", "episode_d", "episode_b"] (by descending influence)Implementations§
Source§impl<T> DualRing<T>
impl<T> DualRing<T>
Sourcepub fn new(nodes: Vec<DualRingNode<T>>) -> Self
pub fn new(nodes: Vec<DualRingNode<T>>) -> Self
Create a dual ring from nodes.
Nodes should be provided in temporal order.
Sourcepub fn get_temporal(&self, idx: usize) -> &DualRingNode<T>
pub fn get_temporal(&self, idx: usize) -> &DualRingNode<T>
Get node by temporal index (wrapping).
Sourcepub fn temporal_next(&self, idx: usize) -> usize
pub fn temporal_next(&self, idx: usize) -> usize
Next in temporal order.
Sourcepub fn temporal_prev(&self, idx: usize) -> usize
pub fn temporal_prev(&self, idx: usize) -> usize
Previous in temporal order.
Sourcepub fn temporal_distance(&self, a: usize, b: usize) -> usize
pub fn temporal_distance(&self, a: usize, b: usize) -> usize
Temporal ring distance.
Sourcepub fn iter_temporal(&self) -> impl Iterator<Item = &DualRingNode<T>>
pub fn iter_temporal(&self) -> impl Iterator<Item = &DualRingNode<T>>
Iterate in temporal order (RCP direction).
Sourcepub fn iter_temporal_from(
&self,
start: usize,
) -> impl Iterator<Item = &DualRingNode<T>>
pub fn iter_temporal_from( &self, start: usize, ) -> impl Iterator<Item = &DualRingNode<T>>
Iterate temporally from a starting point.
Sourcepub fn temporal_neighbors(
&self,
idx: usize,
radius: usize,
) -> impl Iterator<Item = &DualRingNode<T>>
pub fn temporal_neighbors( &self, idx: usize, radius: usize, ) -> impl Iterator<Item = &DualRingNode<T>>
Get temporal neighbors within radius.
Sourcepub fn get_by_influence_rank(&self, rank: usize) -> &DualRingNode<T>
pub fn get_by_influence_rank(&self, rank: usize) -> &DualRingNode<T>
Get node by influence rank (0 = highest influence).
Sourcepub fn influence_rank_of(&self, temporal_idx: usize) -> usize
pub fn influence_rank_of(&self, temporal_idx: usize) -> usize
Get influence rank of a temporal index.
Sourcepub fn iter_by_influence(&self) -> impl Iterator<Item = &DualRingNode<T>>
pub fn iter_by_influence(&self) -> impl Iterator<Item = &DualRingNode<T>>
Iterate by influence (IRCP direction, highest first).
Sourcepub fn top_influential(
&self,
k: usize,
) -> impl Iterator<Item = &DualRingNode<T>>
pub fn top_influential( &self, k: usize, ) -> impl Iterator<Item = &DualRingNode<T>>
Get top-k most influential nodes.
Sourcepub fn influence_distance(&self, a_temporal: usize, b_temporal: usize) -> usize
pub fn influence_distance(&self, a_temporal: usize, b_temporal: usize) -> usize
Influence ring distance (distance in influence-sorted order).
Sourcepub fn influence_neighbors(
&self,
temporal_idx: usize,
radius: usize,
) -> impl Iterator<Item = &DualRingNode<T>>
pub fn influence_neighbors( &self, temporal_idx: usize, radius: usize, ) -> impl Iterator<Item = &DualRingNode<T>>
Get influence neighbors (nodes with similar influence).
Sourcepub fn influence_temporal_spread(&self) -> f32
pub fn influence_temporal_spread(&self) -> f32
Find the temporal distance from high-influence to low-influence nodes.
This measures how “spread out” influence is temporally. Low values mean influence clusters in time; high values mean it’s distributed.
Sourcepub fn forward_attention_flow(&self) -> f32
pub fn forward_attention_flow(&self) -> f32
Compute attention flow from earlier to later nodes (RCP forward flow).
Returns total influence flowing from past to future.
Sourcepub fn inverse_attention_flow(&self) -> f32
pub fn inverse_attention_flow(&self) -> f32
Compute attention flow from later to earlier nodes (IRCP inverse flow).
Returns total influence flowing from future to past (attribution).
Sourcepub fn update_influence(&mut self, temporal_idx: usize, new_influence: f32)
pub fn update_influence(&mut self, temporal_idx: usize, new_influence: f32)
Update influence weight for a node.
Sourcepub fn as_slice(&self) -> &[DualRingNode<T>]
pub fn as_slice(&self) -> &[DualRingNode<T>]
Get underlying nodes.
Trait Implementations§
Auto Trait Implementations§
impl<T> Freeze for DualRing<T>
impl<T> RefUnwindSafe for DualRing<T>where
T: RefUnwindSafe,
impl<T> Send for DualRing<T>where
T: Send,
impl<T> Sync for DualRing<T>where
T: Sync,
impl<T> Unpin for DualRing<T>where
T: Unpin,
impl<T> UnwindSafe for DualRing<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<F, W, T, D> Deserialize<With<T, W>, D> for F
impl<F, W, T, D> Deserialize<With<T, W>, D> for F
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more