1.编写一个函数,能够实现对一个N阶的二维数组进行如下计算:函数的形参为一个N阶二阶数组,返回两个值,依次为该数组的主对角线元素之和、副对角线元素之和。
def diagonal_sum(arr):
n = len(arr)
main_sum = 0
minor_sum = 0
for i in range(n):
main_sum += arr[i][i]
minor_sum += arr[i][n-1-i]
return main_sum, minor_sum
2
自己编写一个函数,实现基于克莱姆法则求解的n元(n≤5)线性方程组,以三元线性方程组为例,整理成形式如下:
要求该函数的形参为上述方程组所有的系数构成的n行n+1列的数组M,返回值为方程组的解构成的列表或元组,矩阵M的行数由程序自己判断,不作为形参输入。
import numpy as np
def cramers_rule(M):
n = M.shape[0]
result = []
if n == 2: # 二元线性方程组
A = M[:, :-1]
b = M[:, -1]
D = np.linalg.det(A)
Dx = np.linalg.det(np.column_stack((b, A[:, 1])))
Dy = np.linalg.det(np.column_stack((A[:, 0], b)))
result.append(Dx/D)
result.append(Dy/D)
elif n == 3: # 三元线性方程组
A = M[:, :-1]
b = M[:, -1]
D = np.linalg.det(A)
Dx = np.linalg.det(np.column_stack((b, A[:, 1], A[:, 2])))
Dy = np.linalg.det(np.column_stack((A[:, 0], b, A[:, 2])))
Dz = np.linalg.det(np.column_stack((A[:, 0], A[:, 1], b)))
result.append(Dx/D)
result.append(Dy/D)
result.append(Dz/D)
else: # n >= 4,使用逆矩阵求解
A = M[:, :-1]
b = M[:, -1]
A_inv = np.linalg.inv(A)
x = np.dot(A_inv, b)
for i in range(n):
result.append(x[i])
return result
M = np.array([[1, 1, -1, 5],
[2, -1, 1, 3],
[1, 3, -2, 10]])
print(cramers_rule(M))
3
在第二题的基础上,编写一个函数判断平面上两直线的位置关系,如果两直线相交,调用第二题的函数求出交点坐标。假设平面两直线的分别表示为如下的一般式:
要求:(1)函数的返回值有两个,一个是表示位置关系的字符串,另一个是求出的交点坐标;(2)如果两直线平行、异面或重合,交点坐标设置为[nan,nan]。
代码:
def line_intersection(line1, line2):
# line1 和 line2 分别是表示两条直线的一般式
# 如 (a1*x + b1*y + c1 = 0) 和 (a2*x + b2*y + c2 = 0)
a1, b1, c1 = line1
a2, b2, c2 = line2
# 判断两个法向量是否平行
if abs(a1*b2 - a2*b1) < 1e-10:
# 判断两个法向量是否共线
if abs(a1/a2 - b1/b2) < 1e-10 and abs(c1/a2 - c2/a2) < 1e-10:
return "两直线重合", [float('nan'), float('nan')]
else:
return "两直线异面", [float('nan'), float('nan')]
else:
# 使用克莱姆法则求解交点坐标
M = np.array([[a1, b1], [a2, b2]])
b = np.array([-c1, -c2])
x, y = cramers_rule(np.column_stack((M, b)))
x = float(x)
y = float(y)
return "两直线相交", [x, y]
line1 = [1, 2, -3] # 对应式子为 x + 2y - 3 = 0
line2 = [2, 4, -5] # 对应式子为 2x + 4y - 5 = 0
print(line_intersection(line1, line2)
编写一个函数生成如下的范德蒙矩阵,要求函数的参数有两个,一个是矩阵中的
构成的列表或数组,另一个是最高幂次n-1中的n。
代码:
import numpy as np
def vander_matrix(x, n):
"""
生成范德蒙矩阵
参数:
x: list 或 array,用于构成范德蒙矩阵中的数组
n: int,要生成的范德蒙矩阵的最高幂次+1
返回值:
生成的范德蒙矩阵
"""
vander = np.zeros((len(x), n)) # 初始化范德蒙矩阵为全零矩阵
for i in range(len(x)): # 依次计算每一行的元素
for j in range(n): # 依次计算该行中的每一个元素
vander[i][j] = x[i] ** (n-1-j) # 根据公式计算相应的元素值
return vander
x = [1, 2, 3, 4] # 用于生成范德蒙矩阵的数组
n = 5 #生成范德蒙矩阵的最高幂次+1
vander = vander_matrix(x, n) # 生成范德蒙矩阵
for row in vander:
print('[', end=' ')
for elem in row:
print('{:>3}'.format(int(elem)), end=' ') # 对每个元素对齐,并指定宽度为3
print(']') # 换行并打印右括号,形成一个矩阵
编写一个函数,用于返回n阶行列式T中指定元素aij的代数余子式Aij的值,其定义为:
其中Mij为行列式T中把元素aij所在的第i行和第j列划去后,剩余的n-1阶行列式的值。函数的形参有两个,一个是行列式T,另一个是列表[i,j],用于指定元素aij的位置。
代码:
import numpy as np
def algebraic_cofactor(T, index):
i, j = index[0], index[1] # 提取指定元素的行列位置i和j
Mij = np.delete(np.delete(T, j, axis=1), i, axis=0) # 删除第i行和第j列,得到剩余的n-1阶行列式Mij
Aij = (-1) ** (i+j) * np.linalg.det(Mij) # 利用代数余子式的公式计算Aij的值
return Aij
T = np.array([[1, 3, -2], [0, -1, 4], [2, 3, 1]])
index = [1, 2]
Aij = algebraic_cofactor(T, index)
print(Aij) # 输出结果:-3.0