简体   繁体   English

如何将 function 作为参数传递

[英]How to pass a function as an argument

I would like to find an approximate value for the number pi = 3.14.. by using the Newton method.我想通过使用牛顿法找到数字pi = 3.14..的近似值。 In order to use it also for some other purpose and thus other function than sin(x) , the aim is to implement a generic function that will be passed over as an argument.为了将它也用于其他目的,以及其他 function 而不是sin(x) ,目的是实现一个通用的 function 作为参数传递。 I have an issue in passing a function as an argument into an other function.我在将 function 作为参数传递给另一个 function 时遇到问题。 I also tried lambda in different variations.我还尝试了不同变体的lambda The code I am showing below produces the error message: IndexError: list index out of range .我在下面显示的代码会产生错误消息: IndexError: list index out of range I will appreciate your help in solving this issue and eventually make any suggestion in the code which may not be correct.感谢您在解决此问题方面的帮助,并最终在代码中提出任何可能不正确的建议。 Thanks.谢谢。

from sympy import *
import numpy as np
import math

x = Symbol('x')
# find the derivative of f
def deriv(f,x):
    h = 1e-5 
    return (lambda x: (f(x+h)-f(x))/h)

def newton(x0,f,err):
    A = [x0]
    n = 1
    while abs(A[n]-A[n-1])<=err:
        if n == 1:
            y = lambda x0: (math.f(x0))
            b = x0-y(x0)/(deriv(y,x0))
            A.append(b)
            n += 1             
        else:
            k = len(A)
            xk = A[k]
            y = lambda xk: (math.f(xk))
            b = newton(A[k],y,err)-y(newton(A[k],y,err))/deriv(y,k)
            A.append(b)
            n += 1
    return A, A[-1]
print(newton(3,math.sin(3),0.000001)) 

I don't know why you use sympy because I made it without Symbol我不知道你为什么使用sympy因为我没有使用Symbol

At the beginning you have to calculate second value and append it to list A and later you can calculate abs(A[n]-A[n-1]) (or the same without n : abs(A[-1] - A[-2]) ) because it needs two values from this list.一开始你必须计算第二个值和 append 它到列表A然后你可以计算abs(A[n]-A[n-1]) (或者没有n相同: abs(A[-1] - A[-2]) ) 因为它需要这个列表中的两个值。

Other problem is that it has to check > instead of <= .另一个问题是它必须检查>而不是<=

If you want to send function sin(x) then you have to use math.sin without () and arguments.如果要发送 function sin(x) ,则必须使用不带()math.sin的 math.sin。

If you want to send function sin(3*x) then you would have to use lambda x: math.sin(3*x)如果你想发送 function sin(3*x)那么你必须使用lambda x: math.sin(3*x)

import math

def deriv(f, x, h=1e-5):
    return (f(x+h) - f(x)) / h

def newton(x0, f, err):
    A = [x0]

    x = A[-1]                     # get last value
    b = x - (f(x) / deriv(f, x))  # calculate new value
    A.append(b)                   # add to list

    while abs(A[-1] - A[-2]) > err:   # it has to be `>` instead of `<=`
        
        x = A[-1]                     # get last value
        b = x - (f(x) / deriv(f, x))  # calculate new value
        A.append(b)                   # add to list
        
    return A, A[-1]

# sin(x)
print(newton(3, math.sin, 0.000001))  # it needs function's name without `()`

# sin(3*x)
print(newton(3, lambda x:math.sin(3*x), 0.000001))

# sin(3*x)  # the same without `lambda`
def function(x):
    return math.sin(3*x)

print(newton(3, function, 0.000001))  

Result:结果:

([3, 3.1425464414785056, 3.1415926532960112, 3.141592653589793], 3.141592653589793)
([3, 3.150770863559604, 3.1415903295877707, 3.1415926535897936, 3.141592653589793], 3.141592653589793)

EDIT:编辑:

You may write loop in newton in different way and it will need <=您可以用不同的方式在牛顿中编写循环,它需要<=

def newton(x0, f, err):
    A = [x0]

    while True:
        
        x = A[-1]                     # get last value
        b = x - (f(x) / deriv(f, x))  # calculate new value
        A.append(b)                   # add to list
        
        if abs(A[-1] - A[-2]) <= err: 
            break
        
    return A, A[-1]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM