0
# Expression Evaluation
1
2
Core functionality for evaluating mathematical expressions on NumPy arrays with performance optimization and multi-threading support. This module provides the primary interface for NumExpr's fast expression evaluation capabilities.
3
4
## Capabilities
5
6
### Primary Expression Evaluation
7
8
Evaluates mathematical expressions on arrays, providing substantial performance improvements over NumPy operations through optimized compilation and execution.
9
10
```python { .api }
11
def evaluate(ex, local_dict=None, global_dict=None, out=None, order='K', casting='safe', **kwargs):
12
"""
13
Evaluate a mathematical expression on arrays.
14
15
This is the primary function for NumExpr evaluation, parsing and executing
16
mathematical expressions on NumPy arrays with automatic optimization and
17
multi-threading.
18
19
Parameters:
20
- ex (str): Mathematical expression string to evaluate
21
- local_dict (dict, optional): Dictionary mapping variable names to arrays/values
22
- global_dict (dict, optional): Global namespace for variable lookup
23
- out (ndarray, optional): Pre-allocated output array for result storage
24
- order (str): Memory layout order - 'K' (keep), 'A' (any), 'C' (C-order), 'F' (Fortran)
25
- casting (str): Casting safety level - 'no', 'equiv', 'safe', 'same_kind', 'unsafe'
26
- **kwargs: Additional keyword arguments for variable substitution
27
28
Returns:
29
ndarray: Result array from expression evaluation
30
31
Raises:
32
ValueError: If expression is invalid or variables are incompatible
33
TypeError: If array types cannot be safely cast
34
"""
35
```
36
37
**Usage Examples:**
38
39
```python
40
import numpy as np
41
import numexpr as ne
42
43
# Basic arithmetic with implicit variable lookup
44
a = np.arange(1000000)
45
b = np.arange(1000000)
46
result = ne.evaluate("a + b * 2")
47
48
# Complex mathematical expressions
49
result = ne.evaluate("sin(a) * exp(-b/1000) + sqrt(a*b)")
50
51
# With explicit variable dictionary
52
data = {'x': np.random.random(10000), 'y': np.random.random(10000)}
53
result = ne.evaluate("x**2 + y**2 < 1", local_dict=data)
54
55
# Using pre-allocated output array
56
out = np.empty(len(a))
57
ne.evaluate("a * 3.14159", out=out)
58
59
# With casting control
60
result = ne.evaluate("a + 1.5", casting='safe') # Ensures safe type conversion
61
```
62
63
### Expression Re-evaluation
64
65
Re-evaluates the most recently compiled expression with new variable values, providing optimal performance for repeated evaluation patterns.
66
67
```python { .api }
68
def re_evaluate(local_dict=None, **kwargs):
69
"""
70
Re-evaluate the previous expression with new variable values.
71
72
This function reuses the compiled representation of the last expression
73
evaluated with evaluate(), providing optimal performance when the same
74
expression needs to be computed with different data.
75
76
Parameters:
77
- local_dict (dict, optional): New local variable bindings
78
- **kwargs: New variable values as keyword arguments
79
80
Returns:
81
ndarray: Result of re-evaluation with new variables
82
83
Raises:
84
RuntimeError: If no previous expression exists to re-evaluate
85
ValueError: If new variables are incompatible with compiled expression
86
"""
87
```
88
89
**Usage Examples:**
90
91
```python
92
# Initial evaluation compiles the expression
93
a1 = np.arange(1000)
94
b1 = np.arange(1000)
95
result1 = ne.evaluate("a * b + 100")
96
97
# Re-evaluate with new data - much faster since expression is pre-compiled
98
a2 = np.arange(1000, 2000)
99
b2 = np.arange(2000, 3000)
100
result2 = ne.re_evaluate(local_dict={'a': a2, 'b': b2})
101
102
# Using keyword arguments
103
result3 = ne.re_evaluate(a=a2*2, b=b2*3)
104
```
105
106
107
## Expression Language Features
108
109
### Supported Operations
110
111
**Arithmetic**: `+`, `-`, `*`, `/`, `%`, `**`
112
- Full NumPy broadcasting support
113
- Automatic type promotion following NumPy rules
114
- Integer division follows Python 3 semantics
115
116
**Comparison**: `==`, `!=`, `<`, `<=`, `>`, `>=`
117
- Element-wise comparison returning boolean arrays
118
- String comparison supported for string arrays
119
120
**Logical**: `&` (and), `|` (or), `~` (not)
121
- Bitwise operations on integer types
122
- Logical operations on boolean arrays
123
124
### Mathematical Functions
125
126
**Trigonometric**: `sin`, `cos`, `tan`, `arcsin`, `arccos`, `arctan`, `sinh`, `cosh`, `tanh`, `arcsinh`, `arccosh`, `arctanh`
127
128
**Exponential/Logarithmic**: `exp`, `expm1`, `log`, `log1p`, `log10`
129
130
**Power and Roots**: `sqrt`, `pow` (same as `**`)
131
132
**Rounding**: `ceil`, `floor`
133
134
**Other**: `abs`/`absolute`, `arctan2(y, x)`, `fmod(x, y)`
135
136
**Complex Numbers**: `real`, `imag`, `complex(real, imag)`, `conjugate`
137
138
### Data Types
139
140
- **bool**: Boolean values (True/False)
141
- **int**: 32-bit signed integers
142
- **long**: 64-bit signed integers
143
- **float**: 32-bit floating point
144
- **double**: 64-bit floating point (default for literals)
145
- **complex**: Complex numbers
146
- **str**: String types for comparison operations
147
148
### Performance Characteristics
149
150
- **Optimal Array Size**: Arrays too large for L1 cache (typically > 10KB)
151
- **Speed Improvements**: 0.95x to 15x faster than pure NumPy
152
- **Memory Usage**: Significantly reduced due to elimination of intermediate arrays
153
- **Threading**: Automatic parallelization across available CPU cores
154
- **Cache Utilization**: Optimized through intelligent data chunking
155
156
### Variable Scope Resolution
157
158
1. **kwargs parameters** (highest priority)
159
2. **local_dict** dictionary
160
3. **Calling frame locals** (automatic inspection)
161
4. **global_dict** dictionary
162
5. **Calling frame globals** (lowest priority)
163
164
This allows natural variable usage without explicit dictionary passing in most cases.