Project: s41467-025-57007-1 | Function: H (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Calculates the Hamiltonian (total energy) of the Potts model system with hidden states. Takes spin configuration and adjacency matrix, returns energy value using Ising-like interaction formula normalized by network connectivity.

**KEY TERMS:** {
  "spin": "s_i (spin states)",
  "adj": "A_ij (adjacency matrix)",
  "J": "J (coupling constant)",
  "Ham": "H (Hamiltonian energy)",
  "spinE": "effective spins",
  "eff": "hidden state processing"
}

**CONTEXT CODE:** #number of domains (parts of the chain with constant spin)
def ndom(spins):
    nd=1
    for j in range(len(spins)-1):
        if spins[j]!=spins[j+1]:
            nd=nd+1
    #check if the last spin has the same value as the first spin, then they belong to the same domain
    if spins[len(spins)-1]==spins[0] and nd>1:
        nd=nd-1
    return(nd)

#length of domains (parts of the chain with constant spin)
def lendom(spins):
    n=len(spins)
    listd=()
    ld=1
    for j in range(len(spins)-1):
        if spins[j]!=spins[j+1]:
            listd=np.append(listd,ld)
            ld=1
        else:
            ld=ld+1
    if spins[0]==spins[n-1] and len(listd)>0:
        listd=np.append(listd,ld+listd[0])
        listd[0]=0
    else:
        listd=np.append(listd,int(ld))
    return(listd)

#energy contribution of the domain
def hdom(l,alpha=2):
    sum = 0
    for k in range(1, int(l) + 1):
        sum += (l - k) / k**alpha
    return sum

#total energy contribution from all domains
def endom(listd,alpha=2):
    sum=0
    for k in range(len(listd)):
        sum +=hdom(listd[k],alpha)
    return(sum)


#total spin magnetization
def mag(spin):
    return(spin.sum())


#The total Hamiltonian of the system, it combines both nearest-neighbor interaction with coupling J and the truncated long-range interaction with coupling C and exponent alpha
def H(spins,C=1,alpha=2,J=1,h=0):
    """
    Computes the Hamiltonian (total energy) for the Truncated long-range Ising model.

    This function implements the Hamiltonian formula:
    H(s)=-J∑_{i=1}^N s_i s_{i+1} - ∑_{i<j} C/|i-j|^α s_i s_j I(s_i,s_j)
    It combines both nearest-neighbor interaction with coupling J and the truncated
    long-range interaction with coupling C and exponent alpha within domains of constant spin.

    Args:
        spins: Spin configuration array of the system
        C: Long-range coupling strength (default: 1)
        alpha: Distance exponent for long-range interactions (default: 2)
        J: Nearest-neighbor coupling constant (default: 1)
        h: External field strength (default: 0)

    Returns:
        float: Total Hamiltonian energy of the system

    Raises:
        NotImplementedError: Function has been masked for testing purposes
    """
    raise NotImplementedError("This function has been masked for testing purposes")

#Tests whether to accept a new state. If the Hamiltonian has decreased, always accept, otherwise use the MC formula
def MCcond(oldspin,newspin,T,C=1,alpha=2,J=1,h=0):
    HamOld=H(oldspin,C,alpha,J,h)
    HamNew=H(newspin,C,alpha,J,h)
    if HamNew <= HamOld:
        return(True)
    else:
        r=np.exp(-1/T*(HamNew-HamOld))
        u=np.random.random()
        if u<=r:
            return(True)
        else:
            return(False)


#initialize the system
def MCinit(npart,init):
    #initialization of spins
    if init=="hot":
        spinN=initHot(npart)
    elif init=="cold":
        spinN=initCold(npart)
    else:
        pup=np.random.random()
        spinN=initSpin(npart,pSpins=[pup,1-pup])
    return(spinN)


#Make a MC step. Try to flip a spin and accept it with the MH probability. spin and adj are spin vector and adjacency matrix. 
#nhid is the number of hidden states, q does not have a purpose now, T is temperature, alpha is the exponent in the distance, J is the nearest-neighbor coupling, C is long-range coupling, h is external field, quiet is for checking purposes (if false it prints whether the state is accepted or rejected) 
def makeMove(spin,T,C=1,alpha=2,J=1,h=0,quiet=True):
    spinOld=np.copy(spin)
    spinNew=spinFlip(spinOld)
    if MCcond(spinOld,spinNew,T,C,alpha,J,h):
        if not quiet:
            print("accepted")
            #print(H(spinNew,C,alpha,J,h))
        return(spinNew) 
    else:
        if not quiet:
            print("rejected")
            #print(np.exp(-1/T*((H(spinNew,C,alpha,J,h)-H(spinOld,C,alpha,J,h)))))
        return(spinOld)


#MC simulation of the whole trajectory. Initialize the system and then run the simulation for nSteps steps. 
def MCsimulation(T,npart,nSteps,init,C=1,alpha=2,J=1,h=0,quiet=True):
   
    #initialization
    spinN = MCinit(npart,init)

    #initial state
    statetraj=([mag(spinN),ndom(spinN)])

    #MC step
    t=0
    while t<nSteps:
        spinN = makeMove(spinN,T,C,alpha,J,h,quiet)
        magdomh=([mag(spinN),ndom(spinN)])
        statetraj=np.vstack([statetraj,magdomh])
        t=t+1
    return(statetraj)






    
#wrapper function for asyncio paralellization
def background(f):
    def wrapped(*args,**kwargs):
        return asyncio.get_event_loop().run_in_executor(None,f,*args,**kwargs)
    
    return wrapped



Complete the function implementation replacing "raise NotImplementedError".