I have a matrix where each entry is a polynomial in the same variable, say a, all with numerical coefficients. The simplest example is:


Now I want to extract the coefficients of the powers of a. Performance is important, where the typical matrix size is at most a few hundred by a few hundred, and the order of the polynomial at most say 5. Readability of the code is also important.

Consider a more realistic M:

n = 100; 
maxp = 4; 
mat = Sum[a^i*RandomReal[{-1*1, 1}, {n, n}], {i, 0, maxp}]; 

Two standard ways of calculating the coefficients are:

coeffs1 = {mat /. a -> 0}~Join~Table[Coefficient[mat, a, n], {n, 1, maxp}];//RepeatedTiming
coeffs2 = CoefficientList[mat, a] //Transpose[#, {2, 3, 1}] &;//RepeatedTiming
coeffs1 == coeffs2

The second method is significantly faster, and this is what I would like to use.

However, in the matrices I'm concerned with it often happens that the highest power of a doesn't occur in every entry, e.g.

mat2 = mat + a^(maxp+1) IdentityMatrix[n];

In this case, the first method still works correctly, with coefficients 0 at appropriate entries. However, the second method no longer works, because instead of a 0 in the last element of the list of coefficients corresponding to one entry, the last element is omitted.

We could simply find all lists which are too short and add zeroes to them to make them of the right length, but this is not very efficient:

coeffs3 = {mat2 /. a -> 0}~Join~Table[Coefficient[mat2, a, n], {n, 1,maxp}]; // RepeatedTiming
coeffs4 = CoefficientList[mat2, a] /. list_List /; Length[list] < 6 :>list~Join~
   Table[0, {6 - Length[list]}] // Transpose[#, {2, 3, 1}] & // Most;// RepeatedTiming
coeffs3 == coeffs4

It is still faster than the first method, but considerably slower than the previous case.

So the question is, is there a more efficient (but still relatively simple and readable) way to do this?

  • 3
    $\begingroup$ Unless I'm missing something, I believe this should answer your question. $\endgroup$
    – rcollyer
    Commented Sep 6, 2016 at 15:30
  • $\begingroup$ @rcollyer Ah yes, I hadn't seen that. PadRight, in combination with CoefficientList, was exactly what I was looking for, thanks. $\endgroup$
    – Jansen
    Commented Sep 6, 2016 at 16:06