不动点迭代法求函数根(非线性方程求解)

问题描述

在[a,b]区间内寻找方程x**5-2*x-1=0的根的初始近似值位置,确定不动点迭代的初始点(可能有多个),然后使用不动点迭代法求方程的根(可能有多个根)。前后两次迭代的差的绝对值小于delta后停止迭代。

输入形式

在屏幕上输入3个数,依次为区间左端点值a、右端点值b和所求根的精度值。各数间都以一个空格分隔。根据输入的所求根的精度值可求得delta.

输出形式

每一行输出一个根(精确到小数点后3位)

样例1输入

-1.2 1.5 3

样例1输出

-1.000
-0.519
1.291

样例1说明

输入:左端点a值为-1.2,右端点b值为1.5,前后两次迭代的差的绝对值小于delta=10**(-3)后停止迭代。输出:从小到大顺序输出三个根的值。

代码

import numpy as np

def f(x):
    return x ** 5 - 2 * x - 1

def g1(x):
    return (x**5-1)/2

def g2(x):
    result = (abs(2 * x + 1))**(1 / 5)
    if (2 * x - 1) < 0:
        return -result
    return result

def getEpsilon(x, epsilon):
    maxY = minY = x[0]
    for each in x:
        maxY = max(f(each), maxY)
        minY = min((f(each), minY))
    epsilon = (maxY - minY) * epsilon
    return epsilon

def getInitialVal(x, N, step, epsilon):
    initalVal = []
    for i in range(N + 1):
        y1, y2, y3 = f(x - step), f(x), f(x + step)
        if (y1 * y2 < 0) and (i != 0):
            initalVal.append((x + x - step) / 2)
        if ((y2 - y1) * (y3 - y2) < 0) and (abs(y2) < epsilon):
            initalVal.append(x)
        x += step

    return initalVal

def findFixedPoint(initalVal, delta,epsilon):
    points = []
    for each in initalVal:
        if (abs(g1(each)) < 1):
            points.append(iteration(each, g1, delta,epsilon))
        else:
            points.append(iteration(each, g2, delta,epsilon))
    return points

def iteration(p1, g, delta,epsilon):
    while True:
        p2 = g(p1)
        err =abs(p2-p1)
        relerr = err/(abs(p2)+epsilon)
        if err<delta or relerr<delta:
            return p2
        p1 = p2
                    
def main():
    a, b, c = input().split(' ')
    a = float(a)
    b = float(b)
    c = int(c)
    delta = 10 ** (-c)
    N = 8
    epsilon = 0.01
    step = (b - a) / N
    x = np.arange(a, b + epsilon, epsilon)
    
    epsilon2 = getEpsilon(x,epsilon)
    initalVal = getInitialVal(a, N, step, epsilon2)
    ans = findFixedPoint(initalVal, delta,epsilon)

    for each in ans:
        print('%.3f' % each)
        
if __name__ == '__main__':
    main()
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值