latex2code 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- latex2code-0.2.0/LICENSE +19 -0
- latex2code-0.2.0/PKG-INFO +481 -0
- latex2code-0.2.0/README.md +443 -0
- latex2code-0.2.0/pyproject.toml +79 -0
- latex2code-0.2.0/setup.cfg +4 -0
- latex2code-0.2.0/src/latex2code/__init__.py +38 -0
- latex2code-0.2.0/src/latex2code/__main__.py +4 -0
- latex2code-0.2.0/src/latex2code/api.py +461 -0
- latex2code-0.2.0/src/latex2code/backends.py +88 -0
- latex2code-0.2.0/src/latex2code/cli.py +230 -0
- latex2code-0.2.0/src/latex2code/core.py +35 -0
- latex2code-0.2.0/src/latex2code/errors.py +210 -0
- latex2code-0.2.0/src/latex2code/normalize.py +207 -0
- latex2code-0.2.0/src/latex2code/parsing.py +597 -0
- latex2code-0.2.0/src/latex2code/printers.py +205 -0
- latex2code-0.2.0/src/latex2code/py.typed +0 -0
- latex2code-0.2.0/src/latex2code.egg-info/PKG-INFO +481 -0
- latex2code-0.2.0/src/latex2code.egg-info/SOURCES.txt +21 -0
- latex2code-0.2.0/src/latex2code.egg-info/dependency_links.txt +1 -0
- latex2code-0.2.0/src/latex2code.egg-info/entry_points.txt +2 -0
- latex2code-0.2.0/src/latex2code.egg-info/requires.txt +18 -0
- latex2code-0.2.0/src/latex2code.egg-info/top_level.txt +1 -0
- latex2code-0.2.0/tests/test_core.py +1513 -0
latex2code-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Thúlio Brandão <https://github.com/ThulioASB>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO MECHANICAL FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
18
|
+
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY FROM, OUT OF OR IN CONNECTION WITH
|
|
19
|
+
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: latex2code
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A lightweight Python library and CLI tool to transpile LaTeX mathematical expressions into executable Python functions.
|
|
5
|
+
Author: Thúlio Brandão
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ThulioASB/latex2code
|
|
8
|
+
Project-URL: Repository, https://github.com/ThulioASB/latex2code
|
|
9
|
+
Project-URL: Issues, https://github.com/ThulioASB/latex2code/issues
|
|
10
|
+
Keywords: latex,sympy,python,transpile,mathematics,numpy
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
18
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: sympy>=1.12
|
|
23
|
+
Requires-Dist: antlr4-python3-runtime==4.11.0
|
|
24
|
+
Requires-Dist: numpy>=1.24.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: black>=24.0; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: hypothesis>=6.0.0; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff>=0.6.0; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy>=1.11.0; extra == "dev"
|
|
32
|
+
Requires-Dist: build>=1.2.0; extra == "dev"
|
|
33
|
+
Provides-Extra: torch
|
|
34
|
+
Requires-Dist: torch>=2.0; extra == "torch"
|
|
35
|
+
Provides-Extra: jax
|
|
36
|
+
Requires-Dist: jax>=0.4; extra == "jax"
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
# latex2code 🧮 ➡️ 🐍
|
|
40
|
+
|
|
41
|
+
[](https://www.python.org/)
|
|
42
|
+
[](https://opensource.org/licenses/MIT)
|
|
43
|
+
[](https://github.com/psf/black)
|
|
44
|
+
|
|
45
|
+
A lightweight Python library and CLI tool that transpiles a supported subset of LaTeX mathematical expressions into Python functions.
|
|
46
|
+
|
|
47
|
+
Designed for scientific computing, machine learning researchers, and engineers who want to bridge the gap between academic papers and executable code.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Features
|
|
52
|
+
|
|
53
|
+
- 📐 **Common Math:** Translates arithmetic, fractions, powers, roots, limits, binomial coefficients, and common functions such as `\sin`, `\cos`, `\tan`, `\exp`, `\log`, `\operatorname{erf}`, `\max`, and hyperbolic functions.
|
|
54
|
+
- 🔢 **Greek Symbols & Constants:** Common Greek-letter commands become variables; `\pi` and `e` are numeric constants.
|
|
55
|
+
- 🔁 **Matrix & Array Support:** Converts LaTeX matrix environments (`\begin{pmatrix}`, `\begin{bmatrix}`, `\begin{matrix}`) and tabular/array layouts like `\begin{array}{cc} ... \end{array}` into `numpy.ndarray` objects.
|
|
56
|
+
- 🧩 **Piecewise Expressions:** Recognizes `\begin{cases} ... \end{cases}` and emits Python conditional expressions.
|
|
57
|
+
- 🔒 **Absolute Values & Floor/Ceiling:** Handles common wrappers like `\left|x\right|`, `\left\lfloor x \right\rfloor`, and `\left\lceil x \right\rceil`.
|
|
58
|
+
- 🧮 **Symbolic Operations:** Uses SymPy to evaluate supported derivatives, limits, integrals, finite products, and nth roots; finite sums are emitted as executable Python.
|
|
59
|
+
- 📐 **Extended Trig & Inverse Functions:** Supports reciprocal and inverse trig functions such as `\csc`, `\arccot`, `\arcsec`, and `\arccsc`.
|
|
60
|
+
- 🤖 **Machine-Learning Functions:** Supports `\operatorname{sigmoid}(x)`, `\operatorname{relu}(x)`, `\operatorname{softplus}(x)`, `\operatorname{logit}(x)`, `\operatorname{softsign}(x)`, and `\operatorname{swish}(x)` in scalar, NumPy, PyTorch, and JAX modes.
|
|
61
|
+
- 🏷️ **Type Annotations:** Automatically generates functions with PEP 484 type hints.
|
|
62
|
+
- 🔍 **Inspection Reports:** Shows the parsed symbolic expression, variables, warnings, and generated Python source.
|
|
63
|
+
- 💻 **Command Line Interface:** Transpiles formulas directly from your terminal and accepts input from stdin.
|
|
64
|
+
|
|
65
|
+
This is a focused expression transpiler, not a complete LaTeX implementation or a computer algebra system.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Installation
|
|
70
|
+
|
|
71
|
+
Clone the repository and install in editable mode:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
git clone https://github.com/ThulioASB/latex2code.git
|
|
75
|
+
cd latex2code
|
|
76
|
+
python -m venv venv
|
|
77
|
+
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
78
|
+
pip install -e .
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Install an optional differentiable backend with one of the extras:
|
|
83
|
+
|
|
84
|
+
```powershell
|
|
85
|
+
pip install -e ".[torch]"
|
|
86
|
+
pip install -e ".[jax]"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Usage
|
|
92
|
+
|
|
93
|
+
### As a Python Library
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from latex2code import transpile_latex
|
|
97
|
+
|
|
98
|
+
# Transpile a fraction with trigonometric functions
|
|
99
|
+
code = transpile_latex(r"\frac{\sin(x) + \cos(y)}{\sqrt{z}}", function_name="calculate_wave")
|
|
100
|
+
print(code)
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Output:**
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
import math
|
|
108
|
+
|
|
109
|
+
def calculate_wave(x: float, y: float, z: float) -> float:
|
|
110
|
+
return (math.sin(x) + math.cos(y))/math.sqrt(z)
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
For direct evaluation in a notebook or application, use `compile_latex`. The returned object is
|
|
115
|
+
callable and retains the generated source and inspection details:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
import numpy as np
|
|
119
|
+
from latex2code import compile_latex
|
|
120
|
+
|
|
121
|
+
formula = compile_latex(
|
|
122
|
+
r"\frac{\sin(x)}{\sqrt{x^2 + 1}}",
|
|
123
|
+
backend="numpy",
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
x = np.linspace(0, 10, 100)
|
|
127
|
+
result = formula(x)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The convenience helper `latex_to_code` accepts the same keyword-only generation options as the
|
|
131
|
+
main transpiler. Use `variable_map` to rename parsed symbols:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from latex2code import latex_to_code
|
|
135
|
+
|
|
136
|
+
code = latex_to_code(
|
|
137
|
+
r"\theta + \lambda",
|
|
138
|
+
function_name="signal_model",
|
|
139
|
+
type_hints=False,
|
|
140
|
+
variable_map={"lambda": "lambda_value"},
|
|
141
|
+
)
|
|
142
|
+
print(code)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The legacy `custom_symbol_map` and `use_numpy` Python arguments are deprecated. Use
|
|
146
|
+
`variable_map` and `backend="numpy"` instead.
|
|
147
|
+
|
|
148
|
+
Choose a backend just as with `transpile_latex`; optional frameworks must be installed when
|
|
149
|
+
compiling a formula for that backend. The callable uses only the arguments supplied by the caller
|
|
150
|
+
and does not automatically move or cast array/tensor inputs.
|
|
151
|
+
|
|
152
|
+
### Constants and Greek Variables
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
from latex2code import transpile_latex
|
|
156
|
+
|
|
157
|
+
code = transpile_latex(r"\sin(\pi x) + e + \theta", function_name="signal_response")
|
|
158
|
+
print(code)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Standard constants `\pi` and `e` are emitted as numeric constants by default. Other Greek-letter
|
|
162
|
+
symbols such as `\theta` remain variables and appear in the generated function signature. Pass a
|
|
163
|
+
`constants` mapping to customize substitutions; for example, `constants={"pi": math.pi}` leaves
|
|
164
|
+
`e` as a function argument. Use `args=["x", "w", "b"]` to explicitly set argument order; the
|
|
165
|
+
default follows each variable's first appearance in the input.
|
|
166
|
+
|
|
167
|
+
Text wrappers preserve their contents: `\mathrm{e}^x` retains the `e`, and `\text{...}` is not
|
|
168
|
+
removed as if it were whitespace.
|
|
169
|
+
|
|
170
|
+
### Inspecting a Transpilation
|
|
171
|
+
|
|
172
|
+
Use the inspection API to check how an expression was interpreted before using its generated source:
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from latex2code import inspect_latex
|
|
176
|
+
|
|
177
|
+
details = inspect_latex(r"\sin(\pi x) + \theta")
|
|
178
|
+
print(details.input_expression)
|
|
179
|
+
print(details.backend)
|
|
180
|
+
print(details.parsed_expression)
|
|
181
|
+
print(details.expression_tree)
|
|
182
|
+
print(details.variables)
|
|
183
|
+
print(details.generated_code)
|
|
184
|
+
print(details.warnings)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
The CLI's `--inspect` option prints the same information as JSON. Parse and unsupported-feature
|
|
188
|
+
errors include a line and column with a short source excerpt when the location can be identified:
|
|
189
|
+
|
|
190
|
+
```powershell
|
|
191
|
+
latex2code "\sin(\pi x) + \theta" --inspect
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Use `variable_map` to give parsed symbols clearer Python argument names without changing the
|
|
195
|
+
mathematics. Keys are parsed symbol names, and values must be unique Python identifiers:
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from latex2code import compile_latex
|
|
199
|
+
|
|
200
|
+
model = compile_latex(
|
|
201
|
+
r"\theta + \lambda",
|
|
202
|
+
variable_map={"theta": "angle", "lambda": "wavelength"},
|
|
203
|
+
)
|
|
204
|
+
print(model(angle=0.5, wavelength=2.0))
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Inspection reports include `expression_tree`, a JSON-compatible tree of SymPy operations and
|
|
208
|
+
arguments, as well as the readable `parsed_expression` string.
|
|
209
|
+
|
|
210
|
+
### Matrix Transpilation
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
from latex2code import transpile_latex
|
|
214
|
+
|
|
215
|
+
latex_matrix = r"\begin{pmatrix} x^2 & 1 \\ 0 & y \end{pmatrix}"
|
|
216
|
+
code = transpile_latex(latex_matrix, function_name="create_matrix", type_hints=False)
|
|
217
|
+
print(code)
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Output:**
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
import numpy as np
|
|
225
|
+
|
|
226
|
+
def create_matrix(x, y):
|
|
227
|
+
return np.array([[x**2, 1], [0, y]])
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Piecewise Expressions
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
from latex2code import transpile_latex
|
|
235
|
+
|
|
236
|
+
code = transpile_latex(
|
|
237
|
+
r"\begin{cases} x & x > 0 \\ -x & x \le 0 \end{cases}",
|
|
238
|
+
function_name="abs_value",
|
|
239
|
+
type_hints=False,
|
|
240
|
+
)
|
|
241
|
+
print(code)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Output:**
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
def abs_value(x):
|
|
248
|
+
return (x) if (x > 0) else (-x)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Machine-Learning Activations
|
|
252
|
+
|
|
253
|
+
Common activation and link functions can be generated for scalar, NumPy, PyTorch, or JAX inputs:
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
from latex2code import transpile_latex
|
|
257
|
+
|
|
258
|
+
code = transpile_latex(
|
|
259
|
+
r"\operatorname{sigmoid}(x)",
|
|
260
|
+
function_name="logistic_probability",
|
|
261
|
+
backend="numpy",
|
|
262
|
+
)
|
|
263
|
+
print(code)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
The default `python` backend emits ordinary Python math. `backend="numpy"` supports NumPy arrays.
|
|
267
|
+
The optional `torch` and `jax` backends generate operations using framework primitives so tensor
|
|
268
|
+
autodiff can trace expressions; pass tensors/arrays of the chosen framework as inputs. These
|
|
269
|
+
backends do not imply that every supported LaTeX construct has equivalent batching or gradient
|
|
270
|
+
semantics. Named `sigmoid`, `softplus`, and `swish` operators use stable scalar or
|
|
271
|
+
framework-native implementations. Writing equivalent expanded formulas manually (such as
|
|
272
|
+
`log(1 + exp(x))`) is not guaranteed to receive this stabilization. Check input domains for
|
|
273
|
+
`logit`, logarithms, and roots; the transpiler does not silently clip inputs.
|
|
274
|
+
|
|
275
|
+
```python
|
|
276
|
+
torch_code = transpile_latex(r"\sin(x)^2 + x", backend="torch")
|
|
277
|
+
jax_code = transpile_latex(r"\sin(x)^2 + x", backend="jax")
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Using Generated Code in Training or Analysis
|
|
281
|
+
|
|
282
|
+
Choose tensor dtype/device and array shape in your application; generated functions preserve
|
|
283
|
+
framework operations and do not move or silently cast tensor inputs:
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
import torch
|
|
287
|
+
|
|
288
|
+
source = transpile_latex(r"\operatorname{softplus}(x) + x^2", backend="torch")
|
|
289
|
+
namespace = {}
|
|
290
|
+
exec(source, namespace)
|
|
291
|
+
formula = namespace["formula"]
|
|
292
|
+
|
|
293
|
+
x = torch.tensor([0.25, 1.0], dtype=torch.float64, device="cpu", requires_grad=True)
|
|
294
|
+
loss = formula(x).mean()
|
|
295
|
+
loss.backward()
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
For JAX, generated functions can be passed to `jax.jit`, `jax.vmap`, and `jax.grad` when the
|
|
299
|
+
expression uses supported JAX primitives. Test the actual shapes and dtypes used by your workload.
|
|
300
|
+
|
|
301
|
+
Piecewise functions use eager elementwise selection (`where`) for array/tensor inputs: both branch
|
|
302
|
+
expressions may be evaluated before selection. Avoid invalid operations in inactive branches (such
|
|
303
|
+
as taking `log(x)` in a branch where `x <= 0`); use a formula with valid branch expressions or
|
|
304
|
+
write a framework-specific implementation when true lazy control flow is required. Transpiling
|
|
305
|
+
piecewise expressions for NumPy, PyTorch, or JAX emits a `PiecewiseEvaluationWarning`. Automatic
|
|
306
|
+
domain clipping is intentionally not performed because it changes the formula and its gradients.
|
|
307
|
+
|
|
308
|
+
### Reproducible Scientific Example: Gaussian Density
|
|
309
|
+
|
|
310
|
+
This normal probability density uses `x`, `mu`, and `sigma` in the same units; its output has
|
|
311
|
+
inverse units. Require `sigma > 0`. At the mean, with `sigma = 2`, the density is
|
|
312
|
+
`1 / (2 sqrt(2 pi))`, approximately `0.19947114020071635`:
|
|
313
|
+
|
|
314
|
+
```python
|
|
315
|
+
from latex2code import compile_latex
|
|
316
|
+
|
|
317
|
+
density = compile_latex(
|
|
318
|
+
r"\frac{1}{\sigma \sqrt{2 \pi}}"
|
|
319
|
+
r"\exp(-\frac{(x-\mu)^2}{2 \sigma^2})"
|
|
320
|
+
)
|
|
321
|
+
value = density(x=0.0, mu=0.0, sigma=2.0)
|
|
322
|
+
print(value) # 0.19947114020071635
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
The expression does not enforce `sigma > 0`; validate model parameters in the calling
|
|
326
|
+
application. To evaluate arrays/tensors, select `backend="numpy"`, `"torch"`, or `"jax"` and
|
|
327
|
+
choose the input dtype to suit the calculation's precision requirements.
|
|
328
|
+
|
|
329
|
+
### Limits and Binomial Coefficients
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
from latex2code import transpile_latex
|
|
333
|
+
|
|
334
|
+
limit_code = transpile_latex(r"\lim_{x \to 0} \frac{\sin(x)}{x}", function_name="sinc_limit", type_hints=False)
|
|
335
|
+
print(limit_code)
|
|
336
|
+
|
|
337
|
+
binomial_code = transpile_latex(r"\binom{n}{k}", function_name="choose", type_hints=False)
|
|
338
|
+
print(binomial_code)
|
|
339
|
+
|
|
340
|
+
product_code = transpile_latex(r"\prod_{i=1}^{n} i", function_name="factorial_product", type_hints=False)
|
|
341
|
+
print(product_code)
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Output:**
|
|
345
|
+
|
|
346
|
+
```python
|
|
347
|
+
def sinc_limit():
|
|
348
|
+
return 1
|
|
349
|
+
|
|
350
|
+
import math
|
|
351
|
+
|
|
352
|
+
def choose(n, k):
|
|
353
|
+
return (math.gamma(n + 1)/(math.gamma(k + 1)*math.gamma(-k + n + 1)))
|
|
354
|
+
|
|
355
|
+
import math
|
|
356
|
+
|
|
357
|
+
def factorial_product(n):
|
|
358
|
+
return math.factorial(n)
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## CLI Usage
|
|
364
|
+
|
|
365
|
+
You can run `latex2code` directly from your command line:
|
|
366
|
+
|
|
367
|
+
```powershell
|
|
368
|
+
latex2code "\frac{a}{b}" --name divide
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
You can also pipe input from standard input:
|
|
372
|
+
|
|
373
|
+
```powershell
|
|
374
|
+
echo '\sin(x) + \cos(y)' | latex2code - --name signal
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Write the generated source directly to a Python file with `--output`:
|
|
378
|
+
|
|
379
|
+
```powershell
|
|
380
|
+
latex2code "\frac{a}{b}" --name divide --output divide.py
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Select an output backend with `--backend`:
|
|
384
|
+
|
|
385
|
+
```powershell
|
|
386
|
+
latex2code "\sin(x)^2 + x" --backend torch --output differentiable.py
|
|
387
|
+
latex2code "\sin(x)^2 + x" --backend jax --output differentiable.py
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Generated source for PyTorch/JAX imports the selected framework, so install that framework in the
|
|
391
|
+
environment where the generated file will run.
|
|
392
|
+
Use `--inspect` to print a JSON report with the parsed expression, function variables, warnings, and source.
|
|
393
|
+
Rename parsed symbols with repeatable `--map-variable SYMBOL=NAME` options:
|
|
394
|
+
|
|
395
|
+
```powershell
|
|
396
|
+
latex2code "\theta + x" --map-variable theta=angle
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
Start an interactive session to paste and transpile expressions. Use `--inspect` to show the
|
|
400
|
+
structured JSON report for each expression; `quit` or `exit` ends the session. For multiline
|
|
401
|
+
expressions, enter `:begin`, paste the expression, then enter `:end`:
|
|
402
|
+
|
|
403
|
+
```powershell
|
|
404
|
+
latex2code --interactive
|
|
405
|
+
latex2code --interactive --inspect --backend numpy
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Options
|
|
409
|
+
|
|
410
|
+
| Flag | Long Option | Description |
|
|
411
|
+
| --- | --- | --- |
|
|
412
|
+
| `-n` | `--name` | Name of the generated Python function (default: `formula`). |
|
|
413
|
+
| | `--no-types` | Disable type hints in the generated signature. |
|
|
414
|
+
| | `--backend` | Select `python`, `numpy`, `torch`, or `jax` output (default: `python`). |
|
|
415
|
+
| `-o` | `--output` | Write generated Python source to a file instead of stdout. |
|
|
416
|
+
| | `--inspect` | Print JSON containing the parsed expression, variables, warnings, and generated source. |
|
|
417
|
+
| | `--map-variable SYMBOL=NAME` | Rename a parsed variable; may be repeated. |
|
|
418
|
+
| `-i` | `--interactive` | Read and transpile expressions until `quit`, `exit`, or end-of-file. |
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Running Tests
|
|
423
|
+
|
|
424
|
+
Run the test suite using `pytest`:
|
|
425
|
+
|
|
426
|
+
```powershell
|
|
427
|
+
pytest
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
## Supported Scope and Limitations
|
|
431
|
+
|
|
432
|
+
- The table describes the supported shapes of input; it does not claim full TeX macro or document parsing.
|
|
433
|
+
|
|
434
|
+
| Area | Supported examples | Notes |
|
|
435
|
+
| --- | --- | --- |
|
|
436
|
+
| Arithmetic | `+`, `-`, products, fractions, powers, roots, nth roots | Parsed expressions follow SymPy's supported LaTeX grammar. |
|
|
437
|
+
| Functions | Trigonometric, inverse/reciprocal trig, hyperbolic, exponential/logarithmic, `erf`, `gamma`, `beta`, `max`, `min` | Function support can depend on backend printer support; beta is generated using log-gamma arithmetic. |
|
|
438
|
+
| ML operators | `sigmoid`, `relu`, `softplus`, `logit`, `softsign`, `swish` | Use `\operatorname{...}(x)`; sigmoid, softplus, and swish use stable scalar/framework-native implementations. |
|
|
439
|
+
| Symbolic calculus | Derivatives, limits, integrals, finite sums and reducible finite products | SymPy evaluates operations when possible; unresolved products fail rather than emitting incomplete code. |
|
|
440
|
+
| Arrays and cases | Matrix/array layouts, `cases`, selected aligned equation layouts | Aligned equations are represented as rows of values, not solved as systems. |
|
|
441
|
+
| Inspection and names | Parsed expression tree and variable-to-identifier mapping | Mappings rename arguments only; they do not substitute values or change expression semantics. |
|
|
442
|
+
|
|
443
|
+
Backend behavior below describes tested pathways, not a guarantee that every parser-supported
|
|
444
|
+
function has equivalent semantics across targets:
|
|
445
|
+
|
|
446
|
+
| Capability | Python | NumPy | PyTorch | JAX |
|
|
447
|
+
| --- | --- | --- | --- | --- |
|
|
448
|
+
| Scalar arithmetic and common functions | Yes | Yes | Yes, for generated native operations | Yes, for generated native operations |
|
|
449
|
+
| Elementwise arrays/tensors | No array contract | NumPy broadcasting | Pass tensors with desired dtype/device | Pass arrays with desired dtype |
|
|
450
|
+
| Matrix/array constructors | NumPy output for compatibility | NumPy arrays | Tensor output; gradients through dynamic entries | JAX arrays |
|
|
451
|
+
| Piecewise array evaluation | Python conditional expression | `where`, eager branches | `where`, eager branches | `where`, eager branches |
|
|
452
|
+
| Automatic differentiation | No | No | Yes, for differentiable native operations | Yes, for differentiable native operations |
|
|
453
|
+
| JIT compilation | No library guarantee | No library guarantee | No library guarantee | `jax.jit` tested for supported primitives |
|
|
454
|
+
|
|
455
|
+
PyTorch and JAX are optional runtime dependencies. Operations without a native differentiable
|
|
456
|
+
implementation are rejected rather than silently replaced with Python math. JAX commonly defaults
|
|
457
|
+
to 32-bit floating point; enable and verify 64-bit mode in the application when needed. Python and
|
|
458
|
+
NumPy error/gamma functions can use Python `math` implementations wrapped for arrays, which may be
|
|
459
|
+
slower than native array kernels.
|
|
460
|
+
|
|
461
|
+
- Input is parsed strictly by SymPy's ANTLR-based LaTeX parser plus a restricted safe fallback, so malformed trailing tokens are rejected rather than silently discarded. Document markup, arbitrary TeX macros, and arbitrary custom functions are outside scope.
|
|
462
|
+
- Presentation-only spacing commands such as `\quad`, `\qquad`, `\,`, `\hspace{...}`, and `\vspace{...}` are ignored. `\displaystyle` and related math-style commands are also ignored. Text wrappers and unknown macros are not stripped because they can carry mathematical meaning; remove or rewrite them explicitly if unsupported.
|
|
463
|
+
- Function application and implicit multiplication follow the parser's documented grammar; no assumptions are made about custom function names or subscript semantics. Inspect the parsed expression/tree and explicitly rename variables instead of relying on guessed intent.
|
|
464
|
+
- Unsupported commands and functions raise `UnsupportedLaTeXFeatureError`; close command/function spellings are suggested when possible. Malformed input raises `InvalidLaTeXSyntaxError`, which includes a source location and excerpt when identifiable, plus delimiter or environment hints when detected.
|
|
465
|
+
- For example, a misspelled `\sinn(x)` reports the likely `\sin` command, while a fraction with an unmatched brace points out the unbalanced delimiters.
|
|
466
|
+
- Piecewise cases without an explicit default remain undefined outside their listed conditions; generated Python returns `None` there, while NumPy mode represents those values as `numpy.nan`.
|
|
467
|
+
- `\pi` and `e` are numeric constants; other Greek symbols may become function parameters. Use `inspect_latex` or CLI `--inspect` to review parsed variables and generated code.
|
|
468
|
+
- Derivatives and integrals are evaluated symbolically when SymPy can do so. An indefinite integral returns one antiderivative and does not add the arbitrary constant of integration.
|
|
469
|
+
- Finite sums are emitted as executable Python sum expressions. Matrices use the selected array backend (Python's matrix output remains a NumPy array for compatibility).
|
|
470
|
+
- Finite products are symbolically evaluated when SymPy can reduce them; unresolved symbolic products raise `CodeGenerationError` rather than returning incomplete Python.
|
|
471
|
+
- NumPy, PyTorch, and JAX operate elementwise where the framework supports the operation. Finite sums still use scalar iteration bounds.
|
|
472
|
+
- Piecewise outputs use elementwise selection in array backends. Validate branch domains when an unselected branch could itself produce invalid values.
|
|
473
|
+
- SymPy's current LaTeX grammar requires the `antlr4-python3-runtime` package (declared with a compatible version range); SymPy's Lark backend was evaluated but does not cover the expression grammar and constructs supported here.
|
|
474
|
+
- Generated tensor code does not promise a particular device, dtype, or shape policy. Gamma has poles at non-positive integers; behavior at singularities and outside mathematical domains follows the selected backend.
|
|
475
|
+
- Generated Python is not a mathematical proof or a guarantee of numerical stability. Review and test output before relying on it in research or production calculations.
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## License
|
|
480
|
+
|
|
481
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|