このディレクトリの索引
#  
#  行列の掛算
#  

行列の掛算(L1,L2,X) :-
        転置(L2,L4),
        行列の掛算_1(L1,L4,X).

行列の掛算_1([],_,[]) :-!.
行列の掛算_1([A|R1],L,[S1|R3]) :-
        行列の掛算_2(A,L,S1),
        行列の掛算_1(R1,L,R3).


行列の掛算_2(_,[],[]) :-!.
行列の掛算_2(A,[B|R2],[C|R3]) :-
        行列の掛算_3(A,B,C),
        行列の掛算_2(A,R2,R3).

行列の掛算_3([],[],0) :-!.
行列の掛算_3([A|R1],[B|R2],S) :-
        分数を含む掛算(A,B,S1),
        行列の掛算_3(R1,R2,S2),
        分数を含む加算(S1,S2,S),!.

分数を含む加算(A1 / A2,B1 / B2,C) :-
        S1 is A1 * B2 + A2 * B1,
        S2 is A2 * B2,
        約分(S1 / S2,C),!.
分数を含む加算(A1 / A2,B,C) :-
        S1 is A1 + A2 * B,
        約分(S1 / A2,C),!.
分数を含む加算(A,B1 / B2,C) :-
        S1 is B1 + B2 * A,
        約分(S1 / B2,C),!.
分数を含む加算(A,B,C) :-
        C is A + B.

分数を含む掛算(A1 / A2,B1 / B2,C) :-
        S1 is A1 * B1,
        S2 is A2 * B2,
        約分(S1 / S2,C),!.
分数を含む掛算(A1 / A2,B,C) :-
        S1 is A1 * B,
        約分(S1 / A2,C),!.
分数を含む掛算(A,B1 / B2,C) :-
        S1 is B1 * A,
        約分(S1 / B2,C),!.
分数を含む掛算(A,B,C) :-
        C is A * B.

約分(B / A,X) :-
        最大公約数(B,A,C),
        _分子 is B // C,
        _分母 is A // C,
        約分の二(_分子,_分母,X),!.

約分の二(_分子,1,_分子) :- !.
約分の二(_分子,1.0,_分子) :- !.
約分の二(_分子,_分母,_分子 / _分母).

最大公約数(M,N,X) :-
        最大公約数をユークリッドの互除法で求める(M,N,X),!.

最大公約数をユークリッドの互除法で求める(M,N,N) :-
        0 is M mod N,!.
最大公約数をユークリッドの互除法で求める(M,N,X) :-
        Mod is M mod N,
        最大公約数をユークリッドの互除法で求める(N,Mod,X).

転置([],[],[]) :- !.
転置([[A|R1]|R2],[R1|R3],[A|R4]) :-
        転置(R2,R3,R4).

転置([[]|_],[]) :- !.
転置(L,[L1|R2]) :-
        転置(L,L2,L1),
        転置(L2,R2).