← Back to team overview

ufl team mailing list archive

Re: Evaluating tensor expressions

 

2008/10/21 Anders Logg <logg@xxxxxxxxx>:
> On Tue, Oct 21, 2008 at 08:22:48PM +0200, Martin Sandve Alnæs wrote:
>> 2008/10/21 Anders Logg <logg@xxxxxxxxx>:
>> > On Tue, Oct 21, 2008 at 07:57:01PM +0200, Martin Sandve Alnæs wrote:
>> >> 2008/10/21 Anders Logg <logg@xxxxxxxxx>:
>> >> > On Tue, Oct 21, 2008 at 06:14:00PM +0200, Martin Sandve Alnæs wrote:
>> >> >> 2008/10/21 Anders Logg <logg@xxxxxxxxx>:
>> >> >> > On Tue, Oct 21, 2008 at 06:03:27PM +0200, Martin Sandve Alnæs wrote:
>> >> >> >> 2008/10/21 Anders Logg <logg@xxxxxxxxx>:
>> >> >> >> > On Tue, Oct 21, 2008 at 05:41:15PM +0200, Martin Sandve Alnæs wrote:
>> >> >> >> >> 2008/10/21 Anders Logg <logg@xxxxxxxxx>:
>> >> >> >> >> > On Tue, Oct 21, 2008 at 05:27:55PM +0200, Anders Logg wrote:
>> >> >> >> >> >> Is there a simple way to evaluate tensor expressions? For example, if
>> >> >> >> >> >>
>> >> >> >> >> >>  a = dot(v, u)*dx
>> >> >> >> >> >>
>> >> >> >> >> >> is there then a way to convert this to
>> >> >> >> >> >>
>> >> >> >> >> >>  v[0]*u[0] + v[1]*u[1] + ...
>> >> >> >> >> >>
>> >> >> >> >> >> ?
>> >> >> >> >> >
>> >> >> >> >> > I found the following in Dot:
>> >> >> >> >> >
>> >> >> >> >> >  def as_basic(self, dim, a, b):
>> >> >> >> >> >      ii = Index()
>> >> >> >> >> >      aa = a[ii] if (a.rank() == 1) else a[...,ii]
>> >> >> >> >> >      bb = b[ii] if (b.rank() == 1) else b[ii,...]
>> >> >> >> >> >      return aa*bb
>> >> >> >> >> >
>> >> >> >> >> > Why are the arguments dim, a and b required? A Dot already knows its
>> >> >> >> >> > operands.
>> >> >> >> >> >
>> >> >> >> >> >> On Tue, Oct 21, 2008 at 05:27:55PM +0200, Anders Logg wrote:
>> >> >> >> >> >> Is there a simple way to evaluate tensor expressions? For example, if
>> >> >> >> >> >>
>> >> >> >> >> >>  a = dot(v, u)*dx
>> >> >> >> >> >>
>> >> >> >> >> >> is there then a way to convert this to
>> >> >> >> >> >>
>> >> >> >> >> >>  v[0]*u[0] + v[1]*u[1] + ...
>> >> >> >> >> >>
>> >> >> >> >> >> ?
>> >> >> >> >> >
>> >> >> >> >> > I found the following in Dot:
>> >> >> >> >> >
>> >> >> >> >> >  def as_basic(self, dim, a, b):
>> >> >> >> >> >      ii = Index()
>> >> >> >> >> >      aa = a[ii] if (a.rank() == 1) else a[...,ii]
>> >> >> >> >> >      bb = b[ii] if (b.rank() == 1) else b[ii,...]
>> >> >> >> >> >      return aa*bb
>> >> >> >> >> >
>> >> >> >> >> > Why are the arguments dim, a and b required? A Dot already knows its
>> >> >> >> >> > operands.
>> >> >> >> >> >
>> >> >> >> >>
>> >> >> >> >> Because it is used in an algorithm that first expands its operands,
>> >> >> >> >> so a and b here are not necessarily its original operands.
>> >> >> >> >> As you see, dim is not used here, but it's used in some other Compounds.
>> >> >> >> >>
>> >> >> >> >> These functions could of course also be placed in the algorithm
>> >> >> >> >> in question instead of in each Compound object, like with several
>> >> >> >> >> other algorithms. But I think that's a detail we can discuss later,
>> >> >> >> >> in context with other similar issues.
>> >> >> >> >
>> >> >> >> > Yes, if as_basic does not work like a member function, it seems
>> >> >> >> > strange to make it a member function. Maybe it could be made static if
>> >> >> >> > necessary.
>> >> >> >> >
>> >> >> >>
>> >> >> >> I'm fine with moving it into the algorithm, I can do that later.
>> >> >> >>
>> >> >> >> Keeping it (static) in the class simplifies adding new Compound
>> >> >> >> objects, that's the only reason I can think of now. But this is not
>> >> >> >> really necessary since they would have to be handled in e.g. the
>> >> >> >> latex compiler and maybe other places for that to make any sense.
>> >> >> >>
>> >> >> >> This probably makes no sense to you right now, we should set
>> >> >> >> up a session where I show how these things fit together.
>> >> >> >
>> >> >> > There are a lot of things that don't make sense to me right now... :-)
>> >> >> >
>> >> >> > So is there any way right now to handle compound expressions, or do I
>> >> >> > need to implement it?
>> >> >> >
>> >> >> > Say that I have a = dot(v, u)*dx, how can I expand it into simpler
>> >> >> > operations (including only +, *, and [])?
>> >> >> >
>> >> >>
>> >> >> As I just mentioned, the function expand_compounds will expand
>> >> >> dot, inner, grad, div, and several others into index-notation.
>> >> >> Not sure what it is you want beyond that?
>> >> >>
>> >> >> Expanding implicit sums and products into explicit sums and
>> >> >> products is not implemented in UFL, since so far I've opted
>> >> >> to do that while converting to swiginac in SFC. It would be nice
>> >> >> to have it in UFL though, but I didn't think you needed that.
>> >> >
>> >> > What is the dim argument to expand_compounds, and why is it needed?
>> >> >
>> >> > Should I look at the operands and find out the appropriate dimension,
>> >> > and how is that best done?
>> >> >
>> >>
>> >> As you've discovered, you don't need to use that.
>> >>
>> >> But anyway, dim is the "default dimension", i.e. the spatial dimension.
>> >> It's used by as_basic in at least the inverse and cofactor, which
>> >> are simply hardcoded with expressions I obtained from ginac...
>> >
>> > Does not sound optimal...
>> >
>> >> There are some issues with this dimension / shape thing,
>> >> but I'll leave that for another day.
>> >
>> > I'll use dim=None for now and hope we can remove the argument at some
>> > point.
>>
>> You shouldn't need to call it at all, why do you do that?
>
> What do you mean? I want to call expand_compounds to get from Dot,
> Grad etc to index notation. And expand_compounds requires a dim
> argument.
>
> --
> Anders

Sorry, I was thinking that expand_compounds figured out the dim.
Given a Form, you easily know the right dim, but expand_compounds only
takes an expression.

I've moved the as_basic functions now.

--
Martin


Follow ups

References