非标量标量投影

时间:2014-02-20 03:53:24

标签: prolog

我需要为列表实现非重复的标量投影。 List是Prolog中的递归数据结构。这也可能吗?我尝试实现如下:

scalar(T,U,S) :- scalar(T,U,S,0).
scalar([X|T],[Y|U],S,M):- repeat,M1 = M + S, S1=X*Y,fail.

repeat.
repeat:-repeat.

但这是错误的,因为我没有通过M1 S1。

C编码后很难理解。 Prolog迭代子句是递归的,但带有“Tail”递归。这意味着我们在递归结束时有正确的答案。 Recursive子句需要bactrack才能得到答案。

非递归方法

scal(L1,L2,R):- scal(L1,L2,0,R).
scal([A|L1],[B|L2],F,R):- F1 is (F + A*B),scal(L1,L2,F1,R).
scal([],[],F,F).

递归方法

scal([],[],0).
scal([A|L1],[B|L2],R) :- scal(L1, L2, R1), R is (R1+A*B).

1 个答案:

答案 0 :(得分:2)

假设你指的是矢量A到B的标量投影,由下式给出:

s = (A dot B)/|B|

然后你可以这样做:

scalar(A, B, S) :-
    dot_product(A, B, P),
    magnitude(B, M),
    S is P / M.

dot_product(A, B, P) :-
    maplist(mult, A, B, M),
    sum_list(M, P).               % In SWI prolog, this would be sumlist

magnitude(V, M) :-
    maplist(sq, V, S),            % Or maplist(mult, V, V, S)
    sum_list(S, SumS),
    M is sqrt(SumS).

mult(X, Y, M) :- M is X * Y.
sq(X, S) :- S is X * X.