How to make equation/expression tree?


I have been using param / panel / holoviews for dashboards and visualizations for a while and wondered into a use case I feel like I should be able to solve with param but not entirely sure how to approach it.

What I am looking to do is use string based expressions that have variable names embedded within them that values can change.

For instance maybe I have a few equations that are defined as string expressions:

x = e * g - c
y = x / c + b
z = sin(a) / x

Where my top level inputs would be, a,b,c,g,e, and I would know that those are the only independent variables. I know I could create param.Number for those independent variables but how could I make a new parameter type that would initialize with an expression and would evaluate to the true value while dynamically changing when a,b,c,g,e change? Is there something built in I could take advantage of or do I need to create a new param type?

Thank you!

I’m not sure you need a new Param type. If that’s enough, you could just define a callback that computes x/y/z and is triggered on instantiation (on_init=True) and watches the independent variables.

import math

class Expr(param.Parameterized):
    a = param.Number(1)
    b = param.Number(1)
    c = param.Number(1)
    e = param.Number(0.5)
    g = param.Number(1)

    @param.depends('a', 'b', 'c', 'e', 'g', watch=True, on_init=True)
    def update(self):
        self.x = self.e * self.g - self.c
        self.y = self.x / self.c + self.b
        self.z = math.sin(self.a) / self.x

expr = Expr()

Hi @maximlt, thanks for the quick response!

I think that would work for the simple case I provided. I am more hoping to be able to define a deeper tree of equations from a list of strings and having the dependencies be able to be inferred. Maybe this is a more representative example:

a = x + y 
b = y - sin(z)
c = (a - b) / c

d = c^z

I was imagining each equation becoming its own param where I could take the list of them and generate a param for each of a,b,c,d,x,y,z by recognizing that sin and ^ are not parameters but operators and the dependencies on which other params are within its expression being updated when one of the “free” (in this case: x,y,z) is changed.

Does that make sense? Thanks again for the quick response!

Any ideas? :grin: