2
votes

I'm trying to perform matrix polynomial multiplication of the type:

(A_1+A_2*y)*(B_1+B_2*y+B_3*y^2)

where y is the variable, all the A_i are constant matrices of the same size and all the B_i are constant matrices of the same size, and the matrix multiplication of the form A_i*B_i makes sense. The matrices A_i and B_i are known and specified by the user.

Formally the multiplication should result in C_1+C_2*y+C_3*y^2+C_4*y^3 and I would like to know the C_i. In MATLAB, if the A_i and B_i are scalars, one could use 'conv'. However, if they are not scalars, the problem is not as easy. I would like to know if there is a simple way (analogous to 'conv') of doing this with matrices in MATLAB: given the A_i and B_i I would like to know the C_i? Of course, I'd like this in a general sense (univariate matrix polynomials of any degree), and would highly want to avoid using the symbolic toolbox.

2
I though I understood your question, but in fact is not quite clear. What do you want to do with the matrices A_1, A_2 and so on? Do you want them to be scalars? Subreferences from a matrix? What have you tried?Werner
@Werner Yes, an example would have been illuminating. What he wants is an equivalent to the scalar conv, an example: a = [1,1]; % <-> 1+1x, b = [1,1]; % <-> 1+1x, c = conv(a,b); % = [1,2,1] <-> (1+1x)*(1+1x) = 1+2x+1x^2. Take a look at the end of my "Test by" code to understand what he is talking about :-)matheburg

2 Answers

1
votes

It's probably not the best solution, but you could reimplement conv for matrices, e.g.:

function C = convMat(A,B)
    nA = size(A,3);
    nB = size(B,3);
    n = nA + nB - 1;
    C = zeros([size(A,1),size(B,2),n]);
    for k = 1:n
        for j = max(1,k+1-nB):min(k,nA)
            C(:,:,k) = C(:,:,k) + A(:,:,j)*B(:,:,k-j+1);
        end
    end

For your interest: Another (worse?) implementation:

function C = convMat2(A,B)
    n = size(A,3) + size(B,3) - 1;
    C = zeros([size(A,1),size(B,2),n]);
    for mA = 1:size(A,1)
        for mB = 1:size(B,2)
            for l = 1:size(A,2) % = size(B,1)
                vA = A(mA,l,:);
                vA = vA(:);
                vB = B(l,mB,:);
                vB = vB(:);
                C(mA,mB,:) = C(mA,mB,:) + reshape(conv(vA,vB),[1,1,n]);
            end
        end
    end

Test by:

% matrix example
A(:,:,1) = rand(3,3); % A1
A(:,:,2) = rand(3,3); % A2
B(:,:,1) = rand(3,4); % B1
B(:,:,2) = rand(3,4); % B2
B(:,:,3) = rand(3,4); % B3

C1 = convMat(A,B);
C2 = convMat2(A,B);

% test
x = rand(1,1);
(A(:,:,1) + A(:,:,2)*x) * (B(:,:,1) + B(:,:,2)*x + B(:,:,3)*x^2)
C1(:,:,1) + C1(:,:,2)*x + C1(:,:,3)*x^2 + C1(:,:,4)*x^3
C2(:,:,1) + C2(:,:,2)*x + C2(:,:,3)*x^2 + C2(:,:,4)*x^3

I am sure it is possible to optimize convMat.

0
votes

Easy enough, using my sympoly toolbox, found on the file exchange. (Does the fact that this avoids the symbolic TB, while using my own sympoly TB invalidate the answer? Only you can decide that.) I'll give an example, with the matrices being fairly non-creatively built.

sympoly y

A_1 = rand(2);
A_2 = rand(2);
B_1 = rand(2);
B_2 = rand(2);
B_3 = rand(2);

The result is a 2x2 matrix of symbolic polynomial elements, since addition, multiplication and matrix multiplication are all defined for the sympoly class.

(A_1+A_2*y)*(B_1+B_2*y+B_3*y^2)
ans =
Sympoly array has size = [2  2]

Sympoly array element [1  1]
    0.88896 + 0.88074*y + 0.87653*y^2 + 0.33102*y^3
Sympoly array element [2  1]
    0.87079 + 1.2145*y + 1.0628*y^2 + 0.69004*y^3
Sympoly array element [1  2]
    0.64143 + 0.78816*y + 0.67242*y^2 + 0.2091*y^3
Sympoly array element [2  2]
    0.64582 + 1.0162*y + 0.78167*y^2 + 0.4313*y^3