Latest version: **v0.1.0**

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

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

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

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

๐ Fixes

- Fix for Windows wheels having wrong build type

- PR: 252

- 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

- 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

wrenfold can now be installed via:

bash

pip install wrenfold

There are no code changes from `v0.0.4` - the version number had to be incremented for PyPi.

bash

pip install wrenfold

There are no code changes from `v0.0.4` - the version number had to be incremented for PyPi.

This release primarily fixes bugs and improves documentation. The most significant bug was an issue where non-optional output arguments were not assigned correctly in generated Rust code (fixed by PR 228).

๐ Features

- build-wheels creates archive of all wheels

- PR: 217

- Add rust example to custom types docs, show how to customize constructor

- PR: 227

- Add an improved quick start guide

- PR: 231

- Add rosenbrock function to the examples

- PR: 233

๐ Fixes

- Fix CI runner build parallelism specification

- PR: 223

- Fixes for gcc-14 compilation issues

- PR: 222

- Fix assignment to non-optional custom type output arguments in rust

- PR: 228

- Disable broken full-piv LU code path

- PR: 236

- Fix integer overflow in bspline example

- PR: 237

๐ Features

- build-wheels creates archive of all wheels

- PR: 217

- Add rust example to custom types docs, show how to customize constructor

- PR: 227

- Add an improved quick start guide

- PR: 231

- Add rosenbrock function to the examples

- PR: 233

๐ Fixes

- Fix CI runner build parallelism specification

- PR: 223

- Fixes for gcc-14 compilation issues

- PR: 222

- Fix assignment to non-optional custom type output arguments in rust

- PR: 228

- Disable broken full-piv LU code path

- PR: 236

- Fix integer overflow in bspline example

- PR: 237

๐ Features

- Add inverse left Jacobian of SO(3) to geometry module

- PR: 195

- Simplify runtime library to two headers (merge span_eigen.h into span.h)

- PR: 196

- Unify the `subs` function interface (eliminate `subs_variables`)

- PR: 199

- Add parameter to `CppCodeGenerator.apply_preamble` to specify imports

- PR: 202

- Substitute visitor uses caching

- PR: 203

- Add `unique_symbols` method to the python wrapper

- PR: 204

- Add a diff test that checks rust_generation_test output code is up to date

- PR: 205

- Do not insert superfluous intermediate variables (more compact output)

- PR: 206

- Remove unused traits from the rust traits crate

- PR: 208

- Improve documentation

- PR: 215

๐ Fixes

- Fix bug preventing nesting of vectors/matrices in custom types

- PR: 194

- Fix bug in to_rotation_vector, add more test coverage

- PR: 201

- Add inverse left Jacobian of SO(3) to geometry module

- PR: 195

- Simplify runtime library to two headers (merge span_eigen.h into span.h)

- PR: 196

- Unify the `subs` function interface (eliminate `subs_variables`)

- PR: 199

- Add parameter to `CppCodeGenerator.apply_preamble` to specify imports

- PR: 202

- Substitute visitor uses caching

- PR: 203

- Add `unique_symbols` method to the python wrapper

- PR: 204

- Add a diff test that checks rust_generation_test output code is up to date

- PR: 205

- Do not insert superfluous intermediate variables (more compact output)

- PR: 206

- Remove unused traits from the rust traits crate

- PR: 208

- Improve documentation

- PR: 215

๐ Fixes

- Fix bug preventing nesting of vectors/matrices in custom types

- PR: 194

- Fix bug in to_rotation_vector, add more test coverage

- PR: 201