def test(): # Two random vectors vec_a = matrix.col((uniform(-20,20), uniform(-20,20), uniform(-20,20))) vec_b = matrix.col((uniform(-20,20), uniform(-20,20), uniform(-20,20))) # The test may fail if the angle between the vectors is small or close to pi # (see gradient of acos(x) for x close to 1 or -1) but we are not interested # in such cases anyway. Skip test if the acute angle is less than 1 degree if vec_a.accute_angle(vec_b, deg=True) < 1: return False a = vec_a.length() b = vec_b.length() a_dot_b = vec_a.dot(vec_b) gamma = acos(a_dot_b / (a*b)) # Analytical dg = AngleDerivativeWrtVectorElts(vec_a, vec_b) # FD dgFD = FDAngleDerivativeWrtVectorElts(vec_a, vec_b) assert approx_equal(dg.dtheta_du_1(), dgFD.dtheta_du_1()) assert approx_equal(dg.dtheta_du_2(), dgFD.dtheta_du_2()) assert approx_equal(dg.dtheta_du_3(), dgFD.dtheta_du_3()) assert approx_equal(dg.dtheta_dv_1(), dgFD.dtheta_dv_1()) assert approx_equal(dg.dtheta_dv_2(), dgFD.dtheta_dv_2()) assert approx_equal(dg.dtheta_dv_3(), dgFD.dtheta_dv_3()) # Test vector version assert approx_equal(dg.derivative_wrt_u(), matrix.col( (dg.dtheta_du_1(), dg.dtheta_du_2(), dg.dtheta_du_3()))) assert approx_equal(dg.derivative_wrt_v(), matrix.col( (dg.dtheta_dv_1(), dg.dtheta_dv_2(), dg.dtheta_dv_3()))) return True
print "d[a]/dp{2} analytical: {0:.5f} FD: {1:.5f}".format(da_dp, fd_grad[i]['da_dp'], i) db_dp = 1./b * bvec.dot(dbv_dp) print "d[b]/dp{2} analytical: {0:.5f} FD: {1:.5f}".format(db_dp, fd_grad[i]['db_dp'], i) dc_dp = 1./c * cvec.dot(dcv_dp) print "d[c]/dp{2} analytical: {0:.5f} FD: {1:.5f}".format(dc_dp, fd_grad[i]['dc_dp'], i) print print "CELL ANGLES" # Here we know the derivatives of the angle alpha with respect to elements # of the vectors a and b. Similarly for beta and gamma. We know these # expressions are correct because they are tested in # tst_angle_derivatives_wrt_vector_elts.py dalpha_db = dalpha.derivative_wrt_u() dalpha_dc = dalpha.derivative_wrt_v() dbeta_da = dbeta.derivative_wrt_u() dbeta_dc = dbeta.derivative_wrt_v() dgamma_da = dgamma.derivative_wrt_u() dgamma_db = dgamma.derivative_wrt_v() # daa_dp = RAD2DEG * (dbv_dp.dot(dalpha_db) + dcv_dp.dot(dalpha_dc)) dbb_dp = RAD2DEG * (dav_dp.dot(dbeta_da) + dcv_dp.dot(dbeta_dc)) dcc_dp = RAD2DEG * (dav_dp.dot(dgamma_da) + dbv_dp.dot(dgamma_db)) print "d[alpha]/dp{2} analytical: {0:.5f} FD: {1:.5f}".format(daa_dp, fd_grad[i]['daa_dp'], i) print "d[beta]/dp{2} analytical: {0:.5f} FD: {1:.5f}".format(dbb_dp, fd_grad[i]['dbb_dp'], i) print "d[gamma]/dp{2} analytical: {0:.5f} FD: {1:.5f}".format(dcc_dp, fd_grad[i]['dcc_dp'], i)