@@ -673,6 +673,91 @@ def forward_differences(self, **kwds):
673
673
"""
674
674
return self .subsequence (1 , {1 : 1 , 0 : - 1 }, ** kwds )
675
675
676
+ @minimize_result
677
+ def _mul_ (self , other ):
678
+ r"""
679
+ Return the product of this `k`-regular sequence with ``other``,
680
+ where the multiplication is convolution.
681
+
682
+ INPUT:
683
+
684
+ - ``other`` -- a :class:`kRegularSequence`
685
+
686
+ - ``minimize`` -- (default: ``None``) a boolean or ``None``.
687
+ If ``True``, then :meth:`~RecognizableSeries.minimized` is called after the operation,
688
+ if ``False``, then not. If this argument is ``None``, then
689
+ the default specified by the parent's ``minimize_results`` is used.
690
+
691
+ OUTPUT:
692
+
693
+ A :class:`kRegularSequence`
694
+
695
+ EXAMPLES::
696
+
697
+ sage: Seq2 = kRegularSequenceSpace(2, ZZ)
698
+ sage: E = Seq2((Matrix([[0, 1], [0, 1]]), Matrix([[0, 0], [0, 1]])),
699
+ ....: vector([1, 0]), vector([1, 1]))
700
+ sage: E
701
+ 2-regular sequence 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, ...
702
+ sage: E * E
703
+ 2-regular sequence 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, ...
704
+
705
+ sage: o = Seq2.one_hadamard()
706
+ sage: E * o
707
+ 2-regular sequence 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, ...
708
+ sage: E * o == E.partial_sums(include_n=True)
709
+ True
710
+ sage: E * o == o * E
711
+ True
712
+ """
713
+ from sage .arith .srange import srange
714
+ from sage .matrix .constructor import Matrix
715
+ from sage .matrix .special import zero_matrix
716
+ from sage .modules .free_module_element import vector
717
+
718
+ P = self .parent ()
719
+ k = P .k
720
+
721
+ def tensor_product (left , right ):
722
+ T = left .tensor_product (right )
723
+ T .subdivide ()
724
+ return T
725
+
726
+ matrices_0 = {r : sum (tensor_product (self .mu [s ], other .mu [r - s ])
727
+ for s in srange (0 , r + 1 ))
728
+ for r in P .alphabet ()}
729
+ matrices_1 = {r : sum (tensor_product (self .mu [s ], other .mu [k + r - s ])
730
+ for s in srange (r + 1 , k ))
731
+ for r in P .alphabet ()}
732
+ left = vector (tensor_product (Matrix (self .left ), Matrix (other .left )))
733
+ right = vector (tensor_product (Matrix (self .right ), Matrix (other .right )))
734
+
735
+ def linear_representation_morphism_recurrence_order_1 (A , B ):
736
+ r"""
737
+ Return the morphism of a linear representation
738
+ for the sequence `z_n` satisfying
739
+ `z_{2n+r} = A_r z_n + B_r z_{n-1}`.
740
+ """
741
+ Z = zero_matrix (A [0 ].dimensions ()[0 ])
742
+
743
+ def blocks (r ):
744
+ upper = list ([A [s ], B [s ], Z ]
745
+ for s in reversed (srange (max (0 , r - 2 ), r + 1 )))
746
+ lower = list ([Z , A [s ], B [s ]]
747
+ for s in reversed (srange (k - 3 + len (upper ), k )))
748
+ return upper + lower
749
+
750
+ return {r : Matrix .block (blocks (r )) for r in P .alphabet ()}
751
+
752
+ result = P .element_class (
753
+ P ,
754
+ linear_representation_morphism_recurrence_order_1 (matrices_0 ,
755
+ matrices_1 ),
756
+ vector (list (left ) + (2 * len (list (left )))* [0 ]),
757
+ vector (list (right ) + (2 * len (list (right )))* [0 ]))
758
+
759
+ return result
760
+
676
761
@minimize_result
677
762
def partial_sums (self , include_n = False ):
678
763
r"""
0 commit comments