我想弄清楚为什么上面的错误出现在我的代码。程序假定在给定两个输入参数的情况下,使用Newton Raphson方法查找一个4杆连杆的连杆位置。
错误发生在这一行
g1 = L1 * np.cos(theta) + L2 * np.cos(alpha) - L3
提前感谢您的帮助。
import numpy as np
L1=1
L2=1.5 * L1
theta = 40 * np.pi / 180
#initial guesses
L3 = 1.5
alpha = 30 * np.pi / 180
epsilon = 1
n = 0
while epsilon > 0.0001:
g1 = L1 * np.cos(theta) + L2 * np.cos(alpha) - L3
dg1dalpha = -L2 * np.sin(alpha)
dg1dL3 = -1;
g2 = L1 * np.sin(theta) - L2 * np.sin(alpha)
dg2dalpha = -L2 * np.cos(alpha);
dg2dL3 = 0
J = np.array([[dg1dalpha, dg1dL3], [dg2dalpha, dg2dL3]])
s = np.array([[alpha], [L3]]) - J/np.array([[g1], [g2]])
epsilon_alpha = abs(s[0] - alpha)
epsilon_L3 = abs(s[1] - L3)
epsilon = max(epsilon_alpha.all, epsilon_L3.all)
alpha = s[0]
L3 = s[1]
n = n + 1
print(n, alpha, L3)
在Python2.7中,在循环开始时添加print('alpha',alpha)
会产生:
('alpha', 0.5235987755982988)
('alpha', array([ 1.85083849, 2.29325173]))
('alpha', array([[array([ 1.98227296, 1.95343536]), 1.7138098231972174],
[array([ 1.81303794, 1.7604074 ]), 2.2932517265367176]], dtype=object))
Traceback (most recent call last):
File "stack32444132.py", line 17, in <module>
g1 = L1 * np.cos(theta) + L2 * np.cos(alpha) - L3
AttributeError: 'numpy.ndarray' object has no attribute 'cos'
所以错误是由调用np.cos(alpha)
引起的,其中alpha
是一个对象数组。alpha
为(2,2)
;第一列包含长度为2的数组;第二个包含浮点数
所以在循环的某个点,你正在添加或连接不同长度的数组或列表。
s = np.array([[alpha], [L3]]) - J/np.array([[g1], [g2]])
alpha = s[0]
添加更多的打印(s
之前)
('J', (2, 2), dtype('float64'))
('alpha', 0.5235987755982988)
('L3', 1.5)
....
('J', (2, 2), dtype('O'))
('alpha', array([ 1.85083849, 2.29325173]))
('L3', array([-10.61649234, 1.5 ]))
在第二个循环中,J
从一个包含浮点数的2x2矩阵变为一个包含对象的2x2矩阵。
Python3在第一次遇到epsilon = max(epsilon_alpha.all, epsilon_L3.all)
表达式时抛出一个错误。epsilon_alpha.all
是一个方法;epsilon_alpha.all()
是一个布尔值。但是,当epsilon_alpha
变成数组时,即使这样也会产生错误。
OK,这个循环运行(alpha
仍然是一个标量);它不会停止,大概是因为epsilon
没有变得足够小;但是我把它留给你。
while epsilon > 0.0001:
# print('alpha', alpha)
g1 = L1 * np.cos(theta) + L2 * np.cos(alpha) - L3
dg1dalpha = -L2 * np.sin(alpha)
dg1dL3 = -1;
g2 = L1 * np.sin(theta) - L2 * np.sin(alpha)
dg2dalpha = -L2 * np.cos(alpha);
dg2dL3 = 0
J = np.array([[dg1dalpha, dg1dL3], [dg2dalpha, dg2dL3]])
print('J', J.shape,J.dtype) # (2,2) floats
s = np.array([[alpha], [L3]]) - J/np.array([[g1], [g2]])
s = s[:,0] # fudge to turn (2,2) array into a (2,) array
epsilon_alpha = abs(s[0] - alpha)
epsilon_L3 = abs(s[1] - L3)
epsilon = max(epsilon_alpha, epsilon_L3)
# max on 2 scalars is ok
alpha = s[0] # scalar
L3 = s[1] # scalar
n = n + 1
问题的根源在
s = np.array([[alpha], [L3]]) - J/np.array([[g1], [g2]])
如果alpha
和L3
是标量,则np.array([[alpha], [L3]])
是(2,1)
。np.array([[g1], [g2]])
也是。但由于J
是(2,2),s
也是(2,2)。但是你一直在使用s[0]
和s[1]
,显然假设s
是'(2,)。
s = s[:,0]
使s
a(2,),所以其余的代码工作。由于epsilon
不收敛,这可能是错误的修复。
我可以强调一下——在开发numpy
代码时,要密切注意数组形状。如果形状是错误的,你会得到这样的错误。根据我的经验,获得正确的形状是调试工作的80%。