Opened 2 years 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.7 |
Component: | linear algebra | Keywords: | |
Cc: | tscrim, egourgoulhon, gh-mjungmath, jhpalmieri | Merged in: | |
Authors: | Reviewers: | ||
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | Stopgaps: |
Description (last modified by )
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 (25)
comment:1 Changed 2 years ago by
- Description modified (diff)
comment:2 Changed 2 years ago by
- Cc jhpalmieri added
comment:3 Changed 2 years ago by
- Description modified (diff)
comment:4 Changed 2 years ago by
- Milestone changed from sage-9.2 to sage-9.3
comment:5 Changed 21 months ago by
- Description modified (diff)
comment:6 follow-up: ↓ 7 Changed 19 months ago by
comment:7 in reply to: ↑ 6 ; follow-up: ↓ 8 Changed 19 months ago by
Replying to jhpalmieri:
A few other things to think about:
- In the first example,
C.tensor(C, C)
works as expected. In contrast, thetensor
function doesn't take multiple inputs, but instead an iterable:tensor([C,C,C])
instead oftensor(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 fortensor([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.
comment:8 in reply to: ↑ 7 ; follow-up: ↓ 9 Changed 19 months ago by
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 19 months ago by
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...
comment:10 follow-up: ↓ 11 Changed 19 months ago by
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 19 months ago by
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: ↓ 20 Changed 19 months ago by
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 19 months ago by
I've opened a ticket for the FiniteRankFreeModule
case: #31276.
comment:14 Changed 19 months ago by
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 19 months ago by
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: ↓ 18 Changed 19 months ago by
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 19 months ago by
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: ↓ 19 Changed 19 months ago by
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: ↓ 21 Changed 19 months ago by
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 19 months ago by
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 19 months ago by
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 18 months ago by
- 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 13 months ago by
- Milestone changed from sage-9.4 to sage-9.5
comment:24 Changed 8 months ago by
- Milestone changed from sage-9.5 to sage-9.6
comment:25 Changed 5 months ago by
- Milestone changed from sage-9.6 to sage-9.7
A few other things to think about:
C.tensor(C, C)
works as expected. In contrast, thetensor
function doesn't take multiple inputs, but instead an iterable:tensor([C,C,C])
instead oftensor(C, C, C)
. I would prefer a consistent syntax.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 fortensor([a,b,c])
vs.a.tensor(b,c)
.