Bravos-Power / pyoframe

Rapidly formulate huge optimization models
https://bravos-power.github.io/pyoframe/
MIT License
2 stars 1 forks source link

Implemented function for summing a list of expressionables #15

Closed kjartan-at-bravos closed 6 months ago

kjartan-at-bravos commented 6 months ago

A preliminary test showed me that the speed-up could be significant doing pl.concat on all the expresionnables' data instead of one by one as in an explicit sum e1 + e2 + e3.

In [10]: m.z = pf.Variable(pl.DataFrame({"p": np.arange(2000)}), pl.DataFrame({"t": np.arange(200)}))
In [11]: %timeit m.x + m.y + m.z
586 ms ± 40.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [12]: %timeit pl.concat([m.x.to_expr().data + m.y.to_expr().data + m.z.to_expr().data], how="vertical_relaxed")
85.8 ms ± 4.11 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

This PR proposes a function sum_list(Iterable[SupportsToExpr]) that implements this.

staadecker commented 6 months ago

Gracias! Me parece bien. The size of the speedup is larger than I would've guessed so this is great! Eventually I'll try to re-route this __add__ to use this as well (to avoid duplicated code) and I might suggest renaming some of the api (I'm thinking perhaps the other should be called sum_over and this should be called sum or quicksum)

kjartan-at-bravos commented 6 months ago

Great! I think the naming you suggests makes sense. I am also curious to see how you would modify __add__ to work with a sequence of additions. I guess you could have self maintain a list of other Expression object that has been added to it, and only do the final sum over the list when it is needed. Like a lazy evaluation.