0

I need to find the product of the matrix A with its transpose A^t, so I should get a third matrix B=A*A^t. Example: A=[[1,2],[3,4]] (then A^t=[[1,3],[2,4]]) so B=[[5,11],[11,25]] (each sub list is a row of the matrix)

Firstly I think that this should be easier as the columns of A^t are the rows of A. So for the dot product of the row of A with the column of A^t I think I can use this:

sum([M|Ms],[N|Ns],Sum) :-
    sum(Ms,Ns,S),
    Sum is S+M*N.
 sum([],[],0).

I also can't use clpfd or if-else.

I've been stuck and don't know what to do next.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
math123
  • 21
  • 1

1 Answers1

0

It is correct that you can use the dot-product of the rows of matrix A for this. Although you probably better name this function dot_product/3 instead of sum/3.

The only task that is left, is to calculate this dot product for every two rows in A. So the i,j-th element of B is the dot product of Ai and Aj.

We can construct a predicate that calculates a row of B with:

transprod_row(A, AI, Row) :-
    maplist(dot_product(AI), A, Row).

Furthermore we can then calculate the transprod/3 with another maplist/3:

transprod(A, B) :-
    maplist(transprod_row(A),A,B).

or in full:

dot_product([],[],0).
dot_product([M|Ms],[N|Ns],Sum) :-
    dot_product(Ms,Ns,S),
    Sum is S+M*N.

transprod_row(A, AI, Row) :-
    maplist(dot_product(AI), A, Row).

transprod(A, B) :-
    maplist(transprod_row(A),A,B).

This then generates:

?- transprod([[1,2],[3,4]],B).
B = [[5, 11], [11, 25]].

The code is not yet the most elegant, nor is it very efficient, since Bij is equal to Bji so we can save half of the work. Furthermore if elements in the matrix are missing, then we can not calculate the product. I leave this as an exercise.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555