鉴于优化问题(1)如下所示,其中p_i
分别给出了p'_i
,w_ji
和i=0,...,6889
,我想使用Levenberg-Marquardt方法使用R_j
找到v_j
和scipy.optimize.root
的最佳解决方案(我欢迎其他建议)。
但是,我不知道如何设置需要传递给root
的可调用函数。到目前为止,我所拥有的一切显然是错误的。
def fun(x, (old_points, new_points, weights, n_joints)):
"""
:param x: variable to optimize. It is supposed to encapsulate R and v from (1)
:param old_points: original vertex positions, (6890,3) numpy array
:param new_points: transformed vertex positions, (6890,3) numpy array
:param weights: weight matrix obtained from spectral clustering, (n_joints, 6890) numpy array
:param n_joints: number of joints
:return: non-linear cost function to find the root of
"""
# Extract rotations and offsets
R = np.array([(np.array(x[j * 15:j * 15 + 9]).reshape(3, 3)) for j in range(n_joints)])
v = np.array([(np.array(x[j * 15 + 9:j * 15 + 12])) for j in range(n_joints)])
# Use equation (1) for the non-linear pass.
# R_j p_i
Rp = np.einsum('jkl,il', x, old_points) # x shall replace R
# w_ji (Rp_ij + v_j)
wRpv = np.einsum('ji,ijk->ik', weights, Rp + x) # x shall replace v
# Set up a non-linear cost function, then compute the squared norm.
d = new_points - wRpv
result = np.einsum('ik,ik', d, d)
return result
编辑:现在,这是正确的结果。
答案 0 :(得分:1)
使用原始的fun
(但要给它起一个更好的名字)
def fun(x, (old_points, new_points, weights, n_joints)):
"""
:param x: variable to optimize. It is supposed to encapsulate R and v from (1)
:param old_points: original vertex positions, (6890,3) numpy array
:param new_points: transformed vertex positions, (6890,3) numpy array
:param weights: weight matrix obtained from spectral clustering, (n_joints, 6890) numpy array
:param n_joints: number of joints
:return: non-linear cost function to find the root of
"""
# Extract rotations and offsets
R = np.array([(np.array(x[j * 15:j * 15 + 9]).reshape(3, 3)) for j in range(n_joints)])
v = np.array([(np.array(x[j * 15 + 9:j * 15 + 12])) for j in range(n_joints)])
# Use equation (1) for the non-linear pass.
# R_j p_i
Rp = np.einsum('jkl,il', x, old_points) # x shall replace R
# w_ji (Rp_ij + v_j)
wRpv = np.einsum('ji,ijk->ik', weights, Rp + x) # x shall replace v
# Set up a non-linear cost function, then compute the squared norm.
d = new_points - wRpv
result = np.einsum('ik,ik', d, d)
return result
对其进行封闭,以便接受单个输入(您要求解的变量):
old_points = ...
new_points = ...
weights = ...
rv = ...
n_joints = ...
def cont_function(x):
return fun(x, old_points, new_points, weights, rv, n_joints)
现在尝试在cost_function
中使用roots