IndexedResolver

Struct IndexedResolver 

Source
pub struct IndexedResolver<S: ResolverState, T> { /* private fields */ }
Expand description

High-performance resolver with O(1) lookup for variables and functions.

IndexedResolver is designed for cases where the number of variables is large and the variable naming follows a strict convention: a single English letter followed by a numeric index (e.g., "a0", "b1"). The letter represents the variable identifier and the number its index in the internal storage.

This resolver significantly outperforms other resolvers due to its flat vector-of-vectors storage. The trade-off is the restricted naming convention.

§Advantages

  • High performance due to indexed lookup.
  • Unlimited storage capacity.

§Disadvantages

  • Limited naming convention.

§Panics

The resolve() method will panic if:

  • The variable name does not follow the expected "letter + number" format.
  • The letter or index is out of bounds of the internal storage.

§Examples

use fee::prelude::*;
use fee::{EmptyResolver, IndexedResolver};

let y0_expr = "y0 * (p0 - p1*y1)";
let y1_expr = "-y1 * (p2 - p3*y0)";

let mut var_resolver = IndexedResolver::new();
var_resolver.add_id('y', 2);
var_resolver.set('y', 0, 1.0);
var_resolver.set('y', 1, 2.0);
var_resolver.add_id('p', 4);
var_resolver.set('p', 0, 1.0);
var_resolver.set('p', 1, 0.0);
var_resolver.set('p', 2, 1.0);
var_resolver.set('p', 3, 0.0);

let context = Context::new(var_resolver, EmptyResolver::new());
let mut stack = Vec::new();

let y0_expr = Expr::compile(y0_expr, &context).unwrap();
let y1_expr = Expr::compile(y1_expr, &context).unwrap();

assert_eq!(y0_expr.eval(&context, &mut stack), Ok(1.0));
assert_eq!(y1_expr.eval(&context, &mut stack), Ok(-2.0));

Implementations§

Source§

impl<S, T> IndexedResolver<S, T>
where S: ResolverState,

Source

pub fn set(&mut self, id: char, index: usize, value: T)

Source§

impl<T: Default + Clone> IndexedResolver<Unlocked, T>

Source

pub fn new() -> Self

Source

pub fn add_id(&mut self, id: char, len: usize)

Trait Implementations§

Source§

impl<'e, 'c, F, LF> ExprCompiler<'e, 'c, Unlocked, IndexedResolver<Unlocked, f64>, F, IndexedResolver<Locked, f64>, LF, IVRpn<'e>> for Expr<IVRpn<'e>>
where F: NotIndexedResolver + UnlockedResolver<ExprFn, LF>, LF: LockedResolver<ExprFn>,

Source§

fn compile( expr: &'e str, ctx: &'c UContext<IndexedResolver<Unlocked, f64>, F, IndexedResolver<Locked, f64>, LF>, ) -> Result<Expr<IVRpn<'e>>, Error<'e>>

Source§

impl<'e, 'c> ExprCompiler<'e, 'c, Unlocked, IndexedResolver<Unlocked, f64>, IndexedResolver<Unlocked, ExprFn>, IndexedResolver<Locked, f64>, IndexedResolver<Locked, ExprFn>, IRpn> for Expr<IRpn>

Source§

impl<'e, 'c, V, LV> ExprCompiler<'e, 'c, Unlocked, V, IndexedResolver<Unlocked, ExprFn>, LV, IndexedResolver<Locked, ExprFn>, IFRpn<'e>> for Expr<IFRpn<'e>>
where V: NotIndexedResolver + UnlockedResolver<f64, LV>, LV: LockedResolver<f64>,

Source§

impl<'e, F, LF> ExprEvaluator<'e, Unlocked, IndexedResolver<Unlocked, f64>, F, IndexedResolver<Locked, f64>, LF> for Expr<IVRpn<'e>>
where F: NotIndexedResolver + UnlockedResolver<ExprFn, LF>, LF: LockedResolver<ExprFn>,

Source§

fn eval( &self, ctx: &UContext<IndexedResolver<Unlocked, f64>, F, IndexedResolver<Locked, f64>, LF>, stack: &mut Vec<f64>, ) -> Result<f64, Error<'e>>

Source§

impl<'e> ExprEvaluator<'e, Unlocked, IndexedResolver<Unlocked, f64>, IndexedResolver<Unlocked, ExprFn>, IndexedResolver<Locked, f64>, IndexedResolver<Locked, ExprFn>> for Expr<IRpn>

Source§

impl<'e, V, LV> ExprEvaluator<'e, Unlocked, V, IndexedResolver<Unlocked, ExprFn>, LV, IndexedResolver<Locked, ExprFn>> for Expr<IFRpn<'e>>
where V: NotIndexedResolver + UnlockedResolver<f64, LV>, LV: LockedResolver<f64>,

Source§

fn eval( &self, ctx: &UContext<V, IndexedResolver<Unlocked, ExprFn>, LV, IndexedResolver<Locked, ExprFn>>, stack: &mut Vec<f64>, ) -> Result<f64, Error<'e>>

Source§

impl<S, T> Resolver<S, T> for IndexedResolver<S, T>
where S: ResolverState,

Source§

fn resolve(&self, name: &str) -> Option<&T>

Auto Trait Implementations§

§

impl<S, T> Freeze for IndexedResolver<S, T>
where S: Freeze,

§

impl<S, T> RefUnwindSafe for IndexedResolver<S, T>

§

impl<S, T> Send for IndexedResolver<S, T>
where S: Send, T: Send,

§

impl<S, T> Sync for IndexedResolver<S, T>
where S: Sync, T: Sync,

§

impl<S, T> Unpin for IndexedResolver<S, T>
where S: Unpin, T: Unpin,

§

impl<S, T> UnwindSafe for IndexedResolver<S, T>
where S: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.