Skip to main content

Python/NumPy Compilation Target

The Python compilation target generates NumPy-compatible Python code from mathematical expressions, enabling seamless integration with scientific Python workflows.

Overview

The PythonTarget class compiles Compute Engine expressions to Python code that uses NumPy for numerical operations. The generated code is:

  • Vectorized: Works with both scalars and NumPy arrays
  • Readable: Clean, idiomatic Python code
  • Efficient: Leverages NumPy's optimized implementations
  • Compatible: Works with SciPy, Pandas, and other scientific Python libraries

Basic Usage

import { ComputeEngine, PythonTarget } from '@cortex-js/compute-engine';

const ce = new ComputeEngine();
const python = new PythonTarget();

// Compile a simple expression
const expr = ce.parse('x^2 + y^2');
const code = python.compile(expr);
console.log(code); // "x ** 2 + y ** 2"

Using with expr.compile()

To use the Python target with expr.compile(), register it first:

import { ComputeEngine, PythonTarget } from '@cortex-js/compute-engine';

const ce = new ComputeEngine();

// Register the Python target (only need to do this once)
ce.registerCompilationTarget('python', new PythonTarget({ includeImports: true }));

// Now you can use it throughout your code
const expr = ce.parse('\\sin(x) + \\cos(y)');
const pythonCode = expr.compile({ to: 'python' });
console.log(pythonCode.toString());
// → import numpy as np
//
// np.sin(x) + np.cos(y)

Features

1. Expression Compilation

Convert mathematical notation to Python code:

const python = new PythonTarget();

// Polynomial
ce.parse('x^4 + 3x^3 + 2x^2 + x + 1');
// → "x ** 4 + 3 * x ** 3 + 2 * x ** 2 + x + 1"

// Trigonometric
ce.parse('\\sin(x) + \\cos(y)');
// → "np.sin(x) + np.cos(y)"

// Square root
ce.parse('\\sqrt{x^2 + y^2}');
// → "np.sqrt(x ** 2 + y ** 2)"

// Constants
ce.parse('2\\pi r');
// → "2 * np.pi * r"

2. Function Generation

Generate complete Python functions:

const python = new PythonTarget({ includeImports: true });

const expr = ce.parse('\\sqrt{(x_2-x_1)^2 + (y_2-y_1)^2}');
const func = python.compileFunction(
expr,
'euclidean_distance',
['x_1', 'y_1', 'x_2', 'y_2'],
'Calculate Euclidean distance between two points'
);

Generates:

import numpy as np

def euclidean_distance(x_1, y_1, x_2, y_2):
"""Calculate Euclidean distance between two points"""
return np.sqrt((x_2 - x_1) ** 2 + (y_2 - y_1) ** 2)

3. Lambda Functions

Create Python lambda expressions:

const expr = ce.parse('x^2 + 2x + 1');
const lambda = python.compileLambda(expr, ['x']);
// → "lambda x: x ** 2 + 2 * x + 1"

4. Vectorized Functions

Generate NumPy-vectorized functions:

const expr = ce.parse('\\sin(x) * \\cos(x)');
const func = python.compileVectorized(expr, 'trig_product', ['x']);

Generates:

import numpy as np

def _trig_product_scalar(x):
return np.sin(x) * np.cos(x)

# Vectorized version
trig_product = np.vectorize(_trig_product_scalar)

Supported Functions

Trigonometric

  • sin, cos, tannp.sin, np.cos, np.tan
  • arcsin, arccos, arctannp.arcsin, np.arccos, np.arctan
  • sinh, cosh, tanhnp.sinh, np.cosh, np.tanh

Exponential & Logarithmic

  • expnp.exp
  • lnnp.log
  • log10np.log10
  • log2np.log2

Power & Roots

  • x^nx ** n
  • sqrtnp.sqrt
  • powernp.power

Rounding

  • absnp.abs
  • floornp.floor
  • ceilingnp.ceil
  • roundnp.round

Statistics

  • sumnp.sum
  • meannp.mean
  • mediannp.median
  • stdnp.std

Linear Algebra

  • dotnp.dot
  • crossnp.cross
  • normnp.linalg.norm
  • detnp.linalg.det
  • invnp.linalg.inv

Configuration Options

new PythonTarget({
includeImports: true, // Add "import numpy as np" to output
useScipy: false // Include scipy.special for advanced functions
})

Real-World Examples

Physics: Kinematic Equation

const expr = ce.parse('u \\cdot t + \\frac{1}{2} a \\cdot t^2');
const kinematics = python.compileFunction(
expr,
'position',
['u', 'a', 't'],
'Position with initial velocity u, acceleration a, at time t'
);

Generates:

import numpy as np

def position(u, a, t):
"""Position with initial velocity u, acceleration a, at time t"""
return 0.5 * a * t ** 2 + t * u

Mathematics: Quadratic Formula

const expr = ce.parse('\\frac{-b + \\sqrt{b^2 - 4ac}}{2a}');
const quadratic = python.compileFunction(
expr,
'quadratic_root',
['a', 'b', 'c'],
'Calculate one root of a quadratic equation'
);

Generates:

import numpy as np

def quadratic_root(a, b, c):
"""Calculate one root of a quadratic equation"""
return (-b + np.sqrt(b ** 2 + -(4 * a * c))) / (2 * a)

Statistics: Gaussian Function

const expr = ce.parse('e^{-x^2}');
const gaussian = python.compileFunction(
expr,
'gaussian',
['x'],
'Unnormalized Gaussian function'
);

Generates:

import numpy as np

def gaussian(x):
"""Unnormalized Gaussian function"""
return np.e ** (-x ** 2)

Use Cases

1. Scientific Computing

Generate NumPy code for numerical analysis and simulations:

# Generated function works with arrays
import numpy as np

# ... generated function here ...

x = np.linspace(0, 10, 100)
y = gaussian(x) # Vectorized operation

2. Machine Learning

Create feature engineering functions:

const expr = ce.parse('\\frac{x - \\mu}{\\sigma}');
const normalize = python.compileFunction(expr, 'z_score', ['x', 'mu', 'sigma']);
// Use in ML pipeline for feature normalization

3. Data Analysis

Convert formulas to vectorized Pandas operations:

import pandas as pd
# Generated function
def calculate_metric(x, y):
return np.sqrt(x ** 2 + y ** 2)

# Use with DataFrames
df['result'] = calculate_metric(df['col1'], df['col2'])

4. Education

Show Python equivalents of mathematical notation:

// Students see: ∑(xᵢ - μ)²/n
const expr = ce.parse('\\frac{\\sum(x - \\mu)^2}{n}');
const code = python.compile(expr);
// Students learn: np.sum((x - mu) ** 2) / n

5. Code Generation

Automated function creation from specifications:

// Read formulas from config/database
const formulas = loadFormulas();
formulas.forEach(formula => {
const expr = ce.parse(formula.latex);
const code = python.compileFunction(expr, formula.name, formula.params);
writeToFile(`generated/${formula.name}.py`, code);
});

Integration Examples

With Jupyter Notebooks

# Cell 1: Generated functions
%load generated_functions.py

# Cell 2: Use with data
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-5, 5, 1000)
y = gaussian(x)

plt.plot(x, y)
plt.title('Generated Gaussian Function')
plt.show()

With SciPy

// Generate function using SciPy special functions
const python = new PythonTarget({ includeImports: true, useScipy: true });
const expr = ce.parse('\\Gamma(x)');
const code = python.compile(expr);
// → Uses scipy.special.gamma

Complete Pipeline

// 1. Parse LaTeX from document
const latex = extractLatexFromDocument('paper.tex');

// 2. Compile to Python
const python = new PythonTarget({ includeImports: true });
const functions = latex.formulas.map(f =>
python.compileFunction(ce.parse(f.equation), f.name, f.variables)
);

// 3. Generate Python module
const module = functions.join('\n\n');
fs.writeFileSync('generated_math.py', module);

// 4. Use in Python
// from generated_math import *

Comparison with Other Targets

FeatureJavaScriptGLSLPython
ExecutionNode.js/BrowserGPU (WebGL)Python Runtime
Use CaseCPU ComputationGraphics/ParallelScientific Computing
OutputExecutable FunctionShader Code (String)Python Code (String)
PerformanceFast (JIT)Very Fast (Parallel)Fast (NumPy/C)
IntegrationDirect in JSWebGL ContextImport in Python

Best Practices

1. Choose the Right Target

  • JavaScript: Browser/Node.js execution, immediate use
  • Python: Scientific workflows, NumPy integration
  • GLSL: GPU parallel computation, graphics

2. Handle Imports Properly

// For standalone scripts
const python = new PythonTarget({ includeImports: true });

// For modules (import at top of file separately)
const python = new PythonTarget({ includeImports: false });

3. Vectorization

Generated functions work with both scalars and arrays:

# Scalar
result = euclidean_distance(1, 2, 4, 6) # Single value

# Arrays (element-wise)
x1 = np.array([1, 2, 3])
y1 = np.array([1, 2, 3])
x2 = np.array([4, 5, 6])
y2 = np.array([4, 5, 6])
result = euclidean_distance(x1, y1, x2, y2) # Array of distances

4. Type Safety

Remember that generated Python code is untyped. Add type hints manually if needed:

def euclidean_distance(x_1: float, y_1: float, x_2: float, y_2: float) -> float:
return np.sqrt((x_2 - x_1) ** 2 + (y_2 - y_1) ** 2)

Limitations

  1. Not Executable in JavaScript: Python code must be run in a Python environment
  2. Type Information Lost: Generated code is untyped (can add hints manually)
  3. Some Simplifications: Expressions are canonicalized (e.g., x/20.5 * x)
  4. Requires NumPy: Most functions need NumPy to be installed

See Also