Source code for eqc_models.utilities.polynomial
- [docs]
- def evaluate_polynomial(terms, solution):
-     val = 0
-     
-     for k, coeff in terms.items():
-         term = coeff
-         for idx in k:
-             if idx > 0:
-                 idx -= 1
-                 term *= solution[idx]
-         
-         
-         val += term
-     return val
- [docs]
- def convert_hamiltonian_to_polynomial(
-     A,
-     B,
-     C,
-     D,
-     num_vars,
- ):
-     """Converts a hamiltonian of up to fourth order to a polynomial.
-     D_{ijkl} x_i x_j x_k x_l + C_{ijk} x_i x_j x_k + B_{ij} x_i x_j
-     + A_i x_i
-     Input:
-     A: First order hamiltonian.
-     B: Second order hamiltonian.
-     C: Third order hamiltonian.
-     D: Fourth order hamiltonian.
-     num_vars: Number of variables.
-     Output:
-     polynomial_indices, polynomila_coefs: Indices and coefficients of
-     polynomial that respresents the hamiltonian.
-     """
-     assert num_vars >= 1, "Invalid number of variables <%d>!" % num_vars
-     if D is not None:
-         assert len(D.shape) == 4, "Incorrect shape!"                
-         assert D.shape[0] == num_vars, "Inconsistent dimensions!"
-         assert D.shape[1] == num_vars, "Inconsistent dimensions!"
-         assert D.shape[2] == num_vars, "Inconsistent dimensions!"
-         assert D.shape[3] == num_vars, "Inconsistent dimensions!"
-         poly_order = 4
-     elif C is not None:
-         assert len(C.shape) == 3, "Incorrect shape!"                
-         assert C.shape[0] == num_vars, "Inconsistent dimensions!"
-         assert C.shape[1] == num_vars, "Inconsistent dimensions!"
-         assert C.shape[2] == num_vars, "Inconsistent dimensions!"
-         poly_order = 3
-     elif B is not None:
-         assert len(B.shape) == 2, "Incorrect shape!"        
-         assert B.shape[0] == num_vars, "Inconsistent dimensions!"
-         assert B.shape[1] == num_vars, "Inconsistent dimensions!"
-         poly_order = 2
-     elif A is not None:
-         assert len(A.shape) in [1, 2], "Incorrect shape!"
-         if len(A.shape) == 2:
-             if A.shape[1] == 1:
-                 A = A.reshape((A.shape[0]))
-             else:
-                 assert False, "Incorrect shape!"
-         
-         assert A.shape[0] == num_vars, "Inconsistent dimensions!"
-             
-         poly_order = 1
-     else:
-         assert False, "No hamiltonian provided!"
-     poly_indices = []
-     poly_coefs = []
-     if A is not None:
-         for i in range(num_vars):
-             coef_val = A[i]
-             if coef_val != 0:
-                 poly_coefs.append(coef_val)
-                 poly_indices.append([0] * (poly_order - 1) + [i + 1])
-     if B is not None:
-         for i in range(num_vars):
-             for j in range(i, num_vars):
-                 if i == j:
-                     coef_val = B[i][i]
-                 else:
-                     coef_val = B[i][j] + B[j][i]
-                 if coef_val != 0:
-                     poly_coefs.append(coef_val)
-                     poly_indices.append(
-                         [0] * (poly_order - 2) + [i + 1, j + 1]
-                     )
-     if C is not None:
-         for i in range(num_vars):
-             for j in range(i, num_vars):
-                 for k in range(j, num_vars):
-                     unique_perms = [
-                         list(item)
-                         for item in set(itertools.permutations([i, j, k]))
-                     ]
-                     coef_val = 0.0
-                     for item in unique_perms:
-                         coef_val += C[item[0]][item[1]][item[2]]
-                     if coef_val != 0:
-                         poly_coefs.append(coef_val)
-                         poly_indices.append(
-                             [0] * (poly_order - 3) + [i + 1, j + 1, k + 1]
-                         )
-     if D is not None:
-         for i in range(num_vars):
-             for j in range(i, num_vars):
-                 for k in range(j, num_vars):
-                     for l in range(k, num_vars):
-                         unique_perms = [
-                             list(item)
-                             for item in set(
-                                 itertools.permutations([i, j, k, l])
-                             )
-                         ]
-                         coef_val = 0.0
-                         for item in unique_perms:
-                             coef_val += D[item[0]][item[1]][item[2]][
-                                 item[3]
-                             ]
-                         if coef_val != 0:
-                             poly_coefs.append(coef_val)
-                             poly_indices.append(
-                                 [i + 1, j + 1, k + 1, l + 1]
-                             )
-     return poly_indices, poly_coefs