def add(self, state: core.Matrix, error: core.Matrix): """ Adds a DIIS state and error vector to the DIIS object. Parameters ---------- state The current state vector. error The current error vector. """ self.error.append(error.clone()) self.state.append(state.clone())
def test_constructors(): int_row = 10 int_col = 20 # int row/col m1 = Matrix(int_row, int_col) check_dense_mat(m1, int_row, int_col) # int row/col w/ name m2 = Matrix("m2", int_row, int_col) check_dense_mat(m2, int_row, int_col, "m2") dim_row = Dimension([3, 2, 1, 4]) dim_col = Dimension([4, 2, 0, 2]) # dim row/col (default sym) m3 = Matrix("m3", dim_row, dim_col) check_block_sparse_mat(m3, 4, dim_row, dim_col, "m3") # dim row/col symm specified m4 = Matrix("m4", dim_row, dim_col, 2) check_block_sparse_mat(m4, 4, dim_row, dim_col, "m4", 2)
def test_doublets(adl, adr, Ga, bdl, bdr, Gb, at, bt): a = build_random_mat(adl, adr, Ga) b = build_random_mat(bdl, bdr, Gb) res = Matrix.doublet(a, b, at, bt) expected = generate_result(a, b, at, bt) assert res.symmetry() == a.symmetry() ^ b.symmetry(), "Symm mismatch {} x {} != {}".format( a.symmetry(), b.symemtry(), res.symmetry()) res_blocks = res.to_array() if isinstance(res_blocks, np.ndarray): res_blocks = [res_blocks] block_checks = [] for blk_idx in range(res.nirrep()): assert compare_arrays(expected[blk_idx], res_blocks[blk_idx], 8, "Block[{}]".format(blk_idx))
def energy_correction(basis_sets, deriv, ref_energies): low_cbs_hess = corl_xtpl_helgaker_2("basis set xtpl Hess", basis_sets[1], deriv[2], basis_sets[0], deriv[1]) low_cbs_e = corl_xtpl_helgaker_2("basis set xtpl E", basis_sets[1], ref_energies[2], basis_sets[0], ref_energies[1]) # This is, for instance, mp2/[T,Q]Z + CCSD(T)/DZ - mp2/DZ + SCF/QZ final_hess = Matrix.from_array(low_cbs_hess.np + deriv[0].np - deriv[3].np + deriv[4].np) final_en = low_cbs_e + ref_energies[0] - ref_energies[3] + ref_energies[4] return final_en, final_hess, low_cbs_e
def test_doublets(adl, adr, Ga, bdl, bdr, Gb, at, bt): a = build_random_mat(adl, adr, Ga) b = build_random_mat(bdl, bdr, Gb) res = Matrix.doublet(a, b, at, bt) expected = generate_result(a, b, at, bt) assert res.symmetry( ) == a.symmetry() ^ b.symmetry(), "Symm mismatch {} x {} != {}".format( a.symmetry(), b.symemtry(), res.symmetry()) res_blocks = res.to_array() if isinstance(res_blocks, np.ndarray): res_blocks = [res_blocks] block_checks = [] for blk_idx in range(res.nirrep()): assert compare_arrays(expected[blk_idx], res_blocks[blk_idx], 8, "Block[{}]".format(blk_idx))
def build_random_mat(rdim, cdim, symmetry=0): m = Matrix("test", rdim, cdim, symmetry) for h in range(m.nirrep()): block_shape = (m.rows(h), m.cols(h ^ m.symmetry())) m.nph[h][:, :] = np.random.randn(*block_shape) return m
Px += (4.0 * J_mo - K_mo - Kt_mo).reshape(prod.nrot) Mx += (Kt_mo - K_mo).reshape(prod.nrot) P[:, jb] = Px M[:, jb] = Mx Px_2, Mx_2 = prod.jk_RHF(fake_guess[:, jb]) P2[:, jb] = Px_2 M2[:, jb] = Mx_2 NH = np.einsum("ij,jk->ik", M, P) NH2 = np.einsum("ij,jk->ik", M2, P2) w, X = np.linalg.eig(NH) w_NH = np.sqrt(w[w.argsort()]) w, X = np.linalg.eig(NH2) w_NH2 = np.sqrt(w[w.argsort()]) Mhalf2 = Matrix.from_array(M2) Mhalf = Matrix.from_array(M) Mhalf.power(0.5, 1.0e-16) Mhalf2.power(0.5, 1.0e-16) Mhalf = Mhalf.to_array() Mhalf2 = Mhalf2.to_array() H = np.einsum("ij,jk,km->im", Mhalf, P, Mhalf) H2 = np.einsum("ij,jk,km->im", Mhalf2, P2, Mhalf2) w, X = np.linalg.eigh(H) w_H = np.sqrt(w[w.argsort()]) w, X = np.linalg.eigh(H2) w_H2 = np.sqrt(w[w.argsort()]) wm, X = np.linalg.eig(M) wp, X = np.linalg.eig(P)
def extrapolate(self, out: core.Matrix = None) -> core.Matrix: """ Extrapolates next state vector from the current set of state and error vectors. Parameters ---------- out A array in which to place the next state vector. Returns ------- ret : Matrix Returns the next state vector. """ # Limit size of DIIS vector diis_count = len(self.state) if diis_count == 0: raise ValidationError("DIIS: No previous vectors.") if diis_count == 1: return self.state[0] if diis_count > self.max_vec: if self.removal_policy == "OLDEST": pos = 0 else: pos = np.argmax([x.rms() for x in self.error]) del self.state[pos] del self.error[pos] diis_count -= 1 # Build error matrix B B = np.empty((diis_count + 1, diis_count + 1)) B[-1, :] = 1 B[:, -1] = 1 B[-1, -1] = 0 for num1, e1 in enumerate(self.error): B[num1, num1] = e1.vector_dot(e1) for num2, e2 in enumerate(self.error): if num2 >= num1: continue val = e1.vector_dot(e2) B[num1, num2] = B[num2, num1] = val # Build residual vector resid = np.zeros(diis_count + 1) resid[-1] = 1 # Solve pulay equations # Yea, yea this is unstable make it stable iszero = np.any(np.diag(B)[:-1] <= 0.0) if iszero: S = np.ones((diis_count + 1)) else: S = np.diag(B).copy() S[:-1] **= -0.5 S[-1] = 1 # Then we gotta do a custom inverse B *= S[:, None] * S invB = core.Matrix.from_array(B) invB.power(-1.0, 1.e-12) ci = np.dot(invB, resid) ci *= S # combination of previous fock matrices if out is None: out = core.Matrix("DIIS result", self.state[0].rowdim(), self.state[1].coldim()) else: out.zero() for num, c in enumerate(ci[:-1]): out.axpy(c, self.state[num]) return out