2017-11-01 43 views
0

転置行列A^tを持つ行列Aの積を求める必要があるので、3番目の行列B = A * A^tを求める必要があります。 例:A=[[1,2],[3,4]](その後A^t=[[1,3],[2,4]])はB=[[5,11],[11,25]] (各サブリストは、行列の行である)Prolog - 転置行列の乗算

まず私はA^Tの列がためだからAの行であるように、これは簡単であるべきだと思いますA^Tの列とAの行の内積は、私がこれを使用することができると思う:

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

私もclpfd場合や、他を使用することはできません。

私は立ち往生しており、次に何をすべきか分かりません。

+0

あなたは既に単一の要素を計算する方法を知っています。だから、あなたはあなたの 'sum' n^2回を計算する述語を書かなければなりません。 –

+0

つまり、マトリックスの2つの行ごとに。 –

答えて

0

マトリックスAの行のドット積を使用することができます。おそらく、sum/3ではなく、この関数の名前をdot_product/3とする方がよいでしょう。

残っている唯一のタスクは、Aの2行ごとにこの内積を計算することです。そうはI、BのJ番目の要素は、の内積 I Jあります。

我々は、とBの行を計算する述語を構築することができる。さらに、我々は、別のmaplist/3transprod/3を算出することができる

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

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

または完全に:

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). 

これは、その後生成します

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

コードはまだ最もエレガントではなく、また IJ B は、私たちはの半分を保存することができますB JIに等しいので、それは、非常に効率的です作業。さらに、行列の要素が欠落している場合、製品を計算することはできません。私は運動としてこれを残します。