最大化正交矩阵的函数

计算科学 约束优化 scipy 计算化学 矩阵方程
2021-12-05 00:32:04

我正在尝试编写一个小代码,给定分子的一组正常振动模式,将它们转换为局部振动模式。为此,我遵循J. Chem 的程序。物理。130, 084106 (2009)他们引入作为正交变换 ( ) 从正常模式 ( ) 到局部模式 ( )。是一个矩阵,Q 是一个矩阵,其中是分子的数量,k 是正常模式的数量。来自于每个分子都有 x,y,z 坐标(Q~=QUUQQ~Uk×k3n×kn3nQ矩阵有时表示为三个索引量,因此可以对笛卡尔坐标求和)。

为了找到进行这种转换的,他们定义了函数:并说转换的正确是最大化这个表达式的那个。 U

ξ(U)=pkin(α=13qk(Qiα,qUqp)2)2
U

我已经在 Python 中编写了这个函数及其梯度,并试图scipy.optimize.minimize针对一个小案例对其进行优化,但所有方法都失败,并显示消息“由于精度损失而不一定实现所需的错误。”。

关键问题似乎是保持的正交性,因为如果没有这个约束,我怀疑问题是不确定的。我已尝试按照Cross Validated 上的问题的建议将其包含在渐变中来包含此约束,但它似乎不起作用。U

我的问题基本上可以归结为:是否有明显的我遗漏的东西可以改善与scipy.optimize.minimizescipy 使用的方法的收敛性,或者问题只是难以解决,我需要尝试不同的方法?我希望不必重新发明轮子,因此首选已经实施的建议。

如果有帮助,我在下面包含了我正在使用的代码。

import numpy as np
from scipy.optimize import minimize

#Q is the matrix of normal modes (3N x k). 

#U is the desired unitary transform matrix (k x k). Optimize only accepts functions of vectors, so have to flatten U. 

#Pipek-Mezey function/criterion
def PM(U,Q,NAtoms,NModes):
    U=np.reshape(U,(NModes,NModes))
    Qtilde=np.einsum('ij,jk->ik',Q,U)

    #Make a 3-index array of cartesian, number of atoms, number of modes for ease of summing
    Qtilde=np.reshape(Qtilde,(3,NAtoms,NModes))
    ##A**2 squares all elements of array, not the square of a matrix
    ##i...->... sums over first index
    C=np.einsum('i...->...',Qtilde**2)

    result=-np.einsum('ij->',C**2)

    return result  

#Gradient of PM condition, shares args with PM. Gradient includes additional factors to 
#ensure U remains orthogonal 
def PM_grad(U,Q,NAtoms,NModes):
    gradient=np.zeros((NModes,NModes))
    U=np.reshape(U,(NModes,NModes))

    #Taking derivatives with respect to U_rs. Sum over s first to reuse intermediates
    for s in range(NModes):
        #Each term of the gradient only contains a column of Qtilde
        Qtildecol=np.einsum('ij,j->i',Q,U[:,s])
        Qtildecol=np.reshape(Qtildecol,(3,NAtoms))
        #Similarly, only a column of C
        Ccol= np.einsum('i...->...',Qtildecol**2)    
        for r in range(NModes):
            Qcol=np.reshape(Q[:,r],(3,NAtoms))
            Intermediate=np.einsum('ij,ij->j',Qcol,Qtildecol)
            gradient[r,s]=-4*np.einsum('i,i->',Intermediate,Ccol)    

    #Gradient correction to ensure orthogonality
    gradient=gradient-(U@np.transpose(gradient)@U) 

    return np.reshape(gradient,(NModes**2))

NModes=3
NAtoms=3
#U is the desired unitary transform matrix (k x k). Optimize only accepts functions of vectors, so have to flatten U. 
U=[0.0,-.800,-.6,.8,-.36,.48,.6,.48,-.64]
#Q is the matrix of normal modes (3N x k).
Q=[0.00000,0.00000,0.00000,0.00000,0.00000,-0.06812,-0.06867,0.05247,0.00000,0.00000,0.00000,0.00000,0.44800,
0.57030,0.54056,0.54492,-0.41639,-0.45330,0.00000,0.00000,0.00000,-0.44800,-0.57030,0.54056,0.54492,-0.41639,0.45330]
Q=np.transpose(np.reshape(Q,(3,9)))


result=minimize(PM,U,args=(Q,NAtoms,NModes),method="BFGS",jac=PM_grad,options={'disp': True})
print(result.x)
3个回答

在正交性约束下,有一些专门的方法可以最小化可微函数参见例如:f(X)XTX=I

赖、荣杰和斯坦利·奥舍。“正交约束问题的分裂方法”。科学计算杂志 58,没有。2 (2014): 431–449。

文、载文、尹沃韬。“一种使用正交约束进行优化的可行方法。” 数学编程 142,没有。1-2(2013):397-434。

引入正交约束的一种简单方法是使用凯莱变换或矩阵指数对所有正交矩阵进行参数化。在这两种情况下,将是正交的,如果Q=(IA)(I+A)1Q=exp(A)QA是斜对称的。搜索斜对称矩阵的空间很容易,因为空间的一个元素可以用斜对称基矩阵的线性组合来表示。Cayley 变换是它自己的逆变换,所以任何正交Q没有 -1 作为特征值的可以用这种方式表示。相似地,A=log(Q), 所以只要Q是可逆的(如果它是正交的,它必须是),它的对数存在,所以任何正交Q可以表示为expA.

另一个很好的参考资料是:“The Geometry of Algorithms with Orthogonality Constraints”,Alan Edelman、Tomás A. Arias 和 Steven T. Smith

我最终使用了一种不同的方法来进行优化。在论文中,他们使用了一种基于 Jacobi 旋转的方法,通过计算出的最佳角度旋转模态对以增加函数值。这种方法以前曾用于执行类似的正交优化以定位分子轨道(Rev. Mod. Phys. 35, 457)。这些最佳旋转永远不会降低函数值,并且旋转保持初始猜测的正交性,因此它们最终会收敛到正交解。他们执行这些旋转,扫描所有模式对,直到所有旋转导致函数值的变化小于某个阈值。

我最初无法让这种方法起作用,这导致了我在最初的问题中的尝试,但我已经设法修复了我自己的 Jacobi Sweep 方法的实现。如果感兴趣,我可以在此处包含代码或指向它的链接。