def decomp_3rdms_to_2rdms_sf(inTerms, d3name, d1, d2, indexOrder = '1212'): """ Decomposes any 3-particle spin free RDMs in inTerms into products of 1 and 2 particle reduced density mattrices. """ # Prepare error message TypeErrorMessage = "inTerms must be a list of term objects" # Check input if type(inTerms) != type([]): raise TypeError, TypeErrorMessage if ( not isinstance(d1, tensor) ) or (len(d1.indices) != 2): raise TypeError, "d1 must be a tensor with 2 indices" if ( not isinstance(d2, tensor) ) or (len(d2.indices) != 4): raise TypeError, "d2 must be a tensor with 4 indices" # Initialize index i = 0 opCount = 0 # One by one, decompose 3RDMs and append the result # to the list of terms while i < len(inTerms): # Assign a short name for the ith term t = inTerms[i] # Check input if not isinstance(t, term): raise TypeError, TypeErrorMessage # Initialize the rdm variable rdm = False # Search for 3-particle RDMs in the term for j in range(len(t.tensors)-1, -1, -1): if t.tensors[j].name == d3name: rdm = t.tensors[j] pre_term = term(t.numConstant, t.constants, t.tensors[0:j]) post_term = term(1.0, [], t.tensors[j+1:]) break # If the term has no 3RDMs, incrment the index if rdm is False: i += 1 # If the term has a 3RDM, decompose it else: opCount += 1 decomp = decomp_3rdm_to_2rdm_sf(rdm, d1, d2, indexOrder) for s in decomp: inTerms.append(pre_term.copy()) inTerms[-1] = multiplyTerms(inTerms[-1], s) inTerms[-1] = multiplyTerms(inTerms[-1], post_term) del(inTerms[i]) if options.verbose: print 'decomposed %i 3-body RDMs' %(opCount)
def decomp_4ops_to_2ops_2rdms_sf(inTerms, d1, d2): """ Decomposes any 4-particle sfExOps in inTerms into products of 1 and 2 particle sfExOps and reduced density mattrices. """ # Prepare error message TypeErrorMessage = "inTerms must be a list of term objects" # Check input if type(inTerms) != type([]): raise TypeError, TypeErrorMessage if ( not isinstance(d1, tensor) ) or (len(d1.indices) != 2): raise TypeError, "d1 must be a tensor with 2 indices" if ( not isinstance(d2, tensor) ) or (len(d2.indices) != 4): raise TypeError, "d2 must be a tensor with 4 indices" # Initialize index i = 0 opCount = 0 # One by one, decompose four particle operators and append the result # to the list of terms while i < len(inTerms): # Assign a short name for the ith term t = inTerms[i] # Check input if not isinstance(t, term): raise TypeError, TypeErrorMessage # Initialize the operator variable op = False # Search for a 4-particle operator in the term for j in range(len(t.tensors)-1, -1, -1): if isinstance(t.tensors[j], sfExOp) and t.tensors[j].order == 3: op = t.tensors[j] pre_term = term(t.numConstant, t.constants, t.tensors[0:j]) post_term = term(1.0, [], t.tensors[j+1:]) break # If the term has no four particle operators, incrment the index if op is False: i += 1 # If the term has a four particle operator, decompose it else: opCount += 1 decomp = decomp_4op_to_2op_2rdm_sf(op, d1, d2) for s in decomp: inTerms.append(pre_term.copy()) inTerms[-1] = multiplyTerms(inTerms[-1], s) inTerms[-1] = multiplyTerms(inTerms[-1], post_term) del(inTerms[i]) if options.verbose: print 'decomposed %i 4-body operators' %(opCount)
def commutator(leftInput, rightInput, contract=True, combine=True): # Convert inputs that are terms into lists of terms if isinstance(leftInput, term): leftTerms = [leftInput] else: leftTerms = leftInput if isinstance(rightInput, term): rightTerms = [rightInput] else: rightTerms = rightInput # Check input integrity TypeErrorMessage = "commutator inputs must be terms or lists of terms" if type(leftTerms) != type([]) or type(rightTerms) != type([]): raise TypeError, TypeErrorMessage for t in rightTerms: if not isinstance(t, term): raise TypeError, TypeErrorMessage for t in leftTerms: if not isinstance(t, term): raise TypeError, TypeErrorMessage # Construct terms resulting from the commutator preNOTerms = [] #terms before normal ordering for lterm in leftTerms: for rterm in rightTerms: preNOTerms.append(multiplyTerms(lterm, rterm)) preNOTerms.append(multiplyTerms(rterm, lterm)) preNOTerms[-1].scale(-1) # For each term, apply Wick's theorem to convert it to normal order noTerms = [] #terms after normal ordering for t in preNOTerms: noTerms.extend(normalOrder(t)) del (preNOTerms) # Contract any delta functions resulting from the normal ordering, # unless told not to if contract: for t in noTerms: t.contractDeltaFuncs() # Remove any terms that are zero termChop(noTerms) # Combine any like terms unless told not to if combine: combineTerms(noTerms) # Return result return noTerms
def commutator(leftInput, rightInput, contract = True, combine = True): # Convert inputs that are terms into lists of terms if isinstance(leftInput,term): leftTerms = [leftInput] else: leftTerms = leftInput if isinstance(rightInput,term): rightTerms = [rightInput] else: rightTerms = rightInput # Check input integrity TypeErrorMessage = "commutator inputs must be terms or lists of terms" if type(leftTerms) != type([]) or type(rightTerms) != type([]): raise TypeError, TypeErrorMessage for t in rightTerms: if not isinstance(t, term): raise TypeError, TypeErrorMessage for t in leftTerms: if not isinstance(t, term): raise TypeError, TypeErrorMessage # Construct terms resulting from the commutator preNOTerms = [] #terms before normal ordering for lterm in leftTerms: for rterm in rightTerms: preNOTerms.append( multiplyTerms(lterm,rterm) ) preNOTerms.append( multiplyTerms(rterm,lterm) ) preNOTerms[-1].scale(-1) # For each term, apply Wick's theorem to convert it to normal order noTerms = [] #terms after normal ordering for t in preNOTerms: noTerms.extend(normalOrder(t)) del(preNOTerms) # Contract any delta functions resulting from the normal ordering, # unless told not to if contract: for t in noTerms: t.contractDeltaFuncs() # Remove any terms that are zero termChop(noTerms) # Combine any like terms unless told not to if combine: combineTerms(noTerms) # Return result return noTerms