Opened 16 months ago

Last modified 5 months ago

#30373 new defect

Parent methods tensor vs. tensor_product

Reported by: mkoeppe Owned by:
Priority: major Milestone: sage-9.5
Component: linear algebra Keywords:
Cc: tscrim, egourgoulhon, gh-mjungmath, jhpalmieri Merged in:
Authors: Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Status badges

Description (last modified by mkoeppe)

We unify the use of the methods tensor vs. tensor_product in parent classes.

Current situation:

Category ModulesWithBasis provides a parent method tensor to construct a tensor product of modules.

sage: C = CombinatorialFreeModule(QQ, ['x', 'y'])                                                                                                                
sage: C.tensor(C)                                                                                                                                                
Free module generated by {'x', 'y'} over Rational Field # Free module generated by {'x', 'y'} over Rational Field

It is not implemented completely for FreeModule

sage: V = FreeModule(QQ, 2)                                                                                                                                      
sage: V.tensor(V)                                                                                                                                                
AttributeError: type object 'FreeModule_ambient_field_with_category' has no attribute 'Tensor'
sage: 

In contrast, FiniteRankFreeModule (which is not in ModulesWithBasis) uses a parent method tensor to construct elements.

sage: F.tensor((2, 2))                                                                                                                                           
Type-(2,2) tensor on the 2-dimensional vector space over the Rational Field

FilteredVectorSpace has both tensor (from ModulesWithBasis) and tensor_product, but only the latter works.

sage: FV = FilteredVectorSpace(2)                                                                                                                                
sage: FV.tensor_product(FV)                                                                                                                                      
QQ^4
sage: FV.tensor(FV)                                                                                                                                              
AttributeError: type object 'FilteredVectorSpace_class_with_category' has no attribute 'Tensor'

The same is true for FreeQuadraticModule_integer_symmetric:

sage: L = IntegralLattice(Matrix(ZZ, 2, [2,1,1,-2]))                                                                                                             
sage: L.tensor_product(L)                                                                                                                                        
Lattice of degree 4 and rank 4 over Integer Ring
Standard basis 
Inner product matrix:
[ 4  2  2  1]
[ 2 -4  1 -2]
[ 2  1 -4 -2]
[ 1 -2 -2  4]
sage: L.tensor(L)                                                                                                                                                
AttributeError: type object 'FreeQuadraticModule_integer_symmetric_with_categor' has no attribute 'Tensor'

The proposed solution in this ticket is to standardize on the method tensor_product, making tensor a deprecated alias.

Modules already has a tensor_square method, which tensor_product complements well.

We also add tensor_power.

No changes are made to the global tensor (unique instance of TensorProductFunctor).

See also: #18349

Change History (23)

comment:1 Changed 16 months ago by mkoeppe

  • Description modified (diff)

comment:2 Changed 16 months ago by mkoeppe

  • Cc jhpalmieri added

comment:3 Changed 16 months ago by mkoeppe

  • Description modified (diff)

comment:4 Changed 15 months ago by mkoeppe

  • Milestone changed from sage-9.2 to sage-9.3

comment:5 Changed 12 months ago by mkoeppe

  • Description modified (diff)

comment:6 follow-up: Changed 10 months ago by jhpalmieri

A few other things to think about:

  • In the first example, C.tensor(C, C) works as expected. In contrast, the tensor function doesn't take multiple inputs, but instead an iterable: tensor([C,C,C]) instead of tensor(C, C, C). I would prefer a consistent syntax.
  • What about tensoring elements together? Right now the tensor function works on elements, although the documentation doesn't make this clear. I am happy for this to continue, but again, the syntax is different for tensor([a,b,c]) vs. a.tensor(b,c).

comment:7 in reply to: ↑ 6 ; follow-up: Changed 10 months ago by gh-mjungmath

Replying to jhpalmieri:

A few other things to think about:

  • In the first example, C.tensor(C, C) works as expected. In contrast, the tensor function doesn't take multiple inputs, but instead an iterable: tensor([C,C,C]) instead of tensor(C, C, C). I would prefer a consistent syntax.

+1. I don't have a strong opinion which one we choose. Multiple inputs feels more flexible (and doesn't need an additional bracket).

  • What about tensoring elements together? Right now the tensor function works on elements, although the documentation doesn't make this clear. I am happy for this to continue, but again, the syntax is different for tensor([a,b,c]) vs. a.tensor(b,c).

I like that behavior, too. However, it feels to me like this behavior was not intended and just works because the element provides a tensor method (that's probably why it's not mentioned in the documentation). From a mathematical-categorial viewpoint this behavior is anyway unexpected (functors usually do not act on objects of objects).

If we want to promote this, which I would agree with, the syntax should indeed be the same.

This might also be a good opportunity to introduce the @ notation you have proposed in here which I really like (so +1 from my side, too).

As for FiniteRankFreeModule, introducing methods like tensor_product and tensor_power is readily done (I already finished the former).

So, should we split the task into several pieces, and I provide the FiniteRankFreeModule add-on? You just have to tell me which syntax you prefer.

Last edited 10 months ago by gh-mjungmath (previous) (diff)

comment:8 in reply to: ↑ 7 ; follow-up: Changed 10 months ago by mkoeppe

Replying to gh-mjungmath:

This might also be a good opportunity to introduce the @ notation you have proposed in here which I really like (so +1 from my side, too).

-1 on this - as per discussion in #30244, @ should be for tensor contraction, not tensor product

comment:9 in reply to: ↑ 8 Changed 10 months ago by gh-mjungmath

Replying to mkoeppe:

Replying to gh-mjungmath:

This might also be a good opportunity to introduce the @ notation you have proposed in here which I really like (so +1 from my side, too).

-1 on this - as per discussion in #30244, @ should be for tensor contraction, not tensor product

But the idea in principle remains, doesn't it? What about # instead? That's already the symbol for tensor products as in categories/tensor.py.

Arrrg, that's commenting...

Last edited 10 months ago by gh-mjungmath (previous) (diff)

comment:10 follow-up: Changed 10 months ago by mkoeppe

Python has only a fixed set of binary operators available. One can resort to overloading something that's rarely used otherwise. In #30244 I suggested & as a possibility, but I am not sure if it's a good idea.

comment:11 in reply to: ↑ 10 Changed 10 months ago by gh-mjungmath

Replying to mkoeppe:

Python has only a fixed set of binary operators available. One can resort to overloading something that's rarely used otherwise. In #30244 I suggested & as a possibility, but I am not sure if it's a good idea.

It feels rather uncanonical. But tensor products seem to be used quite frequently, so if there's no better bet...

What's your opinion on the syntax?

Should I open another ticket to provide tensor_product, tensor_power for FiniteRankFreeModule or just push it into here as open branch?

comment:12 follow-up: Changed 10 months ago by jhpalmieri

We should make people use the unicode for tensor product.

More seriously, if we can switch the syntax to tensor(a,b,c,...) with no extra brackets, that would be nice. I don't know if any of the tensor constructors take optional arguments, so I don't know how hard that would be to implement.

comment:13 Changed 10 months ago by gh-mjungmath

I've opened a ticket for the FiniteRankFreeModule case: #31276.

comment:14 Changed 10 months ago by tscrim

Multiple inputs can also be really annoying when you want to create a list dynamically as you then have to add a * and possibly extra parentheses. The easiest thing to do is to support both behaviors. This is simple enough to implement.

The tensor unicode would be good, except it would depend on how the Python interpreter takes that. Most likely, we would need to implement another find-replace case in the preparser to go to some overloaded infix operator such as &.

comment:15 Changed 10 months ago by gh-mjungmath

Speaking of shortcuts for operations: what about using ^ for the wedge product? There is nothing more appropriate than that!

If that meets your approval, I'll open a ticket for this.

comment:16 follow-up: Changed 10 months ago by jhpalmieri

I find it too easily confused with the exponentiation operator, so I would not like to see it featured prominently in doctests.

comment:17 Changed 10 months ago by gh-mjungmath

So far, the ^ is not supported for exterior algebras:

sage: M = FiniteRankFreeModule(QQ, 3)
sage: AM = M.dual_exterior_power(2)
sage: a = AM.an_element()
sage: a^2
Traceback (most recent call last)
...
TypeError: unsupported operand parent(s) for ^: '2nd exterior power of the dual of the 3-dimensional vector space over the Rational Field' and 'Integer Ring'

But I agree. One would rather expect a^3 == a.wedge(a).wedge(a) if supported.

Mh, one minute ago, I thought it was an ingenious idea. :D

comment:18 in reply to: ↑ 16 ; follow-up: Changed 10 months ago by tscrim

Replying to jhpalmieri:

I find it too easily confused with the exponentiation operator, so I would not like to see it featured prominently in doctests.

However, I think it would be a nice syntactic sugar since a ^ b, for a,b in an exterior algebra, as exponentiation does not make sense.

comment:19 in reply to: ↑ 18 ; follow-up: Changed 10 months ago by gh-mjungmath

Replying to tscrim:

Replying to jhpalmieri:

I find it too easily confused with the exponentiation operator, so I would not like to see it featured prominently in doctests.

However, I think it would be a nice syntactic sugar since a ^ b, for a,b in an exterior algebra, as exponentiation does not make sense.

How do we treat ^ with integers then? As a wedge product, this is the simple multiplication. And I still agree, that this case can easily be confused with the exponential since exponentiation is the standard behavior of Sage anywhere else.

comment:20 in reply to: ↑ 12 Changed 10 months ago by egourgoulhon

Replying to jhpalmieri:

We should make people use the unicode for tensor product.

A relevant ticket here: #30473

comment:21 in reply to: ↑ 19 Changed 10 months ago by egourgoulhon

Replying to gh-mjungmath:

Replying to tscrim:

However, I think it would be a nice syntactic sugar since a ^ b, for a,b in an exterior algebra, as exponentiation does not make sense.

How do we treat ^ with integers then? As a wedge product, this is the simple multiplication. And I still agree, that this case can easily be confused with the exponential since exponentiation is the standard behavior of Sage anywhere else.

+1 (and IMHO a^b looks too far from a wedge product).

comment:22 Changed 10 months ago by mkoeppe

  • Milestone changed from sage-9.3 to sage-9.4

Setting new milestone based on a cursory review of ticket status, priority, and last modification date.

comment:23 Changed 5 months ago by mkoeppe

  • Milestone changed from sage-9.4 to sage-9.5
Note: See TracTickets for help on using tickets.