# Turn a sympy expression to a trainable equation

**URL:** <https://discuss.pytorch.org/t/turn-a-sympy-expression-to-a-trainable-equation/66388>\
**Category:** Uncategorized\
**Created:** [January 11, 2020, 3:37pm UTC](https://discuss.pytorch.org/t/turn-a-sympy-expression-to-a-trainable-equation/66388 "2020-01-11T15:37:29Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![smu226](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/smu226/32/9063_2.png) [@smu226](https://discuss.pytorch.org/u/smu226)\
**Post date:** [January 11, 2020, 3:37pm UTC](https://discuss.pytorch.org/t/turn-a-sympy-expression-to-a-trainable-equation/66388/1 "2020-01-11T15:37:29Z")

</div>

Hello! I have some sympy expressions of the form: `c0*cos(c1*y) + c2 + c3*x**2` I want to turn the parameters c0, c1, c2, c3 to trainable pytorch parameters and run gradient descent on them (as I would do with an actual NN), to fit them to some data of the form (x,y,z). Is there a way to do this? Thank you!

---

<div class="post-metadata">

**Author:** ![ptrblck](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/32/1823_2.png) [@ptrblck](https://discuss.pytorch.org/u/ptrblck)\
**Post date:** [January 12, 2020, 1:46am UTC](https://discuss.pytorch.org/t/turn-a-sympy-expression-to-a-trainable-equation/66388/2 "2020-01-12T01:46:19Z")

</div>

You can define `cX` as an `nn.Parameter`, which would make them trainable.  
Also, you can wrap them in an `nn.Module`, which could make handling them easier:

```python
class MyModel(nn.Module):
    def __init__ (self):
        super(MyModel, self). __init__ ()
        self.c0 = nn.Parameter(torch.randn(1, 1))
        self.c1 = nn.Parameter(torch.randn(1, 1))
        self.c2 = nn.Parameter(torch.randn(1, 1))
        self.c3 = nn.Parameter(torch.randn(1, 1))
        
    def forward(self, x, y):
        out = self.c0 * torch.cos(self.c1 * y) + self.c2 + self.c3 * x**2
        return out

model = MyModel()
x, y = torch.randn(1, 1), torch.randn(1, 1)
out = model(x, y)
out.backward()
for name, param in model.named_parameters():
    print(name, param.grad)

```

---

<div class="post-metadata">

**Author:** ![smu226](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/smu226/32/9063_2.png) [@smu226](https://discuss.pytorch.org/u/smu226)\
**Post date:** [January 12, 2020, 2:06am UTC](https://discuss.pytorch.org/t/turn-a-sympy-expression-to-a-trainable-equation/66388/3 "2020-01-12T02:06:19Z")

</div>

Thank you for your reply! This is the final form that I want to get to. However, my question was if there is a way to go automatically from the sympy expression to this from (sorry if that was not clear). I have lots of sympy expressions, and I want to pass them automatically to a pytorch module for training, not write everything by hand. For example, for the line `out = self.c0 * torch.cos(self.c1 * y) + self.c2 + self.c3 * x**2` I would like some function that would turn my sympy expression to that automatically, something like: `out = sympy_to_pytorch(sympy_expression)`. And something similar for picking the parameters out of my sympy expression and doing the `self.c0 = nn.Parameter(torch.randn(1, 1))` part on its own.

---

<div class="post-metadata">

**Author:** ![ptrblck](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/32/1823_2.png) [@ptrblck](https://discuss.pytorch.org/u/ptrblck)\
**Post date:** [January 12, 2020, 2:10am UTC](https://discuss.pytorch.org/t/turn-a-sympy-expression-to-a-trainable-equation/66388/4 "2020-01-12T02:10:20Z")

</div>

Oh, in that case I misunderstood the use case. 🙂

That’s an interesting idea. I’m unfortunately not deeply familiar with sympy, but do you know, if the “parameters” have some kind of flags?  
I assume we could use some parser to check for the “trainable flag” and create `nn.Parameters` out of them.

EDIT: I’m not sure, if the creation of the actual function would be easy. It seems we would need to have some mapping between sympy to PyTorch methods.

---

<div class="post-metadata">

**Author:** ![Claytonius](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/claytonius/32/21840_2.png) [@Claytonius](https://discuss.pytorch.org/u/Claytonius)\
**Post date:** [December 1, 2020, 7:01pm UTC](https://discuss.pytorch.org/t/turn-a-sympy-expression-to-a-trainable-equation/66388/5 "2020-12-01T19:01:38Z")

</div>

I’ve been working on doing exactly that by adding functionality to sympy that allows reasoning about pytorch tensors.

I’ve documented a few examples here:

> **[Zer0Credibility/symtorch](https://github.com/Zer0Credibility/symtorch)**
>
> Initial Commit. Contribute to Zer0Credibility/symtorch development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![ptrblck](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/32/1823_2.png) [@ptrblck](https://discuss.pytorch.org/u/ptrblck)\
**Post date:** [December 1, 2020, 8:29pm UTC](https://discuss.pytorch.org/t/turn-a-sympy-expression-to-a-trainable-equation/66388/6 "2020-12-01T20:29:23Z")

</div>

That looks pretty cool! Thanks for sharing 🙂

---

<div class="post-metadata">

**Author:** ![strangemonad](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/strangemonad/32/59414_2.png) [@strangemonad](https://discuss.pytorch.org/u/strangemonad)\
**Post date:** [April 12, 2023, 6:10pm UTC](https://discuss.pytorch.org/t/turn-a-sympy-expression-to-a-trainable-equation/66388/7 "2023-04-12T18:10:31Z")

</div>

There’s also sympytorch which looks relatively complete [GitHub - patrick-kidger/sympytorch: Turning SymPy expressions into PyTorch modules.](https://github.com/patrick-kidger/sympytorch)

---

<div class="post-metadata">

**Author:** ![robinechuca](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/r/b77776/32.png) [@robinechuca](https://discuss.pytorch.org/u/robinechuca)\
**Post date:** [June 6, 2023, 10:00pm UTC](https://discuss.pytorch.org/t/turn-a-sympy-expression-to-a-trainable-equation/66388/8 "2023-06-06T22:00:40Z")

</div>

There’s also cutcutcodec which is able to compile sympy expression to pytorch function with some optimizations. But not a lot of functions are yet implemented: [cutcutcodec/core/compilation/sympy\_to\_torch.py · main · robin richard / cutcutcodec · GitLab](https://framagit.org/robinechuca/cutcutcodec/-/blob/main/cutcutcodec/core/compilation/sympy_to_torch.py)

---

<div class="post-metadata">

**Author:** ![robinechuca](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/r/b77776/32.png) [@robinechuca](https://discuss.pytorch.org/u/robinechuca)\
**Post date:** [October 18, 2023, 9:36pm UTC](https://discuss.pytorch.org/t/turn-a-sympy-expression-to-a-trainable-equation/66388/9 "2023-10-18T21:36:06Z")

</div>

Now, this module is very complete: [cutcutcodec/core/compilation/sympy\_to\_torch · main · robin richard / cutcutcodec · GitLab](https://framagit.org/robinechuca/cutcutcodec/-/tree/main/cutcutcodec/core/compilation/sympy_to_torch?ref_type=heads)

- It supports a lot of functions.
- Factorization of the common sub patterns for a complete suppression of the redundancy.
- Dynamic or compiled evaluation for safety or speed.
- Sort the function argument for better broadcasting efficiency.
- Cache smart management for variant and invariant input tensors.
- Reuse internal variable for limiting RAM and speed-up by limiting allocation.
