Best way to iterate through an expression
Hi, my code has a lot of statements of this kind: if (is_a<mul>(some_ex)) { for (const auto& m : some_ex) { // Do something with m } } else { // Do something with some_ex } Is there a more elegant way of iterating through an expression that avoids having to write the "Do something" part twice? Thanks, Jan
Hi, Jan, Did you check the section "5.5 Applying a function on subexpressions" from the tutorial? Best wishes. Vladimir -- Vladimir V. Kisil http://www.maths.leeds.ac.uk/~kisilv/ Book: Geometry of Mobius Transformations http://goo.gl/EaG2Vu Software: Geometry of cycles http://moebinv.sourceforge.net/
On Mon, 8 May 2017 20:06:14 +0200, Jan Rheinländer <jrheinlaender@gmx.de> said:
JR> Hi, JR> my code has a lot of statements of this kind: JR> if (is_a<mul>(some_ex)) { for (const auto& m : some_ex) { // Do JR> something with m } } else { // Do something with some_ex } JR> Is there a more elegant way of iterating through an expression JR> that avoids having to write the "Do something" part twice? JR> Thanks, JR> Jan JR> _______________________________________________ GiNaC-devel JR> mailing list GiNaC-devel@ginac.de JR> https://www.cebix.net/mailman/listinfo/ginac-devel
Hi Vladimir, yes, I know about the map() function. But that recurses into all sub-expressions, doesn't it? I only want to work on the top-level subexpressions. That is, if the expression is a mul, on its factors, otherwise on the expression itself. I suppose I could pass a level argument to the map function, but that seems like a lot of overhead for a simple problem. Most of the time I apply only a single line of code to my expression. Coding that in a map() function would result in lots more lines of code plus an extra function. The sort of thing I am thinking of is that iteration over an expression would work even if the expression consists e.g. of a single integral. Greetings, Jan
On Tue, 9 May 2017 17:41:33 +0200, Jan Rheinländer <jrheinlaender@gmx.de> said:
JR> Hi Vladimir, yes, I know about the map() function. But that JR> recurses into all sub-expressions, doesn't it? I only want to JR> work on the top-level subexpressions. That is, if the expression JR> is a mul, on its factors, otherwise on the expression itself. JR> I suppose I could pass a level argument to the map function, but JR> that seems like a lot of overhead for a simple problem. Most of JR> the time I apply only a single line of code to my JR> expression. Coding that in a map() function would result in lots JR> more lines of code plus an extra function. JR> The sort of thing I am thinking of is that iteration over an JR> expression would work even if the expression consists e.g. of a JR> single integral. Yes, Jan, within your task I do not know a better solution than you had used... -- Vladimir V. Kisil http://www.maths.leeds.ac.uk/~kisilv/ Book: Geometry of Mobius Transformations http://goo.gl/EaG2Vu Software: Geometry of cycles http://moebinv.sourceforge.net/
Dear Jan, Here's a trick I've used to avoid such code duplication: if (!is_a<mul>(some_ex)) some_ex = lst(some_ex); for (const auto& m : some_ex) { // Do something with m } If some_ex is a product then you iterate over the factors, and otherwise you iterate over the 1-element lst containing only some_ex. Perhaps this fits your use case as well. Best wishes, Ricardo On Mon, May 8, 2017 at 8:06 PM, Jan Rheinländer <jrheinlaender@gmx.de> wrote:
Hi,
my code has a lot of statements of this kind:
if (is_a<mul>(some_ex)) { for (const auto& m : some_ex) { // Do something with m } } else { // Do something with some_ex }
Is there a more elegant way of iterating through an expression that avoids having to write the "Do something" part twice?
Thanks,
Jan
_______________________________________________ GiNaC-devel mailing list GiNaC-devel@ginac.de https://www.cebix.net/mailman/listinfo/ginac-devel
Dear Ricardo, great idea! I compacted it to for (const auto& m: (is_a<mul>(some_ex) ? some_ex : lst{some_ex}) // Do something with m Greetings, Jan Am 10.05.2017 um 17:47 schrieb Ricardo Buring:
Dear Jan,
Here's a trick I've used to avoid such code duplication:
if (!is_a<mul>(some_ex)) some_ex = lst(some_ex); for (const auto& m : some_ex) { // Do something with m }
If some_ex is a product then you iterate over the factors, and otherwise you iterate over the 1-element lst containing only some_ex. Perhaps this fits your use case as well.
Best wishes, Ricardo
participants (3)
-
Jan Rheinländer
-
Ricardo Buring
-
Vladimir V. Kisil