def tps_nr_grad(x_ma, lin_ag, _trans_g, w_ng, x_na, return_tuple = False):
    N, D = x_na.shape
    M = x_ma.shape[0]

    assert x_ma.shape[1] == 3
    dists_mn = ssd.cdist(x_ma, x_na,'euclidean')
    diffs_mna = x_ma[:,None,:] - x_na[None,:,:]

    grad_mga = np.empty((M,D,D))
    lin_ga = lin_ag.T
    for a in xrange(D):
        grad_mga[:,:,a] = lin_ga[None,:,a] - np.dot(nan2zero(diffs_mna[:,:,a]/dists_mn),w_ng)

    # m n g a b
    Jw_mngab = - (nan2zero(diffs_mna[:,:,None,:,None]/dists_mn[:,:,None,None,None])) * grad_mga[:,None,:,None,:]
    Jw_mngab = Jw_mngab + Jw_mngab.transpose(0,1,2,4,3)        
    Jw_mabng = Jw_mngab.transpose(0,3,4,1,2)
    Jw = Jw_mabng.reshape(M*D**2,N*D)
    
    Jl_mcgab = np.eye(D)[None,:,None,:,None]*grad_mga[:,None,:,None,:]
    Jl_mcgab = Jl_mcgab + Jl_mcgab.transpose(0,1,2,4,3)
    Jl_mabcg = Jl_mcgab.transpose(0,3,4,1,2)
    Jl = Jl_mabcg.reshape(M*D**2,D*D)
    
    Jt = np.zeros((M*D**2,D))
    
    if return_tuple:
        return Jl, Jt, Jw
    else:
        J = np.c_[Jl, Jt, Jw]
        return J
gradient of green's strain
dataset/ETHPy150Open rll/lfd/lfd/tpsopt/tps.py/tps_nr_grad