我有一些代码应该通过泰勒级数定义找到 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/

    10-13 07:58