tachyon_math_library/functions/
exp.rs1use crate::{FunctionData, FunctionDataAccessors, FunctionLogic, FunctionType, Interpolation, ValueCode, LOAD_ERROR_TOLERANCE};
2use anchor_lang::prelude::*;
3
4use num_traits::Inv;
5use rust_decimal::{Decimal, MathematicalOps};
6
7use crate::error::ErrorCode;
8
9pub struct Exp {}
10
11impl FunctionLogic for Exp {
12 const FUNCTION_TYPE: FunctionType = FunctionType::Exp;
13
14 fn validate_load(x_in: Decimal, y_in: Decimal) -> Result<(Decimal, ValueCode)> {
15 let diff = Self::proportion_difference(x_in, y_in.ln())?;
19
20 if diff > LOAD_ERROR_TOLERANCE {
21 return err!(ErrorCode::InvalidValue);
22 }
23
24 Ok((y_in, ValueCode::Valid))
25 }
26
27 fn eval(fd: &FunctionData, x_in: Decimal, interp: Interpolation, saturating: bool) -> Result<Decimal> {
28 let mut x = x_in;
29
30 let is_negative = x.is_sign_negative();
32 if is_negative {
33 x.set_sign_positive(true);
34 }
35
36 let domain_end = fd.get_domain_end()?;
38
39 if x > domain_end {
41 if saturating {
42 x = domain_end;
43 } else {
44 return err!(ErrorCode::OutOfDomainBounds);
45 }
46 }
47
48 let mut y = Self::interpolate(fd, x, interp)?;
49
50 if is_negative {
52 y = y.inv();
53 }
54
55 Ok(y)
56 }
57}