1
$\begingroup$

Paraphrasing, the problem I am trying to solve is the following. I am given two "matrix valued" sums

expr1 = Sum[c[i] M[i], {i, range1}]
expr2 = Sum[d[j] M[j], {j, range2}]

where the cs and ds are some coefficients and the Ms are some unspecified (symbolic) matrices. I would like to multiply these two sums, with the multiplication of two such matrices understood by me, i.e. specified by some function, let's call it "f". I am trying to do this efficiently. I do not know beforehand which matrices will appear, only that they have head M.

Defining an explicitly linear matrix multiplication works, but seems to be quite inefficient, at least in the way that I managed to come up with (my coefficients are further generic expressions).

Using Collect and Pattern matching instead, I managed to come up with the following

desiredfunction[a_, b_] := 
  Module[{c = Collect[a, M[_]], d = Collect[b, M[_]]},
   c[[0]] = List; d[[0]] = List;
   Outer[#1[[1 ;; -2]]*#2[[1 ;; -2]]*f[#1[[-1]], #2[[-1]]] &, c, d]//Flatten//Tr]

i.e. I explicitly turn the sums into lists of terms, and generate the outer product of the two lists, multiplying the coefficients and combine the matrices using "f", and finally adding everything together.

This does what I want it to, but I cannot shake the feeling that this is such an elementary kind of operation (combining two expressions written in the form coefficients*objects with a rule to combine the objects and coefficients) that there must be a better way to do this, maybe via in-built functions. Am I overlooking something obvious here?


For copy-paste into mathematica:

expr1 = Sum[c[i] M[i], {i, 1, 3}];
expr2 = Sum[d[i] M[i], {i, 2, 6}];

desiredfunction[a_, b_] := 
 Module[{c = Collect[a, M[_]], d = Collect[b, M[_]]},
  c[[0]] = List;
  d[[0]] = List;
  Outer[#1[[1 ;; -2]]*#2[[1 ;; -2]]*f[#1[[-1]], #2[[-1]]] &, c, d] // 
    Flatten // Tr]

desiredfunction[expr1, expr2]
$\endgroup$

1 Answer 1

1
$\begingroup$
ClearAll[desiredF]
desiredF = Total[Tuples[{##}] /. {a_ b_M, c_ d_M} :> a c f[b, d]] &;

desiredF[expr1, expr2] == desiredfunction[expr1, expr2]
  True
$\endgroup$
1
  • $\begingroup$ That's great, thanks a lot! This does need the argument to be in a form where it is collected over M (which was the case for what I wrote above), but I guess that can be easily fixed by applying Collect[#,M[_]]&/@ to the argument of Tuples. $\endgroup$
    – Stijn
    Apr 9, 2020 at 15:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.