0.WARNINGS
本文章主要适用于计算方法代码的实现参考,由于本人是python究极小白,为了实验课速成了一些内容,因此会包含较多的暴力解法orz,如有代码错误、可优化的地方欢迎各位大佬指出,感激不尽。
此外,本人制作本文的目的,主要是懒的将代码保存在本地中,且博客方便个人的复习。
非线性方程和优化主要包含的内容有:二分法;普通迭代法;牛顿迭代法;弦截法(单点&两点);
1.
用二分法求方程 xlnx = 1 在[0.5 , 4] 的近似根,使函数值误差不超过0.001,或有根区间长度不超过0.001。输出保留3位小数。
import math
a=0.5
b=4
def f(x):
return x*math.log(x)-1
while 1:
mid=a / 2 + b / 2
if math.fabs(f(mid)) < 0.001 or math.fabs(a - b) < 0.001:
ret = mid
break
else:
if f(mid)*f(a)<=0:
b=mid
else:
a=mid
print("%.3f" % ret)
2.
用迭代法求方程 x= e –x在x=0.5附近的一个根,结果的精度要求0.00001。输出保留4位小数
import math
def f(x):
return math.e**(-x)
x=0.5
while 1:
temp=x
x=f(x)
if math.fabs(temp-x)<0.00001:
break
print("%.4f" % x)
3.
用迭代法求函数f(x)=x-lnx-2在区间(2,+∞)内的零点,误差是0.00001,最高迭代次数是500次。输出保留三位小数。
import math
def f(x):
return math.log(x)+2
x=2
cnt=0
while cnt<=500:
temp=x
x=f(x)
if math.fabs(temp-x)<0.00001:
break
else:
cnt += 1
print("%.3f" % x)
4.
用迭代法求方程3 x2- e x=0在[3,4]区间的一个根,结果的精度要求0.0001。输出保留3位小数
import math
def f(x):
return math.log(3*x**2)
x=3.5
while x>=3 and x<=4:
temp=x
x=f(x)
if math.fabs(temp-x)<0.00001:
break
print("%.3f" % x)
5.
输出x^3-x^2-1=0的有根区间,并在该有根区间内通过二分法找到其具有4位有效数字的根。
注意:有根区间的长度为0.1,输出到小数点后1位。
例如:
输出:
3.5(有根区间左端点)
3.6(有根区间右端点)
3.578(根)
(此非该题的正确解,只是示例)
import math
def f(x):
return pow(x,3)-pow(x,2)-1
# 容易发现f(1)<0 and f(2)>0
i=1
while i<2:
i+=0.1
if f(i)>0:
b=i
a=i-0.1
break
print("%.1f" % a)
# (有根区间左端点)
print("%.1f" % b)
# (有根区间右端点)
while 1:
mid=a/2+b/2
if math.fabs(f(mid))<0.001 or math.fabs(a-b)<0.001:
ret=mid
break
else:
if f(mid)*f(a)<=0:
b=mid
else:
a=mid
print("%.3f" % ret)
# (根)
6.
设函数f(x)=sinx-(x/2)2,牛顿法求函数的根。初始值是2.0,误差是0.0001,最高迭代次数是500次。输出保留三位小数。
import math
# 设函数f(x)=sinx-(x/2)2,牛顿法求函数的根。
# 初始值是2.0,误差是0.0001,最高迭代次数是500次。输出保留三位小数。
def f(x):
return math.sin(x)-(x/2)**2
def f1(x):
return math.cos(x)-x/2
def fai(x):
return x-f(x)/f1(x)
cnt=0
e=0.0001
myx=2.0
while cnt<500:
temp=fai(myx)
if math.fabs(temp-myx)<e:
myx=temp
break
else:
myx=temp
print("%.3f" % myx)
7.
用牛顿迭代法求解x2=A的根,要求误差小于0.00001
输入:A
输出:迭代序列值 迭代次数(从初值x0=A开始迭代)迭代值保留5位有效数字
例如:
输入: 7
输出: 4.00000 1
2.87500 2
2.65489 3
2.64577 4
2.64575 5
2.64575 6
import math
# 用牛顿迭代法求解x2=A的根,要求误差小于0.00001
A=float(input())
def fai(x,A):
return x-(x**2-A)/(2*x)
e=0.00001
myx=A
cnt=int(0)
while 1:
temp=fai(myx,A)
if math.fabs(temp-myx)<e:
myx=temp
cnt+=1
break
else:
myx=temp
cnt+=1
print("%.5f %d" % (myx, cnt))
print("%.5f %d" % (myx,cnt))
8.
对非零实数a,采用牛顿迭代法设计一个不用除法运算求解1/a的计算程序。误差小于10-5 初值x0=0.01
输入:a
输出:迭代序列 (保留5位小数) 迭代次数
例如:
输入:7
输出:
0.01930 1
0.03599 2
0.06292 3
0.09812 4
0.12885 5
0.14148 6
0.14284 7
0.14286 8
0.14286 9
import math
import sys
# 对非零实数a,采用牛顿迭代法设计一个不用除法运算求解1/a的计算程序。
# 误差小于10-5 初值x0=0.01
a=float(input())
if a==0:
print("a cannot be zero")
sys.exit()
def f(x,a):
return 1/x-a
def f1(x,a):
return -1/(x**2)
def fai(x,a):
return x-f(x,a)/f1(x,a)
e=0.00001
myx=0.01
cnt=int(0)
# fx=1/x
while 1:
temp=fai(myx,a)
if math.fabs(temp-myx)<e:
myx=temp
cnt+=1
break
else:
myx=temp
cnt+=1
print("%.5f %d" % (myx,cnt))
print("%.5f %d" % (myx,cnt))
9.
在重根数未知情况下,求解非线性方程f(x)=e^(2x)-1-2x-2x^2的误差小于0.0001的根。
输入迭代初始值,输出每次的近似解和迭代次数(空格分隔),近似解保留小数点后5。
例如:
输入:2
输出:
-2.47756 1
-0.26450 2
-0.00996 3
-0.00002 4
0.00000 5
import math
import sys
def f(x):
return math.e**(2*x)-1-2*x-2*x**2
def f1(x):
return 2*math.e**(2*x)-2-4*x
def f2(x):
return 4*math.e**(2*x)-4
def fai(x):
return x-f1(x)*f(x)/(f1(x)**2-f(x)*f2(x))
e=0.0001
cnt=int(0)
myx=float(input())
while 1:
temp=fai(myx)
if math.fabs(temp-myx)<e:
myx = temp
cnt += 1
break
else:
myx=temp
cnt+=1
print("%.5f %d" % (myx,cnt))
print("%.5f %d" % (myx,cnt))
10.
单点弦截法求f(x)=x-sinx-1在[1,2]区间解,误差为0.0001
输入格式:
a的值 b的值 (a为定点)
输出格式:
根(保留4位小数)迭代次数
输入:
1 2
输出:
1.9346 12
import math
inp = input().split(' ')
a = float(inp[0])
b = float(inp[1])
e=0.0001
cnt=int(1)
def f(x):
return x-math.sin(x)-1
def fai(x,x0):
return x-f(x)/(f(x)-f(x0))*(x-x0)
# x0=a
while 1:
if math.fabs(b-fai(b,a))<e:
b+=e
break
else:
b=fai(b,a)
cnt+=1
print("%.4f %d" % (b,cnt))
11.
用双点弦法求方程 xex-1=0 在x=0.5附近的根。初始两点分别是0.3, 0.8, 最高迭代次数是500次,误差是0.0001。输出后值,并保留三位小数。
import math
# 用双点弦法求方程 xex-1=0 在x=0.5附近的根。初始两点分别是0.3, 0.8,
# 最高迭代次数是500次,误差是0.0001。输出后值,并保留三位小数。
def f(x):
return x*math.e**x-1
def fai(xk,x):
return xk-f(xk)/(f(xk)-f(x))*(xk-x)
# xk=b,x=a
e=0.0001
a=0.3
b=0.8
cnt=1
myx=0
while cnt<=500:
if math.fabs(fai(b,a)-myx)<e:
myx = fai(b, a)
# output the latter one?
break
else:
myx=fai(b,a)
a=b
b=myx
cnt+=1
print("%.3f" % myx)
12.
对于f(x)=x3-3x-1用三种方法求解。输入两个初值,x0和x1,其中xo作为牛顿法的初值进行迭代求解,x0为单点弦截的不动点和x1作为初值迭代求解,x0和x1作为双点弦截的不动点迭代求解,误差小于0.00001。输出迭代值和迭代次数,迭代值保留5位有小数。
例如:
输入:
1.5 3
输出:
2.06667 1 (牛顿迭代结果)
1.90088 2
1.87972 3
1.87939 4
1.87939 5
1.66667 1(单点弦截迭代结果)
1.96933 2
1.84938 3
1.89032 4
1.87552 5
1.88077 6
1.87889 7
1.87956 8
1.87932 9
1.87941 10
1.87938 11
1.87939 12
1.87938 13
1.66667 1(双点弦截迭代结果)
1.76613 2
1.90130 3
1.87744 4
1.87935 5
1.87939 6
1.87939 7
import math
inp = input().split(' ')
x0 = float(inp[0])
x1 = float(inp[1])
e=0.00001
def f(x):
return x**3-3*x-1
def f1(x):
return 3*x**2-3
def fai(x):
return x-f(x)/f1(x)
def singlefai(x,x0):
return x-f(x)/(f(x)-f(x0))*(x-x0)
# x0=a
# Newton
newtoncnt=0
myx=x0
while 1:
temp=fai(myx)
if math.fabs(temp-myx)<e:
myx=temp
newtoncnt+=1
break
else:
myx=temp
newtoncnt += 1
print("%.5f %d" % (myx,newtoncnt))
print("%.5f %d" % (myx,newtoncnt))
# print("single")
# single point
singlecnt=0
b=x1
a=x0
while 1:
if math.fabs(b-singlefai(b,a))<e:
b+=e
singlecnt += 1
break
else:
b=singlefai(b,a)
singlecnt+=1
print("%.5f %d" % (b,singlecnt))
print("%.5f %d" % (b,singlecnt))
def doublefai(xk,x):
return xk-f(xk)/(f(xk)-f(x))*(xk-x)
# xk=b,x=a
# double point
#print("double point")
doublecnt=0
b=x1
a=x0
myx=2 # ? not sure
while 1:
if math.fabs(doublefai(b,a)-myx)<e:
myx=doublefai(b,a)
doublecnt += 1
break
else:
myx=doublefai(b,a)
a=b
b=myx
doublecnt+=1
print("%.5f %d" % (myx,doublecnt))
print("%.5f %d" % (myx,doublecnt))