1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//! # lieval
//!
//! `lieval` is a lightweight Rust crate for parsing and evaluating mathematical expressions from strings.
//!
//! ## Features
//!
//! - Parse and evaluate simple mathematical expressions.
//! - Basic arithmetic operations: `+`, `-`, `*`, `/`, `%`
//! - Parentheses for expression grouping
//! - Common mathematical functions: `sin`, `cos`, `atan`, `cosh`, `pow`, `sqrt`, `hypot`, `exp`, `ln`, `div_euclid`, `floor` etc...
//! - mathematical constants such as `PI`, `TAU`, and `E`.
//! - Support for variables, operators, and functions.
//! - Minimal dependencies.
//! - Provides a simple and easy-to-use API.
//!
//! ## Usage
//!
//! Add the `lieval` crate to your `Cargo.toml` file:
//!
//! ```toml
//! [dependencies]
//! lieval = "<version>"
//! ```
//!
//! Then, in your Rust code:
//!
//! ```rust
//! use lieval::*;
//!
//! assert_eq!(eval_from_str("1.0 + 2 * (3 - 1)").unwrap(), vec![5.0]);
//! assert_eq!(eval_from_str(&format!("1.0 + 2 * ({} - 1)", 3)).unwrap(), vec![5.0]);
//! assert_eq!(
//! eval_from_str("1.0 - sin(3.14 / 2) * powf(1.5, 2.5)").unwrap(),
//! vec![1.0 - (3.14f64 / 2.0).sin() * 1.5f64.powf(2.5)]
//! );
//!
//! let mut expr = Expr::new("sqrt(4)").unwrap();
//! assert_eq!(expr.eval().unwrap(), 2.0);
//!
//! // using macro `ex!`
//! assert_eq!(ex!("sqrt(4)").eval().unwrap(), 2.0);
//! ```
//!
//! You can assign numerical values to variables and evaluate them using `Context`.
//!
//! ```rust
//! # use lieval::*;
//! #
//! let mut context = Context::new();
//!
//! assert_eq!(
//! eval_from_str_with_context("1 / x", context.set_value("x", 2.0)).unwrap(),
//! vec![0.5]
//! );
//! assert_eq!(
//! context.eval("1 / x").unwrap(),
//! 0.5
//! );
//!
//! assert_eq!(ex!("sqrt(2+x)").set_var("x", 2.0).eval().unwrap(), 2.0);
//! assert_eq!(ex!("sqrt(2+x+y)").set_var("x", 2.0).set_var("y", 5.0).eval().unwrap(), 3.0);
//! ```
//!
//! You can use custom functions.
//!
//! ```rust
//! # use lieval::*;
//! #
//! let mut context = Context::new();
//!
//! assert_eq!(
//! eval_from_str_with_context("1 + func(2,3)", context.set_func("func", 2, |x| x[0] + x[1])).unwrap(),
//! vec![6.0]
//! );
//! assert_eq!(
//! context.eval("1 + func(2,3)").unwrap(),
//! 6.0
//! );
//! ```
//!
//! You can evaluate multiple expressions separated by commas or semicolons.
//!
//! ```rust
//! # use lieval::*;
//! #
//!
//! assert_eq!(
//! eval_from_str("1 + 2, sin(3 + 0.14); 7 % 3").unwrap(),
//! vec![3.0, (3.14f64).sin(), 7.0 % 3.0]
//! );
//!
//! let mut context = Context::new();
//! context.set_value("x", 3.0);
//! assert_eq!(context.evals("sqrt(1+x); 1+3, hypot(x,4)").unwrap(), vec![2.0, 4.0, 5.0]);
//!
//! let mut expr = ex!("sqrt(1+x); 1+3, hypot(x,4)");
//! assert_eq!(expr.set_var("x", 3.0).evals().unwrap(), vec![2.0, 4.0, 5.0]);
//! assert_eq!(expr.eval().unwrap(), 2.0);
//! assert_eq!(expr.eval_index(2).unwrap(), 5.0);
//! ```
//!
//! You can efficiently evaluate by precomputing using `partial_eval`.
//!
//! ```rust
//! # use lieval::*;
//! #
//! let mut expr = ex!("a1 + a2 * sin(x)");
//! expr.set_var("a1", 1.0)
//! .set_var("a2", 0.5)
//! .partial_eval()
//! .unwrap();
//! let mut x = 1.0;
//! for _ in 0..10 {
//! x = expr.set_var("x", x).eval().unwrap();
//! assert_eq!(expr.set_var("x", x).eval().unwrap(), 1.0 + 0.5 * x.sin());
//! }
//! ```
//!
//! You can perform arithmetic operations between Expr objects.
//!
//! ```rust
//! # use lieval::*;
//! #
//! let expr1 = Expr::new("1+x").unwrap();
//! assert_eq!((expr1 + ex!("2*x")).set_var("x", 2.0).eval().unwrap(), 7.0);
//! assert_eq!((ex!("1+x, 2+x, 3+x") + ex!("2*x, 3*x, 4*x")).set_var("x", 2.0).evals().unwrap(), vec![7.0, 10.0, 13.0]);
//!
//! // broadcasting
//! let expr1 = Expr::new("1+x").unwrap();
//! let expr2 = Expr::new("2*x, 3*x, 4*x").unwrap();
//! assert_eq!((ex!("1+x") * ex!("2*x, 3*x, 4*x")).set_var("x", 2.0).evals().unwrap(), vec![12.0, 18.0, 24.0]);
//! assert_eq!((ex!("1+x") * 2.0 * ex!("x") + ex!("2*x, 3*x, 4*x") + 1.0).set_var("x", 2.0).evals().unwrap(), vec![17.0, 19.0, 21.0]);
//!
//! // If variables conflict, the variable in the left expression takes precedence,
//! // so use partial_eval beforehand.
//! let mut expr1 = Expr::new("2*x").unwrap();
//! expr1.set_var("x", 3.0).partial_eval().unwrap();
//! assert_eq!((-ex!("1+x") * expr1).set_var("x", 2.0).eval().unwrap(), -18.0);
//! ```
//!
//! ## API Documentation
//!
//! Detailed API documentation can be found [here](https://docs.rs/lieval).
//!
//! ## License
//!
//! This project is licensed under the MIT license.
pub use crate::;