我有一些代码应该通过泰勒级数定义找到 sin(15°)
的近似值,并将其与内置函数 sin
进行比较。
我有不同的结果。
X
- 弧度值 R
- 系列和 Eps
- 精度值 S
- 签署F
- N
XN
- X
的值的 N
N
- 功率,1,3,5 ... % base
sin_taylor(_,R,Eps,S,FN,XN,_) :-
abs(S*XN/FN) < Eps,
R = 0, !.
% step
sin_taylor(X, R, Eps, S, FN, XN, N) :-
S1 = S*(-1),
N1 = N+1,
FN1 = FN*(2*N+2)*(2*N+3),
XN1 = XN*X*X,
sin_taylor(X,R1,Eps,S1,FN1,XN1,N1),
R is R1+S*XN/FN.
% auxiliary predicate to supply parameters to the main one
sin(X,R,Eps) :-
sin_taylor(X,R1,Eps,-1,1,X*X,1),
R is 1+R1.
控制台中的结果:
?- X is 15*(pi / 180), sin(X,R,0.0001).
X = 0.2617993877991494,
R = 0.931695959721973.
?- X is 15*(pi / 180), R0 is sin(X).
X = 0.2617993877991494,
R0 = 0.25881904510252074.
最佳答案
无法在您的代码中识别出正确的第 n 项……阶乘计算隐藏在哪里?请记住,早期优化是软件工程中所有弊端的根源:)
Wikipedia 中列出的解决方案的直接翻译使我找到了这段代码(好吧,应该在谓词名称中引用 Maclaurin 和 Taylor...)
:- module(sin_taylor,
[sin/3
,rad_deg/2
,fact/2
]).
% help predicate to give parameters to the main one
sin(X,R,Eps):-
syn_taylor(X,Eps,0,R).
syn_taylor(X,Eps,N,R) :-
S is -1**N,
T is 2*N+1,
fact(T,D),
E is X**T,
Q is S*E/D,
( Q < Eps
-> R = Q
; M is N+1,
syn_taylor(X,Eps,M,R1),
R is Q+R1
).
rad_deg(R,D) :-
var(R) -> R is D*(pi / 180).
% tbd compute D from R
fact(N,F) :- N>0 -> N1 is N-1, fact(N1,F1), F is N*F1 ; F=1.
这给出了合理的结果:
?- rad_deg(X,15),sin(X,R,0.0001).
X = 0.2617993877991494,
R = 0.2588088132736575.
?- rad_deg(X,15),R0 is sin(X).
X = 0.2617993877991494,
R0 = 0.25881904510252074.
关于prolog - 泰勒级数的罪的近似值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57624595/