or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compiled-expressions.mdexpression-analysis.mdexpression-evaluation.mdindex.mdthreading-performance.mdvml-integration.md

expression-evaluation.mddocs/

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.