UFL

Reducing a fraction

Asked by Jan Blechta

Hi,
is there a way one can manipulate (by some algorithm) UFL expression or form to reduce a term like
    something * x[0] / x[0]
to mathematically equivalent
    something * 1
which has polynomial degree smaller by two. Moreover it could prevent division by zero.

I'm not asking for a generel algorithm doing a division of rational functions but rather if user can apply some transformation rule locating products with factors x[0] and 1/x[0] and remove it.

I admit I could do this transformation by hand but consider situation when this expression is result of automatic calculations (e.g. automatic differentiation).

Thanks
Jan

Question information

Language:
English Edit question
Status:
Answered
For:
UFL Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Martin Sandve Alnæs (martinal) said :
#1

On 23 October 2012 13:11, Jan Blechta
<email address hidden> wrote:
> New question #212068 on UFL:
> https://answers.launchpad.net/ufl/+question/212068
>
> Hi,
> is there a way one can manipulate (by some algorithm) UFL expression or form to reduce a term like
> something * x[0] / x[0]
> to mathematically equivalent
> something * 1
> which has polynomial degree smaller by two. Moreover it could prevent division by zero.
>
> I'm not asking for a generel algorithm doing a division of rational functions but rather if user can apply some transformation rule locating products with factors x[0] and 1/x[0] and remove it.
>

No, there is no way to do that in ufl without writing additional
algorithms for it.

Such simplification may be feasible for this particular case but
generalized can be a very hard problem.

Martin

> I admit I could do this transformation by hand but consider situation when this expression is result of automatic calculations (e.g. automatic differentiation).
>
> Thanks
> Jan
>
> --
> You received this question notification because you are a member of UFL
> Team, which is an answer contact for UFL.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~ufl
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~ufl
> More help : https://help.launchpad.net/ListHelp

Revision history for this message
Martin Sandve Alnæs (martinal) said :
#2

Jan, I added an automatic simplification for the case f/f -> 1, see if that helps. It does not, however, handle the case (g*f)/f, only g*(f/f), so it may not help you.

Revision history for this message
Jan Blechta (blechta) said :
#3

Good job, Martin. But general cases like (g*f)/f are of my interest. So it would need to recognize associative compound of many products and divisions which could be transformed to general fraction like f1*f2*f3*.../(g1*g2*g3*...) with fi,gi terminals and then to check for possible equalities fi==gj for some i,j to reduce the fraction. So it would simply set terminals fi=gj=1 and kept original expression in order to avoid need for defining additional operator for fraction. What do you think about this design? It of course needs thinking over non-scalar case (possibly do nothing).

I woud try doing something like that sometimes next week (if not anybody else:)) but I'm not much familiar with UFL operation so I can't promise...

Jan

Revision history for this message
Martin Sandve Alnæs (martinal) said :
#4

Ignoring the non-scalar case, and limiting this to pure "chains" of Product/Division, is probably fairly easy to implement as an algorithm you can choose to apply, or that a form compiler can choose to apply. This should also be safe from a floating point point of view. I deliberately do not allow such deep simplifications automatic at construction of expressions however, because they will be O(n) in the size of the expression tree, and they may also obfuscate otherwise clear cases of subexpression reuse.

Revision history for this message
Kristian B. Ølgaard (k.b.oelgaard) said :
#5

On 23 October 2012 17:31, Jan Blechta
<email address hidden> wrote:
> Question #212068 on UFL changed:
> https://answers.launchpad.net/ufl/+question/212068
>
> Jan Blechta posted a new comment:
> Good job, Martin. But general cases like (g*f)/f are of my interest. So
> it would need to recognize associative compound of many products and
> divisions which could be transformed to general fraction like
> f1*f2*f3*.../(g1*g2*g3*...) with fi,gi terminals and then to check for
> possible equalities fi==gj for some i,j to reduce the fraction. So it
> would simply set terminals fi=gj=1 and kept original expression in order
> to avoid need for defining additional operator for fraction. What do you
> think about this design? It of course needs thinking over non-scalar
> case (possibly do nothing).

Something similar to this is implemented in FFC for the quadrature
representation (optimisation).
The difference is that it operates on an intermediate representation
of the code which will be generated meaning that all symbols are
scalar valued.
It is an expensive optimisation to perform, so having something
similar which operates at the higher UFL abstraction level could be
expected to improve performace.

Kristian

> I woud try doing something like that sometimes next week (if not anybody
> else:)) but I'm not much familiar with UFL operation so I can't
> promise...
>
> Jan
>
> --
> You received this question notification because you are a member of UFL
> Team, which is an answer contact for UFL.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~ufl
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~ufl
> More help : https://help.launchpad.net/ListHelp

Can you help with this problem?

Provide an answer of your own, or ask Jan Blechta for more information if necessary.

To post a message you must log in.