def get_first_order_errors(fun, fname, hlist, d1): if d1[0] == 0: name = "dZ%i" % (d1[1] + 1) dx = "Z" exact = jder.sort_derivative(fname, Z, R, N, 1, dx)[d1[1]] if d1[0] == 1: xyz = ['x', 'y', 'z'] name = "d%s%i" %(xyz[d1[1]], d1[2]+1) dx = 'R' exact = jder.sort_derivative(fname, Z, R, N, 1, dx)[d1[1]][d1[2]] print("\n ------------------- \n Derivative %s \n ------------------ \nAnalytical derivative" %name) print(exact) ylist = [] #calculate numerical derivatives for increasingly small h for h in hlist: derf = numder.derivative(fun, [Z,R,N], 'numerical', 1, d1, [0,0], h) exf = exact.flatten() print("derf") print(derf) print("exf") print(exf) error = linalg.norm(derf - exf) ylist.append(error) return(ylist, name)
M_EVCM = jrep.CM_ev_unsrt(Z, R, N = 0, size = 4) diff = (ref_M_EVCM - M_EVCM) error = 0 for d in diff: error += d*d EVCM_aberration.append(error) #calculate CM M_CM = jrep.CM_full_unsorted_matrix(Z, R, N=0, size = 4) #collect all dZ for plotting for j in range(4): dZj = numder.derivative(jrep.CM_ev_unsrt,[Z, R, 0], order = 1, d1 = [0,j]) dZ_slot1_list[j].append(dZj[0]) dZ_slot2_list[j].append(dZj[1]) dZ_slot3_list[j].append(dZj[2]) dZ_slot4_list[j].append(dZj[3]) M_list[j].append(M_EVCM[j]) #dZ1 is dZ[0] and so forth, it contains a list of arrays in 4 dimensions #for every atom, extract it's data #eigenvalues per atom atom1 = np.array(M_list[0]) atom2 = np.array(M_list[1]) atom3 = np.array(M_list[2]) atom4 = np.array(M_list[3])
def get_second_order_errors(fun, fname, hlist, d1, d2): ''' fun: function from representation_ZRN.py fname: string, 'CM', 'CM_EV', 'CM_unsrt', 'OM', 'OM_EV' ''' #calculate exact result if d1[0] == 0: name1 = "dZ%i" % (d1[1] + 1) dx1 = "Z" if d2[0] == 0: name = name1 + "dZ%i" % (d2[1] + 1) dx2 = "Z" exact = jder.sort_derivative(fname, Z, R, N, 2, dx1, dx2)[d1[1]][d2[1]] if d1[0] == 1: xyz = ['x', 'y', 'z'] name1 = "d%s%i" %(xyz[d1[1]], d1[2]) dx1 = 'R' if d2[0] == 1: name = name1 + "d%s%i" %(xyz[d2[1]], (d2[2] + 1)) dx2 = 'R' exact = jder.sort_derivative(fname, Z, R, N, 2, dx1, dx2)[d1[1]][d1[2]][d2[1]][d2[2]] if (d1[0] == 0 and d2[0] == 1) or (d1[0] == 1 and d2[0] == 0): xyz = ['x', 'y', 'z'] #translate dx1 and dx2 to numbers for functions and names dx1 = "Z" dx2 = "R" if d1[0] == 0: ZR_order = True name1 = "dZ%i" % (d1[1]+1) name2 = "d%s%i" %(xyz[d2[1]], d2[2]+1) else: ZR_order = False name1 = "dZ%i" % (d2[1]+1) name2 = "d%s%i" %(xyz[d1[1]], d1[2]+1) name = name1 + name2 if ZR_order: exact = jder.sort_derivative(fname, Z, R, N, 2, dx1, dx2)[d1[1]][d2[1]][d2[2]] else: exact = jder.sort_derivative(fname, Z, R, N, 2, dx1, dx2)[d2[1]][d1[1]][d1[2]] print("\n ------------------- \n Derivative %s \n ------------------ \nAnalytical derivative" %name) print(exact) ylist = [] #calculate numerical derivatives for increasingly small h for h in hlist: derf = numder.derivative(fun, [Z,R,N], 'numerical', 2, d1, d2, h) exf = exact.flatten() error = linalg.norm(derf - exf) print("derf") print(derf) print("exf") print(exf) #print("h", h, "error", error) #print(derf.reshape(3,3)) ylist.append(error) return(ylist, name)
Z = jnp.asarray(Z, dtype=jnp.float32) fun = ZRNrep.Coulomb_Matrix_Sorted #fun = jrep.CM_ev #store all results in arrays to print them later Zder = [] Rder = [] Z2der = [] R2der = [] ZRder = [] #do all Z derivatives for i in range(dim): name = ("dZ%i:" % (i + 1)) der = numder.derivative(fun, [Z, R, N], d1=[0, i]) Zder.append([name, der]) #do all dZdZ derivatives: for j in range(dim): name = ("dZ%i dZ%i:" % (i + 1, j + 1)) der = numder.derivative(fun, [Z, R, N], d1=[0, i], d2=[0, j]) Z2der.append([name, der]) #do all dZdR derivatives: for x in xyz: name = ("dZ%i d%s%i:" % (i + 1, x[1], j + 1)) der = numder.derivative(fun, [Z, R, N], d1=[0, i], d2=[1, j, x[0]])
def calculate_num_der(repro, compoundlist, matrix=False, do_dZ=True, do_dR=True): '''calculates eigenvalues of derived matrices from compounds only functions as translator between the compound object, the derivative_result object and the sorted_derivative function. Arguments: ---------- repro: callable representation function that takes Z, R as first two args all functions in "representations_ZRN.py" work compoundlist: list of database_preparation.compound objects matrix: If repro returns matrix like shape, unravel do_dZ : boolean, if true, do dZ derivative do_dR : boolean, if true, do dR derivative Returns: -------- resultlist: list of derivative_result instances, a class which contains both norm as well as derivatives, eigenvalues and fractual eigenvalue information results: list of fractions of nonzero eigenvalues, structure: [[compound 1: dZ_ev, dR_ev, ...], [compound 2: ...],...] ''' resultlist = [] results = [] print("Your representation is ", repro, "this is a matrix is set to: ", matrix) print( "if this is wrong, change in function 'calculate_num_der' in file jax_additional_derivative.py" ) #extract atomic data from compound for c in compoundlist: Z_orig = np.asarray([float(i) for i in c.Z]) R_orig = np.asarray(c.R) N = float(c.N) #calculate derivatives and representation #M needed to calculate norm for molecule, here always using CM matrix nuclear norm #order needed to preorder molecules (numerical derivative) dim = len(Z_orig) M, order = jrep.CM_full_sorted(Z_orig, R_orig, N, size=dim) #preorder Z and R as numerical derivation may be disturbed by sorted representations Z, R = presort(Z_orig, R_orig, np.asarray(order)) dZ = [[0] for i in range(dim)] dR = [[[0] for j in range(3)] for i in range(dim)] dZdZ = [[[0] for j in range(dim)] for i in range(dim)] dRdR = [[[[[0] for l in range(3)] for k in range(dim)] for j in range(3)] for i in range(dim)] dZdR = [[[[0] for k in range(3)] for j in range(dim)] for i in range(dim)] print( "checkpoint2: now starting numerical differentiation, jax_additional line 82" ) for i in range(dim): if do_dZ: try: dZ[i] = numder.derivative(repro, [Z, R, N], order=1, d1=[0, i]) print("subcheck2: dZ derivative calculated") except TypeError: print("this representation cannot be derived by dZ") for j in range(3): if do_dR: dR[i][j] = numder.derivative(repro, [Z, R, N], order=1, d1=[1, i, j]) for k in range(dim): if do_dZ: try: dZdR[i][k][j] = numder.derivative(repro, [Z, R, N], order=2, d1=[0, i], d2=[1, k, j]) except TypeError: print( "this representation cannot be derived by dZdR" ) if do_dR: for l in range(3): dRdR[i][j][k][l] = numder.derivative(repro, [Z, R, N], order=2, d1=[1, i, j], d2=[1, k, l]) for m in range(dim): if do_dZ: dZdZ[i][m] = numder.derivative(repro, [Z, R, N], order=2, d1=[0, i], d2=[0, m]) print("all derivatives were calculated successfully for compound ", c.filename) #create derivative results instance der_result = datprep.derivative_results(c.filename, Z, M) #get all derivative eigenvalues for the derivatives and add to results instance der_result.add_all_RZev(np.asarray(dZ), np.asarray(dR), np.asarray(dZdZ),\ np.asarray(dRdR), np.asarray(dZdR)) #calculate percentile results and add to results res, addition = der_result.calculate_smallerthan() results.append(res) resultlist.append(der_result) return (resultlist, results)
M_EVCM = jrep.CM_ev_unsrt(Z, R, N=0, size=4) diff = (ref_M_EVCM - M_EVCM) error = 0 for d in diff: error += d * d EVCM_aberration.append(error) #calculate CM M_CM = jrep.CM_full_unsorted_matrix(Z, R, N=0, size=4) #collect all dZ for plotting for j in range(4): dxj = numder.derivative(jrep.CM_ev_unsrt, [Z, R, 0], order=1, d1=[1, j, 0]) dx_slot1_list[j].append(dxj[0]) dx_slot2_list[j].append(dxj[1]) dx_slot3_list[j].append(dxj[2]) dx_slot4_list[j].append(dxj[3]) dyj = numder.derivative(jrep.CM_ev_unsrt, [Z, R, 0], order=1, d1=[1, j, 1]) dy_slot1_list[j].append(dyj[0]) dy_slot2_list[j].append(dyj[1]) dy_slot3_list[j].append(dyj[2]) dy_slot4_list[j].append(dyj[3]) dzj = numder.derivative(jrep.CM_ev_unsrt, [Z, R, 0],