Wrenfold

Latest version: v0.2.2

Safety actively analyzes 696655 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 1 of 2

0.2.2

Support for osx-arm64 on conda

`v0.2.2` resolves an issue (via PR 305) that prevented arm64 builds for OSX on `conda-forge`. There are no breaking changes in this release.

๐Ÿš€ Features

- Add apply_preamble to the python code generator
- PR: 302
- Stubs are generated into the repo and committed to `components/wrapper/stubs`
- PR: 305

๐Ÿ› Fixes

- Do not set git hash at build time if we failed to obtain it
- PR: 304

๐Ÿงน Cleanup

- Remove old python_generation example
- PR: 306

0.2.1

Python code generation

wrenfold can now generate python code targeting three different APIs: JAX, NumPy, and PyTorch. These are implemented in the new `PythonCodeGenerator` class. With this feature, symbolic functions can be generated and invoked within the same python script or notebook, thereby facilitating quicker prototyping.

In addition to `generate_function`, there is now `generate_python` which will return both the code and a callable object you can invoke with numerical types:
python
from wrenfold import code_generation, sym, geometry, type_annotations

def quat_from_matrix(R: type_annotations.Matrix3):
"""A hypothetical symbolic function."""
return geometry.Quaternion.from_rotation_matrix(R).to_vector_wxyz()

func, code = code_generation.generate_python(
func=quat_from_matrix,
target=code_generation.PythonGeneratorTarget.JAX, Target the JAX api.
)
print(code) Visualize the generated code for the purpose of debugging.

We can then batch and JIT the generated function using jax:
func_batched = jax.vmap(func, in_axes=(0, ), out_axes=0)

`func_jit` accepts (B, 3, 3) shaped JAX arrays (of rotation matrices) and returns (B, 4, 1) arrays of quaternions!
It can also be used as part of a larger auto-diffed JAX loss function.
func_jit = jax.jit(func_batched)

R_identity = np.eye(3).reshape(1, 3, 3)

0.1.1

Summary

This release enables support for `CPython 3.13` and adds one new feature: **Derivatives can now be taken with respect to symbolic function invocations.**

For example, you can define a symbolic function and then use it as the argument to a `diff` operation:
python
from wrenfold import sym

f = sym.Function('f')
x, y = sym.symbols('x, y')
g = 2 * x * sym.cos(f(y))
result = g.diff(f(y))
print(result) prints: -2*x*sin(f(y))


In addition, there are two performance improvements:
- Printing/stringify times for large expressions are dramatically improved (around 20x faster).
- Code-generation times are meaningfully improved on some expressions by PR 266. The binarization algorithm had a tendency to grow rapidly in complexity on some expression trees - this issue is now resolved. โš ๏ธ **Note:** This change _does_ affect the number of output expressions. You may see a marginal increase in total operations in exchange.

For example, some representative operation counts from [wrenfold-extra-examples](https://github.com/wrenfold/wrenfold-extra-examples):
- snavely_reprojection_error: 460 --> 465
- sophus `pose3_interpolate`: 4343 --> 4357

๐Ÿš€ Features

- Enable taking derivatives wrt symbolic function invocations
- PR: 268
- Improve performance when printing large expressions
- PR: 275
- Update pybind11 to 2.13.6 to enable python 3.13 wheels
- PR: 278

๐Ÿ› Fixes

- Upgrade `setup-miniconda` step, switch to miniforge3
- PR: 271

๐Ÿ“š Documentation

- Add conda-forge instructions to the documentation
- PR: 269

๐Ÿงน Cleanup

- Simplify binarization algorithm and cleanup code
- PR: 266
- Cleanup CMake + fix brittleness with docs build
- PR: 270
- Update rustc version to 1.81
- PR: 273

0.1.0

Summary

This release implements some new features and is an **API breaking release** (see note below about integer arguments).

This release also resolves the issue where `wrenfold-traits` was pinned to `nalegbra` version `0.32`.

Symbolic function invocation expressions

It is now possible to create an abstract symbolic function, which can be invoked with scalar-valued expression arguments. For example:
python
from wrenfold import sym

f = sym.Function('f')
x, y = sym.symbols('x, y')
g = f(x, sym.sin(y))

We can take derivatives of symbolic function invocations:
g.diff(x) produces: Derivative(f(x, y), x)

Taking the derivative of a symbolic function can be used to create abstract derivative expressions. This can be used to represent a function and its temporal derivatives `f(t), f'(t), f''(t)` symbolically as part of a larger expression.

Integer arguments are supported

You may now annotate function arguments (and members on custom types) as integral valued. Integral args will always be generated as `std::int64_t` (or `i64` in Rust) for now.
python
from wrenfold import sym, type_annotations, code_generation

def func(x: type_annotations.FloatScalar, mode: type_annotations.IntScalar):
Switch on the integer value to change behavior, for example...
return sym.where(sym.eq(mode, 1), sym.cos(x), sym.sin(x))

print(code_generation.generate_function(func, generator=code_generation.CppGenerator()))

Will produce:
cpp
template <typename Scalar>
Scalar func(const Scalar x, const std::int64_t mode)
{
// ...
const std::int64_t v001 = mode;
const Scalar v003 = x;
Scalar v009;
if (1 == v001) {
v009 = std::cos(v003);
} else {
v009 = std::sin(v003);
}
return v009;
}

Operations that combine integer and floating point values are automatically promoted to `Scalar` via `static_cast<>`. If float-scalar-valued values are assigned to integral output values, they are demoted via `static_cast<std::in64_t>`.

โš ๏ธ This is an **API breaking change** because all functions previously annotated with `sym.Expr` must now be annotated with `type_annotations.FloatScalar` (or `type_annotations.IntScalar`, in the case of an integer arg).

If previously you wrote:
python
from wrenfold import sym

def foo(x: sym.Expr):
... some expressions ...
`

You should _now_ write:

python
from wrenfold import type_annotations

def foo(x: type_annotations.FloatScalar):
... some expressions ...


conda-build recipe

We have added a conda-build recipe to the repository, and will shortly submit wrenfold `v0.1.0` to conda-forge.

๐Ÿš€ Features

- Add conda recipe and build scripts
- PR: 251
- Add deferred substitution and symbolic function invocation expressions
- PR: 254
- Add `compare()` function to the python wrapper to enable canonical ordering from python
- PR: 259
- Add standalone versions of the sym.subs and sym.distribute functions
- PR: 262
- Get rid of expression_group type, use any_expression to store function outputs
- PR: 263
- Support integer arguments to generated functions
- PR: 260

๐Ÿ› Fixes

- Fix issue where `distribute` did not recurse, causing some products of fractional powers to not expand
- PR: 258
- Fix `__array__` method on MatrixExpr (missing kwargs)
- PR: 265

๐Ÿ“š Documentation

- Add architecture image to the documentation
- PR: 257

๐Ÿงน Cleanup

- Rename `code_numeric_type` --> `numeric_primitive_type` for clarity
- PR: 261

0.0.7

Version `0.0.7` resolves an issue in previous releases where **Windows** wheels were built in Debug mode by mistake. Prior Linux and OSX wheels are unaffected by this issue.

๐Ÿ› Fixes

- Fix for Windows wheels having wrong build type
- PR: 252

0.0.6

- Fixed an issue present in `v0.0.5` where the generated stubs for the pybind library were omitted from the python wheel.
- Releases now include a source archive that includes the full repo, including submodules.

๐Ÿš€ Features

- Update install instructions to reflect PyPi repository
- PR: 240

๐Ÿ› Fixes

- Fix issue where stubs are missing from wheel files
- PR: 246

Page 1 of 2

ยฉ 2025 Safety CLI Cybersecurity Inc. All Rights Reserved.